This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
timbeight
Date:
Thu May 19 16:02:10 2016 +0000
Revision:
1:0ddbe2d3319c
Parent:
0:f7c60d3e7b8a
This is my first commit while in the class.

Who changed what in which revision?

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