mbed TLS upgraded to 2.6.0

Fork of mbedtls by Mark Radbourne

Committer:
markrad
Date:
Thu Jan 05 00:18:44 2017 +0000
Revision:
0:cdf462088d13
Child:
2:bbdeda018a3c
Initial commit

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