mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

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