mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

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