blob: 5d9af17e45cde9ff1279d011ef3f2fbfbf6b2e39 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSLv3/TLSv1 client-side functions
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020024#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020026#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/debug.h"
31#include "mbedtls/ssl.h"
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +020032#include "mbedtls/ssl_internal.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020040#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_free free
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020042#endif
43
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020044#include <stdint.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000047#include <time.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020048#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Paul Bakker34617722014-06-13 17:20:13 +020051/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020053 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54}
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
58static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +010059 unsigned char *buf,
60 size_t *olen )
61{
62 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +010063 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010064 size_t hostname_len;
Paul Bakkerd3edc862013-03-20 16:07:17 +010065
66 *olen = 0;
67
Paul Bakker66d5d072014-06-17 16:39:18 +020068 if( ssl->hostname == NULL )
Paul Bakkerd3edc862013-03-20 16:07:17 +010069 return;
70
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
Paul Bakkerd3edc862013-03-20 16:07:17 +010072 ssl->hostname ) );
73
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010074 hostname_len = strlen( ssl->hostname );
75
Simon Butcher0fc94e92015-09-28 20:52:04 +010076 if( end < p || (size_t)( end - p ) < hostname_len + 9 )
Simon Butchered997662015-09-28 02:14:30 +010077 {
Simon Butcher0fc94e92015-09-28 20:52:04 +010078 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
Simon Butchered997662015-09-28 02:14:30 +010079 return;
80 }
81
Paul Bakkerd3edc862013-03-20 16:07:17 +010082 /*
83 * struct {
84 * NameType name_type;
85 * select (name_type) {
86 * case host_name: HostName;
87 * } name;
88 * } ServerName;
89 *
90 * enum {
91 * host_name(0), (255)
92 * } NameType;
93 *
94 * opaque HostName<1..2^16-1>;
95 *
96 * struct {
97 * ServerName server_name_list<1..2^16-1>
98 * } ServerNameList;
99 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
101 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100102
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100103 *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
104 *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100105
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100106 *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
107 *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100110 *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
111 *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100112
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100113 memcpy( p, ssl->hostname, hostname_len );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100114
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100115 *olen = hostname_len + 9;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100116}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119#if defined(MBEDTLS_SSL_RENEGOTIATION)
120static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100121 unsigned char *buf,
122 size_t *olen )
123{
124 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100125 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100126
127 *olen = 0;
128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100130 return;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100133
Simon Butcher0fc94e92015-09-28 20:52:04 +0100134 if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
Simon Butchered997662015-09-28 02:14:30 +0100135 {
136 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
137 return;
138 }
139
Paul Bakkerd3edc862013-03-20 16:07:17 +0100140 /*
141 * Secure renegotiation
142 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
144 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100145
146 *p++ = 0x00;
147 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
148 *p++ = ssl->verify_data_len & 0xFF;
149
150 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
151
152 *olen = 5 + ssl->verify_data_len;
153}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100155
Manuel Pégourié-Gonnardd9423232014-12-02 11:57:29 +0100156/*
157 * Only if we handle at least one key exchange that needs signatures.
158 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
160 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
161static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100162 unsigned char *buf,
163 size_t *olen )
164{
165 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100166 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100167 size_t sig_alg_len = 0;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200168 const int *md;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5bfd9682014-06-24 15:18:11 +0200170 unsigned char *sig_alg_list = buf + 6;
171#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100172
173 *olen = 0;
174
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200175 if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100176 return;
177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100179
Simon Butchered997662015-09-28 02:14:30 +0100180 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
181 {
182#if defined(MBEDTLS_ECDSA_C)
183 sig_alg_len += 2;
184#endif
185#if defined(MBEDTLS_RSA_C)
186 sig_alg_len += 2;
187#endif
188 }
189
Simon Butcher0fc94e92015-09-28 20:52:04 +0100190 if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
Simon Butchered997662015-09-28 02:14:30 +0100191 {
192 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
193 return;
194 }
195
Paul Bakkerd3edc862013-03-20 16:07:17 +0100196 /*
197 * Prepare signature_algorithms extension (TLS 1.2)
198 */
Simon Butchered997662015-09-28 02:14:30 +0100199 sig_alg_len = 0;
200
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200201 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
202 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200204 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
205 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200206#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200207#if defined(MBEDTLS_RSA_C)
208 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
209 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200210#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200211 }
Paul Bakkerd3edc862013-03-20 16:07:17 +0100212
213 /*
214 * enum {
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200215 * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
216 * sha512(6), (255)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100217 * } HashAlgorithm;
218 *
219 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
220 * SignatureAlgorithm;
221 *
222 * struct {
223 * HashAlgorithm hash;
224 * SignatureAlgorithm signature;
225 * } SignatureAndHashAlgorithm;
226 *
227 * SignatureAndHashAlgorithm
228 * supported_signature_algorithms<2..2^16-2>;
229 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
231 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100232
233 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
234 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
235
236 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
237 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
238
Paul Bakkerd3edc862013-03-20 16:07:17 +0100239 *olen = 6 + sig_alg_len;
240}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
242 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100243
Manuel Pégourié-Gonnardf4721792015-09-15 10:53:51 +0200244#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +0100245 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100247 unsigned char *buf,
248 size_t *olen )
249{
250 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100251 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard8e205fc2014-01-23 17:27:10 +0100252 unsigned char *elliptic_curve_list = p + 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100253 size_t elliptic_curve_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 const mbedtls_ecp_curve_info *info;
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200255#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 const mbedtls_ecp_group_id *grp_id;
Paul Bakker0910f322014-02-06 13:41:18 +0100257#else
258 ((void) ssl);
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100259#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100260
261 *olen = 0;
262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100264
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200265#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200266 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200267 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100269#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100271 {
272#endif
Simon Butchered997662015-09-28 02:14:30 +0100273 elliptic_curve_len += 2;
274 }
275
Simon Butcher0fc94e92015-09-28 20:52:04 +0100276 if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
Simon Butchered997662015-09-28 02:14:30 +0100277 {
278 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
279 return;
280 }
281
282 elliptic_curve_len = 0;
283
284#if defined(MBEDTLS_ECP_C)
285 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
286 {
287 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
288#else
289 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
290 {
291#endif
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100292
293 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
294 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200295 }
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200296
297 if( elliptic_curve_len == 0 )
298 return;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
301 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100302
303 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
304 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
305
306 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
307 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
308
Paul Bakkerd3edc862013-03-20 16:07:17 +0100309 *olen = 6 + elliptic_curve_len;
310}
311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100313 unsigned char *buf,
314 size_t *olen )
315{
316 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100317 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100318
319 *olen = 0;
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100322
Simon Butcher0fc94e92015-09-28 20:52:04 +0100323 if( end < p || (size_t)( end - p ) < 6 )
Simon Butchered997662015-09-28 02:14:30 +0100324 {
325 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
326 return;
327 }
328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
330 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100331
332 *p++ = 0x00;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100333 *p++ = 2;
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200334
335 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100337
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200338 *olen = 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100339}
Robert Cragieae8535d2015-10-06 17:11:18 +0100340#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
341 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100342
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200343#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200344static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
345 unsigned char *buf,
346 size_t *olen )
347{
348 int ret;
349 unsigned char *p = buf;
Robert Cragie39a60de2015-10-02 13:57:59 +0100350 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200351 size_t kkpp_len;
352
353 *olen = 0;
354
355 /* Skip costly extension if we can't use EC J-PAKE anyway */
356 if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
357 return;
358
359 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
360
361 if( end - p < 4 )
362 {
363 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
364 return;
365 }
366
367 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
368 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
369
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200370 /*
371 * We may need to send ClientHello multiple times for Hello verification.
372 * We don't want to compute fresh values every time (both for performance
373 * and consistency reasons), so cache the extension content.
374 */
375 if( ssl->handshake->ecjpake_cache == NULL ||
376 ssl->handshake->ecjpake_cache_len == 0 )
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200377 {
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200378 MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
379
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +0200380 ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
381 p + 2, end - p - 2, &kkpp_len,
382 ssl->conf->f_rng, ssl->conf->p_rng );
383 if( ret != 0 )
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200384 {
385 MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
386 return;
387 }
388
389 ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
390 if( ssl->handshake->ecjpake_cache == NULL )
391 {
392 MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
393 return;
394 }
395
396 memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
397 ssl->handshake->ecjpake_cache_len = kkpp_len;
398 }
399 else
400 {
401 MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
402
403 kkpp_len = ssl->handshake->ecjpake_cache_len;
404
405 if( (size_t)( end - p - 2 ) < kkpp_len )
406 {
407 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
408 return;
409 }
410
411 memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200412 }
413
414 *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
415 *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
416
417 *olen = kkpp_len + 4;
418}
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200419#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
422static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200423 unsigned char *buf,
424 size_t *olen )
425{
426 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100427 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200428
Simon Butcher0fc94e92015-09-28 20:52:04 +0100429 *olen = 0;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200430
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200431 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200432 return;
433 }
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200436
Simon Butcher0fc94e92015-09-28 20:52:04 +0100437 if( end < p || (size_t)( end - p ) < 5 )
Simon Butchered997662015-09-28 02:14:30 +0100438 {
439 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
440 return;
441 }
442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
444 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200445
446 *p++ = 0x00;
447 *p++ = 1;
448
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200449 *p++ = ssl->conf->mfl_code;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200450
451 *olen = 5;
452}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
456static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200457 unsigned char *buf, size_t *olen )
458{
459 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100460 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200461
Simon Butcher0fc94e92015-09-28 20:52:04 +0100462 *olen = 0;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200463
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200464 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200465 {
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200466 return;
467 }
468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200470
Simon Butcher0fc94e92015-09-28 20:52:04 +0100471 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100472 {
473 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
474 return;
475 }
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
478 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200479
480 *p++ = 0x00;
481 *p++ = 0x00;
482
483 *olen = 4;
484}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
488static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100489 unsigned char *buf, size_t *olen )
490{
491 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100492 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100493
Simon Butcher0fc94e92015-09-28 20:52:04 +0100494 *olen = 0;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100495
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200496 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
497 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100498 {
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100499 return;
500 }
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100503 "extension" ) );
504
Simon Butcher0fc94e92015-09-28 20:52:04 +0100505 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100506 {
507 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
508 return;
509 }
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
512 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100513
514 *p++ = 0x00;
515 *p++ = 0x00;
516
517 *olen = 4;
518}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
522static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200523 unsigned char *buf, size_t *olen )
524{
525 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100526 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200527
Simon Butcher0fc94e92015-09-28 20:52:04 +0100528 *olen = 0;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200529
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200530 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
531 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200532 {
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200533 return;
534 }
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200537 "extension" ) );
538
Simon Butcher0fc94e92015-09-28 20:52:04 +0100539 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100540 {
541 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
542 return;
543 }
544
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
546 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200547
548 *p++ = 0x00;
549 *p++ = 0x00;
550
551 *olen = 4;
552}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200554
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555#if defined(MBEDTLS_SSL_SESSION_TICKETS)
556static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200557 unsigned char *buf, size_t *olen )
558{
559 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100560 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200561 size_t tlen = ssl->session_negotiate->ticket_len;
562
Simon Butcher0fc94e92015-09-28 20:52:04 +0100563 *olen = 0;
564
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200565 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200566 {
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200567 return;
568 }
569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200571
Simon Butcher0fc94e92015-09-28 20:52:04 +0100572 if( end < p || (size_t)( end - p ) < 4 + tlen )
Simon Butchered997662015-09-28 02:14:30 +0100573 {
574 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
575 return;
576 }
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
579 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200580
581 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
582 *p++ = (unsigned char)( ( tlen ) & 0xFF );
583
584 *olen = 4;
585
Simon Butchered997662015-09-28 02:14:30 +0100586 if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200587 {
588 return;
589 }
590
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200592
593 memcpy( p, ssl->session_negotiate->ticket, tlen );
594
595 *olen += tlen;
596}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200598
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599#if defined(MBEDTLS_SSL_ALPN)
600static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200601 unsigned char *buf, size_t *olen )
602{
603 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100604 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
605 size_t alpnlen = 0;
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200606 const char **cur;
607
Simon Butcher0fc94e92015-09-28 20:52:04 +0100608 *olen = 0;
609
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200610 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200611 {
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200612 return;
613 }
614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200616
Simon Butchered997662015-09-28 02:14:30 +0100617 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
Simon Butcher04799a42015-09-29 00:31:09 +0100618 alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
Simon Butchered997662015-09-28 02:14:30 +0100619
Simon Butcher0fc94e92015-09-28 20:52:04 +0100620 if( end < p || (size_t)( end - p ) < 6 + alpnlen )
Simon Butchered997662015-09-28 02:14:30 +0100621 {
622 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
623 return;
624 }
625
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
627 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200628
629 /*
630 * opaque ProtocolName<1..2^8-1>;
631 *
632 * struct {
633 * ProtocolName protocol_name_list<2..2^16-1>
634 * } ProtocolNameList;
635 */
636
637 /* Skip writing extension and list length for now */
638 p += 4;
639
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200640 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200641 {
642 *p = (unsigned char)( strlen( *cur ) & 0xFF );
643 memcpy( p + 1, *cur, *p );
644 p += 1 + *p;
645 }
646
647 *olen = p - buf;
648
649 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
650 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
651 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
652
653 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
654 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
655 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
656}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200658
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200659/*
660 * Generate random bytes for ClientHello
661 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662static int ssl_generate_random( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200663{
664 int ret;
665 unsigned char *p = ssl->handshake->randbytes;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200667 time_t t;
668#endif
669
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200670 /*
671 * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
672 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200674 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200675 ssl->handshake->verify_cookie != NULL )
676 {
677 return( 0 );
678 }
679#endif
680
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200682 t = time( NULL );
683 *p++ = (unsigned char)( t >> 24 );
684 *p++ = (unsigned char)( t >> 16 );
685 *p++ = (unsigned char)( t >> 8 );
686 *p++ = (unsigned char)( t );
687
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200689#else
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100690 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200691 return( ret );
692
693 p += 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#endif /* MBEDTLS_HAVE_TIME */
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200695
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100696 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200697 return( ret );
698
699 return( 0 );
700}
701
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703{
Paul Bakker23986e52011-04-24 08:57:21 +0000704 int ret;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100705 size_t i, n, olen, ext_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706 unsigned char *buf;
Paul Bakker2fbefde2013-06-29 16:01:15 +0200707 unsigned char *p, *q;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200708 unsigned char offer_compress;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200709 const int *ciphersuites;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100714 if( ssl->conf->f_rng == NULL )
Paul Bakkera9a028e2013-11-21 17:31:06 +0100715 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
717 return( MBEDTLS_ERR_SSL_NO_RNG );
Paul Bakkera9a028e2013-11-21 17:31:06 +0100718 }
719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720#if defined(MBEDTLS_SSL_RENEGOTIATION)
721 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100722#endif
Paul Bakker48916f92012-09-16 19:57:18 +0000723 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200724 ssl->major_ver = ssl->conf->min_major_ver;
725 ssl->minor_ver = ssl->conf->min_minor_ver;
Paul Bakker48916f92012-09-16 19:57:18 +0000726 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200728 if( ssl->conf->max_major_ver == 0 )
Paul Bakker490ecc82011-10-06 13:04:09 +0000729 {
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200730 MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
731 "consider using mbedtls_ssl_config_defaults()" ) );
732 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker490ecc82011-10-06 13:04:09 +0000733 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
735 /*
736 * 0 . 0 handshake type
737 * 1 . 3 handshake length
738 * 4 . 5 highest version supported
739 * 6 . 9 current UNIX time
740 * 10 . 37 random bytes
741 */
742 buf = ssl->out_msg;
743 p = buf + 4;
744
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200745 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
746 ssl->conf->transport, p );
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +0100747 p += 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 buf[4], buf[5] ) );
751
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200752 if( ( ret = ssl_generate_random( ssl ) ) != 0 )
753 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200755 return( ret );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200756 }
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200757
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200758 memcpy( p, ssl->handshake->randbytes, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200760 p += 32;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
762 /*
763 * 38 . 38 session id length
764 * 39 . 39+n session id
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100765 * 39+n . 39+n DTLS only: cookie length (1 byte)
766 * 40+n . .. DTSL only: cookie
767 * .. . .. ciphersuitelist length (2 bytes)
768 * .. . .. ciphersuitelist
769 * .. . .. compression methods length (1 byte)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000770 * .. . .. compression methods
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100771 * .. . .. extensions length (2 bytes)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000772 * .. . .. extensions
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 */
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200774 n = ssl->session_negotiate->id_len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100776 if( n < 16 || n > 32 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#if defined(MBEDTLS_SSL_RENEGOTIATION)
778 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100779#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000780 ssl->handshake->resume == 0 )
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200781 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 n = 0;
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200783 }
784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200786 /*
787 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
788 * generate and include a Session ID in the TLS ClientHello."
789 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SSL_RENEGOTIATION)
791 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000792#endif
Manuel Pégourié-Gonnardd2b35ec2015-03-10 11:40:43 +0000793 {
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000794 if( ssl->session_negotiate->ticket != NULL &&
795 ssl->session_negotiate->ticket_len != 0 )
796 {
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100797 ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200798
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000799 if( ret != 0 )
800 return( ret );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200801
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200802 ssl->session_negotiate->id_len = n = 32;
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000803 }
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200804 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
807 *p++ = (unsigned char) n;
808
809 for( i = 0; i < n; i++ )
Paul Bakker48916f92012-09-16 19:57:18 +0000810 *p++ = ssl->session_negotiate->id[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
813 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000814
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100815 /*
816 * DTLS cookie
817 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200819 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100820 {
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200821 if( ssl->handshake->verify_cookie == NULL )
822 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200824 *p++ = 0;
825 }
826 else
827 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200829 ssl->handshake->verify_cookie,
830 ssl->handshake->verify_cookie_len );
831
832 *p++ = ssl->handshake->verify_cookie_len;
833 memcpy( p, ssl->handshake->verify_cookie,
834 ssl->handshake->verify_cookie_len );
835 p += ssl->handshake->verify_cookie_len;
836 }
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100837 }
838#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Paul Bakker48916f92012-09-16 19:57:18 +0000840 /*
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100841 * Ciphersuite list
Paul Bakker48916f92012-09-16 19:57:18 +0000842 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200843 ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100844
845 /* Skip writing ciphersuite length for now */
846 n = 0;
847 q = p;
848 p += 2;
849
Paul Bakker2fbefde2013-06-29 16:01:15 +0200850 for( i = 0; ciphersuites[i] != 0; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200853
854 if( ciphersuite_info == NULL )
855 continue;
856
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200857 if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
858 ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
Paul Bakker2fbefde2013-06-29 16:01:15 +0200859 continue;
860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200862 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
Manuel Pégourié-Gonnardd6664512014-02-06 13:26:57 +0100864 continue;
865#endif
866
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200867#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200868 if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100870 continue;
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200871#endif
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100872
Manuel Pégourié-Gonnardddf97a62015-09-16 09:58:31 +0200873#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
874 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
875 mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
876 continue;
877#endif
878
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +0200879 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
880 ciphersuites[i] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Paul Bakker2fbefde2013-06-29 16:01:15 +0200882 n++;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200883 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
884 *p++ = (unsigned char)( ciphersuites[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 }
886
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000887 /*
888 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
889 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890#if defined(MBEDTLS_SSL_RENEGOTIATION)
891 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000892#endif
893 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
895 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000896 n++;
897 }
898
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200899 /* Some versions of OpenSSL don't handle it correctly if not at end */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
Manuel Pégourié-Gonnard684b0592015-05-06 09:27:31 +0100901 if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200902 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
904 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
905 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200906 n++;
907 }
908#endif
909
Paul Bakker2fbefde2013-06-29 16:01:15 +0200910 *q++ = (unsigned char)( n >> 7 );
911 *q++ = (unsigned char)( n << 1 );
912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200916 offer_compress = 1;
Paul Bakker2770fbd2012-07-03 13:30:23 +0000917#else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200918 offer_compress = 0;
919#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200921 /*
922 * We don't support compression with DTLS right now: is many records come
923 * in the same datagram, uncompressing one could overwrite the next one.
924 * We don't want to add complexity for handling that case unless there is
925 * an actual need for it.
926 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200928 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200929 offer_compress = 0;
930#endif
931
932 if( offer_compress )
933 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
935 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
936 MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200937
938 *p++ = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
940 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200941 }
942 else
943 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
945 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
946 MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200947
948 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200950 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakkerd3edc862013-03-20 16:07:17 +0100952 // First write extensions, then the total length
953 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100955 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
956 ext_len += olen;
Paul Bakker0be444a2013-08-27 21:55:01 +0200957#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100960 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
961 ext_len += olen;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100962#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
965 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100966 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
967 ext_len += olen;
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200968#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000969
Manuel Pégourié-Gonnardf4721792015-09-15 10:53:51 +0200970#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +0100971 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100972 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
973 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100974
Paul Bakkerd3edc862013-03-20 16:07:17 +0100975 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
976 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100977#endif
978
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200979#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200980 ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
981 ext_len += olen;
982#endif
983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200985 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
986 ext_len += olen;
Paul Bakker05decb22013-08-15 13:33:48 +0200987#endif
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200990 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
991 ext_len += olen;
Paul Bakker1f2bc622013-08-15 13:45:55 +0200992#endif
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100995 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
996 ext_len += olen;
997#endif
998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001000 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
1001 ext_len += olen;
1002#endif
1003
Simon Butcher5624ec82015-09-29 01:06:06 +01001004#if defined(MBEDTLS_SSL_ALPN)
1005 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001006 ext_len += olen;
Paul Bakkera503a632013-08-14 13:48:06 +02001007#endif
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001008
Simon Butcher5624ec82015-09-29 01:06:06 +01001009#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1010 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001011 ext_len += olen;
1012#endif
1013
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001014 /* olen unused if all extensions are disabled */
1015 ((void) olen);
1016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
Paul Bakkerc3f177a2012-04-11 16:11:49 +00001018 ext_len ) );
1019
Paul Bakkera7036632014-04-30 10:15:38 +02001020 if( ext_len > 0 )
1021 {
1022 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
1023 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
1024 p += ext_len;
1025 }
Paul Bakker41c83d32013-03-20 14:39:14 +01001026
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 ssl->out_msglen = p - buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
1029 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00001030
1031 ssl->state++;
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001034 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_ssl_send_flight_completed( ssl );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02001036#endif
1037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 return( ret );
1042 }
1043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
1046 return( 0 );
1047}
1048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +02001050 const unsigned char *buf,
Paul Bakker48916f92012-09-16 19:57:18 +00001051 size_t len )
1052{
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001053 int ret;
1054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_SSL_RENEGOTIATION)
1056 if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001057 {
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001058 /* Check verify-data in constant-time. The length OTOH is no secret */
Paul Bakker48916f92012-09-16 19:57:18 +00001059 if( len != 1 + ssl->verify_data_len * 2 ||
1060 buf[0] != ssl->verify_data_len * 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061 mbedtls_ssl_safer_memcmp( buf + 1,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001062 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001064 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001065 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001069 return( ret );
1070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001072 }
1073 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001074 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001076 {
1077 if( len != 1 || buf[0] != 0x00 )
1078 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001080
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001082 return( ret );
1083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001085 }
1086
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087 ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001088 }
Paul Bakker48916f92012-09-16 19:57:18 +00001089
1090 return( 0 );
1091}
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1094static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +02001095 const unsigned char *buf,
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001096 size_t len )
1097{
1098 /*
1099 * server should use the extension only if we did,
1100 * and if so the server's value should match ours (and len is always 1)
1101 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001102 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001103 len != 1 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001104 buf[0] != ssl->conf->mfl_code )
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001105 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001107 }
1108
1109 return( 0 );
1110}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Paul Bakker48916f92012-09-16 19:57:18 +00001112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1114static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001115 const unsigned char *buf,
1116 size_t len )
1117{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001118 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001119 len != 0 )
1120 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001122 }
1123
1124 ((void) buf);
1125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126 ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001127
1128 return( 0 );
1129}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001130#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1133static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001134 const unsigned char *buf,
1135 size_t len )
1136{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001137 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001139 len != 0 )
1140 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001142 }
1143
1144 ((void) buf);
1145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146 ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001147
1148 return( 0 );
1149}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001150#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1153static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001154 const unsigned char *buf,
1155 size_t len )
1156{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001157 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001159 len != 0 )
1160 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001162 }
1163
1164 ((void) buf);
1165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001167
1168 return( 0 );
1169}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1173static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001174 const unsigned char *buf,
1175 size_t len )
1176{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001177 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001178 len != 0 )
1179 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001181 }
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001182
1183 ((void) buf);
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02001184
1185 ssl->handshake->new_session_ticket = 1;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001186
1187 return( 0 );
1188}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001190
Robert Cragie136884c2015-10-02 13:34:31 +01001191#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +01001192 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001194 const unsigned char *buf,
1195 size_t len )
1196{
1197 size_t list_size;
1198 const unsigned char *p;
1199
1200 list_size = buf[0];
1201 if( list_size + 1 != len )
1202 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1204 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001205 }
1206
Manuel Pégourié-Gonnardfd35af12014-06-23 14:10:13 +02001207 p = buf + 1;
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001208 while( list_size > 0 )
1209 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210 if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
1211 p[0] == MBEDTLS_ECP_PF_COMPRESSED )
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001212 {
Robert Cragie136884c2015-10-02 13:34:31 +01001213#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5734b2d2013-08-15 19:04:02 +02001214 ssl->handshake->ecdh_ctx.point_format = p[0];
Robert Cragie136884c2015-10-02 13:34:31 +01001215#endif
Robert Cragieae8535d2015-10-06 17:11:18 +01001216#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Robert Cragie136884c2015-10-02 13:34:31 +01001217 ssl->handshake->ecjpake_ctx.point_format = p[0];
1218#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219 MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001220 return( 0 );
1221 }
1222
1223 list_size--;
1224 p++;
1225 }
1226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001227 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
1228 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001229}
Robert Cragieae8535d2015-10-06 17:11:18 +01001230#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
1231 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001232
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001233#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1234static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
1235 const unsigned char *buf,
1236 size_t len )
1237{
1238 int ret;
1239
1240 if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
1241 MBEDTLS_KEY_EXCHANGE_ECJPAKE )
1242 {
1243 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
1244 return( 0 );
1245 }
1246
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +02001247 /* If we got here, we no longer need our cached extension */
1248 mbedtls_free( ssl->handshake->ecjpake_cache );
1249 ssl->handshake->ecjpake_cache = NULL;
1250 ssl->handshake->ecjpake_cache_len = 0;
1251
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001252 if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
1253 buf, len ) ) != 0 )
1254 {
1255 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
1256 return( ret );
1257 }
1258
1259 return( 0 );
1260}
1261#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263#if defined(MBEDTLS_SSL_ALPN)
1264static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001265 const unsigned char *buf, size_t len )
1266{
1267 size_t list_len, name_len;
1268 const char **p;
1269
1270 /* If we didn't send it, the server shouldn't send it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001271 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001273
1274 /*
1275 * opaque ProtocolName<1..2^8-1>;
1276 *
1277 * struct {
1278 * ProtocolName protocol_name_list<2..2^16-1>
1279 * } ProtocolNameList;
1280 *
1281 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
1282 */
1283
1284 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
1285 if( len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001287
1288 list_len = ( buf[0] << 8 ) | buf[1];
1289 if( list_len != len - 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001291
1292 name_len = buf[2];
1293 if( name_len != list_len - 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001295
1296 /* Check that the server chosen protocol was in our list and save it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001297 for( p = ssl->conf->alpn_list; *p != NULL; p++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001298 {
1299 if( name_len == strlen( *p ) &&
1300 memcmp( buf + 3, *p, name_len ) == 0 )
1301 {
1302 ssl->alpn_chosen = *p;
1303 return( 0 );
1304 }
1305 }
1306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001308}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001309#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001310
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001311/*
1312 * Parse HelloVerifyRequest. Only called after verifying the HS type.
1313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001314#if defined(MBEDTLS_SSL_PROTO_DTLS)
1315static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001316{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001318 int major_ver, minor_ver;
1319 unsigned char cookie_len;
1320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001322
1323 /*
1324 * struct {
1325 * ProtocolVersion server_version;
1326 * opaque cookie<0..2^8-1>;
1327 * } HelloVerifyRequest;
1328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001330 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001331 p += 2;
1332
Manuel Pégourié-Gonnardb35fe562014-08-09 17:00:46 +02001333 /*
1334 * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
1335 * even is lower than our min version.
1336 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337 if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
1338 minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001339 major_ver > ssl->conf->max_major_ver ||
1340 minor_ver > ssl->conf->max_minor_ver )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001341 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001342 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1345 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001348 }
1349
1350 cookie_len = *p++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351 MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001354
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02001355 ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001356 if( ssl->handshake->verify_cookie == NULL )
1357 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02001358 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02001359 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001360 }
1361
1362 memcpy( ssl->handshake->verify_cookie, p, cookie_len );
1363 ssl->handshake->verify_cookie_len = cookie_len;
1364
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02001365 /* Start over at ClientHello */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001366 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
1367 mbedtls_ssl_reset_checksum( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001371 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001372
1373 return( 0 );
1374}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00001378{
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001379 int ret, i;
Paul Bakker23986e52011-04-24 08:57:21 +00001380 size_t n;
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001381 size_t ext_len;
Paul Bakker48916f92012-09-16 19:57:18 +00001382 unsigned char *buf, *ext;
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001383 unsigned char comp;
1384#if defined(MBEDTLS_ZLIB_SUPPORT)
1385 int accept_comp;
1386#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001387#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001388 int renegotiation_info_seen = 0;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001389#endif
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001390 int handshake_failure = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001391 const mbedtls_ssl_ciphersuite_t *suite_info;
1392#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001393 uint32_t t;
1394#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001396 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001397
Paul Bakker5121ce52009-01-03 21:22:43 +00001398 buf = ssl->in_msg;
1399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001401 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001403 return( ret );
1404 }
1405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001407 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408#if defined(MBEDTLS_SSL_RENEGOTIATION)
1409 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001410 {
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001411 ssl->renego_records_seen++;
1412
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001413 if( ssl->conf->renego_max_records >= 0 &&
1414 ssl->renego_records_seen > ssl->conf->renego_max_records )
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001415 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001417 "but not honored by server" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001419 }
1420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001421 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
1422 return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001423 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1427 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001428 }
1429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001431 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001432 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433 if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
1436 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001437 return( ssl_parse_hello_verify_request( ssl ) );
1438 }
1439 else
1440 {
1441 /* We made it through the verification process */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001443 ssl->handshake->verify_cookie = NULL;
1444 ssl->handshake->verify_cookie_len = 0;
1445 }
1446 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00001448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449 if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
1450 buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
Paul Bakker5121ce52009-01-03 21:22:43 +00001451 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1453 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001454 }
1455
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001456 /*
1457 * 0 . 1 server_version
1458 * 2 . 33 random (maybe including 4 bytes of Unix time)
1459 * 34 . 34 session_id length = n
1460 * 35 . 34+n session_id
1461 * 35+n . 36+n cipher_suite
1462 * 37+n . 37+n compression_method
1463 *
1464 * 38+n . 39+n extensions length (optional)
1465 * 40+n . .. extensions
1466 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 buf += mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
1470 mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001471 ssl->conf->transport, buf + 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001472
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001473 if( ssl->major_ver < ssl->conf->min_major_ver ||
1474 ssl->minor_ver < ssl->conf->min_minor_ver ||
1475 ssl->major_ver > ssl->conf->max_major_ver ||
1476 ssl->minor_ver > ssl->conf->max_minor_ver )
Paul Bakker1d29fb52012-09-28 13:28:45 +00001477 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001479 " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001480 ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001481 ssl->major_ver, ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001482 ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1485 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001488 }
1489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001491 t = ( (uint32_t) buf[2] << 24 )
1492 | ( (uint32_t) buf[3] << 16 )
1493 | ( (uint32_t) buf[4] << 8 )
1494 | ( (uint32_t) buf[5] );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
Paul Bakker87e5cda2012-01-14 18:14:15 +00001496#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001497
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001498 memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001499
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001500 n = buf[34];
Paul Bakker5121ce52009-01-03 21:22:43 +00001501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001503
Paul Bakker48916f92012-09-16 19:57:18 +00001504 if( n > 32 )
1505 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1507 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001508 }
1509
Manuel Pégourié-Gonnarda6e5bd52015-07-23 12:14:13 +02001510 if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
Paul Bakker5121ce52009-01-03 21:22:43 +00001511 {
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001512 ext_len = ( ( buf[38 + n] << 8 )
1513 | ( buf[39 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001514
Paul Bakker48916f92012-09-16 19:57:18 +00001515 if( ( ext_len > 0 && ext_len < 4 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
Paul Bakker48916f92012-09-16 19:57:18 +00001517 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1519 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001520 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001521 }
Manuel Pégourié-Gonnarda6e5bd52015-07-23 12:14:13 +02001522 else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001523 {
1524 ext_len = 0;
1525 }
1526 else
1527 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1529 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001530 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001531
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001532 /* ciphersuite (used later) */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001533 i = ( buf[35 + n] << 8 ) | buf[36 + n];
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001534
1535 /*
1536 * Read and check compression
1537 */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001538 comp = buf[37 + n];
Paul Bakker5121ce52009-01-03 21:22:43 +00001539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001541 /* See comments in ssl_write_client_hello() */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001543 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001544 accept_comp = 0;
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001545 else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001546#endif
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001547 accept_comp = 1;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001548
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001549 if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
1550 ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
1551#else /* MBEDTLS_ZLIB_SUPPORT */
1552 if( comp != MBEDTLS_SSL_COMPRESS_NULL )
1553#endif/* MBEDTLS_ZLIB_SUPPORT */
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001554 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001555 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
1556 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001557 }
1558
Paul Bakker380da532012-04-18 16:10:25 +00001559 /*
1560 * Initialize update checksum functions
1561 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001562 ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
Paul Bakker68884e32013-01-07 18:20:04 +01001563
1564 if( ssl->transform_negotiate->ciphersuite_info == NULL )
1565 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
1567 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker68884e32013-01-07 18:20:04 +01001568 }
Paul Bakker380da532012-04-18 16:10:25 +00001569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
Manuel Pégourié-Gonnard3c599f12014-03-10 13:25:07 +01001571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001572 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
1573 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001574
1575 /*
1576 * Check if the session can be resumed
1577 */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001578 if( ssl->handshake->resume == 0 || n == 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579#if defined(MBEDTLS_SSL_RENEGOTIATION)
1580 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001581#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001582 ssl->session_negotiate->ciphersuite != i ||
1583 ssl->session_negotiate->compression != comp ||
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001584 ssl->session_negotiate->id_len != n ||
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001585 memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 {
1587 ssl->state++;
Paul Bakker0a597072012-09-25 21:55:46 +00001588 ssl->handshake->resume = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker48916f92012-09-16 19:57:18 +00001590 ssl->session_negotiate->start = time( NULL );
Paul Bakkerfa9b1002013-07-03 15:31:03 +02001591#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001592 ssl->session_negotiate->ciphersuite = i;
1593 ssl->session_negotiate->compression = comp;
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001594 ssl->session_negotiate->id_len = n;
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001595 memcpy( ssl->session_negotiate->id, buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001596 }
1597 else
1598 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001599 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001601 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001602 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001603 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001604 return( ret );
1605 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001606 }
1607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001608 MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
Paul Bakker0a597072012-09-25 21:55:46 +00001609 ssl->handshake->resume ? "a" : "no" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001610
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +02001611 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614 suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02001615 if( suite_info == NULL
1616#if defined(MBEDTLS_ARC4_C)
1617 || ( ssl->conf->arc4_disabled &&
1618 suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
1619#endif
1620 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001621 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001622 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1623 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001624 }
1625
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +02001626 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
1627
Paul Bakker5121ce52009-01-03 21:22:43 +00001628 i = 0;
1629 while( 1 )
1630 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001631 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001632 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001633 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1634 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001635 }
1636
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001637 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001638 ssl->session_negotiate->ciphersuite )
1639 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001640 break;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001641 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001642 }
1643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001644 if( comp != MBEDTLS_SSL_COMPRESS_NULL
1645#if defined(MBEDTLS_ZLIB_SUPPORT)
1646 && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
Paul Bakker2770fbd2012-07-03 13:30:23 +00001647#endif
1648 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001649 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001650 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1651 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001652 }
Paul Bakker48916f92012-09-16 19:57:18 +00001653 ssl->session_negotiate->compression = comp;
Paul Bakker5121ce52009-01-03 21:22:43 +00001654
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001655 ext = buf + 40 + n;
Paul Bakker48916f92012-09-16 19:57:18 +00001656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001657 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +02001658
Paul Bakker48916f92012-09-16 19:57:18 +00001659 while( ext_len )
1660 {
1661 unsigned int ext_id = ( ( ext[0] << 8 )
1662 | ( ext[1] ) );
1663 unsigned int ext_size = ( ( ext[2] << 8 )
1664 | ( ext[3] ) );
1665
1666 if( ext_size + 4 > ext_len )
1667 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001668 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1669 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001670 }
1671
1672 switch( ext_id )
1673 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001674 case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1675 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
1676#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001677 renegotiation_info_seen = 1;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001678#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001679
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001680 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
1681 ext_size ) ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001682 return( ret );
1683
1684 break;
1685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1687 case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1688 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001689
1690 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
1691 ext + 4, ext_size ) ) != 0 )
1692 {
1693 return( ret );
1694 }
1695
1696 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001697#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001698
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1700 case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
1701 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001702
1703 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
1704 ext + 4, ext_size ) ) != 0 )
1705 {
1706 return( ret );
1707 }
1708
1709 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001710#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001712#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1713 case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1714 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001715
1716 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
1717 ext + 4, ext_size ) ) != 0 )
1718 {
1719 return( ret );
1720 }
1721
1722 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001723#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001725#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1726 case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1727 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001728
1729 if( ( ret = ssl_parse_extended_ms_ext( ssl,
1730 ext + 4, ext_size ) ) != 0 )
1731 {
1732 return( ret );
1733 }
1734
1735 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001738#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1739 case MBEDTLS_TLS_EXT_SESSION_TICKET:
1740 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001741
1742 if( ( ret = ssl_parse_session_ticket_ext( ssl,
1743 ext + 4, ext_size ) ) != 0 )
1744 {
1745 return( ret );
1746 }
1747
1748 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001750
Robert Cragie136884c2015-10-02 13:34:31 +01001751#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +01001752 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753 case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1754 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001755
1756 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
1757 ext + 4, ext_size ) ) != 0 )
1758 {
1759 return( ret );
1760 }
1761
1762 break;
Robert Cragieae8535d2015-10-06 17:11:18 +01001763#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
1764 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001765
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001766#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1767 case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
1768 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
1769
1770 if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
1771 ext + 4, ext_size ) ) != 0 )
1772 {
1773 return( ret );
1774 }
1775
1776 break;
1777#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779#if defined(MBEDTLS_SSL_ALPN)
1780 case MBEDTLS_TLS_EXT_ALPN:
1781 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001782
1783 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
1784 return( ret );
1785
1786 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001788
Paul Bakker48916f92012-09-16 19:57:18 +00001789 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001790 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
Paul Bakker48916f92012-09-16 19:57:18 +00001791 ext_id ) );
1792 }
1793
1794 ext_len -= 4 + ext_size;
1795 ext += 4 + ext_size;
1796
1797 if( ext_len > 0 && ext_len < 4 )
1798 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1800 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001801 }
1802 }
1803
1804 /*
1805 * Renegotiation security checks
1806 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001807 if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001808 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001809 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001810 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001811 handshake_failure = 1;
Paul Bakkerf7abd422013-04-16 13:15:56 +02001812 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001813#if defined(MBEDTLS_SSL_RENEGOTIATION)
1814 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1815 ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001816 renegotiation_info_seen == 0 )
1817 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001818 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001819 handshake_failure = 1;
Paul Bakker48916f92012-09-16 19:57:18 +00001820 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001821 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1822 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001823 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
Paul Bakker48916f92012-09-16 19:57:18 +00001824 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001826 handshake_failure = 1;
1827 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1829 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001830 renegotiation_info_seen == 1 )
1831 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001833 handshake_failure = 1;
1834 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001836
1837 if( handshake_failure == 1 )
1838 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001840 return( ret );
1841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001843 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 return( 0 );
1848}
1849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1851 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1852static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
Paul Bakker29e1f122013-04-16 13:07:56 +02001853 unsigned char *end )
1854{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001856
Paul Bakker29e1f122013-04-16 13:07:56 +02001857 /*
1858 * Ephemeral DH parameters:
1859 *
1860 * struct {
1861 * opaque dh_p<1..2^16-1>;
1862 * opaque dh_g<1..2^16-1>;
1863 * opaque dh_Ys<1..2^16-1>;
1864 * } ServerDHParams;
1865 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001867 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001869 return( ret );
1870 }
1871
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001872 if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
Paul Bakker29e1f122013-04-16 13:07:56 +02001873 {
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001874 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
1875 ssl->handshake->dhm_ctx.len * 8,
1876 ssl->conf->dhm_min_bitlen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001878 }
1879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
1881 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
1882 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
Paul Bakker29e1f122013-04-16 13:07:56 +02001883
1884 return( ret );
1885}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1887 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001889#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1890 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1891 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
1892 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1893 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1894static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001896 const mbedtls_ecp_curve_info *curve_info;
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001897
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001899 if( curve_info == NULL )
1900 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1902 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001903 }
1904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001906
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02001907#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02001908 if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001909#else
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001910 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
1911 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001912#endif
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001913 return( -1 );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001915 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001916
1917 return( 0 );
1918}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1920 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1921 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
1922 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1923 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001925#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1926 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1927 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
1928static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001929 unsigned char **p,
1930 unsigned char *end )
1931{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001933
Paul Bakker29e1f122013-04-16 13:07:56 +02001934 /*
1935 * Ephemeral ECDH parameters:
1936 *
1937 * struct {
1938 * ECParameters curve_params;
1939 * ECPoint public;
1940 * } ServerECDHParams;
1941 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001942 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
Paul Bakker29e1f122013-04-16 13:07:56 +02001943 (const unsigned char **) p, end ) ) != 0 )
1944 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001946 return( ret );
1947 }
1948
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001949 if( ssl_check_server_ecdh_params( ssl ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001950 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
1952 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001953 }
1954
Paul Bakker29e1f122013-04-16 13:07:56 +02001955 return( ret );
1956}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1958 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1959 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001961#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1962static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001963 unsigned char **p,
1964 unsigned char *end )
1965{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001966 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001967 size_t len;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001968 ((void) ssl);
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001969
1970 /*
1971 * PSK parameters:
1972 *
1973 * opaque psk_identity_hint<0..2^16-1>;
1974 */
Manuel Pégourié-Gonnard59b9fe22013-10-15 11:55:33 +02001975 len = (*p)[0] << 8 | (*p)[1];
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001976 *p += 2;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001977
1978 if( (*p) + len > end )
1979 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
1981 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001982 }
1983
1984 // TODO: Retrieve PSK identity hint and callback to app
1985 //
1986 *p += len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001987 ret = 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001988
1989 return( ret );
1990}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
1994 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001995/*
1996 * Generate a pre-master secret and encrypt it with the server's RSA key
1997 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001999 size_t offset, size_t *olen,
2000 size_t pms_offset )
2001{
2002 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002004 unsigned char *p = ssl->handshake->premaster + pms_offset;
2005
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002006 if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN )
2007 {
2008 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
2009 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2010 }
2011
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002012 /*
2013 * Generate (part of) the pre-master as
2014 * struct {
2015 * ProtocolVersion client_version;
2016 * opaque random[46];
2017 * } PreMasterSecret;
2018 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002019 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
2020 ssl->conf->transport, p );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002021
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002022 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002023 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002024 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002025 return( ret );
2026 }
2027
2028 ssl->handshake->pmslen = 48;
2029
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002030 if( ssl->session_negotiate->peer_cert == NULL )
2031 {
2032 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2033 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2034 }
2035
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002036 /*
2037 * Now write it out, encrypted
2038 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2040 MBEDTLS_PK_RSA ) )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002041 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
2043 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002044 }
2045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002046 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002047 p, ssl->handshake->pmslen,
2048 ssl->out_msg + offset + len_bytes, olen,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002050 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002051 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002053 return( ret );
2054 }
2055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2057 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002058 if( len_bytes == 2 )
2059 {
2060 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
2061 ssl->out_msg[offset+1] = (unsigned char)( *olen );
2062 *olen += 2;
2063 }
2064#endif
2065
2066 return( 0 );
2067}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
2069 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02002070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002071#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02002072#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002073static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02002074 unsigned char **p,
2075 unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076 mbedtls_md_type_t *md_alg,
2077 mbedtls_pk_type_t *pk_alg )
Paul Bakker29e1f122013-04-16 13:07:56 +02002078{
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02002079 ((void) ssl);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002080 *md_alg = MBEDTLS_MD_NONE;
2081 *pk_alg = MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002082
2083 /* Only in TLS 1.2 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002084 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002085 {
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002086 return( 0 );
2087 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002088
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002089 if( (*p) + 2 > end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002090 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002091
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002092 /*
2093 * Get hash algorithm
2094 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002096 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002098 "HashAlgorithm %d", *(p)[0] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002100 }
2101
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002102 /*
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002103 * Get signature algorithm
2104 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002106 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002108 "SignatureAlgorithm %d", (*p)[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002109 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002110 }
2111
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02002112 /*
2113 * Check if the hash is acceptable
2114 */
2115 if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
2116 {
2117 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm "
2118 "that was not offered" ) );
2119 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2120 }
2121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002122 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
2123 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002124 *p += 2;
2125
2126 return( 0 );
2127}
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02002128#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002129#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2132 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2133static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002134{
2135 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002136 const mbedtls_ecp_keypair *peer_key;
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002137
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002138 if( ssl->session_negotiate->peer_cert == NULL )
2139 {
2140 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2141 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2142 }
2143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002144 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2145 MBEDTLS_PK_ECKEY ) )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002146 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002147 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
2148 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002149 }
2150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002152
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002153 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
2154 MBEDTLS_ECDH_THEIRS ) ) != 0 )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002155 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002156 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002157 return( ret );
2158 }
2159
2160 if( ssl_check_server_ecdh_params( ssl ) != 0 )
2161 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002162 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
2163 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002164 }
2165
2166 return( ret );
2167}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
2169 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002171static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker41c83d32013-03-20 14:39:14 +01002172{
Paul Bakker23986e52011-04-24 08:57:21 +00002173 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002174 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002175 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00002176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002177 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2180 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002181 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002183 ssl->state++;
2184 return( 0 );
2185 }
Manuel Pégourié-Gonnardbac0e3b2013-10-15 11:54:47 +02002186 ((void) p);
2187 ((void) end);
2188#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002190#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2191 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2192 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2193 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002194 {
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002195 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
2196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002198 return( ret );
2199 }
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002201 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002202 ssl->state++;
2203 return( 0 );
2204 }
2205 ((void) p);
2206 ((void) end);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002207#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2208 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002210 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002211 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002212 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002213 return( ret );
2214 }
2215
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002216 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002217 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002218 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2219 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 }
2221
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002222 /*
2223 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
2224 * doesn't use a psk_identity_hint
2225 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002226 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002227 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002228 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2229 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Paul Bakker188c8de2013-04-19 09:13:37 +02002230 {
2231 ssl->record_read = 1;
2232 goto exit;
2233 }
2234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2236 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002237 }
2238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002239 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002240 end = ssl->in_msg + ssl->in_hslen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002241 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002243#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2244 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2245 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2246 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2247 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002248 {
2249 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
2250 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2252 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002253 }
2254 } /* FALLTROUGH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002255#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002257#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
2258 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2259 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2260 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002261 ; /* nothing more to do */
2262 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002263#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
2264 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2265#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2266 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2267 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2268 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker5121ce52009-01-03 21:22:43 +00002269 {
Paul Bakker29e1f122013-04-16 13:07:56 +02002270 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002271 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2273 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002274 }
2275 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002276 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2278 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2279#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2280 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
2281 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2282 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2283 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2284 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002285 {
2286 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
2287 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002288 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2289 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002290 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002291 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002292 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002293#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2294 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2295 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002296#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2297 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2298 {
2299 ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
2300 p, end - p );
2301 if( ret != 0 )
2302 {
2303 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
2304 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2305 }
2306 }
2307 else
2308#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakker41c83d32013-03-20 14:39:14 +01002309 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002310 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2311 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002312 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002314#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2315 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2316 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2317 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2318 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2319 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002320 {
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002321 size_t sig_len, hashlen;
2322 unsigned char hash[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002323 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2324 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2325 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002326 size_t params_len = p - params;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002327
Paul Bakker29e1f122013-04-16 13:07:56 +02002328 /*
2329 * Handle the digitally-signed structure
2330 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002331#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2332 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002333 {
Paul Bakker9659dae2013-08-28 16:21:34 +02002334 if( ssl_parse_signature_algorithm( ssl, &p, end,
2335 &md_alg, &pk_alg ) != 0 )
2336 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002337 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2338 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker9659dae2013-08-28 16:21:34 +02002339 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002340
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002341 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002342 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002343 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2344 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002345 }
2346 }
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002347 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002348#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2349#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2350 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2351 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002352 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002353 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002354
Paul Bakker9659dae2013-08-28 16:21:34 +02002355 /* Default hash for ECDSA is SHA-1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002356 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
2357 md_alg = MBEDTLS_MD_SHA1;
Paul Bakker9659dae2013-08-28 16:21:34 +02002358 }
2359 else
2360#endif
2361 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002362 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2363 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker9659dae2013-08-28 16:21:34 +02002364 }
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002365
2366 /*
2367 * Read signature
2368 */
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002369 sig_len = ( p[0] << 8 ) | p[1];
Paul Bakker1ef83d62012-04-11 12:09:53 +00002370 p += 2;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002371
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002372 if( end != p + sig_len )
Paul Bakker41c83d32013-03-20 14:39:14 +01002373 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002374 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2375 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002376 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002378 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002379
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002380 /*
2381 * Compute the hash that has been signed
2382 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002383#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2384 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2385 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002386 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002387 mbedtls_md5_context mbedtls_md5;
2388 mbedtls_sha1_context mbedtls_sha1;
Paul Bakker29e1f122013-04-16 13:07:56 +02002389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002390 mbedtls_md5_init( &mbedtls_md5 );
2391 mbedtls_sha1_init( &mbedtls_sha1 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002392
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002393 hashlen = 36;
2394
Paul Bakker29e1f122013-04-16 13:07:56 +02002395 /*
2396 * digitally-signed struct {
2397 * opaque md5_hash[16];
2398 * opaque sha_hash[20];
2399 * };
2400 *
2401 * md5_hash
2402 * MD5(ClientHello.random + ServerHello.random
2403 * + ServerParams);
2404 * sha_hash
2405 * SHA(ClientHello.random + ServerHello.random
2406 * + ServerParams);
2407 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002408 mbedtls_md5_starts( &mbedtls_md5 );
2409 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
2410 mbedtls_md5_update( &mbedtls_md5, params, params_len );
2411 mbedtls_md5_finish( &mbedtls_md5, hash );
Paul Bakker29e1f122013-04-16 13:07:56 +02002412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002413 mbedtls_sha1_starts( &mbedtls_sha1 );
2414 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
2415 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
2416 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002418 mbedtls_md5_free( &mbedtls_md5 );
2419 mbedtls_sha1_free( &mbedtls_sha1 );
Paul Bakker29e1f122013-04-16 13:07:56 +02002420 }
2421 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002422#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2423 MBEDTLS_SSL_PROTO_TLS1_1 */
2424#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2425 defined(MBEDTLS_SSL_PROTO_TLS1_2)
2426 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002427 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002428 mbedtls_md_context_t ctx;
Paul Bakker29e1f122013-04-16 13:07:56 +02002429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002430 mbedtls_md_init( &ctx );
Paul Bakker84bbeb52014-07-01 14:53:22 +02002431
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002432 /* Info from md_alg will be used instead */
2433 hashlen = 0;
Paul Bakker29e1f122013-04-16 13:07:56 +02002434
2435 /*
2436 * digitally-signed struct {
2437 * opaque client_random[32];
2438 * opaque server_random[32];
2439 * ServerDHParams params;
2440 * };
2441 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002442 if( ( ret = mbedtls_md_setup( &ctx,
2443 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02002444 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002445 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02002446 return( ret );
2447 }
2448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 mbedtls_md_starts( &ctx );
2450 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
2451 mbedtls_md_update( &ctx, params, params_len );
2452 mbedtls_md_finish( &ctx, hash );
2453 mbedtls_md_free( &ctx );
Paul Bakker29e1f122013-04-16 13:07:56 +02002454 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002455 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002456#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2457 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002458 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002459 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2460 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002461 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002463 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
2464 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002465
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002466 if( ssl->session_negotiate->peer_cert == NULL )
2467 {
2468 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2469 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2470 }
2471
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002472 /*
2473 * Verify signature
2474 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002475 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002476 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002477 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2478 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002479 }
2480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002481 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard20846b12013-08-19 12:32:12 +02002482 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002483 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002484 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002485 return( ret );
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002486 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002487 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002488#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2489 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2490 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002491
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002492exit:
Paul Bakker5121ce52009-01-03 21:22:43 +00002493 ssl->state++;
2494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002496
2497 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002498}
2499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002500#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2501 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2502 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2503 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2504static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002505{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002506 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002508 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002510 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2511 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2512 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002513 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2514 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002515 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002516 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002517 ssl->state++;
2518 return( 0 );
2519 }
2520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002521 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2522 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002523}
2524#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002525static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002526{
2527 int ret;
Paul Bakker926af752012-11-23 13:38:07 +01002528 unsigned char *buf, *p;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002529 size_t n = 0, m = 0;
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002530 size_t cert_type_len = 0, dn_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002531 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002533 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002534
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002535 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2536 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2537 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002538 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2539 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002540 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002541 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002542 ssl->state++;
2543 return( 0 );
2544 }
2545
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002546 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002547 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002548 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002549 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002550 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002551 return( ret );
2552 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002554 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002555 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002556 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2557 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002558 }
2559
2560 ssl->record_read = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002561 }
2562
2563 ssl->client_auth = 0;
2564 ssl->state++;
2565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002566 if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
Paul Bakker5121ce52009-01-03 21:22:43 +00002567 ssl->client_auth++;
2568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002569 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
Paul Bakker5121ce52009-01-03 21:22:43 +00002570 ssl->client_auth ? "a" : "no" ) );
2571
Paul Bakker926af752012-11-23 13:38:07 +01002572 if( ssl->client_auth == 0 )
2573 goto exit;
2574
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002575 ssl->record_read = 0;
2576
Paul Bakker926af752012-11-23 13:38:07 +01002577 // TODO: handshake_failure alert for an anonymous server to request
2578 // client authentication
2579
Manuel Pégourié-Gonnard04c1b4e2014-09-10 19:25:43 +02002580 /*
2581 * struct {
2582 * ClientCertificateType certificate_types<1..2^8-1>;
2583 * SignatureAndHashAlgorithm
2584 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2585 * DistinguishedName certificate_authorities<0..2^16-1>;
2586 * } CertificateRequest;
2587 */
Paul Bakker926af752012-11-23 13:38:07 +01002588 buf = ssl->in_msg;
Paul Bakkerf7abd422013-04-16 13:15:56 +02002589
Paul Bakker926af752012-11-23 13:38:07 +01002590 // Retrieve cert types
2591 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002592 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
Paul Bakker926af752012-11-23 13:38:07 +01002593 n = cert_type_len;
2594
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002595 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002596 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002597 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2598 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002599 }
2600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
Paul Bakker926af752012-11-23 13:38:07 +01002602 while( cert_type_len > 0 )
2603 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002604#if defined(MBEDTLS_RSA_C)
2605 if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
2606 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
Paul Bakker926af752012-11-23 13:38:07 +01002607 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002608 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
Paul Bakker926af752012-11-23 13:38:07 +01002609 break;
2610 }
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002611 else
2612#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002613#if defined(MBEDTLS_ECDSA_C)
2614 if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
2615 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002616 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002617 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002618 break;
2619 }
2620 else
2621#endif
2622 {
2623 ; /* Unsupported cert type, ignore */
2624 }
Paul Bakker926af752012-11-23 13:38:07 +01002625
2626 cert_type_len--;
2627 p++;
2628 }
2629
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002630#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2631 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002632 {
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002633 /* Ignored, see comments about hash in write_certificate_verify */
2634 // TODO: should check the signature part against our pk_key though
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002635 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
2636 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002637
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002638 m += 2;
Paul Bakker926af752012-11-23 13:38:07 +01002639 n += sig_alg_len;
2640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002641 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002642 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002643 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2644 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002645 }
Paul Bakkerf7abd422013-04-16 13:15:56 +02002646 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002647#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker926af752012-11-23 13:38:07 +01002648
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002649 /* Ignore certificate_authorities, we only have one cert anyway */
2650 // TODO: should not send cert if no CA matches
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002651 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
2652 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002653
2654 n += dn_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
Paul Bakker926af752012-11-23 13:38:07 +01002656 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002657 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2658 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002659 }
2660
2661exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002662 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002663
2664 return( 0 );
2665}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002666#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2667 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2668 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
2669 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002670
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002671static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002672{
2673 int ret;
2674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002675 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002676
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002677 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002678 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002679 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002680 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002681 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002682 return( ret );
2683 }
2684
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002685 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002686 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002687 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2688 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002689 }
2690 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002691 ssl->record_read = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002693 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
2694 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002695 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002696 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2697 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002698 }
2699
2700 ssl->state++;
2701
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002702#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002703 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002704 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002705#endif
2706
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002707 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002708
2709 return( 0 );
2710}
2711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002712static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002713{
Paul Bakker23986e52011-04-24 08:57:21 +00002714 int ret;
2715 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002716 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002717
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002718 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002720#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2721 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002722 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002723 /*
2724 * DHM key exchange -- send G^X mod P
2725 */
Paul Bakker48916f92012-09-16 19:57:18 +00002726 n = ssl->handshake->dhm_ctx.len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002727
2728 ssl->out_msg[4] = (unsigned char)( n >> 8 );
2729 ssl->out_msg[5] = (unsigned char)( n );
2730 i = 6;
2731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002732 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2733 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Paul Bakker5121ce52009-01-03 21:22:43 +00002734 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002735 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00002736 if( ret != 0 )
2737 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002738 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002739 return( ret );
2740 }
2741
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002742 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
2743 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
Paul Bakker5121ce52009-01-03 21:22:43 +00002744
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002745 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
Paul Bakker48916f92012-09-16 19:57:18 +00002746 ssl->handshake->premaster,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01002747 MBEDTLS_PREMASTER_SIZE,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +02002748 &ssl->handshake->pmslen,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002749 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002750 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002751 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002752 return( ret );
2753 }
2754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002755 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
Paul Bakker5121ce52009-01-03 21:22:43 +00002756 }
2757 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002758#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2759#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2760 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
2761 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2762 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2763 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2764 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2765 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2766 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Paul Bakker41c83d32013-03-20 14:39:14 +01002767 {
2768 /*
2769 * ECDH key exchange -- send client public value
2770 */
2771 i = 4;
2772
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002773 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002774 &n,
2775 &ssl->out_msg[i], 1000,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002776 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker41c83d32013-03-20 14:39:14 +01002777 if( ret != 0 )
2778 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002779 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002780 return( ret );
2781 }
2782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002783 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Paul Bakker41c83d32013-03-20 14:39:14 +01002784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002785 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002786 &ssl->handshake->pmslen,
2787 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002788 MBEDTLS_MPI_MAX_SIZE,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002789 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002790 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002791 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002792 return( ret );
2793 }
2794
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002795 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
Paul Bakker41c83d32013-03-20 14:39:14 +01002796 }
2797 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002798#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2799 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2800 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2801 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2802#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2803 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2804 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2805 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2806 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002807 {
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002808 /*
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002809 * opaque psk_identity<0..2^16-1>;
2810 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002811 if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002812 {
2813 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002814 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002815 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002816
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002817 i = 4;
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002818 n = ssl->conf->psk_identity_len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002819
2820 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2821 {
2822 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
2823 "SSL buffer too short" ) );
2824 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2825 }
2826
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002827 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2828 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002829
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002830 memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
2831 i += ssl->conf->psk_identity_len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002833#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
2834 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002835 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002836 n = 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002837 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002838 else
2839#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002840#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2841 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002842 {
2843 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
2844 return( ret );
2845 }
2846 else
2847#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002848#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2849 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002850 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002851 /*
2852 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
2853 */
2854 n = ssl->handshake->dhm_ctx.len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002855
2856 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2857 {
2858 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
2859 " or SSL buffer too short" ) );
2860 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2861 }
2862
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002863 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2864 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002866 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2867 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002868 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002869 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002870 if( ret != 0 )
2871 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002872 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002873 return( ret );
2874 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002875 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002876 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002877#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2878#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2879 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002880 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002881 /*
2882 * ClientECDiffieHellmanPublic public;
2883 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002884 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
2885 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002886 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002887 if( ret != 0 )
2888 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002889 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002890 return( ret );
2891 }
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002893 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002894 }
2895 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002896#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002897 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002898 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2899 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002900 }
2901
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002902 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002903 ciphersuite_info->key_exchange ) ) != 0 )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002904 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002905 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002906 return( ret );
2907 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002908 }
2909 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002910#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
2911#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2912 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002913 {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002914 i = 4;
2915 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
Paul Bakkera3d195c2011-11-27 21:07:34 +00002916 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002917 }
Paul Bakkered27a042013-04-18 22:46:23 +02002918 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002919#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002920#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2921 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2922 {
2923 i = 4;
2924
2925 ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
2926 ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
2927 ssl->conf->f_rng, ssl->conf->p_rng );
2928 if( ret != 0 )
2929 {
2930 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
2931 return( ret );
2932 }
2933
2934 ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
2935 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
2936 ssl->conf->f_rng, ssl->conf->p_rng );
2937 if( ret != 0 )
2938 {
2939 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
2940 return( ret );
2941 }
2942 }
2943 else
2944#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Paul Bakkered27a042013-04-18 22:46:23 +02002945 {
2946 ((void) ciphersuite_info);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002947 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2948 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkered27a042013-04-18 22:46:23 +02002949 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002950
Paul Bakker5121ce52009-01-03 21:22:43 +00002951 ssl->out_msglen = i + n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002952 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2953 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002954
2955 ssl->state++;
2956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002957 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002958 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002959 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002960 return( ret );
2961 }
2962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002963 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002964
2965 return( 0 );
2966}
2967
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002968#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2969 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2970 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2971 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2972static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002973{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002974 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002975 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002977 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002979 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002980 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002981 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002982 return( ret );
2983 }
2984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002985 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2986 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2987 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002988 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2989 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakkered27a042013-04-18 22:46:23 +02002990 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002991 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakkered27a042013-04-18 22:46:23 +02002992 ssl->state++;
2993 return( 0 );
2994 }
2995
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002996 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2997 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002998}
2999#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003000static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003001{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003002 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3003 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003004 size_t n = 0, offset = 0;
3005 unsigned char hash[48];
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003006 unsigned char *hash_start = hash;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003007 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003008 unsigned int hashlen;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003010 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003011
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003012 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003013 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003014 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003015 return( ret );
3016 }
3017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003018 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
3019 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
3020 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02003021 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
3022 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003023 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003024 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003025 ssl->state++;
3026 return( 0 );
3027 }
3028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003029 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003030 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003031 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003032 ssl->state++;
3033 return( 0 );
3034 }
3035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003036 if( mbedtls_ssl_own_key( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003037 {
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02003038 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003039 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003040 }
3041
3042 /*
3043 * Make an RSA signature of the handshake digests
3044 */
Paul Bakker48916f92012-09-16 19:57:18 +00003045 ssl->handshake->calc_verify( ssl, hash );
Paul Bakker5121ce52009-01-03 21:22:43 +00003046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003047#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3048 defined(MBEDTLS_SSL_PROTO_TLS1_1)
3049 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00003050 {
Paul Bakker926af752012-11-23 13:38:07 +01003051 /*
3052 * digitally-signed struct {
3053 * opaque md5_hash[16];
3054 * opaque sha_hash[20];
3055 * };
3056 *
3057 * md5_hash
3058 * MD5(handshake_messages);
3059 *
3060 * sha_hash
3061 * SHA(handshake_messages);
3062 */
3063 hashlen = 36;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003064 md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003065
3066 /*
3067 * For ECDSA, default hash is SHA-1 only
3068 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003069 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003070 {
3071 hash_start += 16;
3072 hashlen -= 16;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003073 md_alg = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003074 }
Paul Bakker926af752012-11-23 13:38:07 +01003075 }
3076 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003077#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
3078 MBEDTLS_SSL_PROTO_TLS1_1 */
3079#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3080 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01003081 {
3082 /*
3083 * digitally-signed struct {
3084 * opaque handshake_messages[handshake_messages_length];
3085 * };
3086 *
3087 * Taking shortcut here. We assume that the server always allows the
3088 * PRF Hash function and has sent it in the allowed signature
3089 * algorithms list received in the Certificate Request message.
3090 *
3091 * Until we encounter a server that does not, we will take this
3092 * shortcut.
3093 *
3094 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
3095 * in order to satisfy 'weird' needs from the server side.
3096 */
Paul Bakkerb7149bc2013-03-20 15:30:09 +01003097 if( ssl->transform_negotiate->ciphersuite_info->mac ==
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003098 MBEDTLS_MD_SHA384 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00003099 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003100 md_alg = MBEDTLS_MD_SHA384;
3101 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003102 }
3103 else
3104 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003105 md_alg = MBEDTLS_MD_SHA256;
3106 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003107 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003108 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
Paul Bakker1ef83d62012-04-11 12:09:53 +00003109
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +02003110 /* Info from md_alg will be used instead */
3111 hashlen = 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003112 offset = 2;
3113 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003114 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003115#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02003116 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003117 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3118 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02003119 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00003120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003121 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003122 ssl->out_msg + 6 + offset, &n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01003123 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003124 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003125 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003126 return( ret );
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003127 }
Paul Bakker926af752012-11-23 13:38:07 +01003128
Paul Bakker1ef83d62012-04-11 12:09:53 +00003129 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
3130 ssl->out_msg[5 + offset] = (unsigned char)( n );
Paul Bakker5121ce52009-01-03 21:22:43 +00003131
Paul Bakker1ef83d62012-04-11 12:09:53 +00003132 ssl->out_msglen = 6 + n + offset;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003133 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3134 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00003135
3136 ssl->state++;
3137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003138 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003139 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003140 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003141 return( ret );
3142 }
3143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003144 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003145
Paul Bakkered27a042013-04-18 22:46:23 +02003146 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003147}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003148#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
3149 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
3150 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00003151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003152#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3153static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003154{
3155 int ret;
3156 uint32_t lifetime;
3157 size_t ticket_len;
3158 unsigned char *ticket;
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003159 const unsigned char *msg;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003161 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003163 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003164 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003165 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003166 return( ret );
3167 }
3168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003169 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003170 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003171 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3172 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003173 }
3174
3175 /*
3176 * struct {
3177 * uint32 ticket_lifetime_hint;
3178 * opaque ticket<0..2^16-1>;
3179 * } NewSessionTicket;
3180 *
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003181 * 0 . 3 ticket_lifetime_hint
3182 * 4 . 5 ticket_len (n)
3183 * 6 . 5+n ticket content
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003184 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003185 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
3186 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003187 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003188 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3189 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003190 }
3191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003192 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003193
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003194 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
3195 ( msg[2] << 8 ) | ( msg[3] );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003196
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003197 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
3198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003199 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003200 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003201 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3202 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003203 }
3204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003205 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003206
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003207 /* We're not waiting for a NewSessionTicket message any more */
3208 ssl->handshake->new_session_ticket = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003209 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003210
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003211 /*
3212 * Zero-length ticket means the server changed his mind and doesn't want
3213 * to send a ticket after all, so just forget it
3214 */
Paul Bakker66d5d072014-06-17 16:39:18 +02003215 if( ticket_len == 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003216 return( 0 );
3217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003218 mbedtls_zeroize( ssl->session_negotiate->ticket,
Paul Bakker34617722014-06-13 17:20:13 +02003219 ssl->session_negotiate->ticket_len );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003220 mbedtls_free( ssl->session_negotiate->ticket );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003221 ssl->session_negotiate->ticket = NULL;
3222 ssl->session_negotiate->ticket_len = 0;
3223
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02003224 if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003225 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02003226 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02003227 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003228 }
3229
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003230 memcpy( ticket, msg + 6, ticket_len );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003231
3232 ssl->session_negotiate->ticket = ticket;
3233 ssl->session_negotiate->ticket_len = ticket_len;
3234 ssl->session_negotiate->ticket_lifetime = lifetime;
3235
3236 /*
3237 * RFC 5077 section 3.4:
3238 * "If the client receives a session ticket from the server, then it
3239 * discards any Session ID that was sent in the ServerHello."
3240 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003241 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02003242 ssl->session_negotiate->id_len = 0;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003244 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003245
3246 return( 0 );
3247}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003248#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003249
Paul Bakker5121ce52009-01-03 21:22:43 +00003250/*
Paul Bakker1961b702013-01-25 14:49:24 +01003251 * SSL handshake -- client side -- single step
Paul Bakker5121ce52009-01-03 21:22:43 +00003252 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003253int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00003254{
3255 int ret = 0;
3256
Manuel Pégourié-Gonnarddba460f2015-06-24 22:59:30 +02003257 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003258 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00003259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003260 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
Paul Bakker1961b702013-01-25 14:49:24 +01003261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003262 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker1961b702013-01-25 14:49:24 +01003263 return( ret );
3264
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003265#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003266 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003267 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003268 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003269 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003270 return( ret );
3271 }
3272#endif
3273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003274 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003275 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003276#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3277 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003278 ssl->handshake->new_session_ticket != 0 )
3279 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003280 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003281 }
3282#endif
3283
Paul Bakker1961b702013-01-25 14:49:24 +01003284 switch( ssl->state )
Paul Bakker5121ce52009-01-03 21:22:43 +00003285 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003286 case MBEDTLS_SSL_HELLO_REQUEST:
3287 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00003288 break;
3289
Paul Bakker1961b702013-01-25 14:49:24 +01003290 /*
3291 * ==> ClientHello
3292 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003293 case MBEDTLS_SSL_CLIENT_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003294 ret = ssl_write_client_hello( ssl );
3295 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003296
Paul Bakker1961b702013-01-25 14:49:24 +01003297 /*
3298 * <== ServerHello
3299 * Certificate
3300 * ( ServerKeyExchange )
3301 * ( CertificateRequest )
3302 * ServerHelloDone
3303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003304 case MBEDTLS_SSL_SERVER_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003305 ret = ssl_parse_server_hello( ssl );
3306 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003308 case MBEDTLS_SSL_SERVER_CERTIFICATE:
3309 ret = mbedtls_ssl_parse_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003310 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003312 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003313 ret = ssl_parse_server_key_exchange( ssl );
3314 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003316 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
Paul Bakker1961b702013-01-25 14:49:24 +01003317 ret = ssl_parse_certificate_request( ssl );
3318 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003320 case MBEDTLS_SSL_SERVER_HELLO_DONE:
Paul Bakker1961b702013-01-25 14:49:24 +01003321 ret = ssl_parse_server_hello_done( ssl );
3322 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003323
Paul Bakker1961b702013-01-25 14:49:24 +01003324 /*
3325 * ==> ( Certificate/Alert )
3326 * ClientKeyExchange
3327 * ( CertificateVerify )
3328 * ChangeCipherSpec
3329 * Finished
3330 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003331 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3332 ret = mbedtls_ssl_write_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003333 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003335 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003336 ret = ssl_write_client_key_exchange( ssl );
3337 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003339 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
Paul Bakker1961b702013-01-25 14:49:24 +01003340 ret = ssl_write_certificate_verify( ssl );
3341 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003343 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3344 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003345 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003347 case MBEDTLS_SSL_CLIENT_FINISHED:
3348 ret = mbedtls_ssl_write_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003349 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003350
Paul Bakker1961b702013-01-25 14:49:24 +01003351 /*
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003352 * <== ( NewSessionTicket )
3353 * ChangeCipherSpec
Paul Bakker1961b702013-01-25 14:49:24 +01003354 * Finished
3355 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003356#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3357 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003358 ret = ssl_parse_new_session_ticket( ssl );
3359 break;
Paul Bakkera503a632013-08-14 13:48:06 +02003360#endif
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003362 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3363 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003364 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003366 case MBEDTLS_SSL_SERVER_FINISHED:
3367 ret = mbedtls_ssl_parse_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003368 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003370 case MBEDTLS_SSL_FLUSH_BUFFERS:
3371 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
3372 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Paul Bakker1961b702013-01-25 14:49:24 +01003373 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003375 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3376 mbedtls_ssl_handshake_wrapup( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003377 break;
Paul Bakker48916f92012-09-16 19:57:18 +00003378
Paul Bakker1961b702013-01-25 14:49:24 +01003379 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003380 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
3381 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1961b702013-01-25 14:49:24 +01003382 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003383
3384 return( ret );
3385}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003386#endif /* MBEDTLS_SSL_CLI_C */