mbed TLS upgraded to 2.6.0

Fork of mbedtls by Mark Radbourne

Committer:
Jasper Wallace
Date:
Fri Sep 29 19:50:30 2017 +0100
Revision:
2:bbdeda018a3c
Parent:
0:cdf462088d13
Update to mbedtls 2.6.0, many changes.

Changes to mbedtls sources made:

in include/mbedtls/config.h comment out:

#define MBEDTLS_FS_IO
#define MBEDTLS_NET_C
#define MBEDTLS_TIMING_C

uncomment:

#define MBEDTLS_NO_PLATFORM_ENTROPY

remove the following directorys:

programs
yotta
visualc

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 0:cdf462088d13 1 /*
markrad 0:cdf462088d13 2 * SSLv3/TLSv1 client-side functions
markrad 0:cdf462088d13 3 *
markrad 0:cdf462088d13 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
markrad 0:cdf462088d13 5 * SPDX-License-Identifier: Apache-2.0
markrad 0:cdf462088d13 6 *
markrad 0:cdf462088d13 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
markrad 0:cdf462088d13 8 * not use this file except in compliance with the License.
markrad 0:cdf462088d13 9 * You may obtain a copy of the License at
markrad 0:cdf462088d13 10 *
markrad 0:cdf462088d13 11 * http://www.apache.org/licenses/LICENSE-2.0
markrad 0:cdf462088d13 12 *
markrad 0:cdf462088d13 13 * Unless required by applicable law or agreed to in writing, software
markrad 0:cdf462088d13 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
markrad 0:cdf462088d13 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
markrad 0:cdf462088d13 16 * See the License for the specific language governing permissions and
markrad 0:cdf462088d13 17 * limitations under the License.
markrad 0:cdf462088d13 18 *
markrad 0:cdf462088d13 19 * This file is part of mbed TLS (https://tls.mbed.org)
markrad 0:cdf462088d13 20 */
markrad 0:cdf462088d13 21
markrad 0:cdf462088d13 22 #if !defined(MBEDTLS_CONFIG_FILE)
markrad 0:cdf462088d13 23 #include "mbedtls/config.h"
markrad 0:cdf462088d13 24 #else
markrad 0:cdf462088d13 25 #include MBEDTLS_CONFIG_FILE
markrad 0:cdf462088d13 26 #endif
markrad 0:cdf462088d13 27
markrad 0:cdf462088d13 28 #if defined(MBEDTLS_SSL_CLI_C)
markrad 0:cdf462088d13 29
markrad 0:cdf462088d13 30 #if defined(MBEDTLS_PLATFORM_C)
markrad 0:cdf462088d13 31 #include "mbedtls/platform.h"
markrad 0:cdf462088d13 32 #else
markrad 0:cdf462088d13 33 #include <stdlib.h>
markrad 0:cdf462088d13 34 #define mbedtls_calloc calloc
markrad 0:cdf462088d13 35 #define mbedtls_free free
markrad 0:cdf462088d13 36 #endif
markrad 0:cdf462088d13 37
markrad 0:cdf462088d13 38 #include "mbedtls/debug.h"
markrad 0:cdf462088d13 39 #include "mbedtls/ssl.h"
markrad 0:cdf462088d13 40 #include "mbedtls/ssl_internal.h"
markrad 0:cdf462088d13 41
markrad 0:cdf462088d13 42 #include <string.h>
markrad 0:cdf462088d13 43
markrad 0:cdf462088d13 44 #include <stdint.h>
markrad 0:cdf462088d13 45
markrad 0:cdf462088d13 46 #if defined(MBEDTLS_HAVE_TIME)
markrad 0:cdf462088d13 47 #include "mbedtls/platform_time.h"
markrad 0:cdf462088d13 48 #endif
markrad 0:cdf462088d13 49
markrad 0:cdf462088d13 50 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 51 /* Implementation that should never be optimized out by the compiler */
markrad 0:cdf462088d13 52 static void mbedtls_zeroize( void *v, size_t n ) {
markrad 0:cdf462088d13 53 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
markrad 0:cdf462088d13 54 }
markrad 0:cdf462088d13 55 #endif
markrad 0:cdf462088d13 56
markrad 0:cdf462088d13 57 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
markrad 0:cdf462088d13 58 static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 59 unsigned char *buf,
markrad 0:cdf462088d13 60 size_t *olen )
markrad 0:cdf462088d13 61 {
markrad 0:cdf462088d13 62 unsigned char *p = buf;
markrad 0:cdf462088d13 63 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 64 size_t hostname_len;
markrad 0:cdf462088d13 65
markrad 0:cdf462088d13 66 *olen = 0;
markrad 0:cdf462088d13 67
markrad 0:cdf462088d13 68 if( ssl->hostname == NULL )
markrad 0:cdf462088d13 69 return;
markrad 0:cdf462088d13 70
markrad 0:cdf462088d13 71 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
markrad 0:cdf462088d13 72 ssl->hostname ) );
markrad 0:cdf462088d13 73
markrad 0:cdf462088d13 74 hostname_len = strlen( ssl->hostname );
markrad 0:cdf462088d13 75
markrad 0:cdf462088d13 76 if( end < p || (size_t)( end - p ) < hostname_len + 9 )
markrad 0:cdf462088d13 77 {
markrad 0:cdf462088d13 78 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 79 return;
markrad 0:cdf462088d13 80 }
markrad 0:cdf462088d13 81
markrad 0:cdf462088d13 82 /*
markrad 0:cdf462088d13 83 * struct {
markrad 0:cdf462088d13 84 * NameType name_type;
markrad 0:cdf462088d13 85 * select (name_type) {
markrad 0:cdf462088d13 86 * case host_name: HostName;
markrad 0:cdf462088d13 87 * } name;
markrad 0:cdf462088d13 88 * } ServerName;
markrad 0:cdf462088d13 89 *
markrad 0:cdf462088d13 90 * enum {
markrad 0:cdf462088d13 91 * host_name(0), (255)
markrad 0:cdf462088d13 92 * } NameType;
markrad 0:cdf462088d13 93 *
markrad 0:cdf462088d13 94 * opaque HostName<1..2^16-1>;
markrad 0:cdf462088d13 95 *
markrad 0:cdf462088d13 96 * struct {
markrad 0:cdf462088d13 97 * ServerName server_name_list<1..2^16-1>
markrad 0:cdf462088d13 98 * } ServerNameList;
markrad 0:cdf462088d13 99 */
markrad 0:cdf462088d13 100 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
markrad 0:cdf462088d13 101 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
markrad 0:cdf462088d13 102
markrad 0:cdf462088d13 103 *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 104 *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
markrad 0:cdf462088d13 105
markrad 0:cdf462088d13 106 *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 107 *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
markrad 0:cdf462088d13 108
markrad 0:cdf462088d13 109 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
markrad 0:cdf462088d13 110 *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
markrad 0:cdf462088d13 111 *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
markrad 0:cdf462088d13 112
markrad 0:cdf462088d13 113 memcpy( p, ssl->hostname, hostname_len );
markrad 0:cdf462088d13 114
markrad 0:cdf462088d13 115 *olen = hostname_len + 9;
markrad 0:cdf462088d13 116 }
markrad 0:cdf462088d13 117 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
markrad 0:cdf462088d13 118
markrad 0:cdf462088d13 119 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 120 static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 121 unsigned char *buf,
markrad 0:cdf462088d13 122 size_t *olen )
markrad 0:cdf462088d13 123 {
markrad 0:cdf462088d13 124 unsigned char *p = buf;
markrad 0:cdf462088d13 125 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 126
markrad 0:cdf462088d13 127 *olen = 0;
markrad 0:cdf462088d13 128
markrad 0:cdf462088d13 129 if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
markrad 0:cdf462088d13 130 return;
markrad 0:cdf462088d13 131
markrad 0:cdf462088d13 132 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
markrad 0:cdf462088d13 133
markrad 0:cdf462088d13 134 if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
markrad 0:cdf462088d13 135 {
markrad 0:cdf462088d13 136 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 137 return;
markrad 0:cdf462088d13 138 }
markrad 0:cdf462088d13 139
markrad 0:cdf462088d13 140 /*
markrad 0:cdf462088d13 141 * Secure renegotiation
markrad 0:cdf462088d13 142 */
markrad 0:cdf462088d13 143 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
markrad 0:cdf462088d13 144 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
markrad 0:cdf462088d13 145
markrad 0:cdf462088d13 146 *p++ = 0x00;
markrad 0:cdf462088d13 147 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
markrad 0:cdf462088d13 148 *p++ = ssl->verify_data_len & 0xFF;
markrad 0:cdf462088d13 149
markrad 0:cdf462088d13 150 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
markrad 0:cdf462088d13 151
markrad 0:cdf462088d13 152 *olen = 5 + ssl->verify_data_len;
markrad 0:cdf462088d13 153 }
markrad 0:cdf462088d13 154 #endif /* MBEDTLS_SSL_RENEGOTIATION */
markrad 0:cdf462088d13 155
markrad 0:cdf462088d13 156 /*
markrad 0:cdf462088d13 157 * Only if we handle at least one key exchange that needs signatures.
markrad 0:cdf462088d13 158 */
markrad 0:cdf462088d13 159 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
markrad 0:cdf462088d13 160 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
markrad 0:cdf462088d13 161 static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 162 unsigned char *buf,
markrad 0:cdf462088d13 163 size_t *olen )
markrad 0:cdf462088d13 164 {
markrad 0:cdf462088d13 165 unsigned char *p = buf;
markrad 0:cdf462088d13 166 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 167 size_t sig_alg_len = 0;
markrad 0:cdf462088d13 168 const int *md;
markrad 0:cdf462088d13 169 #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
markrad 0:cdf462088d13 170 unsigned char *sig_alg_list = buf + 6;
markrad 0:cdf462088d13 171 #endif
markrad 0:cdf462088d13 172
markrad 0:cdf462088d13 173 *olen = 0;
markrad 0:cdf462088d13 174
markrad 0:cdf462088d13 175 if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 176 return;
markrad 0:cdf462088d13 177
markrad 0:cdf462088d13 178 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
markrad 0:cdf462088d13 179
markrad 0:cdf462088d13 180 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
markrad 0:cdf462088d13 181 {
markrad 0:cdf462088d13 182 #if defined(MBEDTLS_ECDSA_C)
markrad 0:cdf462088d13 183 sig_alg_len += 2;
markrad 0:cdf462088d13 184 #endif
markrad 0:cdf462088d13 185 #if defined(MBEDTLS_RSA_C)
markrad 0:cdf462088d13 186 sig_alg_len += 2;
markrad 0:cdf462088d13 187 #endif
markrad 0:cdf462088d13 188 }
markrad 0:cdf462088d13 189
markrad 0:cdf462088d13 190 if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
markrad 0:cdf462088d13 191 {
markrad 0:cdf462088d13 192 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 193 return;
markrad 0:cdf462088d13 194 }
markrad 0:cdf462088d13 195
markrad 0:cdf462088d13 196 /*
markrad 0:cdf462088d13 197 * Prepare signature_algorithms extension (TLS 1.2)
markrad 0:cdf462088d13 198 */
markrad 0:cdf462088d13 199 sig_alg_len = 0;
markrad 0:cdf462088d13 200
markrad 0:cdf462088d13 201 for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
markrad 0:cdf462088d13 202 {
markrad 0:cdf462088d13 203 #if defined(MBEDTLS_ECDSA_C)
markrad 0:cdf462088d13 204 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
markrad 0:cdf462088d13 205 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
markrad 0:cdf462088d13 206 #endif
markrad 0:cdf462088d13 207 #if defined(MBEDTLS_RSA_C)
markrad 0:cdf462088d13 208 sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
markrad 0:cdf462088d13 209 sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
markrad 0:cdf462088d13 210 #endif
markrad 0:cdf462088d13 211 }
markrad 0:cdf462088d13 212
markrad 0:cdf462088d13 213 /*
markrad 0:cdf462088d13 214 * enum {
markrad 0:cdf462088d13 215 * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
markrad 0:cdf462088d13 216 * sha512(6), (255)
markrad 0:cdf462088d13 217 * } HashAlgorithm;
markrad 0:cdf462088d13 218 *
markrad 0:cdf462088d13 219 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
markrad 0:cdf462088d13 220 * SignatureAlgorithm;
markrad 0:cdf462088d13 221 *
markrad 0:cdf462088d13 222 * struct {
markrad 0:cdf462088d13 223 * HashAlgorithm hash;
markrad 0:cdf462088d13 224 * SignatureAlgorithm signature;
markrad 0:cdf462088d13 225 * } SignatureAndHashAlgorithm;
markrad 0:cdf462088d13 226 *
markrad 0:cdf462088d13 227 * SignatureAndHashAlgorithm
markrad 0:cdf462088d13 228 * supported_signature_algorithms<2..2^16-2>;
markrad 0:cdf462088d13 229 */
markrad 0:cdf462088d13 230 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
markrad 0:cdf462088d13 231 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
markrad 0:cdf462088d13 232
markrad 0:cdf462088d13 233 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 234 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
markrad 0:cdf462088d13 235
markrad 0:cdf462088d13 236 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
markrad 0:cdf462088d13 237 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
markrad 0:cdf462088d13 238
markrad 0:cdf462088d13 239 *olen = 6 + sig_alg_len;
markrad 0:cdf462088d13 240 }
markrad 0:cdf462088d13 241 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
markrad 0:cdf462088d13 242 MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
markrad 0:cdf462088d13 243
markrad 0:cdf462088d13 244 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
markrad 0:cdf462088d13 245 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 246 static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 247 unsigned char *buf,
markrad 0:cdf462088d13 248 size_t *olen )
markrad 0:cdf462088d13 249 {
markrad 0:cdf462088d13 250 unsigned char *p = buf;
markrad 0:cdf462088d13 251 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 252 unsigned char *elliptic_curve_list = p + 6;
markrad 0:cdf462088d13 253 size_t elliptic_curve_len = 0;
markrad 0:cdf462088d13 254 const mbedtls_ecp_curve_info *info;
markrad 0:cdf462088d13 255 #if defined(MBEDTLS_ECP_C)
markrad 0:cdf462088d13 256 const mbedtls_ecp_group_id *grp_id;
markrad 0:cdf462088d13 257 #else
markrad 0:cdf462088d13 258 ((void) ssl);
markrad 0:cdf462088d13 259 #endif
markrad 0:cdf462088d13 260
markrad 0:cdf462088d13 261 *olen = 0;
markrad 0:cdf462088d13 262
markrad 0:cdf462088d13 263 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
markrad 0:cdf462088d13 264
markrad 0:cdf462088d13 265 #if defined(MBEDTLS_ECP_C)
markrad 0:cdf462088d13 266 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
markrad 0:cdf462088d13 267 #else
markrad 0:cdf462088d13 268 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Jasper Wallace 2:bbdeda018a3c 269 #endif
markrad 0:cdf462088d13 270 {
Jasper Wallace 2:bbdeda018a3c 271 #if defined(MBEDTLS_ECP_C)
Jasper Wallace 2:bbdeda018a3c 272 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
markrad 0:cdf462088d13 273 #endif
markrad 0:cdf462088d13 274 if( info == NULL )
markrad 0:cdf462088d13 275 {
markrad 0:cdf462088d13 276 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
markrad 0:cdf462088d13 277 return;
markrad 0:cdf462088d13 278 }
markrad 0:cdf462088d13 279
markrad 0:cdf462088d13 280 elliptic_curve_len += 2;
markrad 0:cdf462088d13 281 }
markrad 0:cdf462088d13 282
markrad 0:cdf462088d13 283 if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
markrad 0:cdf462088d13 284 {
markrad 0:cdf462088d13 285 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 286 return;
markrad 0:cdf462088d13 287 }
markrad 0:cdf462088d13 288
markrad 0:cdf462088d13 289 elliptic_curve_len = 0;
markrad 0:cdf462088d13 290
markrad 0:cdf462088d13 291 #if defined(MBEDTLS_ECP_C)
markrad 0:cdf462088d13 292 for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
markrad 0:cdf462088d13 293 #else
markrad 0:cdf462088d13 294 for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
Jasper Wallace 2:bbdeda018a3c 295 #endif
markrad 0:cdf462088d13 296 {
Jasper Wallace 2:bbdeda018a3c 297 #if defined(MBEDTLS_ECP_C)
Jasper Wallace 2:bbdeda018a3c 298 info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
markrad 0:cdf462088d13 299 #endif
markrad 0:cdf462088d13 300 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
markrad 0:cdf462088d13 301 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
markrad 0:cdf462088d13 302 }
markrad 0:cdf462088d13 303
markrad 0:cdf462088d13 304 if( elliptic_curve_len == 0 )
markrad 0:cdf462088d13 305 return;
markrad 0:cdf462088d13 306
markrad 0:cdf462088d13 307 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
markrad 0:cdf462088d13 308 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
markrad 0:cdf462088d13 309
markrad 0:cdf462088d13 310 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 311 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
markrad 0:cdf462088d13 312
markrad 0:cdf462088d13 313 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 314 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
markrad 0:cdf462088d13 315
markrad 0:cdf462088d13 316 *olen = 6 + elliptic_curve_len;
markrad 0:cdf462088d13 317 }
markrad 0:cdf462088d13 318
markrad 0:cdf462088d13 319 static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 320 unsigned char *buf,
markrad 0:cdf462088d13 321 size_t *olen )
markrad 0:cdf462088d13 322 {
markrad 0:cdf462088d13 323 unsigned char *p = buf;
markrad 0:cdf462088d13 324 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 325
markrad 0:cdf462088d13 326 *olen = 0;
markrad 0:cdf462088d13 327
markrad 0:cdf462088d13 328 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
markrad 0:cdf462088d13 329
markrad 0:cdf462088d13 330 if( end < p || (size_t)( end - p ) < 6 )
markrad 0:cdf462088d13 331 {
markrad 0:cdf462088d13 332 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 333 return;
markrad 0:cdf462088d13 334 }
markrad 0:cdf462088d13 335
markrad 0:cdf462088d13 336 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
markrad 0:cdf462088d13 337 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
markrad 0:cdf462088d13 338
markrad 0:cdf462088d13 339 *p++ = 0x00;
markrad 0:cdf462088d13 340 *p++ = 2;
markrad 0:cdf462088d13 341
markrad 0:cdf462088d13 342 *p++ = 1;
markrad 0:cdf462088d13 343 *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
markrad 0:cdf462088d13 344
markrad 0:cdf462088d13 345 *olen = 6;
markrad 0:cdf462088d13 346 }
markrad 0:cdf462088d13 347 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
markrad 0:cdf462088d13 348 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 349
markrad 0:cdf462088d13 350 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 351 static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 352 unsigned char *buf,
markrad 0:cdf462088d13 353 size_t *olen )
markrad 0:cdf462088d13 354 {
markrad 0:cdf462088d13 355 int ret;
markrad 0:cdf462088d13 356 unsigned char *p = buf;
markrad 0:cdf462088d13 357 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 358 size_t kkpp_len;
markrad 0:cdf462088d13 359
markrad 0:cdf462088d13 360 *olen = 0;
markrad 0:cdf462088d13 361
markrad 0:cdf462088d13 362 /* Skip costly extension if we can't use EC J-PAKE anyway */
markrad 0:cdf462088d13 363 if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
markrad 0:cdf462088d13 364 return;
markrad 0:cdf462088d13 365
markrad 0:cdf462088d13 366 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
markrad 0:cdf462088d13 367
markrad 0:cdf462088d13 368 if( end - p < 4 )
markrad 0:cdf462088d13 369 {
markrad 0:cdf462088d13 370 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 371 return;
markrad 0:cdf462088d13 372 }
markrad 0:cdf462088d13 373
markrad 0:cdf462088d13 374 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
markrad 0:cdf462088d13 375 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
markrad 0:cdf462088d13 376
markrad 0:cdf462088d13 377 /*
markrad 0:cdf462088d13 378 * We may need to send ClientHello multiple times for Hello verification.
markrad 0:cdf462088d13 379 * We don't want to compute fresh values every time (both for performance
markrad 0:cdf462088d13 380 * and consistency reasons), so cache the extension content.
markrad 0:cdf462088d13 381 */
markrad 0:cdf462088d13 382 if( ssl->handshake->ecjpake_cache == NULL ||
markrad 0:cdf462088d13 383 ssl->handshake->ecjpake_cache_len == 0 )
markrad 0:cdf462088d13 384 {
markrad 0:cdf462088d13 385 MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
markrad 0:cdf462088d13 386
markrad 0:cdf462088d13 387 ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
markrad 0:cdf462088d13 388 p + 2, end - p - 2, &kkpp_len,
markrad 0:cdf462088d13 389 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 390 if( ret != 0 )
markrad 0:cdf462088d13 391 {
markrad 0:cdf462088d13 392 MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
markrad 0:cdf462088d13 393 return;
markrad 0:cdf462088d13 394 }
markrad 0:cdf462088d13 395
markrad 0:cdf462088d13 396 ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
markrad 0:cdf462088d13 397 if( ssl->handshake->ecjpake_cache == NULL )
markrad 0:cdf462088d13 398 {
markrad 0:cdf462088d13 399 MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
markrad 0:cdf462088d13 400 return;
markrad 0:cdf462088d13 401 }
markrad 0:cdf462088d13 402
markrad 0:cdf462088d13 403 memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
markrad 0:cdf462088d13 404 ssl->handshake->ecjpake_cache_len = kkpp_len;
markrad 0:cdf462088d13 405 }
markrad 0:cdf462088d13 406 else
markrad 0:cdf462088d13 407 {
markrad 0:cdf462088d13 408 MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
markrad 0:cdf462088d13 409
markrad 0:cdf462088d13 410 kkpp_len = ssl->handshake->ecjpake_cache_len;
markrad 0:cdf462088d13 411
markrad 0:cdf462088d13 412 if( (size_t)( end - p - 2 ) < kkpp_len )
markrad 0:cdf462088d13 413 {
markrad 0:cdf462088d13 414 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 415 return;
markrad 0:cdf462088d13 416 }
markrad 0:cdf462088d13 417
markrad 0:cdf462088d13 418 memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
markrad 0:cdf462088d13 419 }
markrad 0:cdf462088d13 420
markrad 0:cdf462088d13 421 *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
markrad 0:cdf462088d13 422 *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
markrad 0:cdf462088d13 423
markrad 0:cdf462088d13 424 *olen = kkpp_len + 4;
markrad 0:cdf462088d13 425 }
markrad 0:cdf462088d13 426 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 427
markrad 0:cdf462088d13 428 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
markrad 0:cdf462088d13 429 static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 430 unsigned char *buf,
markrad 0:cdf462088d13 431 size_t *olen )
markrad 0:cdf462088d13 432 {
markrad 0:cdf462088d13 433 unsigned char *p = buf;
markrad 0:cdf462088d13 434 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 435
markrad 0:cdf462088d13 436 *olen = 0;
markrad 0:cdf462088d13 437
markrad 0:cdf462088d13 438 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
markrad 0:cdf462088d13 439 return;
markrad 0:cdf462088d13 440 }
markrad 0:cdf462088d13 441
markrad 0:cdf462088d13 442 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
markrad 0:cdf462088d13 443
markrad 0:cdf462088d13 444 if( end < p || (size_t)( end - p ) < 5 )
markrad 0:cdf462088d13 445 {
markrad 0:cdf462088d13 446 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 447 return;
markrad 0:cdf462088d13 448 }
markrad 0:cdf462088d13 449
markrad 0:cdf462088d13 450 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
markrad 0:cdf462088d13 451 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
markrad 0:cdf462088d13 452
markrad 0:cdf462088d13 453 *p++ = 0x00;
markrad 0:cdf462088d13 454 *p++ = 1;
markrad 0:cdf462088d13 455
markrad 0:cdf462088d13 456 *p++ = ssl->conf->mfl_code;
markrad 0:cdf462088d13 457
markrad 0:cdf462088d13 458 *olen = 5;
markrad 0:cdf462088d13 459 }
markrad 0:cdf462088d13 460 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
markrad 0:cdf462088d13 461
markrad 0:cdf462088d13 462 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
markrad 0:cdf462088d13 463 static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 464 unsigned char *buf, size_t *olen )
markrad 0:cdf462088d13 465 {
markrad 0:cdf462088d13 466 unsigned char *p = buf;
markrad 0:cdf462088d13 467 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 468
markrad 0:cdf462088d13 469 *olen = 0;
markrad 0:cdf462088d13 470
markrad 0:cdf462088d13 471 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
markrad 0:cdf462088d13 472 {
markrad 0:cdf462088d13 473 return;
markrad 0:cdf462088d13 474 }
markrad 0:cdf462088d13 475
markrad 0:cdf462088d13 476 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
markrad 0:cdf462088d13 477
markrad 0:cdf462088d13 478 if( end < p || (size_t)( end - p ) < 4 )
markrad 0:cdf462088d13 479 {
markrad 0:cdf462088d13 480 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 481 return;
markrad 0:cdf462088d13 482 }
markrad 0:cdf462088d13 483
markrad 0:cdf462088d13 484 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
markrad 0:cdf462088d13 485 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
markrad 0:cdf462088d13 486
markrad 0:cdf462088d13 487 *p++ = 0x00;
markrad 0:cdf462088d13 488 *p++ = 0x00;
markrad 0:cdf462088d13 489
markrad 0:cdf462088d13 490 *olen = 4;
markrad 0:cdf462088d13 491 }
markrad 0:cdf462088d13 492 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
markrad 0:cdf462088d13 493
markrad 0:cdf462088d13 494 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
markrad 0:cdf462088d13 495 static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 496 unsigned char *buf, size_t *olen )
markrad 0:cdf462088d13 497 {
markrad 0:cdf462088d13 498 unsigned char *p = buf;
markrad 0:cdf462088d13 499 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 500
markrad 0:cdf462088d13 501 *olen = 0;
markrad 0:cdf462088d13 502
markrad 0:cdf462088d13 503 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
markrad 0:cdf462088d13 504 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
markrad 0:cdf462088d13 505 {
markrad 0:cdf462088d13 506 return;
markrad 0:cdf462088d13 507 }
markrad 0:cdf462088d13 508
markrad 0:cdf462088d13 509 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
markrad 0:cdf462088d13 510 "extension" ) );
markrad 0:cdf462088d13 511
markrad 0:cdf462088d13 512 if( end < p || (size_t)( end - p ) < 4 )
markrad 0:cdf462088d13 513 {
markrad 0:cdf462088d13 514 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 515 return;
markrad 0:cdf462088d13 516 }
markrad 0:cdf462088d13 517
markrad 0:cdf462088d13 518 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
markrad 0:cdf462088d13 519 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
markrad 0:cdf462088d13 520
markrad 0:cdf462088d13 521 *p++ = 0x00;
markrad 0:cdf462088d13 522 *p++ = 0x00;
markrad 0:cdf462088d13 523
markrad 0:cdf462088d13 524 *olen = 4;
markrad 0:cdf462088d13 525 }
markrad 0:cdf462088d13 526 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
markrad 0:cdf462088d13 527
markrad 0:cdf462088d13 528 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
markrad 0:cdf462088d13 529 static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 530 unsigned char *buf, size_t *olen )
markrad 0:cdf462088d13 531 {
markrad 0:cdf462088d13 532 unsigned char *p = buf;
markrad 0:cdf462088d13 533 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 534
markrad 0:cdf462088d13 535 *olen = 0;
markrad 0:cdf462088d13 536
markrad 0:cdf462088d13 537 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
markrad 0:cdf462088d13 538 ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
markrad 0:cdf462088d13 539 {
markrad 0:cdf462088d13 540 return;
markrad 0:cdf462088d13 541 }
markrad 0:cdf462088d13 542
markrad 0:cdf462088d13 543 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
markrad 0:cdf462088d13 544 "extension" ) );
markrad 0:cdf462088d13 545
markrad 0:cdf462088d13 546 if( end < p || (size_t)( end - p ) < 4 )
markrad 0:cdf462088d13 547 {
markrad 0:cdf462088d13 548 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 549 return;
markrad 0:cdf462088d13 550 }
markrad 0:cdf462088d13 551
markrad 0:cdf462088d13 552 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
markrad 0:cdf462088d13 553 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
markrad 0:cdf462088d13 554
markrad 0:cdf462088d13 555 *p++ = 0x00;
markrad 0:cdf462088d13 556 *p++ = 0x00;
markrad 0:cdf462088d13 557
markrad 0:cdf462088d13 558 *olen = 4;
markrad 0:cdf462088d13 559 }
markrad 0:cdf462088d13 560 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
markrad 0:cdf462088d13 561
markrad 0:cdf462088d13 562 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 563 static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 564 unsigned char *buf, size_t *olen )
markrad 0:cdf462088d13 565 {
markrad 0:cdf462088d13 566 unsigned char *p = buf;
markrad 0:cdf462088d13 567 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 568 size_t tlen = ssl->session_negotiate->ticket_len;
markrad 0:cdf462088d13 569
markrad 0:cdf462088d13 570 *olen = 0;
markrad 0:cdf462088d13 571
markrad 0:cdf462088d13 572 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
markrad 0:cdf462088d13 573 {
markrad 0:cdf462088d13 574 return;
markrad 0:cdf462088d13 575 }
markrad 0:cdf462088d13 576
markrad 0:cdf462088d13 577 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
markrad 0:cdf462088d13 578
markrad 0:cdf462088d13 579 if( end < p || (size_t)( end - p ) < 4 + tlen )
markrad 0:cdf462088d13 580 {
markrad 0:cdf462088d13 581 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 582 return;
markrad 0:cdf462088d13 583 }
markrad 0:cdf462088d13 584
markrad 0:cdf462088d13 585 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
markrad 0:cdf462088d13 586 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
markrad 0:cdf462088d13 587
markrad 0:cdf462088d13 588 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
markrad 0:cdf462088d13 589 *p++ = (unsigned char)( ( tlen ) & 0xFF );
markrad 0:cdf462088d13 590
markrad 0:cdf462088d13 591 *olen = 4;
markrad 0:cdf462088d13 592
markrad 0:cdf462088d13 593 if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
markrad 0:cdf462088d13 594 {
markrad 0:cdf462088d13 595 return;
markrad 0:cdf462088d13 596 }
markrad 0:cdf462088d13 597
markrad 0:cdf462088d13 598 MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
markrad 0:cdf462088d13 599
markrad 0:cdf462088d13 600 memcpy( p, ssl->session_negotiate->ticket, tlen );
markrad 0:cdf462088d13 601
markrad 0:cdf462088d13 602 *olen += tlen;
markrad 0:cdf462088d13 603 }
markrad 0:cdf462088d13 604 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
markrad 0:cdf462088d13 605
markrad 0:cdf462088d13 606 #if defined(MBEDTLS_SSL_ALPN)
markrad 0:cdf462088d13 607 static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 608 unsigned char *buf, size_t *olen )
markrad 0:cdf462088d13 609 {
markrad 0:cdf462088d13 610 unsigned char *p = buf;
markrad 0:cdf462088d13 611 const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
markrad 0:cdf462088d13 612 size_t alpnlen = 0;
markrad 0:cdf462088d13 613 const char **cur;
markrad 0:cdf462088d13 614
markrad 0:cdf462088d13 615 *olen = 0;
markrad 0:cdf462088d13 616
markrad 0:cdf462088d13 617 if( ssl->conf->alpn_list == NULL )
markrad 0:cdf462088d13 618 {
markrad 0:cdf462088d13 619 return;
markrad 0:cdf462088d13 620 }
markrad 0:cdf462088d13 621
markrad 0:cdf462088d13 622 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
markrad 0:cdf462088d13 623
markrad 0:cdf462088d13 624 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
markrad 0:cdf462088d13 625 alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
markrad 0:cdf462088d13 626
markrad 0:cdf462088d13 627 if( end < p || (size_t)( end - p ) < 6 + alpnlen )
markrad 0:cdf462088d13 628 {
markrad 0:cdf462088d13 629 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
markrad 0:cdf462088d13 630 return;
markrad 0:cdf462088d13 631 }
markrad 0:cdf462088d13 632
markrad 0:cdf462088d13 633 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
markrad 0:cdf462088d13 634 *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
markrad 0:cdf462088d13 635
markrad 0:cdf462088d13 636 /*
markrad 0:cdf462088d13 637 * opaque ProtocolName<1..2^8-1>;
markrad 0:cdf462088d13 638 *
markrad 0:cdf462088d13 639 * struct {
markrad 0:cdf462088d13 640 * ProtocolName protocol_name_list<2..2^16-1>
markrad 0:cdf462088d13 641 * } ProtocolNameList;
markrad 0:cdf462088d13 642 */
markrad 0:cdf462088d13 643
markrad 0:cdf462088d13 644 /* Skip writing extension and list length for now */
markrad 0:cdf462088d13 645 p += 4;
markrad 0:cdf462088d13 646
markrad 0:cdf462088d13 647 for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
markrad 0:cdf462088d13 648 {
markrad 0:cdf462088d13 649 *p = (unsigned char)( strlen( *cur ) & 0xFF );
markrad 0:cdf462088d13 650 memcpy( p + 1, *cur, *p );
markrad 0:cdf462088d13 651 p += 1 + *p;
markrad 0:cdf462088d13 652 }
markrad 0:cdf462088d13 653
markrad 0:cdf462088d13 654 *olen = p - buf;
markrad 0:cdf462088d13 655
markrad 0:cdf462088d13 656 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
markrad 0:cdf462088d13 657 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 658 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
markrad 0:cdf462088d13 659
markrad 0:cdf462088d13 660 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
markrad 0:cdf462088d13 661 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
markrad 0:cdf462088d13 662 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
markrad 0:cdf462088d13 663 }
markrad 0:cdf462088d13 664 #endif /* MBEDTLS_SSL_ALPN */
markrad 0:cdf462088d13 665
markrad 0:cdf462088d13 666 /*
markrad 0:cdf462088d13 667 * Generate random bytes for ClientHello
markrad 0:cdf462088d13 668 */
markrad 0:cdf462088d13 669 static int ssl_generate_random( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 670 {
markrad 0:cdf462088d13 671 int ret;
markrad 0:cdf462088d13 672 unsigned char *p = ssl->handshake->randbytes;
markrad 0:cdf462088d13 673 #if defined(MBEDTLS_HAVE_TIME)
markrad 0:cdf462088d13 674 mbedtls_time_t t;
markrad 0:cdf462088d13 675 #endif
markrad 0:cdf462088d13 676
markrad 0:cdf462088d13 677 /*
markrad 0:cdf462088d13 678 * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
markrad 0:cdf462088d13 679 */
markrad 0:cdf462088d13 680 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 681 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
markrad 0:cdf462088d13 682 ssl->handshake->verify_cookie != NULL )
markrad 0:cdf462088d13 683 {
markrad 0:cdf462088d13 684 return( 0 );
markrad 0:cdf462088d13 685 }
markrad 0:cdf462088d13 686 #endif
markrad 0:cdf462088d13 687
markrad 0:cdf462088d13 688 #if defined(MBEDTLS_HAVE_TIME)
markrad 0:cdf462088d13 689 t = mbedtls_time( NULL );
markrad 0:cdf462088d13 690 *p++ = (unsigned char)( t >> 24 );
markrad 0:cdf462088d13 691 *p++ = (unsigned char)( t >> 16 );
markrad 0:cdf462088d13 692 *p++ = (unsigned char)( t >> 8 );
markrad 0:cdf462088d13 693 *p++ = (unsigned char)( t );
markrad 0:cdf462088d13 694
markrad 0:cdf462088d13 695 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
markrad 0:cdf462088d13 696 #else
markrad 0:cdf462088d13 697 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
markrad 0:cdf462088d13 698 return( ret );
markrad 0:cdf462088d13 699
markrad 0:cdf462088d13 700 p += 4;
markrad 0:cdf462088d13 701 #endif /* MBEDTLS_HAVE_TIME */
markrad 0:cdf462088d13 702
markrad 0:cdf462088d13 703 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
markrad 0:cdf462088d13 704 return( ret );
markrad 0:cdf462088d13 705
markrad 0:cdf462088d13 706 return( 0 );
markrad 0:cdf462088d13 707 }
markrad 0:cdf462088d13 708
markrad 0:cdf462088d13 709 static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 710 {
markrad 0:cdf462088d13 711 int ret;
markrad 0:cdf462088d13 712 size_t i, n, olen, ext_len = 0;
markrad 0:cdf462088d13 713 unsigned char *buf;
markrad 0:cdf462088d13 714 unsigned char *p, *q;
markrad 0:cdf462088d13 715 unsigned char offer_compress;
markrad 0:cdf462088d13 716 const int *ciphersuites;
markrad 0:cdf462088d13 717 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
markrad 0:cdf462088d13 718
markrad 0:cdf462088d13 719 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
markrad 0:cdf462088d13 720
markrad 0:cdf462088d13 721 if( ssl->conf->f_rng == NULL )
markrad 0:cdf462088d13 722 {
markrad 0:cdf462088d13 723 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
markrad 0:cdf462088d13 724 return( MBEDTLS_ERR_SSL_NO_RNG );
markrad 0:cdf462088d13 725 }
markrad 0:cdf462088d13 726
markrad 0:cdf462088d13 727 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 728 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
markrad 0:cdf462088d13 729 #endif
markrad 0:cdf462088d13 730 {
markrad 0:cdf462088d13 731 ssl->major_ver = ssl->conf->min_major_ver;
markrad 0:cdf462088d13 732 ssl->minor_ver = ssl->conf->min_minor_ver;
markrad 0:cdf462088d13 733 }
markrad 0:cdf462088d13 734
markrad 0:cdf462088d13 735 if( ssl->conf->max_major_ver == 0 )
markrad 0:cdf462088d13 736 {
markrad 0:cdf462088d13 737 MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
markrad 0:cdf462088d13 738 "consider using mbedtls_ssl_config_defaults()" ) );
markrad 0:cdf462088d13 739 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
markrad 0:cdf462088d13 740 }
markrad 0:cdf462088d13 741
markrad 0:cdf462088d13 742 /*
markrad 0:cdf462088d13 743 * 0 . 0 handshake type
markrad 0:cdf462088d13 744 * 1 . 3 handshake length
markrad 0:cdf462088d13 745 * 4 . 5 highest version supported
markrad 0:cdf462088d13 746 * 6 . 9 current UNIX time
markrad 0:cdf462088d13 747 * 10 . 37 random bytes
markrad 0:cdf462088d13 748 */
markrad 0:cdf462088d13 749 buf = ssl->out_msg;
markrad 0:cdf462088d13 750 p = buf + 4;
markrad 0:cdf462088d13 751
markrad 0:cdf462088d13 752 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
markrad 0:cdf462088d13 753 ssl->conf->transport, p );
markrad 0:cdf462088d13 754 p += 2;
markrad 0:cdf462088d13 755
markrad 0:cdf462088d13 756 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
markrad 0:cdf462088d13 757 buf[4], buf[5] ) );
markrad 0:cdf462088d13 758
markrad 0:cdf462088d13 759 if( ( ret = ssl_generate_random( ssl ) ) != 0 )
markrad 0:cdf462088d13 760 {
markrad 0:cdf462088d13 761 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
markrad 0:cdf462088d13 762 return( ret );
markrad 0:cdf462088d13 763 }
markrad 0:cdf462088d13 764
markrad 0:cdf462088d13 765 memcpy( p, ssl->handshake->randbytes, 32 );
markrad 0:cdf462088d13 766 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
markrad 0:cdf462088d13 767 p += 32;
markrad 0:cdf462088d13 768
markrad 0:cdf462088d13 769 /*
markrad 0:cdf462088d13 770 * 38 . 38 session id length
markrad 0:cdf462088d13 771 * 39 . 39+n session id
markrad 0:cdf462088d13 772 * 39+n . 39+n DTLS only: cookie length (1 byte)
markrad 0:cdf462088d13 773 * 40+n . .. DTSL only: cookie
markrad 0:cdf462088d13 774 * .. . .. ciphersuitelist length (2 bytes)
markrad 0:cdf462088d13 775 * .. . .. ciphersuitelist
markrad 0:cdf462088d13 776 * .. . .. compression methods length (1 byte)
markrad 0:cdf462088d13 777 * .. . .. compression methods
markrad 0:cdf462088d13 778 * .. . .. extensions length (2 bytes)
markrad 0:cdf462088d13 779 * .. . .. extensions
markrad 0:cdf462088d13 780 */
markrad 0:cdf462088d13 781 n = ssl->session_negotiate->id_len;
markrad 0:cdf462088d13 782
markrad 0:cdf462088d13 783 if( n < 16 || n > 32 ||
markrad 0:cdf462088d13 784 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 785 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
markrad 0:cdf462088d13 786 #endif
markrad 0:cdf462088d13 787 ssl->handshake->resume == 0 )
markrad 0:cdf462088d13 788 {
markrad 0:cdf462088d13 789 n = 0;
markrad 0:cdf462088d13 790 }
markrad 0:cdf462088d13 791
markrad 0:cdf462088d13 792 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 793 /*
markrad 0:cdf462088d13 794 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
markrad 0:cdf462088d13 795 * generate and include a Session ID in the TLS ClientHello."
markrad 0:cdf462088d13 796 */
markrad 0:cdf462088d13 797 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 798 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
markrad 0:cdf462088d13 799 #endif
markrad 0:cdf462088d13 800 {
markrad 0:cdf462088d13 801 if( ssl->session_negotiate->ticket != NULL &&
markrad 0:cdf462088d13 802 ssl->session_negotiate->ticket_len != 0 )
markrad 0:cdf462088d13 803 {
markrad 0:cdf462088d13 804 ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
markrad 0:cdf462088d13 805
markrad 0:cdf462088d13 806 if( ret != 0 )
markrad 0:cdf462088d13 807 return( ret );
markrad 0:cdf462088d13 808
markrad 0:cdf462088d13 809 ssl->session_negotiate->id_len = n = 32;
markrad 0:cdf462088d13 810 }
markrad 0:cdf462088d13 811 }
markrad 0:cdf462088d13 812 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
markrad 0:cdf462088d13 813
markrad 0:cdf462088d13 814 *p++ = (unsigned char) n;
markrad 0:cdf462088d13 815
markrad 0:cdf462088d13 816 for( i = 0; i < n; i++ )
markrad 0:cdf462088d13 817 *p++ = ssl->session_negotiate->id[i];
markrad 0:cdf462088d13 818
markrad 0:cdf462088d13 819 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
markrad 0:cdf462088d13 820 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
markrad 0:cdf462088d13 821
markrad 0:cdf462088d13 822 /*
markrad 0:cdf462088d13 823 * DTLS cookie
markrad 0:cdf462088d13 824 */
markrad 0:cdf462088d13 825 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 826 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 827 {
markrad 0:cdf462088d13 828 if( ssl->handshake->verify_cookie == NULL )
markrad 0:cdf462088d13 829 {
markrad 0:cdf462088d13 830 MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
markrad 0:cdf462088d13 831 *p++ = 0;
markrad 0:cdf462088d13 832 }
markrad 0:cdf462088d13 833 else
markrad 0:cdf462088d13 834 {
markrad 0:cdf462088d13 835 MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
markrad 0:cdf462088d13 836 ssl->handshake->verify_cookie,
markrad 0:cdf462088d13 837 ssl->handshake->verify_cookie_len );
markrad 0:cdf462088d13 838
markrad 0:cdf462088d13 839 *p++ = ssl->handshake->verify_cookie_len;
markrad 0:cdf462088d13 840 memcpy( p, ssl->handshake->verify_cookie,
markrad 0:cdf462088d13 841 ssl->handshake->verify_cookie_len );
markrad 0:cdf462088d13 842 p += ssl->handshake->verify_cookie_len;
markrad 0:cdf462088d13 843 }
markrad 0:cdf462088d13 844 }
markrad 0:cdf462088d13 845 #endif
markrad 0:cdf462088d13 846
markrad 0:cdf462088d13 847 /*
markrad 0:cdf462088d13 848 * Ciphersuite list
markrad 0:cdf462088d13 849 */
markrad 0:cdf462088d13 850 ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
markrad 0:cdf462088d13 851
markrad 0:cdf462088d13 852 /* Skip writing ciphersuite length for now */
markrad 0:cdf462088d13 853 n = 0;
markrad 0:cdf462088d13 854 q = p;
markrad 0:cdf462088d13 855 p += 2;
markrad 0:cdf462088d13 856
markrad 0:cdf462088d13 857 for( i = 0; ciphersuites[i] != 0; i++ )
markrad 0:cdf462088d13 858 {
markrad 0:cdf462088d13 859 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
markrad 0:cdf462088d13 860
markrad 0:cdf462088d13 861 if( ciphersuite_info == NULL )
markrad 0:cdf462088d13 862 continue;
markrad 0:cdf462088d13 863
markrad 0:cdf462088d13 864 if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
markrad 0:cdf462088d13 865 ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
markrad 0:cdf462088d13 866 continue;
markrad 0:cdf462088d13 867
markrad 0:cdf462088d13 868 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 869 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
markrad 0:cdf462088d13 870 ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
markrad 0:cdf462088d13 871 continue;
markrad 0:cdf462088d13 872 #endif
markrad 0:cdf462088d13 873
markrad 0:cdf462088d13 874 #if defined(MBEDTLS_ARC4_C)
markrad 0:cdf462088d13 875 if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
markrad 0:cdf462088d13 876 ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
markrad 0:cdf462088d13 877 continue;
markrad 0:cdf462088d13 878 #endif
markrad 0:cdf462088d13 879
markrad 0:cdf462088d13 880 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 881 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
markrad 0:cdf462088d13 882 mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
markrad 0:cdf462088d13 883 continue;
markrad 0:cdf462088d13 884 #endif
markrad 0:cdf462088d13 885
markrad 0:cdf462088d13 886 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
markrad 0:cdf462088d13 887 ciphersuites[i] ) );
markrad 0:cdf462088d13 888
markrad 0:cdf462088d13 889 n++;
markrad 0:cdf462088d13 890 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
markrad 0:cdf462088d13 891 *p++ = (unsigned char)( ciphersuites[i] );
markrad 0:cdf462088d13 892 }
markrad 0:cdf462088d13 893
markrad 0:cdf462088d13 894 /*
markrad 0:cdf462088d13 895 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
markrad 0:cdf462088d13 896 */
markrad 0:cdf462088d13 897 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 898 if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
markrad 0:cdf462088d13 899 #endif
markrad 0:cdf462088d13 900 {
markrad 0:cdf462088d13 901 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
markrad 0:cdf462088d13 902 *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
markrad 0:cdf462088d13 903 n++;
markrad 0:cdf462088d13 904 }
markrad 0:cdf462088d13 905
markrad 0:cdf462088d13 906 /* Some versions of OpenSSL don't handle it correctly if not at end */
markrad 0:cdf462088d13 907 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
markrad 0:cdf462088d13 908 if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
markrad 0:cdf462088d13 909 {
markrad 0:cdf462088d13 910 MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
markrad 0:cdf462088d13 911 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
markrad 0:cdf462088d13 912 *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
markrad 0:cdf462088d13 913 n++;
markrad 0:cdf462088d13 914 }
markrad 0:cdf462088d13 915 #endif
markrad 0:cdf462088d13 916
markrad 0:cdf462088d13 917 *q++ = (unsigned char)( n >> 7 );
markrad 0:cdf462088d13 918 *q++ = (unsigned char)( n << 1 );
markrad 0:cdf462088d13 919
markrad 0:cdf462088d13 920 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
markrad 0:cdf462088d13 921
markrad 0:cdf462088d13 922 #if defined(MBEDTLS_ZLIB_SUPPORT)
markrad 0:cdf462088d13 923 offer_compress = 1;
markrad 0:cdf462088d13 924 #else
markrad 0:cdf462088d13 925 offer_compress = 0;
markrad 0:cdf462088d13 926 #endif
markrad 0:cdf462088d13 927
markrad 0:cdf462088d13 928 /*
markrad 0:cdf462088d13 929 * We don't support compression with DTLS right now: is many records come
markrad 0:cdf462088d13 930 * in the same datagram, uncompressing one could overwrite the next one.
markrad 0:cdf462088d13 931 * We don't want to add complexity for handling that case unless there is
markrad 0:cdf462088d13 932 * an actual need for it.
markrad 0:cdf462088d13 933 */
markrad 0:cdf462088d13 934 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 935 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 936 offer_compress = 0;
markrad 0:cdf462088d13 937 #endif
markrad 0:cdf462088d13 938
markrad 0:cdf462088d13 939 if( offer_compress )
markrad 0:cdf462088d13 940 {
markrad 0:cdf462088d13 941 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
markrad 0:cdf462088d13 942 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
markrad 0:cdf462088d13 943 MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
markrad 0:cdf462088d13 944
markrad 0:cdf462088d13 945 *p++ = 2;
markrad 0:cdf462088d13 946 *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
markrad 0:cdf462088d13 947 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
markrad 0:cdf462088d13 948 }
markrad 0:cdf462088d13 949 else
markrad 0:cdf462088d13 950 {
markrad 0:cdf462088d13 951 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
markrad 0:cdf462088d13 952 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
markrad 0:cdf462088d13 953 MBEDTLS_SSL_COMPRESS_NULL ) );
markrad 0:cdf462088d13 954
markrad 0:cdf462088d13 955 *p++ = 1;
markrad 0:cdf462088d13 956 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
markrad 0:cdf462088d13 957 }
markrad 0:cdf462088d13 958
markrad 0:cdf462088d13 959 // First write extensions, then the total length
markrad 0:cdf462088d13 960 //
markrad 0:cdf462088d13 961 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
markrad 0:cdf462088d13 962 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 963 ext_len += olen;
markrad 0:cdf462088d13 964 #endif
markrad 0:cdf462088d13 965
markrad 0:cdf462088d13 966 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 967 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 968 ext_len += olen;
markrad 0:cdf462088d13 969 #endif
markrad 0:cdf462088d13 970
markrad 0:cdf462088d13 971 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
markrad 0:cdf462088d13 972 defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
markrad 0:cdf462088d13 973 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 974 ext_len += olen;
markrad 0:cdf462088d13 975 #endif
markrad 0:cdf462088d13 976
markrad 0:cdf462088d13 977 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
markrad 0:cdf462088d13 978 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 979 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 980 ext_len += olen;
markrad 0:cdf462088d13 981
markrad 0:cdf462088d13 982 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 983 ext_len += olen;
markrad 0:cdf462088d13 984 #endif
markrad 0:cdf462088d13 985
markrad 0:cdf462088d13 986 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 987 ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 988 ext_len += olen;
markrad 0:cdf462088d13 989 #endif
markrad 0:cdf462088d13 990
markrad 0:cdf462088d13 991 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
markrad 0:cdf462088d13 992 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 993 ext_len += olen;
markrad 0:cdf462088d13 994 #endif
markrad 0:cdf462088d13 995
markrad 0:cdf462088d13 996 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
markrad 0:cdf462088d13 997 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 998 ext_len += olen;
markrad 0:cdf462088d13 999 #endif
markrad 0:cdf462088d13 1000
markrad 0:cdf462088d13 1001 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
markrad 0:cdf462088d13 1002 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 1003 ext_len += olen;
markrad 0:cdf462088d13 1004 #endif
markrad 0:cdf462088d13 1005
markrad 0:cdf462088d13 1006 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
markrad 0:cdf462088d13 1007 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 1008 ext_len += olen;
markrad 0:cdf462088d13 1009 #endif
markrad 0:cdf462088d13 1010
markrad 0:cdf462088d13 1011 #if defined(MBEDTLS_SSL_ALPN)
markrad 0:cdf462088d13 1012 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 1013 ext_len += olen;
markrad 0:cdf462088d13 1014 #endif
markrad 0:cdf462088d13 1015
markrad 0:cdf462088d13 1016 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 1017 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
markrad 0:cdf462088d13 1018 ext_len += olen;
markrad 0:cdf462088d13 1019 #endif
markrad 0:cdf462088d13 1020
markrad 0:cdf462088d13 1021 /* olen unused if all extensions are disabled */
markrad 0:cdf462088d13 1022 ((void) olen);
markrad 0:cdf462088d13 1023
markrad 0:cdf462088d13 1024 MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
markrad 0:cdf462088d13 1025 ext_len ) );
markrad 0:cdf462088d13 1026
markrad 0:cdf462088d13 1027 if( ext_len > 0 )
markrad 0:cdf462088d13 1028 {
markrad 0:cdf462088d13 1029 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
markrad 0:cdf462088d13 1030 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
markrad 0:cdf462088d13 1031 p += ext_len;
markrad 0:cdf462088d13 1032 }
markrad 0:cdf462088d13 1033
markrad 0:cdf462088d13 1034 ssl->out_msglen = p - buf;
markrad 0:cdf462088d13 1035 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
markrad 0:cdf462088d13 1036 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
markrad 0:cdf462088d13 1037
markrad 0:cdf462088d13 1038 ssl->state++;
markrad 0:cdf462088d13 1039
markrad 0:cdf462088d13 1040 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 1041 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 1042 mbedtls_ssl_send_flight_completed( ssl );
markrad 0:cdf462088d13 1043 #endif
markrad 0:cdf462088d13 1044
markrad 0:cdf462088d13 1045 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 1046 {
markrad 0:cdf462088d13 1047 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
markrad 0:cdf462088d13 1048 return( ret );
markrad 0:cdf462088d13 1049 }
markrad 0:cdf462088d13 1050
markrad 0:cdf462088d13 1051 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
markrad 0:cdf462088d13 1052
markrad 0:cdf462088d13 1053 return( 0 );
markrad 0:cdf462088d13 1054 }
markrad 0:cdf462088d13 1055
markrad 0:cdf462088d13 1056 static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1057 const unsigned char *buf,
markrad 0:cdf462088d13 1058 size_t len )
markrad 0:cdf462088d13 1059 {
markrad 0:cdf462088d13 1060 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1061 if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
markrad 0:cdf462088d13 1062 {
markrad 0:cdf462088d13 1063 /* Check verify-data in constant-time. The length OTOH is no secret */
markrad 0:cdf462088d13 1064 if( len != 1 + ssl->verify_data_len * 2 ||
markrad 0:cdf462088d13 1065 buf[0] != ssl->verify_data_len * 2 ||
markrad 0:cdf462088d13 1066 mbedtls_ssl_safer_memcmp( buf + 1,
markrad 0:cdf462088d13 1067 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
markrad 0:cdf462088d13 1068 mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
markrad 0:cdf462088d13 1069 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
markrad 0:cdf462088d13 1070 {
markrad 0:cdf462088d13 1071 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
Jasper Wallace 2:bbdeda018a3c 1072 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1073 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1074 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1075 }
markrad 0:cdf462088d13 1076 }
markrad 0:cdf462088d13 1077 else
markrad 0:cdf462088d13 1078 #endif /* MBEDTLS_SSL_RENEGOTIATION */
markrad 0:cdf462088d13 1079 {
markrad 0:cdf462088d13 1080 if( len != 1 || buf[0] != 0x00 )
markrad 0:cdf462088d13 1081 {
markrad 0:cdf462088d13 1082 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
Jasper Wallace 2:bbdeda018a3c 1083 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1084 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1085 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1086 }
markrad 0:cdf462088d13 1087
markrad 0:cdf462088d13 1088 ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
markrad 0:cdf462088d13 1089 }
markrad 0:cdf462088d13 1090
markrad 0:cdf462088d13 1091 return( 0 );
markrad 0:cdf462088d13 1092 }
markrad 0:cdf462088d13 1093
markrad 0:cdf462088d13 1094 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
markrad 0:cdf462088d13 1095 static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1096 const unsigned char *buf,
markrad 0:cdf462088d13 1097 size_t len )
markrad 0:cdf462088d13 1098 {
markrad 0:cdf462088d13 1099 /*
markrad 0:cdf462088d13 1100 * server should use the extension only if we did,
markrad 0:cdf462088d13 1101 * and if so the server's value should match ours (and len is always 1)
markrad 0:cdf462088d13 1102 */
markrad 0:cdf462088d13 1103 if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
markrad 0:cdf462088d13 1104 len != 1 ||
markrad 0:cdf462088d13 1105 buf[0] != ssl->conf->mfl_code )
markrad 0:cdf462088d13 1106 {
Jasper Wallace 2:bbdeda018a3c 1107 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) );
Jasper Wallace 2:bbdeda018a3c 1108 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1109 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1110 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1111 }
markrad 0:cdf462088d13 1112
markrad 0:cdf462088d13 1113 return( 0 );
markrad 0:cdf462088d13 1114 }
markrad 0:cdf462088d13 1115 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
markrad 0:cdf462088d13 1116
markrad 0:cdf462088d13 1117 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
markrad 0:cdf462088d13 1118 static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1119 const unsigned char *buf,
markrad 0:cdf462088d13 1120 size_t len )
markrad 0:cdf462088d13 1121 {
markrad 0:cdf462088d13 1122 if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
markrad 0:cdf462088d13 1123 len != 0 )
markrad 0:cdf462088d13 1124 {
Jasper Wallace 2:bbdeda018a3c 1125 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) );
Jasper Wallace 2:bbdeda018a3c 1126 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1127 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1128 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1129 }
markrad 0:cdf462088d13 1130
markrad 0:cdf462088d13 1131 ((void) buf);
markrad 0:cdf462088d13 1132
markrad 0:cdf462088d13 1133 ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
markrad 0:cdf462088d13 1134
markrad 0:cdf462088d13 1135 return( 0 );
markrad 0:cdf462088d13 1136 }
markrad 0:cdf462088d13 1137 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
markrad 0:cdf462088d13 1138
markrad 0:cdf462088d13 1139 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
markrad 0:cdf462088d13 1140 static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1141 const unsigned char *buf,
markrad 0:cdf462088d13 1142 size_t len )
markrad 0:cdf462088d13 1143 {
markrad 0:cdf462088d13 1144 if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
markrad 0:cdf462088d13 1145 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
markrad 0:cdf462088d13 1146 len != 0 )
markrad 0:cdf462088d13 1147 {
Jasper Wallace 2:bbdeda018a3c 1148 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) );
Jasper Wallace 2:bbdeda018a3c 1149 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1150 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1151 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1152 }
markrad 0:cdf462088d13 1153
markrad 0:cdf462088d13 1154 ((void) buf);
markrad 0:cdf462088d13 1155
markrad 0:cdf462088d13 1156 ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
markrad 0:cdf462088d13 1157
markrad 0:cdf462088d13 1158 return( 0 );
markrad 0:cdf462088d13 1159 }
markrad 0:cdf462088d13 1160 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
markrad 0:cdf462088d13 1161
markrad 0:cdf462088d13 1162 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
markrad 0:cdf462088d13 1163 static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1164 const unsigned char *buf,
markrad 0:cdf462088d13 1165 size_t len )
markrad 0:cdf462088d13 1166 {
markrad 0:cdf462088d13 1167 if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
markrad 0:cdf462088d13 1168 ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
markrad 0:cdf462088d13 1169 len != 0 )
markrad 0:cdf462088d13 1170 {
Jasper Wallace 2:bbdeda018a3c 1171 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) );
Jasper Wallace 2:bbdeda018a3c 1172 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1173 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1174 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1175 }
markrad 0:cdf462088d13 1176
markrad 0:cdf462088d13 1177 ((void) buf);
markrad 0:cdf462088d13 1178
markrad 0:cdf462088d13 1179 ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
markrad 0:cdf462088d13 1180
markrad 0:cdf462088d13 1181 return( 0 );
markrad 0:cdf462088d13 1182 }
markrad 0:cdf462088d13 1183 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
markrad 0:cdf462088d13 1184
markrad 0:cdf462088d13 1185 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 1186 static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1187 const unsigned char *buf,
markrad 0:cdf462088d13 1188 size_t len )
markrad 0:cdf462088d13 1189 {
markrad 0:cdf462088d13 1190 if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
markrad 0:cdf462088d13 1191 len != 0 )
markrad 0:cdf462088d13 1192 {
Jasper Wallace 2:bbdeda018a3c 1193 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) );
Jasper Wallace 2:bbdeda018a3c 1194 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1195 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1196 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1197 }
markrad 0:cdf462088d13 1198
markrad 0:cdf462088d13 1199 ((void) buf);
markrad 0:cdf462088d13 1200
markrad 0:cdf462088d13 1201 ssl->handshake->new_session_ticket = 1;
markrad 0:cdf462088d13 1202
markrad 0:cdf462088d13 1203 return( 0 );
markrad 0:cdf462088d13 1204 }
markrad 0:cdf462088d13 1205 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
markrad 0:cdf462088d13 1206
markrad 0:cdf462088d13 1207 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
markrad 0:cdf462088d13 1208 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 1209 static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1210 const unsigned char *buf,
markrad 0:cdf462088d13 1211 size_t len )
markrad 0:cdf462088d13 1212 {
markrad 0:cdf462088d13 1213 size_t list_size;
markrad 0:cdf462088d13 1214 const unsigned char *p;
markrad 0:cdf462088d13 1215
markrad 0:cdf462088d13 1216 list_size = buf[0];
markrad 0:cdf462088d13 1217 if( list_size + 1 != len )
markrad 0:cdf462088d13 1218 {
markrad 0:cdf462088d13 1219 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1220 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1221 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1222 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1223 }
markrad 0:cdf462088d13 1224
markrad 0:cdf462088d13 1225 p = buf + 1;
markrad 0:cdf462088d13 1226 while( list_size > 0 )
markrad 0:cdf462088d13 1227 {
markrad 0:cdf462088d13 1228 if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
markrad 0:cdf462088d13 1229 p[0] == MBEDTLS_ECP_PF_COMPRESSED )
markrad 0:cdf462088d13 1230 {
markrad 0:cdf462088d13 1231 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
markrad 0:cdf462088d13 1232 ssl->handshake->ecdh_ctx.point_format = p[0];
Jasper Wallace 2:bbdeda018a3c 1233 #endif
markrad 0:cdf462088d13 1234 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 1235 ssl->handshake->ecjpake_ctx.point_format = p[0];
markrad 0:cdf462088d13 1236 #endif
markrad 0:cdf462088d13 1237 MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
markrad 0:cdf462088d13 1238 return( 0 );
markrad 0:cdf462088d13 1239 }
markrad 0:cdf462088d13 1240
markrad 0:cdf462088d13 1241 list_size--;
markrad 0:cdf462088d13 1242 p++;
markrad 0:cdf462088d13 1243 }
markrad 0:cdf462088d13 1244
markrad 0:cdf462088d13 1245 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
Jasper Wallace 2:bbdeda018a3c 1246 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1247 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1248 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1249 }
markrad 0:cdf462088d13 1250 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
markrad 0:cdf462088d13 1251 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 1252
markrad 0:cdf462088d13 1253 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 1254 static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1255 const unsigned char *buf,
markrad 0:cdf462088d13 1256 size_t len )
markrad 0:cdf462088d13 1257 {
markrad 0:cdf462088d13 1258 int ret;
markrad 0:cdf462088d13 1259
markrad 0:cdf462088d13 1260 if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
markrad 0:cdf462088d13 1261 MBEDTLS_KEY_EXCHANGE_ECJPAKE )
markrad 0:cdf462088d13 1262 {
markrad 0:cdf462088d13 1263 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
markrad 0:cdf462088d13 1264 return( 0 );
markrad 0:cdf462088d13 1265 }
markrad 0:cdf462088d13 1266
markrad 0:cdf462088d13 1267 /* If we got here, we no longer need our cached extension */
markrad 0:cdf462088d13 1268 mbedtls_free( ssl->handshake->ecjpake_cache );
markrad 0:cdf462088d13 1269 ssl->handshake->ecjpake_cache = NULL;
markrad 0:cdf462088d13 1270 ssl->handshake->ecjpake_cache_len = 0;
markrad 0:cdf462088d13 1271
markrad 0:cdf462088d13 1272 if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
markrad 0:cdf462088d13 1273 buf, len ) ) != 0 )
markrad 0:cdf462088d13 1274 {
markrad 0:cdf462088d13 1275 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
Jasper Wallace 2:bbdeda018a3c 1276 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1277 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1278 return( ret );
markrad 0:cdf462088d13 1279 }
markrad 0:cdf462088d13 1280
markrad 0:cdf462088d13 1281 return( 0 );
markrad 0:cdf462088d13 1282 }
markrad 0:cdf462088d13 1283 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 1284
markrad 0:cdf462088d13 1285 #if defined(MBEDTLS_SSL_ALPN)
markrad 0:cdf462088d13 1286 static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 1287 const unsigned char *buf, size_t len )
markrad 0:cdf462088d13 1288 {
markrad 0:cdf462088d13 1289 size_t list_len, name_len;
markrad 0:cdf462088d13 1290 const char **p;
markrad 0:cdf462088d13 1291
markrad 0:cdf462088d13 1292 /* If we didn't send it, the server shouldn't send it */
markrad 0:cdf462088d13 1293 if( ssl->conf->alpn_list == NULL )
Jasper Wallace 2:bbdeda018a3c 1294 {
Jasper Wallace 2:bbdeda018a3c 1295 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) );
Jasper Wallace 2:bbdeda018a3c 1296 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1297 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1298 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Jasper Wallace 2:bbdeda018a3c 1299 }
markrad 0:cdf462088d13 1300
markrad 0:cdf462088d13 1301 /*
markrad 0:cdf462088d13 1302 * opaque ProtocolName<1..2^8-1>;
markrad 0:cdf462088d13 1303 *
markrad 0:cdf462088d13 1304 * struct {
markrad 0:cdf462088d13 1305 * ProtocolName protocol_name_list<2..2^16-1>
markrad 0:cdf462088d13 1306 * } ProtocolNameList;
markrad 0:cdf462088d13 1307 *
markrad 0:cdf462088d13 1308 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
markrad 0:cdf462088d13 1309 */
markrad 0:cdf462088d13 1310
markrad 0:cdf462088d13 1311 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
markrad 0:cdf462088d13 1312 if( len < 4 )
Jasper Wallace 2:bbdeda018a3c 1313 {
Jasper Wallace 2:bbdeda018a3c 1314 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1315 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1316 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Jasper Wallace 2:bbdeda018a3c 1317 }
markrad 0:cdf462088d13 1318
markrad 0:cdf462088d13 1319 list_len = ( buf[0] << 8 ) | buf[1];
markrad 0:cdf462088d13 1320 if( list_len != len - 2 )
Jasper Wallace 2:bbdeda018a3c 1321 {
Jasper Wallace 2:bbdeda018a3c 1322 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1323 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1324 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Jasper Wallace 2:bbdeda018a3c 1325 }
markrad 0:cdf462088d13 1326
markrad 0:cdf462088d13 1327 name_len = buf[2];
markrad 0:cdf462088d13 1328 if( name_len != list_len - 1 )
Jasper Wallace 2:bbdeda018a3c 1329 {
Jasper Wallace 2:bbdeda018a3c 1330 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1331 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1332 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
Jasper Wallace 2:bbdeda018a3c 1333 }
markrad 0:cdf462088d13 1334
markrad 0:cdf462088d13 1335 /* Check that the server chosen protocol was in our list and save it */
markrad 0:cdf462088d13 1336 for( p = ssl->conf->alpn_list; *p != NULL; p++ )
markrad 0:cdf462088d13 1337 {
markrad 0:cdf462088d13 1338 if( name_len == strlen( *p ) &&
markrad 0:cdf462088d13 1339 memcmp( buf + 3, *p, name_len ) == 0 )
markrad 0:cdf462088d13 1340 {
markrad 0:cdf462088d13 1341 ssl->alpn_chosen = *p;
markrad 0:cdf462088d13 1342 return( 0 );
markrad 0:cdf462088d13 1343 }
markrad 0:cdf462088d13 1344 }
markrad 0:cdf462088d13 1345
Jasper Wallace 2:bbdeda018a3c 1346 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
Jasper Wallace 2:bbdeda018a3c 1347 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1348 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1349 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1350 }
markrad 0:cdf462088d13 1351 #endif /* MBEDTLS_SSL_ALPN */
markrad 0:cdf462088d13 1352
markrad 0:cdf462088d13 1353 /*
markrad 0:cdf462088d13 1354 * Parse HelloVerifyRequest. Only called after verifying the HS type.
markrad 0:cdf462088d13 1355 */
markrad 0:cdf462088d13 1356 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 1357 static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 1358 {
markrad 0:cdf462088d13 1359 const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
markrad 0:cdf462088d13 1360 int major_ver, minor_ver;
markrad 0:cdf462088d13 1361 unsigned char cookie_len;
markrad 0:cdf462088d13 1362
markrad 0:cdf462088d13 1363 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
markrad 0:cdf462088d13 1364
markrad 0:cdf462088d13 1365 /*
markrad 0:cdf462088d13 1366 * struct {
markrad 0:cdf462088d13 1367 * ProtocolVersion server_version;
markrad 0:cdf462088d13 1368 * opaque cookie<0..2^8-1>;
markrad 0:cdf462088d13 1369 * } HelloVerifyRequest;
markrad 0:cdf462088d13 1370 */
markrad 0:cdf462088d13 1371 MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
markrad 0:cdf462088d13 1372 mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
markrad 0:cdf462088d13 1373 p += 2;
markrad 0:cdf462088d13 1374
markrad 0:cdf462088d13 1375 /*
markrad 0:cdf462088d13 1376 * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
markrad 0:cdf462088d13 1377 * even is lower than our min version.
markrad 0:cdf462088d13 1378 */
markrad 0:cdf462088d13 1379 if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
markrad 0:cdf462088d13 1380 minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
markrad 0:cdf462088d13 1381 major_ver > ssl->conf->max_major_ver ||
markrad 0:cdf462088d13 1382 minor_ver > ssl->conf->max_minor_ver )
markrad 0:cdf462088d13 1383 {
markrad 0:cdf462088d13 1384 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
markrad 0:cdf462088d13 1385
markrad 0:cdf462088d13 1386 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
markrad 0:cdf462088d13 1387 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
markrad 0:cdf462088d13 1388
markrad 0:cdf462088d13 1389 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
markrad 0:cdf462088d13 1390 }
markrad 0:cdf462088d13 1391
markrad 0:cdf462088d13 1392 cookie_len = *p++;
markrad 0:cdf462088d13 1393 MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
markrad 0:cdf462088d13 1394
markrad 0:cdf462088d13 1395 if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
markrad 0:cdf462088d13 1396 {
markrad 0:cdf462088d13 1397 MBEDTLS_SSL_DEBUG_MSG( 1,
markrad 0:cdf462088d13 1398 ( "cookie length does not match incoming message size" ) );
markrad 0:cdf462088d13 1399 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
markrad 0:cdf462088d13 1400 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1401 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1402 }
markrad 0:cdf462088d13 1403
markrad 0:cdf462088d13 1404 mbedtls_free( ssl->handshake->verify_cookie );
markrad 0:cdf462088d13 1405
markrad 0:cdf462088d13 1406 ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
markrad 0:cdf462088d13 1407 if( ssl->handshake->verify_cookie == NULL )
markrad 0:cdf462088d13 1408 {
markrad 0:cdf462088d13 1409 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
markrad 0:cdf462088d13 1410 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
markrad 0:cdf462088d13 1411 }
markrad 0:cdf462088d13 1412
markrad 0:cdf462088d13 1413 memcpy( ssl->handshake->verify_cookie, p, cookie_len );
markrad 0:cdf462088d13 1414 ssl->handshake->verify_cookie_len = cookie_len;
markrad 0:cdf462088d13 1415
markrad 0:cdf462088d13 1416 /* Start over at ClientHello */
markrad 0:cdf462088d13 1417 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
markrad 0:cdf462088d13 1418 mbedtls_ssl_reset_checksum( ssl );
markrad 0:cdf462088d13 1419
markrad 0:cdf462088d13 1420 mbedtls_ssl_recv_flight_completed( ssl );
markrad 0:cdf462088d13 1421
markrad 0:cdf462088d13 1422 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
markrad 0:cdf462088d13 1423
markrad 0:cdf462088d13 1424 return( 0 );
markrad 0:cdf462088d13 1425 }
markrad 0:cdf462088d13 1426 #endif /* MBEDTLS_SSL_PROTO_DTLS */
markrad 0:cdf462088d13 1427
markrad 0:cdf462088d13 1428 static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 1429 {
markrad 0:cdf462088d13 1430 int ret, i;
markrad 0:cdf462088d13 1431 size_t n;
markrad 0:cdf462088d13 1432 size_t ext_len;
markrad 0:cdf462088d13 1433 unsigned char *buf, *ext;
markrad 0:cdf462088d13 1434 unsigned char comp;
markrad 0:cdf462088d13 1435 #if defined(MBEDTLS_ZLIB_SUPPORT)
markrad 0:cdf462088d13 1436 int accept_comp;
markrad 0:cdf462088d13 1437 #endif
markrad 0:cdf462088d13 1438 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1439 int renegotiation_info_seen = 0;
markrad 0:cdf462088d13 1440 #endif
markrad 0:cdf462088d13 1441 int handshake_failure = 0;
markrad 0:cdf462088d13 1442 const mbedtls_ssl_ciphersuite_t *suite_info;
markrad 0:cdf462088d13 1443 #if defined(MBEDTLS_DEBUG_C)
markrad 0:cdf462088d13 1444 uint32_t t;
markrad 0:cdf462088d13 1445 #endif
markrad 0:cdf462088d13 1446
markrad 0:cdf462088d13 1447 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
markrad 0:cdf462088d13 1448
markrad 0:cdf462088d13 1449 buf = ssl->in_msg;
markrad 0:cdf462088d13 1450
markrad 0:cdf462088d13 1451 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 1452 {
Jasper Wallace 2:bbdeda018a3c 1453 /* No alert on a read error. */
markrad 0:cdf462088d13 1454 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
markrad 0:cdf462088d13 1455 return( ret );
markrad 0:cdf462088d13 1456 }
markrad 0:cdf462088d13 1457
markrad 0:cdf462088d13 1458 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
markrad 0:cdf462088d13 1459 {
markrad 0:cdf462088d13 1460 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1461 if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
markrad 0:cdf462088d13 1462 {
markrad 0:cdf462088d13 1463 ssl->renego_records_seen++;
markrad 0:cdf462088d13 1464
markrad 0:cdf462088d13 1465 if( ssl->conf->renego_max_records >= 0 &&
markrad 0:cdf462088d13 1466 ssl->renego_records_seen > ssl->conf->renego_max_records )
markrad 0:cdf462088d13 1467 {
markrad 0:cdf462088d13 1468 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
markrad 0:cdf462088d13 1469 "but not honored by server" ) );
markrad 0:cdf462088d13 1470 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 1471 }
markrad 0:cdf462088d13 1472
markrad 0:cdf462088d13 1473 MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
Jasper Wallace 2:bbdeda018a3c 1474
Jasper Wallace 2:bbdeda018a3c 1475 ssl->keep_current_message = 1;
markrad 0:cdf462088d13 1476 return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
markrad 0:cdf462088d13 1477 }
markrad 0:cdf462088d13 1478 #endif /* MBEDTLS_SSL_RENEGOTIATION */
markrad 0:cdf462088d13 1479
markrad 0:cdf462088d13 1480 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1481 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1482 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 1483 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 1484 }
markrad 0:cdf462088d13 1485
markrad 0:cdf462088d13 1486 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 1487 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 1488 {
markrad 0:cdf462088d13 1489 if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
markrad 0:cdf462088d13 1490 {
markrad 0:cdf462088d13 1491 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
markrad 0:cdf462088d13 1492 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
markrad 0:cdf462088d13 1493 return( ssl_parse_hello_verify_request( ssl ) );
markrad 0:cdf462088d13 1494 }
markrad 0:cdf462088d13 1495 else
markrad 0:cdf462088d13 1496 {
markrad 0:cdf462088d13 1497 /* We made it through the verification process */
markrad 0:cdf462088d13 1498 mbedtls_free( ssl->handshake->verify_cookie );
markrad 0:cdf462088d13 1499 ssl->handshake->verify_cookie = NULL;
markrad 0:cdf462088d13 1500 ssl->handshake->verify_cookie_len = 0;
markrad 0:cdf462088d13 1501 }
markrad 0:cdf462088d13 1502 }
markrad 0:cdf462088d13 1503 #endif /* MBEDTLS_SSL_PROTO_DTLS */
markrad 0:cdf462088d13 1504
markrad 0:cdf462088d13 1505 if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
markrad 0:cdf462088d13 1506 buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
markrad 0:cdf462088d13 1507 {
markrad 0:cdf462088d13 1508 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1509 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1510 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1511 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1512 }
markrad 0:cdf462088d13 1513
markrad 0:cdf462088d13 1514 /*
markrad 0:cdf462088d13 1515 * 0 . 1 server_version
markrad 0:cdf462088d13 1516 * 2 . 33 random (maybe including 4 bytes of Unix time)
markrad 0:cdf462088d13 1517 * 34 . 34 session_id length = n
markrad 0:cdf462088d13 1518 * 35 . 34+n session_id
markrad 0:cdf462088d13 1519 * 35+n . 36+n cipher_suite
markrad 0:cdf462088d13 1520 * 37+n . 37+n compression_method
markrad 0:cdf462088d13 1521 *
markrad 0:cdf462088d13 1522 * 38+n . 39+n extensions length (optional)
markrad 0:cdf462088d13 1523 * 40+n . .. extensions
markrad 0:cdf462088d13 1524 */
markrad 0:cdf462088d13 1525 buf += mbedtls_ssl_hs_hdr_len( ssl );
markrad 0:cdf462088d13 1526
markrad 0:cdf462088d13 1527 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
markrad 0:cdf462088d13 1528 mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
markrad 0:cdf462088d13 1529 ssl->conf->transport, buf + 0 );
markrad 0:cdf462088d13 1530
markrad 0:cdf462088d13 1531 if( ssl->major_ver < ssl->conf->min_major_ver ||
markrad 0:cdf462088d13 1532 ssl->minor_ver < ssl->conf->min_minor_ver ||
markrad 0:cdf462088d13 1533 ssl->major_ver > ssl->conf->max_major_ver ||
markrad 0:cdf462088d13 1534 ssl->minor_ver > ssl->conf->max_minor_ver )
markrad 0:cdf462088d13 1535 {
markrad 0:cdf462088d13 1536 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
markrad 0:cdf462088d13 1537 " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
markrad 0:cdf462088d13 1538 ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
markrad 0:cdf462088d13 1539 ssl->major_ver, ssl->minor_ver,
markrad 0:cdf462088d13 1540 ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
markrad 0:cdf462088d13 1541
markrad 0:cdf462088d13 1542 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
markrad 0:cdf462088d13 1543 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
markrad 0:cdf462088d13 1544
markrad 0:cdf462088d13 1545 return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
markrad 0:cdf462088d13 1546 }
markrad 0:cdf462088d13 1547
markrad 0:cdf462088d13 1548 #if defined(MBEDTLS_DEBUG_C)
markrad 0:cdf462088d13 1549 t = ( (uint32_t) buf[2] << 24 )
markrad 0:cdf462088d13 1550 | ( (uint32_t) buf[3] << 16 )
markrad 0:cdf462088d13 1551 | ( (uint32_t) buf[4] << 8 )
markrad 0:cdf462088d13 1552 | ( (uint32_t) buf[5] );
markrad 0:cdf462088d13 1553 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
markrad 0:cdf462088d13 1554 #endif
markrad 0:cdf462088d13 1555
markrad 0:cdf462088d13 1556 memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
markrad 0:cdf462088d13 1557
markrad 0:cdf462088d13 1558 n = buf[34];
markrad 0:cdf462088d13 1559
markrad 0:cdf462088d13 1560 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
markrad 0:cdf462088d13 1561
markrad 0:cdf462088d13 1562 if( n > 32 )
markrad 0:cdf462088d13 1563 {
markrad 0:cdf462088d13 1564 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1565 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1566 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1567 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1568 }
markrad 0:cdf462088d13 1569
markrad 0:cdf462088d13 1570 if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
markrad 0:cdf462088d13 1571 {
markrad 0:cdf462088d13 1572 ext_len = ( ( buf[38 + n] << 8 )
markrad 0:cdf462088d13 1573 | ( buf[39 + n] ) );
markrad 0:cdf462088d13 1574
markrad 0:cdf462088d13 1575 if( ( ext_len > 0 && ext_len < 4 ) ||
markrad 0:cdf462088d13 1576 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
markrad 0:cdf462088d13 1577 {
markrad 0:cdf462088d13 1578 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1579 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1580 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1581 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1582 }
markrad 0:cdf462088d13 1583 }
markrad 0:cdf462088d13 1584 else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
markrad 0:cdf462088d13 1585 {
markrad 0:cdf462088d13 1586 ext_len = 0;
markrad 0:cdf462088d13 1587 }
markrad 0:cdf462088d13 1588 else
markrad 0:cdf462088d13 1589 {
markrad 0:cdf462088d13 1590 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1591 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1592 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1593 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1594 }
markrad 0:cdf462088d13 1595
markrad 0:cdf462088d13 1596 /* ciphersuite (used later) */
markrad 0:cdf462088d13 1597 i = ( buf[35 + n] << 8 ) | buf[36 + n];
markrad 0:cdf462088d13 1598
markrad 0:cdf462088d13 1599 /*
markrad 0:cdf462088d13 1600 * Read and check compression
markrad 0:cdf462088d13 1601 */
markrad 0:cdf462088d13 1602 comp = buf[37 + n];
markrad 0:cdf462088d13 1603
markrad 0:cdf462088d13 1604 #if defined(MBEDTLS_ZLIB_SUPPORT)
markrad 0:cdf462088d13 1605 /* See comments in ssl_write_client_hello() */
markrad 0:cdf462088d13 1606 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 1607 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 1608 accept_comp = 0;
markrad 0:cdf462088d13 1609 else
markrad 0:cdf462088d13 1610 #endif
markrad 0:cdf462088d13 1611 accept_comp = 1;
markrad 0:cdf462088d13 1612
markrad 0:cdf462088d13 1613 if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
markrad 0:cdf462088d13 1614 ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
markrad 0:cdf462088d13 1615 #else /* MBEDTLS_ZLIB_SUPPORT */
markrad 0:cdf462088d13 1616 if( comp != MBEDTLS_SSL_COMPRESS_NULL )
markrad 0:cdf462088d13 1617 #endif/* MBEDTLS_ZLIB_SUPPORT */
markrad 0:cdf462088d13 1618 {
markrad 0:cdf462088d13 1619 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
Jasper Wallace 2:bbdeda018a3c 1620 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1621 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 1622 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
markrad 0:cdf462088d13 1623 }
markrad 0:cdf462088d13 1624
markrad 0:cdf462088d13 1625 /*
markrad 0:cdf462088d13 1626 * Initialize update checksum functions
markrad 0:cdf462088d13 1627 */
markrad 0:cdf462088d13 1628 ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
markrad 0:cdf462088d13 1629
markrad 0:cdf462088d13 1630 if( ssl->transform_negotiate->ciphersuite_info == NULL )
markrad 0:cdf462088d13 1631 {
markrad 0:cdf462088d13 1632 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
Jasper Wallace 2:bbdeda018a3c 1633 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1634 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
markrad 0:cdf462088d13 1635 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
markrad 0:cdf462088d13 1636 }
markrad 0:cdf462088d13 1637
markrad 0:cdf462088d13 1638 mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
markrad 0:cdf462088d13 1639
markrad 0:cdf462088d13 1640 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
markrad 0:cdf462088d13 1641 MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
markrad 0:cdf462088d13 1642
markrad 0:cdf462088d13 1643 /*
markrad 0:cdf462088d13 1644 * Check if the session can be resumed
markrad 0:cdf462088d13 1645 */
markrad 0:cdf462088d13 1646 if( ssl->handshake->resume == 0 || n == 0 ||
markrad 0:cdf462088d13 1647 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1648 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
markrad 0:cdf462088d13 1649 #endif
markrad 0:cdf462088d13 1650 ssl->session_negotiate->ciphersuite != i ||
markrad 0:cdf462088d13 1651 ssl->session_negotiate->compression != comp ||
markrad 0:cdf462088d13 1652 ssl->session_negotiate->id_len != n ||
markrad 0:cdf462088d13 1653 memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
markrad 0:cdf462088d13 1654 {
markrad 0:cdf462088d13 1655 ssl->state++;
markrad 0:cdf462088d13 1656 ssl->handshake->resume = 0;
markrad 0:cdf462088d13 1657 #if defined(MBEDTLS_HAVE_TIME)
markrad 0:cdf462088d13 1658 ssl->session_negotiate->start = mbedtls_time( NULL );
markrad 0:cdf462088d13 1659 #endif
markrad 0:cdf462088d13 1660 ssl->session_negotiate->ciphersuite = i;
markrad 0:cdf462088d13 1661 ssl->session_negotiate->compression = comp;
markrad 0:cdf462088d13 1662 ssl->session_negotiate->id_len = n;
markrad 0:cdf462088d13 1663 memcpy( ssl->session_negotiate->id, buf + 35, n );
markrad 0:cdf462088d13 1664 }
markrad 0:cdf462088d13 1665 else
markrad 0:cdf462088d13 1666 {
markrad 0:cdf462088d13 1667 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
markrad 0:cdf462088d13 1668
markrad 0:cdf462088d13 1669 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
markrad 0:cdf462088d13 1670 {
markrad 0:cdf462088d13 1671 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
Jasper Wallace 2:bbdeda018a3c 1672 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1673 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
markrad 0:cdf462088d13 1674 return( ret );
markrad 0:cdf462088d13 1675 }
markrad 0:cdf462088d13 1676 }
markrad 0:cdf462088d13 1677
markrad 0:cdf462088d13 1678 MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
markrad 0:cdf462088d13 1679 ssl->handshake->resume ? "a" : "no" ) );
markrad 0:cdf462088d13 1680
markrad 0:cdf462088d13 1681 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
markrad 0:cdf462088d13 1682 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
markrad 0:cdf462088d13 1683
markrad 0:cdf462088d13 1684 suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
markrad 0:cdf462088d13 1685 if( suite_info == NULL
markrad 0:cdf462088d13 1686 #if defined(MBEDTLS_ARC4_C)
markrad 0:cdf462088d13 1687 || ( ssl->conf->arc4_disabled &&
markrad 0:cdf462088d13 1688 suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
markrad 0:cdf462088d13 1689 #endif
markrad 0:cdf462088d13 1690 )
markrad 0:cdf462088d13 1691 {
markrad 0:cdf462088d13 1692 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1693 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1694 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 1695 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1696 }
markrad 0:cdf462088d13 1697
markrad 0:cdf462088d13 1698 MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
markrad 0:cdf462088d13 1699
markrad 0:cdf462088d13 1700 i = 0;
markrad 0:cdf462088d13 1701 while( 1 )
markrad 0:cdf462088d13 1702 {
markrad 0:cdf462088d13 1703 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
markrad 0:cdf462088d13 1704 {
markrad 0:cdf462088d13 1705 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1706 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1707 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 1708 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1709 }
markrad 0:cdf462088d13 1710
markrad 0:cdf462088d13 1711 if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
markrad 0:cdf462088d13 1712 ssl->session_negotiate->ciphersuite )
markrad 0:cdf462088d13 1713 {
markrad 0:cdf462088d13 1714 break;
markrad 0:cdf462088d13 1715 }
markrad 0:cdf462088d13 1716 }
markrad 0:cdf462088d13 1717
markrad 0:cdf462088d13 1718 if( comp != MBEDTLS_SSL_COMPRESS_NULL
markrad 0:cdf462088d13 1719 #if defined(MBEDTLS_ZLIB_SUPPORT)
markrad 0:cdf462088d13 1720 && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
markrad 0:cdf462088d13 1721 #endif
markrad 0:cdf462088d13 1722 )
markrad 0:cdf462088d13 1723 {
markrad 0:cdf462088d13 1724 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1725 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1726 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 1727 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1728 }
markrad 0:cdf462088d13 1729 ssl->session_negotiate->compression = comp;
markrad 0:cdf462088d13 1730
markrad 0:cdf462088d13 1731 ext = buf + 40 + n;
markrad 0:cdf462088d13 1732
markrad 0:cdf462088d13 1733 MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
markrad 0:cdf462088d13 1734
markrad 0:cdf462088d13 1735 while( ext_len )
markrad 0:cdf462088d13 1736 {
markrad 0:cdf462088d13 1737 unsigned int ext_id = ( ( ext[0] << 8 )
markrad 0:cdf462088d13 1738 | ( ext[1] ) );
markrad 0:cdf462088d13 1739 unsigned int ext_size = ( ( ext[2] << 8 )
markrad 0:cdf462088d13 1740 | ( ext[3] ) );
markrad 0:cdf462088d13 1741
markrad 0:cdf462088d13 1742 if( ext_size + 4 > ext_len )
markrad 0:cdf462088d13 1743 {
markrad 0:cdf462088d13 1744 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Jasper Wallace 2:bbdeda018a3c 1745 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1746 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 1747 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1748 }
markrad 0:cdf462088d13 1749
markrad 0:cdf462088d13 1750 switch( ext_id )
markrad 0:cdf462088d13 1751 {
markrad 0:cdf462088d13 1752 case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
markrad 0:cdf462088d13 1753 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
markrad 0:cdf462088d13 1754 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1755 renegotiation_info_seen = 1;
markrad 0:cdf462088d13 1756 #endif
markrad 0:cdf462088d13 1757
markrad 0:cdf462088d13 1758 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
markrad 0:cdf462088d13 1759 ext_size ) ) != 0 )
markrad 0:cdf462088d13 1760 return( ret );
markrad 0:cdf462088d13 1761
markrad 0:cdf462088d13 1762 break;
markrad 0:cdf462088d13 1763
markrad 0:cdf462088d13 1764 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
markrad 0:cdf462088d13 1765 case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
markrad 0:cdf462088d13 1766 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
markrad 0:cdf462088d13 1767
markrad 0:cdf462088d13 1768 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
markrad 0:cdf462088d13 1769 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1770 {
markrad 0:cdf462088d13 1771 return( ret );
markrad 0:cdf462088d13 1772 }
markrad 0:cdf462088d13 1773
markrad 0:cdf462088d13 1774 break;
markrad 0:cdf462088d13 1775 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
markrad 0:cdf462088d13 1776
markrad 0:cdf462088d13 1777 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
markrad 0:cdf462088d13 1778 case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
markrad 0:cdf462088d13 1779 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
markrad 0:cdf462088d13 1780
markrad 0:cdf462088d13 1781 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
markrad 0:cdf462088d13 1782 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1783 {
markrad 0:cdf462088d13 1784 return( ret );
markrad 0:cdf462088d13 1785 }
markrad 0:cdf462088d13 1786
markrad 0:cdf462088d13 1787 break;
markrad 0:cdf462088d13 1788 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
markrad 0:cdf462088d13 1789
markrad 0:cdf462088d13 1790 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
markrad 0:cdf462088d13 1791 case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
markrad 0:cdf462088d13 1792 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
markrad 0:cdf462088d13 1793
markrad 0:cdf462088d13 1794 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
markrad 0:cdf462088d13 1795 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1796 {
markrad 0:cdf462088d13 1797 return( ret );
markrad 0:cdf462088d13 1798 }
markrad 0:cdf462088d13 1799
markrad 0:cdf462088d13 1800 break;
markrad 0:cdf462088d13 1801 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
markrad 0:cdf462088d13 1802
markrad 0:cdf462088d13 1803 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
markrad 0:cdf462088d13 1804 case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
markrad 0:cdf462088d13 1805 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
markrad 0:cdf462088d13 1806
markrad 0:cdf462088d13 1807 if( ( ret = ssl_parse_extended_ms_ext( ssl,
markrad 0:cdf462088d13 1808 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1809 {
markrad 0:cdf462088d13 1810 return( ret );
markrad 0:cdf462088d13 1811 }
markrad 0:cdf462088d13 1812
markrad 0:cdf462088d13 1813 break;
markrad 0:cdf462088d13 1814 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
markrad 0:cdf462088d13 1815
markrad 0:cdf462088d13 1816 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 1817 case MBEDTLS_TLS_EXT_SESSION_TICKET:
markrad 0:cdf462088d13 1818 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
markrad 0:cdf462088d13 1819
markrad 0:cdf462088d13 1820 if( ( ret = ssl_parse_session_ticket_ext( ssl,
markrad 0:cdf462088d13 1821 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1822 {
markrad 0:cdf462088d13 1823 return( ret );
markrad 0:cdf462088d13 1824 }
markrad 0:cdf462088d13 1825
markrad 0:cdf462088d13 1826 break;
markrad 0:cdf462088d13 1827 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
markrad 0:cdf462088d13 1828
markrad 0:cdf462088d13 1829 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
markrad 0:cdf462088d13 1830 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 1831 case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
markrad 0:cdf462088d13 1832 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
markrad 0:cdf462088d13 1833
markrad 0:cdf462088d13 1834 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
markrad 0:cdf462088d13 1835 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1836 {
markrad 0:cdf462088d13 1837 return( ret );
markrad 0:cdf462088d13 1838 }
markrad 0:cdf462088d13 1839
markrad 0:cdf462088d13 1840 break;
markrad 0:cdf462088d13 1841 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
markrad 0:cdf462088d13 1842 MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 1843
markrad 0:cdf462088d13 1844 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 1845 case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
markrad 0:cdf462088d13 1846 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
markrad 0:cdf462088d13 1847
markrad 0:cdf462088d13 1848 if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
markrad 0:cdf462088d13 1849 ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1850 {
markrad 0:cdf462088d13 1851 return( ret );
markrad 0:cdf462088d13 1852 }
markrad 0:cdf462088d13 1853
markrad 0:cdf462088d13 1854 break;
markrad 0:cdf462088d13 1855 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 1856
markrad 0:cdf462088d13 1857 #if defined(MBEDTLS_SSL_ALPN)
markrad 0:cdf462088d13 1858 case MBEDTLS_TLS_EXT_ALPN:
markrad 0:cdf462088d13 1859 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
markrad 0:cdf462088d13 1860
markrad 0:cdf462088d13 1861 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
markrad 0:cdf462088d13 1862 return( ret );
markrad 0:cdf462088d13 1863
markrad 0:cdf462088d13 1864 break;
markrad 0:cdf462088d13 1865 #endif /* MBEDTLS_SSL_ALPN */
markrad 0:cdf462088d13 1866
markrad 0:cdf462088d13 1867 default:
markrad 0:cdf462088d13 1868 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
markrad 0:cdf462088d13 1869 ext_id ) );
markrad 0:cdf462088d13 1870 }
markrad 0:cdf462088d13 1871
markrad 0:cdf462088d13 1872 ext_len -= 4 + ext_size;
markrad 0:cdf462088d13 1873 ext += 4 + ext_size;
markrad 0:cdf462088d13 1874
markrad 0:cdf462088d13 1875 if( ext_len > 0 && ext_len < 4 )
markrad 0:cdf462088d13 1876 {
markrad 0:cdf462088d13 1877 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
markrad 0:cdf462088d13 1878 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1879 }
markrad 0:cdf462088d13 1880 }
markrad 0:cdf462088d13 1881
markrad 0:cdf462088d13 1882 /*
markrad 0:cdf462088d13 1883 * Renegotiation security checks
markrad 0:cdf462088d13 1884 */
markrad 0:cdf462088d13 1885 if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
markrad 0:cdf462088d13 1886 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
markrad 0:cdf462088d13 1887 {
markrad 0:cdf462088d13 1888 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
markrad 0:cdf462088d13 1889 handshake_failure = 1;
markrad 0:cdf462088d13 1890 }
markrad 0:cdf462088d13 1891 #if defined(MBEDTLS_SSL_RENEGOTIATION)
markrad 0:cdf462088d13 1892 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
markrad 0:cdf462088d13 1893 ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
markrad 0:cdf462088d13 1894 renegotiation_info_seen == 0 )
markrad 0:cdf462088d13 1895 {
markrad 0:cdf462088d13 1896 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
markrad 0:cdf462088d13 1897 handshake_failure = 1;
markrad 0:cdf462088d13 1898 }
markrad 0:cdf462088d13 1899 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
markrad 0:cdf462088d13 1900 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
markrad 0:cdf462088d13 1901 ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
markrad 0:cdf462088d13 1902 {
markrad 0:cdf462088d13 1903 MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
markrad 0:cdf462088d13 1904 handshake_failure = 1;
markrad 0:cdf462088d13 1905 }
markrad 0:cdf462088d13 1906 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
markrad 0:cdf462088d13 1907 ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
markrad 0:cdf462088d13 1908 renegotiation_info_seen == 1 )
markrad 0:cdf462088d13 1909 {
markrad 0:cdf462088d13 1910 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
markrad 0:cdf462088d13 1911 handshake_failure = 1;
markrad 0:cdf462088d13 1912 }
markrad 0:cdf462088d13 1913 #endif /* MBEDTLS_SSL_RENEGOTIATION */
markrad 0:cdf462088d13 1914
markrad 0:cdf462088d13 1915 if( handshake_failure == 1 )
markrad 0:cdf462088d13 1916 {
Jasper Wallace 2:bbdeda018a3c 1917 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 1918 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 1919 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
markrad 0:cdf462088d13 1920 }
markrad 0:cdf462088d13 1921
markrad 0:cdf462088d13 1922 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
markrad 0:cdf462088d13 1923
markrad 0:cdf462088d13 1924 return( 0 );
markrad 0:cdf462088d13 1925 }
markrad 0:cdf462088d13 1926
markrad 0:cdf462088d13 1927 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 1928 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
markrad 0:cdf462088d13 1929 static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
markrad 0:cdf462088d13 1930 unsigned char *end )
markrad 0:cdf462088d13 1931 {
markrad 0:cdf462088d13 1932 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
markrad 0:cdf462088d13 1933
markrad 0:cdf462088d13 1934 /*
markrad 0:cdf462088d13 1935 * Ephemeral DH parameters:
markrad 0:cdf462088d13 1936 *
markrad 0:cdf462088d13 1937 * struct {
markrad 0:cdf462088d13 1938 * opaque dh_p<1..2^16-1>;
markrad 0:cdf462088d13 1939 * opaque dh_g<1..2^16-1>;
markrad 0:cdf462088d13 1940 * opaque dh_Ys<1..2^16-1>;
markrad 0:cdf462088d13 1941 * } ServerDHParams;
markrad 0:cdf462088d13 1942 */
markrad 0:cdf462088d13 1943 if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
markrad 0:cdf462088d13 1944 {
markrad 0:cdf462088d13 1945 MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
markrad 0:cdf462088d13 1946 return( ret );
markrad 0:cdf462088d13 1947 }
markrad 0:cdf462088d13 1948
markrad 0:cdf462088d13 1949 if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
markrad 0:cdf462088d13 1950 {
markrad 0:cdf462088d13 1951 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
markrad 0:cdf462088d13 1952 ssl->handshake->dhm_ctx.len * 8,
markrad 0:cdf462088d13 1953 ssl->conf->dhm_min_bitlen ) );
markrad 0:cdf462088d13 1954 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 1955 }
markrad 0:cdf462088d13 1956
markrad 0:cdf462088d13 1957 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
markrad 0:cdf462088d13 1958 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
markrad 0:cdf462088d13 1959 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
markrad 0:cdf462088d13 1960
markrad 0:cdf462088d13 1961 return( ret );
markrad 0:cdf462088d13 1962 }
markrad 0:cdf462088d13 1963 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
markrad 0:cdf462088d13 1964 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
markrad 0:cdf462088d13 1965
markrad 0:cdf462088d13 1966 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 1967 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
markrad 0:cdf462088d13 1968 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
markrad 0:cdf462088d13 1969 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
markrad 0:cdf462088d13 1970 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
markrad 0:cdf462088d13 1971 static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 1972 {
markrad 0:cdf462088d13 1973 const mbedtls_ecp_curve_info *curve_info;
markrad 0:cdf462088d13 1974
markrad 0:cdf462088d13 1975 curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
markrad 0:cdf462088d13 1976 if( curve_info == NULL )
markrad 0:cdf462088d13 1977 {
markrad 0:cdf462088d13 1978 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 1979 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 1980 }
markrad 0:cdf462088d13 1981
markrad 0:cdf462088d13 1982 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
markrad 0:cdf462088d13 1983
markrad 0:cdf462088d13 1984 #if defined(MBEDTLS_ECP_C)
markrad 0:cdf462088d13 1985 if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
markrad 0:cdf462088d13 1986 #else
markrad 0:cdf462088d13 1987 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
markrad 0:cdf462088d13 1988 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
markrad 0:cdf462088d13 1989 #endif
markrad 0:cdf462088d13 1990 return( -1 );
markrad 0:cdf462088d13 1991
markrad 0:cdf462088d13 1992 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
markrad 0:cdf462088d13 1993
markrad 0:cdf462088d13 1994 return( 0 );
markrad 0:cdf462088d13 1995 }
markrad 0:cdf462088d13 1996 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
markrad 0:cdf462088d13 1997 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
markrad 0:cdf462088d13 1998 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
markrad 0:cdf462088d13 1999 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
markrad 0:cdf462088d13 2000 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
markrad 0:cdf462088d13 2001
markrad 0:cdf462088d13 2002 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2003 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
markrad 0:cdf462088d13 2004 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
markrad 0:cdf462088d13 2005 static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 2006 unsigned char **p,
markrad 0:cdf462088d13 2007 unsigned char *end )
markrad 0:cdf462088d13 2008 {
markrad 0:cdf462088d13 2009 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
markrad 0:cdf462088d13 2010
markrad 0:cdf462088d13 2011 /*
markrad 0:cdf462088d13 2012 * Ephemeral ECDH parameters:
markrad 0:cdf462088d13 2013 *
markrad 0:cdf462088d13 2014 * struct {
markrad 0:cdf462088d13 2015 * ECParameters curve_params;
markrad 0:cdf462088d13 2016 * ECPoint public;
markrad 0:cdf462088d13 2017 * } ServerECDHParams;
markrad 0:cdf462088d13 2018 */
markrad 0:cdf462088d13 2019 if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
markrad 0:cdf462088d13 2020 (const unsigned char **) p, end ) ) != 0 )
markrad 0:cdf462088d13 2021 {
markrad 0:cdf462088d13 2022 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
markrad 0:cdf462088d13 2023 return( ret );
markrad 0:cdf462088d13 2024 }
markrad 0:cdf462088d13 2025
markrad 0:cdf462088d13 2026 if( ssl_check_server_ecdh_params( ssl ) != 0 )
markrad 0:cdf462088d13 2027 {
markrad 0:cdf462088d13 2028 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
markrad 0:cdf462088d13 2029 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2030 }
markrad 0:cdf462088d13 2031
markrad 0:cdf462088d13 2032 return( ret );
markrad 0:cdf462088d13 2033 }
markrad 0:cdf462088d13 2034 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2035 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
markrad 0:cdf462088d13 2036 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
markrad 0:cdf462088d13 2037
markrad 0:cdf462088d13 2038 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
markrad 0:cdf462088d13 2039 static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 2040 unsigned char **p,
markrad 0:cdf462088d13 2041 unsigned char *end )
markrad 0:cdf462088d13 2042 {
markrad 0:cdf462088d13 2043 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
markrad 0:cdf462088d13 2044 size_t len;
markrad 0:cdf462088d13 2045 ((void) ssl);
markrad 0:cdf462088d13 2046
markrad 0:cdf462088d13 2047 /*
markrad 0:cdf462088d13 2048 * PSK parameters:
markrad 0:cdf462088d13 2049 *
markrad 0:cdf462088d13 2050 * opaque psk_identity_hint<0..2^16-1>;
markrad 0:cdf462088d13 2051 */
markrad 0:cdf462088d13 2052 len = (*p)[0] << 8 | (*p)[1];
markrad 0:cdf462088d13 2053 *p += 2;
markrad 0:cdf462088d13 2054
markrad 0:cdf462088d13 2055 if( (*p) + len > end )
markrad 0:cdf462088d13 2056 {
Jasper Wallace 2:bbdeda018a3c 2057 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
Jasper Wallace 2:bbdeda018a3c 2058 "(psk_identity_hint length)" ) );
markrad 0:cdf462088d13 2059 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2060 }
markrad 0:cdf462088d13 2061
markrad 0:cdf462088d13 2062 /*
markrad 0:cdf462088d13 2063 * Note: we currently ignore the PKS identity hint, as we only allow one
markrad 0:cdf462088d13 2064 * PSK to be provisionned on the client. This could be changed later if
markrad 0:cdf462088d13 2065 * someone needs that feature.
markrad 0:cdf462088d13 2066 */
markrad 0:cdf462088d13 2067 *p += len;
markrad 0:cdf462088d13 2068 ret = 0;
markrad 0:cdf462088d13 2069
markrad 0:cdf462088d13 2070 return( ret );
markrad 0:cdf462088d13 2071 }
markrad 0:cdf462088d13 2072 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
markrad 0:cdf462088d13 2073
markrad 0:cdf462088d13 2074 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2075 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
markrad 0:cdf462088d13 2076 /*
markrad 0:cdf462088d13 2077 * Generate a pre-master secret and encrypt it with the server's RSA key
markrad 0:cdf462088d13 2078 */
markrad 0:cdf462088d13 2079 static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 2080 size_t offset, size_t *olen,
markrad 0:cdf462088d13 2081 size_t pms_offset )
markrad 0:cdf462088d13 2082 {
markrad 0:cdf462088d13 2083 int ret;
markrad 0:cdf462088d13 2084 size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
markrad 0:cdf462088d13 2085 unsigned char *p = ssl->handshake->premaster + pms_offset;
markrad 0:cdf462088d13 2086
markrad 0:cdf462088d13 2087 if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN )
markrad 0:cdf462088d13 2088 {
markrad 0:cdf462088d13 2089 MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
markrad 0:cdf462088d13 2090 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
markrad 0:cdf462088d13 2091 }
markrad 0:cdf462088d13 2092
markrad 0:cdf462088d13 2093 /*
markrad 0:cdf462088d13 2094 * Generate (part of) the pre-master as
markrad 0:cdf462088d13 2095 * struct {
markrad 0:cdf462088d13 2096 * ProtocolVersion client_version;
markrad 0:cdf462088d13 2097 * opaque random[46];
markrad 0:cdf462088d13 2098 * } PreMasterSecret;
markrad 0:cdf462088d13 2099 */
markrad 0:cdf462088d13 2100 mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
markrad 0:cdf462088d13 2101 ssl->conf->transport, p );
markrad 0:cdf462088d13 2102
markrad 0:cdf462088d13 2103 if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
markrad 0:cdf462088d13 2104 {
markrad 0:cdf462088d13 2105 MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
markrad 0:cdf462088d13 2106 return( ret );
markrad 0:cdf462088d13 2107 }
markrad 0:cdf462088d13 2108
markrad 0:cdf462088d13 2109 ssl->handshake->pmslen = 48;
markrad 0:cdf462088d13 2110
markrad 0:cdf462088d13 2111 if( ssl->session_negotiate->peer_cert == NULL )
markrad 0:cdf462088d13 2112 {
markrad 0:cdf462088d13 2113 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
markrad 0:cdf462088d13 2114 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2115 }
markrad 0:cdf462088d13 2116
markrad 0:cdf462088d13 2117 /*
markrad 0:cdf462088d13 2118 * Now write it out, encrypted
markrad 0:cdf462088d13 2119 */
markrad 0:cdf462088d13 2120 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
markrad 0:cdf462088d13 2121 MBEDTLS_PK_RSA ) )
markrad 0:cdf462088d13 2122 {
markrad 0:cdf462088d13 2123 MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
markrad 0:cdf462088d13 2124 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
markrad 0:cdf462088d13 2125 }
markrad 0:cdf462088d13 2126
markrad 0:cdf462088d13 2127 if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
markrad 0:cdf462088d13 2128 p, ssl->handshake->pmslen,
markrad 0:cdf462088d13 2129 ssl->out_msg + offset + len_bytes, olen,
markrad 0:cdf462088d13 2130 MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
markrad 0:cdf462088d13 2131 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
markrad 0:cdf462088d13 2132 {
markrad 0:cdf462088d13 2133 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
markrad 0:cdf462088d13 2134 return( ret );
markrad 0:cdf462088d13 2135 }
markrad 0:cdf462088d13 2136
markrad 0:cdf462088d13 2137 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
markrad 0:cdf462088d13 2138 defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 2139 if( len_bytes == 2 )
markrad 0:cdf462088d13 2140 {
markrad 0:cdf462088d13 2141 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
markrad 0:cdf462088d13 2142 ssl->out_msg[offset+1] = (unsigned char)( *olen );
markrad 0:cdf462088d13 2143 *olen += 2;
markrad 0:cdf462088d13 2144 }
markrad 0:cdf462088d13 2145 #endif
markrad 0:cdf462088d13 2146
markrad 0:cdf462088d13 2147 return( 0 );
markrad 0:cdf462088d13 2148 }
markrad 0:cdf462088d13 2149 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
markrad 0:cdf462088d13 2150 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
markrad 0:cdf462088d13 2151
markrad 0:cdf462088d13 2152 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 2153 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2154 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2155 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
markrad 0:cdf462088d13 2156 static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
markrad 0:cdf462088d13 2157 unsigned char **p,
markrad 0:cdf462088d13 2158 unsigned char *end,
markrad 0:cdf462088d13 2159 mbedtls_md_type_t *md_alg,
markrad 0:cdf462088d13 2160 mbedtls_pk_type_t *pk_alg )
markrad 0:cdf462088d13 2161 {
markrad 0:cdf462088d13 2162 ((void) ssl);
markrad 0:cdf462088d13 2163 *md_alg = MBEDTLS_MD_NONE;
markrad 0:cdf462088d13 2164 *pk_alg = MBEDTLS_PK_NONE;
markrad 0:cdf462088d13 2165
markrad 0:cdf462088d13 2166 /* Only in TLS 1.2 */
markrad 0:cdf462088d13 2167 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 2168 {
markrad 0:cdf462088d13 2169 return( 0 );
markrad 0:cdf462088d13 2170 }
markrad 0:cdf462088d13 2171
markrad 0:cdf462088d13 2172 if( (*p) + 2 > end )
markrad 0:cdf462088d13 2173 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2174
markrad 0:cdf462088d13 2175 /*
markrad 0:cdf462088d13 2176 * Get hash algorithm
markrad 0:cdf462088d13 2177 */
markrad 0:cdf462088d13 2178 if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
markrad 0:cdf462088d13 2179 {
markrad 0:cdf462088d13 2180 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
markrad 0:cdf462088d13 2181 "HashAlgorithm %d", *(p)[0] ) );
markrad 0:cdf462088d13 2182 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2183 }
markrad 0:cdf462088d13 2184
markrad 0:cdf462088d13 2185 /*
markrad 0:cdf462088d13 2186 * Get signature algorithm
markrad 0:cdf462088d13 2187 */
markrad 0:cdf462088d13 2188 if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
markrad 0:cdf462088d13 2189 {
markrad 0:cdf462088d13 2190 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
markrad 0:cdf462088d13 2191 "SignatureAlgorithm %d", (*p)[1] ) );
markrad 0:cdf462088d13 2192 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2193 }
markrad 0:cdf462088d13 2194
markrad 0:cdf462088d13 2195 /*
markrad 0:cdf462088d13 2196 * Check if the hash is acceptable
markrad 0:cdf462088d13 2197 */
markrad 0:cdf462088d13 2198 if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
markrad 0:cdf462088d13 2199 {
Jasper Wallace 2:bbdeda018a3c 2200 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered",
Jasper Wallace 2:bbdeda018a3c 2201 *(p)[0] ) );
markrad 0:cdf462088d13 2202 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2203 }
markrad 0:cdf462088d13 2204
markrad 0:cdf462088d13 2205 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
markrad 0:cdf462088d13 2206 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
markrad 0:cdf462088d13 2207 *p += 2;
markrad 0:cdf462088d13 2208
markrad 0:cdf462088d13 2209 return( 0 );
markrad 0:cdf462088d13 2210 }
markrad 0:cdf462088d13 2211 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2212 MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2213 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
markrad 0:cdf462088d13 2214 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
markrad 0:cdf462088d13 2215
markrad 0:cdf462088d13 2216 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
markrad 0:cdf462088d13 2217 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
markrad 0:cdf462088d13 2218 static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2219 {
markrad 0:cdf462088d13 2220 int ret;
markrad 0:cdf462088d13 2221 const mbedtls_ecp_keypair *peer_key;
markrad 0:cdf462088d13 2222
markrad 0:cdf462088d13 2223 if( ssl->session_negotiate->peer_cert == NULL )
markrad 0:cdf462088d13 2224 {
markrad 0:cdf462088d13 2225 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
markrad 0:cdf462088d13 2226 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2227 }
markrad 0:cdf462088d13 2228
markrad 0:cdf462088d13 2229 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
markrad 0:cdf462088d13 2230 MBEDTLS_PK_ECKEY ) )
markrad 0:cdf462088d13 2231 {
markrad 0:cdf462088d13 2232 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
markrad 0:cdf462088d13 2233 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
markrad 0:cdf462088d13 2234 }
markrad 0:cdf462088d13 2235
markrad 0:cdf462088d13 2236 peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
markrad 0:cdf462088d13 2237
markrad 0:cdf462088d13 2238 if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
markrad 0:cdf462088d13 2239 MBEDTLS_ECDH_THEIRS ) ) != 0 )
markrad 0:cdf462088d13 2240 {
markrad 0:cdf462088d13 2241 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
markrad 0:cdf462088d13 2242 return( ret );
markrad 0:cdf462088d13 2243 }
markrad 0:cdf462088d13 2244
markrad 0:cdf462088d13 2245 if( ssl_check_server_ecdh_params( ssl ) != 0 )
markrad 0:cdf462088d13 2246 {
markrad 0:cdf462088d13 2247 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
markrad 0:cdf462088d13 2248 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
markrad 0:cdf462088d13 2249 }
markrad 0:cdf462088d13 2250
markrad 0:cdf462088d13 2251 return( ret );
markrad 0:cdf462088d13 2252 }
markrad 0:cdf462088d13 2253 #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
markrad 0:cdf462088d13 2254 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
markrad 0:cdf462088d13 2255
markrad 0:cdf462088d13 2256 static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2257 {
markrad 0:cdf462088d13 2258 int ret;
Jasper Wallace 2:bbdeda018a3c 2259 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 2260 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 2261 unsigned char *p, *end;
markrad 0:cdf462088d13 2262
markrad 0:cdf462088d13 2263 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
markrad 0:cdf462088d13 2264
markrad 0:cdf462088d13 2265 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
markrad 0:cdf462088d13 2266 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
markrad 0:cdf462088d13 2267 {
markrad 0:cdf462088d13 2268 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
markrad 0:cdf462088d13 2269 ssl->state++;
markrad 0:cdf462088d13 2270 return( 0 );
markrad 0:cdf462088d13 2271 }
markrad 0:cdf462088d13 2272 ((void) p);
markrad 0:cdf462088d13 2273 ((void) end);
markrad 0:cdf462088d13 2274 #endif
markrad 0:cdf462088d13 2275
markrad 0:cdf462088d13 2276 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
markrad 0:cdf462088d13 2277 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
markrad 0:cdf462088d13 2278 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
markrad 0:cdf462088d13 2279 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
markrad 0:cdf462088d13 2280 {
markrad 0:cdf462088d13 2281 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
markrad 0:cdf462088d13 2282 {
markrad 0:cdf462088d13 2283 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
Jasper Wallace 2:bbdeda018a3c 2284 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2285 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 2286 return( ret );
markrad 0:cdf462088d13 2287 }
markrad 0:cdf462088d13 2288
markrad 0:cdf462088d13 2289 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
markrad 0:cdf462088d13 2290 ssl->state++;
markrad 0:cdf462088d13 2291 return( 0 );
markrad 0:cdf462088d13 2292 }
markrad 0:cdf462088d13 2293 ((void) p);
markrad 0:cdf462088d13 2294 ((void) end);
markrad 0:cdf462088d13 2295 #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
markrad 0:cdf462088d13 2296 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
markrad 0:cdf462088d13 2297
markrad 0:cdf462088d13 2298 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 2299 {
markrad 0:cdf462088d13 2300 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
markrad 0:cdf462088d13 2301 return( ret );
markrad 0:cdf462088d13 2302 }
markrad 0:cdf462088d13 2303
markrad 0:cdf462088d13 2304 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
markrad 0:cdf462088d13 2305 {
markrad 0:cdf462088d13 2306 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2307 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2308 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2309 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2310 }
markrad 0:cdf462088d13 2311
markrad 0:cdf462088d13 2312 /*
markrad 0:cdf462088d13 2313 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
markrad 0:cdf462088d13 2314 * doesn't use a psk_identity_hint
markrad 0:cdf462088d13 2315 */
markrad 0:cdf462088d13 2316 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
markrad 0:cdf462088d13 2317 {
markrad 0:cdf462088d13 2318 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
markrad 0:cdf462088d13 2319 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
markrad 0:cdf462088d13 2320 {
Jasper Wallace 2:bbdeda018a3c 2321 /* Current message is probably either
Jasper Wallace 2:bbdeda018a3c 2322 * CertificateRequest or ServerHelloDone */
Jasper Wallace 2:bbdeda018a3c 2323 ssl->keep_current_message = 1;
markrad 0:cdf462088d13 2324 goto exit;
markrad 0:cdf462088d13 2325 }
markrad 0:cdf462088d13 2326
Jasper Wallace 2:bbdeda018a3c 2327 MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must "
Jasper Wallace 2:bbdeda018a3c 2328 "not be skipped" ) );
Jasper Wallace 2:bbdeda018a3c 2329 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2330 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
Jasper Wallace 2:bbdeda018a3c 2331
markrad 0:cdf462088d13 2332 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2333 }
markrad 0:cdf462088d13 2334
markrad 0:cdf462088d13 2335 p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
markrad 0:cdf462088d13 2336 end = ssl->in_msg + ssl->in_hslen;
markrad 0:cdf462088d13 2337 MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
markrad 0:cdf462088d13 2338
markrad 0:cdf462088d13 2339 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
markrad 0:cdf462088d13 2340 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
markrad 0:cdf462088d13 2341 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
markrad 0:cdf462088d13 2342 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
markrad 0:cdf462088d13 2343 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
markrad 0:cdf462088d13 2344 {
markrad 0:cdf462088d13 2345 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
markrad 0:cdf462088d13 2346 {
markrad 0:cdf462088d13 2347 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2348 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2349 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2350 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2351 }
markrad 0:cdf462088d13 2352 } /* FALLTROUGH */
markrad 0:cdf462088d13 2353 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
markrad 0:cdf462088d13 2354
markrad 0:cdf462088d13 2355 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
markrad 0:cdf462088d13 2356 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
markrad 0:cdf462088d13 2357 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
markrad 0:cdf462088d13 2358 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
markrad 0:cdf462088d13 2359 ; /* nothing more to do */
markrad 0:cdf462088d13 2360 else
markrad 0:cdf462088d13 2361 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
markrad 0:cdf462088d13 2362 MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
markrad 0:cdf462088d13 2363 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2364 defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
markrad 0:cdf462088d13 2365 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
markrad 0:cdf462088d13 2366 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
markrad 0:cdf462088d13 2367 {
markrad 0:cdf462088d13 2368 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
markrad 0:cdf462088d13 2369 {
markrad 0:cdf462088d13 2370 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2371 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2372 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2373 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2374 }
markrad 0:cdf462088d13 2375 }
markrad 0:cdf462088d13 2376 else
markrad 0:cdf462088d13 2377 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2378 MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
markrad 0:cdf462088d13 2379 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2380 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
markrad 0:cdf462088d13 2381 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
markrad 0:cdf462088d13 2382 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
markrad 0:cdf462088d13 2383 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
markrad 0:cdf462088d13 2384 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
markrad 0:cdf462088d13 2385 {
markrad 0:cdf462088d13 2386 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
markrad 0:cdf462088d13 2387 {
markrad 0:cdf462088d13 2388 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2389 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2390 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2391 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2392 }
markrad 0:cdf462088d13 2393 }
markrad 0:cdf462088d13 2394 else
markrad 0:cdf462088d13 2395 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2396 MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
markrad 0:cdf462088d13 2397 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
markrad 0:cdf462088d13 2398 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 2399 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
markrad 0:cdf462088d13 2400 {
markrad 0:cdf462088d13 2401 ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
markrad 0:cdf462088d13 2402 p, end - p );
markrad 0:cdf462088d13 2403 if( ret != 0 )
markrad 0:cdf462088d13 2404 {
markrad 0:cdf462088d13 2405 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
Jasper Wallace 2:bbdeda018a3c 2406 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2407 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2408 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2409 }
markrad 0:cdf462088d13 2410 }
markrad 0:cdf462088d13 2411 else
markrad 0:cdf462088d13 2412 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
markrad 0:cdf462088d13 2413 {
markrad 0:cdf462088d13 2414 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 2415 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 2416 }
markrad 0:cdf462088d13 2417
Jasper Wallace 2:bbdeda018a3c 2418 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
Jasper Wallace 2:bbdeda018a3c 2419 if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
markrad 0:cdf462088d13 2420 {
markrad 0:cdf462088d13 2421 size_t sig_len, hashlen;
markrad 0:cdf462088d13 2422 unsigned char hash[64];
markrad 0:cdf462088d13 2423 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
markrad 0:cdf462088d13 2424 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
markrad 0:cdf462088d13 2425 unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
markrad 0:cdf462088d13 2426 size_t params_len = p - params;
markrad 0:cdf462088d13 2427
markrad 0:cdf462088d13 2428 /*
markrad 0:cdf462088d13 2429 * Handle the digitally-signed structure
markrad 0:cdf462088d13 2430 */
markrad 0:cdf462088d13 2431 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 2432 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 2433 {
markrad 0:cdf462088d13 2434 if( ssl_parse_signature_algorithm( ssl, &p, end,
markrad 0:cdf462088d13 2435 &md_alg, &pk_alg ) != 0 )
markrad 0:cdf462088d13 2436 {
markrad 0:cdf462088d13 2437 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2438 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2439 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2440 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2441 }
markrad 0:cdf462088d13 2442
markrad 0:cdf462088d13 2443 if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
markrad 0:cdf462088d13 2444 {
markrad 0:cdf462088d13 2445 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2446 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2447 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
markrad 0:cdf462088d13 2448 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2449 }
markrad 0:cdf462088d13 2450 }
markrad 0:cdf462088d13 2451 else
markrad 0:cdf462088d13 2452 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
markrad 0:cdf462088d13 2453 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
markrad 0:cdf462088d13 2454 defined(MBEDTLS_SSL_PROTO_TLS1_1)
markrad 0:cdf462088d13 2455 if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 2456 {
markrad 0:cdf462088d13 2457 pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
markrad 0:cdf462088d13 2458
markrad 0:cdf462088d13 2459 /* Default hash for ECDSA is SHA-1 */
markrad 0:cdf462088d13 2460 if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
markrad 0:cdf462088d13 2461 md_alg = MBEDTLS_MD_SHA1;
markrad 0:cdf462088d13 2462 }
markrad 0:cdf462088d13 2463 else
markrad 0:cdf462088d13 2464 #endif
markrad 0:cdf462088d13 2465 {
markrad 0:cdf462088d13 2466 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 2467 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 2468 }
markrad 0:cdf462088d13 2469
markrad 0:cdf462088d13 2470 /*
markrad 0:cdf462088d13 2471 * Read signature
markrad 0:cdf462088d13 2472 */
markrad 0:cdf462088d13 2473 sig_len = ( p[0] << 8 ) | p[1];
markrad 0:cdf462088d13 2474 p += 2;
markrad 0:cdf462088d13 2475
markrad 0:cdf462088d13 2476 if( end != p + sig_len )
markrad 0:cdf462088d13 2477 {
markrad 0:cdf462088d13 2478 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2479 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2480 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 2481 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
markrad 0:cdf462088d13 2482 }
markrad 0:cdf462088d13 2483
markrad 0:cdf462088d13 2484 MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
markrad 0:cdf462088d13 2485
markrad 0:cdf462088d13 2486 /*
markrad 0:cdf462088d13 2487 * Compute the hash that has been signed
markrad 0:cdf462088d13 2488 */
markrad 0:cdf462088d13 2489 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
markrad 0:cdf462088d13 2490 defined(MBEDTLS_SSL_PROTO_TLS1_1)
markrad 0:cdf462088d13 2491 if( md_alg == MBEDTLS_MD_NONE )
markrad 0:cdf462088d13 2492 {
markrad 0:cdf462088d13 2493 mbedtls_md5_context mbedtls_md5;
markrad 0:cdf462088d13 2494 mbedtls_sha1_context mbedtls_sha1;
markrad 0:cdf462088d13 2495
markrad 0:cdf462088d13 2496 mbedtls_md5_init( &mbedtls_md5 );
markrad 0:cdf462088d13 2497 mbedtls_sha1_init( &mbedtls_sha1 );
markrad 0:cdf462088d13 2498
markrad 0:cdf462088d13 2499 hashlen = 36;
markrad 0:cdf462088d13 2500
markrad 0:cdf462088d13 2501 /*
markrad 0:cdf462088d13 2502 * digitally-signed struct {
markrad 0:cdf462088d13 2503 * opaque md5_hash[16];
markrad 0:cdf462088d13 2504 * opaque sha_hash[20];
markrad 0:cdf462088d13 2505 * };
markrad 0:cdf462088d13 2506 *
markrad 0:cdf462088d13 2507 * md5_hash
markrad 0:cdf462088d13 2508 * MD5(ClientHello.random + ServerHello.random
markrad 0:cdf462088d13 2509 * + ServerParams);
markrad 0:cdf462088d13 2510 * sha_hash
markrad 0:cdf462088d13 2511 * SHA(ClientHello.random + ServerHello.random
markrad 0:cdf462088d13 2512 * + ServerParams);
markrad 0:cdf462088d13 2513 */
markrad 0:cdf462088d13 2514 mbedtls_md5_starts( &mbedtls_md5 );
markrad 0:cdf462088d13 2515 mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
markrad 0:cdf462088d13 2516 mbedtls_md5_update( &mbedtls_md5, params, params_len );
markrad 0:cdf462088d13 2517 mbedtls_md5_finish( &mbedtls_md5, hash );
markrad 0:cdf462088d13 2518
markrad 0:cdf462088d13 2519 mbedtls_sha1_starts( &mbedtls_sha1 );
markrad 0:cdf462088d13 2520 mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
markrad 0:cdf462088d13 2521 mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
markrad 0:cdf462088d13 2522 mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
markrad 0:cdf462088d13 2523
markrad 0:cdf462088d13 2524 mbedtls_md5_free( &mbedtls_md5 );
markrad 0:cdf462088d13 2525 mbedtls_sha1_free( &mbedtls_sha1 );
markrad 0:cdf462088d13 2526 }
markrad 0:cdf462088d13 2527 else
markrad 0:cdf462088d13 2528 #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
markrad 0:cdf462088d13 2529 MBEDTLS_SSL_PROTO_TLS1_1 */
markrad 0:cdf462088d13 2530 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
markrad 0:cdf462088d13 2531 defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 2532 if( md_alg != MBEDTLS_MD_NONE )
markrad 0:cdf462088d13 2533 {
markrad 0:cdf462088d13 2534 mbedtls_md_context_t ctx;
markrad 0:cdf462088d13 2535
markrad 0:cdf462088d13 2536 mbedtls_md_init( &ctx );
markrad 0:cdf462088d13 2537
markrad 0:cdf462088d13 2538 /* Info from md_alg will be used instead */
markrad 0:cdf462088d13 2539 hashlen = 0;
markrad 0:cdf462088d13 2540
markrad 0:cdf462088d13 2541 /*
markrad 0:cdf462088d13 2542 * digitally-signed struct {
markrad 0:cdf462088d13 2543 * opaque client_random[32];
markrad 0:cdf462088d13 2544 * opaque server_random[32];
markrad 0:cdf462088d13 2545 * ServerDHParams params;
markrad 0:cdf462088d13 2546 * };
markrad 0:cdf462088d13 2547 */
markrad 0:cdf462088d13 2548 if( ( ret = mbedtls_md_setup( &ctx,
markrad 0:cdf462088d13 2549 mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
markrad 0:cdf462088d13 2550 {
markrad 0:cdf462088d13 2551 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
Jasper Wallace 2:bbdeda018a3c 2552 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2553 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
markrad 0:cdf462088d13 2554 return( ret );
markrad 0:cdf462088d13 2555 }
markrad 0:cdf462088d13 2556
markrad 0:cdf462088d13 2557 mbedtls_md_starts( &ctx );
markrad 0:cdf462088d13 2558 mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
markrad 0:cdf462088d13 2559 mbedtls_md_update( &ctx, params, params_len );
markrad 0:cdf462088d13 2560 mbedtls_md_finish( &ctx, hash );
markrad 0:cdf462088d13 2561 mbedtls_md_free( &ctx );
markrad 0:cdf462088d13 2562 }
markrad 0:cdf462088d13 2563 else
markrad 0:cdf462088d13 2564 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
markrad 0:cdf462088d13 2565 MBEDTLS_SSL_PROTO_TLS1_2 */
markrad 0:cdf462088d13 2566 {
markrad 0:cdf462088d13 2567 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 2568 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 2569 }
markrad 0:cdf462088d13 2570
markrad 0:cdf462088d13 2571 MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
markrad 0:cdf462088d13 2572 (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
markrad 0:cdf462088d13 2573
markrad 0:cdf462088d13 2574 if( ssl->session_negotiate->peer_cert == NULL )
markrad 0:cdf462088d13 2575 {
markrad 0:cdf462088d13 2576 MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
Jasper Wallace 2:bbdeda018a3c 2577 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2578 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 2579 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2580 }
markrad 0:cdf462088d13 2581
markrad 0:cdf462088d13 2582 /*
markrad 0:cdf462088d13 2583 * Verify signature
markrad 0:cdf462088d13 2584 */
markrad 0:cdf462088d13 2585 if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
markrad 0:cdf462088d13 2586 {
markrad 0:cdf462088d13 2587 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Jasper Wallace 2:bbdeda018a3c 2588 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2589 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
markrad 0:cdf462088d13 2590 return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
markrad 0:cdf462088d13 2591 }
markrad 0:cdf462088d13 2592
markrad 0:cdf462088d13 2593 if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
markrad 0:cdf462088d13 2594 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
markrad 0:cdf462088d13 2595 {
Jasper Wallace 2:bbdeda018a3c 2596 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2597 MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
markrad 0:cdf462088d13 2598 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
markrad 0:cdf462088d13 2599 return( ret );
markrad 0:cdf462088d13 2600 }
markrad 0:cdf462088d13 2601 }
Jasper Wallace 2:bbdeda018a3c 2602 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
markrad 0:cdf462088d13 2603
markrad 0:cdf462088d13 2604 exit:
markrad 0:cdf462088d13 2605 ssl->state++;
markrad 0:cdf462088d13 2606
markrad 0:cdf462088d13 2607 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
markrad 0:cdf462088d13 2608
markrad 0:cdf462088d13 2609 return( 0 );
markrad 0:cdf462088d13 2610 }
markrad 0:cdf462088d13 2611
Jasper Wallace 2:bbdeda018a3c 2612 #if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
markrad 0:cdf462088d13 2613 static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2614 {
Jasper Wallace 2:bbdeda018a3c 2615 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 2616 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 2617
markrad 0:cdf462088d13 2618 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
markrad 0:cdf462088d13 2619
Jasper Wallace 2:bbdeda018a3c 2620 if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
markrad 0:cdf462088d13 2621 {
markrad 0:cdf462088d13 2622 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
markrad 0:cdf462088d13 2623 ssl->state++;
markrad 0:cdf462088d13 2624 return( 0 );
markrad 0:cdf462088d13 2625 }
markrad 0:cdf462088d13 2626
markrad 0:cdf462088d13 2627 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 2628 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 2629 }
Jasper Wallace 2:bbdeda018a3c 2630 #else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
markrad 0:cdf462088d13 2631 static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2632 {
markrad 0:cdf462088d13 2633 int ret;
markrad 0:cdf462088d13 2634 unsigned char *buf;
markrad 0:cdf462088d13 2635 size_t n = 0;
markrad 0:cdf462088d13 2636 size_t cert_type_len = 0, dn_len = 0;
Jasper Wallace 2:bbdeda018a3c 2637 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 2638 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 2639
markrad 0:cdf462088d13 2640 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
markrad 0:cdf462088d13 2641
Jasper Wallace 2:bbdeda018a3c 2642 if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
markrad 0:cdf462088d13 2643 {
markrad 0:cdf462088d13 2644 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
markrad 0:cdf462088d13 2645 ssl->state++;
markrad 0:cdf462088d13 2646 return( 0 );
markrad 0:cdf462088d13 2647 }
markrad 0:cdf462088d13 2648
Jasper Wallace 2:bbdeda018a3c 2649 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
Jasper Wallace 2:bbdeda018a3c 2650 {
Jasper Wallace 2:bbdeda018a3c 2651 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Jasper Wallace 2:bbdeda018a3c 2652 return( ret );
Jasper Wallace 2:bbdeda018a3c 2653 }
Jasper Wallace 2:bbdeda018a3c 2654
Jasper Wallace 2:bbdeda018a3c 2655 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
markrad 0:cdf462088d13 2656 {
Jasper Wallace 2:bbdeda018a3c 2657 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Jasper Wallace 2:bbdeda018a3c 2658 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2659 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
Jasper Wallace 2:bbdeda018a3c 2660 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 2661 }
markrad 0:cdf462088d13 2662
markrad 0:cdf462088d13 2663 ssl->state++;
Jasper Wallace 2:bbdeda018a3c 2664 ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST );
markrad 0:cdf462088d13 2665
markrad 0:cdf462088d13 2666 MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
markrad 0:cdf462088d13 2667 ssl->client_auth ? "a" : "no" ) );
markrad 0:cdf462088d13 2668
markrad 0:cdf462088d13 2669 if( ssl->client_auth == 0 )
Jasper Wallace 2:bbdeda018a3c 2670 {
Jasper Wallace 2:bbdeda018a3c 2671 /* Current message is probably the ServerHelloDone */
Jasper Wallace 2:bbdeda018a3c 2672 ssl->keep_current_message = 1;
markrad 0:cdf462088d13 2673 goto exit;
Jasper Wallace 2:bbdeda018a3c 2674 }
markrad 0:cdf462088d13 2675
markrad 0:cdf462088d13 2676 /*
markrad 0:cdf462088d13 2677 * struct {
markrad 0:cdf462088d13 2678 * ClientCertificateType certificate_types<1..2^8-1>;
markrad 0:cdf462088d13 2679 * SignatureAndHashAlgorithm
markrad 0:cdf462088d13 2680 * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
markrad 0:cdf462088d13 2681 * DistinguishedName certificate_authorities<0..2^16-1>;
markrad 0:cdf462088d13 2682 * } CertificateRequest;
markrad 0:cdf462088d13 2683 *
markrad 0:cdf462088d13 2684 * Since we only support a single certificate on clients, let's just
markrad 0:cdf462088d13 2685 * ignore all the information that's supposed to help us pick a
markrad 0:cdf462088d13 2686 * certificate.
markrad 0:cdf462088d13 2687 *
markrad 0:cdf462088d13 2688 * We could check that our certificate matches the request, and bail out
markrad 0:cdf462088d13 2689 * if it doesn't, but it's simpler to just send the certificate anyway,
markrad 0:cdf462088d13 2690 * and give the server the opportunity to decide if it should terminate
markrad 0:cdf462088d13 2691 * the connection when it doesn't like our certificate.
markrad 0:cdf462088d13 2692 *
markrad 0:cdf462088d13 2693 * Same goes for the hash in TLS 1.2's signature_algorithms: at this
markrad 0:cdf462088d13 2694 * point we only have one hash available (see comments in
markrad 0:cdf462088d13 2695 * write_certificate_verify), so let's just use what we have.
markrad 0:cdf462088d13 2696 *
markrad 0:cdf462088d13 2697 * However, we still minimally parse the message to check it is at least
markrad 0:cdf462088d13 2698 * superficially sane.
markrad 0:cdf462088d13 2699 */
markrad 0:cdf462088d13 2700 buf = ssl->in_msg;
markrad 0:cdf462088d13 2701
markrad 0:cdf462088d13 2702 /* certificate_types */
markrad 0:cdf462088d13 2703 cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
markrad 0:cdf462088d13 2704 n = cert_type_len;
markrad 0:cdf462088d13 2705
markrad 0:cdf462088d13 2706 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
markrad 0:cdf462088d13 2707 {
markrad 0:cdf462088d13 2708 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Jasper Wallace 2:bbdeda018a3c 2709 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2710 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 2711 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
markrad 0:cdf462088d13 2712 }
markrad 0:cdf462088d13 2713
markrad 0:cdf462088d13 2714 /* supported_signature_algorithms */
markrad 0:cdf462088d13 2715 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 2716 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 2717 {
markrad 0:cdf462088d13 2718 size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
markrad 0:cdf462088d13 2719 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
markrad 0:cdf462088d13 2720 #if defined(MBEDTLS_DEBUG_C)
markrad 0:cdf462088d13 2721 unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
markrad 0:cdf462088d13 2722 size_t i;
markrad 0:cdf462088d13 2723
markrad 0:cdf462088d13 2724 for( i = 0; i < sig_alg_len; i += 2 )
markrad 0:cdf462088d13 2725 {
Jasper Wallace 2:bbdeda018a3c 2726 MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
Jasper Wallace 2:bbdeda018a3c 2727 ",%d", sig_alg[i], sig_alg[i + 1] ) );
markrad 0:cdf462088d13 2728 }
markrad 0:cdf462088d13 2729 #endif
markrad 0:cdf462088d13 2730
markrad 0:cdf462088d13 2731 n += 2 + sig_alg_len;
markrad 0:cdf462088d13 2732
markrad 0:cdf462088d13 2733 if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
markrad 0:cdf462088d13 2734 {
markrad 0:cdf462088d13 2735 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Jasper Wallace 2:bbdeda018a3c 2736 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2737 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 2738 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
markrad 0:cdf462088d13 2739 }
markrad 0:cdf462088d13 2740 }
markrad 0:cdf462088d13 2741 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
markrad 0:cdf462088d13 2742
markrad 0:cdf462088d13 2743 /* certificate_authorities */
markrad 0:cdf462088d13 2744 dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
markrad 0:cdf462088d13 2745 | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
markrad 0:cdf462088d13 2746
markrad 0:cdf462088d13 2747 n += dn_len;
markrad 0:cdf462088d13 2748 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
markrad 0:cdf462088d13 2749 {
markrad 0:cdf462088d13 2750 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Jasper Wallace 2:bbdeda018a3c 2751 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2752 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 2753 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
markrad 0:cdf462088d13 2754 }
markrad 0:cdf462088d13 2755
markrad 0:cdf462088d13 2756 exit:
markrad 0:cdf462088d13 2757 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
markrad 0:cdf462088d13 2758
markrad 0:cdf462088d13 2759 return( 0 );
markrad 0:cdf462088d13 2760 }
Jasper Wallace 2:bbdeda018a3c 2761 #endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
markrad 0:cdf462088d13 2762
markrad 0:cdf462088d13 2763 static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2764 {
markrad 0:cdf462088d13 2765 int ret;
markrad 0:cdf462088d13 2766
markrad 0:cdf462088d13 2767 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
markrad 0:cdf462088d13 2768
Jasper Wallace 2:bbdeda018a3c 2769 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 2770 {
Jasper Wallace 2:bbdeda018a3c 2771 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Jasper Wallace 2:bbdeda018a3c 2772 return( ret );
markrad 0:cdf462088d13 2773 }
Jasper Wallace 2:bbdeda018a3c 2774
Jasper Wallace 2:bbdeda018a3c 2775 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
Jasper Wallace 2:bbdeda018a3c 2776 {
Jasper Wallace 2:bbdeda018a3c 2777 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Jasper Wallace 2:bbdeda018a3c 2778 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Jasper Wallace 2:bbdeda018a3c 2779 }
markrad 0:cdf462088d13 2780
markrad 0:cdf462088d13 2781 if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
markrad 0:cdf462088d13 2782 ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
markrad 0:cdf462088d13 2783 {
markrad 0:cdf462088d13 2784 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Jasper Wallace 2:bbdeda018a3c 2785 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 2786 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 2787 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
markrad 0:cdf462088d13 2788 }
markrad 0:cdf462088d13 2789
markrad 0:cdf462088d13 2790 ssl->state++;
markrad 0:cdf462088d13 2791
markrad 0:cdf462088d13 2792 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 2793 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
markrad 0:cdf462088d13 2794 mbedtls_ssl_recv_flight_completed( ssl );
markrad 0:cdf462088d13 2795 #endif
markrad 0:cdf462088d13 2796
markrad 0:cdf462088d13 2797 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
markrad 0:cdf462088d13 2798
markrad 0:cdf462088d13 2799 return( 0 );
markrad 0:cdf462088d13 2800 }
markrad 0:cdf462088d13 2801
markrad 0:cdf462088d13 2802 static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 2803 {
markrad 0:cdf462088d13 2804 int ret;
markrad 0:cdf462088d13 2805 size_t i, n;
Jasper Wallace 2:bbdeda018a3c 2806 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 2807 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 2808
markrad 0:cdf462088d13 2809 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
markrad 0:cdf462088d13 2810
markrad 0:cdf462088d13 2811 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
markrad 0:cdf462088d13 2812 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
markrad 0:cdf462088d13 2813 {
markrad 0:cdf462088d13 2814 /*
markrad 0:cdf462088d13 2815 * DHM key exchange -- send G^X mod P
markrad 0:cdf462088d13 2816 */
markrad 0:cdf462088d13 2817 n = ssl->handshake->dhm_ctx.len;
markrad 0:cdf462088d13 2818
markrad 0:cdf462088d13 2819 ssl->out_msg[4] = (unsigned char)( n >> 8 );
markrad 0:cdf462088d13 2820 ssl->out_msg[5] = (unsigned char)( n );
markrad 0:cdf462088d13 2821 i = 6;
markrad 0:cdf462088d13 2822
markrad 0:cdf462088d13 2823 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
markrad 0:cdf462088d13 2824 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
markrad 0:cdf462088d13 2825 &ssl->out_msg[i], n,
markrad 0:cdf462088d13 2826 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 2827 if( ret != 0 )
markrad 0:cdf462088d13 2828 {
markrad 0:cdf462088d13 2829 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
markrad 0:cdf462088d13 2830 return( ret );
markrad 0:cdf462088d13 2831 }
markrad 0:cdf462088d13 2832
markrad 0:cdf462088d13 2833 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
markrad 0:cdf462088d13 2834 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
markrad 0:cdf462088d13 2835
markrad 0:cdf462088d13 2836 if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
markrad 0:cdf462088d13 2837 ssl->handshake->premaster,
markrad 0:cdf462088d13 2838 MBEDTLS_PREMASTER_SIZE,
markrad 0:cdf462088d13 2839 &ssl->handshake->pmslen,
markrad 0:cdf462088d13 2840 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
markrad 0:cdf462088d13 2841 {
markrad 0:cdf462088d13 2842 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
markrad 0:cdf462088d13 2843 return( ret );
markrad 0:cdf462088d13 2844 }
markrad 0:cdf462088d13 2845
markrad 0:cdf462088d13 2846 MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
markrad 0:cdf462088d13 2847 }
markrad 0:cdf462088d13 2848 else
markrad 0:cdf462088d13 2849 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
markrad 0:cdf462088d13 2850 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
markrad 0:cdf462088d13 2851 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
markrad 0:cdf462088d13 2852 defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
markrad 0:cdf462088d13 2853 defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
markrad 0:cdf462088d13 2854 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
markrad 0:cdf462088d13 2855 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
markrad 0:cdf462088d13 2856 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
markrad 0:cdf462088d13 2857 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
markrad 0:cdf462088d13 2858 {
markrad 0:cdf462088d13 2859 /*
markrad 0:cdf462088d13 2860 * ECDH key exchange -- send client public value
markrad 0:cdf462088d13 2861 */
markrad 0:cdf462088d13 2862 i = 4;
markrad 0:cdf462088d13 2863
markrad 0:cdf462088d13 2864 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
markrad 0:cdf462088d13 2865 &n,
markrad 0:cdf462088d13 2866 &ssl->out_msg[i], 1000,
markrad 0:cdf462088d13 2867 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 2868 if( ret != 0 )
markrad 0:cdf462088d13 2869 {
markrad 0:cdf462088d13 2870 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
markrad 0:cdf462088d13 2871 return( ret );
markrad 0:cdf462088d13 2872 }
markrad 0:cdf462088d13 2873
markrad 0:cdf462088d13 2874 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
markrad 0:cdf462088d13 2875
markrad 0:cdf462088d13 2876 if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
markrad 0:cdf462088d13 2877 &ssl->handshake->pmslen,
markrad 0:cdf462088d13 2878 ssl->handshake->premaster,
markrad 0:cdf462088d13 2879 MBEDTLS_MPI_MAX_SIZE,
markrad 0:cdf462088d13 2880 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
markrad 0:cdf462088d13 2881 {
markrad 0:cdf462088d13 2882 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
markrad 0:cdf462088d13 2883 return( ret );
markrad 0:cdf462088d13 2884 }
markrad 0:cdf462088d13 2885
markrad 0:cdf462088d13 2886 MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
markrad 0:cdf462088d13 2887 }
markrad 0:cdf462088d13 2888 else
markrad 0:cdf462088d13 2889 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
markrad 0:cdf462088d13 2890 MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
markrad 0:cdf462088d13 2891 MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
markrad 0:cdf462088d13 2892 MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
markrad 0:cdf462088d13 2893 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Jasper Wallace 2:bbdeda018a3c 2894 if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
markrad 0:cdf462088d13 2895 {
markrad 0:cdf462088d13 2896 /*
markrad 0:cdf462088d13 2897 * opaque psk_identity<0..2^16-1>;
markrad 0:cdf462088d13 2898 */
markrad 0:cdf462088d13 2899 if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
markrad 0:cdf462088d13 2900 {
markrad 0:cdf462088d13 2901 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
markrad 0:cdf462088d13 2902 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
markrad 0:cdf462088d13 2903 }
markrad 0:cdf462088d13 2904
markrad 0:cdf462088d13 2905 i = 4;
markrad 0:cdf462088d13 2906 n = ssl->conf->psk_identity_len;
markrad 0:cdf462088d13 2907
markrad 0:cdf462088d13 2908 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
markrad 0:cdf462088d13 2909 {
markrad 0:cdf462088d13 2910 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
markrad 0:cdf462088d13 2911 "SSL buffer too short" ) );
markrad 0:cdf462088d13 2912 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
markrad 0:cdf462088d13 2913 }
markrad 0:cdf462088d13 2914
markrad 0:cdf462088d13 2915 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
markrad 0:cdf462088d13 2916 ssl->out_msg[i++] = (unsigned char)( n );
markrad 0:cdf462088d13 2917
markrad 0:cdf462088d13 2918 memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
markrad 0:cdf462088d13 2919 i += ssl->conf->psk_identity_len;
markrad 0:cdf462088d13 2920
markrad 0:cdf462088d13 2921 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
markrad 0:cdf462088d13 2922 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
markrad 0:cdf462088d13 2923 {
markrad 0:cdf462088d13 2924 n = 0;
markrad 0:cdf462088d13 2925 }
markrad 0:cdf462088d13 2926 else
markrad 0:cdf462088d13 2927 #endif
markrad 0:cdf462088d13 2928 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
markrad 0:cdf462088d13 2929 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
markrad 0:cdf462088d13 2930 {
markrad 0:cdf462088d13 2931 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
markrad 0:cdf462088d13 2932 return( ret );
markrad 0:cdf462088d13 2933 }
markrad 0:cdf462088d13 2934 else
markrad 0:cdf462088d13 2935 #endif
markrad 0:cdf462088d13 2936 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
markrad 0:cdf462088d13 2937 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
markrad 0:cdf462088d13 2938 {
markrad 0:cdf462088d13 2939 /*
markrad 0:cdf462088d13 2940 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
markrad 0:cdf462088d13 2941 */
markrad 0:cdf462088d13 2942 n = ssl->handshake->dhm_ctx.len;
markrad 0:cdf462088d13 2943
markrad 0:cdf462088d13 2944 if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
markrad 0:cdf462088d13 2945 {
markrad 0:cdf462088d13 2946 MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
markrad 0:cdf462088d13 2947 " or SSL buffer too short" ) );
markrad 0:cdf462088d13 2948 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
markrad 0:cdf462088d13 2949 }
markrad 0:cdf462088d13 2950
markrad 0:cdf462088d13 2951 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
markrad 0:cdf462088d13 2952 ssl->out_msg[i++] = (unsigned char)( n );
markrad 0:cdf462088d13 2953
markrad 0:cdf462088d13 2954 ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
markrad 0:cdf462088d13 2955 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
markrad 0:cdf462088d13 2956 &ssl->out_msg[i], n,
markrad 0:cdf462088d13 2957 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 2958 if( ret != 0 )
markrad 0:cdf462088d13 2959 {
markrad 0:cdf462088d13 2960 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
markrad 0:cdf462088d13 2961 return( ret );
markrad 0:cdf462088d13 2962 }
markrad 0:cdf462088d13 2963 }
markrad 0:cdf462088d13 2964 else
markrad 0:cdf462088d13 2965 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
markrad 0:cdf462088d13 2966 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
markrad 0:cdf462088d13 2967 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
markrad 0:cdf462088d13 2968 {
markrad 0:cdf462088d13 2969 /*
markrad 0:cdf462088d13 2970 * ClientECDiffieHellmanPublic public;
markrad 0:cdf462088d13 2971 */
markrad 0:cdf462088d13 2972 ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
markrad 0:cdf462088d13 2973 &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
markrad 0:cdf462088d13 2974 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 2975 if( ret != 0 )
markrad 0:cdf462088d13 2976 {
markrad 0:cdf462088d13 2977 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
markrad 0:cdf462088d13 2978 return( ret );
markrad 0:cdf462088d13 2979 }
markrad 0:cdf462088d13 2980
markrad 0:cdf462088d13 2981 MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
markrad 0:cdf462088d13 2982 }
markrad 0:cdf462088d13 2983 else
markrad 0:cdf462088d13 2984 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
markrad 0:cdf462088d13 2985 {
markrad 0:cdf462088d13 2986 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 2987 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 2988 }
markrad 0:cdf462088d13 2989
markrad 0:cdf462088d13 2990 if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
markrad 0:cdf462088d13 2991 ciphersuite_info->key_exchange ) ) != 0 )
markrad 0:cdf462088d13 2992 {
markrad 0:cdf462088d13 2993 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
markrad 0:cdf462088d13 2994 return( ret );
markrad 0:cdf462088d13 2995 }
markrad 0:cdf462088d13 2996 }
markrad 0:cdf462088d13 2997 else
markrad 0:cdf462088d13 2998 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
markrad 0:cdf462088d13 2999 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
markrad 0:cdf462088d13 3000 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
markrad 0:cdf462088d13 3001 {
markrad 0:cdf462088d13 3002 i = 4;
markrad 0:cdf462088d13 3003 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
markrad 0:cdf462088d13 3004 return( ret );
markrad 0:cdf462088d13 3005 }
markrad 0:cdf462088d13 3006 else
markrad 0:cdf462088d13 3007 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
markrad 0:cdf462088d13 3008 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
markrad 0:cdf462088d13 3009 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
markrad 0:cdf462088d13 3010 {
markrad 0:cdf462088d13 3011 i = 4;
markrad 0:cdf462088d13 3012
markrad 0:cdf462088d13 3013 ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
markrad 0:cdf462088d13 3014 ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
markrad 0:cdf462088d13 3015 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 3016 if( ret != 0 )
markrad 0:cdf462088d13 3017 {
markrad 0:cdf462088d13 3018 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
markrad 0:cdf462088d13 3019 return( ret );
markrad 0:cdf462088d13 3020 }
markrad 0:cdf462088d13 3021
markrad 0:cdf462088d13 3022 ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
markrad 0:cdf462088d13 3023 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
markrad 0:cdf462088d13 3024 ssl->conf->f_rng, ssl->conf->p_rng );
markrad 0:cdf462088d13 3025 if( ret != 0 )
markrad 0:cdf462088d13 3026 {
markrad 0:cdf462088d13 3027 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
markrad 0:cdf462088d13 3028 return( ret );
markrad 0:cdf462088d13 3029 }
markrad 0:cdf462088d13 3030 }
markrad 0:cdf462088d13 3031 else
markrad 0:cdf462088d13 3032 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
markrad 0:cdf462088d13 3033 {
markrad 0:cdf462088d13 3034 ((void) ciphersuite_info);
markrad 0:cdf462088d13 3035 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 3036 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 3037 }
markrad 0:cdf462088d13 3038
markrad 0:cdf462088d13 3039 ssl->out_msglen = i + n;
markrad 0:cdf462088d13 3040 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
markrad 0:cdf462088d13 3041 ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
markrad 0:cdf462088d13 3042
markrad 0:cdf462088d13 3043 ssl->state++;
markrad 0:cdf462088d13 3044
markrad 0:cdf462088d13 3045 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 3046 {
markrad 0:cdf462088d13 3047 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
markrad 0:cdf462088d13 3048 return( ret );
markrad 0:cdf462088d13 3049 }
markrad 0:cdf462088d13 3050
markrad 0:cdf462088d13 3051 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
markrad 0:cdf462088d13 3052
markrad 0:cdf462088d13 3053 return( 0 );
markrad 0:cdf462088d13 3054 }
markrad 0:cdf462088d13 3055
markrad 0:cdf462088d13 3056 #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
markrad 0:cdf462088d13 3057 !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
markrad 0:cdf462088d13 3058 !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
markrad 0:cdf462088d13 3059 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
markrad 0:cdf462088d13 3060 !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
markrad 0:cdf462088d13 3061 !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
markrad 0:cdf462088d13 3062 static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 3063 {
Jasper Wallace 2:bbdeda018a3c 3064 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 3065 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 3066 int ret;
markrad 0:cdf462088d13 3067
markrad 0:cdf462088d13 3068 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
markrad 0:cdf462088d13 3069
markrad 0:cdf462088d13 3070 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
markrad 0:cdf462088d13 3071 {
markrad 0:cdf462088d13 3072 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
markrad 0:cdf462088d13 3073 return( ret );
markrad 0:cdf462088d13 3074 }
markrad 0:cdf462088d13 3075
markrad 0:cdf462088d13 3076 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
markrad 0:cdf462088d13 3077 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
markrad 0:cdf462088d13 3078 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
markrad 0:cdf462088d13 3079 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
markrad 0:cdf462088d13 3080 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
markrad 0:cdf462088d13 3081 {
markrad 0:cdf462088d13 3082 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
markrad 0:cdf462088d13 3083 ssl->state++;
markrad 0:cdf462088d13 3084 return( 0 );
markrad 0:cdf462088d13 3085 }
markrad 0:cdf462088d13 3086
markrad 0:cdf462088d13 3087 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 3088 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 3089 }
markrad 0:cdf462088d13 3090 #else
markrad 0:cdf462088d13 3091 static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 3092 {
markrad 0:cdf462088d13 3093 int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Jasper Wallace 2:bbdeda018a3c 3094 const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
Jasper Wallace 2:bbdeda018a3c 3095 ssl->transform_negotiate->ciphersuite_info;
markrad 0:cdf462088d13 3096 size_t n = 0, offset = 0;
markrad 0:cdf462088d13 3097 unsigned char hash[48];
markrad 0:cdf462088d13 3098 unsigned char *hash_start = hash;
markrad 0:cdf462088d13 3099 mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
markrad 0:cdf462088d13 3100 unsigned int hashlen;
markrad 0:cdf462088d13 3101
markrad 0:cdf462088d13 3102 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
markrad 0:cdf462088d13 3103
markrad 0:cdf462088d13 3104 if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
markrad 0:cdf462088d13 3105 {
markrad 0:cdf462088d13 3106 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
markrad 0:cdf462088d13 3107 return( ret );
markrad 0:cdf462088d13 3108 }
markrad 0:cdf462088d13 3109
markrad 0:cdf462088d13 3110 if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
markrad 0:cdf462088d13 3111 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
markrad 0:cdf462088d13 3112 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
markrad 0:cdf462088d13 3113 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
markrad 0:cdf462088d13 3114 ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
markrad 0:cdf462088d13 3115 {
markrad 0:cdf462088d13 3116 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
markrad 0:cdf462088d13 3117 ssl->state++;
markrad 0:cdf462088d13 3118 return( 0 );
markrad 0:cdf462088d13 3119 }
markrad 0:cdf462088d13 3120
markrad 0:cdf462088d13 3121 if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
markrad 0:cdf462088d13 3122 {
markrad 0:cdf462088d13 3123 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
markrad 0:cdf462088d13 3124 ssl->state++;
markrad 0:cdf462088d13 3125 return( 0 );
markrad 0:cdf462088d13 3126 }
markrad 0:cdf462088d13 3127
markrad 0:cdf462088d13 3128 if( mbedtls_ssl_own_key( ssl ) == NULL )
markrad 0:cdf462088d13 3129 {
markrad 0:cdf462088d13 3130 MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
markrad 0:cdf462088d13 3131 return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
markrad 0:cdf462088d13 3132 }
markrad 0:cdf462088d13 3133
markrad 0:cdf462088d13 3134 /*
markrad 0:cdf462088d13 3135 * Make an RSA signature of the handshake digests
markrad 0:cdf462088d13 3136 */
markrad 0:cdf462088d13 3137 ssl->handshake->calc_verify( ssl, hash );
markrad 0:cdf462088d13 3138
markrad 0:cdf462088d13 3139 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
markrad 0:cdf462088d13 3140 defined(MBEDTLS_SSL_PROTO_TLS1_1)
markrad 0:cdf462088d13 3141 if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 3142 {
markrad 0:cdf462088d13 3143 /*
markrad 0:cdf462088d13 3144 * digitally-signed struct {
markrad 0:cdf462088d13 3145 * opaque md5_hash[16];
markrad 0:cdf462088d13 3146 * opaque sha_hash[20];
markrad 0:cdf462088d13 3147 * };
markrad 0:cdf462088d13 3148 *
markrad 0:cdf462088d13 3149 * md5_hash
markrad 0:cdf462088d13 3150 * MD5(handshake_messages);
markrad 0:cdf462088d13 3151 *
markrad 0:cdf462088d13 3152 * sha_hash
markrad 0:cdf462088d13 3153 * SHA(handshake_messages);
markrad 0:cdf462088d13 3154 */
markrad 0:cdf462088d13 3155 hashlen = 36;
markrad 0:cdf462088d13 3156 md_alg = MBEDTLS_MD_NONE;
markrad 0:cdf462088d13 3157
markrad 0:cdf462088d13 3158 /*
markrad 0:cdf462088d13 3159 * For ECDSA, default hash is SHA-1 only
markrad 0:cdf462088d13 3160 */
markrad 0:cdf462088d13 3161 if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
markrad 0:cdf462088d13 3162 {
markrad 0:cdf462088d13 3163 hash_start += 16;
markrad 0:cdf462088d13 3164 hashlen -= 16;
markrad 0:cdf462088d13 3165 md_alg = MBEDTLS_MD_SHA1;
markrad 0:cdf462088d13 3166 }
markrad 0:cdf462088d13 3167 }
markrad 0:cdf462088d13 3168 else
markrad 0:cdf462088d13 3169 #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
markrad 0:cdf462088d13 3170 MBEDTLS_SSL_PROTO_TLS1_1 */
markrad 0:cdf462088d13 3171 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
markrad 0:cdf462088d13 3172 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
markrad 0:cdf462088d13 3173 {
markrad 0:cdf462088d13 3174 /*
markrad 0:cdf462088d13 3175 * digitally-signed struct {
markrad 0:cdf462088d13 3176 * opaque handshake_messages[handshake_messages_length];
markrad 0:cdf462088d13 3177 * };
markrad 0:cdf462088d13 3178 *
markrad 0:cdf462088d13 3179 * Taking shortcut here. We assume that the server always allows the
markrad 0:cdf462088d13 3180 * PRF Hash function and has sent it in the allowed signature
markrad 0:cdf462088d13 3181 * algorithms list received in the Certificate Request message.
markrad 0:cdf462088d13 3182 *
markrad 0:cdf462088d13 3183 * Until we encounter a server that does not, we will take this
markrad 0:cdf462088d13 3184 * shortcut.
markrad 0:cdf462088d13 3185 *
markrad 0:cdf462088d13 3186 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
markrad 0:cdf462088d13 3187 * in order to satisfy 'weird' needs from the server side.
markrad 0:cdf462088d13 3188 */
markrad 0:cdf462088d13 3189 if( ssl->transform_negotiate->ciphersuite_info->mac ==
markrad 0:cdf462088d13 3190 MBEDTLS_MD_SHA384 )
markrad 0:cdf462088d13 3191 {
markrad 0:cdf462088d13 3192 md_alg = MBEDTLS_MD_SHA384;
markrad 0:cdf462088d13 3193 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
markrad 0:cdf462088d13 3194 }
markrad 0:cdf462088d13 3195 else
markrad 0:cdf462088d13 3196 {
markrad 0:cdf462088d13 3197 md_alg = MBEDTLS_MD_SHA256;
markrad 0:cdf462088d13 3198 ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
markrad 0:cdf462088d13 3199 }
markrad 0:cdf462088d13 3200 ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
markrad 0:cdf462088d13 3201
markrad 0:cdf462088d13 3202 /* Info from md_alg will be used instead */
markrad 0:cdf462088d13 3203 hashlen = 0;
markrad 0:cdf462088d13 3204 offset = 2;
markrad 0:cdf462088d13 3205 }
markrad 0:cdf462088d13 3206 else
markrad 0:cdf462088d13 3207 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
markrad 0:cdf462088d13 3208 {
markrad 0:cdf462088d13 3209 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
markrad 0:cdf462088d13 3210 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
markrad 0:cdf462088d13 3211 }
markrad 0:cdf462088d13 3212
markrad 0:cdf462088d13 3213 if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
markrad 0:cdf462088d13 3214 ssl->out_msg + 6 + offset, &n,
markrad 0:cdf462088d13 3215 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
markrad 0:cdf462088d13 3216 {
markrad 0:cdf462088d13 3217 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
markrad 0:cdf462088d13 3218 return( ret );
markrad 0:cdf462088d13 3219 }
markrad 0:cdf462088d13 3220
markrad 0:cdf462088d13 3221 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
markrad 0:cdf462088d13 3222 ssl->out_msg[5 + offset] = (unsigned char)( n );
markrad 0:cdf462088d13 3223
markrad 0:cdf462088d13 3224 ssl->out_msglen = 6 + n + offset;
markrad 0:cdf462088d13 3225 ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
markrad 0:cdf462088d13 3226 ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
markrad 0:cdf462088d13 3227
markrad 0:cdf462088d13 3228 ssl->state++;
markrad 0:cdf462088d13 3229
markrad 0:cdf462088d13 3230 if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 3231 {
markrad 0:cdf462088d13 3232 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
markrad 0:cdf462088d13 3233 return( ret );
markrad 0:cdf462088d13 3234 }
markrad 0:cdf462088d13 3235
markrad 0:cdf462088d13 3236 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
markrad 0:cdf462088d13 3237
markrad 0:cdf462088d13 3238 return( ret );
markrad 0:cdf462088d13 3239 }
markrad 0:cdf462088d13 3240 #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
markrad 0:cdf462088d13 3241 !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
markrad 0:cdf462088d13 3242 !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
markrad 0:cdf462088d13 3243 !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
markrad 0:cdf462088d13 3244 !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
markrad 0:cdf462088d13 3245 !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
markrad 0:cdf462088d13 3246
markrad 0:cdf462088d13 3247 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 3248 static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 3249 {
markrad 0:cdf462088d13 3250 int ret;
markrad 0:cdf462088d13 3251 uint32_t lifetime;
markrad 0:cdf462088d13 3252 size_t ticket_len;
markrad 0:cdf462088d13 3253 unsigned char *ticket;
markrad 0:cdf462088d13 3254 const unsigned char *msg;
markrad 0:cdf462088d13 3255
markrad 0:cdf462088d13 3256 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
markrad 0:cdf462088d13 3257
markrad 0:cdf462088d13 3258 if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
markrad 0:cdf462088d13 3259 {
markrad 0:cdf462088d13 3260 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
markrad 0:cdf462088d13 3261 return( ret );
markrad 0:cdf462088d13 3262 }
markrad 0:cdf462088d13 3263
markrad 0:cdf462088d13 3264 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
markrad 0:cdf462088d13 3265 {
markrad 0:cdf462088d13 3266 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
Jasper Wallace 2:bbdeda018a3c 3267 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 3268 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 3269 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
markrad 0:cdf462088d13 3270 }
markrad 0:cdf462088d13 3271
markrad 0:cdf462088d13 3272 /*
markrad 0:cdf462088d13 3273 * struct {
markrad 0:cdf462088d13 3274 * uint32 ticket_lifetime_hint;
markrad 0:cdf462088d13 3275 * opaque ticket<0..2^16-1>;
markrad 0:cdf462088d13 3276 * } NewSessionTicket;
markrad 0:cdf462088d13 3277 *
markrad 0:cdf462088d13 3278 * 0 . 3 ticket_lifetime_hint
markrad 0:cdf462088d13 3279 * 4 . 5 ticket_len (n)
markrad 0:cdf462088d13 3280 * 6 . 5+n ticket content
markrad 0:cdf462088d13 3281 */
markrad 0:cdf462088d13 3282 if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
markrad 0:cdf462088d13 3283 ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
markrad 0:cdf462088d13 3284 {
markrad 0:cdf462088d13 3285 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
Jasper Wallace 2:bbdeda018a3c 3286 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 3287 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 3288 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
markrad 0:cdf462088d13 3289 }
markrad 0:cdf462088d13 3290
markrad 0:cdf462088d13 3291 msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
markrad 0:cdf462088d13 3292
markrad 0:cdf462088d13 3293 lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
markrad 0:cdf462088d13 3294 ( msg[2] << 8 ) | ( msg[3] );
markrad 0:cdf462088d13 3295
markrad 0:cdf462088d13 3296 ticket_len = ( msg[4] << 8 ) | ( msg[5] );
markrad 0:cdf462088d13 3297
markrad 0:cdf462088d13 3298 if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
markrad 0:cdf462088d13 3299 {
markrad 0:cdf462088d13 3300 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
Jasper Wallace 2:bbdeda018a3c 3301 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 3302 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
markrad 0:cdf462088d13 3303 return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
markrad 0:cdf462088d13 3304 }
markrad 0:cdf462088d13 3305
markrad 0:cdf462088d13 3306 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
markrad 0:cdf462088d13 3307
markrad 0:cdf462088d13 3308 /* We're not waiting for a NewSessionTicket message any more */
markrad 0:cdf462088d13 3309 ssl->handshake->new_session_ticket = 0;
markrad 0:cdf462088d13 3310 ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
markrad 0:cdf462088d13 3311
markrad 0:cdf462088d13 3312 /*
markrad 0:cdf462088d13 3313 * Zero-length ticket means the server changed his mind and doesn't want
markrad 0:cdf462088d13 3314 * to send a ticket after all, so just forget it
markrad 0:cdf462088d13 3315 */
markrad 0:cdf462088d13 3316 if( ticket_len == 0 )
markrad 0:cdf462088d13 3317 return( 0 );
markrad 0:cdf462088d13 3318
markrad 0:cdf462088d13 3319 mbedtls_zeroize( ssl->session_negotiate->ticket,
markrad 0:cdf462088d13 3320 ssl->session_negotiate->ticket_len );
markrad 0:cdf462088d13 3321 mbedtls_free( ssl->session_negotiate->ticket );
markrad 0:cdf462088d13 3322 ssl->session_negotiate->ticket = NULL;
markrad 0:cdf462088d13 3323 ssl->session_negotiate->ticket_len = 0;
markrad 0:cdf462088d13 3324
markrad 0:cdf462088d13 3325 if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
markrad 0:cdf462088d13 3326 {
markrad 0:cdf462088d13 3327 MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
Jasper Wallace 2:bbdeda018a3c 3328 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
Jasper Wallace 2:bbdeda018a3c 3329 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
markrad 0:cdf462088d13 3330 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
markrad 0:cdf462088d13 3331 }
markrad 0:cdf462088d13 3332
markrad 0:cdf462088d13 3333 memcpy( ticket, msg + 6, ticket_len );
markrad 0:cdf462088d13 3334
markrad 0:cdf462088d13 3335 ssl->session_negotiate->ticket = ticket;
markrad 0:cdf462088d13 3336 ssl->session_negotiate->ticket_len = ticket_len;
markrad 0:cdf462088d13 3337 ssl->session_negotiate->ticket_lifetime = lifetime;
markrad 0:cdf462088d13 3338
markrad 0:cdf462088d13 3339 /*
markrad 0:cdf462088d13 3340 * RFC 5077 section 3.4:
markrad 0:cdf462088d13 3341 * "If the client receives a session ticket from the server, then it
markrad 0:cdf462088d13 3342 * discards any Session ID that was sent in the ServerHello."
markrad 0:cdf462088d13 3343 */
markrad 0:cdf462088d13 3344 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
markrad 0:cdf462088d13 3345 ssl->session_negotiate->id_len = 0;
markrad 0:cdf462088d13 3346
markrad 0:cdf462088d13 3347 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
markrad 0:cdf462088d13 3348
markrad 0:cdf462088d13 3349 return( 0 );
markrad 0:cdf462088d13 3350 }
markrad 0:cdf462088d13 3351 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
markrad 0:cdf462088d13 3352
markrad 0:cdf462088d13 3353 /*
markrad 0:cdf462088d13 3354 * SSL handshake -- client side -- single step
markrad 0:cdf462088d13 3355 */
markrad 0:cdf462088d13 3356 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
markrad 0:cdf462088d13 3357 {
markrad 0:cdf462088d13 3358 int ret = 0;
markrad 0:cdf462088d13 3359
markrad 0:cdf462088d13 3360 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
markrad 0:cdf462088d13 3361 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
markrad 0:cdf462088d13 3362
markrad 0:cdf462088d13 3363 MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
markrad 0:cdf462088d13 3364
markrad 0:cdf462088d13 3365 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
markrad 0:cdf462088d13 3366 return( ret );
markrad 0:cdf462088d13 3367
markrad 0:cdf462088d13 3368 #if defined(MBEDTLS_SSL_PROTO_DTLS)
markrad 0:cdf462088d13 3369 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
markrad 0:cdf462088d13 3370 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
markrad 0:cdf462088d13 3371 {
markrad 0:cdf462088d13 3372 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
markrad 0:cdf462088d13 3373 return( ret );
markrad 0:cdf462088d13 3374 }
markrad 0:cdf462088d13 3375 #endif
markrad 0:cdf462088d13 3376
markrad 0:cdf462088d13 3377 /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
markrad 0:cdf462088d13 3378 * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
markrad 0:cdf462088d13 3379 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 3380 if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
markrad 0:cdf462088d13 3381 ssl->handshake->new_session_ticket != 0 )
markrad 0:cdf462088d13 3382 {
markrad 0:cdf462088d13 3383 ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
markrad 0:cdf462088d13 3384 }
markrad 0:cdf462088d13 3385 #endif
markrad 0:cdf462088d13 3386
markrad 0:cdf462088d13 3387 switch( ssl->state )
markrad 0:cdf462088d13 3388 {
markrad 0:cdf462088d13 3389 case MBEDTLS_SSL_HELLO_REQUEST:
markrad 0:cdf462088d13 3390 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
markrad 0:cdf462088d13 3391 break;
markrad 0:cdf462088d13 3392
markrad 0:cdf462088d13 3393 /*
markrad 0:cdf462088d13 3394 * ==> ClientHello
markrad 0:cdf462088d13 3395 */
markrad 0:cdf462088d13 3396 case MBEDTLS_SSL_CLIENT_HELLO:
markrad 0:cdf462088d13 3397 ret = ssl_write_client_hello( ssl );
markrad 0:cdf462088d13 3398 break;
markrad 0:cdf462088d13 3399
markrad 0:cdf462088d13 3400 /*
markrad 0:cdf462088d13 3401 * <== ServerHello
markrad 0:cdf462088d13 3402 * Certificate
markrad 0:cdf462088d13 3403 * ( ServerKeyExchange )
markrad 0:cdf462088d13 3404 * ( CertificateRequest )
markrad 0:cdf462088d13 3405 * ServerHelloDone
markrad 0:cdf462088d13 3406 */
markrad 0:cdf462088d13 3407 case MBEDTLS_SSL_SERVER_HELLO:
markrad 0:cdf462088d13 3408 ret = ssl_parse_server_hello( ssl );
markrad 0:cdf462088d13 3409 break;
markrad 0:cdf462088d13 3410
markrad 0:cdf462088d13 3411 case MBEDTLS_SSL_SERVER_CERTIFICATE:
markrad 0:cdf462088d13 3412 ret = mbedtls_ssl_parse_certificate( ssl );
markrad 0:cdf462088d13 3413 break;
markrad 0:cdf462088d13 3414
markrad 0:cdf462088d13 3415 case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
markrad 0:cdf462088d13 3416 ret = ssl_parse_server_key_exchange( ssl );
markrad 0:cdf462088d13 3417 break;
markrad 0:cdf462088d13 3418
markrad 0:cdf462088d13 3419 case MBEDTLS_SSL_CERTIFICATE_REQUEST:
markrad 0:cdf462088d13 3420 ret = ssl_parse_certificate_request( ssl );
markrad 0:cdf462088d13 3421 break;
markrad 0:cdf462088d13 3422
markrad 0:cdf462088d13 3423 case MBEDTLS_SSL_SERVER_HELLO_DONE:
markrad 0:cdf462088d13 3424 ret = ssl_parse_server_hello_done( ssl );
markrad 0:cdf462088d13 3425 break;
markrad 0:cdf462088d13 3426
markrad 0:cdf462088d13 3427 /*
markrad 0:cdf462088d13 3428 * ==> ( Certificate/Alert )
markrad 0:cdf462088d13 3429 * ClientKeyExchange
markrad 0:cdf462088d13 3430 * ( CertificateVerify )
markrad 0:cdf462088d13 3431 * ChangeCipherSpec
markrad 0:cdf462088d13 3432 * Finished
markrad 0:cdf462088d13 3433 */
markrad 0:cdf462088d13 3434 case MBEDTLS_SSL_CLIENT_CERTIFICATE:
markrad 0:cdf462088d13 3435 ret = mbedtls_ssl_write_certificate( ssl );
markrad 0:cdf462088d13 3436 break;
markrad 0:cdf462088d13 3437
markrad 0:cdf462088d13 3438 case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
markrad 0:cdf462088d13 3439 ret = ssl_write_client_key_exchange( ssl );
markrad 0:cdf462088d13 3440 break;
markrad 0:cdf462088d13 3441
markrad 0:cdf462088d13 3442 case MBEDTLS_SSL_CERTIFICATE_VERIFY:
markrad 0:cdf462088d13 3443 ret = ssl_write_certificate_verify( ssl );
markrad 0:cdf462088d13 3444 break;
markrad 0:cdf462088d13 3445
markrad 0:cdf462088d13 3446 case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
markrad 0:cdf462088d13 3447 ret = mbedtls_ssl_write_change_cipher_spec( ssl );
markrad 0:cdf462088d13 3448 break;
markrad 0:cdf462088d13 3449
markrad 0:cdf462088d13 3450 case MBEDTLS_SSL_CLIENT_FINISHED:
markrad 0:cdf462088d13 3451 ret = mbedtls_ssl_write_finished( ssl );
markrad 0:cdf462088d13 3452 break;
markrad 0:cdf462088d13 3453
markrad 0:cdf462088d13 3454 /*
markrad 0:cdf462088d13 3455 * <== ( NewSessionTicket )
markrad 0:cdf462088d13 3456 * ChangeCipherSpec
markrad 0:cdf462088d13 3457 * Finished
markrad 0:cdf462088d13 3458 */
markrad 0:cdf462088d13 3459 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
markrad 0:cdf462088d13 3460 case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
markrad 0:cdf462088d13 3461 ret = ssl_parse_new_session_ticket( ssl );
markrad 0:cdf462088d13 3462 break;
markrad 0:cdf462088d13 3463 #endif
markrad 0:cdf462088d13 3464
markrad 0:cdf462088d13 3465 case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
markrad 0:cdf462088d13 3466 ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
markrad 0:cdf462088d13 3467 break;
markrad 0:cdf462088d13 3468
markrad 0:cdf462088d13 3469 case MBEDTLS_SSL_SERVER_FINISHED:
markrad 0:cdf462088d13 3470 ret = mbedtls_ssl_parse_finished( ssl );
markrad 0:cdf462088d13 3471 break;
markrad 0:cdf462088d13 3472
markrad 0:cdf462088d13 3473 case MBEDTLS_SSL_FLUSH_BUFFERS:
markrad 0:cdf462088d13 3474 MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
markrad 0:cdf462088d13 3475 ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
markrad 0:cdf462088d13 3476 break;
markrad 0:cdf462088d13 3477
markrad 0:cdf462088d13 3478 case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
markrad 0:cdf462088d13 3479 mbedtls_ssl_handshake_wrapup( ssl );
markrad 0:cdf462088d13 3480 break;
markrad 0:cdf462088d13 3481
markrad 0:cdf462088d13 3482 default:
markrad 0:cdf462088d13 3483 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
markrad 0:cdf462088d13 3484 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
markrad 0:cdf462088d13 3485 }
markrad 0:cdf462088d13 3486
markrad 0:cdf462088d13 3487 return( ret );
markrad 0:cdf462088d13 3488 }
markrad 0:cdf462088d13 3489 #endif /* MBEDTLS_SSL_CLI_C */