blob: 9663fae4a5e4dbfec32416ac26feb26169ff9d67 [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 Bakkerc3f177a2012-04-11 16:11:49 +0000420
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 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001262
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 */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001778
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 Bakker48916f92012-09-16 19:57:18 +00001811 handshake_failure = 1;
1812 }
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 Bakker48916f92012-09-16 19:57:18 +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 Bakker48916f92012-09-16 19:57:18 +00001819 handshake_failure = 1;
1820 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001821 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1822 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001823 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
Paul Bakker48916f92012-09-16 19:57:18 +00001824 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001826 handshake_failure = 1;
1827 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1829 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001830 renegotiation_info_seen == 1 )
1831 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001833 handshake_failure = 1;
1834 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001836
1837 if( handshake_failure == 1 )
1838 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00001840 return( ret );
1841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker48916f92012-09-16 19:57:18 +00001843 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 return( 0 );
1848}
1849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
1851 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1852static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
Paul Bakker29e1f122013-04-16 13:07:56 +02001853 unsigned char *end )
1854{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001856
Paul Bakker29e1f122013-04-16 13:07:56 +02001857 /*
1858 * Ephemeral DH parameters:
1859 *
1860 * struct {
1861 * opaque dh_p<1..2^16-1>;
1862 * opaque dh_g<1..2^16-1>;
1863 * opaque dh_Ys<1..2^16-1>;
1864 * } ServerDHParams;
1865 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001867 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001869 return( ret );
1870 }
1871
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001872 if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
Paul Bakker29e1f122013-04-16 13:07:56 +02001873 {
Manuel Pégourié-Gonnardbd990d62015-06-11 14:49:42 +02001874 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
1875 ssl->handshake->dhm_ctx.len * 8,
1876 ssl->conf->dhm_min_bitlen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001878 }
1879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
1881 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
1882 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
Paul Bakker29e1f122013-04-16 13:07:56 +02001883
1884 return( ret );
1885}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1887 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001889#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1890 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1891 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
1892 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1893 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1894static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001896 const mbedtls_ecp_curve_info *curve_info;
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001897
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001899 if( curve_info == NULL )
1900 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1902 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardc3f6b62c2014-02-06 10:13:09 +01001903 }
1904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001906
Manuel Pégourié-Gonnardb541da62015-06-17 11:43:30 +02001907#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard9d412d82015-06-17 12:10:46 +02001908 if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001909#else
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001910 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
1911 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01001912#endif
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001913 return( -1 );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001915 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001916
1917 return( 0 );
1918}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1920 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1921 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
1922 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
1923 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001925#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
1926 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
1927 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
1928static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02001929 unsigned char **p,
1930 unsigned char *end )
1931{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakker29e1f122013-04-16 13:07:56 +02001933
Paul Bakker29e1f122013-04-16 13:07:56 +02001934 /*
1935 * Ephemeral ECDH parameters:
1936 *
1937 * struct {
1938 * ECParameters curve_params;
1939 * ECPoint public;
1940 * } ServerECDHParams;
1941 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001942 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
Paul Bakker29e1f122013-04-16 13:07:56 +02001943 (const unsigned char **) p, end ) ) != 0 )
1944 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02001946 return( ret );
1947 }
1948
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01001949 if( ssl_check_server_ecdh_params( ssl ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02001950 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
1952 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02001953 }
1954
Paul Bakker29e1f122013-04-16 13:07:56 +02001955 return( ret );
1956}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
1958 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1959 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02001960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001961#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1962static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001963 unsigned char **p,
1964 unsigned char *end )
1965{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001966 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001967 size_t len;
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02001968 ((void) ssl);
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001969
1970 /*
1971 * PSK parameters:
1972 *
1973 * opaque psk_identity_hint<0..2^16-1>;
1974 */
Manuel Pégourié-Gonnard59b9fe22013-10-15 11:55:33 +02001975 len = (*p)[0] << 8 | (*p)[1];
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001976 *p += 2;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001977
1978 if( (*p) + len > end )
1979 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
1981 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001982 }
1983
1984 // TODO: Retrieve PSK identity hint and callback to app
1985 //
1986 *p += len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02001987 ret = 0;
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001988
1989 return( ret );
1990}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02001992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
1994 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001995/*
1996 * Generate a pre-master secret and encrypt it with the server's RSA key
1997 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02001999 size_t offset, size_t *olen,
2000 size_t pms_offset )
2001{
2002 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002004 unsigned char *p = ssl->handshake->premaster + pms_offset;
2005
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002006 if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN )
2007 {
2008 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
2009 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2010 }
2011
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002012 /*
2013 * Generate (part of) the pre-master as
2014 * struct {
2015 * ProtocolVersion client_version;
2016 * opaque random[46];
2017 * } PreMasterSecret;
2018 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002019 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
2020 ssl->conf->transport, p );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002021
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002022 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002023 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002024 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002025 return( ret );
2026 }
2027
2028 ssl->handshake->pmslen = 48;
2029
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002030 if( ssl->session_negotiate->peer_cert == NULL )
2031 {
2032 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2033 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2034 }
2035
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002036 /*
2037 * Now write it out, encrypted
2038 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2040 MBEDTLS_PK_RSA ) )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002041 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
2043 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002044 }
2045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002046 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002047 p, ssl->handshake->pmslen,
2048 ssl->out_msg + offset + len_bytes, olen,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002050 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002051 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002053 return( ret );
2054 }
2055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2057 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002058 if( len_bytes == 2 )
2059 {
2060 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
2061 ssl->out_msg[offset+1] = (unsigned char)( *olen );
2062 *olen += 2;
2063 }
2064#endif
2065
2066 return( 0 );
2067}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
2069 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
Paul Bakker29e1f122013-04-16 13:07:56 +02002070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002071#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Manuel Pégourié-Gonnard5c2a7ca2015-10-23 08:48:41 +02002072#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2073 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2074 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002075static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
Paul Bakker29e1f122013-04-16 13:07:56 +02002076 unsigned char **p,
2077 unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002078 mbedtls_md_type_t *md_alg,
2079 mbedtls_pk_type_t *pk_alg )
Paul Bakker29e1f122013-04-16 13:07:56 +02002080{
Paul Bakkerc5a79cc2013-06-26 15:08:35 +02002081 ((void) ssl);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002082 *md_alg = MBEDTLS_MD_NONE;
2083 *pk_alg = MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002084
2085 /* Only in TLS 1.2 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002086 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002087 {
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002088 return( 0 );
2089 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002090
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002091 if( (*p) + 2 > end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002092 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002093
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002094 /*
2095 * Get hash algorithm
2096 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002098 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002100 "HashAlgorithm %d", *(p)[0] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002102 }
2103
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002104 /*
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002105 * Get signature algorithm
2106 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002109 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported "
Manuel Pégourié-Gonnarda20c58c2013-08-22 13:52:48 +02002110 "SignatureAlgorithm %d", (*p)[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002111 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker29e1f122013-04-16 13:07:56 +02002112 }
2113
Manuel Pégourié-Gonnard7bfc1222015-06-17 14:34:48 +02002114 /*
2115 * Check if the hash is acceptable
2116 */
2117 if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
2118 {
2119 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm "
2120 "that was not offered" ) );
2121 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2122 }
2123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002124 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
2125 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002126 *p += 2;
2127
2128 return( 0 );
2129}
Manuel Pégourié-Gonnard5c2a7ca2015-10-23 08:48:41 +02002130#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2131 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2132 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002133#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002134
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002135#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2136 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2137static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002138{
2139 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002140 const mbedtls_ecp_keypair *peer_key;
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002141
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002142 if( ssl->session_negotiate->peer_cert == NULL )
2143 {
2144 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2145 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2146 }
2147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002148 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
2149 MBEDTLS_PK_ECKEY ) )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002150 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
2152 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002153 }
2154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
2158 MBEDTLS_ECDH_THEIRS ) ) != 0 )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002159 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002160 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002161 return( ret );
2162 }
2163
2164 if( ssl_check_server_ecdh_params( ssl ) != 0 )
2165 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002166 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
2167 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002168 }
2169
2170 return( ret );
2171}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002172#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
2173 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker41c83d32013-03-20 14:39:14 +01002176{
Paul Bakker23986e52011-04-24 08:57:21 +00002177 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002179 unsigned char *p, *end;
Paul Bakker5121ce52009-01-03 21:22:43 +00002180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002183#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2184 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002185 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002186 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002187 ssl->state++;
2188 return( 0 );
2189 }
Manuel Pégourié-Gonnardbac0e3b2013-10-15 11:54:47 +02002190 ((void) p);
2191 ((void) end);
2192#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2195 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2196 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2197 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002198 {
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002199 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
2200 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002201 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Manuel Pégourié-Gonnardab240102014-02-04 16:18:07 +01002202 return( ret );
2203 }
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002205 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002206 ssl->state++;
2207 return( 0 );
2208 }
2209 ((void) p);
2210 ((void) end);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002211#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2212 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
Manuel Pégourié-Gonnardd18cc572013-12-11 17:45:46 +01002213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002214 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002215 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002216 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002217 return( ret );
2218 }
2219
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002221 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002222 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2223 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002224 }
2225
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002226 /*
2227 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
2228 * doesn't use a psk_identity_hint
2229 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002230 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002231 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002232 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2233 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Paul Bakker188c8de2013-04-19 09:13:37 +02002234 {
2235 ssl->record_read = 1;
2236 goto exit;
2237 }
2238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002239 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2240 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002241 }
2242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002243 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002244 end = ssl->in_msg + ssl->in_hslen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002245 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
Paul Bakker3b6a07b2013-03-21 11:56:50 +01002246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002247#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2248 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2249 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2250 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2251 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002252 {
2253 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
2254 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002255 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2256 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002257 }
2258 } /* FALLTROUGH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002261#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
2262 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2263 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2264 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard09258b92013-10-15 10:43:36 +02002265 ; /* nothing more to do */
2266 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002267#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
2268 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2269#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2270 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2271 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2272 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker5121ce52009-01-03 21:22:43 +00002273 {
Paul Bakker29e1f122013-04-16 13:07:56 +02002274 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002275 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002276 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2277 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002278 }
2279 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002280 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002281#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2282 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2283#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2284 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
2285 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2286 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2287 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2288 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002289 {
2290 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
2291 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002292 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2293 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002294 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002295 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002296 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002297#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2298 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2299 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002300#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2301 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2302 {
2303 ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
2304 p, end - p );
2305 if( ret != 0 )
2306 {
2307 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
2308 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
2309 }
2310 }
2311 else
2312#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
Paul Bakker41c83d32013-03-20 14:39:14 +01002313 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002314 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2315 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002316 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
2319 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2320 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2321 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2322 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2323 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002324 {
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002325 size_t sig_len, hashlen;
2326 unsigned char hash[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002327 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2328 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2329 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnardd92d6a12014-09-10 15:25:02 +00002330 size_t params_len = p - params;
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002331
Paul Bakker29e1f122013-04-16 13:07:56 +02002332 /*
2333 * Handle the digitally-signed structure
2334 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002335#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2336 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002337 {
Paul Bakker9659dae2013-08-28 16:21:34 +02002338 if( ssl_parse_signature_algorithm( ssl, &p, end,
2339 &md_alg, &pk_alg ) != 0 )
2340 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002341 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2342 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker9659dae2013-08-28 16:21:34 +02002343 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00002344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002345 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
Paul Bakker1ef83d62012-04-11 12:09:53 +00002346 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002347 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2348 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002349 }
2350 }
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002351 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002352#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2353#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2354 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2355 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
Manuel Pégourié-Gonnard09edda82013-08-19 13:50:33 +02002356 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002357 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
Paul Bakker1ef83d62012-04-11 12:09:53 +00002358
Paul Bakker9659dae2013-08-28 16:21:34 +02002359 /* Default hash for ECDSA is SHA-1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002360 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
2361 md_alg = MBEDTLS_MD_SHA1;
Paul Bakker9659dae2013-08-28 16:21:34 +02002362 }
2363 else
2364#endif
2365 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002366 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2367 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker9659dae2013-08-28 16:21:34 +02002368 }
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002369
2370 /*
2371 * Read signature
2372 */
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002373 sig_len = ( p[0] << 8 ) | p[1];
Paul Bakker1ef83d62012-04-11 12:09:53 +00002374 p += 2;
Paul Bakker1ef83d62012-04-11 12:09:53 +00002375
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002376 if( end != p + sig_len )
Paul Bakker41c83d32013-03-20 14:39:14 +01002377 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002378 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2379 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker41c83d32013-03-20 14:39:14 +01002380 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002382 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
Manuel Pégourié-Gonnardff56da32013-07-11 10:46:21 +02002383
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002384 /*
2385 * Compute the hash that has been signed
2386 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002387#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
2388 defined(MBEDTLS_SSL_PROTO_TLS1_1)
2389 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002390 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002391 mbedtls_md5_context mbedtls_md5;
2392 mbedtls_sha1_context mbedtls_sha1;
Paul Bakker29e1f122013-04-16 13:07:56 +02002393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002394 mbedtls_md5_init( &mbedtls_md5 );
2395 mbedtls_sha1_init( &mbedtls_sha1 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002396
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002397 hashlen = 36;
2398
Paul Bakker29e1f122013-04-16 13:07:56 +02002399 /*
2400 * digitally-signed struct {
2401 * opaque md5_hash[16];
2402 * opaque sha_hash[20];
2403 * };
2404 *
2405 * md5_hash
2406 * MD5(ClientHello.random + ServerHello.random
2407 * + ServerParams);
2408 * sha_hash
2409 * SHA(ClientHello.random + ServerHello.random
2410 * + ServerParams);
2411 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002412 mbedtls_md5_starts( &mbedtls_md5 );
2413 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
2414 mbedtls_md5_update( &mbedtls_md5, params, params_len );
2415 mbedtls_md5_finish( &mbedtls_md5, hash );
Paul Bakker29e1f122013-04-16 13:07:56 +02002416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002417 mbedtls_sha1_starts( &mbedtls_sha1 );
2418 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
2419 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
2420 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
Paul Bakker5b4af392014-06-26 12:09:34 +02002421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002422 mbedtls_md5_free( &mbedtls_md5 );
2423 mbedtls_sha1_free( &mbedtls_sha1 );
Paul Bakker29e1f122013-04-16 13:07:56 +02002424 }
2425 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002426#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
2427 MBEDTLS_SSL_PROTO_TLS1_1 */
2428#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
2429 defined(MBEDTLS_SSL_PROTO_TLS1_2)
2430 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker29e1f122013-04-16 13:07:56 +02002431 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002432 mbedtls_md_context_t ctx;
Paul Bakker29e1f122013-04-16 13:07:56 +02002433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002434 mbedtls_md_init( &ctx );
Paul Bakker84bbeb52014-07-01 14:53:22 +02002435
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02002436 /* Info from md_alg will be used instead */
2437 hashlen = 0;
Paul Bakker29e1f122013-04-16 13:07:56 +02002438
2439 /*
2440 * digitally-signed struct {
2441 * opaque client_random[32];
2442 * opaque server_random[32];
2443 * ServerDHParams params;
2444 * };
2445 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002446 if( ( ret = mbedtls_md_setup( &ctx,
2447 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
Paul Bakker29e1f122013-04-16 13:07:56 +02002448 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Paul Bakker29e1f122013-04-16 13:07:56 +02002450 return( ret );
2451 }
2452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002453 mbedtls_md_starts( &ctx );
2454 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
2455 mbedtls_md_update( &ctx, params, params_len );
2456 mbedtls_md_finish( &ctx, hash );
2457 mbedtls_md_free( &ctx );
Paul Bakker29e1f122013-04-16 13:07:56 +02002458 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002459 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002460#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
2461 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker29e1f122013-04-16 13:07:56 +02002462 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002463 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2464 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02002465 }
Paul Bakker29e1f122013-04-16 13:07:56 +02002466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
2468 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
Paul Bakker29e1f122013-04-16 13:07:56 +02002469
Manuel Pégourié-Gonnard7f2f0622015-09-03 10:44:32 +02002470 if( ssl->session_negotiate->peer_cert == NULL )
2471 {
2472 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
2473 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
2474 }
2475
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002476 /*
2477 * Verify signature
2478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002479 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002480 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002481 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
2482 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002483 }
2484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002485 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
Manuel Pégourié-Gonnard20846b12013-08-19 12:32:12 +02002486 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
Manuel Pégourié-Gonnardefebb0a2013-08-19 12:06:38 +02002487 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002488 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002489 return( ret );
Paul Bakkerc3f177a2012-04-11 16:11:49 +00002490 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002491 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002492#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2493 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2494 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002495
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002496exit:
Paul Bakker5121ce52009-01-03 21:22:43 +00002497 ssl->state++;
2498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002499 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002500
2501 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002502}
2503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002504#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2505 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2506 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2507 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2508static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002509{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002510 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002512 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002514 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2515 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2516 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002517 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2518 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002519 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002520 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002521 ssl->state++;
2522 return( 0 );
2523 }
2524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002525 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2526 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002527}
2528#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002529static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002530{
2531 int ret;
Paul Bakker926af752012-11-23 13:38:07 +01002532 unsigned char *buf, *p;
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002533 size_t n = 0, m = 0;
Paul Bakkerd2f068e2013-08-27 21:19:20 +02002534 size_t cert_type_len = 0, dn_len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002535 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002537 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002539 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2540 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2541 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002542 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2543 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002544 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002545 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
Manuel Pégourié-Gonnardda1ff382013-11-25 17:38:36 +01002546 ssl->state++;
2547 return( 0 );
2548 }
2549
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002550 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002551 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002552 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002553 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002554 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002555 return( ret );
2556 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002558 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002559 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002560 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2561 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002562 }
2563
2564 ssl->record_read = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002565 }
2566
2567 ssl->client_auth = 0;
2568 ssl->state++;
2569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002570 if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
Paul Bakker5121ce52009-01-03 21:22:43 +00002571 ssl->client_auth++;
2572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002573 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
Paul Bakker5121ce52009-01-03 21:22:43 +00002574 ssl->client_auth ? "a" : "no" ) );
2575
Paul Bakker926af752012-11-23 13:38:07 +01002576 if( ssl->client_auth == 0 )
2577 goto exit;
2578
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002579 ssl->record_read = 0;
2580
Paul Bakker926af752012-11-23 13:38:07 +01002581 // TODO: handshake_failure alert for an anonymous server to request
2582 // client authentication
2583
Manuel Pégourié-Gonnard04c1b4e2014-09-10 19:25:43 +02002584 /*
2585 * struct {
2586 * ClientCertificateType certificate_types<1..2^8-1>;
2587 * SignatureAndHashAlgorithm
2588 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2589 * DistinguishedName certificate_authorities<0..2^16-1>;
2590 * } CertificateRequest;
2591 */
Paul Bakker926af752012-11-23 13:38:07 +01002592 buf = ssl->in_msg;
Paul Bakkerf7abd422013-04-16 13:15:56 +02002593
Paul Bakker926af752012-11-23 13:38:07 +01002594 // Retrieve cert types
2595 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002596 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
Paul Bakker926af752012-11-23 13:38:07 +01002597 n = cert_type_len;
2598
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002599 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002600 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2602 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002603 }
2604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002605 p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
Paul Bakker926af752012-11-23 13:38:07 +01002606 while( cert_type_len > 0 )
2607 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002608#if defined(MBEDTLS_RSA_C)
2609 if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
2610 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
Paul Bakker926af752012-11-23 13:38:07 +01002611 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002612 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
Paul Bakker926af752012-11-23 13:38:07 +01002613 break;
2614 }
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002615 else
2616#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002617#if defined(MBEDTLS_ECDSA_C)
2618 if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
2619 mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002620 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002621 ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002622 break;
2623 }
2624 else
2625#endif
2626 {
2627 ; /* Unsupported cert type, ignore */
2628 }
Paul Bakker926af752012-11-23 13:38:07 +01002629
2630 cert_type_len--;
2631 p++;
2632 }
2633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002634#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2635 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01002636 {
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002637 /* Ignored, see comments about hash in write_certificate_verify */
2638 // TODO: should check the signature part against our pk_key though
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002639 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
2640 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002641
Paul Bakker9c94cdd2013-01-22 13:45:33 +01002642 m += 2;
Paul Bakker926af752012-11-23 13:38:07 +01002643 n += sig_alg_len;
2644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002645 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
Paul Bakker926af752012-11-23 13:38:07 +01002646 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002647 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2648 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002649 }
Paul Bakkerf7abd422013-04-16 13:15:56 +02002650 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002651#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker926af752012-11-23 13:38:07 +01002652
Manuel Pégourié-Gonnarda3104592013-09-17 21:17:44 +02002653 /* Ignore certificate_authorities, we only have one cert anyway */
2654 // TODO: should not send cert if no CA matches
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
2656 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
Paul Bakker926af752012-11-23 13:38:07 +01002657
2658 n += dn_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002659 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
Paul Bakker926af752012-11-23 13:38:07 +01002660 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002661 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
2662 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
Paul Bakker926af752012-11-23 13:38:07 +01002663 }
2664
2665exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002666 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002667
2668 return( 0 );
2669}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002670#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
2671 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
2672 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
2673 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00002674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002675static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002676{
2677 int ret;
2678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002679 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002680
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002681 if( ssl->record_read == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002682 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002683 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002684 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002685 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002686 return( ret );
2687 }
2688
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002689 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002690 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002691 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2692 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002693 }
2694 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002695 ssl->record_read = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002697 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
2698 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002700 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
2701 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002702 }
2703
2704 ssl->state++;
2705
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002706#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002707 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002708 mbedtls_ssl_recv_flight_completed( ssl );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002709#endif
2710
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002711 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002712
2713 return( 0 );
2714}
2715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002716static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002717{
Paul Bakker23986e52011-04-24 08:57:21 +00002718 int ret;
2719 size_t i, n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002720 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker5121ce52009-01-03 21:22:43 +00002721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002722 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002723
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002724#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2725 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002726 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002727 /*
2728 * DHM key exchange -- send G^X mod P
2729 */
Paul Bakker48916f92012-09-16 19:57:18 +00002730 n = ssl->handshake->dhm_ctx.len;
Paul Bakker5121ce52009-01-03 21:22:43 +00002731
2732 ssl->out_msg[4] = (unsigned char)( n >> 8 );
2733 ssl->out_msg[5] = (unsigned char)( n );
2734 i = 6;
2735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002736 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2737 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Paul Bakker5121ce52009-01-03 21:22:43 +00002738 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002739 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00002740 if( ret != 0 )
2741 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002742 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002743 return( ret );
2744 }
2745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002746 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
2747 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
Paul Bakker5121ce52009-01-03 21:22:43 +00002748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002749 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
Paul Bakker48916f92012-09-16 19:57:18 +00002750 ssl->handshake->premaster,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +01002751 MBEDTLS_PREMASTER_SIZE,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +02002752 &ssl->handshake->pmslen,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002753 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002754 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002755 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002756 return( ret );
2757 }
2758
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002759 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
Paul Bakker5121ce52009-01-03 21:22:43 +00002760 }
2761 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002762#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2763#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
2764 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
2765 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2766 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2767 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2768 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2769 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2770 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
Paul Bakker41c83d32013-03-20 14:39:14 +01002771 {
2772 /*
2773 * ECDH key exchange -- send client public value
2774 */
2775 i = 4;
2776
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002777 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002778 &n,
2779 &ssl->out_msg[i], 1000,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002780 ssl->conf->f_rng, ssl->conf->p_rng );
Paul Bakker41c83d32013-03-20 14:39:14 +01002781 if( ret != 0 )
2782 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002783 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002784 return( ret );
2785 }
2786
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002787 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Paul Bakker41c83d32013-03-20 14:39:14 +01002788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002789 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
Paul Bakker41c83d32013-03-20 14:39:14 +01002790 &ssl->handshake->pmslen,
2791 ssl->handshake->premaster,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002792 MBEDTLS_MPI_MAX_SIZE,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002793 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker41c83d32013-03-20 14:39:14 +01002794 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002795 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
Paul Bakker41c83d32013-03-20 14:39:14 +01002796 return( ret );
2797 }
2798
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002799 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
Paul Bakker41c83d32013-03-20 14:39:14 +01002800 }
2801 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002802#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2803 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2804 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2805 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2806#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
2807 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2808 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2809 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2810 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002811 {
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002812 /*
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002813 * opaque psk_identity<0..2^16-1>;
2814 */
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002815 if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002816 {
2817 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002818 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02002819 }
Paul Bakkerd4a56ec2013-04-16 18:05:29 +02002820
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002821 i = 4;
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002822 n = ssl->conf->psk_identity_len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002823
2824 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2825 {
2826 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
2827 "SSL buffer too short" ) );
2828 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2829 }
2830
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002831 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2832 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002833
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002834 memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
2835 i += ssl->conf->psk_identity_len;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002837#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
2838 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002839 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002840 n = 0;
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002841 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002842 else
2843#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002844#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2845 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002846 {
2847 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
2848 return( ret );
2849 }
2850 else
2851#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002852#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2853 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002854 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002855 /*
2856 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
2857 */
2858 n = ssl->handshake->dhm_ctx.len;
Manuel Pégourié-Gonnardc6b5d832015-08-27 16:37:35 +02002859
2860 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
2861 {
2862 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
2863 " or SSL buffer too short" ) );
2864 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
2865 }
2866
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002867 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
2868 ssl->out_msg[i++] = (unsigned char)( n );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002870 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
2871 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002872 &ssl->out_msg[i], n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002873 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002874 if( ret != 0 )
2875 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002876 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002877 return( ret );
2878 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002879 }
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002880 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002881#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2882#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2883 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002884 {
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002885 /*
2886 * ClientECDiffieHellmanPublic public;
2887 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002888 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
2889 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01002890 ssl->conf->f_rng, ssl->conf->p_rng );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002891 if( ret != 0 )
2892 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002893 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002894 return( ret );
2895 }
Manuel Pégourié-Gonnard3ce3bbd2013-10-11 16:53:50 +02002896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002897 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002898 }
2899 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002900#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
Manuel Pégourié-Gonnard72fb62d2013-10-14 14:01:58 +02002901 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002902 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2903 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002904 }
2905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002906 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
Manuel Pégourié-Gonnardbd1ae242013-10-14 13:09:25 +02002907 ciphersuite_info->key_exchange ) ) != 0 )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002908 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002909 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002910 return( ret );
2911 }
Paul Bakker48f7a5d2013-04-19 14:30:58 +02002912 }
2913 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002914#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
2915#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2916 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
Paul Bakker5121ce52009-01-03 21:22:43 +00002917 {
Manuel Pégourié-Gonnard0fae60b2013-10-14 17:39:48 +02002918 i = 4;
2919 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
Paul Bakkera3d195c2011-11-27 21:07:34 +00002920 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002921 }
Paul Bakkered27a042013-04-18 22:46:23 +02002922 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002923#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Manuel Pégourié-Gonnard0f1660a2015-09-16 22:41:06 +02002924#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2925 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
2926 {
2927 i = 4;
2928
2929 ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
2930 ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
2931 ssl->conf->f_rng, ssl->conf->p_rng );
2932 if( ret != 0 )
2933 {
2934 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
2935 return( ret );
2936 }
2937
2938 ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
2939 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
2940 ssl->conf->f_rng, ssl->conf->p_rng );
2941 if( ret != 0 )
2942 {
2943 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
2944 return( ret );
2945 }
2946 }
2947 else
2948#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
Paul Bakkered27a042013-04-18 22:46:23 +02002949 {
2950 ((void) ciphersuite_info);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2952 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkered27a042013-04-18 22:46:23 +02002953 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002954
Paul Bakker5121ce52009-01-03 21:22:43 +00002955 ssl->out_msglen = i + n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002956 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2957 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002958
2959 ssl->state++;
2960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002961 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002962 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002963 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002964 return( ret );
2965 }
2966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002967 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002968
2969 return( 0 );
2970}
2971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002972#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
2973 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
2974 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
2975 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2976static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002977{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002978 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002979 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002981 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002983 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002984 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002985 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02002986 return( ret );
2987 }
2988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002989 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2990 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2991 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02002992 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2993 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakkered27a042013-04-18 22:46:23 +02002994 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002995 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakkered27a042013-04-18 22:46:23 +02002996 ssl->state++;
2997 return( 0 );
2998 }
2999
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003000 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3001 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003002}
3003#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003004static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003005{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003006 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3007 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003008 size_t n = 0, offset = 0;
3009 unsigned char hash[48];
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003010 unsigned char *hash_start = hash;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003011 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003012 unsigned int hashlen;
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003014 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003016 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003017 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003018 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Manuel Pégourié-Gonnardada30302014-10-20 20:33:10 +02003019 return( ret );
3020 }
3021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003022 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
3023 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
3024 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
Manuel Pégourié-Gonnard25dbeb02015-09-16 17:30:03 +02003025 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
3026 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003027 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003028 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker48f7a5d2013-04-19 14:30:58 +02003029 ssl->state++;
3030 return( 0 );
3031 }
3032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003033 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003034 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003035 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003036 ssl->state++;
3037 return( 0 );
3038 }
3039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003040 if( mbedtls_ssl_own_key( ssl ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003041 {
Manuel Pégourié-Gonnardb4b19f32015-07-07 11:41:21 +02003042 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003043 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +00003044 }
3045
3046 /*
3047 * Make an RSA signature of the handshake digests
3048 */
Paul Bakker48916f92012-09-16 19:57:18 +00003049 ssl->handshake->calc_verify( ssl, hash );
Paul Bakker5121ce52009-01-03 21:22:43 +00003050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003051#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
3052 defined(MBEDTLS_SSL_PROTO_TLS1_1)
3053 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker1ef83d62012-04-11 12:09:53 +00003054 {
Paul Bakker926af752012-11-23 13:38:07 +01003055 /*
3056 * digitally-signed struct {
3057 * opaque md5_hash[16];
3058 * opaque sha_hash[20];
3059 * };
3060 *
3061 * md5_hash
3062 * MD5(handshake_messages);
3063 *
3064 * sha_hash
3065 * SHA(handshake_messages);
3066 */
3067 hashlen = 36;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003068 md_alg = MBEDTLS_MD_NONE;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003069
3070 /*
3071 * For ECDSA, default hash is SHA-1 only
3072 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003073 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003074 {
3075 hash_start += 16;
3076 hashlen -= 16;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003077 md_alg = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnard4bd12842013-08-27 13:31:28 +02003078 }
Paul Bakker926af752012-11-23 13:38:07 +01003079 }
3080 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003081#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
3082 MBEDTLS_SSL_PROTO_TLS1_1 */
3083#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3084 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
Paul Bakker926af752012-11-23 13:38:07 +01003085 {
3086 /*
3087 * digitally-signed struct {
3088 * opaque handshake_messages[handshake_messages_length];
3089 * };
3090 *
3091 * Taking shortcut here. We assume that the server always allows the
3092 * PRF Hash function and has sent it in the allowed signature
3093 * algorithms list received in the Certificate Request message.
3094 *
3095 * Until we encounter a server that does not, we will take this
3096 * shortcut.
3097 *
3098 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
3099 * in order to satisfy 'weird' needs from the server side.
3100 */
Paul Bakkerb7149bc2013-03-20 15:30:09 +01003101 if( ssl->transform_negotiate->ciphersuite_info->mac ==
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003102 MBEDTLS_MD_SHA384 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00003103 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003104 md_alg = MBEDTLS_MD_SHA384;
3105 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003106 }
3107 else
3108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003109 md_alg = MBEDTLS_MD_SHA256;
3110 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
Paul Bakkerca4ab492012-04-18 14:23:57 +00003111 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003112 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
Paul Bakker1ef83d62012-04-11 12:09:53 +00003113
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +02003114 /* Info from md_alg will be used instead */
3115 hashlen = 0;
Paul Bakker1ef83d62012-04-11 12:09:53 +00003116 offset = 2;
3117 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02003118 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003119#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02003120 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003121 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
3122 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02003123 }
Paul Bakker1ef83d62012-04-11 12:09:53 +00003124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003125 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003126 ssl->out_msg + 6 + offset, &n,
Manuel Pégourié-Gonnard750e4d72015-05-07 12:35:38 +01003127 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003128 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003129 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
Manuel Pégourié-Gonnard0d420492013-08-21 16:14:26 +02003130 return( ret );
Manuel Pégourié-Gonnard76c18a12013-08-20 16:50:40 +02003131 }
Paul Bakker926af752012-11-23 13:38:07 +01003132
Paul Bakker1ef83d62012-04-11 12:09:53 +00003133 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
3134 ssl->out_msg[5 + offset] = (unsigned char)( n );
Paul Bakker5121ce52009-01-03 21:22:43 +00003135
Paul Bakker1ef83d62012-04-11 12:09:53 +00003136 ssl->out_msglen = 6 + n + offset;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003137 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3138 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00003139
3140 ssl->state++;
3141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003142 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003143 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003144 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003145 return( ret );
3146 }
3147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003148 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003149
Paul Bakkered27a042013-04-18 22:46:23 +02003150 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003151}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003152#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
3153 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
3154 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
Paul Bakker5121ce52009-01-03 21:22:43 +00003155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003156#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3157static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003158{
3159 int ret;
3160 uint32_t lifetime;
3161 size_t ticket_len;
3162 unsigned char *ticket;
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003163 const unsigned char *msg;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003165 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003167 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003168 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003169 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003170 return( ret );
3171 }
3172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003173 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003174 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003175 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3176 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003177 }
3178
3179 /*
3180 * struct {
3181 * uint32 ticket_lifetime_hint;
3182 * opaque ticket<0..2^16-1>;
3183 * } NewSessionTicket;
3184 *
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003185 * 0 . 3 ticket_lifetime_hint
3186 * 4 . 5 ticket_len (n)
3187 * 6 . 5+n ticket content
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003188 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003189 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
3190 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003191 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003192 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3193 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003194 }
3195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003196 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003197
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003198 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
3199 ( msg[2] << 8 ) | ( msg[3] );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003200
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003201 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
3202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003203 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003204 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003205 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
3206 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003207 }
3208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003209 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003210
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003211 /* We're not waiting for a NewSessionTicket message any more */
3212 ssl->handshake->new_session_ticket = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003213 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
Manuel Pégourié-Gonnard7cd59242013-08-02 13:24:41 +02003214
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003215 /*
3216 * Zero-length ticket means the server changed his mind and doesn't want
3217 * to send a ticket after all, so just forget it
3218 */
Paul Bakker66d5d072014-06-17 16:39:18 +02003219 if( ticket_len == 0 )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003220 return( 0 );
3221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003222 mbedtls_zeroize( ssl->session_negotiate->ticket,
Paul Bakker34617722014-06-13 17:20:13 +02003223 ssl->session_negotiate->ticket_len );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003224 mbedtls_free( ssl->session_negotiate->ticket );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003225 ssl->session_negotiate->ticket = NULL;
3226 ssl->session_negotiate->ticket_len = 0;
3227
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02003228 if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003229 {
Manuel Pégourié-Gonnardb2a18a22015-05-27 16:29:56 +02003230 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02003231 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003232 }
3233
Manuel Pégourié-Gonnard000d5ae2014-09-10 21:52:12 +02003234 memcpy( ticket, msg + 6, ticket_len );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003235
3236 ssl->session_negotiate->ticket = ticket;
3237 ssl->session_negotiate->ticket_len = ticket_len;
3238 ssl->session_negotiate->ticket_lifetime = lifetime;
3239
3240 /*
3241 * RFC 5077 section 3.4:
3242 * "If the client receives a session ticket from the server, then it
3243 * discards any Session ID that was sent in the ServerHello."
3244 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003245 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
Manuel Pégourié-Gonnard12ad7982015-06-18 15:50:37 +02003246 ssl->session_negotiate->id_len = 0;
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003248 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003249
3250 return( 0 );
3251}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003252#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003253
Paul Bakker5121ce52009-01-03 21:22:43 +00003254/*
Paul Bakker1961b702013-01-25 14:49:24 +01003255 * SSL handshake -- client side -- single step
Paul Bakker5121ce52009-01-03 21:22:43 +00003256 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003257int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00003258{
3259 int ret = 0;
3260
Manuel Pégourié-Gonnarddba460f2015-06-24 22:59:30 +02003261 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003262 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00003263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003264 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
Paul Bakker1961b702013-01-25 14:49:24 +01003265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003266 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker1961b702013-01-25 14:49:24 +01003267 return( ret );
3268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003269#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003270 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003271 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003272 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003273 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02003274 return( ret );
3275 }
3276#endif
3277
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003278 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003279 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003280#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3281 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003282 ssl->handshake->new_session_ticket != 0 )
3283 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003284 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003285 }
3286#endif
3287
Paul Bakker1961b702013-01-25 14:49:24 +01003288 switch( ssl->state )
Paul Bakker5121ce52009-01-03 21:22:43 +00003289 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003290 case MBEDTLS_SSL_HELLO_REQUEST:
3291 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
Paul Bakker5121ce52009-01-03 21:22:43 +00003292 break;
3293
Paul Bakker1961b702013-01-25 14:49:24 +01003294 /*
3295 * ==> ClientHello
3296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003297 case MBEDTLS_SSL_CLIENT_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003298 ret = ssl_write_client_hello( ssl );
3299 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003300
Paul Bakker1961b702013-01-25 14:49:24 +01003301 /*
3302 * <== ServerHello
3303 * Certificate
3304 * ( ServerKeyExchange )
3305 * ( CertificateRequest )
3306 * ServerHelloDone
3307 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003308 case MBEDTLS_SSL_SERVER_HELLO:
Paul Bakker1961b702013-01-25 14:49:24 +01003309 ret = ssl_parse_server_hello( ssl );
3310 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003312 case MBEDTLS_SSL_SERVER_CERTIFICATE:
3313 ret = mbedtls_ssl_parse_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003314 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003316 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003317 ret = ssl_parse_server_key_exchange( ssl );
3318 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003320 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
Paul Bakker1961b702013-01-25 14:49:24 +01003321 ret = ssl_parse_certificate_request( ssl );
3322 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003324 case MBEDTLS_SSL_SERVER_HELLO_DONE:
Paul Bakker1961b702013-01-25 14:49:24 +01003325 ret = ssl_parse_server_hello_done( ssl );
3326 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003327
Paul Bakker1961b702013-01-25 14:49:24 +01003328 /*
3329 * ==> ( Certificate/Alert )
3330 * ClientKeyExchange
3331 * ( CertificateVerify )
3332 * ChangeCipherSpec
3333 * Finished
3334 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003335 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3336 ret = mbedtls_ssl_write_certificate( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003337 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003339 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
Paul Bakker1961b702013-01-25 14:49:24 +01003340 ret = ssl_write_client_key_exchange( ssl );
3341 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003343 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
Paul Bakker1961b702013-01-25 14:49:24 +01003344 ret = ssl_write_certificate_verify( ssl );
3345 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003347 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3348 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003349 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003351 case MBEDTLS_SSL_CLIENT_FINISHED:
3352 ret = mbedtls_ssl_write_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003353 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003354
Paul Bakker1961b702013-01-25 14:49:24 +01003355 /*
Manuel Pégourié-Gonnarda5cc6022013-07-31 12:58:16 +02003356 * <== ( NewSessionTicket )
3357 * ChangeCipherSpec
Paul Bakker1961b702013-01-25 14:49:24 +01003358 * Finished
3359 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003360#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3361 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003362 ret = ssl_parse_new_session_ticket( ssl );
3363 break;
Paul Bakkera503a632013-08-14 13:48:06 +02003364#endif
Manuel Pégourié-Gonnardcd32a502014-09-20 13:54:12 +02003365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003366 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3367 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003368 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003370 case MBEDTLS_SSL_SERVER_FINISHED:
3371 ret = mbedtls_ssl_parse_finished( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003372 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003374 case MBEDTLS_SSL_FLUSH_BUFFERS:
3375 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
3376 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
Paul Bakker1961b702013-01-25 14:49:24 +01003377 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00003378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003379 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3380 mbedtls_ssl_handshake_wrapup( ssl );
Paul Bakker1961b702013-01-25 14:49:24 +01003381 break;
Paul Bakker48916f92012-09-16 19:57:18 +00003382
Paul Bakker1961b702013-01-25 14:49:24 +01003383 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003384 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
3385 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1961b702013-01-25 14:49:24 +01003386 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003387
3388 return( ret );
3389}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003390#endif /* MBEDTLS_SSL_CLI_C */