blob: e0ffbc605282b56337848729d785e3d441922bff [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"
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +020033#include "mbedtls/ssl_internal.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Rich Evans00ab4702015-02-06 13:43:58 +000035#include <string.h>
36
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/platform.h"
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020039#else
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020041#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#define mbedtls_free free
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020043#endif
44
Paul Bakkerfa6a6202013-10-28 18:48:30 +010045#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
Paul Bakkerfa9b1002013-07-03 15:31:03 +020046#include <basetsd.h>
47typedef UINT32 uint32_t;
48#else
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020049#include <stdint.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020050#endif
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000053#include <time.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020054#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Paul Bakker34617722014-06-13 17:20:13 +020057/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020059 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
60}
61#endif
62
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
64static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +010065 unsigned char *buf,
66 size_t *olen )
67{
68 unsigned char *p = buf;
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010069 size_t hostname_len;
Paul Bakkerd3edc862013-03-20 16:07:17 +010070
71 *olen = 0;
72
Paul Bakker66d5d072014-06-17 16:39:18 +020073 if( ssl->hostname == NULL )
Paul Bakkerd3edc862013-03-20 16:07:17 +010074 return;
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
Paul Bakkerd3edc862013-03-20 16:07:17 +010077 ssl->hostname ) );
78
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010079 hostname_len = strlen( ssl->hostname );
80
Paul Bakkerd3edc862013-03-20 16:07:17 +010081 /*
82 * struct {
83 * NameType name_type;
84 * select (name_type) {
85 * case host_name: HostName;
86 * } name;
87 * } ServerName;
88 *
89 * enum {
90 * host_name(0), (255)
91 * } NameType;
92 *
93 * opaque HostName<1..2^16-1>;
94 *
95 * struct {
96 * ServerName server_name_list<1..2^16-1>
97 * } ServerNameList;
98 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
100 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100101
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100102 *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
103 *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100104
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100105 *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
106 *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100109 *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
110 *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100111
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100112 memcpy( p, ssl->hostname, hostname_len );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100113
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100114 *olen = hostname_len + 9;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100115}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if defined(MBEDTLS_SSL_RENEGOTIATION)
119static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100120 unsigned char *buf,
121 size_t *olen )
122{
123 unsigned char *p = buf;
124
125 *olen = 0;
126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100128 return;
129
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200130 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100131
132 /*
133 * Secure renegotiation
134 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
136 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100137
138 *p++ = 0x00;
139 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
140 *p++ = ssl->verify_data_len & 0xFF;
141
142 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
143
144 *olen = 5 + ssl->verify_data_len;
145}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100147
Manuel Pégourié-Gonnardd9423232014-12-02 11:57:29 +0100148/*
149 * Only if we handle at least one key exchange that needs signatures.
150 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
152 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
153static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100154 unsigned char *buf,
155 size_t *olen )
156{
157 unsigned char *p = buf;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100158 size_t sig_alg_len = 0;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200159 const int *md;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5bfd9682014-06-24 15:18:11 +0200161 unsigned char *sig_alg_list = buf + 6;
162#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100163
164 *olen = 0;
165
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200166 if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100167 return;
168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100170
171 /*
172 * Prepare signature_algorithms extension (TLS 1.2)
173 */
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200174 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
175 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200177 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
178 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200179#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200180#if defined(MBEDTLS_RSA_C)
181 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
182 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200183#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200184 }
Paul Bakkerd3edc862013-03-20 16:07:17 +0100185
186 /*
187 * enum {
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200188 * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
189 * sha512(6), (255)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100190 * } HashAlgorithm;
191 *
192 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
193 * SignatureAlgorithm;
194 *
195 * struct {
196 * HashAlgorithm hash;
197 * SignatureAlgorithm signature;
198 * } SignatureAndHashAlgorithm;
199 *
200 * SignatureAndHashAlgorithm
201 * supported_signature_algorithms<2..2^16-2>;
202 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
204 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100205
206 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
207 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
208
209 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
210 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
211
Paul Bakkerd3edc862013-03-20 16:07:17 +0100212 *olen = 6 + sig_alg_len;
213}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
215 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100216
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
218static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100219 unsigned char *buf,
220 size_t *olen )
221{
222 unsigned char *p = buf;
Manuel Pégourié-Gonnard8e205fc2014-01-23 17:27:10 +0100223 unsigned char *elliptic_curve_list = p + 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100224 size_t elliptic_curve_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 const mbedtls_ecp_curve_info *info;
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200226#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 const mbedtls_ecp_group_id *grp_id;
Paul Bakker0910f322014-02-06 13:41:18 +0100228#else
229 ((void) ssl);
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100230#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100231
232 *olen = 0;
233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100235
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200236#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200237 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200238 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100240#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100242 {
243#endif
244
245 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
246 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200247 }
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200248
249 if( elliptic_curve_len == 0 )
250 return;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
253 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100254
255 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
256 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
257
258 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
259 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
260
Paul Bakkerd3edc862013-03-20 16:07:17 +0100261 *olen = 6 + elliptic_curve_len;
262}
263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100265 unsigned char *buf,
266 size_t *olen )
267{
268 unsigned char *p = buf;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +0200269 ((void) ssl);
Paul Bakkerd3edc862013-03-20 16:07:17 +0100270
271 *olen = 0;
272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
276 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100277
278 *p++ = 0x00;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100279 *p++ = 2;
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200280
281 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100283
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200284 *olen = 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100285}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
289static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200290 unsigned char *buf,
291 size_t *olen )
292{
293 unsigned char *p = buf;
294
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200295 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200296 *olen = 0;
297 return;
298 }
299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
303 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200304
305 *p++ = 0x00;
306 *p++ = 1;
307
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200308 *p++ = ssl->conf->mfl_code;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200309
310 *olen = 5;
311}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
315static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200316 unsigned char *buf, size_t *olen )
317{
318 unsigned char *p = buf;
319
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200320 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200321 {
322 *olen = 0;
323 return;
324 }
325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
329 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200330
331 *p++ = 0x00;
332 *p++ = 0x00;
333
334 *olen = 4;
335}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
339static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100340 unsigned char *buf, size_t *olen )
341{
342 unsigned char *p = buf;
343
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200344 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
345 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100346 {
347 *olen = 0;
348 return;
349 }
350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100352 "extension" ) );
353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
355 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100356
357 *p++ = 0x00;
358 *p++ = 0x00;
359
360 *olen = 4;
361}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
365static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200366 unsigned char *buf, size_t *olen )
367{
368 unsigned char *p = buf;
369
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200370 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
371 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200372 {
373 *olen = 0;
374 return;
375 }
376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200378 "extension" ) );
379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
381 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200382
383 *p++ = 0x00;
384 *p++ = 0x00;
385
386 *olen = 4;
387}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390#if defined(MBEDTLS_SSL_SESSION_TICKETS)
391static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200392 unsigned char *buf, size_t *olen )
393{
394 unsigned char *p = buf;
395 size_t tlen = ssl->session_negotiate->ticket_len;
396
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200397 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200398 {
399 *olen = 0;
400 return;
401 }
402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
406 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200407
408 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
409 *p++ = (unsigned char)( ( tlen ) & 0xFF );
410
411 *olen = 4;
412
413 if( ssl->session_negotiate->ticket == NULL ||
414 ssl->session_negotiate->ticket_len == 0 )
415 {
416 return;
417 }
418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200420
421 memcpy( p, ssl->session_negotiate->ticket, tlen );
422
423 *olen += tlen;
424}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427#if defined(MBEDTLS_SSL_ALPN)
428static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200429 unsigned char *buf, size_t *olen )
430{
431 unsigned char *p = buf;
432 const char **cur;
433
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200434 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200435 {
436 *olen = 0;
437 return;
438 }
439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
443 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200444
445 /*
446 * opaque ProtocolName<1..2^8-1>;
447 *
448 * struct {
449 * ProtocolName protocol_name_list<2..2^16-1>
450 * } ProtocolNameList;
451 */
452
453 /* Skip writing extension and list length for now */
454 p += 4;
455
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200456 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200457 {
458 *p = (unsigned char)( strlen( *cur ) & 0xFF );
459 memcpy( p + 1, *cur, *p );
460 p += 1 + *p;
461 }
462
463 *olen = p - buf;
464
465 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
466 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
467 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
468
469 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
470 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
471 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
472}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200474
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200475/*
476 * Generate random bytes for ClientHello
477 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478static int ssl_generate_random( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200479{
480 int ret;
481 unsigned char *p = ssl->handshake->randbytes;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200483 time_t t;
484#endif
485
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200486 /*
487 * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
488 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200490 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200491 ssl->handshake->verify_cookie != NULL )
492 {
493 return( 0 );
494 }
495#endif
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200498 t = time( NULL );
499 *p++ = (unsigned char)( t >> 24 );
500 *p++ = (unsigned char)( t >> 16 );
501 *p++ = (unsigned char)( t >> 8 );
502 *p++ = (unsigned char)( t );
503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200505#else
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100506 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200507 return( ret );
508
509 p += 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510#endif /* MBEDTLS_HAVE_TIME */
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200511
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100512 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200513 return( ret );
514
515 return( 0 );
516}
517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +0000519{
Paul Bakker23986e52011-04-24 08:57:21 +0000520 int ret;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100521 size_t i, n, olen, ext_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 unsigned char *buf;
Paul Bakker2fbefde2013-06-29 16:01:15 +0200523 unsigned char *p, *q;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200524 unsigned char offer_compress;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200525 const int *ciphersuites;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100530 if( ssl->conf->f_rng == NULL )
Paul Bakkera9a028e2013-11-21 17:31:06 +0100531 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
533 return( MBEDTLS_ERR_SSL_NO_RNG );
Paul Bakkera9a028e2013-11-21 17:31:06 +0100534 }
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536#if defined(MBEDTLS_SSL_RENEGOTIATION)
537 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100538#endif
Paul Bakker48916f92012-09-16 19:57:18 +0000539 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200540 ssl->major_ver = ssl->conf->min_major_ver;
541 ssl->minor_ver = ssl->conf->min_minor_ver;
Paul Bakker48916f92012-09-16 19:57:18 +0000542 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200544 if( ssl->conf->max_major_ver == 0 )
Paul Bakker490ecc82011-10-06 13:04:09 +0000545 {
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200546 MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
547 "consider using mbedtls_ssl_config_defaults()" ) );
548 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker490ecc82011-10-06 13:04:09 +0000549 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 /*
552 * 0 . 0 handshake type
553 * 1 . 3 handshake length
554 * 4 . 5 highest version supported
555 * 6 . 9 current UNIX time
556 * 10 . 37 random bytes
557 */
558 buf = ssl->out_msg;
559 p = buf + 4;
560
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200561 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
562 ssl->conf->transport, p );
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +0100563 p += 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 buf[4], buf[5] ) );
567
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200568 if( ( ret = ssl_generate_random( ssl ) ) != 0 )
569 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200571 return( ret );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200572 }
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200573
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200574 memcpy( p, ssl->handshake->randbytes, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200576 p += 32;
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 /*
579 * 38 . 38 session id length
580 * 39 . 39+n session id
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100581 * 39+n . 39+n DTLS only: cookie length (1 byte)
582 * 40+n . .. DTSL only: cookie
583 * .. . .. ciphersuitelist length (2 bytes)
584 * .. . .. ciphersuitelist
585 * .. . .. compression methods length (1 byte)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000586 * .. . .. compression methods
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100587 * .. . .. extensions length (2 bytes)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000588 * .. . .. extensions
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 */
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200590 n = ssl->session_negotiate->id_len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100592 if( n < 16 || n > 32 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593#if defined(MBEDTLS_SSL_RENEGOTIATION)
594 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100595#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000596 ssl->handshake->resume == 0 )
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200597 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 n = 0;
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200599 }
600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200602 /*
603 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
604 * generate and include a Session ID in the TLS ClientHello."
605 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606#if defined(MBEDTLS_SSL_RENEGOTIATION)
607 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000608#endif
Manuel Pégourié-Gonnardd2b35ec2015-03-10 11:40:43 +0000609 {
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000610 if( ssl->session_negotiate->ticket != NULL &&
611 ssl->session_negotiate->ticket_len != 0 )
612 {
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100613 ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200614
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000615 if( ret != 0 )
616 return( ret );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200617
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200618 ssl->session_negotiate->id_len = n = 32;
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000619 }
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200620 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 *p++ = (unsigned char) n;
624
625 for( i = 0; i < n; i++ )
Paul Bakker48916f92012-09-16 19:57:18 +0000626 *p++ = ssl->session_negotiate->id[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
629 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100631 /*
632 * DTLS cookie
633 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200635 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100636 {
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200637 if( ssl->handshake->verify_cookie == NULL )
638 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200640 *p++ = 0;
641 }
642 else
643 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200645 ssl->handshake->verify_cookie,
646 ssl->handshake->verify_cookie_len );
647
648 *p++ = ssl->handshake->verify_cookie_len;
649 memcpy( p, ssl->handshake->verify_cookie,
650 ssl->handshake->verify_cookie_len );
651 p += ssl->handshake->verify_cookie_len;
652 }
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100653 }
654#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Paul Bakker48916f92012-09-16 19:57:18 +0000656 /*
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100657 * Ciphersuite list
Paul Bakker48916f92012-09-16 19:57:18 +0000658 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200659 ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100660
661 /* Skip writing ciphersuite length for now */
662 n = 0;
663 q = p;
664 p += 2;
665
Paul Bakker2fbefde2013-06-29 16:01:15 +0200666 for( i = 0; ciphersuites[i] != 0; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200669
670 if( ciphersuite_info == NULL )
671 continue;
672
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200673 if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
674 ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
Paul Bakker2fbefde2013-06-29 16:01:15 +0200675 continue;
676
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200678 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
Manuel Pégourié-Gonnardd6664512014-02-06 13:26:57 +0100680 continue;
681#endif
682
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200683#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200684 if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100686 continue;
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200687#endif
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100688
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d",
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200690 ciphersuites[i] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Paul Bakker2fbefde2013-06-29 16:01:15 +0200692 n++;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200693 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
694 *p++ = (unsigned char)( ciphersuites[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 }
696
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000697 /*
698 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
699 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700#if defined(MBEDTLS_SSL_RENEGOTIATION)
701 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000702#endif
703 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
705 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000706 n++;
707 }
708
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200709 /* Some versions of OpenSSL don't handle it correctly if not at end */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
Manuel Pégourié-Gonnard684b0592015-05-06 09:27:31 +0100711 if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200712 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
714 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
715 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200716 n++;
717 }
718#endif
719
Paul Bakker2fbefde2013-06-29 16:01:15 +0200720 *q++ = (unsigned char)( n >> 7 );
721 *q++ = (unsigned char)( n << 1 );
722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200726 offer_compress = 1;
Paul Bakker2770fbd2012-07-03 13:30:23 +0000727#else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200728 offer_compress = 0;
729#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200731 /*
732 * We don't support compression with DTLS right now: is many records come
733 * in the same datagram, uncompressing one could overwrite the next one.
734 * We don't want to add complexity for handling that case unless there is
735 * an actual need for it.
736 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200738 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200739 offer_compress = 0;
740#endif
741
742 if( offer_compress )
743 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
745 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
746 MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200747
748 *p++ = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
750 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200751 }
752 else
753 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
755 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
756 MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200757
758 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200760 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
Paul Bakkerd3edc862013-03-20 16:07:17 +0100762 // First write extensions, then the total length
763 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100765 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
766 ext_len += olen;
Paul Bakker0be444a2013-08-27 21:55:01 +0200767#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100770 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
771 ext_len += olen;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100772#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
775 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100776 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
777 ext_len += olen;
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200778#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000779
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100781 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
782 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100783
Paul Bakkerd3edc862013-03-20 16:07:17 +0100784 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
785 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100786#endif
787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200789 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
790 ext_len += olen;
Paul Bakker05decb22013-08-15 13:33:48 +0200791#endif
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200794 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
795 ext_len += olen;
Paul Bakker1f2bc622013-08-15 13:45:55 +0200796#endif
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200797
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100799 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
800 ext_len += olen;
801#endif
802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200804 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
805 ext_len += olen;
806#endif
807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200809 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
810 ext_len += olen;
Paul Bakkera503a632013-08-14 13:48:06 +0200811#endif
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200814 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
815 ext_len += olen;
816#endif
817
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +0100818 /* olen unused if all extensions are disabled */
819 ((void) olen);
820
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000822 ext_len ) );
823
Paul Bakkera7036632014-04-30 10:15:38 +0200824 if( ext_len > 0 )
825 {
826 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
827 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
828 p += ext_len;
829 }
Paul Bakker41c83d32013-03-20 14:39:14 +0100830
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 ssl->out_msglen = p - buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
833 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
835 ssl->state++;
836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200838 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 mbedtls_ssl_send_flight_completed( ssl );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +0200840#endif
841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000843 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000845 return( ret );
846 }
847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
850 return( 0 );
851}
852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +0200854 const unsigned char *buf,
Paul Bakker48916f92012-09-16 19:57:18 +0000855 size_t len )
856{
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000857 int ret;
858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859#if defined(MBEDTLS_SSL_RENEGOTIATION)
860 if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +0000861 {
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100862 /* Check verify-data in constant-time. The length OTOH is no secret */
Paul Bakker48916f92012-09-16 19:57:18 +0000863 if( len != 1 + ssl->verify_data_len * 2 ||
864 buf[0] != ssl->verify_data_len * 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 mbedtls_ssl_safer_memcmp( buf + 1,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100866 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +0100868 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +0000869 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +0000873 return( ret );
874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +0000876 }
877 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100878 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100880 {
881 if( len != 1 || buf[0] != 0x00 )
882 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100886 return( ret );
887
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100889 }
890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100892 }
Paul Bakker48916f92012-09-16 19:57:18 +0000893
894 return( 0 );
895}
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
898static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +0200899 const unsigned char *buf,
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200900 size_t len )
901{
902 /*
903 * server should use the extension only if we did,
904 * and if so the server's value should match ours (and len is always 1)
905 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200906 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200907 len != 1 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200908 buf[0] != ssl->conf->mfl_code )
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200909 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +0200911 }
912
913 return( 0 );
914}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Paul Bakker48916f92012-09-16 19:57:18 +0000916
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
918static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200919 const unsigned char *buf,
920 size_t len )
921{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200922 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200923 len != 0 )
924 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200926 }
927
928 ((void) buf);
929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200931
932 return( 0 );
933}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
937static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100938 const unsigned char *buf,
939 size_t len )
940{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200941 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100943 len != 0 )
944 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100946 }
947
948 ((void) buf);
949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100951
952 return( 0 );
953}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
957static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200958 const unsigned char *buf,
959 size_t len )
960{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200961 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200963 len != 0 )
964 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200966 }
967
968 ((void) buf);
969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200971
972 return( 0 );
973}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976#if defined(MBEDTLS_SSL_SESSION_TICKETS)
977static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200978 const unsigned char *buf,
979 size_t len )
980{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200981 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200982 len != 0 )
983 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200985 }
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200986
987 ((void) buf);
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +0200988
989 ssl->handshake->new_session_ticket = 1;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200990
991 return( 0 );
992}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
996static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +0200997 const unsigned char *buf,
998 size_t len )
999{
1000 size_t list_size;
1001 const unsigned char *p;
1002
1003 list_size = buf[0];
1004 if( list_size + 1 != len )
1005 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1007 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001008 }
1009
Manuel Pégourié-Gonnardfd35af12014-06-23 14:10:13 +02001010 p = buf + 1;
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001011 while( list_size > 0 )
1012 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
1014 p[0] == MBEDTLS_ECP_PF_COMPRESSED )
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001015 {
Manuel Pégourié-Gonnard5734b2d2013-08-15 19:04:02 +02001016 ssl->handshake->ecdh_ctx.point_format = p[0];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001018 return( 0 );
1019 }
1020
1021 list_size--;
1022 p++;
1023 }
1024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
1026 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001027}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030#if defined(MBEDTLS_SSL_ALPN)
1031static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001032 const unsigned char *buf, size_t len )
1033{
1034 size_t list_len, name_len;
1035 const char **p;
1036
1037 /* If we didn't send it, the server shouldn't send it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001038 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001040
1041 /*
1042 * opaque ProtocolName<1..2^8-1>;
1043 *
1044 * struct {
1045 * ProtocolName protocol_name_list<2..2^16-1>
1046 * } ProtocolNameList;
1047 *
1048 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
1049 */
1050
1051 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
1052 if( len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001054
1055 list_len = ( buf[0] << 8 ) | buf[1];
1056 if( list_len != len - 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001058
1059 name_len = buf[2];
1060 if( name_len != list_len - 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001062
1063 /* Check that the server chosen protocol was in our list and save it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001064 for( p = ssl->conf->alpn_list; *p != NULL; p++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001065 {
1066 if( name_len == strlen( *p ) &&
1067 memcmp( buf + 3, *p, name_len ) == 0 )
1068 {
1069 ssl->alpn_chosen = *p;
1070 return( 0 );
1071 }
1072 }
1073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001075}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001077
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001078/*
1079 * Parse HelloVerifyRequest. Only called after verifying the HS type.
1080 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081#if defined(MBEDTLS_SSL_PROTO_DTLS)
1082static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001083{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001085 int major_ver, minor_ver;
1086 unsigned char cookie_len;
1087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001089
1090 /*
1091 * struct {
1092 * ProtocolVersion server_version;
1093 * opaque cookie<0..2^8-1>;
1094 * } HelloVerifyRequest;
1095 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096 MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001097 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001098 p += 2;
1099
Manuel Pégourié-Gonnardb35fe562014-08-09 17:00:46 +02001100 /*
1101 * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
1102 * even is lower than our min version.
1103 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
1105 minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001106 major_ver > ssl->conf->max_major_ver ||
1107 minor_ver > ssl->conf->max_minor_ver )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1112 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001115 }
1116
1117 cookie_len = *p++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118 MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001121
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02001122 ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001123 if( ssl->handshake->verify_cookie == NULL )
1124 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02001125 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02001126 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001127 }
1128
1129 memcpy( ssl->handshake->verify_cookie, p, cookie_len );
1130 ssl->handshake->verify_cookie_len = cookie_len;
1131
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02001132 /* Start over at ClientHello */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
1134 mbedtls_ssl_reset_checksum( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001139
1140 return( 0 );
1141}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145{
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001146 int ret, i;
Paul Bakker23986e52011-04-24 08:57:21 +00001147 size_t n;
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001148 size_t ext_len;
Paul Bakker48916f92012-09-16 19:57:18 +00001149 unsigned char *buf, *ext;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001150 unsigned char comp, accept_comp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001152 int renegotiation_info_seen = 0;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001153#endif
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001154 int handshake_failure = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155 const mbedtls_ssl_ciphersuite_t *suite_info;
1156#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001157 uint32_t t;
1158#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 buf = ssl->in_msg;
1163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001167 return( ret );
1168 }
1169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001171 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172#if defined(MBEDTLS_SSL_RENEGOTIATION)
1173 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001174 {
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001175 ssl->renego_records_seen++;
1176
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001177 if( ssl->conf->renego_max_records >= 0 &&
1178 ssl->renego_records_seen > ssl->conf->renego_max_records )
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001179 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001181 "but not honored by server" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001183 }
1184
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001185 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
1186 return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001187 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001189
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1191 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001192 }
1193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001194#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001195 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001197 if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001198 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001199 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
1200 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001201 return( ssl_parse_hello_verify_request( ssl ) );
1202 }
1203 else
1204 {
1205 /* We made it through the verification process */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001206 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001207 ssl->handshake->verify_cookie = NULL;
1208 ssl->handshake->verify_cookie_len = 0;
1209 }
1210 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00001212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213 if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
1214 buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1217 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001218 }
1219
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001220 /*
1221 * 0 . 1 server_version
1222 * 2 . 33 random (maybe including 4 bytes of Unix time)
1223 * 34 . 34 session_id length = n
1224 * 35 . 34+n session_id
1225 * 35+n . 36+n cipher_suite
1226 * 37+n . 37+n compression_method
1227 *
1228 * 38+n . 39+n extensions length (optional)
1229 * 40+n . .. extensions
1230 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001231 buf += mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001233 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
1234 mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001235 ssl->conf->transport, buf + 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001236
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001237 if( ssl->major_ver < ssl->conf->min_major_ver ||
1238 ssl->minor_ver < ssl->conf->min_minor_ver ||
1239 ssl->major_ver > ssl->conf->max_major_ver ||
1240 ssl->minor_ver > ssl->conf->max_minor_ver )
Paul Bakker1d29fb52012-09-28 13:28:45 +00001241 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001243 " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001244 ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001245 ssl->major_ver, ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001246 ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1249 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001252 }
1253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001254#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001255 t = ( (uint32_t) buf[2] << 24 )
1256 | ( (uint32_t) buf[3] << 16 )
1257 | ( (uint32_t) buf[4] << 8 )
1258 | ( (uint32_t) buf[5] );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001259 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
Paul Bakker87e5cda2012-01-14 18:14:15 +00001260#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001261
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001262 memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001263
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001264 n = buf[34];
Paul Bakker5121ce52009-01-03 21:22:43 +00001265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001267
Paul Bakker48916f92012-09-16 19:57:18 +00001268 if( n > 32 )
1269 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1271 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001272 }
1273
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001274 if( ssl->in_hslen > 39 + n )
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 {
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001276 ext_len = ( ( buf[38 + n] << 8 )
1277 | ( buf[39 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001278
Paul Bakker48916f92012-09-16 19:57:18 +00001279 if( ( ext_len > 0 && ext_len < 4 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001280 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
Paul Bakker48916f92012-09-16 19:57:18 +00001281 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1283 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001284 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001285 }
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001286 else if( ssl->in_hslen == 38 + n )
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001287 {
1288 ext_len = 0;
1289 }
1290 else
1291 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1293 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001294 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001295
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001296 /* ciphersuite (used later) */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001297 i = ( buf[35 + n] << 8 ) | buf[36 + n];
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001298
1299 /*
1300 * Read and check compression
1301 */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001302 comp = buf[37 + n];
Paul Bakker5121ce52009-01-03 21:22:43 +00001303
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001305 accept_comp = 1;
1306#else
1307 accept_comp = 0;
1308#endif
1309
1310 /* See comments in ssl_write_client_hello() */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001311#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001312 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001313 accept_comp = 0;
1314#endif
1315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001316 if( ( accept_comp == 0 && comp != MBEDTLS_SSL_COMPRESS_NULL ) ||
1317 ( comp != MBEDTLS_SSL_COMPRESS_NULL && comp != MBEDTLS_SSL_COMPRESS_DEFLATE ) )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001318 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001319 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
1320 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001321 }
1322
Paul Bakker380da532012-04-18 16:10:25 +00001323 /*
1324 * Initialize update checksum functions
1325 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001326 ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
Paul Bakker68884e32013-01-07 18:20:04 +01001327
1328 if( ssl->transform_negotiate->ciphersuite_info == NULL )
1329 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001330 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
1331 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker68884e32013-01-07 18:20:04 +01001332 }
Paul Bakker380da532012-04-18 16:10:25 +00001333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001334 mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
Manuel Pégourié-Gonnard3c599f12014-03-10 13:25:07 +01001335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001336 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
1337 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338
1339 /*
1340 * Check if the session can be resumed
1341 */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001342 if( ssl->handshake->resume == 0 || n == 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001343#if defined(MBEDTLS_SSL_RENEGOTIATION)
1344 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001345#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001346 ssl->session_negotiate->ciphersuite != i ||
1347 ssl->session_negotiate->compression != comp ||
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001348 ssl->session_negotiate->id_len != n ||
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001349 memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 {
1351 ssl->state++;
Paul Bakker0a597072012-09-25 21:55:46 +00001352 ssl->handshake->resume = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker48916f92012-09-16 19:57:18 +00001354 ssl->session_negotiate->start = time( NULL );
Paul Bakkerfa9b1002013-07-03 15:31:03 +02001355#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001356 ssl->session_negotiate->ciphersuite = i;
1357 ssl->session_negotiate->compression = comp;
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001358 ssl->session_negotiate->id_len = n;
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001359 memcpy( ssl->session_negotiate->id, buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 }
1361 else
1362 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001365 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001366 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001368 return( ret );
1369 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 }
1371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001372 MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
Paul Bakker0a597072012-09-25 21:55:46 +00001373 ssl->handshake->resume ? "a" : "no" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) );
1376 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378 suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02001379 if( suite_info == NULL
1380#if defined(MBEDTLS_ARC4_C)
1381 || ( ssl->conf->arc4_disabled &&
1382 suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
1383#endif
1384 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001385 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001386 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1387 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001388 }
1389
Paul Bakker5121ce52009-01-03 21:22:43 +00001390 i = 0;
1391 while( 1 )
1392 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001393 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001394 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001395 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1396 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001397 }
1398
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001399 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001400 ssl->session_negotiate->ciphersuite )
1401 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001402 break;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001403 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001404 }
1405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 if( comp != MBEDTLS_SSL_COMPRESS_NULL
1407#if defined(MBEDTLS_ZLIB_SUPPORT)
1408 && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
Paul Bakker2770fbd2012-07-03 13:30:23 +00001409#endif
1410 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001411 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001412 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1413 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001414 }
Paul Bakker48916f92012-09-16 19:57:18 +00001415 ssl->session_negotiate->compression = comp;
Paul Bakker5121ce52009-01-03 21:22:43 +00001416
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001417 ext = buf + 40 + n;
Paul Bakker48916f92012-09-16 19:57:18 +00001418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +02001420
Paul Bakker48916f92012-09-16 19:57:18 +00001421 while( ext_len )
1422 {
1423 unsigned int ext_id = ( ( ext[0] << 8 )
1424 | ( ext[1] ) );
1425 unsigned int ext_size = ( ( ext[2] << 8 )
1426 | ( ext[3] ) );
1427
1428 if( ext_size + 4 > ext_len )
1429 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1431 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001432 }
1433
1434 switch( ext_id )
1435 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001436 case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1437 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
1438#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001439 renegotiation_info_seen = 1;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001440#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001441
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001442 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
1443 ext_size ) ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001444 return( ret );
1445
1446 break;
1447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1449 case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1450 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001451
1452 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
1453 ext + 4, ext_size ) ) != 0 )
1454 {
1455 return( ret );
1456 }
1457
1458 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1462 case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
1463 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001464
1465 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
1466 ext + 4, ext_size ) ) != 0 )
1467 {
1468 return( ret );
1469 }
1470
1471 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1475 case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1476 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001477
1478 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
1479 ext + 4, ext_size ) ) != 0 )
1480 {
1481 return( ret );
1482 }
1483
1484 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1488 case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1489 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001490
1491 if( ( ret = ssl_parse_extended_ms_ext( ssl,
1492 ext + 4, ext_size ) ) != 0 )
1493 {
1494 return( ret );
1495 }
1496
1497 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1501 case MBEDTLS_TLS_EXT_SESSION_TICKET:
1502 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001503
1504 if( ( ret = ssl_parse_session_ticket_ext( ssl,
1505 ext + 4, ext_size ) ) != 0 )
1506 {
1507 return( ret );
1508 }
1509
1510 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001511#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
1514 case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1515 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001516
1517 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
1518 ext + 4, ext_size ) ) != 0 )
1519 {
1520 return( ret );
1521 }
1522
1523 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#if defined(MBEDTLS_SSL_ALPN)
1527 case MBEDTLS_TLS_EXT_ALPN:
1528 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001529
1530 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
1531 return( ret );
1532
1533 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001535
Paul Bakker48916f92012-09-16 19:57:18 +00001536 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
Paul Bakker48916f92012-09-16 19:57:18 +00001538 ext_id ) );
1539 }
1540
1541 ext_len -= 4 + ext_size;
1542 ext += 4 + ext_size;
1543
1544 if( ext_len > 0 && ext_len < 4 )
1545 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1547 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001548 }
1549 }
1550
1551 /*
1552 * Renegotiation security checks
1553 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554 if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001555 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001556 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001558 handshake_failure = 1;
Paul Bakkerf7abd422013-04-16 13:15:56 +02001559 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001560#if defined(MBEDTLS_SSL_RENEGOTIATION)
1561 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1562 ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001563 renegotiation_info_seen == 0 )
1564 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001565 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001566 handshake_failure = 1;
Paul Bakker48916f92012-09-16 19:57:18 +00001567 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001568 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1569 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001570 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
Paul Bakker48916f92012-09-16 19:57:18 +00001571 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001572 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001573 handshake_failure = 1;
1574 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1576 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001577 renegotiation_info_seen == 1 )
1578 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001580 handshake_failure = 1;
1581 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001582#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001583
1584 if( handshake_failure == 1 )
1585 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001587 return( ret );
1588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001590 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001591
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001592 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
1594 return( 0 );
1595}
1596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001597#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1598 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1599static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
Paul Bakker29e1f122013-04-16 13:07:56 +02001600 unsigned char *end )
1601{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001602 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001603
Paul Bakker29e1f122013-04-16 13:07:56 +02001604 /*
1605 * Ephemeral DH parameters:
1606 *
1607 * struct {
1608 * opaque dh_p<1..2^16-1>;
1609 * opaque dh_g<1..2^16-1>;
1610 * opaque dh_Ys<1..2^16-1>;
1611 * } ServerDHParams;
1612 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001613 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001614 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001615 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001616 return( ret );
1617 }
1618
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001619 if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
Paul Bakker29e1f122013-04-16 13:07:56 +02001620 {
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001621 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
1622 ssl->handshake->dhm_ctx.len * 8,
1623 ssl->conf->dhm_min_bitlen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001624 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001625 }
1626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001627 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
1628 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
1629 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
Paul Bakker29e1f122013-04-16 13:07:56 +02001630
1631 return( ret );
1632}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001633#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1634 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001636#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1637 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1638 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
1639 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1640 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1641static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001642{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001643 const mbedtls_ecp_curve_info *curve_info;
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001645 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001646 if( curve_info == NULL )
1647 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001648 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1649 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001650 }
1651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001652 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001653
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02001654#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02001655 if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001656#else
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001657 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
1658 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001659#endif
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001660 return( -1 );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001662 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001663
1664 return( 0 );
1665}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001666#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1667 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1668 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
1669 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1670 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001672#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1673 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1674 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
1675static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001676 unsigned char **p,
1677 unsigned char *end )
1678{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001679 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001680
Paul Bakker29e1f122013-04-16 13:07:56 +02001681 /*
1682 * Ephemeral ECDH parameters:
1683 *
1684 * struct {
1685 * ECParameters curve_params;
1686 * ECPoint public;
1687 * } ServerECDHParams;
1688 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001689 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
Paul Bakker29e1f122013-04-16 13:07:56 +02001690 (const unsigned char **) p, end ) ) != 0 )
1691 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001692 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001693 return( ret );
1694 }
1695
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001696 if( ssl_check_server_ecdh_params( ssl ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001697 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001698 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
1699 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001700 }
1701
Paul Bakker29e1f122013-04-16 13:07:56 +02001702 return( ret );
1703}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001704#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1705 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1706 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001707
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001708#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1709static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001710 unsigned char **p,
1711 unsigned char *end )
1712{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001713 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001714 size_t len;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001715 ((void) ssl);
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001716
1717 /*
1718 * PSK parameters:
1719 *
1720 * opaque psk_identity_hint<0..2^16-1>;
1721 */
Manuel Pégourié-Gonnard59b9fe22013-10-15 11:55:33 +02001722 len = (*p)[0] << 8 | (*p)[1];
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001723 *p += 2;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001724
1725 if( (*p) + len > end )
1726 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001727 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
1728 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001729 }
1730
1731 // TODO: Retrieve PSK identity hint and callback to app
1732 //
1733 *p += len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001734 ret = 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001735
1736 return( ret );
1737}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001738#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001739
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001740#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
1741 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001742/*
1743 * Generate a pre-master secret and encrypt it with the server's RSA key
1744 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001745static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001746 size_t offset, size_t *olen,
1747 size_t pms_offset )
1748{
1749 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001750 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001751 unsigned char *p = ssl->handshake->premaster + pms_offset;
1752
1753 /*
1754 * Generate (part of) the pre-master as
1755 * struct {
1756 * ProtocolVersion client_version;
1757 * opaque random[46];
1758 * } PreMasterSecret;
1759 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001760 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
1761 ssl->conf->transport, p );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001762
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01001763 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001764 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001765 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001766 return( ret );
1767 }
1768
1769 ssl->handshake->pmslen = 48;
1770
1771 /*
1772 * Now write it out, encrypted
1773 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001774 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
1775 MBEDTLS_PK_RSA ) )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001776 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001777 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
1778 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001779 }
1780
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001781 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001782 p, ssl->handshake->pmslen,
1783 ssl->out_msg + offset + len_bytes, olen,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001784 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01001785 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001786 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001788 return( ret );
1789 }
1790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001791#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1792 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001793 if( len_bytes == 2 )
1794 {
1795 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
1796 ssl->out_msg[offset+1] = (unsigned char)( *olen );
1797 *olen += 2;
1798 }
1799#endif
1800
1801 return( 0 );
1802}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001803#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
1804 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001806#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02001807#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001808static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001809 unsigned char **p,
1810 unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001811 mbedtls_md_type_t *md_alg,
1812 mbedtls_pk_type_t *pk_alg )
Paul Bakker29e1f122013-04-16 13:07:56 +02001813{
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001814 ((void) ssl);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001815 *md_alg = MBEDTLS_MD_NONE;
1816 *pk_alg = MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001817
1818 /* Only in TLS 1.2 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001819 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001820 {
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001821 return( 0 );
1822 }
Paul Bakker29e1f122013-04-16 13:07:56 +02001823
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001824 if( (*p) + 2 > end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001826
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001827 /*
1828 * Get hash algorithm
1829 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001830 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02001831 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02001833 "HashAlgorithm %d", *(p)[0] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001834 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001835 }
1836
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001837 /*
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02001838 * Get signature algorithm
1839 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001840 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02001841 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02001843 "SignatureAlgorithm %d", (*p)[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001844 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001845 }
1846
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02001847 /*
1848 * Check if the hash is acceptable
1849 */
1850 if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
1851 {
1852 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm "
1853 "that was not offered" ) );
1854 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
1855 }
1856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001857 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
1858 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02001859 *p += 2;
1860
1861 return( 0 );
1862}
Manuel Pégourié-Gonnard36a8b572015-06-17 12:43:26 +02001863#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02001865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1867 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1868static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001869{
1870 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001871 const mbedtls_ecp_keypair *peer_key;
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001873 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
1874 MBEDTLS_PK_ECKEY ) )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001875 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001876 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
1877 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001878 }
1879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001882 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
1883 MBEDTLS_ECDH_THEIRS ) ) != 0 )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001884 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001886 return( ret );
1887 }
1888
1889 if( ssl_check_server_ecdh_params( ssl ) != 0 )
1890 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001891 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
1892 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001893 }
1894
1895 return( ret );
1896}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001897#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
1898 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001899
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001900static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker41c83d32013-03-20 14:39:14 +01001901{
Paul Bakker23986e52011-04-24 08:57:21 +00001902 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001904 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
1909 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001911 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 ssl->state++;
1913 return( 0 );
1914 }
Manuel Pégourié-Gonnardbac0e3b2013-10-15 11:54:47 +02001915 ((void) p);
1916 ((void) end);
1917#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1920 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1921 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
1922 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001923 {
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001924 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
1925 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001926 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001927 return( ret );
1928 }
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001930 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001931 ssl->state++;
1932 return( 0 );
1933 }
1934 ((void) p);
1935 ((void) end);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001936#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1937 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001938
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001939 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001940 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001941 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001942 return( ret );
1943 }
1944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001946 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001947 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
1948 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 }
1950
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001951 /*
1952 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
1953 * doesn't use a psk_identity_hint
1954 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001955 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
1958 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Paul Bakker188c8de2013-04-19 09:13:37 +02001959 {
1960 ssl->record_read = 1;
1961 goto exit;
1962 }
1963
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é-Gonnard2cf5a7c2015-04-08 12:49:31 +02001968 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01001969 end = ssl->in_msg + ssl->in_hslen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001970 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01001971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001972#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1973 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
1974 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
1975 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
1976 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001977 {
1978 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
1979 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
1981 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001982 }
1983 } /* FALLTROUGH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001984#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001986#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
1987 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
1988 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
1989 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02001990 ; /* nothing more to do */
1991 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001992#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
1993 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
1994#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1995 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1996 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
1997 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker5121ce52009-01-03 21:22:43 +00001998 {
Paul Bakker29e1f122013-04-16 13:07:56 +02001999 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002000 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2002 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002003 }
2004 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002005 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002006#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2007 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2008#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2009 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
2010 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2011 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2012 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2013 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002014 {
2015 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
2016 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2018 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002019 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002020 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002021 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002022#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2023 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2024 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker41c83d32013-03-20 14:39:14 +01002025 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002026 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2027 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002028 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002030#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2031 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2032 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2033 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2034 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2035 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002036 {
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002037 size_t sig_len, hashlen;
2038 unsigned char hash[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2040 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2041 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002042 size_t params_len = p - params;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002043
Paul Bakker29e1f122013-04-16 13:07:56 +02002044 /*
2045 * Handle the digitally-signed structure
2046 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002047#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2048 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002049 {
Paul Bakker9659dae2013-08-28 16:21:34 +02002050 if( ssl_parse_signature_algorithm( ssl, &p, end,
2051 &md_alg, &pk_alg ) != 0 )
2052 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002053 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2054 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker9659dae2013-08-28 16:21:34 +02002055 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002058 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2060 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002061 }
2062 }
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002063 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002064#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2065#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2066 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2067 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002068 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002069 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002070
Paul Bakker9659dae2013-08-28 16:21:34 +02002071 /* Default hash for ECDSA is SHA-1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002072 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
2073 md_alg = MBEDTLS_MD_SHA1;
Paul Bakker9659dae2013-08-28 16:21:34 +02002074 }
2075 else
2076#endif
2077 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002078 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2079 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker9659dae2013-08-28 16:21:34 +02002080 }
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002081
2082 /*
2083 * Read signature
2084 */
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002085 sig_len = ( p[0] << 8 ) | p[1];
Paul Bakker1ef83d62012-04-11 12:09:53 +00002086 p += 2;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002087
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002088 if( end != p + sig_len )
Paul Bakker41c83d32013-03-20 14:39:14 +01002089 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002090 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2091 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002092 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002094 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002095
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002096 /*
2097 * Compute the hash that has been signed
2098 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2100 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2101 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002102 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103 mbedtls_md5_context mbedtls_md5;
2104 mbedtls_sha1_context mbedtls_sha1;
Paul Bakker29e1f122013-04-16 13:07:56 +02002105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002106 mbedtls_md5_init( &mbedtls_md5 );
2107 mbedtls_sha1_init( &mbedtls_sha1 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002108
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002109 hashlen = 36;
2110
Paul Bakker29e1f122013-04-16 13:07:56 +02002111 /*
2112 * digitally-signed struct {
2113 * opaque md5_hash[16];
2114 * opaque sha_hash[20];
2115 * };
2116 *
2117 * md5_hash
2118 * MD5(ClientHello.random + ServerHello.random
2119 * + ServerParams);
2120 * sha_hash
2121 * SHA(ClientHello.random + ServerHello.random
2122 * + ServerParams);
2123 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002124 mbedtls_md5_starts( &mbedtls_md5 );
2125 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
2126 mbedtls_md5_update( &mbedtls_md5, params, params_len );
2127 mbedtls_md5_finish( &mbedtls_md5, hash );
Paul Bakker29e1f122013-04-16 13:07:56 +02002128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002129 mbedtls_sha1_starts( &mbedtls_sha1 );
2130 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
2131 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
2132 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002133
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002134 mbedtls_md5_free( &mbedtls_md5 );
2135 mbedtls_sha1_free( &mbedtls_sha1 );
Paul Bakker29e1f122013-04-16 13:07:56 +02002136 }
2137 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002138#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2139 MBEDTLS_SSL_PROTO_TLS1_1 */
2140#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2141 defined(MBEDTLS_SSL_PROTO_TLS1_2)
2142 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002143 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002144 mbedtls_md_context_t ctx;
Paul Bakker29e1f122013-04-16 13:07:56 +02002145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002146 mbedtls_md_init( &ctx );
Paul Bakker84bbeb52014-07-01 14:53:22 +02002147
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002148 /* Info from md_alg will be used instead */
2149 hashlen = 0;
Paul Bakker29e1f122013-04-16 13:07:56 +02002150
2151 /*
2152 * digitally-signed struct {
2153 * opaque client_random[32];
2154 * opaque server_random[32];
2155 * ServerDHParams params;
2156 * };
2157 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002158 if( ( ret = mbedtls_md_setup( &ctx,
2159 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02002160 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002161 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02002162 return( ret );
2163 }
2164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002165 mbedtls_md_starts( &ctx );
2166 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
2167 mbedtls_md_update( &ctx, params, params_len );
2168 mbedtls_md_finish( &ctx, hash );
2169 mbedtls_md_free( &ctx );
Paul Bakker29e1f122013-04-16 13:07:56 +02002170 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002171 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002172#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2173 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002174 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2176 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002177 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
2180 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002181
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002182 /*
2183 * Verify signature
2184 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002186 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2188 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002189 }
2190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002191 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard20846b12013-08-19 12:32:12 +02002192 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002193 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002195 return( ret );
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002196 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002197 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002198#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2199 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2200 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002201
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002202exit:
Paul Bakker5121ce52009-01-03 21:22:43 +00002203 ssl->state++;
2204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002205 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
2207 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002208}
2209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002210#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2211 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2212 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2213 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2214static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002215{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002216 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002218 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002219
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2221 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2222 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2223 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002224 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002225 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002226 ssl->state++;
2227 return( 0 );
2228 }
2229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002230 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2231 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002232}
2233#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002234static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002235{
2236 int ret;
Paul Bakker926af752012-11-23 13:38:07 +01002237 unsigned char *buf, *p;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002238 size_t n = 0, m = 0;
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002239 size_t cert_type_len = 0, dn_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002240 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002244 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2245 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2246 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2247 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002248 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002249 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002250 ssl->state++;
2251 return( 0 );
2252 }
2253
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002254 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002255 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002256 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002257 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002258 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002259 return( ret );
2260 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002262 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002263 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002264 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2265 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002266 }
2267
2268 ssl->record_read = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002269 }
2270
2271 ssl->client_auth = 0;
2272 ssl->state++;
2273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002274 if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
Paul Bakker5121ce52009-01-03 21:22:43 +00002275 ssl->client_auth++;
2276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
Paul Bakker5121ce52009-01-03 21:22:43 +00002278 ssl->client_auth ? "a" : "no" ) );
2279
Paul Bakker926af752012-11-23 13:38:07 +01002280 if( ssl->client_auth == 0 )
2281 goto exit;
2282
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002283 ssl->record_read = 0;
2284
Paul Bakker926af752012-11-23 13:38:07 +01002285 // TODO: handshake_failure alert for an anonymous server to request
2286 // client authentication
2287
Manuel Pégourié-Gonnard04c1b4e2014-09-10 19:25:43 +02002288 /*
2289 * struct {
2290 * ClientCertificateType certificate_types<1..2^8-1>;
2291 * SignatureAndHashAlgorithm
2292 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2293 * DistinguishedName certificate_authorities<0..2^16-1>;
2294 * } CertificateRequest;
2295 */
Paul Bakker926af752012-11-23 13:38:07 +01002296 buf = ssl->in_msg;
Paul Bakkerf7abd422013-04-16 13:15:56 +02002297
Paul Bakker926af752012-11-23 13:38:07 +01002298 // Retrieve cert types
2299 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002300 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
Paul Bakker926af752012-11-23 13:38:07 +01002301 n = cert_type_len;
2302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002304 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002305 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2306 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002307 }
2308
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002309 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
Paul Bakker926af752012-11-23 13:38:07 +01002310 while( cert_type_len > 0 )
2311 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002312#if defined(MBEDTLS_RSA_C)
2313 if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
2314 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
Paul Bakker926af752012-11-23 13:38:07 +01002315 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002316 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
Paul Bakker926af752012-11-23 13:38:07 +01002317 break;
2318 }
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002319 else
2320#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002321#if defined(MBEDTLS_ECDSA_C)
2322 if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
2323 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002324 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002325 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002326 break;
2327 }
2328 else
2329#endif
2330 {
2331 ; /* Unsupported cert type, ignore */
2332 }
Paul Bakker926af752012-11-23 13:38:07 +01002333
2334 cert_type_len--;
2335 p++;
2336 }
2337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2339 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002340 {
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002341 /* Ignored, see comments about hash in write_certificate_verify */
2342 // TODO: should check the signature part against our pk_key though
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002343 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
2344 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002346 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002347 m += 2;
Paul Bakker926af752012-11-23 13:38:07 +01002348 n += sig_alg_len;
2349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002350 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002351 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002352 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2353 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002354 }
Paul Bakkerf7abd422013-04-16 13:15:56 +02002355 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002356#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker926af752012-11-23 13:38:07 +01002357
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002358 /* Ignore certificate_authorities, we only have one cert anyway */
2359 // TODO: should not send cert if no CA matches
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002360 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
2361 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002362
2363 n += dn_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
Paul Bakker926af752012-11-23 13:38:07 +01002365 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002366 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2367 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002368 }
2369
2370exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002371 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002372
2373 return( 0 );
2374}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002375#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2376 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2377 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
2378 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002380static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002381{
2382 int ret;
2383
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002384 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002385
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002386 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002387 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002388 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002389 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002390 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002391 return( ret );
2392 }
2393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002394 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002395 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002396 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2397 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002398 }
2399 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002400 ssl->record_read = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002402 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
2403 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002404 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002405 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2406 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002407 }
2408
2409 ssl->state++;
2410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002411#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002412 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002413 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002414#endif
2415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002416 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002417
2418 return( 0 );
2419}
2420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002421static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002422{
Paul Bakker23986e52011-04-24 08:57:21 +00002423 int ret;
2424 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002425 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002427 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002429#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2430 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002431 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002432 /*
2433 * DHM key exchange -- send G^X mod P
2434 */
Paul Bakker48916f92012-09-16 19:57:18 +00002435 n = ssl->handshake->dhm_ctx.len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002436
2437 ssl->out_msg[4] = (unsigned char)( n >> 8 );
2438 ssl->out_msg[5] = (unsigned char)( n );
2439 i = 6;
2440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002441 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2442 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Paul Bakker5121ce52009-01-03 21:22:43 +00002443 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002444 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00002445 if( ret != 0 )
2446 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002447 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002448 return( ret );
2449 }
2450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002451 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
2452 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
Paul Bakker5121ce52009-01-03 21:22:43 +00002453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002454 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
Paul Bakker48916f92012-09-16 19:57:18 +00002455 ssl->handshake->premaster,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01002456 MBEDTLS_PREMASTER_SIZE,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +02002457 &ssl->handshake->pmslen,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002458 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002459 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002460 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002461 return( ret );
2462 }
2463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002464 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
Paul Bakker5121ce52009-01-03 21:22:43 +00002465 }
2466 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2468#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2469 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
2470 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2471 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2472 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2473 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2474 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2475 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Paul Bakker41c83d32013-03-20 14:39:14 +01002476 {
2477 /*
2478 * ECDH key exchange -- send client public value
2479 */
2480 i = 4;
2481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002482 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002483 &n,
2484 &ssl->out_msg[i], 1000,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002485 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker41c83d32013-03-20 14:39:14 +01002486 if( ret != 0 )
2487 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002488 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002489 return( ret );
2490 }
2491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002492 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Paul Bakker41c83d32013-03-20 14:39:14 +01002493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002494 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002495 &ssl->handshake->pmslen,
2496 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002497 MBEDTLS_MPI_MAX_SIZE,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002498 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002499 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002500 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002501 return( ret );
2502 }
2503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002504 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
Paul Bakker41c83d32013-03-20 14:39:14 +01002505 }
2506 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002507#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2508 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2509 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2510 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2511#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2512 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2513 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2514 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2515 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002516 {
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002517 /*
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002518 * opaque psk_identity<0..2^16-1>;
2519 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002520 if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002521 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002522
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002523 i = 4;
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002524 n = ssl->conf->psk_identity_len;
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002525 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2526 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002527
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002528 memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
2529 i += ssl->conf->psk_identity_len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002531#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
2532 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002533 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002534 n = 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002535 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002536 else
2537#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002538#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2539 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002540 {
2541 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
2542 return( ret );
2543 }
2544 else
2545#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002546#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2547 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002548 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002549 /*
2550 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
2551 */
2552 n = ssl->handshake->dhm_ctx.len;
2553 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2554 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002556 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2557 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002558 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002559 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002560 if( ret != 0 )
2561 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002562 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002563 return( ret );
2564 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002565 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002566 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002567#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2568#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2569 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002570 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002571 /*
2572 * ClientECDiffieHellmanPublic public;
2573 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002574 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
2575 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002576 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002577 if( ret != 0 )
2578 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002579 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002580 return( ret );
2581 }
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002583 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002584 }
2585 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002586#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002587 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002588 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2589 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002590 }
2591
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002592 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002593 ciphersuite_info->key_exchange ) ) != 0 )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002594 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002595 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002596 return( ret );
2597 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002598 }
2599 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002600#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
2601#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2602 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002603 {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002604 i = 4;
2605 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
Paul Bakkera3d195c2011-11-27 21:07:34 +00002606 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002607 }
Paul Bakkered27a042013-04-18 22:46:23 +02002608 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002609#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Paul Bakkered27a042013-04-18 22:46:23 +02002610 {
2611 ((void) ciphersuite_info);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002612 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2613 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkered27a042013-04-18 22:46:23 +02002614 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002615
Paul Bakker5121ce52009-01-03 21:22:43 +00002616 ssl->out_msglen = i + n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002617 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2618 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002619
2620 ssl->state++;
2621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002622 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002623 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002624 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002625 return( ret );
2626 }
2627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002628 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002629
2630 return( 0 );
2631}
2632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002633#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2634 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2635 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2636 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2637static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002638{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002639 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002640 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002641
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002642 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002644 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002645 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002646 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002647 return( ret );
2648 }
2649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002650 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2651 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2652 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2653 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakkered27a042013-04-18 22:46:23 +02002654 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakkered27a042013-04-18 22:46:23 +02002656 ssl->state++;
2657 return( 0 );
2658 }
2659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002660 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2661 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002662}
2663#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002664static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002665{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002666 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
2667 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002668 size_t n = 0, offset = 0;
2669 unsigned char hash[48];
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002670 unsigned char *hash_start = hash;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002671 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002672 unsigned int hashlen;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002674 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002675
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002676 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002677 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002678 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002679 return( ret );
2680 }
2681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002682 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2683 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2684 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2685 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002686 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002687 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002688 ssl->state++;
2689 return( 0 );
2690 }
2691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002692 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00002693 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002694 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002695 ssl->state++;
2696 return( 0 );
2697 }
2698
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002699 if( mbedtls_ssl_own_key( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00002700 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002701 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
2702 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002703 }
2704
2705 /*
2706 * Make an RSA signature of the handshake digests
2707 */
Paul Bakker48916f92012-09-16 19:57:18 +00002708 ssl->handshake->calc_verify( ssl, hash );
Paul Bakker5121ce52009-01-03 21:22:43 +00002709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002710#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2711 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2712 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002713 {
Paul Bakker926af752012-11-23 13:38:07 +01002714 /*
2715 * digitally-signed struct {
2716 * opaque md5_hash[16];
2717 * opaque sha_hash[20];
2718 * };
2719 *
2720 * md5_hash
2721 * MD5(handshake_messages);
2722 *
2723 * sha_hash
2724 * SHA(handshake_messages);
2725 */
2726 hashlen = 36;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002727 md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002728
2729 /*
2730 * For ECDSA, default hash is SHA-1 only
2731 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002732 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002733 {
2734 hash_start += 16;
2735 hashlen -= 16;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002736 md_alg = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002737 }
Paul Bakker926af752012-11-23 13:38:07 +01002738 }
2739 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002740#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2741 MBEDTLS_SSL_PROTO_TLS1_1 */
2742#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2743 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002744 {
2745 /*
2746 * digitally-signed struct {
2747 * opaque handshake_messages[handshake_messages_length];
2748 * };
2749 *
2750 * Taking shortcut here. We assume that the server always allows the
2751 * PRF Hash function and has sent it in the allowed signature
2752 * algorithms list received in the Certificate Request message.
2753 *
2754 * Until we encounter a server that does not, we will take this
2755 * shortcut.
2756 *
2757 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
2758 * in order to satisfy 'weird' needs from the server side.
2759 */
Paul Bakkerb7149bc2013-03-20 15:30:09 +01002760 if( ssl->transform_negotiate->ciphersuite_info->mac ==
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002761 MBEDTLS_MD_SHA384 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00002762 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002763 md_alg = MBEDTLS_MD_SHA384;
2764 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
Paul Bakkerca4ab492012-04-18 14:23:57 +00002765 }
2766 else
2767 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002768 md_alg = MBEDTLS_MD_SHA256;
2769 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
Paul Bakkerca4ab492012-04-18 14:23:57 +00002770 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002771 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002772
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +02002773 /* Info from md_alg will be used instead */
2774 hashlen = 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002775 offset = 2;
2776 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002777 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002778#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02002779 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002780 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2781 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002782 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002783
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002784 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02002785 ssl->out_msg + 6 + offset, &n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002786 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002787 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002788 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02002789 return( ret );
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02002790 }
Paul Bakker926af752012-11-23 13:38:07 +01002791
Paul Bakker1ef83d62012-04-11 12:09:53 +00002792 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
2793 ssl->out_msg[5 + offset] = (unsigned char)( n );
Paul Bakker5121ce52009-01-03 21:22:43 +00002794
Paul Bakker1ef83d62012-04-11 12:09:53 +00002795 ssl->out_msglen = 6 + n + offset;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002796 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2797 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00002798
2799 ssl->state++;
2800
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002801 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002802 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002803 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002804 return( ret );
2805 }
2806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002807 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002808
Paul Bakkered27a042013-04-18 22:46:23 +02002809 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002810}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002811#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2812 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2813 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002815#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2816static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002817{
2818 int ret;
2819 uint32_t lifetime;
2820 size_t ticket_len;
2821 unsigned char *ticket;
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002822 const unsigned char *msg;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002824 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002826 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002827 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002828 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002829 return( ret );
2830 }
2831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002832 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002833 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002834 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2835 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002836 }
2837
2838 /*
2839 * struct {
2840 * uint32 ticket_lifetime_hint;
2841 * opaque ticket<0..2^16-1>;
2842 * } NewSessionTicket;
2843 *
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002844 * 0 . 3 ticket_lifetime_hint
2845 * 4 . 5 ticket_len (n)
2846 * 6 . 5+n ticket content
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002847 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002848 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
2849 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002850 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002851 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2852 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002853 }
2854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002855 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002856
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002857 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
2858 ( msg[2] << 8 ) | ( msg[3] );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002859
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002860 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
2861
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002862 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002863 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002864 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
2865 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002866 }
2867
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002868 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002869
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02002870 /* We're not waiting for a NewSessionTicket message any more */
2871 ssl->handshake->new_session_ticket = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002872 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02002873
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002874 /*
2875 * Zero-length ticket means the server changed his mind and doesn't want
2876 * to send a ticket after all, so just forget it
2877 */
Paul Bakker66d5d072014-06-17 16:39:18 +02002878 if( ticket_len == 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002879 return( 0 );
2880
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002881 mbedtls_zeroize( ssl->session_negotiate->ticket,
Paul Bakker34617722014-06-13 17:20:13 +02002882 ssl->session_negotiate->ticket_len );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002883 mbedtls_free( ssl->session_negotiate->ticket );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002884 ssl->session_negotiate->ticket = NULL;
2885 ssl->session_negotiate->ticket_len = 0;
2886
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02002887 if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002888 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02002889 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02002890 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002891 }
2892
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02002893 memcpy( ticket, msg + 6, ticket_len );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002894
2895 ssl->session_negotiate->ticket = ticket;
2896 ssl->session_negotiate->ticket_len = ticket_len;
2897 ssl->session_negotiate->ticket_lifetime = lifetime;
2898
2899 /*
2900 * RFC 5077 section 3.4:
2901 * "If the client receives a session ticket from the server, then it
2902 * discards any Session ID that was sent in the ServerHello."
2903 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002904 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02002905 ssl->session_negotiate->id_len = 0;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002906
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002907 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002908
2909 return( 0 );
2910}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002911#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02002912
Paul Bakker5121ce52009-01-03 21:22:43 +00002913/*
Paul Bakker1961b702013-01-25 14:49:24 +01002914 * SSL handshake -- client side -- single step
Paul Bakker5121ce52009-01-03 21:22:43 +00002915 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002916int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002917{
2918 int ret = 0;
2919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002920 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
2921 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002923 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
Paul Bakker1961b702013-01-25 14:49:24 +01002924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002925 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker1961b702013-01-25 14:49:24 +01002926 return( ret );
2927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002928#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002929 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002930 ssl->handshake != NULL &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002931 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002932 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002933 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002934 return( ret );
2935 }
2936#endif
2937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002938 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002939 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002940#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2941 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002942 ssl->handshake->new_session_ticket != 0 )
2943 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002944 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02002945 }
2946#endif
2947
Paul Bakker1961b702013-01-25 14:49:24 +01002948 switch( ssl->state )
Paul Bakker5121ce52009-01-03 21:22:43 +00002949 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002950 case MBEDTLS_SSL_HELLO_REQUEST:
2951 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00002952 break;
2953
Paul Bakker1961b702013-01-25 14:49:24 +01002954 /*
2955 * ==> ClientHello
2956 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002957 case MBEDTLS_SSL_CLIENT_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01002958 ret = ssl_write_client_hello( ssl );
2959 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002960
Paul Bakker1961b702013-01-25 14:49:24 +01002961 /*
2962 * <== ServerHello
2963 * Certificate
2964 * ( ServerKeyExchange )
2965 * ( CertificateRequest )
2966 * ServerHelloDone
2967 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002968 case MBEDTLS_SSL_SERVER_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01002969 ret = ssl_parse_server_hello( ssl );
2970 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002972 case MBEDTLS_SSL_SERVER_CERTIFICATE:
2973 ret = mbedtls_ssl_parse_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01002974 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002976 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01002977 ret = ssl_parse_server_key_exchange( ssl );
2978 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002980 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
Paul Bakker1961b702013-01-25 14:49:24 +01002981 ret = ssl_parse_certificate_request( ssl );
2982 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002984 case MBEDTLS_SSL_SERVER_HELLO_DONE:
Paul Bakker1961b702013-01-25 14:49:24 +01002985 ret = ssl_parse_server_hello_done( ssl );
2986 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002987
Paul Bakker1961b702013-01-25 14:49:24 +01002988 /*
2989 * ==> ( Certificate/Alert )
2990 * ClientKeyExchange
2991 * ( CertificateVerify )
2992 * ChangeCipherSpec
2993 * Finished
2994 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002995 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
2996 ret = mbedtls_ssl_write_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01002997 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002999 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003000 ret = ssl_write_client_key_exchange( ssl );
3001 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003003 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
Paul Bakker1961b702013-01-25 14:49:24 +01003004 ret = ssl_write_certificate_verify( ssl );
3005 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003006
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003007 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3008 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003009 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003010
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003011 case MBEDTLS_SSL_CLIENT_FINISHED:
3012 ret = mbedtls_ssl_write_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003013 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003014
Paul Bakker1961b702013-01-25 14:49:24 +01003015 /*
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003016 * <== ( NewSessionTicket )
3017 * ChangeCipherSpec
Paul Bakker1961b702013-01-25 14:49:24 +01003018 * Finished
3019 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003020#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3021 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003022 ret = ssl_parse_new_session_ticket( ssl );
3023 break;
Paul Bakkera503a632013-08-14 13:48:06 +02003024#endif
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003026 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3027 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003028 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003030 case MBEDTLS_SSL_SERVER_FINISHED:
3031 ret = mbedtls_ssl_parse_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003032 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003034 case MBEDTLS_SSL_FLUSH_BUFFERS:
3035 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
3036 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Paul Bakker1961b702013-01-25 14:49:24 +01003037 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003039 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3040 mbedtls_ssl_handshake_wrapup( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003041 break;
Paul Bakker48916f92012-09-16 19:57:18 +00003042
Paul Bakker1961b702013-01-25 14:49:24 +01003043 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003044 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
3045 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1961b702013-01-25 14:49:24 +01003046 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003047
3048 return( ret );
3049}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003050#endif /* MBEDTLS_SSL_CLI_C */