Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

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