Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

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