blob: 9f04b2bb4db7074da8c8ee122a9a74e9a7734814 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSLv3/TLSv1 client-side functions
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020023#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020025#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020027#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if defined(MBEDTLS_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/debug.h"
32#include "mbedtls/ssl.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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#define mbedtls_malloc malloc
41#define mbedtls_free free
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020042#endif
43
Paul Bakkerfa6a6202013-10-28 18:48:30 +010044#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
Paul Bakkerfa9b1002013-07-03 15:31:03 +020045#include <basetsd.h>
46typedef UINT32 uint32_t;
47#else
48#include <inttypes.h>
49#endif
50
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000052#include <time.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020053#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Paul Bakker34617722014-06-13 17:20:13 +020056/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020058 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
59}
60#endif
61
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
63static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +010064 unsigned char *buf,
65 size_t *olen )
66{
67 unsigned char *p = buf;
68
69 *olen = 0;
70
Paul Bakker66d5d072014-06-17 16:39:18 +020071 if( ssl->hostname == NULL )
Paul Bakkerd3edc862013-03-20 16:07:17 +010072 return;
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
Paul Bakkerd3edc862013-03-20 16:07:17 +010075 ssl->hostname ) );
76
77 /*
78 * struct {
79 * NameType name_type;
80 * select (name_type) {
81 * case host_name: HostName;
82 * } name;
83 * } ServerName;
84 *
85 * enum {
86 * host_name(0), (255)
87 * } NameType;
88 *
89 * opaque HostName<1..2^16-1>;
90 *
91 * struct {
92 * ServerName server_name_list<1..2^16-1>
93 * } ServerNameList;
94 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
96 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +010097
98 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
99 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF );
100
101 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
102 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF );
103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100105 *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
106 *p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF );
107
108 memcpy( p, ssl->hostname, ssl->hostname_len );
109
110 *olen = ssl->hostname_len + 9;
111}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114#if defined(MBEDTLS_SSL_RENEGOTIATION)
115static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100116 unsigned char *buf,
117 size_t *olen )
118{
119 unsigned char *p = buf;
120
121 *olen = 0;
122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100124 return;
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100127
128 /*
129 * Secure renegotiation
130 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
132 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100133
134 *p++ = 0x00;
135 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
136 *p++ = ssl->verify_data_len & 0xFF;
137
138 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
139
140 *olen = 5 + ssl->verify_data_len;
141}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100143
Manuel Pégourié-Gonnardd9423232014-12-02 11:57:29 +0100144/*
145 * Only if we handle at least one key exchange that needs signatures.
146 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
148 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
149static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100150 unsigned char *buf,
151 size_t *olen )
152{
153 unsigned char *p = buf;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100154 size_t sig_alg_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5bfd9682014-06-24 15:18:11 +0200156 unsigned char *sig_alg_list = buf + 6;
157#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100158
159 *olen = 0;
160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 if( ssl->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100162 return;
163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100165
166 /*
167 * Prepare signature_algorithms extension (TLS 1.2)
168 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169#if defined(MBEDTLS_RSA_C)
170#if defined(MBEDTLS_SHA512_C)
171 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA512;
172 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
173 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA384;
174 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100175#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176#if defined(MBEDTLS_SHA256_C)
177 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA256;
178 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
179 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA224;
180 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100181#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182#if defined(MBEDTLS_SHA1_C)
183 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA1;
184 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100185#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186#if defined(MBEDTLS_MD5_C)
187 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_MD5;
188 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100189#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190#endif /* MBEDTLS_RSA_C */
191#if defined(MBEDTLS_ECDSA_C)
192#if defined(MBEDTLS_SHA512_C)
193 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA512;
194 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
195 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA384;
196 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200197#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198#if defined(MBEDTLS_SHA256_C)
199 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA256;
200 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
201 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA224;
202 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200203#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204#if defined(MBEDTLS_SHA1_C)
205 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_SHA1;
206 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200207#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208#if defined(MBEDTLS_MD5_C)
209 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_HASH_MD5;
210 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200211#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212#endif /* MBEDTLS_ECDSA_C */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100213
214 /*
215 * enum {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 * none(0), mbedtls_md5(1), mbedtls_sha1(2), sha224(3), mbedtls_sha256(4), sha384(5),
217 * mbedtls_sha512(6), (255)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100218 * } HashAlgorithm;
219 *
220 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
221 * SignatureAlgorithm;
222 *
223 * struct {
224 * HashAlgorithm hash;
225 * SignatureAlgorithm signature;
226 * } SignatureAndHashAlgorithm;
227 *
228 * SignatureAndHashAlgorithm
229 * supported_signature_algorithms<2..2^16-2>;
230 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
232 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100233
234 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
235 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
236
237 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
238 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
239
Paul Bakkerd3edc862013-03-20 16:07:17 +0100240 *olen = 6 + sig_alg_len;
241}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
243 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
246static 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;
Manuel Pégourié-Gonnard8e205fc2014-01-23 17:27:10 +0100251 unsigned char *elliptic_curve_list = p + 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100252 size_t elliptic_curve_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 const mbedtls_ecp_curve_info *info;
254#if defined(MBEDTLS_SSL_SET_CURVES)
255 const mbedtls_ecp_group_id *grp_id;
Paul Bakker0910f322014-02-06 13:41:18 +0100256#else
257 ((void) ssl);
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100258#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100259
260 *olen = 0;
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264#if defined(MBEDTLS_SSL_SET_CURVES)
265 for( grp_id = ssl->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200266 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100268#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100270 {
271#endif
272
273 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
274 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200275 }
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200276
277 if( elliptic_curve_len == 0 )
278 return;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
281 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100282
283 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
284 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
285
286 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
287 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
288
Paul Bakkerd3edc862013-03-20 16:07:17 +0100289 *olen = 6 + elliptic_curve_len;
290}
291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100293 unsigned char *buf,
294 size_t *olen )
295{
296 unsigned char *p = buf;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +0200297 ((void) ssl);
Paul Bakkerd3edc862013-03-20 16:07:17 +0100298
299 *olen = 0;
300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
304 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100305
306 *p++ = 0x00;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100307 *p++ = 2;
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200308
309 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310 *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100311
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200312 *olen = 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100313}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
317static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200318 unsigned char *buf,
319 size_t *olen )
320{
321 unsigned char *p = buf;
322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 if( ssl->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200324 *olen = 0;
325 return;
326 }
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
331 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200332
333 *p++ = 0x00;
334 *p++ = 1;
335
336 *p++ = ssl->mfl_code;
337
338 *olen = 5;
339}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
343static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200344 unsigned char *buf, size_t *olen )
345{
346 unsigned char *p = buf;
347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 if( ssl->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200349 {
350 *olen = 0;
351 return;
352 }
353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
357 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200358
359 *p++ = 0x00;
360 *p++ = 0x00;
361
362 *olen = 4;
363}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
367static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100368 unsigned char *buf, size_t *olen )
369{
370 unsigned char *p = buf;
371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 if( ssl->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
373 ssl->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100374 {
375 *olen = 0;
376 return;
377 }
378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100380 "extension" ) );
381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
383 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100384
385 *p++ = 0x00;
386 *p++ = 0x00;
387
388 *olen = 4;
389}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
393static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200394 unsigned char *buf, size_t *olen )
395{
396 unsigned char *p = buf;
397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 if( ssl->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
399 ssl->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200400 {
401 *olen = 0;
402 return;
403 }
404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200406 "extension" ) );
407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
409 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200410
411 *p++ = 0x00;
412 *p++ = 0x00;
413
414 *olen = 4;
415}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418#if defined(MBEDTLS_SSL_SESSION_TICKETS)
419static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200420 unsigned char *buf, size_t *olen )
421{
422 unsigned char *p = buf;
423 size_t tlen = ssl->session_negotiate->ticket_len;
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 if( ssl->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200426 {
427 *olen = 0;
428 return;
429 }
430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
434 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200435
436 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
437 *p++ = (unsigned char)( ( tlen ) & 0xFF );
438
439 *olen = 4;
440
441 if( ssl->session_negotiate->ticket == NULL ||
442 ssl->session_negotiate->ticket_len == 0 )
443 {
444 return;
445 }
446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200448
449 memcpy( p, ssl->session_negotiate->ticket, tlen );
450
451 *olen += tlen;
452}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#if defined(MBEDTLS_SSL_ALPN)
456static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200457 unsigned char *buf, size_t *olen )
458{
459 unsigned char *p = buf;
460 const char **cur;
461
462 if( ssl->alpn_list == NULL )
463 {
464 *olen = 0;
465 return;
466 }
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
471 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200472
473 /*
474 * opaque ProtocolName<1..2^8-1>;
475 *
476 * struct {
477 * ProtocolName protocol_name_list<2..2^16-1>
478 * } ProtocolNameList;
479 */
480
481 /* Skip writing extension and list length for now */
482 p += 4;
483
484 for( cur = ssl->alpn_list; *cur != NULL; cur++ )
485 {
486 *p = (unsigned char)( strlen( *cur ) & 0xFF );
487 memcpy( p + 1, *cur, *p );
488 p += 1 + *p;
489 }
490
491 *olen = p - buf;
492
493 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
494 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
495 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
496
497 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
498 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
499 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
500}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200502
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200503/*
504 * Generate random bytes for ClientHello
505 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506static int ssl_generate_random( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200507{
508 int ret;
509 unsigned char *p = ssl->handshake->randbytes;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200511 time_t t;
512#endif
513
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200514 /*
515 * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
516 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517#if defined(MBEDTLS_SSL_PROTO_DTLS)
518 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200519 ssl->handshake->verify_cookie != NULL )
520 {
521 return( 0 );
522 }
523#endif
524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200526 t = time( NULL );
527 *p++ = (unsigned char)( t >> 24 );
528 *p++ = (unsigned char)( t >> 16 );
529 *p++ = (unsigned char)( t >> 8 );
530 *p++ = (unsigned char)( t );
531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200533#else
534 if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 )
535 return( ret );
536
537 p += 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538#endif /* MBEDTLS_HAVE_TIME */
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200539
540 if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
541 return( ret );
542
543 return( 0 );
544}
545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +0000547{
Paul Bakker23986e52011-04-24 08:57:21 +0000548 int ret;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100549 size_t i, n, olen, ext_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000550 unsigned char *buf;
Paul Bakker2fbefde2013-06-29 16:01:15 +0200551 unsigned char *p, *q;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200552 unsigned char offer_compress;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200553 const int *ciphersuites;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
Paul Bakkera9a028e2013-11-21 17:31:06 +0100558 if( ssl->f_rng == NULL )
559 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
561 return( MBEDTLS_ERR_SSL_NO_RNG );
Paul Bakkera9a028e2013-11-21 17:31:06 +0100562 }
563
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564#if defined(MBEDTLS_SSL_RENEGOTIATION)
565 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100566#endif
Paul Bakker48916f92012-09-16 19:57:18 +0000567 {
Paul Bakker993d11d2012-09-28 15:00:12 +0000568 ssl->major_ver = ssl->min_major_ver;
569 ssl->minor_ver = ssl->min_minor_ver;
Paul Bakker48916f92012-09-16 19:57:18 +0000570 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Paul Bakker490ecc82011-10-06 13:04:09 +0000572 if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
573 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 ssl->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
575 ssl->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
Paul Bakker490ecc82011-10-06 13:04:09 +0000576 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 /*
579 * 0 . 0 handshake type
580 * 1 . 3 handshake length
581 * 4 . 5 highest version supported
582 * 6 . 9 current UNIX time
583 * 10 . 37 random bytes
584 */
585 buf = ssl->out_msg;
586 p = buf + 4;
587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_ssl_write_version( ssl->max_major_ver, ssl->max_minor_ver,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +0100589 ssl->transport, p );
590 p += 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 buf[4], buf[5] ) );
594
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200595 if( ( ret = ssl_generate_random( ssl ) ) != 0 )
596 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200598 return( ret );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200599 }
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200600
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200601 memcpy( p, ssl->handshake->randbytes, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200603 p += 32;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 /*
606 * 38 . 38 session id length
607 * 39 . 39+n session id
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100608 * 39+n . 39+n DTLS only: cookie length (1 byte)
609 * 40+n . .. DTSL only: cookie
610 * .. . .. ciphersuitelist length (2 bytes)
611 * .. . .. ciphersuitelist
612 * .. . .. compression methods length (1 byte)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000613 * .. . .. compression methods
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100614 * .. . .. extensions length (2 bytes)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000615 * .. . .. extensions
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 */
Paul Bakker48916f92012-09-16 19:57:18 +0000617 n = ssl->session_negotiate->length;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100619 if( n < 16 || n > 32 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#if defined(MBEDTLS_SSL_RENEGOTIATION)
621 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100622#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000623 ssl->handshake->resume == 0 )
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200624 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 n = 0;
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200626 }
627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200629 /*
630 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
631 * generate and include a Session ID in the TLS ClientHello."
632 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#if defined(MBEDTLS_SSL_RENEGOTIATION)
634 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000635#endif
Manuel Pégourié-Gonnardd2b35ec2015-03-10 11:40:43 +0000636 {
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000637 if( ssl->session_negotiate->ticket != NULL &&
638 ssl->session_negotiate->ticket_len != 0 )
639 {
640 ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200641
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000642 if( ret != 0 )
643 return( ret );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200644
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000645 ssl->session_negotiate->length = n = 32;
646 }
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200647 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 *p++ = (unsigned char) n;
651
652 for( i = 0; i < n; i++ )
Paul Bakker48916f92012-09-16 19:57:18 +0000653 *p++ = ssl->session_negotiate->id[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
656 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100658 /*
659 * DTLS cookie
660 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#if defined(MBEDTLS_SSL_PROTO_DTLS)
662 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100663 {
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200664 if( ssl->handshake->verify_cookie == NULL )
665 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200667 *p++ = 0;
668 }
669 else
670 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200672 ssl->handshake->verify_cookie,
673 ssl->handshake->verify_cookie_len );
674
675 *p++ = ssl->handshake->verify_cookie_len;
676 memcpy( p, ssl->handshake->verify_cookie,
677 ssl->handshake->verify_cookie_len );
678 p += ssl->handshake->verify_cookie_len;
679 }
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100680 }
681#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Paul Bakker48916f92012-09-16 19:57:18 +0000683 /*
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100684 * Ciphersuite list
Paul Bakker48916f92012-09-16 19:57:18 +0000685 */
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100686 ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
687
688 /* Skip writing ciphersuite length for now */
689 n = 0;
690 q = p;
691 p += 2;
692
Paul Bakker2fbefde2013-06-29 16:01:15 +0200693 for( i = 0; ciphersuites[i] != 0; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000694 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200696
697 if( ciphersuite_info == NULL )
698 continue;
699
700 if( ciphersuite_info->min_minor_ver > ssl->max_minor_ver ||
701 ciphersuite_info->max_minor_ver < ssl->min_minor_ver )
702 continue;
703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704#if defined(MBEDTLS_SSL_PROTO_DTLS)
705 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
706 ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
Manuel Pégourié-Gonnardd6664512014-02-06 13:26:57 +0100707 continue;
708#endif
709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 if( ssl->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
711 ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100712 continue;
713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d",
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200715 ciphersuites[i] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
Paul Bakker2fbefde2013-06-29 16:01:15 +0200717 n++;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200718 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
719 *p++ = (unsigned char)( ciphersuites[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000720 }
721
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000722 /*
723 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
724 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#if defined(MBEDTLS_SSL_RENEGOTIATION)
726 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000727#endif
728 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200729 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
730 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000731 n++;
732 }
733
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200734 /* Some versions of OpenSSL don't handle it correctly if not at end */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200735#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
736 if( ssl->fallback == MBEDTLS_SSL_IS_FALLBACK )
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200737 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
739 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
740 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200741 n++;
742 }
743#endif
744
Paul Bakker2fbefde2013-06-29 16:01:15 +0200745 *q++ = (unsigned char)( n >> 7 );
746 *q++ = (unsigned char)( n << 1 );
747
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200748 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200749
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200751 offer_compress = 1;
Paul Bakker2770fbd2012-07-03 13:30:23 +0000752#else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200753 offer_compress = 0;
754#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200756 /*
757 * We don't support compression with DTLS right now: is many records come
758 * in the same datagram, uncompressing one could overwrite the next one.
759 * We don't want to add complexity for handling that case unless there is
760 * an actual need for it.
761 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762#if defined(MBEDTLS_SSL_PROTO_DTLS)
763 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200764 offer_compress = 0;
765#endif
766
767 if( offer_compress )
768 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
770 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
771 MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200772
773 *p++ = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774 *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
775 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200776 }
777 else
778 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
780 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
781 MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200782
783 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200785 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
Paul Bakkerd3edc862013-03-20 16:07:17 +0100787 // First write extensions, then the total length
788 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100790 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
791 ext_len += olen;
Paul Bakker0be444a2013-08-27 21:55:01 +0200792#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100795 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
796 ext_len += olen;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100797#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000798
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
800 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100801 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
802 ext_len += olen;
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200803#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100806 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
807 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100808
Paul Bakkerd3edc862013-03-20 16:07:17 +0100809 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
810 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100811#endif
812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200814 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
815 ext_len += olen;
Paul Bakker05decb22013-08-15 13:33:48 +0200816#endif
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200817
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200819 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
820 ext_len += olen;
Paul Bakker1f2bc622013-08-15 13:45:55 +0200821#endif
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200822
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100824 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
825 ext_len += olen;
826#endif
827
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200829 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
830 ext_len += olen;
831#endif
832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200834 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
835 ext_len += olen;
Paul Bakkera503a632013-08-14 13:48:06 +0200836#endif
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200839 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
840 ext_len += olen;
841#endif
842
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +0100843 /* olen unused if all extensions are disabled */
844 ((void) olen);
845
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000847 ext_len ) );
848
Paul Bakkera7036632014-04-30 10:15:38 +0200849 if( ext_len > 0 )
850 {
851 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
852 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
853 p += ext_len;
854 }
Paul Bakker41c83d32013-03-20 14:39:14 +0100855
Paul Bakker5121ce52009-01-03 21:22:43 +0000856 ssl->out_msglen = p - buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
858 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
860 ssl->state++;
861
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862#if defined(MBEDTLS_SSL_PROTO_DTLS)
863 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
864 mbedtls_ssl_send_flight_completed( ssl );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +0200865#endif
866
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870 return( ret );
871 }
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
875 return( 0 );
876}
877
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +0200879 const unsigned char *buf,
Paul Bakker48916f92012-09-16 19:57:18 +0000880 size_t len )
881{
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000882 int ret;
883
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884#if defined(MBEDTLS_SSL_RENEGOTIATION)
885 if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +0000886 {
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100887 /* Check verify-data in constant-time. The length OTOH is no secret */
Paul Bakker48916f92012-09-16 19:57:18 +0000888 if( len != 1 + ssl->verify_data_len * 2 ||
889 buf[0] != ssl->verify_data_len * 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 mbedtls_ssl_safer_memcmp( buf + 1,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100891 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100893 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +0000894 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000898 return( ret );
899
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +0000901 }
902 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100903 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100905 {
906 if( len != 1 || buf[0] != 0x00 )
907 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100911 return( ret );
912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100914 }
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100917 }
Paul Bakker48916f92012-09-16 19:57:18 +0000918
919 return( 0 );
920}
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
923static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +0200924 const unsigned char *buf,
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200925 size_t len )
926{
927 /*
928 * server should use the extension only if we did,
929 * and if so the server's value should match ours (and len is always 1)
930 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 if( ssl->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200932 len != 1 ||
933 buf[0] != ssl->mfl_code )
934 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200936 }
937
938 return( 0 );
939}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Paul Bakker48916f92012-09-16 19:57:18 +0000941
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
943static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200944 const unsigned char *buf,
945 size_t len )
946{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 if( ssl->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200948 len != 0 )
949 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200951 }
952
953 ((void) buf);
954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200956
957 return( 0 );
958}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
962static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100963 const unsigned char *buf,
964 size_t len )
965{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 if( ssl->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
967 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100968 len != 0 )
969 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100971 }
972
973 ((void) buf);
974
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975 ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100976
977 return( 0 );
978}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
982static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200983 const unsigned char *buf,
984 size_t len )
985{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 if( ssl->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
987 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200988 len != 0 )
989 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200991 }
992
993 ((void) buf);
994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200996
997 return( 0 );
998}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1002static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001003 const unsigned char *buf,
1004 size_t len )
1005{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 if( ssl->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001007 len != 0 )
1008 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001010 }
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001011
1012 ((void) buf);
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02001013
1014 ssl->handshake->new_session_ticket = 1;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001015
1016 return( 0 );
1017}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
1021static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001022 const unsigned char *buf,
1023 size_t len )
1024{
1025 size_t list_size;
1026 const unsigned char *p;
1027
1028 list_size = buf[0];
1029 if( list_size + 1 != len )
1030 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1032 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001033 }
1034
Manuel Pégourié-Gonnardfd35af12014-06-23 14:10:13 +02001035 p = buf + 1;
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001036 while( list_size > 0 )
1037 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
1039 p[0] == MBEDTLS_ECP_PF_COMPRESSED )
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001040 {
Manuel Pégourié-Gonnard5734b2d2013-08-15 19:04:02 +02001041 ssl->handshake->ecdh_ctx.point_format = p[0];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042 MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001043 return( 0 );
1044 }
1045
1046 list_size--;
1047 p++;
1048 }
1049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
1051 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001052}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_SSL_ALPN)
1056static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001057 const unsigned char *buf, size_t len )
1058{
1059 size_t list_len, name_len;
1060 const char **p;
1061
1062 /* If we didn't send it, the server shouldn't send it */
1063 if( ssl->alpn_list == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001065
1066 /*
1067 * opaque ProtocolName<1..2^8-1>;
1068 *
1069 * struct {
1070 * ProtocolName protocol_name_list<2..2^16-1>
1071 * } ProtocolNameList;
1072 *
1073 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
1074 */
1075
1076 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
1077 if( len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001079
1080 list_len = ( buf[0] << 8 ) | buf[1];
1081 if( list_len != len - 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001083
1084 name_len = buf[2];
1085 if( name_len != list_len - 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001087
1088 /* Check that the server chosen protocol was in our list and save it */
1089 for( p = ssl->alpn_list; *p != NULL; p++ )
1090 {
1091 if( name_len == strlen( *p ) &&
1092 memcmp( buf + 3, *p, name_len ) == 0 )
1093 {
1094 ssl->alpn_chosen = *p;
1095 return( 0 );
1096 }
1097 }
1098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001100}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001102
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001103/*
1104 * Parse HelloVerifyRequest. Only called after verifying the HS type.
1105 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#if defined(MBEDTLS_SSL_PROTO_DTLS)
1107static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001108{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001110 int major_ver, minor_ver;
1111 unsigned char cookie_len;
1112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001114
1115 /*
1116 * struct {
1117 * ProtocolVersion server_version;
1118 * opaque cookie<0..2^8-1>;
1119 * } HelloVerifyRequest;
1120 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121 MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
1122 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->transport, p );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001123 p += 2;
1124
Manuel Pégourié-Gonnardb35fe562014-08-09 17:00:46 +02001125 /*
1126 * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
1127 * even is lower than our min version.
1128 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
1130 minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
Manuel Pégourié-Gonnardb35fe562014-08-09 17:00:46 +02001131 major_ver > ssl->max_major_ver ||
1132 minor_ver > ssl->max_minor_ver )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001133 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1137 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001140 }
1141
1142 cookie_len = *p++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001143 MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001147 ssl->handshake->verify_cookie = mbedtls_malloc( cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001148 if( ssl->handshake->verify_cookie == NULL )
1149 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001150 MBEDTLS_SSL_DEBUG_MSG( 1, ( "malloc failed (%d bytes)", cookie_len ) );
1151 return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001152 }
1153
1154 memcpy( ssl->handshake->verify_cookie, p, cookie_len );
1155 ssl->handshake->verify_cookie_len = cookie_len;
1156
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02001157 /* Start over at ClientHello */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
1159 mbedtls_ssl_reset_checksum( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001164
1165 return( 0 );
1166}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00001170{
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001171 int ret, i;
Paul Bakker23986e52011-04-24 08:57:21 +00001172 size_t n;
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001173 size_t ext_len;
Paul Bakker48916f92012-09-16 19:57:18 +00001174 unsigned char *buf, *ext;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001175 unsigned char comp, accept_comp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001177 int renegotiation_info_seen = 0;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001178#endif
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001179 int handshake_failure = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 const mbedtls_ssl_ciphersuite_t *suite_info;
1181#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001182 uint32_t t;
1183#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001184
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001185 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 buf = ssl->in_msg;
1188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001190 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001191 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001192 return( ret );
1193 }
1194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001195 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001197#if defined(MBEDTLS_SSL_RENEGOTIATION)
1198 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001199 {
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001200 ssl->renego_records_seen++;
1201
1202 if( ssl->renego_max_records >= 0 &&
1203 ssl->renego_records_seen > ssl->renego_max_records )
1204 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001206 "but not honored by server" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001208 }
1209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
1211 return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001212 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1216 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 }
1218
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219#if defined(MBEDTLS_SSL_PROTO_DTLS)
1220 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001221 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001223 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
1225 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001226 return( ssl_parse_hello_verify_request( ssl ) );
1227 }
1228 else
1229 {
1230 /* We made it through the verification process */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001231 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001232 ssl->handshake->verify_cookie = NULL;
1233 ssl->handshake->verify_cookie_len = 0;
1234 }
1235 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238 if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
1239 buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1242 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001243 }
1244
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001245 /*
1246 * 0 . 1 server_version
1247 * 2 . 33 random (maybe including 4 bytes of Unix time)
1248 * 34 . 34 session_id length = n
1249 * 35 . 34+n session_id
1250 * 35+n . 36+n cipher_suite
1251 * 37+n . 37+n compression_method
1252 *
1253 * 38+n . 39+n extensions length (optional)
1254 * 40+n . .. extensions
1255 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 buf += mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001257
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001258 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
1259 mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001260 ssl->transport, buf + 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001261
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001262 if( ssl->major_ver < ssl->min_major_ver ||
1263 ssl->minor_ver < ssl->min_minor_ver ||
1264 ssl->major_ver > ssl->max_major_ver ||
1265 ssl->minor_ver > ssl->max_minor_ver )
Paul Bakker1d29fb52012-09-28 13:28:45 +00001266 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001268 " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
1269 ssl->min_major_ver, ssl->min_minor_ver,
1270 ssl->major_ver, ssl->minor_ver,
1271 ssl->max_major_ver, ssl->max_minor_ver ) );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001273 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1274 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001276 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001277 }
1278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001279#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001280 t = ( (uint32_t) buf[2] << 24 )
1281 | ( (uint32_t) buf[3] << 16 )
1282 | ( (uint32_t) buf[4] << 8 )
1283 | ( (uint32_t) buf[5] );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
Paul Bakker87e5cda2012-01-14 18:14:15 +00001285#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001286
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001287 memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001289 n = buf[34];
Paul Bakker5121ce52009-01-03 21:22:43 +00001290
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001291 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001292
Paul Bakker48916f92012-09-16 19:57:18 +00001293 if( n > 32 )
1294 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001295 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1296 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001297 }
1298
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001299 if( ssl->in_hslen > 39 + n )
Paul Bakker5121ce52009-01-03 21:22:43 +00001300 {
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001301 ext_len = ( ( buf[38 + n] << 8 )
1302 | ( buf[39 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001303
Paul Bakker48916f92012-09-16 19:57:18 +00001304 if( ( ext_len > 0 && ext_len < 4 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001305 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
Paul Bakker48916f92012-09-16 19:57:18 +00001306 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1308 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001309 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001310 }
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001311 else if( ssl->in_hslen == 38 + n )
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001312 {
1313 ext_len = 0;
1314 }
1315 else
1316 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1318 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001319 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001320
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001321 /* ciphersuite (used later) */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001322 i = ( buf[35 + n] << 8 ) | buf[36 + n];
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001323
1324 /*
1325 * Read and check compression
1326 */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001327 comp = buf[37 + n];
Paul Bakker5121ce52009-01-03 21:22:43 +00001328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001330 accept_comp = 1;
1331#else
1332 accept_comp = 0;
1333#endif
1334
1335 /* See comments in ssl_write_client_hello() */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001336#if defined(MBEDTLS_SSL_PROTO_DTLS)
1337 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001338 accept_comp = 0;
1339#endif
1340
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001341 if( ( accept_comp == 0 && comp != MBEDTLS_SSL_COMPRESS_NULL ) ||
1342 ( comp != MBEDTLS_SSL_COMPRESS_NULL && comp != MBEDTLS_SSL_COMPRESS_DEFLATE ) )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001343 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
1345 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001346 }
1347
Paul Bakker380da532012-04-18 16:10:25 +00001348 /*
1349 * Initialize update checksum functions
1350 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351 ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
Paul Bakker68884e32013-01-07 18:20:04 +01001352
1353 if( ssl->transform_negotiate->ciphersuite_info == NULL )
1354 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001355 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
1356 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker68884e32013-01-07 18:20:04 +01001357 }
Paul Bakker380da532012-04-18 16:10:25 +00001358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
Manuel Pégourié-Gonnard3c599f12014-03-10 13:25:07 +01001360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001361 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
1362 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001363
1364 /*
1365 * Check if the session can be resumed
1366 */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001367 if( ssl->handshake->resume == 0 || n == 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368#if defined(MBEDTLS_SSL_RENEGOTIATION)
1369 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001370#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001371 ssl->session_negotiate->ciphersuite != i ||
1372 ssl->session_negotiate->compression != comp ||
1373 ssl->session_negotiate->length != n ||
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001374 memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 {
1376 ssl->state++;
Paul Bakker0a597072012-09-25 21:55:46 +00001377 ssl->handshake->resume = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker48916f92012-09-16 19:57:18 +00001379 ssl->session_negotiate->start = time( NULL );
Paul Bakkerfa9b1002013-07-03 15:31:03 +02001380#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001381 ssl->session_negotiate->ciphersuite = i;
1382 ssl->session_negotiate->compression = comp;
1383 ssl->session_negotiate->length = n;
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001384 memcpy( ssl->session_negotiate->id, buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 }
1386 else
1387 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001391 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001393 return( ret );
1394 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001395 }
1396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397 MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
Paul Bakker0a597072012-09-25 21:55:46 +00001398 ssl->handshake->resume ? "a" : "no" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) );
1401 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001403 suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001404 if( suite_info == NULL ||
1405 ( ssl->arc4_disabled &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001407 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1409 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001410 }
1411
1412
Paul Bakker5121ce52009-01-03 21:22:43 +00001413 i = 0;
1414 while( 1 )
1415 {
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001416 if( ssl->ciphersuite_list[ssl->minor_ver][i] == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001417 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1419 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001420 }
1421
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001422 if( ssl->ciphersuite_list[ssl->minor_ver][i++] ==
1423 ssl->session_negotiate->ciphersuite )
1424 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001425 break;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001426 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001427 }
1428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429 if( comp != MBEDTLS_SSL_COMPRESS_NULL
1430#if defined(MBEDTLS_ZLIB_SUPPORT)
1431 && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
Paul Bakker2770fbd2012-07-03 13:30:23 +00001432#endif
1433 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1436 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001437 }
Paul Bakker48916f92012-09-16 19:57:18 +00001438 ssl->session_negotiate->compression = comp;
Paul Bakker5121ce52009-01-03 21:22:43 +00001439
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001440 ext = buf + 40 + n;
Paul Bakker48916f92012-09-16 19:57:18 +00001441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +02001443
Paul Bakker48916f92012-09-16 19:57:18 +00001444 while( ext_len )
1445 {
1446 unsigned int ext_id = ( ( ext[0] << 8 )
1447 | ( ext[1] ) );
1448 unsigned int ext_size = ( ( ext[2] << 8 )
1449 | ( ext[3] ) );
1450
1451 if( ext_size + 4 > ext_len )
1452 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1454 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001455 }
1456
1457 switch( ext_id )
1458 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459 case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1460 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
1461#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001462 renegotiation_info_seen = 1;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001463#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001464
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001465 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
1466 ext_size ) ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001467 return( ret );
1468
1469 break;
1470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1472 case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1473 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001474
1475 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
1476 ext + 4, ext_size ) ) != 0 )
1477 {
1478 return( ret );
1479 }
1480
1481 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1485 case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
1486 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001487
1488 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
1489 ext + 4, ext_size ) ) != 0 )
1490 {
1491 return( ret );
1492 }
1493
1494 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1498 case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1499 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001500
1501 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
1502 ext + 4, ext_size ) ) != 0 )
1503 {
1504 return( ret );
1505 }
1506
1507 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001510#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1511 case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1512 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001513
1514 if( ( ret = ssl_parse_extended_ms_ext( ssl,
1515 ext + 4, ext_size ) ) != 0 )
1516 {
1517 return( ret );
1518 }
1519
1520 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1524 case MBEDTLS_TLS_EXT_SESSION_TICKET:
1525 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001526
1527 if( ( ret = ssl_parse_session_ticket_ext( ssl,
1528 ext + 4, ext_size ) ) != 0 )
1529 {
1530 return( ret );
1531 }
1532
1533 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
1537 case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1538 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001539
1540 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
1541 ext + 4, ext_size ) ) != 0 )
1542 {
1543 return( ret );
1544 }
1545
1546 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549#if defined(MBEDTLS_SSL_ALPN)
1550 case MBEDTLS_TLS_EXT_ALPN:
1551 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001552
1553 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
1554 return( ret );
1555
1556 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001558
Paul Bakker48916f92012-09-16 19:57:18 +00001559 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001560 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
Paul Bakker48916f92012-09-16 19:57:18 +00001561 ext_id ) );
1562 }
1563
1564 ext_len -= 4 + ext_size;
1565 ext += 4 + ext_size;
1566
1567 if( ext_len > 0 && ext_len < 4 )
1568 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1570 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001571 }
1572 }
1573
1574 /*
1575 * Renegotiation security checks
1576 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577 if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1578 ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001579 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001581 handshake_failure = 1;
Paul Bakkerf7abd422013-04-16 13:15:56 +02001582 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583#if defined(MBEDTLS_SSL_RENEGOTIATION)
1584 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1585 ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001586 renegotiation_info_seen == 0 )
1587 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001588 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001589 handshake_failure = 1;
Paul Bakker48916f92012-09-16 19:57:18 +00001590 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001591 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1592 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1593 ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
Paul Bakker48916f92012-09-16 19:57:18 +00001594 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001596 handshake_failure = 1;
1597 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001598 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1599 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001600 renegotiation_info_seen == 1 )
1601 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001602 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001603 handshake_failure = 1;
1604 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001605#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001606
1607 if( handshake_failure == 1 )
1608 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001610 return( ret );
1611
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001613 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001615 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001616
1617 return( 0 );
1618}
1619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001620#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1621 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1622static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
Paul Bakker29e1f122013-04-16 13:07:56 +02001623 unsigned char *end )
1624{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001625 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001626
Paul Bakker29e1f122013-04-16 13:07:56 +02001627 /*
1628 * Ephemeral DH parameters:
1629 *
1630 * struct {
1631 * opaque dh_p<1..2^16-1>;
1632 * opaque dh_g<1..2^16-1>;
1633 * opaque dh_Ys<1..2^16-1>;
1634 * } ServerDHParams;
1635 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001636 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001637 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001638 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001639 return( ret );
1640 }
1641
1642 if( ssl->handshake->dhm_ctx.len < 64 ||
1643 ssl->handshake->dhm_ctx.len > 512 )
1644 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001645 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) );
1646 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001647 }
1648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001649 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
1650 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
1651 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
Paul Bakker29e1f122013-04-16 13:07:56 +02001652
1653 return( ret );
1654}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001655#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1656 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001658#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1659 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1660 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
1661 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1662 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1663static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001664{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665 const mbedtls_ecp_curve_info *curve_info;
Manuel Pégourié-Gonnardc3f6b622014-02-06 10:13:09 +01001666
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001667 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
Manuel Pégourié-Gonnardc3f6b622014-02-06 10:13:09 +01001668 if( curve_info == NULL )
1669 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001670 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1671 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardc3f6b622014-02-06 10:13:09 +01001672 }
1673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001674 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001675
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001676#if defined(MBEDTLS_SSL_SET_CURVES)
1677 if( ! mbedtls_ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001678#else
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001679 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
1680 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001681#endif
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001682 return( -1 );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001685
1686 return( 0 );
1687}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1689 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1690 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
1691 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1692 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001694#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1695 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1696 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
1697static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001698 unsigned char **p,
1699 unsigned char *end )
1700{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001701 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001702
Paul Bakker29e1f122013-04-16 13:07:56 +02001703 /*
1704 * Ephemeral ECDH parameters:
1705 *
1706 * struct {
1707 * ECParameters curve_params;
1708 * ECPoint public;
1709 * } ServerECDHParams;
1710 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001711 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
Paul Bakker29e1f122013-04-16 13:07:56 +02001712 (const unsigned char **) p, end ) ) != 0 )
1713 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001714 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001715 return( ret );
1716 }
1717
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001718 if( ssl_check_server_ecdh_params( ssl ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001719 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001720 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
1721 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001722 }
1723
Paul Bakker29e1f122013-04-16 13:07:56 +02001724 return( ret );
1725}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001726#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1727 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1728 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001729
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001730#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1731static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001732 unsigned char **p,
1733 unsigned char *end )
1734{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001735 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001736 size_t len;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001737 ((void) ssl);
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001738
1739 /*
1740 * PSK parameters:
1741 *
1742 * opaque psk_identity_hint<0..2^16-1>;
1743 */
Manuel Pégourié-Gonnard59b9fe22013-10-15 11:55:33 +02001744 len = (*p)[0] << 8 | (*p)[1];
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001745 *p += 2;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001746
1747 if( (*p) + len > end )
1748 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
1750 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001751 }
1752
1753 // TODO: Retrieve PSK identity hint and callback to app
1754 //
1755 *p += len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001756 ret = 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001757
1758 return( ret );
1759}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001760#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001761
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001762#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
1763 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001764/*
1765 * Generate a pre-master secret and encrypt it with the server's RSA key
1766 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001767static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001768 size_t offset, size_t *olen,
1769 size_t pms_offset )
1770{
1771 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001772 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001773 unsigned char *p = ssl->handshake->premaster + pms_offset;
1774
1775 /*
1776 * Generate (part of) the pre-master as
1777 * struct {
1778 * ProtocolVersion client_version;
1779 * opaque random[46];
1780 * } PreMasterSecret;
1781 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001782 mbedtls_ssl_write_version( ssl->max_major_ver, ssl->max_minor_ver,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001783 ssl->transport, p );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001784
1785 if( ( ret = ssl->f_rng( ssl->p_rng, p + 2, 46 ) ) != 0 )
1786 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001788 return( ret );
1789 }
1790
1791 ssl->handshake->pmslen = 48;
1792
1793 /*
1794 * Now write it out, encrypted
1795 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001796 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
1797 MBEDTLS_PK_RSA ) )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001798 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
1800 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001801 }
1802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001803 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001804 p, ssl->handshake->pmslen,
1805 ssl->out_msg + offset + len_bytes, olen,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001806 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001807 ssl->f_rng, ssl->p_rng ) ) != 0 )
1808 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001809 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001810 return( ret );
1811 }
1812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001813#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1814 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001815 if( len_bytes == 2 )
1816 {
1817 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
1818 ssl->out_msg[offset+1] = (unsigned char)( *olen );
1819 *olen += 2;
1820 }
1821#endif
1822
1823 return( 0 );
1824}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
1826 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001827
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1829#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1830 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1831 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
1832static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001833 unsigned char **p,
1834 unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835 mbedtls_md_type_t *md_alg,
1836 mbedtls_pk_type_t *pk_alg )
Paul Bakker29e1f122013-04-16 13:07:56 +02001837{
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001838 ((void) ssl);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 *md_alg = MBEDTLS_MD_NONE;
1840 *pk_alg = MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001841
1842 /* Only in TLS 1.2 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001844 {
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001845 return( 0 );
1846 }
Paul Bakker29e1f122013-04-16 13:07:56 +02001847
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001848 if( (*p) + 2 > end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001850
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001851 /*
1852 * Get hash algorithm
1853 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02001855 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001856 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02001857 "HashAlgorithm %d", *(p)[0] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001858 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001859 }
1860
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001861 /*
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001862 * Get signature algorithm
1863 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02001865 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02001867 "SignatureAlgorithm %d", (*p)[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001869 }
1870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001871 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
1872 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02001873 *p += 2;
1874
1875 return( 0 );
1876}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1878 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1879 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
1880#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02001881
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001883#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1884 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1885static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001886{
1887 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001888 const mbedtls_ecp_keypair *peer_key;
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001889
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001890 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
1891 MBEDTLS_PK_ECKEY ) )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001892 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001893 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
1894 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001895 }
1896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001897 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001899 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
1900 MBEDTLS_ECDH_THEIRS ) ) != 0 )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001901 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001902 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001903 return( ret );
1904 }
1905
1906 if( ssl_check_server_ecdh_params( ssl ) != 0 )
1907 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
1909 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001910 }
1911
1912 return( ret );
1913}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001914#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
1915 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001916
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001917static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker41c83d32013-03-20 14:39:14 +01001918{
Paul Bakker23986e52011-04-24 08:57:21 +00001919 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001920 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001921 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001923 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001925#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
1926 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00001927 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001928 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001929 ssl->state++;
1930 return( 0 );
1931 }
Manuel Pégourié-Gonnardbac0e3b2013-10-15 11:54:47 +02001932 ((void) p);
1933 ((void) end);
1934#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001936#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1937 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1938 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
1939 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001940 {
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001941 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
1942 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001943 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001944 return( ret );
1945 }
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001947 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001948 ssl->state++;
1949 return( 0 );
1950 }
1951 ((void) p);
1952 ((void) end);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001953#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1954 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001958 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 return( ret );
1960 }
1961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001962 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001964 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
1965 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 }
1967
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001968 /*
1969 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
1970 * doesn't use a psk_identity_hint
1971 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001972 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001973 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001974 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
1975 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Paul Bakker188c8de2013-04-19 09:13:37 +02001976 {
1977 ssl->record_read = 1;
1978 goto exit;
1979 }
1980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001981 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
1982 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 }
1984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001985 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01001986 end = ssl->in_msg + ssl->in_hslen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001987 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01001988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001989#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1990 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
1991 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
1992 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
1993 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001994 {
1995 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
1996 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001997 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
1998 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001999 }
2000 } /* FALLTROUGH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
2004 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2005 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2006 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002007 ; /* nothing more to do */
2008 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
2010 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2011#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2012 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2013 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2014 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker5121ce52009-01-03 21:22:43 +00002015 {
Paul Bakker29e1f122013-04-16 13:07:56 +02002016 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002017 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002018 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2019 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002020 }
2021 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002022 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2024 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2025#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2026 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
2027 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2028 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2029 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2030 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002031 {
2032 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
2033 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002034 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2035 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002036 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002037 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002038 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2040 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2041 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker41c83d32013-03-20 14:39:14 +01002042 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002043 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2044 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002045 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002047#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2048 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2049 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2050 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2051 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2052 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002053 {
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002054 size_t sig_len, hashlen;
2055 unsigned char hash[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2057 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2058 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002059 size_t params_len = p - params;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002060
Paul Bakker29e1f122013-04-16 13:07:56 +02002061 /*
2062 * Handle the digitally-signed structure
2063 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002064#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2065 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002066 {
Paul Bakker9659dae2013-08-28 16:21:34 +02002067 if( ssl_parse_signature_algorithm( ssl, &p, end,
2068 &md_alg, &pk_alg ) != 0 )
2069 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002070 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2071 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker9659dae2013-08-28 16:21:34 +02002072 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002074 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002075 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2077 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002078 }
2079 }
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002080 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002081#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2082#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2083 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2084 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002085 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002086 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002087
Paul Bakker9659dae2013-08-28 16:21:34 +02002088 /* Default hash for ECDSA is SHA-1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
2090 md_alg = MBEDTLS_MD_SHA1;
Paul Bakker9659dae2013-08-28 16:21:34 +02002091 }
2092 else
2093#endif
2094 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2096 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker9659dae2013-08-28 16:21:34 +02002097 }
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002098
2099 /*
2100 * Read signature
2101 */
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002102 sig_len = ( p[0] << 8 ) | p[1];
Paul Bakker1ef83d62012-04-11 12:09:53 +00002103 p += 2;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002104
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002105 if( end != p + sig_len )
Paul Bakker41c83d32013-03-20 14:39:14 +01002106 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2108 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002111 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002112
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002113 /*
2114 * Compute the hash that has been signed
2115 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002116#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2117 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2118 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002119 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002120 mbedtls_md5_context mbedtls_md5;
2121 mbedtls_sha1_context mbedtls_sha1;
Paul Bakker29e1f122013-04-16 13:07:56 +02002122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123 mbedtls_md5_init( &mbedtls_md5 );
2124 mbedtls_sha1_init( &mbedtls_sha1 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002125
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002126 hashlen = 36;
2127
Paul Bakker29e1f122013-04-16 13:07:56 +02002128 /*
2129 * digitally-signed struct {
2130 * opaque md5_hash[16];
2131 * opaque sha_hash[20];
2132 * };
2133 *
2134 * md5_hash
2135 * MD5(ClientHello.random + ServerHello.random
2136 * + ServerParams);
2137 * sha_hash
2138 * SHA(ClientHello.random + ServerHello.random
2139 * + ServerParams);
2140 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002141 mbedtls_md5_starts( &mbedtls_md5 );
2142 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
2143 mbedtls_md5_update( &mbedtls_md5, params, params_len );
2144 mbedtls_md5_finish( &mbedtls_md5, hash );
Paul Bakker29e1f122013-04-16 13:07:56 +02002145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002146 mbedtls_sha1_starts( &mbedtls_sha1 );
2147 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
2148 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
2149 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 mbedtls_md5_free( &mbedtls_md5 );
2152 mbedtls_sha1_free( &mbedtls_sha1 );
Paul Bakker29e1f122013-04-16 13:07:56 +02002153 }
2154 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2156 MBEDTLS_SSL_PROTO_TLS1_1 */
2157#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2158 defined(MBEDTLS_SSL_PROTO_TLS1_2)
2159 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002160 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002161 mbedtls_md_context_t ctx;
Paul Bakker29e1f122013-04-16 13:07:56 +02002162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002163 mbedtls_md_init( &ctx );
Paul Bakker84bbeb52014-07-01 14:53:22 +02002164
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002165 /* Info from md_alg will be used instead */
2166 hashlen = 0;
Paul Bakker29e1f122013-04-16 13:07:56 +02002167
2168 /*
2169 * digitally-signed struct {
2170 * opaque client_random[32];
2171 * opaque server_random[32];
2172 * ServerDHParams params;
2173 * };
2174 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 if( ( ret = mbedtls_md_setup( &ctx,
2176 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02002177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02002179 return( ret );
2180 }
2181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182 mbedtls_md_starts( &ctx );
2183 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
2184 mbedtls_md_update( &ctx, params, params_len );
2185 mbedtls_md_finish( &ctx, hash );
2186 mbedtls_md_free( &ctx );
Paul Bakker29e1f122013-04-16 13:07:56 +02002187 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002188 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002189#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2190 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002191 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002192 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2193 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002194 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002196 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
2197 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002198
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002199 /*
2200 * Verify signature
2201 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002202 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002203 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002204 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2205 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002206 }
2207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002208 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard20846b12013-08-19 12:32:12 +02002209 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002210 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002211 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002212 return( ret );
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002213 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002214 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002215#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2216 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2217 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002218
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002219exit:
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 ssl->state++;
2221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002222 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002223
2224 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002225}
2226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002227#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2228 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2229 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2230 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2231static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002232{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002233 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002237 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2238 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2239 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2240 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002241 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002243 ssl->state++;
2244 return( 0 );
2245 }
2246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002247 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2248 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002249}
2250#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002252{
2253 int ret;
Paul Bakker926af752012-11-23 13:38:07 +01002254 unsigned char *buf, *p;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002255 size_t n = 0, m = 0;
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002256 size_t cert_type_len = 0, dn_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002257 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002261 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2262 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2263 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2264 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002265 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002266 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002267 ssl->state++;
2268 return( 0 );
2269 }
2270
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002271 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002272 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002273 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002274 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002275 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002276 return( ret );
2277 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002279 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002280 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002281 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2282 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002283 }
2284
2285 ssl->record_read = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002286 }
2287
2288 ssl->client_auth = 0;
2289 ssl->state++;
2290
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002291 if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
Paul Bakker5121ce52009-01-03 21:22:43 +00002292 ssl->client_auth++;
2293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002294 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
Paul Bakker5121ce52009-01-03 21:22:43 +00002295 ssl->client_auth ? "a" : "no" ) );
2296
Paul Bakker926af752012-11-23 13:38:07 +01002297 if( ssl->client_auth == 0 )
2298 goto exit;
2299
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002300 ssl->record_read = 0;
2301
Paul Bakker926af752012-11-23 13:38:07 +01002302 // TODO: handshake_failure alert for an anonymous server to request
2303 // client authentication
2304
Manuel Pégourié-Gonnard04c1b4e2014-09-10 19:25:43 +02002305 /*
2306 * struct {
2307 * ClientCertificateType certificate_types<1..2^8-1>;
2308 * SignatureAndHashAlgorithm
2309 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2310 * DistinguishedName certificate_authorities<0..2^16-1>;
2311 * } CertificateRequest;
2312 */
Paul Bakker926af752012-11-23 13:38:07 +01002313 buf = ssl->in_msg;
Paul Bakkerf7abd422013-04-16 13:15:56 +02002314
Paul Bakker926af752012-11-23 13:38:07 +01002315 // Retrieve cert types
2316 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
Paul Bakker926af752012-11-23 13:38:07 +01002318 n = cert_type_len;
2319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002321 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2323 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002324 }
2325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002326 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
Paul Bakker926af752012-11-23 13:38:07 +01002327 while( cert_type_len > 0 )
2328 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002329#if defined(MBEDTLS_RSA_C)
2330 if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
2331 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
Paul Bakker926af752012-11-23 13:38:07 +01002332 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
Paul Bakker926af752012-11-23 13:38:07 +01002334 break;
2335 }
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002336 else
2337#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338#if defined(MBEDTLS_ECDSA_C)
2339 if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
2340 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002341 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002342 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002343 break;
2344 }
2345 else
2346#endif
2347 {
2348 ; /* Unsupported cert type, ignore */
2349 }
Paul Bakker926af752012-11-23 13:38:07 +01002350
2351 cert_type_len--;
2352 p++;
2353 }
2354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002355#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2356 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002357 {
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002358 /* Ignored, see comments about hash in write_certificate_verify */
2359 // TODO: should check the signature part against our pk_key though
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002360 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
2361 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002363 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002364 m += 2;
Paul Bakker926af752012-11-23 13:38:07 +01002365 n += sig_alg_len;
2366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002367 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002368 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002369 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2370 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002371 }
Paul Bakkerf7abd422013-04-16 13:15:56 +02002372 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002373#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker926af752012-11-23 13:38:07 +01002374
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002375 /* Ignore certificate_authorities, we only have one cert anyway */
2376 // TODO: should not send cert if no CA matches
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002377 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
2378 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002379
2380 n += dn_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002381 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
Paul Bakker926af752012-11-23 13:38:07 +01002382 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002383 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2384 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002385 }
2386
2387exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002388 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002389
2390 return( 0 );
2391}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002392#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2393 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2394 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
2395 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002397static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002398{
2399 int ret;
2400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002401 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002402
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002403 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002404 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002405 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002406 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002407 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002408 return( ret );
2409 }
2410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002411 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002412 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002413 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2414 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002415 }
2416 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002417 ssl->record_read = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
2420 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002421 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002422 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2423 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002424 }
2425
2426 ssl->state++;
2427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002428#if defined(MBEDTLS_SSL_PROTO_DTLS)
2429 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
2430 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002431#endif
2432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002433 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002434
2435 return( 0 );
2436}
2437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002438static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002439{
Paul Bakker23986e52011-04-24 08:57:21 +00002440 int ret;
2441 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002442 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002444 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002446#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2447 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002448 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002449 /*
2450 * DHM key exchange -- send G^X mod P
2451 */
Paul Bakker48916f92012-09-16 19:57:18 +00002452 n = ssl->handshake->dhm_ctx.len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002453
2454 ssl->out_msg[4] = (unsigned char)( n >> 8 );
2455 ssl->out_msg[5] = (unsigned char)( n );
2456 i = 6;
2457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002458 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2459 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Paul Bakker5121ce52009-01-03 21:22:43 +00002460 &ssl->out_msg[i], n,
2461 ssl->f_rng, ssl->p_rng );
2462 if( ret != 0 )
2463 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002464 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002465 return( ret );
2466 }
2467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002468 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
2469 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
Paul Bakker5121ce52009-01-03 21:22:43 +00002470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002471 ssl->handshake->pmslen = MBEDTLS_PREMASTER_SIZE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002473 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
Paul Bakker48916f92012-09-16 19:57:18 +00002474 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +02002475 &ssl->handshake->pmslen,
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +02002476 ssl->f_rng, ssl->p_rng ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002477 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002478 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002479 return( ret );
2480 }
2481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002482 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
Paul Bakker5121ce52009-01-03 21:22:43 +00002483 }
2484 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002485#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2486#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2487 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
2488 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2489 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2490 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2491 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2492 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2493 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Paul Bakker41c83d32013-03-20 14:39:14 +01002494 {
2495 /*
2496 * ECDH key exchange -- send client public value
2497 */
2498 i = 4;
2499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002500 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002501 &n,
2502 &ssl->out_msg[i], 1000,
2503 ssl->f_rng, ssl->p_rng );
2504 if( ret != 0 )
2505 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002506 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002507 return( ret );
2508 }
2509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002510 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Paul Bakker41c83d32013-03-20 14:39:14 +01002511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002512 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002513 &ssl->handshake->pmslen,
2514 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002515 MBEDTLS_MPI_MAX_SIZE,
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02002516 ssl->f_rng, ssl->p_rng ) ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002517 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002518 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002519 return( ret );
2520 }
2521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002522 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
Paul Bakker41c83d32013-03-20 14:39:14 +01002523 }
2524 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002525#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2526 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2527 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2528 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2529#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2530 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2531 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2532 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2533 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002534 {
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002535 /*
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002536 * opaque psk_identity<0..2^16-1>;
2537 */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002538 if( ssl->psk == NULL || ssl->psk_identity == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002539 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002540
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002541 i = 4;
2542 n = ssl->psk_identity_len;
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002543 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2544 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002545
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002546 memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len );
2547 i += ssl->psk_identity_len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002549#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
2550 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002551 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002552 n = 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002553 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002554 else
2555#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002556#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2557 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002558 {
2559 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
2560 return( ret );
2561 }
2562 else
2563#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002564#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2565 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002566 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002567 /*
2568 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
2569 */
2570 n = ssl->handshake->dhm_ctx.len;
2571 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2572 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002573
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002574 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2575 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002576 &ssl->out_msg[i], n,
2577 ssl->f_rng, ssl->p_rng );
2578 if( ret != 0 )
2579 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002580 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002581 return( ret );
2582 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002583 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002584 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002585#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2586#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2587 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002588 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002589 /*
2590 * ClientECDiffieHellmanPublic public;
2591 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002592 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
2593 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002594 ssl->f_rng, ssl->p_rng );
2595 if( ret != 0 )
2596 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002597 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002598 return( ret );
2599 }
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002602 }
2603 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002604#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002605 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002606 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2607 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002608 }
2609
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002610 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002611 ciphersuite_info->key_exchange ) ) != 0 )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002612 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002613 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002614 return( ret );
2615 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002616 }
2617 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002618#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
2619#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2620 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002621 {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002622 i = 4;
2623 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
Paul Bakkera3d195c2011-11-27 21:07:34 +00002624 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002625 }
Paul Bakkered27a042013-04-18 22:46:23 +02002626 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002627#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Paul Bakkered27a042013-04-18 22:46:23 +02002628 {
2629 ((void) ciphersuite_info);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002630 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2631 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkered27a042013-04-18 22:46:23 +02002632 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002633
Paul Bakker5121ce52009-01-03 21:22:43 +00002634 ssl->out_msglen = i + n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002635 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2636 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002637
2638 ssl->state++;
2639
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002640 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002641 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002642 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002643 return( ret );
2644 }
2645
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002646 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002647
2648 return( 0 );
2649}
2650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002651#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2652 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2653 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2654 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2655static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002656{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002657 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002658 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002660 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002662 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002663 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002664 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002665 return( ret );
2666 }
2667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002668 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2669 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2670 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2671 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakkered27a042013-04-18 22:46:23 +02002672 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002673 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakkered27a042013-04-18 22:46:23 +02002674 ssl->state++;
2675 return( 0 );
2676 }
2677
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002678 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2679 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002680}
2681#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002682static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002683{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002684 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
2685 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002686 size_t n = 0, offset = 0;
2687 unsigned char hash[48];
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002688 unsigned char *hash_start = hash;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002689 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002690 unsigned int hashlen;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002692 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002694 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002695 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002696 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002697 return( ret );
2698 }
2699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002700 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2701 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2702 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2703 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002704 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002705 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002706 ssl->state++;
2707 return( 0 );
2708 }
2709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002710 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00002711 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002712 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002713 ssl->state++;
2714 return( 0 );
2715 }
2716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002717 if( mbedtls_ssl_own_key( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00002718 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002719 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
2720 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002721 }
2722
2723 /*
2724 * Make an RSA signature of the handshake digests
2725 */
Paul Bakker48916f92012-09-16 19:57:18 +00002726 ssl->handshake->calc_verify( ssl, hash );
Paul Bakker5121ce52009-01-03 21:22:43 +00002727
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002728#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2729 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2730 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002731 {
Paul Bakker926af752012-11-23 13:38:07 +01002732 /*
2733 * digitally-signed struct {
2734 * opaque md5_hash[16];
2735 * opaque sha_hash[20];
2736 * };
2737 *
2738 * md5_hash
2739 * MD5(handshake_messages);
2740 *
2741 * sha_hash
2742 * SHA(handshake_messages);
2743 */
2744 hashlen = 36;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002745 md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002746
2747 /*
2748 * For ECDSA, default hash is SHA-1 only
2749 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002750 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002751 {
2752 hash_start += 16;
2753 hashlen -= 16;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002754 md_alg = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002755 }
Paul Bakker926af752012-11-23 13:38:07 +01002756 }
2757 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002758#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2759 MBEDTLS_SSL_PROTO_TLS1_1 */
2760#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2761 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002762 {
2763 /*
2764 * digitally-signed struct {
2765 * opaque handshake_messages[handshake_messages_length];
2766 * };
2767 *
2768 * Taking shortcut here. We assume that the server always allows the
2769 * PRF Hash function and has sent it in the allowed signature
2770 * algorithms list received in the Certificate Request message.
2771 *
2772 * Until we encounter a server that does not, we will take this
2773 * shortcut.
2774 *
2775 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
2776 * in order to satisfy 'weird' needs from the server side.
2777 */
Paul Bakkerb7149bc2013-03-20 15:30:09 +01002778 if( ssl->transform_negotiate->ciphersuite_info->mac ==
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002779 MBEDTLS_MD_SHA384 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00002780 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002781 md_alg = MBEDTLS_MD_SHA384;
2782 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
Paul Bakkerca4ab492012-04-18 14:23:57 +00002783 }
2784 else
2785 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002786 md_alg = MBEDTLS_MD_SHA256;
2787 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
Paul Bakkerca4ab492012-04-18 14:23:57 +00002788 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002789 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002790
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +02002791 /* Info from md_alg will be used instead */
2792 hashlen = 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002793 offset = 2;
2794 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002795 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002796#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02002797 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002798 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2799 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002800 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002802 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02002803 ssl->out_msg + 6 + offset, &n,
2804 ssl->f_rng, ssl->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002805 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002806 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02002807 return( ret );
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002808 }
Paul Bakker926af752012-11-23 13:38:07 +01002809
Paul Bakker1ef83d62012-04-11 12:09:53 +00002810 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
2811 ssl->out_msg[5 + offset] = (unsigned char)( n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002812
Paul Bakker1ef83d62012-04-11 12:09:53 +00002813 ssl->out_msglen = 6 + n + offset;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002814 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2815 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00002816
2817 ssl->state++;
2818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002819 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002820 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002821 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002822 return( ret );
2823 }
2824
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002825 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002826
Paul Bakkered27a042013-04-18 22:46:23 +02002827 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002828}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002829#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2830 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2831 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002833#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2834static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002835{
2836 int ret;
2837 uint32_t lifetime;
2838 size_t ticket_len;
2839 unsigned char *ticket;
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002840 const unsigned char *msg;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002842 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002844 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002845 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002846 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002847 return( ret );
2848 }
2849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002850 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002851 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002852 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2853 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002854 }
2855
2856 /*
2857 * struct {
2858 * uint32 ticket_lifetime_hint;
2859 * opaque ticket<0..2^16-1>;
2860 * } NewSessionTicket;
2861 *
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002862 * 0 . 3 ticket_lifetime_hint
2863 * 4 . 5 ticket_len (n)
2864 * 6 . 5+n ticket content
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002865 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002866 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
2867 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002868 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002869 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2870 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002871 }
2872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002873 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002874
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002875 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
2876 ( msg[2] << 8 ) | ( msg[3] );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002877
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002878 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
2879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002880 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002881 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002882 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2883 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002884 }
2885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002886 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002887
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02002888 /* We're not waiting for a NewSessionTicket message any more */
2889 ssl->handshake->new_session_ticket = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002890 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02002891
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002892 /*
2893 * Zero-length ticket means the server changed his mind and doesn't want
2894 * to send a ticket after all, so just forget it
2895 */
Paul Bakker66d5d072014-06-17 16:39:18 +02002896 if( ticket_len == 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002897 return( 0 );
2898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002899 mbedtls_zeroize( ssl->session_negotiate->ticket,
Paul Bakker34617722014-06-13 17:20:13 +02002900 ssl->session_negotiate->ticket_len );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002901 mbedtls_free( ssl->session_negotiate->ticket );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002902 ssl->session_negotiate->ticket = NULL;
2903 ssl->session_negotiate->ticket_len = 0;
2904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002905 if( ( ticket = mbedtls_malloc( ticket_len ) ) == NULL )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002906 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002907 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket malloc failed" ) );
2908 return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002909 }
2910
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002911 memcpy( ticket, msg + 6, ticket_len );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002912
2913 ssl->session_negotiate->ticket = ticket;
2914 ssl->session_negotiate->ticket_len = ticket_len;
2915 ssl->session_negotiate->ticket_lifetime = lifetime;
2916
2917 /*
2918 * RFC 5077 section 3.4:
2919 * "If the client receives a session ticket from the server, then it
2920 * discards any Session ID that was sent in the ServerHello."
2921 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002922 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002923 ssl->session_negotiate->length = 0;
2924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002925 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002926
2927 return( 0 );
2928}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002929#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002930
Paul Bakker5121ce52009-01-03 21:22:43 +00002931/*
Paul Bakker1961b702013-01-25 14:49:24 +01002932 * SSL handshake -- client side -- single step
Paul Bakker5121ce52009-01-03 21:22:43 +00002933 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002934int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002935{
2936 int ret = 0;
2937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002938 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
2939 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002940
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002941 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
Paul Bakker1961b702013-01-25 14:49:24 +01002942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002943 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker1961b702013-01-25 14:49:24 +01002944 return( ret );
2945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002946#if defined(MBEDTLS_SSL_PROTO_DTLS)
2947 if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002948 ssl->handshake != NULL &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002949 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002950 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002951 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002952 return( ret );
2953 }
2954#endif
2955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002956 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002957 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002958#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2959 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002960 ssl->handshake->new_session_ticket != 0 )
2961 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002962 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002963 }
2964#endif
2965
Paul Bakker1961b702013-01-25 14:49:24 +01002966 switch( ssl->state )
Paul Bakker5121ce52009-01-03 21:22:43 +00002967 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002968 case MBEDTLS_SSL_HELLO_REQUEST:
2969 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00002970 break;
2971
Paul Bakker1961b702013-01-25 14:49:24 +01002972 /*
2973 * ==> ClientHello
2974 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002975 case MBEDTLS_SSL_CLIENT_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01002976 ret = ssl_write_client_hello( ssl );
2977 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002978
Paul Bakker1961b702013-01-25 14:49:24 +01002979 /*
2980 * <== ServerHello
2981 * Certificate
2982 * ( ServerKeyExchange )
2983 * ( CertificateRequest )
2984 * ServerHelloDone
2985 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002986 case MBEDTLS_SSL_SERVER_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01002987 ret = ssl_parse_server_hello( ssl );
2988 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002990 case MBEDTLS_SSL_SERVER_CERTIFICATE:
2991 ret = mbedtls_ssl_parse_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01002992 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002994 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01002995 ret = ssl_parse_server_key_exchange( ssl );
2996 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002997
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002998 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
Paul Bakker1961b702013-01-25 14:49:24 +01002999 ret = ssl_parse_certificate_request( ssl );
3000 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003002 case MBEDTLS_SSL_SERVER_HELLO_DONE:
Paul Bakker1961b702013-01-25 14:49:24 +01003003 ret = ssl_parse_server_hello_done( ssl );
3004 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003005
Paul Bakker1961b702013-01-25 14:49:24 +01003006 /*
3007 * ==> ( Certificate/Alert )
3008 * ClientKeyExchange
3009 * ( CertificateVerify )
3010 * ChangeCipherSpec
3011 * Finished
3012 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003013 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3014 ret = mbedtls_ssl_write_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003015 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003017 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003018 ret = ssl_write_client_key_exchange( ssl );
3019 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003021 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
Paul Bakker1961b702013-01-25 14:49:24 +01003022 ret = ssl_write_certificate_verify( ssl );
3023 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003025 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3026 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003027 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003029 case MBEDTLS_SSL_CLIENT_FINISHED:
3030 ret = mbedtls_ssl_write_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003031 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003032
Paul Bakker1961b702013-01-25 14:49:24 +01003033 /*
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003034 * <== ( NewSessionTicket )
3035 * ChangeCipherSpec
Paul Bakker1961b702013-01-25 14:49:24 +01003036 * Finished
3037 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003038#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3039 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003040 ret = ssl_parse_new_session_ticket( ssl );
3041 break;
Paul Bakkera503a632013-08-14 13:48:06 +02003042#endif
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003044 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3045 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003046 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003048 case MBEDTLS_SSL_SERVER_FINISHED:
3049 ret = mbedtls_ssl_parse_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003050 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003052 case MBEDTLS_SSL_FLUSH_BUFFERS:
3053 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
3054 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Paul Bakker1961b702013-01-25 14:49:24 +01003055 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003057 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3058 mbedtls_ssl_handshake_wrapup( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003059 break;
Paul Bakker48916f92012-09-16 19:57:18 +00003060
Paul Bakker1961b702013-01-25 14:49:24 +01003061 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003062 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
3063 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1961b702013-01-25 14:49:24 +01003064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003065
3066 return( ret );
3067}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003068#endif /* MBEDTLS_SSL_CLI_C */