blob: 1d22d1518e15da03bc919797ca3cab657cd2d6ee [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSLv3/TLSv1 client-side functions
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020024#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020026#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/debug.h"
31#include "mbedtls/ssl.h"
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +020032#include "mbedtls/ssl_internal.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020040#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_free free
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +020042#endif
43
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020044#include <stdint.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000047#include <time.h>
Paul Bakkerfa9b1002013-07-03 15:31:03 +020048#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Paul Bakker34617722014-06-13 17:20:13 +020051/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020053 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54}
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
58static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +010059 unsigned char *buf,
60 size_t *olen )
61{
62 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +010063 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010064 size_t hostname_len;
Paul Bakkerd3edc862013-03-20 16:07:17 +010065
66 *olen = 0;
67
Paul Bakker66d5d072014-06-17 16:39:18 +020068 if( ssl->hostname == NULL )
Paul Bakkerd3edc862013-03-20 16:07:17 +010069 return;
70
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
Paul Bakkerd3edc862013-03-20 16:07:17 +010072 ssl->hostname ) );
73
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +010074 hostname_len = strlen( ssl->hostname );
75
Simon Butcher0fc94e92015-09-28 20:52:04 +010076 if( end < p || (size_t)( end - p ) < hostname_len + 9 )
Simon Butchered997662015-09-28 02:14:30 +010077 {
Simon Butcher0fc94e92015-09-28 20:52:04 +010078 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
Simon Butchered997662015-09-28 02:14:30 +010079 return;
80 }
81
Paul Bakkerd3edc862013-03-20 16:07:17 +010082 /*
83 * struct {
84 * NameType name_type;
85 * select (name_type) {
86 * case host_name: HostName;
87 * } name;
88 * } ServerName;
89 *
90 * enum {
91 * host_name(0), (255)
92 * } NameType;
93 *
94 * opaque HostName<1..2^16-1>;
95 *
96 * struct {
97 * ServerName server_name_list<1..2^16-1>
98 * } ServerNameList;
99 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
101 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100102
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100103 *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
104 *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100105
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100106 *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
107 *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100110 *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
111 *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100112
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100113 memcpy( p, ssl->hostname, hostname_len );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100114
Manuel Pégourié-Gonnardba26c242015-05-06 10:47:06 +0100115 *olen = hostname_len + 9;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100116}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119#if defined(MBEDTLS_SSL_RENEGOTIATION)
120static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100121 unsigned char *buf,
122 size_t *olen )
123{
124 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100125 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100126
127 *olen = 0;
128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100130 return;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100133
Simon Butcher0fc94e92015-09-28 20:52:04 +0100134 if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
Simon Butchered997662015-09-28 02:14:30 +0100135 {
136 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
137 return;
138 }
139
Paul Bakkerd3edc862013-03-20 16:07:17 +0100140 /*
141 * Secure renegotiation
142 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
144 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100145
146 *p++ = 0x00;
147 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
148 *p++ = ssl->verify_data_len & 0xFF;
149
150 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
151
152 *olen = 5 + ssl->verify_data_len;
153}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100155
Manuel Pégourié-Gonnardd9423232014-12-02 11:57:29 +0100156/*
157 * Only if we handle at least one key exchange that needs signatures.
158 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
160 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
161static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100162 unsigned char *buf,
163 size_t *olen )
164{
165 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100166 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100167 size_t sig_alg_len = 0;
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200168 const int *md;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5bfd9682014-06-24 15:18:11 +0200170 unsigned char *sig_alg_list = buf + 6;
171#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100172
173 *olen = 0;
174
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200175 if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakkerd3edc862013-03-20 16:07:17 +0100176 return;
177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100179
Simon Butchered997662015-09-28 02:14:30 +0100180 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
181 {
182#if defined(MBEDTLS_ECDSA_C)
183 sig_alg_len += 2;
184#endif
185#if defined(MBEDTLS_RSA_C)
186 sig_alg_len += 2;
187#endif
188 }
189
Simon Butcher0fc94e92015-09-28 20:52:04 +0100190 if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
Simon Butchered997662015-09-28 02:14:30 +0100191 {
192 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
193 return;
194 }
195
Paul Bakkerd3edc862013-03-20 16:07:17 +0100196 /*
197 * Prepare signature_algorithms extension (TLS 1.2)
198 */
Simon Butchered997662015-09-28 02:14:30 +0100199 sig_alg_len = 0;
200
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200201 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
202 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200204 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
205 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200206#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200207#if defined(MBEDTLS_RSA_C)
208 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
209 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
Manuel Pégourié-Gonnardd11eb7c2013-08-22 15:57:15 +0200210#endif
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200211 }
Paul Bakkerd3edc862013-03-20 16:07:17 +0100212
213 /*
214 * enum {
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +0200215 * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
216 * sha512(6), (255)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100217 * } HashAlgorithm;
218 *
219 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
220 * SignatureAlgorithm;
221 *
222 * struct {
223 * HashAlgorithm hash;
224 * SignatureAlgorithm signature;
225 * } SignatureAndHashAlgorithm;
226 *
227 * SignatureAndHashAlgorithm
228 * supported_signature_algorithms<2..2^16-2>;
229 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
231 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100232
233 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
234 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
235
236 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
237 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
238
Paul Bakkerd3edc862013-03-20 16:07:17 +0100239 *olen = 6 + sig_alg_len;
240}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
242 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100243
Manuel Pégourié-Gonnardf4721792015-09-15 10:53:51 +0200244#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +0100245 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100247 unsigned char *buf,
248 size_t *olen )
249{
250 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100251 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard8e205fc2014-01-23 17:27:10 +0100252 unsigned char *elliptic_curve_list = p + 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100253 size_t elliptic_curve_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 const mbedtls_ecp_curve_info *info;
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200255#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 const mbedtls_ecp_group_id *grp_id;
Paul Bakker0910f322014-02-06 13:41:18 +0100257#else
258 ((void) ssl);
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100259#endif
Paul Bakkerd3edc862013-03-20 16:07:17 +0100260
261 *olen = 0;
262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100264
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +0200265#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200266 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200267 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100269#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100271 {
272#endif
Simon Butchered997662015-09-28 02:14:30 +0100273 elliptic_curve_len += 2;
274 }
275
Simon Butcher0fc94e92015-09-28 20:52:04 +0100276 if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
Simon Butchered997662015-09-28 02:14:30 +0100277 {
278 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
279 return;
280 }
281
282 elliptic_curve_len = 0;
283
284#if defined(MBEDTLS_ECP_C)
285 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
286 {
287 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
288#else
289 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
290 {
291#endif
Manuel Pégourié-Gonnardcd49f762014-02-04 15:14:13 +0100292
293 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
294 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200295 }
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200296
297 if( elliptic_curve_len == 0 )
298 return;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
301 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100302
303 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
304 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
305
306 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
307 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
308
Paul Bakkerd3edc862013-03-20 16:07:17 +0100309 *olen = 6 + elliptic_curve_len;
310}
311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Paul Bakkerd3edc862013-03-20 16:07:17 +0100313 unsigned char *buf,
314 size_t *olen )
315{
316 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100317 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100318
319 *olen = 0;
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100322
Simon Butcher0fc94e92015-09-28 20:52:04 +0100323 if( end < p || (size_t)( end - p ) < 6 )
Simon Butchered997662015-09-28 02:14:30 +0100324 {
325 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
326 return;
327 }
328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
330 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
Paul Bakkerd3edc862013-03-20 16:07:17 +0100331
332 *p++ = 0x00;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100333 *p++ = 2;
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200334
335 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100337
Manuel Pégourié-Gonnard6b8846d2013-08-15 17:42:02 +0200338 *olen = 6;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100339}
Robert Cragieae8535d2015-10-06 17:11:18 +0100340#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
341 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100342
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200343#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200344static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
345 unsigned char *buf,
346 size_t *olen )
347{
348 int ret;
349 unsigned char *p = buf;
Robert Cragie39a60de2015-10-02 13:57:59 +0100350 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200351 size_t kkpp_len;
352
353 *olen = 0;
354
355 /* Skip costly extension if we can't use EC J-PAKE anyway */
356 if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
357 return;
358
359 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
360
361 if( end - p < 4 )
362 {
363 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
364 return;
365 }
366
367 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
368 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
369
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200370 /*
371 * We may need to send ClientHello multiple times for Hello verification.
372 * We don't want to compute fresh values every time (both for performance
373 * and consistency reasons), so cache the extension content.
374 */
375 if( ssl->handshake->ecjpake_cache == NULL ||
376 ssl->handshake->ecjpake_cache_len == 0 )
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200377 {
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200378 MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
379
Manuel Pégourié-Gonnard5674a972015-10-19 15:14:03 +0200380 ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
381 p + 2, end - p - 2, &kkpp_len,
382 ssl->conf->f_rng, ssl->conf->p_rng );
383 if( ret != 0 )
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +0200384 {
385 MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
386 return;
387 }
388
389 ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
390 if( ssl->handshake->ecjpake_cache == NULL )
391 {
392 MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
393 return;
394 }
395
396 memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
397 ssl->handshake->ecjpake_cache_len = kkpp_len;
398 }
399 else
400 {
401 MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
402
403 kkpp_len = ssl->handshake->ecjpake_cache_len;
404
405 if( (size_t)( end - p - 2 ) < kkpp_len )
406 {
407 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
408 return;
409 }
410
411 memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200412 }
413
414 *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
415 *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
416
417 *olen = kkpp_len + 4;
418}
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200419#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakkerd3edc862013-03-20 16:07:17 +0100420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
422static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200423 unsigned char *buf,
424 size_t *olen )
425{
426 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100427 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200428
Simon Butcher0fc94e92015-09-28 20:52:04 +0100429 *olen = 0;
430
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200431 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200432 return;
433 }
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200436
Simon Butcher0fc94e92015-09-28 20:52:04 +0100437 if( end < p || (size_t)( end - p ) < 5 )
Simon Butchered997662015-09-28 02:14:30 +0100438 {
439 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
440 return;
441 }
442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
444 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200445
446 *p++ = 0x00;
447 *p++ = 1;
448
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200449 *p++ = ssl->conf->mfl_code;
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200450
451 *olen = 5;
452}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
456static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200457 unsigned char *buf, size_t *olen )
458{
459 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100460 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200461
Simon Butcher0fc94e92015-09-28 20:52:04 +0100462 *olen = 0;
463
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200464 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200465 {
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200466 return;
467 }
468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200470
Simon Butcher0fc94e92015-09-28 20:52:04 +0100471 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100472 {
473 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
474 return;
475 }
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
478 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200479
480 *p++ = 0x00;
481 *p++ = 0x00;
482
483 *olen = 4;
484}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
488static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100489 unsigned char *buf, size_t *olen )
490{
491 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100492 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100493
Simon Butcher0fc94e92015-09-28 20:52:04 +0100494 *olen = 0;
495
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200496 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
497 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100498 {
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100499 return;
500 }
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100503 "extension" ) );
504
Simon Butcher0fc94e92015-09-28 20:52:04 +0100505 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100506 {
507 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
508 return;
509 }
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
512 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100513
514 *p++ = 0x00;
515 *p++ = 0x00;
516
517 *olen = 4;
518}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
522static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200523 unsigned char *buf, size_t *olen )
524{
525 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100526 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200527
Simon Butcher0fc94e92015-09-28 20:52:04 +0100528 *olen = 0;
529
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200530 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
531 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200532 {
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200533 return;
534 }
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200537 "extension" ) );
538
Simon Butcher0fc94e92015-09-28 20:52:04 +0100539 if( end < p || (size_t)( end - p ) < 4 )
Simon Butchered997662015-09-28 02:14:30 +0100540 {
541 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
542 return;
543 }
544
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
546 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200547
548 *p++ = 0x00;
549 *p++ = 0x00;
550
551 *olen = 4;
552}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200554
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555#if defined(MBEDTLS_SSL_SESSION_TICKETS)
556static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200557 unsigned char *buf, size_t *olen )
558{
559 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100560 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200561 size_t tlen = ssl->session_negotiate->ticket_len;
562
Simon Butcher0fc94e92015-09-28 20:52:04 +0100563 *olen = 0;
564
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200565 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200566 {
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200567 return;
568 }
569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200571
Simon Butcher0fc94e92015-09-28 20:52:04 +0100572 if( end < p || (size_t)( end - p ) < 4 + tlen )
Simon Butchered997662015-09-28 02:14:30 +0100573 {
574 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
575 return;
576 }
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
579 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200580
581 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
582 *p++ = (unsigned char)( ( tlen ) & 0xFF );
583
584 *olen = 4;
585
Simon Butchered997662015-09-28 02:14:30 +0100586 if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200587 {
588 return;
589 }
590
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200592
593 memcpy( p, ssl->session_negotiate->ticket, tlen );
594
595 *olen += tlen;
596}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +0200598
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599#if defined(MBEDTLS_SSL_ALPN)
600static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200601 unsigned char *buf, size_t *olen )
602{
603 unsigned char *p = buf;
Simon Butchered997662015-09-28 02:14:30 +0100604 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
605 size_t alpnlen = 0;
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200606 const char **cur;
607
Simon Butcher0fc94e92015-09-28 20:52:04 +0100608 *olen = 0;
609
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200610 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200611 {
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200612 return;
613 }
614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200616
Simon Butchered997662015-09-28 02:14:30 +0100617 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
Simon Butcher04799a42015-09-29 00:31:09 +0100618 alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
Simon Butchered997662015-09-28 02:14:30 +0100619
Simon Butcher0fc94e92015-09-28 20:52:04 +0100620 if( end < p || (size_t)( end - p ) < 6 + alpnlen )
Simon Butchered997662015-09-28 02:14:30 +0100621 {
622 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
623 return;
624 }
625
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
627 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200628
629 /*
630 * opaque ProtocolName<1..2^8-1>;
631 *
632 * struct {
633 * ProtocolName protocol_name_list<2..2^16-1>
634 * } ProtocolNameList;
635 */
636
637 /* Skip writing extension and list length for now */
638 p += 4;
639
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200640 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200641 {
642 *p = (unsigned char)( strlen( *cur ) & 0xFF );
643 memcpy( p + 1, *cur, *p );
644 p += 1 + *p;
645 }
646
647 *olen = p - buf;
648
649 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
650 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
651 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
652
653 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
654 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
655 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
656}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +0200658
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200659/*
660 * Generate random bytes for ClientHello
661 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662static int ssl_generate_random( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200663{
664 int ret;
665 unsigned char *p = ssl->handshake->randbytes;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200667 time_t t;
668#endif
669
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200670 /*
671 * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
672 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200674 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardfb2d2232014-07-22 15:59:14 +0200675 ssl->handshake->verify_cookie != NULL )
676 {
677 return( 0 );
678 }
679#endif
680
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681#if defined(MBEDTLS_HAVE_TIME)
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200682 t = time( NULL );
683 *p++ = (unsigned char)( t >> 24 );
684 *p++ = (unsigned char)( t >> 16 );
685 *p++ = (unsigned char)( t >> 8 );
686 *p++ = (unsigned char)( t );
687
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200689#else
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100690 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200691 return( ret );
692
693 p += 4;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#endif /* MBEDTLS_HAVE_TIME */
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200695
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100696 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200697 return( ret );
698
699 return( 0 );
700}
701
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703{
Paul Bakker23986e52011-04-24 08:57:21 +0000704 int ret;
Paul Bakkerd3edc862013-03-20 16:07:17 +0100705 size_t i, n, olen, ext_len = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706 unsigned char *buf;
Paul Bakker2fbefde2013-06-29 16:01:15 +0200707 unsigned char *p, *q;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200708 unsigned char offer_compress;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200709 const int *ciphersuites;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100714 if( ssl->conf->f_rng == NULL )
Paul Bakkera9a028e2013-11-21 17:31:06 +0100715 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
717 return( MBEDTLS_ERR_SSL_NO_RNG );
Paul Bakkera9a028e2013-11-21 17:31:06 +0100718 }
719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720#if defined(MBEDTLS_SSL_RENEGOTIATION)
721 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100722#endif
Paul Bakker48916f92012-09-16 19:57:18 +0000723 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200724 ssl->major_ver = ssl->conf->min_major_ver;
725 ssl->minor_ver = ssl->conf->min_minor_ver;
Paul Bakker48916f92012-09-16 19:57:18 +0000726 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200728 if( ssl->conf->max_major_ver == 0 )
Paul Bakker490ecc82011-10-06 13:04:09 +0000729 {
Manuel Pégourié-Gonnard1897af92015-05-10 23:27:38 +0200730 MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
731 "consider using mbedtls_ssl_config_defaults()" ) );
732 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker490ecc82011-10-06 13:04:09 +0000733 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
735 /*
736 * 0 . 0 handshake type
737 * 1 . 3 handshake length
738 * 4 . 5 highest version supported
739 * 6 . 9 current UNIX time
740 * 10 . 37 random bytes
741 */
742 buf = ssl->out_msg;
743 p = buf + 4;
744
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200745 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
746 ssl->conf->transport, p );
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +0100747 p += 2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 buf[4], buf[5] ) );
751
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200752 if( ( ret = ssl_generate_random( ssl ) ) != 0 )
753 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200755 return( ret );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200756 }
Paul Bakkerfa9b1002013-07-03 15:31:03 +0200757
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200758 memcpy( p, ssl->handshake->randbytes, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
Manuel Pégourié-Gonnardb760f002014-07-22 15:53:27 +0200760 p += 32;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
762 /*
763 * 38 . 38 session id length
764 * 39 . 39+n session id
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100765 * 39+n . 39+n DTLS only: cookie length (1 byte)
766 * 40+n . .. DTSL only: cookie
767 * .. . .. ciphersuitelist length (2 bytes)
768 * .. . .. ciphersuitelist
769 * .. . .. compression methods length (1 byte)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000770 * .. . .. compression methods
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100771 * .. . .. extensions length (2 bytes)
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000772 * .. . .. extensions
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 */
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200774 n = ssl->session_negotiate->id_len;
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100776 if( n < 16 || n > 32 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#if defined(MBEDTLS_SSL_RENEGOTIATION)
778 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100779#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000780 ssl->handshake->resume == 0 )
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200781 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 n = 0;
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200783 }
784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200786 /*
787 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
788 * generate and include a Session ID in the TLS ClientHello."
789 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SSL_RENEGOTIATION)
791 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000792#endif
Manuel Pégourié-Gonnardd2b35ec2015-03-10 11:40:43 +0000793 {
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000794 if( ssl->session_negotiate->ticket != NULL &&
795 ssl->session_negotiate->ticket_len != 0 )
796 {
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +0100797 ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200798
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000799 if( ret != 0 )
800 return( ret );
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200801
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +0200802 ssl->session_negotiate->id_len = n = 32;
Manuel Pégourié-Gonnard59c6f2e2015-01-22 11:06:40 +0000803 }
Manuel Pégourié-Gonnard6377e412013-07-31 16:31:33 +0200804 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
807 *p++ = (unsigned char) n;
808
809 for( i = 0; i < n; i++ )
Paul Bakker48916f92012-09-16 19:57:18 +0000810 *p++ = ssl->session_negotiate->id[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
813 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000814
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100815 /*
816 * DTLS cookie
817 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200819 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100820 {
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200821 if( ssl->handshake->verify_cookie == NULL )
822 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200824 *p++ = 0;
825 }
826 else
827 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +0200829 ssl->handshake->verify_cookie,
830 ssl->handshake->verify_cookie_len );
831
832 *p++ = ssl->handshake->verify_cookie_len;
833 memcpy( p, ssl->handshake->verify_cookie,
834 ssl->handshake->verify_cookie_len );
835 p += ssl->handshake->verify_cookie_len;
836 }
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100837 }
838#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Paul Bakker48916f92012-09-16 19:57:18 +0000840 /*
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100841 * Ciphersuite list
Paul Bakker48916f92012-09-16 19:57:18 +0000842 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200843 ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
Manuel Pégourié-Gonnard4128aa72014-03-21 09:40:12 +0100844
845 /* Skip writing ciphersuite length for now */
846 n = 0;
847 q = p;
848 p += 2;
849
Paul Bakker2fbefde2013-06-29 16:01:15 +0200850 for( i = 0; ciphersuites[i] != 0; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200853
854 if( ciphersuite_info == NULL )
855 continue;
856
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200857 if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
858 ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
Paul Bakker2fbefde2013-06-29 16:01:15 +0200859 continue;
860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200862 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
Manuel Pégourié-Gonnardd6664512014-02-06 13:26:57 +0100864 continue;
865#endif
866
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200867#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200868 if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100870 continue;
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +0200871#endif
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100872
Manuel Pégourié-Gonnardddf97a62015-09-16 09:58:31 +0200873#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
874 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
875 mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
876 continue;
877#endif
878
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +0200879 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
880 ciphersuites[i] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Paul Bakker2fbefde2013-06-29 16:01:15 +0200882 n++;
Paul Bakker8f4ddae2013-04-15 15:09:54 +0200883 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
884 *p++ = (unsigned char)( ciphersuites[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 }
886
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000887 /*
888 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
889 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890#if defined(MBEDTLS_SSL_RENEGOTIATION)
891 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000892#endif
893 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
895 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
Manuel Pégourié-Gonnard5d9cde22015-01-22 10:49:41 +0000896 n++;
897 }
898
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200899 /* Some versions of OpenSSL don't handle it correctly if not at end */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
Manuel Pégourié-Gonnard684b0592015-05-06 09:27:31 +0100901 if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200902 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
904 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
905 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
Manuel Pégourié-Gonnard1cbd39d2014-10-20 13:34:59 +0200906 n++;
907 }
908#endif
909
Paul Bakker2fbefde2013-06-29 16:01:15 +0200910 *q++ = (unsigned char)( n >> 7 );
911 *q++ = (unsigned char)( n << 1 );
912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
Paul Bakker2fbefde2013-06-29 16:01:15 +0200914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200916 offer_compress = 1;
Paul Bakker2770fbd2012-07-03 13:30:23 +0000917#else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200918 offer_compress = 0;
919#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200921 /*
922 * We don't support compression with DTLS right now: is many records come
923 * in the same datagram, uncompressing one could overwrite the next one.
924 * We don't want to add complexity for handling that case unless there is
925 * an actual need for it.
926 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200928 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200929 offer_compress = 0;
930#endif
931
932 if( offer_compress )
933 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
935 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
936 MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200937
938 *p++ = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
940 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200941 }
942 else
943 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
945 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
946 MBEDTLS_SSL_COMPRESS_NULL ) );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200947
948 *p++ = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +0200950 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Paul Bakkerd3edc862013-03-20 16:07:17 +0100952 // First write extensions, then the total length
953 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100955 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
956 ext_len += olen;
Paul Bakker0be444a2013-08-27 21:55:01 +0200957#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100960 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
961 ext_len += olen;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100962#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
965 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100966 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
967 ext_len += olen;
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200968#endif
Paul Bakkerc3f177a2012-04-11 16:11:49 +0000969
Manuel Pégourié-Gonnardf4721792015-09-15 10:53:51 +0200970#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +0100971 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Paul Bakkerd3edc862013-03-20 16:07:17 +0100972 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
973 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100974
Paul Bakkerd3edc862013-03-20 16:07:17 +0100975 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
976 ext_len += olen;
Paul Bakker41c83d32013-03-20 14:39:14 +0100977#endif
978
Manuel Pégourié-Gonnardeef142d2015-09-16 10:05:04 +0200979#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard294139b2015-09-15 16:55:05 +0200980 ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
981 ext_len += olen;
982#endif
983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200985 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
986 ext_len += olen;
Paul Bakker05decb22013-08-15 13:33:48 +0200987#endif
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +0200988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200990 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
991 ext_len += olen;
Paul Bakker1f2bc622013-08-15 13:45:55 +0200992#endif
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +0200993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100995 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
996 ext_len += olen;
997#endif
998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001000 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
1001 ext_len += olen;
1002#endif
1003
Simon Butcher5624ec82015-09-29 01:06:06 +01001004#if defined(MBEDTLS_SSL_ALPN)
1005 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001006 ext_len += olen;
Paul Bakkera503a632013-08-14 13:48:06 +02001007#endif
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001008
Simon Butcher5624ec82015-09-29 01:06:06 +01001009#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1010 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001011 ext_len += olen;
1012#endif
1013
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001014 /* olen unused if all extensions are disabled */
1015 ((void) olen);
1016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
Paul Bakkerc3f177a2012-04-11 16:11:49 +00001018 ext_len ) );
1019
Paul Bakkera7036632014-04-30 10:15:38 +02001020 if( ext_len > 0 )
1021 {
1022 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
1023 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
1024 p += ext_len;
1025 }
Paul Bakker41c83d32013-03-20 14:39:14 +01001026
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 ssl->out_msglen = p - buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
1029 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00001030
1031 ssl->state++;
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001034 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_ssl_send_flight_completed( ssl );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02001036#endif
1037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 return( ret );
1042 }
1043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
1046 return( 0 );
1047}
1048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +02001050 const unsigned char *buf,
Paul Bakker48916f92012-09-16 19:57:18 +00001051 size_t len )
1052{
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001053 int ret;
1054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_SSL_RENEGOTIATION)
1056 if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001057 {
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001058 /* Check verify-data in constant-time. The length OTOH is no secret */
Paul Bakker48916f92012-09-16 19:57:18 +00001059 if( len != 1 + ssl->verify_data_len * 2 ||
1060 buf[0] != ssl->verify_data_len * 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061 mbedtls_ssl_safer_memcmp( buf + 1,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001062 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
Manuel Pégourié-Gonnard31ff1d22013-10-28 13:46:11 +01001064 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001065 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001069 return( ret );
1070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001072 }
1073 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001074 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001076 {
1077 if( len != 1 || buf[0] != 0x00 )
1078 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001080
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001082 return( ret );
1083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001085 }
1086
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087 ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001088 }
Paul Bakker48916f92012-09-16 19:57:18 +00001089
1090 return( 0 );
1091}
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1094static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarde048b672013-07-19 12:47:00 +02001095 const unsigned char *buf,
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001096 size_t len )
1097{
1098 /*
1099 * server should use the extension only if we did,
1100 * and if so the server's value should match ours (and len is always 1)
1101 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001102 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001103 len != 1 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001104 buf[0] != ssl->conf->mfl_code )
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001105 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001107 }
1108
1109 return( 0 );
1110}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Paul Bakker48916f92012-09-16 19:57:18 +00001112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1114static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001115 const unsigned char *buf,
1116 size_t len )
1117{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001118 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001119 len != 0 )
1120 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001122 }
1123
1124 ((void) buf);
1125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126 ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001127
1128 return( 0 );
1129}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001130#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1133static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001134 const unsigned char *buf,
1135 size_t len )
1136{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001137 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001139 len != 0 )
1140 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001142 }
1143
1144 ((void) buf);
1145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146 ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001147
1148 return( 0 );
1149}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001150#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1153static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001154 const unsigned char *buf,
1155 size_t len )
1156{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001157 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001159 len != 0 )
1160 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001162 }
1163
1164 ((void) buf);
1165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001167
1168 return( 0 );
1169}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1173static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001174 const unsigned char *buf,
1175 size_t len )
1176{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001177 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001178 len != 0 )
1179 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001181 }
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001182
1183 ((void) buf);
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02001184
1185 ssl->handshake->new_session_ticket = 1;
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001186
1187 return( 0 );
1188}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001190
Robert Cragie136884c2015-10-02 13:34:31 +01001191#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +01001192 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001194 const unsigned char *buf,
1195 size_t len )
1196{
1197 size_t list_size;
1198 const unsigned char *p;
1199
1200 list_size = buf[0];
1201 if( list_size + 1 != len )
1202 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1204 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001205 }
1206
Manuel Pégourié-Gonnardfd35af12014-06-23 14:10:13 +02001207 p = buf + 1;
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001208 while( list_size > 0 )
1209 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210 if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
1211 p[0] == MBEDTLS_ECP_PF_COMPRESSED )
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001212 {
Robert Cragie136884c2015-10-02 13:34:31 +01001213#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard5734b2d2013-08-15 19:04:02 +02001214 ssl->handshake->ecdh_ctx.point_format = p[0];
Robert Cragie136884c2015-10-02 13:34:31 +01001215#endif
Robert Cragieae8535d2015-10-06 17:11:18 +01001216#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Robert Cragie136884c2015-10-02 13:34:31 +01001217 ssl->handshake->ecjpake_ctx.point_format = p[0];
1218#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219 MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001220 return( 0 );
1221 }
1222
1223 list_size--;
1224 p++;
1225 }
1226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001227 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
1228 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001229}
Robert Cragieae8535d2015-10-06 17:11:18 +01001230#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
1231 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001232
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001233#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1234static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
1235 const unsigned char *buf,
1236 size_t len )
1237{
1238 int ret;
1239
1240 if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
1241 MBEDTLS_KEY_EXCHANGE_ECJPAKE )
1242 {
1243 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
1244 return( 0 );
1245 }
1246
Manuel Pégourié-Gonnardd0d8cb32015-09-17 14:16:30 +02001247 /* If we got here, we no longer need our cached extension */
1248 mbedtls_free( ssl->handshake->ecjpake_cache );
1249 ssl->handshake->ecjpake_cache = NULL;
1250 ssl->handshake->ecjpake_cache_len = 0;
1251
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001252 if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
1253 buf, len ) ) != 0 )
1254 {
1255 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
1256 return( ret );
1257 }
1258
1259 return( 0 );
1260}
1261#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263#if defined(MBEDTLS_SSL_ALPN)
1264static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001265 const unsigned char *buf, size_t len )
1266{
1267 size_t list_len, name_len;
1268 const char **p;
1269
1270 /* If we didn't send it, the server shouldn't send it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001271 if( ssl->conf->alpn_list == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001273
1274 /*
1275 * opaque ProtocolName<1..2^8-1>;
1276 *
1277 * struct {
1278 * ProtocolName protocol_name_list<2..2^16-1>
1279 * } ProtocolNameList;
1280 *
1281 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
1282 */
1283
1284 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
1285 if( len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001287
1288 list_len = ( buf[0] << 8 ) | buf[1];
1289 if( list_len != len - 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001291
1292 name_len = buf[2];
1293 if( name_len != list_len - 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001295
1296 /* Check that the server chosen protocol was in our list and save it */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001297 for( p = ssl->conf->alpn_list; *p != NULL; p++ )
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001298 {
1299 if( name_len == strlen( *p ) &&
1300 memcmp( buf + 3, *p, name_len ) == 0 )
1301 {
1302 ssl->alpn_chosen = *p;
1303 return( 0 );
1304 }
1305 }
1306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001308}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001309#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001310
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001311/*
1312 * Parse HelloVerifyRequest. Only called after verifying the HS type.
1313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001314#if defined(MBEDTLS_SSL_PROTO_DTLS)
1315static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001316{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001318 int major_ver, minor_ver;
1319 unsigned char cookie_len;
1320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001322
1323 /*
1324 * struct {
1325 * ProtocolVersion server_version;
1326 * opaque cookie<0..2^8-1>;
1327 * } HelloVerifyRequest;
1328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001330 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001331 p += 2;
1332
Manuel Pégourié-Gonnardb35fe562014-08-09 17:00:46 +02001333 /*
1334 * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
1335 * even is lower than our min version.
1336 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337 if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
1338 minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001339 major_ver > ssl->conf->max_major_ver ||
1340 minor_ver > ssl->conf->max_minor_ver )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001341 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001342 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1345 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001348 }
1349
1350 cookie_len = *p++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351 MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001354
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02001355 ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001356 if( ssl->handshake->verify_cookie == NULL )
1357 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02001358 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02001359 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001360 }
1361
1362 memcpy( ssl->handshake->verify_cookie, p, cookie_len );
1363 ssl->handshake->verify_cookie_len = cookie_len;
1364
Manuel Pégourié-Gonnard67427c02014-07-11 13:45:34 +02001365 /* Start over at ClientHello */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001366 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
1367 mbedtls_ssl_reset_checksum( ssl );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001371 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001372
1373 return( 0 );
1374}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00001378{
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001379 int ret, i;
Paul Bakker23986e52011-04-24 08:57:21 +00001380 size_t n;
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001381 size_t ext_len;
Paul Bakker48916f92012-09-16 19:57:18 +00001382 unsigned char *buf, *ext;
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001383 unsigned char comp;
1384#if defined(MBEDTLS_ZLIB_SUPPORT)
1385 int accept_comp;
1386#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001387#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001388 int renegotiation_info_seen = 0;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001389#endif
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001390 int handshake_failure = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001391 const mbedtls_ssl_ciphersuite_t *suite_info;
1392#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001393 uint32_t t;
1394#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001396 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001397
Paul Bakker5121ce52009-01-03 21:22:43 +00001398 buf = ssl->in_msg;
1399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001401 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001403 return( ret );
1404 }
1405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001407 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408#if defined(MBEDTLS_SSL_RENEGOTIATION)
1409 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001410 {
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001411 ssl->renego_records_seen++;
1412
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001413 if( ssl->conf->renego_max_records >= 0 &&
1414 ssl->renego_records_seen > ssl->conf->renego_max_records )
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001415 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001417 "but not honored by server" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard44ade652014-08-19 13:58:40 +02001419 }
1420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001421 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
1422 return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001423 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard65919622014-08-19 12:50:30 +02001425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1427 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001428 }
1429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001431 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001432 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433 if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
1436 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001437 return( ssl_parse_hello_verify_request( ssl ) );
1438 }
1439 else
1440 {
1441 /* We made it through the verification process */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 mbedtls_free( ssl->handshake->verify_cookie );
Manuel Pégourié-Gonnard74848812014-07-11 02:43:49 +02001443 ssl->handshake->verify_cookie = NULL;
1444 ssl->handshake->verify_cookie_len = 0;
1445 }
1446 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00001448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449 if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
1450 buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
Paul Bakker5121ce52009-01-03 21:22:43 +00001451 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1453 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001454 }
1455
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001456 /*
1457 * 0 . 1 server_version
1458 * 2 . 33 random (maybe including 4 bytes of Unix time)
1459 * 34 . 34 session_id length = n
1460 * 35 . 34+n session_id
1461 * 35+n . 36+n cipher_suite
1462 * 37+n . 37+n compression_method
1463 *
1464 * 38+n . 39+n extensions length (optional)
1465 * 40+n . .. extensions
1466 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 buf += mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
1470 mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001471 ssl->conf->transport, buf + 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001472
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001473 if( ssl->major_ver < ssl->conf->min_major_ver ||
1474 ssl->minor_ver < ssl->conf->min_minor_ver ||
1475 ssl->major_ver > ssl->conf->max_major_ver ||
1476 ssl->minor_ver > ssl->conf->max_minor_ver )
Paul Bakker1d29fb52012-09-28 13:28:45 +00001477 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001479 " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001480 ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01001481 ssl->major_ver, ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001482 ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1485 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001488 }
1489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#if defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001491 t = ( (uint32_t) buf[2] << 24 )
1492 | ( (uint32_t) buf[3] << 16 )
1493 | ( (uint32_t) buf[4] << 8 )
1494 | ( (uint32_t) buf[5] );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
Paul Bakker87e5cda2012-01-14 18:14:15 +00001496#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001497
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001498 memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001499
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001500 n = buf[34];
Paul Bakker5121ce52009-01-03 21:22:43 +00001501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001503
Paul Bakker48916f92012-09-16 19:57:18 +00001504 if( n > 32 )
1505 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1507 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001508 }
1509
Manuel Pégourié-Gonnarda6e5bd52015-07-23 12:14:13 +02001510 if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
Paul Bakker5121ce52009-01-03 21:22:43 +00001511 {
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001512 ext_len = ( ( buf[38 + n] << 8 )
1513 | ( buf[39 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001514
Paul Bakker48916f92012-09-16 19:57:18 +00001515 if( ( ext_len > 0 && ext_len < 4 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
Paul Bakker48916f92012-09-16 19:57:18 +00001517 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1519 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001520 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001521 }
Manuel Pégourié-Gonnarda6e5bd52015-07-23 12:14:13 +02001522 else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001523 {
1524 ext_len = 0;
1525 }
1526 else
1527 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1529 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardf7cdbc02014-10-17 17:02:10 +02001530 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001531
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001532 /* ciphersuite (used later) */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001533 i = ( buf[35 + n] << 8 ) | buf[36 + n];
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001534
1535 /*
1536 * Read and check compression
1537 */
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001538 comp = buf[37 + n];
Paul Bakker5121ce52009-01-03 21:22:43 +00001539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#if defined(MBEDTLS_ZLIB_SUPPORT)
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001541 /* See comments in ssl_write_client_hello() */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001543 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001544 accept_comp = 0;
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001545 else
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001546#endif
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001547 accept_comp = 1;
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001548
Manuel Pégourié-Gonnard1cf7b302015-06-24 22:28:19 +02001549 if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
1550 ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
1551#else /* MBEDTLS_ZLIB_SUPPORT */
1552 if( comp != MBEDTLS_SSL_COMPRESS_NULL )
1553#endif/* MBEDTLS_ZLIB_SUPPORT */
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001554 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001555 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
1556 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarda0e16322014-07-14 17:38:41 +02001557 }
1558
Paul Bakker380da532012-04-18 16:10:25 +00001559 /*
1560 * Initialize update checksum functions
1561 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001562 ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
Paul Bakker68884e32013-01-07 18:20:04 +01001563
1564 if( ssl->transform_negotiate->ciphersuite_info == NULL )
1565 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
1567 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker68884e32013-01-07 18:20:04 +01001568 }
Paul Bakker380da532012-04-18 16:10:25 +00001569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
Manuel Pégourié-Gonnard3c599f12014-03-10 13:25:07 +01001571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001572 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
1573 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001574
1575 /*
1576 * Check if the session can be resumed
1577 */
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001578 if( ssl->handshake->resume == 0 || n == 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579#if defined(MBEDTLS_SSL_RENEGOTIATION)
1580 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001581#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001582 ssl->session_negotiate->ciphersuite != i ||
1583 ssl->session_negotiate->compression != comp ||
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001584 ssl->session_negotiate->id_len != n ||
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001585 memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 {
1587 ssl->state++;
Paul Bakker0a597072012-09-25 21:55:46 +00001588 ssl->handshake->resume = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589#if defined(MBEDTLS_HAVE_TIME)
Paul Bakker48916f92012-09-16 19:57:18 +00001590 ssl->session_negotiate->start = time( NULL );
Paul Bakkerfa9b1002013-07-03 15:31:03 +02001591#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001592 ssl->session_negotiate->ciphersuite = i;
1593 ssl->session_negotiate->compression = comp;
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02001594 ssl->session_negotiate->id_len = n;
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001595 memcpy( ssl->session_negotiate->id, buf + 35, n );
Paul Bakker5121ce52009-01-03 21:22:43 +00001596 }
1597 else
1598 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001599 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Paul Bakkerff60ee62010-03-16 21:09:09 +00001600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001601 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Paul Bakkerff60ee62010-03-16 21:09:09 +00001602 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001603 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Paul Bakkerff60ee62010-03-16 21:09:09 +00001604 return( ret );
1605 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001606 }
1607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001608 MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
Paul Bakker0a597072012-09-25 21:55:46 +00001609 ssl->handshake->resume ? "a" : "no" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001610
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +02001611 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614 suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02001615 if( suite_info == NULL
1616#if defined(MBEDTLS_ARC4_C)
1617 || ( ssl->conf->arc4_disabled &&
1618 suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
1619#endif
1620 )
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001621 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001622 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1623 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001624 }
1625
Manuel Pégourié-Gonnard60884a12015-09-16 11:13:41 +02001626 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
1627
Paul Bakker5121ce52009-01-03 21:22:43 +00001628 i = 0;
1629 while( 1 )
1630 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001631 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001632 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001633 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1634 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001635 }
1636
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001637 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001638 ssl->session_negotiate->ciphersuite )
1639 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001640 break;
Paul Bakker8f4ddae2013-04-15 15:09:54 +02001641 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001642 }
1643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001644 if( comp != MBEDTLS_SSL_COMPRESS_NULL
1645#if defined(MBEDTLS_ZLIB_SUPPORT)
1646 && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
Paul Bakker2770fbd2012-07-03 13:30:23 +00001647#endif
1648 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001649 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001650 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1651 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001652 }
Paul Bakker48916f92012-09-16 19:57:18 +00001653 ssl->session_negotiate->compression = comp;
Paul Bakker5121ce52009-01-03 21:22:43 +00001654
Manuel Pégourié-Gonnard0b3400d2014-09-10 21:23:41 +02001655 ext = buf + 40 + n;
Paul Bakker48916f92012-09-16 19:57:18 +00001656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001657 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
Manuel Pégourié-Gonnarda0528492013-07-16 17:26:28 +02001658
Paul Bakker48916f92012-09-16 19:57:18 +00001659 while( ext_len )
1660 {
1661 unsigned int ext_id = ( ( ext[0] << 8 )
1662 | ( ext[1] ) );
1663 unsigned int ext_size = ( ( ext[2] << 8 )
1664 | ( ext[3] ) );
1665
1666 if( ext_size + 4 > ext_len )
1667 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001668 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1669 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001670 }
1671
1672 switch( ext_id )
1673 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001674 case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1675 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
1676#if defined(MBEDTLS_SSL_RENEGOTIATION)
Paul Bakker48916f92012-09-16 19:57:18 +00001677 renegotiation_info_seen = 1;
Manuel Pégourié-Gonnardeaecbd32014-11-06 02:38:02 +01001678#endif
Paul Bakker48916f92012-09-16 19:57:18 +00001679
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001680 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
1681 ext_size ) ) != 0 )
Paul Bakker48916f92012-09-16 19:57:18 +00001682 return( ret );
1683
1684 break;
1685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1687 case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1688 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001689
1690 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
1691 ext + 4, ext_size ) ) != 0 )
1692 {
1693 return( ret );
1694 }
1695
1696 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001697#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Manuel Pégourié-Gonnardde600e52013-07-17 10:14:38 +02001698
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1700 case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
1701 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001702
1703 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
1704 ext + 4, ext_size ) ) != 0 )
1705 {
1706 return( ret );
1707 }
1708
1709 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001710#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
Manuel Pégourié-Gonnard57c28522013-07-19 11:41:43 +02001711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001712#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1713 case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1714 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001715
1716 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
1717 ext + 4, ext_size ) ) != 0 )
1718 {
1719 return( ret );
1720 }
1721
1722 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001723#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001725#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1726 case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1727 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001728
1729 if( ( ret = ssl_parse_extended_ms_ext( ssl,
1730 ext + 4, ext_size ) ) != 0 )
1731 {
1732 return( ret );
1733 }
1734
1735 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001738#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1739 case MBEDTLS_TLS_EXT_SESSION_TICKET:
1740 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001741
1742 if( ( ret = ssl_parse_session_ticket_ext( ssl,
1743 ext + 4, ext_size ) ) != 0 )
1744 {
1745 return( ret );
1746 }
1747
1748 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnard60182ef2013-08-02 14:44:54 +02001750
Robert Cragie136884c2015-10-02 13:34:31 +01001751#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
Robert Cragieae8535d2015-10-06 17:11:18 +01001752 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753 case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1754 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001755
1756 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
1757 ext + 4, ext_size ) ) != 0 )
1758 {
1759 return( ret );
1760 }
1761
1762 break;
Robert Cragieae8535d2015-10-06 17:11:18 +01001763#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
1764 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001765
Manuel Pégourié-Gonnard0a1324a2015-09-16 16:01:00 +02001766#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1767 case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
1768 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
1769
1770 if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
1771 ext + 4, ext_size ) ) != 0 )
1772 {
1773 return( ret );
1774 }
1775
1776 break;
1777#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Manuel Pégourié-Gonnard7b19c162013-08-15 18:01:11 +02001778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779#if defined(MBEDTLS_SSL_ALPN)
1780 case MBEDTLS_TLS_EXT_ALPN:
1781 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001782
1783 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
1784 return( ret );
1785
1786 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard0b874dc2014-04-07 10:57:45 +02001788
Paul Bakker48916f92012-09-16 19:57:18 +00001789 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001790 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
Paul Bakker48916f92012-09-16 19:57:18 +00001791 ext_id ) );
1792 }
1793
1794 ext_len -= 4 + ext_size;
1795 ext += 4 + ext_size;
1796
1797 if( ext_len > 0 && ext_len < 4 )
1798 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
1800 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001801 }
1802 }
1803
1804 /*
1805 * Renegotiation security checks
1806 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001807 if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001808 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00001809 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001810 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001811 handshake_failure = 1;
Paul Bakkerf7abd422013-04-16 13:15:56 +02001812 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001813#if defined(MBEDTLS_SSL_RENEGOTIATION)
1814 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1815 ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001816 renegotiation_info_seen == 0 )
1817 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001818 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001819 handshake_failure = 1;
Paul Bakker48916f92012-09-16 19:57:18 +00001820 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001821 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1822 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001823 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
Paul Bakker48916f92012-09-16 19:57:18 +00001824 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001826 handshake_failure = 1;
1827 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1829 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001830 renegotiation_info_seen == 1 )
1831 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001833 handshake_failure = 1;
1834 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001836
1837 if( handshake_failure == 1 )
1838 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001840 return( ret );
1841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001843 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 return( 0 );
1848}
1849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1851 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1852static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
Paul Bakker29e1f122013-04-16 13:07:56 +02001853 unsigned char *end )
1854{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001856
Paul Bakker29e1f122013-04-16 13:07:56 +02001857 /*
1858 * Ephemeral DH parameters:
1859 *
1860 * struct {
1861 * opaque dh_p<1..2^16-1>;
1862 * opaque dh_g<1..2^16-1>;
1863 * opaque dh_Ys<1..2^16-1>;
1864 * } ServerDHParams;
1865 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001867 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001869 return( ret );
1870 }
1871
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001872 if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
Paul Bakker29e1f122013-04-16 13:07:56 +02001873 {
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001874 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
1875 ssl->handshake->dhm_ctx.len * 8,
1876 ssl->conf->dhm_min_bitlen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001878 }
1879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
1881 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
1882 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
Paul Bakker29e1f122013-04-16 13:07:56 +02001883
1884 return( ret );
1885}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1887 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001889#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1890 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1891 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
1892 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1893 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1894static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001896 const mbedtls_ecp_curve_info *curve_info;
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001897
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001899 if( curve_info == NULL )
1900 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1902 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001903 }
1904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001906
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02001907#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02001908 if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001909#else
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001910 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
1911 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001912#endif
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001913 return( -1 );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001915 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001916
1917 return( 0 );
1918}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1920 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1921 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
1922 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1923 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001925#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1926 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1927 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
1928static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001929 unsigned char **p,
1930 unsigned char *end )
1931{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001933
Paul Bakker29e1f122013-04-16 13:07:56 +02001934 /*
1935 * Ephemeral ECDH parameters:
1936 *
1937 * struct {
1938 * ECParameters curve_params;
1939 * ECPoint public;
1940 * } ServerECDHParams;
1941 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001942 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
Paul Bakker29e1f122013-04-16 13:07:56 +02001943 (const unsigned char **) p, end ) ) != 0 )
1944 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001946 return( ret );
1947 }
1948
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001949 if( ssl_check_server_ecdh_params( ssl ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001950 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
1952 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001953 }
1954
Paul Bakker29e1f122013-04-16 13:07:56 +02001955 return( ret );
1956}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1958 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1959 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001961#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1962static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001963 unsigned char **p,
1964 unsigned char *end )
1965{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001966 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001967 size_t len;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001968 ((void) ssl);
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001969
1970 /*
1971 * PSK parameters:
1972 *
1973 * opaque psk_identity_hint<0..2^16-1>;
1974 */
Manuel Pégourié-Gonnard59b9fe22013-10-15 11:55:33 +02001975 len = (*p)[0] << 8 | (*p)[1];
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001976 *p += 2;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001977
1978 if( (*p) + len > end )
1979 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
1981 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001982 }
1983
Manuel Pégourié-Gonnard9d624122016-02-22 11:10:14 +01001984 /*
1985 * Note: we currently ignore the PKS identity hint, as we only allow one
1986 * PSK to be provisionned on the client. This could be changed later if
1987 * someone needs that feature.
1988 */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001989 *p += len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001990 ret = 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001991
1992 return( ret );
1993}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001994#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001995
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001996#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
1997 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001998/*
1999 * Generate a pre-master secret and encrypt it with the server's RSA key
2000 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002002 size_t offset, size_t *olen,
2003 size_t pms_offset )
2004{
2005 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002006 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002007 unsigned char *p = ssl->handshake->premaster + pms_offset;
2008
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002009 if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN )
2010 {
2011 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
2012 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2013 }
2014
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002015 /*
2016 * Generate (part of) the pre-master as
2017 * struct {
2018 * ProtocolVersion client_version;
2019 * opaque random[46];
2020 * } PreMasterSecret;
2021 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002022 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
2023 ssl->conf->transport, p );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002024
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002025 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002026 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002027 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002028 return( ret );
2029 }
2030
2031 ssl->handshake->pmslen = 48;
2032
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002033 if( ssl->session_negotiate->peer_cert == NULL )
2034 {
2035 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2036 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2037 }
2038
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002039 /*
2040 * Now write it out, encrypted
2041 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2043 MBEDTLS_PK_RSA ) )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002044 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002045 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
2046 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002047 }
2048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002050 p, ssl->handshake->pmslen,
2051 ssl->out_msg + offset + len_bytes, olen,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002053 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002054 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002055 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002056 return( ret );
2057 }
2058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2060 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002061 if( len_bytes == 2 )
2062 {
2063 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
2064 ssl->out_msg[offset+1] = (unsigned char)( *olen );
2065 *olen += 2;
2066 }
2067#endif
2068
2069 return( 0 );
2070}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002071#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
2072 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02002073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002074#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard5c2a7ca2015-10-23 08:48:41 +02002075#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2076 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2077 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002078static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02002079 unsigned char **p,
2080 unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002081 mbedtls_md_type_t *md_alg,
2082 mbedtls_pk_type_t *pk_alg )
Paul Bakker29e1f122013-04-16 13:07:56 +02002083{
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02002084 ((void) ssl);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002085 *md_alg = MBEDTLS_MD_NONE;
2086 *pk_alg = MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002087
2088 /* Only in TLS 1.2 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002090 {
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002091 return( 0 );
2092 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002093
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002094 if( (*p) + 2 > end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002096
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002097 /*
2098 * Get hash algorithm
2099 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002100 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002101 {
Manuel Pégourié-Gonnardd8053242015-12-08 09:53:51 +01002102 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002103 "HashAlgorithm %d", *(p)[0] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002104 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002105 }
2106
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002107 /*
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002108 * Get signature algorithm
2109 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002110 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002111 {
Manuel Pégourié-Gonnardd8053242015-12-08 09:53:51 +01002112 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002113 "SignatureAlgorithm %d", (*p)[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002114 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002115 }
2116
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02002117 /*
2118 * Check if the hash is acceptable
2119 */
2120 if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
2121 {
Manuel Pégourié-Gonnardd8053242015-12-08 09:53:51 +01002122 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm "
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02002123 "that was not offered" ) );
2124 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2125 }
2126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002127 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
2128 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002129 *p += 2;
2130
2131 return( 0 );
2132}
Manuel Pégourié-Gonnard5c2a7ca2015-10-23 08:48:41 +02002133#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2134 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2135 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002136#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002138#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2139 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2140static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002141{
2142 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143 const mbedtls_ecp_keypair *peer_key;
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002144
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002145 if( ssl->session_negotiate->peer_cert == NULL )
2146 {
2147 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2148 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2149 }
2150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2152 MBEDTLS_PK_ECKEY ) )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002153 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002154 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
2155 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002156 }
2157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002158 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002160 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
2161 MBEDTLS_ECDH_THEIRS ) ) != 0 )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002162 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002163 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002164 return( ret );
2165 }
2166
2167 if( ssl_check_server_ecdh_params( ssl ) != 0 )
2168 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
2170 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002171 }
2172
2173 return( ret );
2174}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
2176 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker41c83d32013-03-20 14:39:14 +01002179{
Paul Bakker23986e52011-04-24 08:57:21 +00002180 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002182 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00002183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002184 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002186#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2187 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002188 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002189 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002190 ssl->state++;
2191 return( 0 );
2192 }
Manuel Pégourié-Gonnardbac0e3b2013-10-15 11:54:47 +02002193 ((void) p);
2194 ((void) end);
2195#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002196
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2198 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2199 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2200 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002201 {
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002202 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
2203 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002204 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002205 return( ret );
2206 }
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002208 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002209 ssl->state++;
2210 return( 0 );
2211 }
2212 ((void) p);
2213 ((void) end);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002214#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2215 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002216
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002217 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002218 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002219 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002220 return( ret );
2221 }
2222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002223 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002224 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002225 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2226 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002227 }
2228
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002229 /*
2230 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
2231 * doesn't use a psk_identity_hint
2232 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002233 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002234 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2236 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Paul Bakker188c8de2013-04-19 09:13:37 +02002237 {
2238 ssl->record_read = 1;
2239 goto exit;
2240 }
2241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2243 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002244 }
2245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002247 end = ssl->in_msg + ssl->in_hslen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002248 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002250#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2251 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2252 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2253 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2254 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002255 {
2256 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
2257 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002258 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2259 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002260 }
2261 } /* FALLTROUGH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002262#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002264#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
2265 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2266 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2267 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002268 ; /* nothing more to do */
2269 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002270#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
2271 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2272#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2273 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2274 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2275 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker5121ce52009-01-03 21:22:43 +00002276 {
Paul Bakker29e1f122013-04-16 13:07:56 +02002277 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002278 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002279 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2280 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002281 }
2282 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002283 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002284#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2285 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2286#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2287 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
2288 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2289 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2290 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2291 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002292 {
2293 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
2294 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2296 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002297 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002298 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002299 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002300#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2301 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2302 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002303#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2304 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2305 {
2306 ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
2307 p, end - p );
2308 if( ret != 0 )
2309 {
2310 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
2311 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2312 }
2313 }
2314 else
2315#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakker41c83d32013-03-20 14:39:14 +01002316 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2318 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002319 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002321#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2322 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2323 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2324 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2325 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2326 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002327 {
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002328 size_t sig_len, hashlen;
2329 unsigned char hash[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002330 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2331 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2332 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002333 size_t params_len = p - params;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002334
Paul Bakker29e1f122013-04-16 13:07:56 +02002335 /*
2336 * Handle the digitally-signed structure
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 Bakker1ef83d62012-04-11 12:09:53 +00002340 {
Paul Bakker9659dae2013-08-28 16:21:34 +02002341 if( ssl_parse_signature_algorithm( ssl, &p, end,
2342 &md_alg, &pk_alg ) != 0 )
2343 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002344 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2345 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker9659dae2013-08-28 16:21:34 +02002346 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002348 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002349 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002350 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2351 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002352 }
2353 }
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002354 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002355#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2356#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2357 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2358 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002359 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002360 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002361
Paul Bakker9659dae2013-08-28 16:21:34 +02002362 /* Default hash for ECDSA is SHA-1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002363 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
2364 md_alg = MBEDTLS_MD_SHA1;
Paul Bakker9659dae2013-08-28 16:21:34 +02002365 }
2366 else
2367#endif
2368 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002369 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2370 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker9659dae2013-08-28 16:21:34 +02002371 }
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002372
2373 /*
2374 * Read signature
2375 */
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002376 sig_len = ( p[0] << 8 ) | p[1];
Paul Bakker1ef83d62012-04-11 12:09:53 +00002377 p += 2;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002378
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002379 if( end != p + sig_len )
Paul Bakker41c83d32013-03-20 14:39:14 +01002380 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002381 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2382 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002383 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002385 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002386
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002387 /*
2388 * Compute the hash that has been signed
2389 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002390#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2391 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2392 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002393 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002394 mbedtls_md5_context mbedtls_md5;
2395 mbedtls_sha1_context mbedtls_sha1;
Paul Bakker29e1f122013-04-16 13:07:56 +02002396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002397 mbedtls_md5_init( &mbedtls_md5 );
2398 mbedtls_sha1_init( &mbedtls_sha1 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002399
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002400 hashlen = 36;
2401
Paul Bakker29e1f122013-04-16 13:07:56 +02002402 /*
2403 * digitally-signed struct {
2404 * opaque md5_hash[16];
2405 * opaque sha_hash[20];
2406 * };
2407 *
2408 * md5_hash
2409 * MD5(ClientHello.random + ServerHello.random
2410 * + ServerParams);
2411 * sha_hash
2412 * SHA(ClientHello.random + ServerHello.random
2413 * + ServerParams);
2414 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002415 mbedtls_md5_starts( &mbedtls_md5 );
2416 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
2417 mbedtls_md5_update( &mbedtls_md5, params, params_len );
2418 mbedtls_md5_finish( &mbedtls_md5, hash );
Paul Bakker29e1f122013-04-16 13:07:56 +02002419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002420 mbedtls_sha1_starts( &mbedtls_sha1 );
2421 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
2422 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
2423 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002425 mbedtls_md5_free( &mbedtls_md5 );
2426 mbedtls_sha1_free( &mbedtls_sha1 );
Paul Bakker29e1f122013-04-16 13:07:56 +02002427 }
2428 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002429#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2430 MBEDTLS_SSL_PROTO_TLS1_1 */
2431#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2432 defined(MBEDTLS_SSL_PROTO_TLS1_2)
2433 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002435 mbedtls_md_context_t ctx;
Paul Bakker29e1f122013-04-16 13:07:56 +02002436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002437 mbedtls_md_init( &ctx );
Paul Bakker84bbeb52014-07-01 14:53:22 +02002438
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002439 /* Info from md_alg will be used instead */
2440 hashlen = 0;
Paul Bakker29e1f122013-04-16 13:07:56 +02002441
2442 /*
2443 * digitally-signed struct {
2444 * opaque client_random[32];
2445 * opaque server_random[32];
2446 * ServerDHParams params;
2447 * };
2448 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 if( ( ret = mbedtls_md_setup( &ctx,
2450 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02002451 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002452 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02002453 return( ret );
2454 }
2455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002456 mbedtls_md_starts( &ctx );
2457 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
2458 mbedtls_md_update( &ctx, params, params_len );
2459 mbedtls_md_finish( &ctx, hash );
2460 mbedtls_md_free( &ctx );
Paul Bakker29e1f122013-04-16 13:07:56 +02002461 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002462 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002463#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2464 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002465 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002466 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2467 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002468 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002470 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
2471 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002472
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002473 if( ssl->session_negotiate->peer_cert == NULL )
2474 {
2475 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2476 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2477 }
2478
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002479 /*
2480 * Verify signature
2481 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002482 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002483 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002484 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2485 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002486 }
2487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002488 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard20846b12013-08-19 12:32:12 +02002489 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002490 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002491 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002492 return( ret );
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002493 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002494 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2496 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2497 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002498
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002499exit:
Paul Bakker5121ce52009-01-03 21:22:43 +00002500 ssl->state++;
2501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002502 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002503
2504 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002505}
2506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002507#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2508 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2509 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2510 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2511static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002512{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002513 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002515 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002517 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2518 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2519 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002520 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2521 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002522 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002523 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002524 ssl->state++;
2525 return( 0 );
2526 }
2527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002528 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2529 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002530}
2531#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002532static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002533{
2534 int ret;
Paul Bakker926af752012-11-23 13:38:07 +01002535 unsigned char *buf, *p;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002536 size_t n = 0, m = 0;
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002537 size_t cert_type_len = 0, dn_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002538 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002540 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002542 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2543 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2544 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002545 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2546 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002547 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002548 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002549 ssl->state++;
2550 return( 0 );
2551 }
2552
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002553 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002554 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002555 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002556 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002557 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002558 return( ret );
2559 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002560
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002561 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002562 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002563 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2564 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002565 }
2566
2567 ssl->record_read = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002568 }
2569
2570 ssl->client_auth = 0;
2571 ssl->state++;
2572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002573 if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
Paul Bakker5121ce52009-01-03 21:22:43 +00002574 ssl->client_auth++;
2575
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002576 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
Paul Bakker5121ce52009-01-03 21:22:43 +00002577 ssl->client_auth ? "a" : "no" ) );
2578
Paul Bakker926af752012-11-23 13:38:07 +01002579 if( ssl->client_auth == 0 )
2580 goto exit;
2581
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002582 ssl->record_read = 0;
2583
Paul Bakker926af752012-11-23 13:38:07 +01002584 // TODO: handshake_failure alert for an anonymous server to request
2585 // client authentication
2586
Manuel Pégourié-Gonnard04c1b4e2014-09-10 19:25:43 +02002587 /*
2588 * struct {
2589 * ClientCertificateType certificate_types<1..2^8-1>;
2590 * SignatureAndHashAlgorithm
2591 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2592 * DistinguishedName certificate_authorities<0..2^16-1>;
2593 * } CertificateRequest;
2594 */
Paul Bakker926af752012-11-23 13:38:07 +01002595 buf = ssl->in_msg;
Paul Bakkerf7abd422013-04-16 13:15:56 +02002596
Paul Bakker926af752012-11-23 13:38:07 +01002597 // Retrieve cert types
2598 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002599 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
Paul Bakker926af752012-11-23 13:38:07 +01002600 n = cert_type_len;
2601
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002602 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002603 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002604 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2605 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002606 }
2607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002608 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
Paul Bakker926af752012-11-23 13:38:07 +01002609 while( cert_type_len > 0 )
2610 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002611#if defined(MBEDTLS_RSA_C)
2612 if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
2613 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
Paul Bakker926af752012-11-23 13:38:07 +01002614 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002615 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
Paul Bakker926af752012-11-23 13:38:07 +01002616 break;
2617 }
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002618 else
2619#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002620#if defined(MBEDTLS_ECDSA_C)
2621 if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
2622 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002623 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002624 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002625 break;
2626 }
2627 else
2628#endif
2629 {
2630 ; /* Unsupported cert type, ignore */
2631 }
Paul Bakker926af752012-11-23 13:38:07 +01002632
2633 cert_type_len--;
2634 p++;
2635 }
2636
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002637#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2638 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002639 {
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002640 /* Ignored, see comments about hash in write_certificate_verify */
2641 // TODO: should check the signature part against our pk_key though
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002642 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
2643 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002644
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002645 m += 2;
Paul Bakker926af752012-11-23 13:38:07 +01002646 n += sig_alg_len;
2647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002648 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002649 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002650 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2651 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002652 }
Paul Bakkerf7abd422013-04-16 13:15:56 +02002653 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002654#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker926af752012-11-23 13:38:07 +01002655
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002656 /* Ignore certificate_authorities, we only have one cert anyway */
2657 // TODO: should not send cert if no CA matches
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002658 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
2659 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002660
2661 n += dn_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002662 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
Paul Bakker926af752012-11-23 13:38:07 +01002663 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002664 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2665 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002666 }
2667
2668exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002669 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002670
2671 return( 0 );
2672}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002673#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2674 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2675 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
2676 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002677
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002678static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002679{
2680 int ret;
2681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002682 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002683
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002684 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002685 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002686 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002687 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002688 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002689 return( ret );
2690 }
2691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002692 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002693 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002694 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2695 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002696 }
2697 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002698 ssl->record_read = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002700 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
2701 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002702 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002703 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2704 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002705 }
2706
2707 ssl->state++;
2708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002709#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002710 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002711 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002712#endif
2713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002714 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002715
2716 return( 0 );
2717}
2718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002719static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002720{
Paul Bakker23986e52011-04-24 08:57:21 +00002721 int ret;
2722 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002723 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002725 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002726
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002727#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2728 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002729 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002730 /*
2731 * DHM key exchange -- send G^X mod P
2732 */
Paul Bakker48916f92012-09-16 19:57:18 +00002733 n = ssl->handshake->dhm_ctx.len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002734
2735 ssl->out_msg[4] = (unsigned char)( n >> 8 );
2736 ssl->out_msg[5] = (unsigned char)( n );
2737 i = 6;
2738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002739 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2740 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Paul Bakker5121ce52009-01-03 21:22:43 +00002741 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002742 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 if( ret != 0 )
2744 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002745 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002746 return( ret );
2747 }
2748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002749 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
2750 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
Paul Bakker5121ce52009-01-03 21:22:43 +00002751
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002752 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
Paul Bakker48916f92012-09-16 19:57:18 +00002753 ssl->handshake->premaster,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01002754 MBEDTLS_PREMASTER_SIZE,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +02002755 &ssl->handshake->pmslen,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002756 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002757 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002758 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002759 return( ret );
2760 }
2761
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002762 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
Paul Bakker5121ce52009-01-03 21:22:43 +00002763 }
2764 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002765#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2766#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2767 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
2768 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2769 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2770 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2771 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2772 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2773 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Paul Bakker41c83d32013-03-20 14:39:14 +01002774 {
2775 /*
2776 * ECDH key exchange -- send client public value
2777 */
2778 i = 4;
2779
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002780 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002781 &n,
2782 &ssl->out_msg[i], 1000,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002783 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker41c83d32013-03-20 14:39:14 +01002784 if( ret != 0 )
2785 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002786 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002787 return( ret );
2788 }
2789
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002790 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Paul Bakker41c83d32013-03-20 14:39:14 +01002791
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002792 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002793 &ssl->handshake->pmslen,
2794 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002795 MBEDTLS_MPI_MAX_SIZE,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002796 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002797 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002798 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002799 return( ret );
2800 }
2801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002802 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
Paul Bakker41c83d32013-03-20 14:39:14 +01002803 }
2804 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002805#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2806 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2807 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2808 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2809#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2810 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2811 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2812 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2813 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002814 {
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002815 /*
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002816 * opaque psk_identity<0..2^16-1>;
2817 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002818 if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002819 {
2820 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002821 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002822 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002823
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002824 i = 4;
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002825 n = ssl->conf->psk_identity_len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002826
2827 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2828 {
2829 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
2830 "SSL buffer too short" ) );
2831 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2832 }
2833
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002834 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2835 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002836
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002837 memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
2838 i += ssl->conf->psk_identity_len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002839
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002840#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
2841 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002842 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002843 n = 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002844 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002845 else
2846#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002847#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2848 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002849 {
2850 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
2851 return( ret );
2852 }
2853 else
2854#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002855#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2856 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002857 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002858 /*
2859 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
2860 */
2861 n = ssl->handshake->dhm_ctx.len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002862
2863 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2864 {
2865 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
2866 " or SSL buffer too short" ) );
2867 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2868 }
2869
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002870 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2871 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002873 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2874 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002875 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002876 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002877 if( ret != 0 )
2878 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002879 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002880 return( ret );
2881 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002882 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002883 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002884#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2885#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2886 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002887 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002888 /*
2889 * ClientECDiffieHellmanPublic public;
2890 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002891 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
2892 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002893 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002894 if( ret != 0 )
2895 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002896 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002897 return( ret );
2898 }
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002899
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002900 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002901 }
2902 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002903#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002904 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002905 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2906 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002907 }
2908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002909 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002910 ciphersuite_info->key_exchange ) ) != 0 )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002911 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002912 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002913 return( ret );
2914 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002915 }
2916 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002917#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
2918#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2919 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002920 {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002921 i = 4;
2922 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
Paul Bakkera3d195c2011-11-27 21:07:34 +00002923 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002924 }
Paul Bakkered27a042013-04-18 22:46:23 +02002925 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002926#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002927#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2928 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2929 {
2930 i = 4;
2931
2932 ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
2933 ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
2934 ssl->conf->f_rng, ssl->conf->p_rng );
2935 if( ret != 0 )
2936 {
2937 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
2938 return( ret );
2939 }
2940
2941 ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
2942 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
2943 ssl->conf->f_rng, ssl->conf->p_rng );
2944 if( ret != 0 )
2945 {
2946 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
2947 return( ret );
2948 }
2949 }
2950 else
2951#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Paul Bakkered27a042013-04-18 22:46:23 +02002952 {
2953 ((void) ciphersuite_info);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002954 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2955 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkered27a042013-04-18 22:46:23 +02002956 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002957
Paul Bakker5121ce52009-01-03 21:22:43 +00002958 ssl->out_msglen = i + n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002959 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2960 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002961
2962 ssl->state++;
2963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002964 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002965 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002966 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002967 return( ret );
2968 }
2969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002970 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002971
2972 return( 0 );
2973}
2974
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002975#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2976 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2977 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2978 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2979static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002980{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002981 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002982 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002984 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002986 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002987 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002988 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002989 return( ret );
2990 }
2991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002992 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2993 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2994 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002995 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2996 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakkered27a042013-04-18 22:46:23 +02002997 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002998 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakkered27a042013-04-18 22:46:23 +02002999 ssl->state++;
3000 return( 0 );
3001 }
3002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003003 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3004 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003005}
3006#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003007static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003008{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003009 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3010 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003011 size_t n = 0, offset = 0;
3012 unsigned char hash[48];
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003013 unsigned char *hash_start = hash;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003014 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003015 unsigned int hashlen;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003017 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003019 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003020 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003021 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003022 return( ret );
3023 }
3024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003025 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
3026 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
3027 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02003028 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
3029 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003030 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003031 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003032 ssl->state++;
3033 return( 0 );
3034 }
3035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003036 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003037 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003038 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003039 ssl->state++;
3040 return( 0 );
3041 }
3042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003043 if( mbedtls_ssl_own_key( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003044 {
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02003045 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003046 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003047 }
3048
3049 /*
3050 * Make an RSA signature of the handshake digests
3051 */
Paul Bakker48916f92012-09-16 19:57:18 +00003052 ssl->handshake->calc_verify( ssl, hash );
Paul Bakker5121ce52009-01-03 21:22:43 +00003053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003054#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3055 defined(MBEDTLS_SSL_PROTO_TLS1_1)
3056 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00003057 {
Paul Bakker926af752012-11-23 13:38:07 +01003058 /*
3059 * digitally-signed struct {
3060 * opaque md5_hash[16];
3061 * opaque sha_hash[20];
3062 * };
3063 *
3064 * md5_hash
3065 * MD5(handshake_messages);
3066 *
3067 * sha_hash
3068 * SHA(handshake_messages);
3069 */
3070 hashlen = 36;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003071 md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003072
3073 /*
3074 * For ECDSA, default hash is SHA-1 only
3075 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003076 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003077 {
3078 hash_start += 16;
3079 hashlen -= 16;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003080 md_alg = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003081 }
Paul Bakker926af752012-11-23 13:38:07 +01003082 }
3083 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003084#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
3085 MBEDTLS_SSL_PROTO_TLS1_1 */
3086#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3087 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01003088 {
3089 /*
3090 * digitally-signed struct {
3091 * opaque handshake_messages[handshake_messages_length];
3092 * };
3093 *
3094 * Taking shortcut here. We assume that the server always allows the
3095 * PRF Hash function and has sent it in the allowed signature
3096 * algorithms list received in the Certificate Request message.
3097 *
3098 * Until we encounter a server that does not, we will take this
3099 * shortcut.
3100 *
3101 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
3102 * in order to satisfy 'weird' needs from the server side.
3103 */
Paul Bakkerb7149bc2013-03-20 15:30:09 +01003104 if( ssl->transform_negotiate->ciphersuite_info->mac ==
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003105 MBEDTLS_MD_SHA384 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00003106 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003107 md_alg = MBEDTLS_MD_SHA384;
3108 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003109 }
3110 else
3111 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003112 md_alg = MBEDTLS_MD_SHA256;
3113 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003114 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003115 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
Paul Bakker1ef83d62012-04-11 12:09:53 +00003116
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +02003117 /* Info from md_alg will be used instead */
3118 hashlen = 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003119 offset = 2;
3120 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003121 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003122#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02003123 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003124 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3125 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02003126 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00003127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003128 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003129 ssl->out_msg + 6 + offset, &n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01003130 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003131 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003132 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003133 return( ret );
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003134 }
Paul Bakker926af752012-11-23 13:38:07 +01003135
Paul Bakker1ef83d62012-04-11 12:09:53 +00003136 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
3137 ssl->out_msg[5 + offset] = (unsigned char)( n );
Paul Bakker5121ce52009-01-03 21:22:43 +00003138
Paul Bakker1ef83d62012-04-11 12:09:53 +00003139 ssl->out_msglen = 6 + n + offset;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003140 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3141 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00003142
3143 ssl->state++;
3144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003145 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003146 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003147 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003148 return( ret );
3149 }
3150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003151 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003152
Paul Bakkered27a042013-04-18 22:46:23 +02003153 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003154}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003155#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
3156 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
3157 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00003158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003159#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3160static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003161{
3162 int ret;
3163 uint32_t lifetime;
3164 size_t ticket_len;
3165 unsigned char *ticket;
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003166 const unsigned char *msg;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003168 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003170 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003171 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003172 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003173 return( ret );
3174 }
3175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003176 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003178 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3179 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003180 }
3181
3182 /*
3183 * struct {
3184 * uint32 ticket_lifetime_hint;
3185 * opaque ticket<0..2^16-1>;
3186 * } NewSessionTicket;
3187 *
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003188 * 0 . 3 ticket_lifetime_hint
3189 * 4 . 5 ticket_len (n)
3190 * 6 . 5+n ticket content
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003192 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
3193 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003194 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003195 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3196 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003197 }
3198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003199 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003200
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003201 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
3202 ( msg[2] << 8 ) | ( msg[3] );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003203
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003204 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
3205
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003206 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003207 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003208 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3209 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003210 }
3211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003212 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003213
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003214 /* We're not waiting for a NewSessionTicket message any more */
3215 ssl->handshake->new_session_ticket = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003216 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003217
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003218 /*
3219 * Zero-length ticket means the server changed his mind and doesn't want
3220 * to send a ticket after all, so just forget it
3221 */
Paul Bakker66d5d072014-06-17 16:39:18 +02003222 if( ticket_len == 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003223 return( 0 );
3224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003225 mbedtls_zeroize( ssl->session_negotiate->ticket,
Paul Bakker34617722014-06-13 17:20:13 +02003226 ssl->session_negotiate->ticket_len );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003227 mbedtls_free( ssl->session_negotiate->ticket );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003228 ssl->session_negotiate->ticket = NULL;
3229 ssl->session_negotiate->ticket_len = 0;
3230
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02003231 if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003232 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02003233 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02003234 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003235 }
3236
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003237 memcpy( ticket, msg + 6, ticket_len );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003238
3239 ssl->session_negotiate->ticket = ticket;
3240 ssl->session_negotiate->ticket_len = ticket_len;
3241 ssl->session_negotiate->ticket_lifetime = lifetime;
3242
3243 /*
3244 * RFC 5077 section 3.4:
3245 * "If the client receives a session ticket from the server, then it
3246 * discards any Session ID that was sent in the ServerHello."
3247 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003248 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02003249 ssl->session_negotiate->id_len = 0;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003251 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003252
3253 return( 0 );
3254}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003255#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003256
Paul Bakker5121ce52009-01-03 21:22:43 +00003257/*
Paul Bakker1961b702013-01-25 14:49:24 +01003258 * SSL handshake -- client side -- single step
Paul Bakker5121ce52009-01-03 21:22:43 +00003259 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003260int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00003261{
3262 int ret = 0;
3263
Manuel Pégourié-Gonnarddba460f2015-06-24 22:59:30 +02003264 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003265 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00003266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003267 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
Paul Bakker1961b702013-01-25 14:49:24 +01003268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003269 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker1961b702013-01-25 14:49:24 +01003270 return( ret );
3271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003272#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003273 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003274 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003275 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003276 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003277 return( ret );
3278 }
3279#endif
3280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003281 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003282 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003283#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3284 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003285 ssl->handshake->new_session_ticket != 0 )
3286 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003287 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003288 }
3289#endif
3290
Paul Bakker1961b702013-01-25 14:49:24 +01003291 switch( ssl->state )
Paul Bakker5121ce52009-01-03 21:22:43 +00003292 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003293 case MBEDTLS_SSL_HELLO_REQUEST:
3294 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00003295 break;
3296
Paul Bakker1961b702013-01-25 14:49:24 +01003297 /*
3298 * ==> ClientHello
3299 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003300 case MBEDTLS_SSL_CLIENT_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003301 ret = ssl_write_client_hello( ssl );
3302 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003303
Paul Bakker1961b702013-01-25 14:49:24 +01003304 /*
3305 * <== ServerHello
3306 * Certificate
3307 * ( ServerKeyExchange )
3308 * ( CertificateRequest )
3309 * ServerHelloDone
3310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003311 case MBEDTLS_SSL_SERVER_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003312 ret = ssl_parse_server_hello( ssl );
3313 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003315 case MBEDTLS_SSL_SERVER_CERTIFICATE:
3316 ret = mbedtls_ssl_parse_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003317 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003319 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003320 ret = ssl_parse_server_key_exchange( ssl );
3321 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003323 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
Paul Bakker1961b702013-01-25 14:49:24 +01003324 ret = ssl_parse_certificate_request( ssl );
3325 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003327 case MBEDTLS_SSL_SERVER_HELLO_DONE:
Paul Bakker1961b702013-01-25 14:49:24 +01003328 ret = ssl_parse_server_hello_done( ssl );
3329 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003330
Paul Bakker1961b702013-01-25 14:49:24 +01003331 /*
3332 * ==> ( Certificate/Alert )
3333 * ClientKeyExchange
3334 * ( CertificateVerify )
3335 * ChangeCipherSpec
3336 * Finished
3337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003338 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3339 ret = mbedtls_ssl_write_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003340 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003342 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003343 ret = ssl_write_client_key_exchange( ssl );
3344 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003346 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
Paul Bakker1961b702013-01-25 14:49:24 +01003347 ret = ssl_write_certificate_verify( ssl );
3348 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003350 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3351 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003352 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003354 case MBEDTLS_SSL_CLIENT_FINISHED:
3355 ret = mbedtls_ssl_write_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003356 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003357
Paul Bakker1961b702013-01-25 14:49:24 +01003358 /*
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003359 * <== ( NewSessionTicket )
3360 * ChangeCipherSpec
Paul Bakker1961b702013-01-25 14:49:24 +01003361 * Finished
3362 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003363#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3364 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003365 ret = ssl_parse_new_session_ticket( ssl );
3366 break;
Paul Bakkera503a632013-08-14 13:48:06 +02003367#endif
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003369 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3370 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003371 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003373 case MBEDTLS_SSL_SERVER_FINISHED:
3374 ret = mbedtls_ssl_parse_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003375 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003377 case MBEDTLS_SSL_FLUSH_BUFFERS:
3378 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
3379 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Paul Bakker1961b702013-01-25 14:49:24 +01003380 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003382 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3383 mbedtls_ssl_handshake_wrapup( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003384 break;
Paul Bakker48916f92012-09-16 19:57:18 +00003385
Paul Bakker1961b702013-01-25 14:49:24 +01003386 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003387 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
3388 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1961b702013-01-25 14:49:24 +01003389 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003390
3391 return( ret );
3392}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003393#endif /* MBEDTLS_SSL_CLI_C */