mbed os with nrf51 internal bandgap enabled to read battery level

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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