mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /*
ansond 0:137634ff4186 2 * SSLv3/TLSv1 client-side functions
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 9 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 10 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 11 * (at your option) any later version.
ansond 0:137634ff4186 12 *
ansond 0:137634ff4186 13 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 16 * GNU General Public License for more details.
ansond 0:137634ff4186 17 *
ansond 0:137634ff4186 18 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 19 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 21 */
ansond 0:137634ff4186 22
ansond 0:137634ff4186 23 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 24 #include "polarssl/config.h"
ansond 0:137634ff4186 25 #else
ansond 0:137634ff4186 26 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 27 #endif
ansond 0:137634ff4186 28
ansond 0:137634ff4186 29 #if defined(POLARSSL_SSL_CLI_C)
ansond 0:137634ff4186 30
ansond 0:137634ff4186 31 #include "polarssl/debug.h"
ansond 0:137634ff4186 32 #include "polarssl/ssl.h"
ansond 0:137634ff4186 33
ansond 0:137634ff4186 34 #include <string.h>
ansond 0:137634ff4186 35
ansond 0:137634ff4186 36 #if defined(POLARSSL_PLATFORM_C)
ansond 0:137634ff4186 37 #include "polarssl/platform.h"
ansond 0:137634ff4186 38 #else
ansond 0:137634ff4186 39 #include <stdlib.h>
ansond 0:137634ff4186 40 #define polarssl_malloc malloc
ansond 0:137634ff4186 41 #define polarssl_free free
ansond 0:137634ff4186 42 #endif
ansond 0:137634ff4186 43
ansond 0:137634ff4186 44 #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
ansond 0:137634ff4186 45 #include <basetsd.h>
ansond 0:137634ff4186 46 typedef UINT32 uint32_t;
ansond 0:137634ff4186 47 #else
ansond 0:137634ff4186 48 #include <inttypes.h>
ansond 0:137634ff4186 49 #endif
ansond 0:137634ff4186 50
ansond 0:137634ff4186 51 #if defined(POLARSSL_HAVE_TIME)
ansond 0:137634ff4186 52 #include <time.h>
ansond 0:137634ff4186 53 #endif
ansond 0:137634ff4186 54
ansond 0:137634ff4186 55 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 56 /* Implementation that should never be optimized out by the compiler */
ansond 0:137634ff4186 57 static void polarssl_zeroize( void *v, size_t n ) {
ansond 0:137634ff4186 58 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
ansond 0:137634ff4186 59 }
ansond 0:137634ff4186 60 #endif
ansond 0:137634ff4186 61
ansond 0:137634ff4186 62 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
ansond 0:137634ff4186 63 static void ssl_write_hostname_ext( ssl_context *ssl,
ansond 0:137634ff4186 64 unsigned char *buf,
ansond 0:137634ff4186 65 size_t *olen )
ansond 0:137634ff4186 66 {
ansond 0:137634ff4186 67 unsigned char *p = buf;
ansond 0:137634ff4186 68
ansond 0:137634ff4186 69 *olen = 0;
ansond 0:137634ff4186 70
ansond 0:137634ff4186 71 if( ssl->hostname == NULL )
ansond 0:137634ff4186 72 return;
ansond 0:137634ff4186 73
ansond 0:137634ff4186 74 SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
ansond 0:137634ff4186 75 ssl->hostname ) );
ansond 0:137634ff4186 76
ansond 0:137634ff4186 77 /*
ansond 0:137634ff4186 78 * struct {
ansond 0:137634ff4186 79 * NameType name_type;
ansond 0:137634ff4186 80 * select (name_type) {
ansond 0:137634ff4186 81 * case host_name: HostName;
ansond 0:137634ff4186 82 * } name;
ansond 0:137634ff4186 83 * } ServerName;
ansond 0:137634ff4186 84 *
ansond 0:137634ff4186 85 * enum {
ansond 0:137634ff4186 86 * host_name(0), (255)
ansond 0:137634ff4186 87 * } NameType;
ansond 0:137634ff4186 88 *
ansond 0:137634ff4186 89 * opaque HostName<1..2^16-1>;
ansond 0:137634ff4186 90 *
ansond 0:137634ff4186 91 * struct {
ansond 0:137634ff4186 92 * ServerName server_name_list<1..2^16-1>
ansond 0:137634ff4186 93 * } ServerNameList;
ansond 0:137634ff4186 94 */
ansond 0:137634ff4186 95 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
ansond 0:137634ff4186 96 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xFF );
ansond 0:137634ff4186 97
ansond 0:137634ff4186 98 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
ansond 0:137634ff4186 99 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF );
ansond 0:137634ff4186 100
ansond 0:137634ff4186 101 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
ansond 0:137634ff4186 102 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF );
ansond 0:137634ff4186 103
ansond 0:137634ff4186 104 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
ansond 0:137634ff4186 105 *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
ansond 0:137634ff4186 106 *p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF );
ansond 0:137634ff4186 107
ansond 0:137634ff4186 108 memcpy( p, ssl->hostname, ssl->hostname_len );
ansond 0:137634ff4186 109
ansond 0:137634ff4186 110 *olen = ssl->hostname_len + 9;
ansond 0:137634ff4186 111 }
ansond 0:137634ff4186 112 #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
ansond 0:137634ff4186 113
ansond 0:137634ff4186 114 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 115 static void ssl_write_renegotiation_ext( ssl_context *ssl,
ansond 0:137634ff4186 116 unsigned char *buf,
ansond 0:137634ff4186 117 size_t *olen )
ansond 0:137634ff4186 118 {
ansond 0:137634ff4186 119 unsigned char *p = buf;
ansond 0:137634ff4186 120
ansond 0:137634ff4186 121 *olen = 0;
ansond 0:137634ff4186 122
ansond 0:137634ff4186 123 if( ssl->renegotiation != SSL_RENEGOTIATION )
ansond 0:137634ff4186 124 return;
ansond 0:137634ff4186 125
ansond 0:137634ff4186 126 SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
ansond 0:137634ff4186 127
ansond 0:137634ff4186 128 /*
ansond 0:137634ff4186 129 * Secure renegotiation
ansond 0:137634ff4186 130 */
ansond 0:137634ff4186 131 *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
ansond 0:137634ff4186 132 *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
ansond 0:137634ff4186 133
ansond 0:137634ff4186 134 *p++ = 0x00;
ansond 0:137634ff4186 135 *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
ansond 0:137634ff4186 136 *p++ = ssl->verify_data_len & 0xFF;
ansond 0:137634ff4186 137
ansond 0:137634ff4186 138 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
ansond 0:137634ff4186 139
ansond 0:137634ff4186 140 *olen = 5 + ssl->verify_data_len;
ansond 0:137634ff4186 141 }
ansond 0:137634ff4186 142 #endif /* POLARSSL_SSL_RENEGOTIATION */
ansond 0:137634ff4186 143
ansond 0:137634ff4186 144 /*
ansond 0:137634ff4186 145 * Only if we handle at least one key exchange that needs signatures.
ansond 0:137634ff4186 146 */
ansond 0:137634ff4186 147 #if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
ansond 0:137634ff4186 148 defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
ansond 0:137634ff4186 149 static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
ansond 0:137634ff4186 150 unsigned char *buf,
ansond 0:137634ff4186 151 size_t *olen )
ansond 0:137634ff4186 152 {
ansond 0:137634ff4186 153 unsigned char *p = buf;
ansond 0:137634ff4186 154 size_t sig_alg_len = 0;
ansond 0:137634ff4186 155 #if defined(POLARSSL_RSA_C) || defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 156 unsigned char *sig_alg_list = buf + 6;
ansond 0:137634ff4186 157 #endif
ansond 0:137634ff4186 158
ansond 0:137634ff4186 159 *olen = 0;
ansond 0:137634ff4186 160
ansond 0:137634ff4186 161 if( ssl->max_minor_ver != SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 162 return;
ansond 0:137634ff4186 163
ansond 0:137634ff4186 164 SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
ansond 0:137634ff4186 165
ansond 0:137634ff4186 166 /*
ansond 0:137634ff4186 167 * Prepare signature_algorithms extension (TLS 1.2)
ansond 0:137634ff4186 168 */
ansond 0:137634ff4186 169 #if defined(POLARSSL_RSA_C)
ansond 0:137634ff4186 170 #if defined(POLARSSL_SHA512_C)
ansond 0:137634ff4186 171 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA512;
ansond 0:137634ff4186 172 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 173 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA384;
ansond 0:137634ff4186 174 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 175 #endif
ansond 0:137634ff4186 176 #if defined(POLARSSL_SHA256_C)
ansond 0:137634ff4186 177 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA256;
ansond 0:137634ff4186 178 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 179 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA224;
ansond 0:137634ff4186 180 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 181 #endif
ansond 0:137634ff4186 182 #if defined(POLARSSL_SHA1_C)
ansond 0:137634ff4186 183 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA1;
ansond 0:137634ff4186 184 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 185 #endif
ansond 0:137634ff4186 186 #if defined(POLARSSL_MD5_C)
ansond 0:137634ff4186 187 sig_alg_list[sig_alg_len++] = SSL_HASH_MD5;
ansond 0:137634ff4186 188 sig_alg_list[sig_alg_len++] = SSL_SIG_RSA;
ansond 0:137634ff4186 189 #endif
ansond 0:137634ff4186 190 #endif /* POLARSSL_RSA_C */
ansond 0:137634ff4186 191 #if defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 192 #if defined(POLARSSL_SHA512_C)
ansond 0:137634ff4186 193 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA512;
ansond 0:137634ff4186 194 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 195 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA384;
ansond 0:137634ff4186 196 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 197 #endif
ansond 0:137634ff4186 198 #if defined(POLARSSL_SHA256_C)
ansond 0:137634ff4186 199 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA256;
ansond 0:137634ff4186 200 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 201 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA224;
ansond 0:137634ff4186 202 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 203 #endif
ansond 0:137634ff4186 204 #if defined(POLARSSL_SHA1_C)
ansond 0:137634ff4186 205 sig_alg_list[sig_alg_len++] = SSL_HASH_SHA1;
ansond 0:137634ff4186 206 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 207 #endif
ansond 0:137634ff4186 208 #if defined(POLARSSL_MD5_C)
ansond 0:137634ff4186 209 sig_alg_list[sig_alg_len++] = SSL_HASH_MD5;
ansond 0:137634ff4186 210 sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA;
ansond 0:137634ff4186 211 #endif
ansond 0:137634ff4186 212 #endif /* POLARSSL_ECDSA_C */
ansond 0:137634ff4186 213
ansond 0:137634ff4186 214 /*
ansond 0:137634ff4186 215 * enum {
ansond 0:137634ff4186 216 * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
ansond 0:137634ff4186 217 * sha512(6), (255)
ansond 0:137634ff4186 218 * } HashAlgorithm;
ansond 0:137634ff4186 219 *
ansond 0:137634ff4186 220 * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
ansond 0:137634ff4186 221 * SignatureAlgorithm;
ansond 0:137634ff4186 222 *
ansond 0:137634ff4186 223 * struct {
ansond 0:137634ff4186 224 * HashAlgorithm hash;
ansond 0:137634ff4186 225 * SignatureAlgorithm signature;
ansond 0:137634ff4186 226 * } SignatureAndHashAlgorithm;
ansond 0:137634ff4186 227 *
ansond 0:137634ff4186 228 * SignatureAndHashAlgorithm
ansond 0:137634ff4186 229 * supported_signature_algorithms<2..2^16-2>;
ansond 0:137634ff4186 230 */
ansond 0:137634ff4186 231 *p++ = (unsigned char)( ( TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
ansond 0:137634ff4186 232 *p++ = (unsigned char)( ( TLS_EXT_SIG_ALG ) & 0xFF );
ansond 0:137634ff4186 233
ansond 0:137634ff4186 234 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
ansond 0:137634ff4186 235 *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
ansond 0:137634ff4186 236
ansond 0:137634ff4186 237 *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
ansond 0:137634ff4186 238 *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
ansond 0:137634ff4186 239
ansond 0:137634ff4186 240 *olen = 6 + sig_alg_len;
ansond 0:137634ff4186 241 }
ansond 0:137634ff4186 242 #endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
ansond 0:137634ff4186 243 POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
ansond 0:137634ff4186 244
ansond 0:137634ff4186 245 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 246 static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl,
ansond 0:137634ff4186 247 unsigned char *buf,
ansond 0:137634ff4186 248 size_t *olen )
ansond 0:137634ff4186 249 {
ansond 0:137634ff4186 250 unsigned char *p = buf;
ansond 0:137634ff4186 251 unsigned char *elliptic_curve_list = p + 6;
ansond 0:137634ff4186 252 size_t elliptic_curve_len = 0;
ansond 0:137634ff4186 253 const ecp_curve_info *info;
ansond 0:137634ff4186 254 #if defined(POLARSSL_SSL_SET_CURVES)
ansond 0:137634ff4186 255 const ecp_group_id *grp_id;
ansond 0:137634ff4186 256 #else
ansond 0:137634ff4186 257 ((void) ssl);
ansond 0:137634ff4186 258 #endif
ansond 0:137634ff4186 259
ansond 0:137634ff4186 260 *olen = 0;
ansond 0:137634ff4186 261
ansond 0:137634ff4186 262 SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
ansond 0:137634ff4186 263
ansond 0:137634ff4186 264 #if defined(POLARSSL_SSL_SET_CURVES)
ansond 0:137634ff4186 265 for( grp_id = ssl->curve_list; *grp_id != POLARSSL_ECP_DP_NONE; grp_id++ )
ansond 0:137634ff4186 266 {
ansond 0:137634ff4186 267 info = ecp_curve_info_from_grp_id( *grp_id );
ansond 0:137634ff4186 268 #else
ansond 0:137634ff4186 269 for( info = ecp_curve_list(); info->grp_id != POLARSSL_ECP_DP_NONE; info++ )
ansond 0:137634ff4186 270 {
ansond 0:137634ff4186 271 #endif
ansond 0:137634ff4186 272
ansond 0:137634ff4186 273 elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
ansond 0:137634ff4186 274 elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
ansond 0:137634ff4186 275 }
ansond 0:137634ff4186 276
ansond 0:137634ff4186 277 if( elliptic_curve_len == 0 )
ansond 0:137634ff4186 278 return;
ansond 0:137634ff4186 279
ansond 0:137634ff4186 280 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
ansond 0:137634ff4186 281 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
ansond 0:137634ff4186 282
ansond 0:137634ff4186 283 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
ansond 0:137634ff4186 284 *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
ansond 0:137634ff4186 285
ansond 0:137634ff4186 286 *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
ansond 0:137634ff4186 287 *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
ansond 0:137634ff4186 288
ansond 0:137634ff4186 289 *olen = 6 + elliptic_curve_len;
ansond 0:137634ff4186 290 }
ansond 0:137634ff4186 291
ansond 0:137634ff4186 292 static void ssl_write_supported_point_formats_ext( ssl_context *ssl,
ansond 0:137634ff4186 293 unsigned char *buf,
ansond 0:137634ff4186 294 size_t *olen )
ansond 0:137634ff4186 295 {
ansond 0:137634ff4186 296 unsigned char *p = buf;
ansond 0:137634ff4186 297 ((void) ssl);
ansond 0:137634ff4186 298
ansond 0:137634ff4186 299 *olen = 0;
ansond 0:137634ff4186 300
ansond 0:137634ff4186 301 SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
ansond 0:137634ff4186 302
ansond 0:137634ff4186 303 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
ansond 0:137634ff4186 304 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
ansond 0:137634ff4186 305
ansond 0:137634ff4186 306 *p++ = 0x00;
ansond 0:137634ff4186 307 *p++ = 2;
ansond 0:137634ff4186 308
ansond 0:137634ff4186 309 *p++ = 1;
ansond 0:137634ff4186 310 *p++ = POLARSSL_ECP_PF_UNCOMPRESSED;
ansond 0:137634ff4186 311
ansond 0:137634ff4186 312 *olen = 6;
ansond 0:137634ff4186 313 }
ansond 0:137634ff4186 314 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
ansond 0:137634ff4186 315
ansond 0:137634ff4186 316 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
ansond 0:137634ff4186 317 static void ssl_write_max_fragment_length_ext( ssl_context *ssl,
ansond 0:137634ff4186 318 unsigned char *buf,
ansond 0:137634ff4186 319 size_t *olen )
ansond 0:137634ff4186 320 {
ansond 0:137634ff4186 321 unsigned char *p = buf;
ansond 0:137634ff4186 322
ansond 0:137634ff4186 323 if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ) {
ansond 0:137634ff4186 324 *olen = 0;
ansond 0:137634ff4186 325 return;
ansond 0:137634ff4186 326 }
ansond 0:137634ff4186 327
ansond 0:137634ff4186 328 SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
ansond 0:137634ff4186 329
ansond 0:137634ff4186 330 *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
ansond 0:137634ff4186 331 *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
ansond 0:137634ff4186 332
ansond 0:137634ff4186 333 *p++ = 0x00;
ansond 0:137634ff4186 334 *p++ = 1;
ansond 0:137634ff4186 335
ansond 0:137634ff4186 336 *p++ = ssl->mfl_code;
ansond 0:137634ff4186 337
ansond 0:137634ff4186 338 *olen = 5;
ansond 0:137634ff4186 339 }
ansond 0:137634ff4186 340 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
ansond 0:137634ff4186 341
ansond 0:137634ff4186 342 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
ansond 0:137634ff4186 343 static void ssl_write_truncated_hmac_ext( ssl_context *ssl,
ansond 0:137634ff4186 344 unsigned char *buf, size_t *olen )
ansond 0:137634ff4186 345 {
ansond 0:137634ff4186 346 unsigned char *p = buf;
ansond 0:137634ff4186 347
ansond 0:137634ff4186 348 if( ssl->trunc_hmac == SSL_TRUNC_HMAC_DISABLED )
ansond 0:137634ff4186 349 {
ansond 0:137634ff4186 350 *olen = 0;
ansond 0:137634ff4186 351 return;
ansond 0:137634ff4186 352 }
ansond 0:137634ff4186 353
ansond 0:137634ff4186 354 SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
ansond 0:137634ff4186 355
ansond 0:137634ff4186 356 *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
ansond 0:137634ff4186 357 *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
ansond 0:137634ff4186 358
ansond 0:137634ff4186 359 *p++ = 0x00;
ansond 0:137634ff4186 360 *p++ = 0x00;
ansond 0:137634ff4186 361
ansond 0:137634ff4186 362 *olen = 4;
ansond 0:137634ff4186 363 }
ansond 0:137634ff4186 364 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
ansond 0:137634ff4186 365
ansond 0:137634ff4186 366 #if defined(POLARSSL_SSL_ENCRYPT_THEN_MAC)
ansond 0:137634ff4186 367 static void ssl_write_encrypt_then_mac_ext( ssl_context *ssl,
ansond 0:137634ff4186 368 unsigned char *buf, size_t *olen )
ansond 0:137634ff4186 369 {
ansond 0:137634ff4186 370 unsigned char *p = buf;
ansond 0:137634ff4186 371
ansond 0:137634ff4186 372 if( ssl->encrypt_then_mac == SSL_ETM_DISABLED ||
ansond 0:137634ff4186 373 ssl->max_minor_ver == SSL_MINOR_VERSION_0 )
ansond 0:137634ff4186 374 {
ansond 0:137634ff4186 375 *olen = 0;
ansond 0:137634ff4186 376 return;
ansond 0:137634ff4186 377 }
ansond 0:137634ff4186 378
ansond 0:137634ff4186 379 SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
ansond 0:137634ff4186 380 "extension" ) );
ansond 0:137634ff4186 381
ansond 0:137634ff4186 382 *p++ = (unsigned char)( ( TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
ansond 0:137634ff4186 383 *p++ = (unsigned char)( ( TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
ansond 0:137634ff4186 384
ansond 0:137634ff4186 385 *p++ = 0x00;
ansond 0:137634ff4186 386 *p++ = 0x00;
ansond 0:137634ff4186 387
ansond 0:137634ff4186 388 *olen = 4;
ansond 0:137634ff4186 389 }
ansond 0:137634ff4186 390 #endif /* POLARSSL_SSL_ENCRYPT_THEN_MAC */
ansond 0:137634ff4186 391
ansond 0:137634ff4186 392 #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
ansond 0:137634ff4186 393 static void ssl_write_extended_ms_ext( ssl_context *ssl,
ansond 0:137634ff4186 394 unsigned char *buf, size_t *olen )
ansond 0:137634ff4186 395 {
ansond 0:137634ff4186 396 unsigned char *p = buf;
ansond 0:137634ff4186 397
ansond 0:137634ff4186 398 if( ssl->extended_ms == SSL_EXTENDED_MS_DISABLED ||
ansond 0:137634ff4186 399 ssl->max_minor_ver == SSL_MINOR_VERSION_0 )
ansond 0:137634ff4186 400 {
ansond 0:137634ff4186 401 *olen = 0;
ansond 0:137634ff4186 402 return;
ansond 0:137634ff4186 403 }
ansond 0:137634ff4186 404
ansond 0:137634ff4186 405 SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
ansond 0:137634ff4186 406 "extension" ) );
ansond 0:137634ff4186 407
ansond 0:137634ff4186 408 *p++ = (unsigned char)( ( TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
ansond 0:137634ff4186 409 *p++ = (unsigned char)( ( TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
ansond 0:137634ff4186 410
ansond 0:137634ff4186 411 *p++ = 0x00;
ansond 0:137634ff4186 412 *p++ = 0x00;
ansond 0:137634ff4186 413
ansond 0:137634ff4186 414 *olen = 4;
ansond 0:137634ff4186 415 }
ansond 0:137634ff4186 416 #endif /* POLARSSL_SSL_EXTENDED_MASTER_SECRET */
ansond 0:137634ff4186 417
ansond 0:137634ff4186 418 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 419 static void ssl_write_session_ticket_ext( ssl_context *ssl,
ansond 0:137634ff4186 420 unsigned char *buf, size_t *olen )
ansond 0:137634ff4186 421 {
ansond 0:137634ff4186 422 unsigned char *p = buf;
ansond 0:137634ff4186 423 size_t tlen = ssl->session_negotiate->ticket_len;
ansond 0:137634ff4186 424
ansond 0:137634ff4186 425 if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED )
ansond 0:137634ff4186 426 {
ansond 0:137634ff4186 427 *olen = 0;
ansond 0:137634ff4186 428 return;
ansond 0:137634ff4186 429 }
ansond 0:137634ff4186 430
ansond 0:137634ff4186 431 SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
ansond 0:137634ff4186 432
ansond 0:137634ff4186 433 *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
ansond 0:137634ff4186 434 *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET ) & 0xFF );
ansond 0:137634ff4186 435
ansond 0:137634ff4186 436 *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
ansond 0:137634ff4186 437 *p++ = (unsigned char)( ( tlen ) & 0xFF );
ansond 0:137634ff4186 438
ansond 0:137634ff4186 439 *olen = 4;
ansond 0:137634ff4186 440
ansond 0:137634ff4186 441 if( ssl->session_negotiate->ticket == NULL ||
ansond 0:137634ff4186 442 ssl->session_negotiate->ticket_len == 0 )
ansond 0:137634ff4186 443 {
ansond 0:137634ff4186 444 return;
ansond 0:137634ff4186 445 }
ansond 0:137634ff4186 446
ansond 0:137634ff4186 447 SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
ansond 0:137634ff4186 448
ansond 0:137634ff4186 449 memcpy( p, ssl->session_negotiate->ticket, tlen );
ansond 0:137634ff4186 450
ansond 0:137634ff4186 451 *olen += tlen;
ansond 0:137634ff4186 452 }
ansond 0:137634ff4186 453 #endif /* POLARSSL_SSL_SESSION_TICKETS */
ansond 0:137634ff4186 454
ansond 0:137634ff4186 455 #if defined(POLARSSL_SSL_ALPN)
ansond 0:137634ff4186 456 static void ssl_write_alpn_ext( ssl_context *ssl,
ansond 0:137634ff4186 457 unsigned char *buf, size_t *olen )
ansond 0:137634ff4186 458 {
ansond 0:137634ff4186 459 unsigned char *p = buf;
ansond 0:137634ff4186 460 const char **cur;
ansond 0:137634ff4186 461
ansond 0:137634ff4186 462 if( ssl->alpn_list == NULL )
ansond 0:137634ff4186 463 {
ansond 0:137634ff4186 464 *olen = 0;
ansond 0:137634ff4186 465 return;
ansond 0:137634ff4186 466 }
ansond 0:137634ff4186 467
ansond 0:137634ff4186 468 SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
ansond 0:137634ff4186 469
ansond 0:137634ff4186 470 *p++ = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF );
ansond 0:137634ff4186 471 *p++ = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF );
ansond 0:137634ff4186 472
ansond 0:137634ff4186 473 /*
ansond 0:137634ff4186 474 * opaque ProtocolName<1..2^8-1>;
ansond 0:137634ff4186 475 *
ansond 0:137634ff4186 476 * struct {
ansond 0:137634ff4186 477 * ProtocolName protocol_name_list<2..2^16-1>
ansond 0:137634ff4186 478 * } ProtocolNameList;
ansond 0:137634ff4186 479 */
ansond 0:137634ff4186 480
ansond 0:137634ff4186 481 /* Skip writing extension and list length for now */
ansond 0:137634ff4186 482 p += 4;
ansond 0:137634ff4186 483
ansond 0:137634ff4186 484 for( cur = ssl->alpn_list; *cur != NULL; cur++ )
ansond 0:137634ff4186 485 {
ansond 0:137634ff4186 486 *p = (unsigned char)( strlen( *cur ) & 0xFF );
ansond 0:137634ff4186 487 memcpy( p + 1, *cur, *p );
ansond 0:137634ff4186 488 p += 1 + *p;
ansond 0:137634ff4186 489 }
ansond 0:137634ff4186 490
ansond 0:137634ff4186 491 *olen = p - buf;
ansond 0:137634ff4186 492
ansond 0:137634ff4186 493 /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
ansond 0:137634ff4186 494 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
ansond 0:137634ff4186 495 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
ansond 0:137634ff4186 496
ansond 0:137634ff4186 497 /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
ansond 0:137634ff4186 498 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
ansond 0:137634ff4186 499 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
ansond 0:137634ff4186 500 }
ansond 0:137634ff4186 501 #endif /* POLARSSL_SSL_ALPN */
ansond 0:137634ff4186 502
ansond 0:137634ff4186 503 static int ssl_write_client_hello( ssl_context *ssl )
ansond 0:137634ff4186 504 {
ansond 0:137634ff4186 505 int ret;
ansond 0:137634ff4186 506 size_t i, n, olen, ext_len = 0;
ansond 0:137634ff4186 507 unsigned char *buf;
ansond 0:137634ff4186 508 unsigned char *p, *q;
ansond 0:137634ff4186 509 #if defined(POLARSSL_HAVE_TIME)
ansond 0:137634ff4186 510 time_t t;
ansond 0:137634ff4186 511 #endif
ansond 0:137634ff4186 512 const int *ciphersuites;
ansond 0:137634ff4186 513 const ssl_ciphersuite_t *ciphersuite_info;
ansond 0:137634ff4186 514
ansond 0:137634ff4186 515 SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
ansond 0:137634ff4186 516
ansond 0:137634ff4186 517 if( ssl->f_rng == NULL )
ansond 0:137634ff4186 518 {
ansond 0:137634ff4186 519 SSL_DEBUG_MSG( 1, ( "no RNG provided") );
ansond 0:137634ff4186 520 return( POLARSSL_ERR_SSL_NO_RNG );
ansond 0:137634ff4186 521 }
ansond 0:137634ff4186 522
ansond 0:137634ff4186 523 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 524 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
ansond 0:137634ff4186 525 #endif
ansond 0:137634ff4186 526 {
ansond 0:137634ff4186 527 ssl->major_ver = ssl->min_major_ver;
ansond 0:137634ff4186 528 ssl->minor_ver = ssl->min_minor_ver;
ansond 0:137634ff4186 529 }
ansond 0:137634ff4186 530
ansond 0:137634ff4186 531 if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
ansond 0:137634ff4186 532 {
ansond 0:137634ff4186 533 ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
ansond 0:137634ff4186 534 ssl->max_minor_ver = SSL_MAX_MINOR_VERSION;
ansond 0:137634ff4186 535 }
ansond 0:137634ff4186 536
ansond 0:137634ff4186 537 /*
ansond 0:137634ff4186 538 * 0 . 0 handshake type
ansond 0:137634ff4186 539 * 1 . 3 handshake length
ansond 0:137634ff4186 540 * 4 . 5 highest version supported
ansond 0:137634ff4186 541 * 6 . 9 current UNIX time
ansond 0:137634ff4186 542 * 10 . 37 random bytes
ansond 0:137634ff4186 543 */
ansond 0:137634ff4186 544 buf = ssl->out_msg;
ansond 0:137634ff4186 545 p = buf + 4;
ansond 0:137634ff4186 546
ansond 0:137634ff4186 547 *p++ = (unsigned char) ssl->max_major_ver;
ansond 0:137634ff4186 548 *p++ = (unsigned char) ssl->max_minor_ver;
ansond 0:137634ff4186 549
ansond 0:137634ff4186 550 SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
ansond 0:137634ff4186 551 buf[4], buf[5] ) );
ansond 0:137634ff4186 552
ansond 0:137634ff4186 553 #if defined(POLARSSL_HAVE_TIME)
ansond 0:137634ff4186 554 t = time( NULL );
ansond 0:137634ff4186 555 *p++ = (unsigned char)( t >> 24 );
ansond 0:137634ff4186 556 *p++ = (unsigned char)( t >> 16 );
ansond 0:137634ff4186 557 *p++ = (unsigned char)( t >> 8 );
ansond 0:137634ff4186 558 *p++ = (unsigned char)( t );
ansond 0:137634ff4186 559
ansond 0:137634ff4186 560 SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
ansond 0:137634ff4186 561 #else
ansond 0:137634ff4186 562 if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 )
ansond 0:137634ff4186 563 return( ret );
ansond 0:137634ff4186 564
ansond 0:137634ff4186 565 p += 4;
ansond 0:137634ff4186 566 #endif /* POLARSSL_HAVE_TIME */
ansond 0:137634ff4186 567
ansond 0:137634ff4186 568 if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
ansond 0:137634ff4186 569 return( ret );
ansond 0:137634ff4186 570
ansond 0:137634ff4186 571 p += 28;
ansond 0:137634ff4186 572
ansond 0:137634ff4186 573 memcpy( ssl->handshake->randbytes, buf + 6, 32 );
ansond 0:137634ff4186 574
ansond 0:137634ff4186 575 SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 );
ansond 0:137634ff4186 576
ansond 0:137634ff4186 577 /*
ansond 0:137634ff4186 578 * 38 . 38 session id length
ansond 0:137634ff4186 579 * 39 . 39+n session id
ansond 0:137634ff4186 580 * 40+n . 41+n ciphersuitelist length
ansond 0:137634ff4186 581 * 42+n . .. ciphersuitelist
ansond 0:137634ff4186 582 * .. . .. compression methods length
ansond 0:137634ff4186 583 * .. . .. compression methods
ansond 0:137634ff4186 584 * .. . .. extensions length
ansond 0:137634ff4186 585 * .. . .. extensions
ansond 0:137634ff4186 586 */
ansond 0:137634ff4186 587 n = ssl->session_negotiate->length;
ansond 0:137634ff4186 588
ansond 0:137634ff4186 589 if( n < 16 || n > 32 ||
ansond 0:137634ff4186 590 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 591 ssl->renegotiation != SSL_INITIAL_HANDSHAKE ||
ansond 0:137634ff4186 592 #endif
ansond 0:137634ff4186 593 ssl->handshake->resume == 0 )
ansond 0:137634ff4186 594 {
ansond 0:137634ff4186 595 n = 0;
ansond 0:137634ff4186 596 }
ansond 0:137634ff4186 597
ansond 0:137634ff4186 598 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 599 /*
ansond 0:137634ff4186 600 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
ansond 0:137634ff4186 601 * generate and include a Session ID in the TLS ClientHello."
ansond 0:137634ff4186 602 */
ansond 0:137634ff4186 603 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 604 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
ansond 0:137634ff4186 605 #endif
ansond 0:137634ff4186 606 {
ansond 0:137634ff4186 607 if( ssl->session_negotiate->ticket != NULL &&
ansond 0:137634ff4186 608 ssl->session_negotiate->ticket_len != 0 )
ansond 0:137634ff4186 609 {
ansond 0:137634ff4186 610 ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 );
ansond 0:137634ff4186 611
ansond 0:137634ff4186 612 if( ret != 0 )
ansond 0:137634ff4186 613 return( ret );
ansond 0:137634ff4186 614
ansond 0:137634ff4186 615 ssl->session_negotiate->length = n = 32;
ansond 0:137634ff4186 616 }
ansond 0:137634ff4186 617 }
ansond 0:137634ff4186 618 #endif /* POLARSSL_SSL_SESSION_TICKETS */
ansond 0:137634ff4186 619
ansond 0:137634ff4186 620 *p++ = (unsigned char) n;
ansond 0:137634ff4186 621
ansond 0:137634ff4186 622 for( i = 0; i < n; i++ )
ansond 0:137634ff4186 623 *p++ = ssl->session_negotiate->id[i];
ansond 0:137634ff4186 624
ansond 0:137634ff4186 625 SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
ansond 0:137634ff4186 626 SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
ansond 0:137634ff4186 627
ansond 0:137634ff4186 628 ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
ansond 0:137634ff4186 629 n = 0;
ansond 0:137634ff4186 630 q = p;
ansond 0:137634ff4186 631
ansond 0:137634ff4186 632 // Skip writing ciphersuite length for now
ansond 0:137634ff4186 633 p += 2;
ansond 0:137634ff4186 634
ansond 0:137634ff4186 635 for( i = 0; ciphersuites[i] != 0; i++ )
ansond 0:137634ff4186 636 {
ansond 0:137634ff4186 637 ciphersuite_info = ssl_ciphersuite_from_id( ciphersuites[i] );
ansond 0:137634ff4186 638
ansond 0:137634ff4186 639 if( ciphersuite_info == NULL )
ansond 0:137634ff4186 640 continue;
ansond 0:137634ff4186 641
ansond 0:137634ff4186 642 if( ciphersuite_info->min_minor_ver > ssl->max_minor_ver ||
ansond 0:137634ff4186 643 ciphersuite_info->max_minor_ver < ssl->min_minor_ver )
ansond 0:137634ff4186 644 continue;
ansond 0:137634ff4186 645
ansond 0:137634ff4186 646 if( ssl->arc4_disabled == SSL_ARC4_DISABLED &&
ansond 0:137634ff4186 647 ciphersuite_info->cipher == POLARSSL_CIPHER_ARC4_128 )
ansond 0:137634ff4186 648 continue;
ansond 0:137634ff4186 649
ansond 0:137634ff4186 650 SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d",
ansond 0:137634ff4186 651 ciphersuites[i] ) );
ansond 0:137634ff4186 652
ansond 0:137634ff4186 653 n++;
ansond 0:137634ff4186 654 *p++ = (unsigned char)( ciphersuites[i] >> 8 );
ansond 0:137634ff4186 655 *p++ = (unsigned char)( ciphersuites[i] );
ansond 0:137634ff4186 656 }
ansond 0:137634ff4186 657
ansond 0:137634ff4186 658 /*
ansond 0:137634ff4186 659 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
ansond 0:137634ff4186 660 */
ansond 0:137634ff4186 661 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 662 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
ansond 0:137634ff4186 663 #endif
ansond 0:137634ff4186 664 {
ansond 0:137634ff4186 665 *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
ansond 0:137634ff4186 666 *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO );
ansond 0:137634ff4186 667 n++;
ansond 0:137634ff4186 668 }
ansond 0:137634ff4186 669
ansond 0:137634ff4186 670 /* Some versions of OpenSSL don't handle it correctly if not at end */
ansond 0:137634ff4186 671 #if defined(POLARSSL_SSL_FALLBACK_SCSV)
ansond 0:137634ff4186 672 if( ssl->fallback == SSL_IS_FALLBACK )
ansond 0:137634ff4186 673 {
ansond 0:137634ff4186 674 SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
ansond 0:137634ff4186 675 *p++ = (unsigned char)( SSL_FALLBACK_SCSV >> 8 );
ansond 0:137634ff4186 676 *p++ = (unsigned char)( SSL_FALLBACK_SCSV );
ansond 0:137634ff4186 677 n++;
ansond 0:137634ff4186 678 }
ansond 0:137634ff4186 679 #endif
ansond 0:137634ff4186 680
ansond 0:137634ff4186 681 *q++ = (unsigned char)( n >> 7 );
ansond 0:137634ff4186 682 *q++ = (unsigned char)( n << 1 );
ansond 0:137634ff4186 683
ansond 0:137634ff4186 684 SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
ansond 0:137634ff4186 685
ansond 0:137634ff4186 686
ansond 0:137634ff4186 687 #if defined(POLARSSL_ZLIB_SUPPORT)
ansond 0:137634ff4186 688 SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
ansond 0:137634ff4186 689 SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
ansond 0:137634ff4186 690 SSL_COMPRESS_DEFLATE, SSL_COMPRESS_NULL ) );
ansond 0:137634ff4186 691
ansond 0:137634ff4186 692 *p++ = 2;
ansond 0:137634ff4186 693 *p++ = SSL_COMPRESS_DEFLATE;
ansond 0:137634ff4186 694 *p++ = SSL_COMPRESS_NULL;
ansond 0:137634ff4186 695 #else
ansond 0:137634ff4186 696 SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
ansond 0:137634ff4186 697 SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", SSL_COMPRESS_NULL ) );
ansond 0:137634ff4186 698
ansond 0:137634ff4186 699 *p++ = 1;
ansond 0:137634ff4186 700 *p++ = SSL_COMPRESS_NULL;
ansond 0:137634ff4186 701 #endif /* POLARSSL_ZLIB_SUPPORT */
ansond 0:137634ff4186 702
ansond 0:137634ff4186 703 // First write extensions, then the total length
ansond 0:137634ff4186 704 //
ansond 0:137634ff4186 705 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
ansond 0:137634ff4186 706 ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 707 ext_len += olen;
ansond 0:137634ff4186 708 #endif
ansond 0:137634ff4186 709
ansond 0:137634ff4186 710 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 711 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 712 ext_len += olen;
ansond 0:137634ff4186 713 #endif
ansond 0:137634ff4186 714
ansond 0:137634ff4186 715 #if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
ansond 0:137634ff4186 716 defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
ansond 0:137634ff4186 717 ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 718 ext_len += olen;
ansond 0:137634ff4186 719 #endif
ansond 0:137634ff4186 720
ansond 0:137634ff4186 721 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 722 ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 723 ext_len += olen;
ansond 0:137634ff4186 724
ansond 0:137634ff4186 725 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 726 ext_len += olen;
ansond 0:137634ff4186 727 #endif
ansond 0:137634ff4186 728
ansond 0:137634ff4186 729 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
ansond 0:137634ff4186 730 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 731 ext_len += olen;
ansond 0:137634ff4186 732 #endif
ansond 0:137634ff4186 733
ansond 0:137634ff4186 734 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
ansond 0:137634ff4186 735 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 736 ext_len += olen;
ansond 0:137634ff4186 737 #endif
ansond 0:137634ff4186 738
ansond 0:137634ff4186 739 #if defined(POLARSSL_SSL_ENCRYPT_THEN_MAC)
ansond 0:137634ff4186 740 ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 741 ext_len += olen;
ansond 0:137634ff4186 742 #endif
ansond 0:137634ff4186 743
ansond 0:137634ff4186 744 #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
ansond 0:137634ff4186 745 ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 746 ext_len += olen;
ansond 0:137634ff4186 747 #endif
ansond 0:137634ff4186 748
ansond 0:137634ff4186 749 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 750 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 751 ext_len += olen;
ansond 0:137634ff4186 752 #endif
ansond 0:137634ff4186 753
ansond 0:137634ff4186 754 #if defined(POLARSSL_SSL_ALPN)
ansond 0:137634ff4186 755 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ansond 0:137634ff4186 756 ext_len += olen;
ansond 0:137634ff4186 757 #endif
ansond 0:137634ff4186 758
ansond 0:137634ff4186 759 /* olen unused if all extensions are disabled */
ansond 0:137634ff4186 760 ((void) olen);
ansond 0:137634ff4186 761
ansond 0:137634ff4186 762 SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
ansond 0:137634ff4186 763 ext_len ) );
ansond 0:137634ff4186 764
ansond 0:137634ff4186 765 if( ext_len > 0 )
ansond 0:137634ff4186 766 {
ansond 0:137634ff4186 767 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
ansond 0:137634ff4186 768 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
ansond 0:137634ff4186 769 p += ext_len;
ansond 0:137634ff4186 770 }
ansond 0:137634ff4186 771
ansond 0:137634ff4186 772 ssl->out_msglen = p - buf;
ansond 0:137634ff4186 773 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ansond 0:137634ff4186 774 ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
ansond 0:137634ff4186 775
ansond 0:137634ff4186 776 ssl->state++;
ansond 0:137634ff4186 777
ansond 0:137634ff4186 778 if( ( ret = ssl_write_record( ssl ) ) != 0 )
ansond 0:137634ff4186 779 {
ansond 0:137634ff4186 780 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
ansond 0:137634ff4186 781 return( ret );
ansond 0:137634ff4186 782 }
ansond 0:137634ff4186 783
ansond 0:137634ff4186 784 SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
ansond 0:137634ff4186 785
ansond 0:137634ff4186 786 return( 0 );
ansond 0:137634ff4186 787 }
ansond 0:137634ff4186 788
ansond 0:137634ff4186 789 static int ssl_parse_renegotiation_info( ssl_context *ssl,
ansond 0:137634ff4186 790 const unsigned char *buf,
ansond 0:137634ff4186 791 size_t len )
ansond 0:137634ff4186 792 {
ansond 0:137634ff4186 793 int ret;
ansond 0:137634ff4186 794
ansond 0:137634ff4186 795 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 796 if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
ansond 0:137634ff4186 797 {
ansond 0:137634ff4186 798 /* Check verify-data in constant-time. The length OTOH is no secret */
ansond 0:137634ff4186 799 if( len != 1 + ssl->verify_data_len * 2 ||
ansond 0:137634ff4186 800 buf[0] != ssl->verify_data_len * 2 ||
ansond 0:137634ff4186 801 safer_memcmp( buf + 1,
ansond 0:137634ff4186 802 ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
ansond 0:137634ff4186 803 safer_memcmp( buf + 1 + ssl->verify_data_len,
ansond 0:137634ff4186 804 ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
ansond 0:137634ff4186 805 {
ansond 0:137634ff4186 806 SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
ansond 0:137634ff4186 807
ansond 0:137634ff4186 808 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
ansond 0:137634ff4186 809 return( ret );
ansond 0:137634ff4186 810
ansond 0:137634ff4186 811 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 812 }
ansond 0:137634ff4186 813 }
ansond 0:137634ff4186 814 else
ansond 0:137634ff4186 815 #endif /* POLARSSL_SSL_RENEGOTIATION */
ansond 0:137634ff4186 816 {
ansond 0:137634ff4186 817 if( len != 1 || buf[0] != 0x00 )
ansond 0:137634ff4186 818 {
ansond 0:137634ff4186 819 SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
ansond 0:137634ff4186 820
ansond 0:137634ff4186 821 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
ansond 0:137634ff4186 822 return( ret );
ansond 0:137634ff4186 823
ansond 0:137634ff4186 824 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 825 }
ansond 0:137634ff4186 826
ansond 0:137634ff4186 827 ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
ansond 0:137634ff4186 828 }
ansond 0:137634ff4186 829
ansond 0:137634ff4186 830 return( 0 );
ansond 0:137634ff4186 831 }
ansond 0:137634ff4186 832
ansond 0:137634ff4186 833 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
ansond 0:137634ff4186 834 static int ssl_parse_max_fragment_length_ext( ssl_context *ssl,
ansond 0:137634ff4186 835 const unsigned char *buf,
ansond 0:137634ff4186 836 size_t len )
ansond 0:137634ff4186 837 {
ansond 0:137634ff4186 838 /*
ansond 0:137634ff4186 839 * server should use the extension only if we did,
ansond 0:137634ff4186 840 * and if so the server's value should match ours (and len is always 1)
ansond 0:137634ff4186 841 */
ansond 0:137634ff4186 842 if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ||
ansond 0:137634ff4186 843 len != 1 ||
ansond 0:137634ff4186 844 buf[0] != ssl->mfl_code )
ansond 0:137634ff4186 845 {
ansond 0:137634ff4186 846 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 847 }
ansond 0:137634ff4186 848
ansond 0:137634ff4186 849 return( 0 );
ansond 0:137634ff4186 850 }
ansond 0:137634ff4186 851 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
ansond 0:137634ff4186 852
ansond 0:137634ff4186 853 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
ansond 0:137634ff4186 854 static int ssl_parse_truncated_hmac_ext( ssl_context *ssl,
ansond 0:137634ff4186 855 const unsigned char *buf,
ansond 0:137634ff4186 856 size_t len )
ansond 0:137634ff4186 857 {
ansond 0:137634ff4186 858 if( ssl->trunc_hmac == SSL_TRUNC_HMAC_DISABLED ||
ansond 0:137634ff4186 859 len != 0 )
ansond 0:137634ff4186 860 {
ansond 0:137634ff4186 861 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 862 }
ansond 0:137634ff4186 863
ansond 0:137634ff4186 864 ((void) buf);
ansond 0:137634ff4186 865
ansond 0:137634ff4186 866 ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
ansond 0:137634ff4186 867
ansond 0:137634ff4186 868 return( 0 );
ansond 0:137634ff4186 869 }
ansond 0:137634ff4186 870 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
ansond 0:137634ff4186 871
ansond 0:137634ff4186 872 #if defined(POLARSSL_SSL_ENCRYPT_THEN_MAC)
ansond 0:137634ff4186 873 static int ssl_parse_encrypt_then_mac_ext( ssl_context *ssl,
ansond 0:137634ff4186 874 const unsigned char *buf,
ansond 0:137634ff4186 875 size_t len )
ansond 0:137634ff4186 876 {
ansond 0:137634ff4186 877 if( ssl->encrypt_then_mac == SSL_ETM_DISABLED ||
ansond 0:137634ff4186 878 ssl->minor_ver == SSL_MINOR_VERSION_0 ||
ansond 0:137634ff4186 879 len != 0 )
ansond 0:137634ff4186 880 {
ansond 0:137634ff4186 881 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 882 }
ansond 0:137634ff4186 883
ansond 0:137634ff4186 884 ((void) buf);
ansond 0:137634ff4186 885
ansond 0:137634ff4186 886 ssl->session_negotiate->encrypt_then_mac = SSL_ETM_ENABLED;
ansond 0:137634ff4186 887
ansond 0:137634ff4186 888 return( 0 );
ansond 0:137634ff4186 889 }
ansond 0:137634ff4186 890 #endif /* POLARSSL_SSL_ENCRYPT_THEN_MAC */
ansond 0:137634ff4186 891
ansond 0:137634ff4186 892 #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
ansond 0:137634ff4186 893 static int ssl_parse_extended_ms_ext( ssl_context *ssl,
ansond 0:137634ff4186 894 const unsigned char *buf,
ansond 0:137634ff4186 895 size_t len )
ansond 0:137634ff4186 896 {
ansond 0:137634ff4186 897 if( ssl->extended_ms == SSL_EXTENDED_MS_DISABLED ||
ansond 0:137634ff4186 898 ssl->minor_ver == SSL_MINOR_VERSION_0 ||
ansond 0:137634ff4186 899 len != 0 )
ansond 0:137634ff4186 900 {
ansond 0:137634ff4186 901 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 902 }
ansond 0:137634ff4186 903
ansond 0:137634ff4186 904 ((void) buf);
ansond 0:137634ff4186 905
ansond 0:137634ff4186 906 ssl->handshake->extended_ms = SSL_EXTENDED_MS_ENABLED;
ansond 0:137634ff4186 907
ansond 0:137634ff4186 908 return( 0 );
ansond 0:137634ff4186 909 }
ansond 0:137634ff4186 910 #endif /* POLARSSL_SSL_EXTENDED_MASTER_SECRET */
ansond 0:137634ff4186 911
ansond 0:137634ff4186 912 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 913 static int ssl_parse_session_ticket_ext( ssl_context *ssl,
ansond 0:137634ff4186 914 const unsigned char *buf,
ansond 0:137634ff4186 915 size_t len )
ansond 0:137634ff4186 916 {
ansond 0:137634ff4186 917 if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED ||
ansond 0:137634ff4186 918 len != 0 )
ansond 0:137634ff4186 919 {
ansond 0:137634ff4186 920 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 921 }
ansond 0:137634ff4186 922
ansond 0:137634ff4186 923 ((void) buf);
ansond 0:137634ff4186 924
ansond 0:137634ff4186 925 ssl->handshake->new_session_ticket = 1;
ansond 0:137634ff4186 926
ansond 0:137634ff4186 927 return( 0 );
ansond 0:137634ff4186 928 }
ansond 0:137634ff4186 929 #endif /* POLARSSL_SSL_SESSION_TICKETS */
ansond 0:137634ff4186 930
ansond 0:137634ff4186 931 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 932 static int ssl_parse_supported_point_formats_ext( ssl_context *ssl,
ansond 0:137634ff4186 933 const unsigned char *buf,
ansond 0:137634ff4186 934 size_t len )
ansond 0:137634ff4186 935 {
ansond 0:137634ff4186 936 size_t list_size;
ansond 0:137634ff4186 937 const unsigned char *p;
ansond 0:137634ff4186 938
ansond 0:137634ff4186 939 list_size = buf[0];
ansond 0:137634ff4186 940 if( list_size + 1 != len )
ansond 0:137634ff4186 941 {
ansond 0:137634ff4186 942 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 943 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 944 }
ansond 0:137634ff4186 945
ansond 0:137634ff4186 946 p = buf + 1;
ansond 0:137634ff4186 947 while( list_size > 0 )
ansond 0:137634ff4186 948 {
ansond 0:137634ff4186 949 if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED ||
ansond 0:137634ff4186 950 p[0] == POLARSSL_ECP_PF_COMPRESSED )
ansond 0:137634ff4186 951 {
ansond 0:137634ff4186 952 ssl->handshake->ecdh_ctx.point_format = p[0];
ansond 0:137634ff4186 953 SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
ansond 0:137634ff4186 954 return( 0 );
ansond 0:137634ff4186 955 }
ansond 0:137634ff4186 956
ansond 0:137634ff4186 957 list_size--;
ansond 0:137634ff4186 958 p++;
ansond 0:137634ff4186 959 }
ansond 0:137634ff4186 960
ansond 0:137634ff4186 961 SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
ansond 0:137634ff4186 962 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 963 }
ansond 0:137634ff4186 964 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
ansond 0:137634ff4186 965
ansond 0:137634ff4186 966 #if defined(POLARSSL_SSL_ALPN)
ansond 0:137634ff4186 967 static int ssl_parse_alpn_ext( ssl_context *ssl,
ansond 0:137634ff4186 968 const unsigned char *buf, size_t len )
ansond 0:137634ff4186 969 {
ansond 0:137634ff4186 970 size_t list_len, name_len;
ansond 0:137634ff4186 971 const char **p;
ansond 0:137634ff4186 972
ansond 0:137634ff4186 973 /* If we didn't send it, the server shouldn't send it */
ansond 0:137634ff4186 974 if( ssl->alpn_list == NULL )
ansond 0:137634ff4186 975 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 976
ansond 0:137634ff4186 977 /*
ansond 0:137634ff4186 978 * opaque ProtocolName<1..2^8-1>;
ansond 0:137634ff4186 979 *
ansond 0:137634ff4186 980 * struct {
ansond 0:137634ff4186 981 * ProtocolName protocol_name_list<2..2^16-1>
ansond 0:137634ff4186 982 * } ProtocolNameList;
ansond 0:137634ff4186 983 *
ansond 0:137634ff4186 984 * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
ansond 0:137634ff4186 985 */
ansond 0:137634ff4186 986
ansond 0:137634ff4186 987 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
ansond 0:137634ff4186 988 if( len < 4 )
ansond 0:137634ff4186 989 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 990
ansond 0:137634ff4186 991 list_len = ( buf[0] << 8 ) | buf[1];
ansond 0:137634ff4186 992 if( list_len != len - 2 )
ansond 0:137634ff4186 993 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 994
ansond 0:137634ff4186 995 name_len = buf[2];
ansond 0:137634ff4186 996 if( name_len != list_len - 1 )
ansond 0:137634ff4186 997 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 998
ansond 0:137634ff4186 999 /* Check that the server chosen protocol was in our list and save it */
ansond 0:137634ff4186 1000 for( p = ssl->alpn_list; *p != NULL; p++ )
ansond 0:137634ff4186 1001 {
ansond 0:137634ff4186 1002 if( name_len == strlen( *p ) &&
ansond 0:137634ff4186 1003 memcmp( buf + 3, *p, name_len ) == 0 )
ansond 0:137634ff4186 1004 {
ansond 0:137634ff4186 1005 ssl->alpn_chosen = *p;
ansond 0:137634ff4186 1006 return( 0 );
ansond 0:137634ff4186 1007 }
ansond 0:137634ff4186 1008 }
ansond 0:137634ff4186 1009
ansond 0:137634ff4186 1010 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1011 }
ansond 0:137634ff4186 1012 #endif /* POLARSSL_SSL_ALPN */
ansond 0:137634ff4186 1013
ansond 0:137634ff4186 1014 static int ssl_parse_server_hello( ssl_context *ssl )
ansond 0:137634ff4186 1015 {
ansond 0:137634ff4186 1016 int ret, i, comp;
ansond 0:137634ff4186 1017 size_t n;
ansond 0:137634ff4186 1018 size_t ext_len;
ansond 0:137634ff4186 1019 unsigned char *buf, *ext;
ansond 0:137634ff4186 1020 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 1021 int renegotiation_info_seen = 0;
ansond 0:137634ff4186 1022 #endif
ansond 0:137634ff4186 1023 int handshake_failure = 0;
ansond 0:137634ff4186 1024 const ssl_ciphersuite_t *suite_info;
ansond 0:137634ff4186 1025 #if defined(POLARSSL_DEBUG_C)
ansond 0:137634ff4186 1026 uint32_t t;
ansond 0:137634ff4186 1027 #endif
ansond 0:137634ff4186 1028
ansond 0:137634ff4186 1029 SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
ansond 0:137634ff4186 1030
ansond 0:137634ff4186 1031 /*
ansond 0:137634ff4186 1032 * 0 . 0 handshake type
ansond 0:137634ff4186 1033 * 1 . 3 handshake length
ansond 0:137634ff4186 1034 * 4 . 5 protocol version
ansond 0:137634ff4186 1035 * 6 . 9 UNIX time()
ansond 0:137634ff4186 1036 * 10 . 37 random bytes
ansond 0:137634ff4186 1037 */
ansond 0:137634ff4186 1038 buf = ssl->in_msg;
ansond 0:137634ff4186 1039
ansond 0:137634ff4186 1040 if( ( ret = ssl_read_record( ssl ) ) != 0 )
ansond 0:137634ff4186 1041 {
ansond 0:137634ff4186 1042 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
ansond 0:137634ff4186 1043 return( ret );
ansond 0:137634ff4186 1044 }
ansond 0:137634ff4186 1045
ansond 0:137634ff4186 1046 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
ansond 0:137634ff4186 1047 {
ansond 0:137634ff4186 1048 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 1049 if( ssl->renegotiation == SSL_RENEGOTIATION )
ansond 0:137634ff4186 1050 {
ansond 0:137634ff4186 1051 ssl->renego_records_seen++;
ansond 0:137634ff4186 1052
ansond 0:137634ff4186 1053 if( ssl->renego_max_records >= 0 &&
ansond 0:137634ff4186 1054 ssl->renego_records_seen > ssl->renego_max_records )
ansond 0:137634ff4186 1055 {
ansond 0:137634ff4186 1056 SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
ansond 0:137634ff4186 1057 "but not honored by server" ) );
ansond 0:137634ff4186 1058 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 1059 }
ansond 0:137634ff4186 1060
ansond 0:137634ff4186 1061 SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
ansond 0:137634ff4186 1062 return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
ansond 0:137634ff4186 1063 }
ansond 0:137634ff4186 1064 #endif /* POLARSSL_SSL_RENEGOTIATION */
ansond 0:137634ff4186 1065
ansond 0:137634ff4186 1066 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1067 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 1068 }
ansond 0:137634ff4186 1069
ansond 0:137634ff4186 1070 SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
ansond 0:137634ff4186 1071 buf[4], buf[5] ) );
ansond 0:137634ff4186 1072
ansond 0:137634ff4186 1073 if( ssl->in_hslen < 42 ||
ansond 0:137634ff4186 1074 buf[0] != SSL_HS_SERVER_HELLO ||
ansond 0:137634ff4186 1075 buf[4] != SSL_MAJOR_VERSION_3 )
ansond 0:137634ff4186 1076 {
ansond 0:137634ff4186 1077 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1078 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1079 }
ansond 0:137634ff4186 1080
ansond 0:137634ff4186 1081 if( buf[5] > ssl->max_minor_ver )
ansond 0:137634ff4186 1082 {
ansond 0:137634ff4186 1083 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1084 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1085 }
ansond 0:137634ff4186 1086
ansond 0:137634ff4186 1087 ssl->minor_ver = buf[5];
ansond 0:137634ff4186 1088
ansond 0:137634ff4186 1089 if( ssl->minor_ver < ssl->min_minor_ver )
ansond 0:137634ff4186 1090 {
ansond 0:137634ff4186 1091 SSL_DEBUG_MSG( 1, ( "server only supports ssl smaller than minimum"
ansond 0:137634ff4186 1092 " [%d:%d] < [%d:%d]", ssl->major_ver,
ansond 0:137634ff4186 1093 ssl->minor_ver, buf[4], buf[5] ) );
ansond 0:137634ff4186 1094
ansond 0:137634ff4186 1095 ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
ansond 0:137634ff4186 1096 SSL_ALERT_MSG_PROTOCOL_VERSION );
ansond 0:137634ff4186 1097
ansond 0:137634ff4186 1098 return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
ansond 0:137634ff4186 1099 }
ansond 0:137634ff4186 1100
ansond 0:137634ff4186 1101 #if defined(POLARSSL_DEBUG_C)
ansond 0:137634ff4186 1102 t = ( (uint32_t) buf[6] << 24 )
ansond 0:137634ff4186 1103 | ( (uint32_t) buf[7] << 16 )
ansond 0:137634ff4186 1104 | ( (uint32_t) buf[8] << 8 )
ansond 0:137634ff4186 1105 | ( (uint32_t) buf[9] );
ansond 0:137634ff4186 1106 SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
ansond 0:137634ff4186 1107 #endif
ansond 0:137634ff4186 1108
ansond 0:137634ff4186 1109 memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
ansond 0:137634ff4186 1110
ansond 0:137634ff4186 1111 n = buf[38];
ansond 0:137634ff4186 1112
ansond 0:137634ff4186 1113 SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
ansond 0:137634ff4186 1114
ansond 0:137634ff4186 1115 if( n > 32 )
ansond 0:137634ff4186 1116 {
ansond 0:137634ff4186 1117 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1118 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1119 }
ansond 0:137634ff4186 1120
ansond 0:137634ff4186 1121 /*
ansond 0:137634ff4186 1122 * 38 . 38 session id length
ansond 0:137634ff4186 1123 * 39 . 38+n session id
ansond 0:137634ff4186 1124 * 39+n . 40+n chosen ciphersuite
ansond 0:137634ff4186 1125 * 41+n . 41+n chosen compression alg.
ansond 0:137634ff4186 1126 * 42+n . 43+n extensions length
ansond 0:137634ff4186 1127 * 44+n . 44+n+m extensions
ansond 0:137634ff4186 1128 */
ansond 0:137634ff4186 1129 if( ssl->in_hslen > 43 + n )
ansond 0:137634ff4186 1130 {
ansond 0:137634ff4186 1131 ext_len = ( ( buf[42 + n] << 8 )
ansond 0:137634ff4186 1132 | ( buf[43 + n] ) );
ansond 0:137634ff4186 1133
ansond 0:137634ff4186 1134 if( ( ext_len > 0 && ext_len < 4 ) ||
ansond 0:137634ff4186 1135 ssl->in_hslen != 44 + n + ext_len )
ansond 0:137634ff4186 1136 {
ansond 0:137634ff4186 1137 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1138 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1139 }
ansond 0:137634ff4186 1140 }
ansond 0:137634ff4186 1141 else if( ssl->in_hslen == 42 + n )
ansond 0:137634ff4186 1142 {
ansond 0:137634ff4186 1143 ext_len = 0;
ansond 0:137634ff4186 1144 }
ansond 0:137634ff4186 1145 else
ansond 0:137634ff4186 1146 {
ansond 0:137634ff4186 1147 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1148 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1149 }
ansond 0:137634ff4186 1150
ansond 0:137634ff4186 1151 i = ( buf[39 + n] << 8 ) | buf[40 + n];
ansond 0:137634ff4186 1152 comp = buf[41 + n];
ansond 0:137634ff4186 1153
ansond 0:137634ff4186 1154 /*
ansond 0:137634ff4186 1155 * Initialize update checksum functions
ansond 0:137634ff4186 1156 */
ansond 0:137634ff4186 1157 ssl->transform_negotiate->ciphersuite_info = ssl_ciphersuite_from_id( i );
ansond 0:137634ff4186 1158
ansond 0:137634ff4186 1159 if( ssl->transform_negotiate->ciphersuite_info == NULL )
ansond 0:137634ff4186 1160 {
ansond 0:137634ff4186 1161 SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
ansond 0:137634ff4186 1162 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
ansond 0:137634ff4186 1163 }
ansond 0:137634ff4186 1164
ansond 0:137634ff4186 1165 ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
ansond 0:137634ff4186 1166
ansond 0:137634ff4186 1167 SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
ansond 0:137634ff4186 1168 SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
ansond 0:137634ff4186 1169
ansond 0:137634ff4186 1170 /*
ansond 0:137634ff4186 1171 * Check if the session can be resumed
ansond 0:137634ff4186 1172 */
ansond 0:137634ff4186 1173 if( ssl->handshake->resume == 0 || n == 0 ||
ansond 0:137634ff4186 1174 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 1175 ssl->renegotiation != SSL_INITIAL_HANDSHAKE ||
ansond 0:137634ff4186 1176 #endif
ansond 0:137634ff4186 1177 ssl->session_negotiate->ciphersuite != i ||
ansond 0:137634ff4186 1178 ssl->session_negotiate->compression != comp ||
ansond 0:137634ff4186 1179 ssl->session_negotiate->length != n ||
ansond 0:137634ff4186 1180 memcmp( ssl->session_negotiate->id, buf + 39, n ) != 0 )
ansond 0:137634ff4186 1181 {
ansond 0:137634ff4186 1182 ssl->state++;
ansond 0:137634ff4186 1183 ssl->handshake->resume = 0;
ansond 0:137634ff4186 1184 #if defined(POLARSSL_HAVE_TIME)
ansond 0:137634ff4186 1185 ssl->session_negotiate->start = time( NULL );
ansond 0:137634ff4186 1186 #endif
ansond 0:137634ff4186 1187 ssl->session_negotiate->ciphersuite = i;
ansond 0:137634ff4186 1188 ssl->session_negotiate->compression = comp;
ansond 0:137634ff4186 1189 ssl->session_negotiate->length = n;
ansond 0:137634ff4186 1190 memcpy( ssl->session_negotiate->id, buf + 39, n );
ansond 0:137634ff4186 1191 }
ansond 0:137634ff4186 1192 else
ansond 0:137634ff4186 1193 {
ansond 0:137634ff4186 1194 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
ansond 0:137634ff4186 1195
ansond 0:137634ff4186 1196 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
ansond 0:137634ff4186 1197 {
ansond 0:137634ff4186 1198 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
ansond 0:137634ff4186 1199 return( ret );
ansond 0:137634ff4186 1200 }
ansond 0:137634ff4186 1201 }
ansond 0:137634ff4186 1202
ansond 0:137634ff4186 1203 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ansond 0:137634ff4186 1204 ssl->handshake->resume ? "a" : "no" ) );
ansond 0:137634ff4186 1205
ansond 0:137634ff4186 1206 SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) );
ansond 0:137634ff4186 1207 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
ansond 0:137634ff4186 1208
ansond 0:137634ff4186 1209 suite_info = ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
ansond 0:137634ff4186 1210 if( suite_info == NULL ||
ansond 0:137634ff4186 1211 ( ssl->arc4_disabled &&
ansond 0:137634ff4186 1212 suite_info->cipher == POLARSSL_CIPHER_ARC4_128 ) )
ansond 0:137634ff4186 1213 {
ansond 0:137634ff4186 1214 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1215 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1216 }
ansond 0:137634ff4186 1217
ansond 0:137634ff4186 1218
ansond 0:137634ff4186 1219 i = 0;
ansond 0:137634ff4186 1220 while( 1 )
ansond 0:137634ff4186 1221 {
ansond 0:137634ff4186 1222 if( ssl->ciphersuite_list[ssl->minor_ver][i] == 0 )
ansond 0:137634ff4186 1223 {
ansond 0:137634ff4186 1224 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1225 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1226 }
ansond 0:137634ff4186 1227
ansond 0:137634ff4186 1228 if( ssl->ciphersuite_list[ssl->minor_ver][i++] ==
ansond 0:137634ff4186 1229 ssl->session_negotiate->ciphersuite )
ansond 0:137634ff4186 1230 {
ansond 0:137634ff4186 1231 break;
ansond 0:137634ff4186 1232 }
ansond 0:137634ff4186 1233 }
ansond 0:137634ff4186 1234
ansond 0:137634ff4186 1235 if( comp != SSL_COMPRESS_NULL
ansond 0:137634ff4186 1236 #if defined(POLARSSL_ZLIB_SUPPORT)
ansond 0:137634ff4186 1237 && comp != SSL_COMPRESS_DEFLATE
ansond 0:137634ff4186 1238 #endif
ansond 0:137634ff4186 1239 )
ansond 0:137634ff4186 1240 {
ansond 0:137634ff4186 1241 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1242 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1243 }
ansond 0:137634ff4186 1244 ssl->session_negotiate->compression = comp;
ansond 0:137634ff4186 1245
ansond 0:137634ff4186 1246 ext = buf + 44 + n;
ansond 0:137634ff4186 1247
ansond 0:137634ff4186 1248 SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
ansond 0:137634ff4186 1249
ansond 0:137634ff4186 1250 while( ext_len )
ansond 0:137634ff4186 1251 {
ansond 0:137634ff4186 1252 unsigned int ext_id = ( ( ext[0] << 8 )
ansond 0:137634ff4186 1253 | ( ext[1] ) );
ansond 0:137634ff4186 1254 unsigned int ext_size = ( ( ext[2] << 8 )
ansond 0:137634ff4186 1255 | ( ext[3] ) );
ansond 0:137634ff4186 1256
ansond 0:137634ff4186 1257 if( ext_size + 4 > ext_len )
ansond 0:137634ff4186 1258 {
ansond 0:137634ff4186 1259 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1260 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1261 }
ansond 0:137634ff4186 1262
ansond 0:137634ff4186 1263 switch( ext_id )
ansond 0:137634ff4186 1264 {
ansond 0:137634ff4186 1265 case TLS_EXT_RENEGOTIATION_INFO:
ansond 0:137634ff4186 1266 SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
ansond 0:137634ff4186 1267 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 1268 renegotiation_info_seen = 1;
ansond 0:137634ff4186 1269 #endif
ansond 0:137634ff4186 1270
ansond 0:137634ff4186 1271 if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
ansond 0:137634ff4186 1272 ext_size ) ) != 0 )
ansond 0:137634ff4186 1273 return( ret );
ansond 0:137634ff4186 1274
ansond 0:137634ff4186 1275 break;
ansond 0:137634ff4186 1276
ansond 0:137634ff4186 1277 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
ansond 0:137634ff4186 1278 case TLS_EXT_MAX_FRAGMENT_LENGTH:
ansond 0:137634ff4186 1279 SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
ansond 0:137634ff4186 1280
ansond 0:137634ff4186 1281 if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
ansond 0:137634ff4186 1282 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1283 {
ansond 0:137634ff4186 1284 return( ret );
ansond 0:137634ff4186 1285 }
ansond 0:137634ff4186 1286
ansond 0:137634ff4186 1287 break;
ansond 0:137634ff4186 1288 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
ansond 0:137634ff4186 1289
ansond 0:137634ff4186 1290 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
ansond 0:137634ff4186 1291 case TLS_EXT_TRUNCATED_HMAC:
ansond 0:137634ff4186 1292 SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
ansond 0:137634ff4186 1293
ansond 0:137634ff4186 1294 if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
ansond 0:137634ff4186 1295 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1296 {
ansond 0:137634ff4186 1297 return( ret );
ansond 0:137634ff4186 1298 }
ansond 0:137634ff4186 1299
ansond 0:137634ff4186 1300 break;
ansond 0:137634ff4186 1301 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
ansond 0:137634ff4186 1302
ansond 0:137634ff4186 1303 #if defined(POLARSSL_SSL_ENCRYPT_THEN_MAC)
ansond 0:137634ff4186 1304 case TLS_EXT_ENCRYPT_THEN_MAC:
ansond 0:137634ff4186 1305 SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
ansond 0:137634ff4186 1306
ansond 0:137634ff4186 1307 if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
ansond 0:137634ff4186 1308 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1309 {
ansond 0:137634ff4186 1310 return( ret );
ansond 0:137634ff4186 1311 }
ansond 0:137634ff4186 1312
ansond 0:137634ff4186 1313 break;
ansond 0:137634ff4186 1314 #endif /* POLARSSL_SSL_ENCRYPT_THEN_MAC */
ansond 0:137634ff4186 1315
ansond 0:137634ff4186 1316 #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
ansond 0:137634ff4186 1317 case TLS_EXT_EXTENDED_MASTER_SECRET:
ansond 0:137634ff4186 1318 SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
ansond 0:137634ff4186 1319
ansond 0:137634ff4186 1320 if( ( ret = ssl_parse_extended_ms_ext( ssl,
ansond 0:137634ff4186 1321 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1322 {
ansond 0:137634ff4186 1323 return( ret );
ansond 0:137634ff4186 1324 }
ansond 0:137634ff4186 1325
ansond 0:137634ff4186 1326 break;
ansond 0:137634ff4186 1327 #endif /* POLARSSL_SSL_EXTENDED_MASTER_SECRET */
ansond 0:137634ff4186 1328
ansond 0:137634ff4186 1329 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 1330 case TLS_EXT_SESSION_TICKET:
ansond 0:137634ff4186 1331 SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
ansond 0:137634ff4186 1332
ansond 0:137634ff4186 1333 if( ( ret = ssl_parse_session_ticket_ext( ssl,
ansond 0:137634ff4186 1334 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1335 {
ansond 0:137634ff4186 1336 return( ret );
ansond 0:137634ff4186 1337 }
ansond 0:137634ff4186 1338
ansond 0:137634ff4186 1339 break;
ansond 0:137634ff4186 1340 #endif /* POLARSSL_SSL_SESSION_TICKETS */
ansond 0:137634ff4186 1341
ansond 0:137634ff4186 1342 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 1343 case TLS_EXT_SUPPORTED_POINT_FORMATS:
ansond 0:137634ff4186 1344 SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
ansond 0:137634ff4186 1345
ansond 0:137634ff4186 1346 if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
ansond 0:137634ff4186 1347 ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1348 {
ansond 0:137634ff4186 1349 return( ret );
ansond 0:137634ff4186 1350 }
ansond 0:137634ff4186 1351
ansond 0:137634ff4186 1352 break;
ansond 0:137634ff4186 1353 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
ansond 0:137634ff4186 1354
ansond 0:137634ff4186 1355 #if defined(POLARSSL_SSL_ALPN)
ansond 0:137634ff4186 1356 case TLS_EXT_ALPN:
ansond 0:137634ff4186 1357 SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
ansond 0:137634ff4186 1358
ansond 0:137634ff4186 1359 if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
ansond 0:137634ff4186 1360 return( ret );
ansond 0:137634ff4186 1361
ansond 0:137634ff4186 1362 break;
ansond 0:137634ff4186 1363 #endif /* POLARSSL_SSL_ALPN */
ansond 0:137634ff4186 1364
ansond 0:137634ff4186 1365 default:
ansond 0:137634ff4186 1366 SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
ansond 0:137634ff4186 1367 ext_id ) );
ansond 0:137634ff4186 1368 }
ansond 0:137634ff4186 1369
ansond 0:137634ff4186 1370 ext_len -= 4 + ext_size;
ansond 0:137634ff4186 1371 ext += 4 + ext_size;
ansond 0:137634ff4186 1372
ansond 0:137634ff4186 1373 if( ext_len > 0 && ext_len < 4 )
ansond 0:137634ff4186 1374 {
ansond 0:137634ff4186 1375 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
ansond 0:137634ff4186 1376 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1377 }
ansond 0:137634ff4186 1378 }
ansond 0:137634ff4186 1379
ansond 0:137634ff4186 1380 /*
ansond 0:137634ff4186 1381 * Renegotiation security checks
ansond 0:137634ff4186 1382 */
ansond 0:137634ff4186 1383 if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
ansond 0:137634ff4186 1384 ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
ansond 0:137634ff4186 1385 {
ansond 0:137634ff4186 1386 SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
ansond 0:137634ff4186 1387 handshake_failure = 1;
ansond 0:137634ff4186 1388 }
ansond 0:137634ff4186 1389 #if defined(POLARSSL_SSL_RENEGOTIATION)
ansond 0:137634ff4186 1390 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
ansond 0:137634ff4186 1391 ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
ansond 0:137634ff4186 1392 renegotiation_info_seen == 0 )
ansond 0:137634ff4186 1393 {
ansond 0:137634ff4186 1394 SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
ansond 0:137634ff4186 1395 handshake_failure = 1;
ansond 0:137634ff4186 1396 }
ansond 0:137634ff4186 1397 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
ansond 0:137634ff4186 1398 ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
ansond 0:137634ff4186 1399 ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION )
ansond 0:137634ff4186 1400 {
ansond 0:137634ff4186 1401 SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
ansond 0:137634ff4186 1402 handshake_failure = 1;
ansond 0:137634ff4186 1403 }
ansond 0:137634ff4186 1404 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
ansond 0:137634ff4186 1405 ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
ansond 0:137634ff4186 1406 renegotiation_info_seen == 1 )
ansond 0:137634ff4186 1407 {
ansond 0:137634ff4186 1408 SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
ansond 0:137634ff4186 1409 handshake_failure = 1;
ansond 0:137634ff4186 1410 }
ansond 0:137634ff4186 1411 #endif /* POLARSSL_SSL_RENEGOTIATION */
ansond 0:137634ff4186 1412
ansond 0:137634ff4186 1413 if( handshake_failure == 1 )
ansond 0:137634ff4186 1414 {
ansond 0:137634ff4186 1415 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
ansond 0:137634ff4186 1416 return( ret );
ansond 0:137634ff4186 1417
ansond 0:137634ff4186 1418 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
ansond 0:137634ff4186 1419 }
ansond 0:137634ff4186 1420
ansond 0:137634ff4186 1421 SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
ansond 0:137634ff4186 1422
ansond 0:137634ff4186 1423 return( 0 );
ansond 0:137634ff4186 1424 }
ansond 0:137634ff4186 1425
ansond 0:137634ff4186 1426 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1427 defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
ansond 0:137634ff4186 1428 static int ssl_parse_server_dh_params( ssl_context *ssl, unsigned char **p,
ansond 0:137634ff4186 1429 unsigned char *end )
ansond 0:137634ff4186 1430 {
ansond 0:137634ff4186 1431 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
ansond 0:137634ff4186 1432
ansond 0:137634ff4186 1433 /*
ansond 0:137634ff4186 1434 * Ephemeral DH parameters:
ansond 0:137634ff4186 1435 *
ansond 0:137634ff4186 1436 * struct {
ansond 0:137634ff4186 1437 * opaque dh_p<1..2^16-1>;
ansond 0:137634ff4186 1438 * opaque dh_g<1..2^16-1>;
ansond 0:137634ff4186 1439 * opaque dh_Ys<1..2^16-1>;
ansond 0:137634ff4186 1440 * } ServerDHParams;
ansond 0:137634ff4186 1441 */
ansond 0:137634ff4186 1442 if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
ansond 0:137634ff4186 1443 {
ansond 0:137634ff4186 1444 SSL_DEBUG_RET( 2, ( "dhm_read_params" ), ret );
ansond 0:137634ff4186 1445 return( ret );
ansond 0:137634ff4186 1446 }
ansond 0:137634ff4186 1447
ansond 0:137634ff4186 1448 if( ssl->handshake->dhm_ctx.len < 64 ||
ansond 0:137634ff4186 1449 ssl->handshake->dhm_ctx.len > 512 )
ansond 0:137634ff4186 1450 {
ansond 0:137634ff4186 1451 SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) );
ansond 0:137634ff4186 1452 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1453 }
ansond 0:137634ff4186 1454
ansond 0:137634ff4186 1455 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
ansond 0:137634ff4186 1456 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
ansond 0:137634ff4186 1457 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
ansond 0:137634ff4186 1458
ansond 0:137634ff4186 1459 return( ret );
ansond 0:137634ff4186 1460 }
ansond 0:137634ff4186 1461 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
ansond 0:137634ff4186 1462 POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
ansond 0:137634ff4186 1463
ansond 0:137634ff4186 1464 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1465 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
ansond 0:137634ff4186 1466 defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
ansond 0:137634ff4186 1467 defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
ansond 0:137634ff4186 1468 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
ansond 0:137634ff4186 1469 static int ssl_check_server_ecdh_params( const ssl_context *ssl )
ansond 0:137634ff4186 1470 {
ansond 0:137634ff4186 1471 const ecp_curve_info *curve_info;
ansond 0:137634ff4186 1472
ansond 0:137634ff4186 1473 curve_info = ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
ansond 0:137634ff4186 1474 if( curve_info == NULL )
ansond 0:137634ff4186 1475 {
ansond 0:137634ff4186 1476 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 1477 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 1478 }
ansond 0:137634ff4186 1479
ansond 0:137634ff4186 1480 SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
ansond 0:137634ff4186 1481
ansond 0:137634ff4186 1482 #if defined(POLARSSL_SSL_SET_CURVES)
ansond 0:137634ff4186 1483 if( ! ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) )
ansond 0:137634ff4186 1484 #else
ansond 0:137634ff4186 1485 if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
ansond 0:137634ff4186 1486 ssl->handshake->ecdh_ctx.grp.nbits > 521 )
ansond 0:137634ff4186 1487 #endif
ansond 0:137634ff4186 1488 return( -1 );
ansond 0:137634ff4186 1489
ansond 0:137634ff4186 1490 SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
ansond 0:137634ff4186 1491
ansond 0:137634ff4186 1492 return( 0 );
ansond 0:137634ff4186 1493 }
ansond 0:137634ff4186 1494 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 1495 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
ansond 0:137634ff4186 1496 POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
ansond 0:137634ff4186 1497 POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
ansond 0:137634ff4186 1498 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
ansond 0:137634ff4186 1499
ansond 0:137634ff4186 1500 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1501 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
ansond 0:137634ff4186 1502 defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
ansond 0:137634ff4186 1503 static int ssl_parse_server_ecdh_params( ssl_context *ssl,
ansond 0:137634ff4186 1504 unsigned char **p,
ansond 0:137634ff4186 1505 unsigned char *end )
ansond 0:137634ff4186 1506 {
ansond 0:137634ff4186 1507 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
ansond 0:137634ff4186 1508
ansond 0:137634ff4186 1509 /*
ansond 0:137634ff4186 1510 * Ephemeral ECDH parameters:
ansond 0:137634ff4186 1511 *
ansond 0:137634ff4186 1512 * struct {
ansond 0:137634ff4186 1513 * ECParameters curve_params;
ansond 0:137634ff4186 1514 * ECPoint public;
ansond 0:137634ff4186 1515 * } ServerECDHParams;
ansond 0:137634ff4186 1516 */
ansond 0:137634ff4186 1517 if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx,
ansond 0:137634ff4186 1518 (const unsigned char **) p, end ) ) != 0 )
ansond 0:137634ff4186 1519 {
ansond 0:137634ff4186 1520 SSL_DEBUG_RET( 1, ( "ecdh_read_params" ), ret );
ansond 0:137634ff4186 1521 return( ret );
ansond 0:137634ff4186 1522 }
ansond 0:137634ff4186 1523
ansond 0:137634ff4186 1524 if( ssl_check_server_ecdh_params( ssl ) != 0 )
ansond 0:137634ff4186 1525 {
ansond 0:137634ff4186 1526 SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
ansond 0:137634ff4186 1527 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1528 }
ansond 0:137634ff4186 1529
ansond 0:137634ff4186 1530 return( ret );
ansond 0:137634ff4186 1531 }
ansond 0:137634ff4186 1532 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 1533 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
ansond 0:137634ff4186 1534 POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
ansond 0:137634ff4186 1535
ansond 0:137634ff4186 1536 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
ansond 0:137634ff4186 1537 static int ssl_parse_server_psk_hint( ssl_context *ssl,
ansond 0:137634ff4186 1538 unsigned char **p,
ansond 0:137634ff4186 1539 unsigned char *end )
ansond 0:137634ff4186 1540 {
ansond 0:137634ff4186 1541 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
ansond 0:137634ff4186 1542 size_t len;
ansond 0:137634ff4186 1543 ((void) ssl);
ansond 0:137634ff4186 1544
ansond 0:137634ff4186 1545 /*
ansond 0:137634ff4186 1546 * PSK parameters:
ansond 0:137634ff4186 1547 *
ansond 0:137634ff4186 1548 * opaque psk_identity_hint<0..2^16-1>;
ansond 0:137634ff4186 1549 */
ansond 0:137634ff4186 1550 len = (*p)[0] << 8 | (*p)[1];
ansond 0:137634ff4186 1551 *p += 2;
ansond 0:137634ff4186 1552
ansond 0:137634ff4186 1553 if( (*p) + len > end )
ansond 0:137634ff4186 1554 {
ansond 0:137634ff4186 1555 SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
ansond 0:137634ff4186 1556 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1557 }
ansond 0:137634ff4186 1558
ansond 0:137634ff4186 1559 // TODO: Retrieve PSK identity hint and callback to app
ansond 0:137634ff4186 1560 //
ansond 0:137634ff4186 1561 *p += len;
ansond 0:137634ff4186 1562 ret = 0;
ansond 0:137634ff4186 1563
ansond 0:137634ff4186 1564 return( ret );
ansond 0:137634ff4186 1565 }
ansond 0:137634ff4186 1566 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
ansond 0:137634ff4186 1567
ansond 0:137634ff4186 1568 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \
ansond 0:137634ff4186 1569 defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
ansond 0:137634ff4186 1570 /*
ansond 0:137634ff4186 1571 * Generate a pre-master secret and encrypt it with the server's RSA key
ansond 0:137634ff4186 1572 */
ansond 0:137634ff4186 1573 static int ssl_write_encrypted_pms( ssl_context *ssl,
ansond 0:137634ff4186 1574 size_t offset, size_t *olen,
ansond 0:137634ff4186 1575 size_t pms_offset )
ansond 0:137634ff4186 1576 {
ansond 0:137634ff4186 1577 int ret;
ansond 0:137634ff4186 1578 size_t len_bytes = ssl->minor_ver == SSL_MINOR_VERSION_0 ? 0 : 2;
ansond 0:137634ff4186 1579 unsigned char *p = ssl->handshake->premaster + pms_offset;
ansond 0:137634ff4186 1580
ansond 0:137634ff4186 1581 /*
ansond 0:137634ff4186 1582 * Generate (part of) the pre-master as
ansond 0:137634ff4186 1583 * struct {
ansond 0:137634ff4186 1584 * ProtocolVersion client_version;
ansond 0:137634ff4186 1585 * opaque random[46];
ansond 0:137634ff4186 1586 * } PreMasterSecret;
ansond 0:137634ff4186 1587 */
ansond 0:137634ff4186 1588 p[0] = (unsigned char) ssl->max_major_ver;
ansond 0:137634ff4186 1589 p[1] = (unsigned char) ssl->max_minor_ver;
ansond 0:137634ff4186 1590
ansond 0:137634ff4186 1591 if( ( ret = ssl->f_rng( ssl->p_rng, p + 2, 46 ) ) != 0 )
ansond 0:137634ff4186 1592 {
ansond 0:137634ff4186 1593 SSL_DEBUG_RET( 1, "f_rng", ret );
ansond 0:137634ff4186 1594 return( ret );
ansond 0:137634ff4186 1595 }
ansond 0:137634ff4186 1596
ansond 0:137634ff4186 1597 ssl->handshake->pmslen = 48;
ansond 0:137634ff4186 1598
ansond 0:137634ff4186 1599 /*
ansond 0:137634ff4186 1600 * Now write it out, encrypted
ansond 0:137634ff4186 1601 */
ansond 0:137634ff4186 1602 if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
ansond 0:137634ff4186 1603 POLARSSL_PK_RSA ) )
ansond 0:137634ff4186 1604 {
ansond 0:137634ff4186 1605 SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
ansond 0:137634ff4186 1606 return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
ansond 0:137634ff4186 1607 }
ansond 0:137634ff4186 1608
ansond 0:137634ff4186 1609 if( ( ret = pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
ansond 0:137634ff4186 1610 p, ssl->handshake->pmslen,
ansond 0:137634ff4186 1611 ssl->out_msg + offset + len_bytes, olen,
ansond 0:137634ff4186 1612 SSL_MAX_CONTENT_LEN - offset - len_bytes,
ansond 0:137634ff4186 1613 ssl->f_rng, ssl->p_rng ) ) != 0 )
ansond 0:137634ff4186 1614 {
ansond 0:137634ff4186 1615 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
ansond 0:137634ff4186 1616 return( ret );
ansond 0:137634ff4186 1617 }
ansond 0:137634ff4186 1618
ansond 0:137634ff4186 1619 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
ansond 0:137634ff4186 1620 defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 1621 if( len_bytes == 2 )
ansond 0:137634ff4186 1622 {
ansond 0:137634ff4186 1623 ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
ansond 0:137634ff4186 1624 ssl->out_msg[offset+1] = (unsigned char)( *olen );
ansond 0:137634ff4186 1625 *olen += 2;
ansond 0:137634ff4186 1626 }
ansond 0:137634ff4186 1627 #endif
ansond 0:137634ff4186 1628
ansond 0:137634ff4186 1629 return( 0 );
ansond 0:137634ff4186 1630 }
ansond 0:137634ff4186 1631 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED ||
ansond 0:137634ff4186 1632 POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
ansond 0:137634ff4186 1633
ansond 0:137634ff4186 1634 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 1635 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1636 defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1637 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 1638 static int ssl_parse_signature_algorithm( ssl_context *ssl,
ansond 0:137634ff4186 1639 unsigned char **p,
ansond 0:137634ff4186 1640 unsigned char *end,
ansond 0:137634ff4186 1641 md_type_t *md_alg,
ansond 0:137634ff4186 1642 pk_type_t *pk_alg )
ansond 0:137634ff4186 1643 {
ansond 0:137634ff4186 1644 ((void) ssl);
ansond 0:137634ff4186 1645 *md_alg = POLARSSL_MD_NONE;
ansond 0:137634ff4186 1646 *pk_alg = POLARSSL_PK_NONE;
ansond 0:137634ff4186 1647
ansond 0:137634ff4186 1648 /* Only in TLS 1.2 */
ansond 0:137634ff4186 1649 if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 1650 {
ansond 0:137634ff4186 1651 return( 0 );
ansond 0:137634ff4186 1652 }
ansond 0:137634ff4186 1653
ansond 0:137634ff4186 1654 if( (*p) + 2 > end )
ansond 0:137634ff4186 1655 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1656
ansond 0:137634ff4186 1657 /*
ansond 0:137634ff4186 1658 * Get hash algorithm
ansond 0:137634ff4186 1659 */
ansond 0:137634ff4186 1660 if( ( *md_alg = ssl_md_alg_from_hash( (*p)[0] ) ) == POLARSSL_MD_NONE )
ansond 0:137634ff4186 1661 {
ansond 0:137634ff4186 1662 SSL_DEBUG_MSG( 2, ( "Server used unsupported "
ansond 0:137634ff4186 1663 "HashAlgorithm %d", *(p)[0] ) );
ansond 0:137634ff4186 1664 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1665 }
ansond 0:137634ff4186 1666
ansond 0:137634ff4186 1667 /*
ansond 0:137634ff4186 1668 * Get signature algorithm
ansond 0:137634ff4186 1669 */
ansond 0:137634ff4186 1670 if( ( *pk_alg = ssl_pk_alg_from_sig( (*p)[1] ) ) == POLARSSL_PK_NONE )
ansond 0:137634ff4186 1671 {
ansond 0:137634ff4186 1672 SSL_DEBUG_MSG( 2, ( "server used unsupported "
ansond 0:137634ff4186 1673 "SignatureAlgorithm %d", (*p)[1] ) );
ansond 0:137634ff4186 1674 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1675 }
ansond 0:137634ff4186 1676
ansond 0:137634ff4186 1677 SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
ansond 0:137634ff4186 1678 SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
ansond 0:137634ff4186 1679 *p += 2;
ansond 0:137634ff4186 1680
ansond 0:137634ff4186 1681 return( 0 );
ansond 0:137634ff4186 1682 }
ansond 0:137634ff4186 1683 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
ansond 0:137634ff4186 1684 POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 1685 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
ansond 0:137634ff4186 1686 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
ansond 0:137634ff4186 1687
ansond 0:137634ff4186 1688
ansond 0:137634ff4186 1689 #if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
ansond 0:137634ff4186 1690 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
ansond 0:137634ff4186 1691 static int ssl_get_ecdh_params_from_cert( ssl_context *ssl )
ansond 0:137634ff4186 1692 {
ansond 0:137634ff4186 1693 int ret;
ansond 0:137634ff4186 1694 const ecp_keypair *peer_key;
ansond 0:137634ff4186 1695
ansond 0:137634ff4186 1696 if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
ansond 0:137634ff4186 1697 POLARSSL_PK_ECKEY ) )
ansond 0:137634ff4186 1698 {
ansond 0:137634ff4186 1699 SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
ansond 0:137634ff4186 1700 return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
ansond 0:137634ff4186 1701 }
ansond 0:137634ff4186 1702
ansond 0:137634ff4186 1703 peer_key = pk_ec( ssl->session_negotiate->peer_cert->pk );
ansond 0:137634ff4186 1704
ansond 0:137634ff4186 1705 if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
ansond 0:137634ff4186 1706 POLARSSL_ECDH_THEIRS ) ) != 0 )
ansond 0:137634ff4186 1707 {
ansond 0:137634ff4186 1708 SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret );
ansond 0:137634ff4186 1709 return( ret );
ansond 0:137634ff4186 1710 }
ansond 0:137634ff4186 1711
ansond 0:137634ff4186 1712 if( ssl_check_server_ecdh_params( ssl ) != 0 )
ansond 0:137634ff4186 1713 {
ansond 0:137634ff4186 1714 SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
ansond 0:137634ff4186 1715 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
ansond 0:137634ff4186 1716 }
ansond 0:137634ff4186 1717
ansond 0:137634ff4186 1718 return( ret );
ansond 0:137634ff4186 1719 }
ansond 0:137634ff4186 1720 #endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
ansond 0:137634ff4186 1721 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
ansond 0:137634ff4186 1722
ansond 0:137634ff4186 1723 static int ssl_parse_server_key_exchange( ssl_context *ssl )
ansond 0:137634ff4186 1724 {
ansond 0:137634ff4186 1725 int ret;
ansond 0:137634ff4186 1726 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 1727 unsigned char *p, *end;
ansond 0:137634ff4186 1728 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1729 defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1730 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 1731 size_t sig_len, params_len;
ansond 0:137634ff4186 1732 unsigned char hash[64];
ansond 0:137634ff4186 1733 md_type_t md_alg = POLARSSL_MD_NONE;
ansond 0:137634ff4186 1734 size_t hashlen;
ansond 0:137634ff4186 1735 pk_type_t pk_alg = POLARSSL_PK_NONE;
ansond 0:137634ff4186 1736 #endif
ansond 0:137634ff4186 1737
ansond 0:137634ff4186 1738 SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
ansond 0:137634ff4186 1739
ansond 0:137634ff4186 1740 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
ansond 0:137634ff4186 1741 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
ansond 0:137634ff4186 1742 {
ansond 0:137634ff4186 1743 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ansond 0:137634ff4186 1744 ssl->state++;
ansond 0:137634ff4186 1745 return( 0 );
ansond 0:137634ff4186 1746 }
ansond 0:137634ff4186 1747 ((void) p);
ansond 0:137634ff4186 1748 ((void) end);
ansond 0:137634ff4186 1749 #endif
ansond 0:137634ff4186 1750
ansond 0:137634ff4186 1751 #if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
ansond 0:137634ff4186 1752 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
ansond 0:137634ff4186 1753 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
ansond 0:137634ff4186 1754 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
ansond 0:137634ff4186 1755 {
ansond 0:137634ff4186 1756 if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
ansond 0:137634ff4186 1757 {
ansond 0:137634ff4186 1758 SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
ansond 0:137634ff4186 1759 return( ret );
ansond 0:137634ff4186 1760 }
ansond 0:137634ff4186 1761
ansond 0:137634ff4186 1762 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ansond 0:137634ff4186 1763 ssl->state++;
ansond 0:137634ff4186 1764 return( 0 );
ansond 0:137634ff4186 1765 }
ansond 0:137634ff4186 1766 ((void) p);
ansond 0:137634ff4186 1767 ((void) end);
ansond 0:137634ff4186 1768 #endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
ansond 0:137634ff4186 1769 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
ansond 0:137634ff4186 1770
ansond 0:137634ff4186 1771 if( ( ret = ssl_read_record( ssl ) ) != 0 )
ansond 0:137634ff4186 1772 {
ansond 0:137634ff4186 1773 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
ansond 0:137634ff4186 1774 return( ret );
ansond 0:137634ff4186 1775 }
ansond 0:137634ff4186 1776
ansond 0:137634ff4186 1777 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
ansond 0:137634ff4186 1778 {
ansond 0:137634ff4186 1779 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1780 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 1781 }
ansond 0:137634ff4186 1782
ansond 0:137634ff4186 1783 /*
ansond 0:137634ff4186 1784 * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
ansond 0:137634ff4186 1785 * doesn't use a psk_identity_hint
ansond 0:137634ff4186 1786 */
ansond 0:137634ff4186 1787 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
ansond 0:137634ff4186 1788 {
ansond 0:137634ff4186 1789 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 1790 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
ansond 0:137634ff4186 1791 {
ansond 0:137634ff4186 1792 ssl->record_read = 1;
ansond 0:137634ff4186 1793 goto exit;
ansond 0:137634ff4186 1794 }
ansond 0:137634ff4186 1795
ansond 0:137634ff4186 1796 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1797 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 1798 }
ansond 0:137634ff4186 1799
ansond 0:137634ff4186 1800 p = ssl->in_msg + 4;
ansond 0:137634ff4186 1801 end = ssl->in_msg + ssl->in_hslen;
ansond 0:137634ff4186 1802 SSL_DEBUG_BUF( 3, "server key exchange", p, ssl->in_hslen - 4 );
ansond 0:137634ff4186 1803
ansond 0:137634ff4186 1804 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
ansond 0:137634ff4186 1805 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 1806 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 1807 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
ansond 0:137634ff4186 1808 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
ansond 0:137634ff4186 1809 {
ansond 0:137634ff4186 1810 if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
ansond 0:137634ff4186 1811 {
ansond 0:137634ff4186 1812 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1813 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1814 }
ansond 0:137634ff4186 1815 } /* FALLTROUGH */
ansond 0:137634ff4186 1816 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
ansond 0:137634ff4186 1817
ansond 0:137634ff4186 1818 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \
ansond 0:137634ff4186 1819 defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
ansond 0:137634ff4186 1820 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 1821 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
ansond 0:137634ff4186 1822 ; /* nothing more to do */
ansond 0:137634ff4186 1823 else
ansond 0:137634ff4186 1824 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
ansond 0:137634ff4186 1825 POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
ansond 0:137634ff4186 1826 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1827 defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
ansond 0:137634ff4186 1828 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
ansond 0:137634ff4186 1829 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
ansond 0:137634ff4186 1830 {
ansond 0:137634ff4186 1831 if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
ansond 0:137634ff4186 1832 {
ansond 0:137634ff4186 1833 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1834 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1835 }
ansond 0:137634ff4186 1836 }
ansond 0:137634ff4186 1837 else
ansond 0:137634ff4186 1838 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
ansond 0:137634ff4186 1839 POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
ansond 0:137634ff4186 1840 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1841 defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
ansond 0:137634ff4186 1842 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 1843 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
ansond 0:137634ff4186 1844 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
ansond 0:137634ff4186 1845 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
ansond 0:137634ff4186 1846 {
ansond 0:137634ff4186 1847 if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
ansond 0:137634ff4186 1848 {
ansond 0:137634ff4186 1849 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1850 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1851 }
ansond 0:137634ff4186 1852 }
ansond 0:137634ff4186 1853 else
ansond 0:137634ff4186 1854 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 1855 POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
ansond 0:137634ff4186 1856 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
ansond 0:137634ff4186 1857 {
ansond 0:137634ff4186 1858 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 1859 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 1860 }
ansond 0:137634ff4186 1861
ansond 0:137634ff4186 1862 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1863 defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 1864 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 1865 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
ansond 0:137634ff4186 1866 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
ansond 0:137634ff4186 1867 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
ansond 0:137634ff4186 1868 {
ansond 0:137634ff4186 1869 params_len = p - ( ssl->in_msg + 4 );
ansond 0:137634ff4186 1870
ansond 0:137634ff4186 1871 /*
ansond 0:137634ff4186 1872 * Handle the digitally-signed structure
ansond 0:137634ff4186 1873 */
ansond 0:137634ff4186 1874 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 1875 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 1876 {
ansond 0:137634ff4186 1877 if( ssl_parse_signature_algorithm( ssl, &p, end,
ansond 0:137634ff4186 1878 &md_alg, &pk_alg ) != 0 )
ansond 0:137634ff4186 1879 {
ansond 0:137634ff4186 1880 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1881 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1882 }
ansond 0:137634ff4186 1883
ansond 0:137634ff4186 1884 if( pk_alg != ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
ansond 0:137634ff4186 1885 {
ansond 0:137634ff4186 1886 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1887 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1888 }
ansond 0:137634ff4186 1889 }
ansond 0:137634ff4186 1890 else
ansond 0:137634ff4186 1891 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
ansond 0:137634ff4186 1892 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
ansond 0:137634ff4186 1893 defined(POLARSSL_SSL_PROTO_TLS1_1)
ansond 0:137634ff4186 1894 if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 1895 {
ansond 0:137634ff4186 1896 pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
ansond 0:137634ff4186 1897
ansond 0:137634ff4186 1898 /* Default hash for ECDSA is SHA-1 */
ansond 0:137634ff4186 1899 if( pk_alg == POLARSSL_PK_ECDSA && md_alg == POLARSSL_MD_NONE )
ansond 0:137634ff4186 1900 md_alg = POLARSSL_MD_SHA1;
ansond 0:137634ff4186 1901 }
ansond 0:137634ff4186 1902 else
ansond 0:137634ff4186 1903 #endif
ansond 0:137634ff4186 1904 {
ansond 0:137634ff4186 1905 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 1906 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 1907 }
ansond 0:137634ff4186 1908
ansond 0:137634ff4186 1909 /*
ansond 0:137634ff4186 1910 * Read signature
ansond 0:137634ff4186 1911 */
ansond 0:137634ff4186 1912 sig_len = ( p[0] << 8 ) | p[1];
ansond 0:137634ff4186 1913 p += 2;
ansond 0:137634ff4186 1914
ansond 0:137634ff4186 1915 if( end != p + sig_len )
ansond 0:137634ff4186 1916 {
ansond 0:137634ff4186 1917 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 1918 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
ansond 0:137634ff4186 1919 }
ansond 0:137634ff4186 1920
ansond 0:137634ff4186 1921 SSL_DEBUG_BUF( 3, "signature", p, sig_len );
ansond 0:137634ff4186 1922
ansond 0:137634ff4186 1923 /*
ansond 0:137634ff4186 1924 * Compute the hash that has been signed
ansond 0:137634ff4186 1925 */
ansond 0:137634ff4186 1926 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
ansond 0:137634ff4186 1927 defined(POLARSSL_SSL_PROTO_TLS1_1)
ansond 0:137634ff4186 1928 if( md_alg == POLARSSL_MD_NONE )
ansond 0:137634ff4186 1929 {
ansond 0:137634ff4186 1930 md5_context md5;
ansond 0:137634ff4186 1931 sha1_context sha1;
ansond 0:137634ff4186 1932
ansond 0:137634ff4186 1933 md5_init( &md5 );
ansond 0:137634ff4186 1934 sha1_init( &sha1 );
ansond 0:137634ff4186 1935
ansond 0:137634ff4186 1936 hashlen = 36;
ansond 0:137634ff4186 1937
ansond 0:137634ff4186 1938 /*
ansond 0:137634ff4186 1939 * digitally-signed struct {
ansond 0:137634ff4186 1940 * opaque md5_hash[16];
ansond 0:137634ff4186 1941 * opaque sha_hash[20];
ansond 0:137634ff4186 1942 * };
ansond 0:137634ff4186 1943 *
ansond 0:137634ff4186 1944 * md5_hash
ansond 0:137634ff4186 1945 * MD5(ClientHello.random + ServerHello.random
ansond 0:137634ff4186 1946 * + ServerParams);
ansond 0:137634ff4186 1947 * sha_hash
ansond 0:137634ff4186 1948 * SHA(ClientHello.random + ServerHello.random
ansond 0:137634ff4186 1949 * + ServerParams);
ansond 0:137634ff4186 1950 */
ansond 0:137634ff4186 1951 md5_starts( &md5 );
ansond 0:137634ff4186 1952 md5_update( &md5, ssl->handshake->randbytes, 64 );
ansond 0:137634ff4186 1953 md5_update( &md5, ssl->in_msg + 4, params_len );
ansond 0:137634ff4186 1954 md5_finish( &md5, hash );
ansond 0:137634ff4186 1955
ansond 0:137634ff4186 1956 sha1_starts( &sha1 );
ansond 0:137634ff4186 1957 sha1_update( &sha1, ssl->handshake->randbytes, 64 );
ansond 0:137634ff4186 1958 sha1_update( &sha1, ssl->in_msg + 4, params_len );
ansond 0:137634ff4186 1959 sha1_finish( &sha1, hash + 16 );
ansond 0:137634ff4186 1960
ansond 0:137634ff4186 1961 md5_free( &md5 );
ansond 0:137634ff4186 1962 sha1_free( &sha1 );
ansond 0:137634ff4186 1963 }
ansond 0:137634ff4186 1964 else
ansond 0:137634ff4186 1965 #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
ansond 0:137634ff4186 1966 POLARSSL_SSL_PROTO_TLS1_1 */
ansond 0:137634ff4186 1967 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
ansond 0:137634ff4186 1968 defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 1969 if( md_alg != POLARSSL_MD_NONE )
ansond 0:137634ff4186 1970 {
ansond 0:137634ff4186 1971 md_context_t ctx;
ansond 0:137634ff4186 1972
ansond 0:137634ff4186 1973 md_init( &ctx );
ansond 0:137634ff4186 1974
ansond 0:137634ff4186 1975 /* Info from md_alg will be used instead */
ansond 0:137634ff4186 1976 hashlen = 0;
ansond 0:137634ff4186 1977
ansond 0:137634ff4186 1978 /*
ansond 0:137634ff4186 1979 * digitally-signed struct {
ansond 0:137634ff4186 1980 * opaque client_random[32];
ansond 0:137634ff4186 1981 * opaque server_random[32];
ansond 0:137634ff4186 1982 * ServerDHParams params;
ansond 0:137634ff4186 1983 * };
ansond 0:137634ff4186 1984 */
ansond 0:137634ff4186 1985 if( ( ret = md_init_ctx( &ctx,
ansond 0:137634ff4186 1986 md_info_from_type( md_alg ) ) ) != 0 )
ansond 0:137634ff4186 1987 {
ansond 0:137634ff4186 1988 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
ansond 0:137634ff4186 1989 return( ret );
ansond 0:137634ff4186 1990 }
ansond 0:137634ff4186 1991
ansond 0:137634ff4186 1992 md_starts( &ctx );
ansond 0:137634ff4186 1993 md_update( &ctx, ssl->handshake->randbytes, 64 );
ansond 0:137634ff4186 1994 md_update( &ctx, ssl->in_msg + 4, params_len );
ansond 0:137634ff4186 1995 md_finish( &ctx, hash );
ansond 0:137634ff4186 1996 md_free( &ctx );
ansond 0:137634ff4186 1997 }
ansond 0:137634ff4186 1998 else
ansond 0:137634ff4186 1999 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
ansond 0:137634ff4186 2000 POLARSSL_SSL_PROTO_TLS1_2 */
ansond 0:137634ff4186 2001 {
ansond 0:137634ff4186 2002 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2003 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2004 }
ansond 0:137634ff4186 2005
ansond 0:137634ff4186 2006 SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
ansond 0:137634ff4186 2007 (unsigned int) ( md_info_from_type( md_alg ) )->size );
ansond 0:137634ff4186 2008
ansond 0:137634ff4186 2009 /*
ansond 0:137634ff4186 2010 * Verify signature
ansond 0:137634ff4186 2011 */
ansond 0:137634ff4186 2012 if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
ansond 0:137634ff4186 2013 {
ansond 0:137634ff4186 2014 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
ansond 0:137634ff4186 2015 return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
ansond 0:137634ff4186 2016 }
ansond 0:137634ff4186 2017
ansond 0:137634ff4186 2018 if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
ansond 0:137634ff4186 2019 md_alg, hash, hashlen, p, sig_len ) ) != 0 )
ansond 0:137634ff4186 2020 {
ansond 0:137634ff4186 2021 SSL_DEBUG_RET( 1, "pk_verify", ret );
ansond 0:137634ff4186 2022 return( ret );
ansond 0:137634ff4186 2023 }
ansond 0:137634ff4186 2024 }
ansond 0:137634ff4186 2025 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
ansond 0:137634ff4186 2026 POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 2027 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
ansond 0:137634ff4186 2028
ansond 0:137634ff4186 2029 exit:
ansond 0:137634ff4186 2030 ssl->state++;
ansond 0:137634ff4186 2031
ansond 0:137634ff4186 2032 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
ansond 0:137634ff4186 2033
ansond 0:137634ff4186 2034 return( 0 );
ansond 0:137634ff4186 2035 }
ansond 0:137634ff4186 2036
ansond 0:137634ff4186 2037 #if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
ansond 0:137634ff4186 2038 !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
ansond 0:137634ff4186 2039 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
ansond 0:137634ff4186 2040 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 2041 static int ssl_parse_certificate_request( ssl_context *ssl )
ansond 0:137634ff4186 2042 {
ansond 0:137634ff4186 2043 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 2044
ansond 0:137634ff4186 2045 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
ansond 0:137634ff4186 2046
ansond 0:137634ff4186 2047 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 2048 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 2049 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
ansond 0:137634ff4186 2050 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
ansond 0:137634ff4186 2051 {
ansond 0:137634ff4186 2052 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ansond 0:137634ff4186 2053 ssl->state++;
ansond 0:137634ff4186 2054 return( 0 );
ansond 0:137634ff4186 2055 }
ansond 0:137634ff4186 2056
ansond 0:137634ff4186 2057 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2058 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2059 }
ansond 0:137634ff4186 2060 #else
ansond 0:137634ff4186 2061 static int ssl_parse_certificate_request( ssl_context *ssl )
ansond 0:137634ff4186 2062 {
ansond 0:137634ff4186 2063 int ret;
ansond 0:137634ff4186 2064 unsigned char *buf, *p;
ansond 0:137634ff4186 2065 size_t n = 0, m = 0;
ansond 0:137634ff4186 2066 size_t cert_type_len = 0, dn_len = 0;
ansond 0:137634ff4186 2067 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 2068
ansond 0:137634ff4186 2069 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
ansond 0:137634ff4186 2070
ansond 0:137634ff4186 2071 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 2072 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 2073 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
ansond 0:137634ff4186 2074 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
ansond 0:137634ff4186 2075 {
ansond 0:137634ff4186 2076 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ansond 0:137634ff4186 2077 ssl->state++;
ansond 0:137634ff4186 2078 return( 0 );
ansond 0:137634ff4186 2079 }
ansond 0:137634ff4186 2080
ansond 0:137634ff4186 2081 /*
ansond 0:137634ff4186 2082 * 0 . 0 handshake type
ansond 0:137634ff4186 2083 * 1 . 3 handshake length
ansond 0:137634ff4186 2084 * 4 . 4 cert type count
ansond 0:137634ff4186 2085 * 5 .. m-1 cert types
ansond 0:137634ff4186 2086 * m .. m+1 sig alg length (TLS 1.2 only)
ansond 0:137634ff4186 2087 * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only)
ansond 0:137634ff4186 2088 * n .. n+1 length of all DNs
ansond 0:137634ff4186 2089 * n+2 .. n+3 length of DN 1
ansond 0:137634ff4186 2090 * n+4 .. ... Distinguished Name #1
ansond 0:137634ff4186 2091 * ... .. ... length of DN 2, etc.
ansond 0:137634ff4186 2092 */
ansond 0:137634ff4186 2093 if( ssl->record_read == 0 )
ansond 0:137634ff4186 2094 {
ansond 0:137634ff4186 2095 if( ( ret = ssl_read_record( ssl ) ) != 0 )
ansond 0:137634ff4186 2096 {
ansond 0:137634ff4186 2097 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
ansond 0:137634ff4186 2098 return( ret );
ansond 0:137634ff4186 2099 }
ansond 0:137634ff4186 2100
ansond 0:137634ff4186 2101 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
ansond 0:137634ff4186 2102 {
ansond 0:137634ff4186 2103 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
ansond 0:137634ff4186 2104 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 2105 }
ansond 0:137634ff4186 2106
ansond 0:137634ff4186 2107 ssl->record_read = 1;
ansond 0:137634ff4186 2108 }
ansond 0:137634ff4186 2109
ansond 0:137634ff4186 2110 ssl->client_auth = 0;
ansond 0:137634ff4186 2111 ssl->state++;
ansond 0:137634ff4186 2112
ansond 0:137634ff4186 2113 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
ansond 0:137634ff4186 2114 ssl->client_auth++;
ansond 0:137634ff4186 2115
ansond 0:137634ff4186 2116 SSL_DEBUG_MSG( 3, ( "got %s certificate request",
ansond 0:137634ff4186 2117 ssl->client_auth ? "a" : "no" ) );
ansond 0:137634ff4186 2118
ansond 0:137634ff4186 2119 if( ssl->client_auth == 0 )
ansond 0:137634ff4186 2120 goto exit;
ansond 0:137634ff4186 2121
ansond 0:137634ff4186 2122 ssl->record_read = 0;
ansond 0:137634ff4186 2123
ansond 0:137634ff4186 2124 // TODO: handshake_failure alert for an anonymous server to request
ansond 0:137634ff4186 2125 // client authentication
ansond 0:137634ff4186 2126
ansond 0:137634ff4186 2127 buf = ssl->in_msg;
ansond 0:137634ff4186 2128
ansond 0:137634ff4186 2129 // Retrieve cert types
ansond 0:137634ff4186 2130 //
ansond 0:137634ff4186 2131 cert_type_len = buf[4];
ansond 0:137634ff4186 2132 n = cert_type_len;
ansond 0:137634ff4186 2133
ansond 0:137634ff4186 2134 if( ssl->in_hslen < 6 + n )
ansond 0:137634ff4186 2135 {
ansond 0:137634ff4186 2136 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
ansond 0:137634ff4186 2137 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
ansond 0:137634ff4186 2138 }
ansond 0:137634ff4186 2139
ansond 0:137634ff4186 2140 p = buf + 5;
ansond 0:137634ff4186 2141 while( cert_type_len > 0 )
ansond 0:137634ff4186 2142 {
ansond 0:137634ff4186 2143 #if defined(POLARSSL_RSA_C)
ansond 0:137634ff4186 2144 if( *p == SSL_CERT_TYPE_RSA_SIGN &&
ansond 0:137634ff4186 2145 pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) )
ansond 0:137634ff4186 2146 {
ansond 0:137634ff4186 2147 ssl->handshake->cert_type = SSL_CERT_TYPE_RSA_SIGN;
ansond 0:137634ff4186 2148 break;
ansond 0:137634ff4186 2149 }
ansond 0:137634ff4186 2150 else
ansond 0:137634ff4186 2151 #endif
ansond 0:137634ff4186 2152 #if defined(POLARSSL_ECDSA_C)
ansond 0:137634ff4186 2153 if( *p == SSL_CERT_TYPE_ECDSA_SIGN &&
ansond 0:137634ff4186 2154 pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECDSA ) )
ansond 0:137634ff4186 2155 {
ansond 0:137634ff4186 2156 ssl->handshake->cert_type = SSL_CERT_TYPE_ECDSA_SIGN;
ansond 0:137634ff4186 2157 break;
ansond 0:137634ff4186 2158 }
ansond 0:137634ff4186 2159 else
ansond 0:137634ff4186 2160 #endif
ansond 0:137634ff4186 2161 {
ansond 0:137634ff4186 2162 ; /* Unsupported cert type, ignore */
ansond 0:137634ff4186 2163 }
ansond 0:137634ff4186 2164
ansond 0:137634ff4186 2165 cert_type_len--;
ansond 0:137634ff4186 2166 p++;
ansond 0:137634ff4186 2167 }
ansond 0:137634ff4186 2168
ansond 0:137634ff4186 2169 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 2170 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 2171 {
ansond 0:137634ff4186 2172 /* Ignored, see comments about hash in write_certificate_verify */
ansond 0:137634ff4186 2173 // TODO: should check the signature part against our pk_key though
ansond 0:137634ff4186 2174 size_t sig_alg_len = ( ( buf[5 + n] << 8 )
ansond 0:137634ff4186 2175 | ( buf[6 + n] ) );
ansond 0:137634ff4186 2176
ansond 0:137634ff4186 2177 p = buf + 7 + n;
ansond 0:137634ff4186 2178 m += 2;
ansond 0:137634ff4186 2179 n += sig_alg_len;
ansond 0:137634ff4186 2180
ansond 0:137634ff4186 2181 if( ssl->in_hslen < 6 + n )
ansond 0:137634ff4186 2182 {
ansond 0:137634ff4186 2183 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
ansond 0:137634ff4186 2184 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
ansond 0:137634ff4186 2185 }
ansond 0:137634ff4186 2186 }
ansond 0:137634ff4186 2187 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
ansond 0:137634ff4186 2188
ansond 0:137634ff4186 2189 /* Ignore certificate_authorities, we only have one cert anyway */
ansond 0:137634ff4186 2190 // TODO: should not send cert if no CA matches
ansond 0:137634ff4186 2191 dn_len = ( ( buf[5 + m + n] << 8 )
ansond 0:137634ff4186 2192 | ( buf[6 + m + n] ) );
ansond 0:137634ff4186 2193
ansond 0:137634ff4186 2194 n += dn_len;
ansond 0:137634ff4186 2195 if( ssl->in_hslen != 7 + m + n )
ansond 0:137634ff4186 2196 {
ansond 0:137634ff4186 2197 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
ansond 0:137634ff4186 2198 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
ansond 0:137634ff4186 2199 }
ansond 0:137634ff4186 2200
ansond 0:137634ff4186 2201 exit:
ansond 0:137634ff4186 2202 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
ansond 0:137634ff4186 2203
ansond 0:137634ff4186 2204 return( 0 );
ansond 0:137634ff4186 2205 }
ansond 0:137634ff4186 2206 #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED &&
ansond 0:137634ff4186 2207 !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
ansond 0:137634ff4186 2208 !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
ansond 0:137634ff4186 2209 !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
ansond 0:137634ff4186 2210
ansond 0:137634ff4186 2211 static int ssl_parse_server_hello_done( ssl_context *ssl )
ansond 0:137634ff4186 2212 {
ansond 0:137634ff4186 2213 int ret;
ansond 0:137634ff4186 2214
ansond 0:137634ff4186 2215 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
ansond 0:137634ff4186 2216
ansond 0:137634ff4186 2217 if( ssl->record_read == 0 )
ansond 0:137634ff4186 2218 {
ansond 0:137634ff4186 2219 if( ( ret = ssl_read_record( ssl ) ) != 0 )
ansond 0:137634ff4186 2220 {
ansond 0:137634ff4186 2221 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
ansond 0:137634ff4186 2222 return( ret );
ansond 0:137634ff4186 2223 }
ansond 0:137634ff4186 2224
ansond 0:137634ff4186 2225 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
ansond 0:137634ff4186 2226 {
ansond 0:137634ff4186 2227 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
ansond 0:137634ff4186 2228 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 2229 }
ansond 0:137634ff4186 2230 }
ansond 0:137634ff4186 2231 ssl->record_read = 0;
ansond 0:137634ff4186 2232
ansond 0:137634ff4186 2233 if( ssl->in_hslen != 4 ||
ansond 0:137634ff4186 2234 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
ansond 0:137634ff4186 2235 {
ansond 0:137634ff4186 2236 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
ansond 0:137634ff4186 2237 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
ansond 0:137634ff4186 2238 }
ansond 0:137634ff4186 2239
ansond 0:137634ff4186 2240 ssl->state++;
ansond 0:137634ff4186 2241
ansond 0:137634ff4186 2242 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
ansond 0:137634ff4186 2243
ansond 0:137634ff4186 2244 return( 0 );
ansond 0:137634ff4186 2245 }
ansond 0:137634ff4186 2246
ansond 0:137634ff4186 2247 static int ssl_write_client_key_exchange( ssl_context *ssl )
ansond 0:137634ff4186 2248 {
ansond 0:137634ff4186 2249 int ret;
ansond 0:137634ff4186 2250 size_t i, n;
ansond 0:137634ff4186 2251 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 2252
ansond 0:137634ff4186 2253 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
ansond 0:137634ff4186 2254
ansond 0:137634ff4186 2255 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)
ansond 0:137634ff4186 2256 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
ansond 0:137634ff4186 2257 {
ansond 0:137634ff4186 2258 /*
ansond 0:137634ff4186 2259 * DHM key exchange -- send G^X mod P
ansond 0:137634ff4186 2260 */
ansond 0:137634ff4186 2261 n = ssl->handshake->dhm_ctx.len;
ansond 0:137634ff4186 2262
ansond 0:137634ff4186 2263 ssl->out_msg[4] = (unsigned char)( n >> 8 );
ansond 0:137634ff4186 2264 ssl->out_msg[5] = (unsigned char)( n );
ansond 0:137634ff4186 2265 i = 6;
ansond 0:137634ff4186 2266
ansond 0:137634ff4186 2267 ret = dhm_make_public( &ssl->handshake->dhm_ctx,
ansond 0:137634ff4186 2268 (int) mpi_size( &ssl->handshake->dhm_ctx.P ),
ansond 0:137634ff4186 2269 &ssl->out_msg[i], n,
ansond 0:137634ff4186 2270 ssl->f_rng, ssl->p_rng );
ansond 0:137634ff4186 2271 if( ret != 0 )
ansond 0:137634ff4186 2272 {
ansond 0:137634ff4186 2273 SSL_DEBUG_RET( 1, "dhm_make_public", ret );
ansond 0:137634ff4186 2274 return( ret );
ansond 0:137634ff4186 2275 }
ansond 0:137634ff4186 2276
ansond 0:137634ff4186 2277 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
ansond 0:137634ff4186 2278 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
ansond 0:137634ff4186 2279
ansond 0:137634ff4186 2280 ssl->handshake->pmslen = POLARSSL_PREMASTER_SIZE;
ansond 0:137634ff4186 2281
ansond 0:137634ff4186 2282 if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
ansond 0:137634ff4186 2283 ssl->handshake->premaster,
ansond 0:137634ff4186 2284 &ssl->handshake->pmslen,
ansond 0:137634ff4186 2285 ssl->f_rng, ssl->p_rng ) ) != 0 )
ansond 0:137634ff4186 2286 {
ansond 0:137634ff4186 2287 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
ansond 0:137634ff4186 2288 return( ret );
ansond 0:137634ff4186 2289 }
ansond 0:137634ff4186 2290
ansond 0:137634ff4186 2291 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
ansond 0:137634ff4186 2292 }
ansond 0:137634ff4186 2293 else
ansond 0:137634ff4186 2294 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */
ansond 0:137634ff4186 2295 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
ansond 0:137634ff4186 2296 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
ansond 0:137634ff4186 2297 defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
ansond 0:137634ff4186 2298 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
ansond 0:137634ff4186 2299 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
ansond 0:137634ff4186 2300 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ||
ansond 0:137634ff4186 2301 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
ansond 0:137634ff4186 2302 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
ansond 0:137634ff4186 2303 {
ansond 0:137634ff4186 2304 /*
ansond 0:137634ff4186 2305 * ECDH key exchange -- send client public value
ansond 0:137634ff4186 2306 */
ansond 0:137634ff4186 2307 i = 4;
ansond 0:137634ff4186 2308
ansond 0:137634ff4186 2309 ret = ecdh_make_public( &ssl->handshake->ecdh_ctx,
ansond 0:137634ff4186 2310 &n,
ansond 0:137634ff4186 2311 &ssl->out_msg[i], 1000,
ansond 0:137634ff4186 2312 ssl->f_rng, ssl->p_rng );
ansond 0:137634ff4186 2313 if( ret != 0 )
ansond 0:137634ff4186 2314 {
ansond 0:137634ff4186 2315 SSL_DEBUG_RET( 1, "ecdh_make_public", ret );
ansond 0:137634ff4186 2316 return( ret );
ansond 0:137634ff4186 2317 }
ansond 0:137634ff4186 2318
ansond 0:137634ff4186 2319 SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
ansond 0:137634ff4186 2320
ansond 0:137634ff4186 2321 if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
ansond 0:137634ff4186 2322 &ssl->handshake->pmslen,
ansond 0:137634ff4186 2323 ssl->handshake->premaster,
ansond 0:137634ff4186 2324 POLARSSL_MPI_MAX_SIZE,
ansond 0:137634ff4186 2325 ssl->f_rng, ssl->p_rng ) ) != 0 )
ansond 0:137634ff4186 2326 {
ansond 0:137634ff4186 2327 SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
ansond 0:137634ff4186 2328 return( ret );
ansond 0:137634ff4186 2329 }
ansond 0:137634ff4186 2330
ansond 0:137634ff4186 2331 SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
ansond 0:137634ff4186 2332 }
ansond 0:137634ff4186 2333 else
ansond 0:137634ff4186 2334 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
ansond 0:137634ff4186 2335 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
ansond 0:137634ff4186 2336 POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
ansond 0:137634ff4186 2337 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
ansond 0:137634ff4186 2338 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
ansond 0:137634ff4186 2339 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 2340 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 2341 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
ansond 0:137634ff4186 2342 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
ansond 0:137634ff4186 2343 {
ansond 0:137634ff4186 2344 /*
ansond 0:137634ff4186 2345 * opaque psk_identity<0..2^16-1>;
ansond 0:137634ff4186 2346 */
ansond 0:137634ff4186 2347 if( ssl->psk == NULL || ssl->psk_identity == NULL )
ansond 0:137634ff4186 2348 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
ansond 0:137634ff4186 2349
ansond 0:137634ff4186 2350 i = 4;
ansond 0:137634ff4186 2351 n = ssl->psk_identity_len;
ansond 0:137634ff4186 2352 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
ansond 0:137634ff4186 2353 ssl->out_msg[i++] = (unsigned char)( n );
ansond 0:137634ff4186 2354
ansond 0:137634ff4186 2355 memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len );
ansond 0:137634ff4186 2356 i += ssl->psk_identity_len;
ansond 0:137634ff4186 2357
ansond 0:137634ff4186 2358 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
ansond 0:137634ff4186 2359 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
ansond 0:137634ff4186 2360 {
ansond 0:137634ff4186 2361 n = 0;
ansond 0:137634ff4186 2362 }
ansond 0:137634ff4186 2363 else
ansond 0:137634ff4186 2364 #endif
ansond 0:137634ff4186 2365 #if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
ansond 0:137634ff4186 2366 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
ansond 0:137634ff4186 2367 {
ansond 0:137634ff4186 2368 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
ansond 0:137634ff4186 2369 return( ret );
ansond 0:137634ff4186 2370 }
ansond 0:137634ff4186 2371 else
ansond 0:137634ff4186 2372 #endif
ansond 0:137634ff4186 2373 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
ansond 0:137634ff4186 2374 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
ansond 0:137634ff4186 2375 {
ansond 0:137634ff4186 2376 /*
ansond 0:137634ff4186 2377 * ClientDiffieHellmanPublic public (DHM send G^X mod P)
ansond 0:137634ff4186 2378 */
ansond 0:137634ff4186 2379 n = ssl->handshake->dhm_ctx.len;
ansond 0:137634ff4186 2380 ssl->out_msg[i++] = (unsigned char)( n >> 8 );
ansond 0:137634ff4186 2381 ssl->out_msg[i++] = (unsigned char)( n );
ansond 0:137634ff4186 2382
ansond 0:137634ff4186 2383 ret = dhm_make_public( &ssl->handshake->dhm_ctx,
ansond 0:137634ff4186 2384 (int) mpi_size( &ssl->handshake->dhm_ctx.P ),
ansond 0:137634ff4186 2385 &ssl->out_msg[i], n,
ansond 0:137634ff4186 2386 ssl->f_rng, ssl->p_rng );
ansond 0:137634ff4186 2387 if( ret != 0 )
ansond 0:137634ff4186 2388 {
ansond 0:137634ff4186 2389 SSL_DEBUG_RET( 1, "dhm_make_public", ret );
ansond 0:137634ff4186 2390 return( ret );
ansond 0:137634ff4186 2391 }
ansond 0:137634ff4186 2392 }
ansond 0:137634ff4186 2393 else
ansond 0:137634ff4186 2394 #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
ansond 0:137634ff4186 2395 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
ansond 0:137634ff4186 2396 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
ansond 0:137634ff4186 2397 {
ansond 0:137634ff4186 2398 /*
ansond 0:137634ff4186 2399 * ClientECDiffieHellmanPublic public;
ansond 0:137634ff4186 2400 */
ansond 0:137634ff4186 2401 ret = ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
ansond 0:137634ff4186 2402 &ssl->out_msg[i], SSL_MAX_CONTENT_LEN - i,
ansond 0:137634ff4186 2403 ssl->f_rng, ssl->p_rng );
ansond 0:137634ff4186 2404 if( ret != 0 )
ansond 0:137634ff4186 2405 {
ansond 0:137634ff4186 2406 SSL_DEBUG_RET( 1, "ecdh_make_public", ret );
ansond 0:137634ff4186 2407 return( ret );
ansond 0:137634ff4186 2408 }
ansond 0:137634ff4186 2409
ansond 0:137634ff4186 2410 SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
ansond 0:137634ff4186 2411 }
ansond 0:137634ff4186 2412 else
ansond 0:137634ff4186 2413 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
ansond 0:137634ff4186 2414 {
ansond 0:137634ff4186 2415 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2416 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2417 }
ansond 0:137634ff4186 2418
ansond 0:137634ff4186 2419 if( ( ret = ssl_psk_derive_premaster( ssl,
ansond 0:137634ff4186 2420 ciphersuite_info->key_exchange ) ) != 0 )
ansond 0:137634ff4186 2421 {
ansond 0:137634ff4186 2422 SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
ansond 0:137634ff4186 2423 return( ret );
ansond 0:137634ff4186 2424 }
ansond 0:137634ff4186 2425 }
ansond 0:137634ff4186 2426 else
ansond 0:137634ff4186 2427 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
ansond 0:137634ff4186 2428 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
ansond 0:137634ff4186 2429 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
ansond 0:137634ff4186 2430 {
ansond 0:137634ff4186 2431 i = 4;
ansond 0:137634ff4186 2432 if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
ansond 0:137634ff4186 2433 return( ret );
ansond 0:137634ff4186 2434 }
ansond 0:137634ff4186 2435 else
ansond 0:137634ff4186 2436 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */
ansond 0:137634ff4186 2437 {
ansond 0:137634ff4186 2438 ((void) ciphersuite_info);
ansond 0:137634ff4186 2439 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2440 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2441 }
ansond 0:137634ff4186 2442
ansond 0:137634ff4186 2443 ssl->out_msglen = i + n;
ansond 0:137634ff4186 2444 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ansond 0:137634ff4186 2445 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
ansond 0:137634ff4186 2446
ansond 0:137634ff4186 2447 ssl->state++;
ansond 0:137634ff4186 2448
ansond 0:137634ff4186 2449 if( ( ret = ssl_write_record( ssl ) ) != 0 )
ansond 0:137634ff4186 2450 {
ansond 0:137634ff4186 2451 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
ansond 0:137634ff4186 2452 return( ret );
ansond 0:137634ff4186 2453 }
ansond 0:137634ff4186 2454
ansond 0:137634ff4186 2455 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
ansond 0:137634ff4186 2456
ansond 0:137634ff4186 2457 return( 0 );
ansond 0:137634ff4186 2458 }
ansond 0:137634ff4186 2459
ansond 0:137634ff4186 2460 #if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
ansond 0:137634ff4186 2461 !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
ansond 0:137634ff4186 2462 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
ansond 0:137634ff4186 2463 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ansond 0:137634ff4186 2464 static int ssl_write_certificate_verify( ssl_context *ssl )
ansond 0:137634ff4186 2465 {
ansond 0:137634ff4186 2466 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 2467 int ret;
ansond 0:137634ff4186 2468
ansond 0:137634ff4186 2469 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
ansond 0:137634ff4186 2470
ansond 0:137634ff4186 2471 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
ansond 0:137634ff4186 2472 {
ansond 0:137634ff4186 2473 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
ansond 0:137634ff4186 2474 return( ret );
ansond 0:137634ff4186 2475 }
ansond 0:137634ff4186 2476
ansond 0:137634ff4186 2477 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 2478 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 2479 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
ansond 0:137634ff4186 2480 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
ansond 0:137634ff4186 2481 {
ansond 0:137634ff4186 2482 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ansond 0:137634ff4186 2483 ssl->state++;
ansond 0:137634ff4186 2484 return( 0 );
ansond 0:137634ff4186 2485 }
ansond 0:137634ff4186 2486
ansond 0:137634ff4186 2487 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2488 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2489 }
ansond 0:137634ff4186 2490 #else
ansond 0:137634ff4186 2491 static int ssl_write_certificate_verify( ssl_context *ssl )
ansond 0:137634ff4186 2492 {
ansond 0:137634ff4186 2493 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
ansond 0:137634ff4186 2494 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ansond 0:137634ff4186 2495 size_t n = 0, offset = 0;
ansond 0:137634ff4186 2496 unsigned char hash[48];
ansond 0:137634ff4186 2497 unsigned char *hash_start = hash;
ansond 0:137634ff4186 2498 md_type_t md_alg = POLARSSL_MD_NONE;
ansond 0:137634ff4186 2499 unsigned int hashlen;
ansond 0:137634ff4186 2500
ansond 0:137634ff4186 2501 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
ansond 0:137634ff4186 2502
ansond 0:137634ff4186 2503 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
ansond 0:137634ff4186 2504 {
ansond 0:137634ff4186 2505 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
ansond 0:137634ff4186 2506 return( ret );
ansond 0:137634ff4186 2507 }
ansond 0:137634ff4186 2508
ansond 0:137634ff4186 2509 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ansond 0:137634ff4186 2510 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
ansond 0:137634ff4186 2511 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
ansond 0:137634ff4186 2512 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
ansond 0:137634ff4186 2513 {
ansond 0:137634ff4186 2514 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ansond 0:137634ff4186 2515 ssl->state++;
ansond 0:137634ff4186 2516 return( 0 );
ansond 0:137634ff4186 2517 }
ansond 0:137634ff4186 2518
ansond 0:137634ff4186 2519 if( ssl->client_auth == 0 || ssl_own_cert( ssl ) == NULL )
ansond 0:137634ff4186 2520 {
ansond 0:137634ff4186 2521 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ansond 0:137634ff4186 2522 ssl->state++;
ansond 0:137634ff4186 2523 return( 0 );
ansond 0:137634ff4186 2524 }
ansond 0:137634ff4186 2525
ansond 0:137634ff4186 2526 if( ssl_own_key( ssl ) == NULL )
ansond 0:137634ff4186 2527 {
ansond 0:137634ff4186 2528 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
ansond 0:137634ff4186 2529 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
ansond 0:137634ff4186 2530 }
ansond 0:137634ff4186 2531
ansond 0:137634ff4186 2532 /*
ansond 0:137634ff4186 2533 * Make an RSA signature of the handshake digests
ansond 0:137634ff4186 2534 */
ansond 0:137634ff4186 2535 ssl->handshake->calc_verify( ssl, hash );
ansond 0:137634ff4186 2536
ansond 0:137634ff4186 2537 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
ansond 0:137634ff4186 2538 defined(POLARSSL_SSL_PROTO_TLS1_1)
ansond 0:137634ff4186 2539 if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 2540 {
ansond 0:137634ff4186 2541 /*
ansond 0:137634ff4186 2542 * digitally-signed struct {
ansond 0:137634ff4186 2543 * opaque md5_hash[16];
ansond 0:137634ff4186 2544 * opaque sha_hash[20];
ansond 0:137634ff4186 2545 * };
ansond 0:137634ff4186 2546 *
ansond 0:137634ff4186 2547 * md5_hash
ansond 0:137634ff4186 2548 * MD5(handshake_messages);
ansond 0:137634ff4186 2549 *
ansond 0:137634ff4186 2550 * sha_hash
ansond 0:137634ff4186 2551 * SHA(handshake_messages);
ansond 0:137634ff4186 2552 */
ansond 0:137634ff4186 2553 hashlen = 36;
ansond 0:137634ff4186 2554 md_alg = POLARSSL_MD_NONE;
ansond 0:137634ff4186 2555
ansond 0:137634ff4186 2556 /*
ansond 0:137634ff4186 2557 * For ECDSA, default hash is SHA-1 only
ansond 0:137634ff4186 2558 */
ansond 0:137634ff4186 2559 if( pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECDSA ) )
ansond 0:137634ff4186 2560 {
ansond 0:137634ff4186 2561 hash_start += 16;
ansond 0:137634ff4186 2562 hashlen -= 16;
ansond 0:137634ff4186 2563 md_alg = POLARSSL_MD_SHA1;
ansond 0:137634ff4186 2564 }
ansond 0:137634ff4186 2565 }
ansond 0:137634ff4186 2566 else
ansond 0:137634ff4186 2567 #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
ansond 0:137634ff4186 2568 POLARSSL_SSL_PROTO_TLS1_1 */
ansond 0:137634ff4186 2569 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
ansond 0:137634ff4186 2570 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
ansond 0:137634ff4186 2571 {
ansond 0:137634ff4186 2572 /*
ansond 0:137634ff4186 2573 * digitally-signed struct {
ansond 0:137634ff4186 2574 * opaque handshake_messages[handshake_messages_length];
ansond 0:137634ff4186 2575 * };
ansond 0:137634ff4186 2576 *
ansond 0:137634ff4186 2577 * Taking shortcut here. We assume that the server always allows the
ansond 0:137634ff4186 2578 * PRF Hash function and has sent it in the allowed signature
ansond 0:137634ff4186 2579 * algorithms list received in the Certificate Request message.
ansond 0:137634ff4186 2580 *
ansond 0:137634ff4186 2581 * Until we encounter a server that does not, we will take this
ansond 0:137634ff4186 2582 * shortcut.
ansond 0:137634ff4186 2583 *
ansond 0:137634ff4186 2584 * Reason: Otherwise we should have running hashes for SHA512 and SHA224
ansond 0:137634ff4186 2585 * in order to satisfy 'weird' needs from the server side.
ansond 0:137634ff4186 2586 */
ansond 0:137634ff4186 2587 if( ssl->transform_negotiate->ciphersuite_info->mac ==
ansond 0:137634ff4186 2588 POLARSSL_MD_SHA384 )
ansond 0:137634ff4186 2589 {
ansond 0:137634ff4186 2590 md_alg = POLARSSL_MD_SHA384;
ansond 0:137634ff4186 2591 ssl->out_msg[4] = SSL_HASH_SHA384;
ansond 0:137634ff4186 2592 }
ansond 0:137634ff4186 2593 else
ansond 0:137634ff4186 2594 {
ansond 0:137634ff4186 2595 md_alg = POLARSSL_MD_SHA256;
ansond 0:137634ff4186 2596 ssl->out_msg[4] = SSL_HASH_SHA256;
ansond 0:137634ff4186 2597 }
ansond 0:137634ff4186 2598 ssl->out_msg[5] = ssl_sig_from_pk( ssl_own_key( ssl ) );
ansond 0:137634ff4186 2599
ansond 0:137634ff4186 2600 /* Info from md_alg will be used instead */
ansond 0:137634ff4186 2601 hashlen = 0;
ansond 0:137634ff4186 2602 offset = 2;
ansond 0:137634ff4186 2603 }
ansond 0:137634ff4186 2604 else
ansond 0:137634ff4186 2605 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
ansond 0:137634ff4186 2606 {
ansond 0:137634ff4186 2607 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
ansond 0:137634ff4186 2608 return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
ansond 0:137634ff4186 2609 }
ansond 0:137634ff4186 2610
ansond 0:137634ff4186 2611 if( ( ret = pk_sign( ssl_own_key( ssl ), md_alg, hash_start, hashlen,
ansond 0:137634ff4186 2612 ssl->out_msg + 6 + offset, &n,
ansond 0:137634ff4186 2613 ssl->f_rng, ssl->p_rng ) ) != 0 )
ansond 0:137634ff4186 2614 {
ansond 0:137634ff4186 2615 SSL_DEBUG_RET( 1, "pk_sign", ret );
ansond 0:137634ff4186 2616 return( ret );
ansond 0:137634ff4186 2617 }
ansond 0:137634ff4186 2618
ansond 0:137634ff4186 2619 ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
ansond 0:137634ff4186 2620 ssl->out_msg[5 + offset] = (unsigned char)( n );
ansond 0:137634ff4186 2621
ansond 0:137634ff4186 2622 ssl->out_msglen = 6 + n + offset;
ansond 0:137634ff4186 2623 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ansond 0:137634ff4186 2624 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
ansond 0:137634ff4186 2625
ansond 0:137634ff4186 2626 ssl->state++;
ansond 0:137634ff4186 2627
ansond 0:137634ff4186 2628 if( ( ret = ssl_write_record( ssl ) ) != 0 )
ansond 0:137634ff4186 2629 {
ansond 0:137634ff4186 2630 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
ansond 0:137634ff4186 2631 return( ret );
ansond 0:137634ff4186 2632 }
ansond 0:137634ff4186 2633
ansond 0:137634ff4186 2634 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
ansond 0:137634ff4186 2635
ansond 0:137634ff4186 2636 return( ret );
ansond 0:137634ff4186 2637 }
ansond 0:137634ff4186 2638 #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED &&
ansond 0:137634ff4186 2639 !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
ansond 0:137634ff4186 2640 !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
ansond 0:137634ff4186 2641
ansond 0:137634ff4186 2642 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 2643 static int ssl_parse_new_session_ticket( ssl_context *ssl )
ansond 0:137634ff4186 2644 {
ansond 0:137634ff4186 2645 int ret;
ansond 0:137634ff4186 2646 uint32_t lifetime;
ansond 0:137634ff4186 2647 size_t ticket_len;
ansond 0:137634ff4186 2648 unsigned char *ticket;
ansond 0:137634ff4186 2649
ansond 0:137634ff4186 2650 SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
ansond 0:137634ff4186 2651
ansond 0:137634ff4186 2652 if( ( ret = ssl_read_record( ssl ) ) != 0 )
ansond 0:137634ff4186 2653 {
ansond 0:137634ff4186 2654 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
ansond 0:137634ff4186 2655 return( ret );
ansond 0:137634ff4186 2656 }
ansond 0:137634ff4186 2657
ansond 0:137634ff4186 2658 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
ansond 0:137634ff4186 2659 {
ansond 0:137634ff4186 2660 SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
ansond 0:137634ff4186 2661 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
ansond 0:137634ff4186 2662 }
ansond 0:137634ff4186 2663
ansond 0:137634ff4186 2664 /*
ansond 0:137634ff4186 2665 * struct {
ansond 0:137634ff4186 2666 * uint32 ticket_lifetime_hint;
ansond 0:137634ff4186 2667 * opaque ticket<0..2^16-1>;
ansond 0:137634ff4186 2668 * } NewSessionTicket;
ansond 0:137634ff4186 2669 *
ansond 0:137634ff4186 2670 * 0 . 0 handshake message type
ansond 0:137634ff4186 2671 * 1 . 3 handshake message length
ansond 0:137634ff4186 2672 * 4 . 7 ticket_lifetime_hint
ansond 0:137634ff4186 2673 * 8 . 9 ticket_len (n)
ansond 0:137634ff4186 2674 * 10 . 9+n ticket content
ansond 0:137634ff4186 2675 */
ansond 0:137634ff4186 2676 if( ssl->in_msg[0] != SSL_HS_NEW_SESSION_TICKET ||
ansond 0:137634ff4186 2677 ssl->in_hslen < 10 )
ansond 0:137634ff4186 2678 {
ansond 0:137634ff4186 2679 SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
ansond 0:137634ff4186 2680 return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
ansond 0:137634ff4186 2681 }
ansond 0:137634ff4186 2682
ansond 0:137634ff4186 2683 lifetime = ( ssl->in_msg[4] << 24 ) | ( ssl->in_msg[5] << 16 ) |
ansond 0:137634ff4186 2684 ( ssl->in_msg[6] << 8 ) | ( ssl->in_msg[7] );
ansond 0:137634ff4186 2685
ansond 0:137634ff4186 2686 ticket_len = ( ssl->in_msg[8] << 8 ) | ( ssl->in_msg[9] );
ansond 0:137634ff4186 2687
ansond 0:137634ff4186 2688 if( ticket_len + 10 != ssl->in_hslen )
ansond 0:137634ff4186 2689 {
ansond 0:137634ff4186 2690 SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
ansond 0:137634ff4186 2691 return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
ansond 0:137634ff4186 2692 }
ansond 0:137634ff4186 2693
ansond 0:137634ff4186 2694 SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
ansond 0:137634ff4186 2695
ansond 0:137634ff4186 2696 /* We're not waiting for a NewSessionTicket message any more */
ansond 0:137634ff4186 2697 ssl->handshake->new_session_ticket = 0;
ansond 0:137634ff4186 2698
ansond 0:137634ff4186 2699 /*
ansond 0:137634ff4186 2700 * Zero-length ticket means the server changed his mind and doesn't want
ansond 0:137634ff4186 2701 * to send a ticket after all, so just forget it
ansond 0:137634ff4186 2702 */
ansond 0:137634ff4186 2703 if( ticket_len == 0 )
ansond 0:137634ff4186 2704 return( 0 );
ansond 0:137634ff4186 2705
ansond 0:137634ff4186 2706 polarssl_zeroize( ssl->session_negotiate->ticket,
ansond 0:137634ff4186 2707 ssl->session_negotiate->ticket_len );
ansond 0:137634ff4186 2708 polarssl_free( ssl->session_negotiate->ticket );
ansond 0:137634ff4186 2709 ssl->session_negotiate->ticket = NULL;
ansond 0:137634ff4186 2710 ssl->session_negotiate->ticket_len = 0;
ansond 0:137634ff4186 2711
ansond 0:137634ff4186 2712 if( ( ticket = polarssl_malloc( ticket_len ) ) == NULL )
ansond 0:137634ff4186 2713 {
ansond 0:137634ff4186 2714 SSL_DEBUG_MSG( 1, ( "ticket malloc failed" ) );
ansond 0:137634ff4186 2715 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
ansond 0:137634ff4186 2716 }
ansond 0:137634ff4186 2717
ansond 0:137634ff4186 2718 memcpy( ticket, ssl->in_msg + 10, ticket_len );
ansond 0:137634ff4186 2719
ansond 0:137634ff4186 2720 ssl->session_negotiate->ticket = ticket;
ansond 0:137634ff4186 2721 ssl->session_negotiate->ticket_len = ticket_len;
ansond 0:137634ff4186 2722 ssl->session_negotiate->ticket_lifetime = lifetime;
ansond 0:137634ff4186 2723
ansond 0:137634ff4186 2724 /*
ansond 0:137634ff4186 2725 * RFC 5077 section 3.4:
ansond 0:137634ff4186 2726 * "If the client receives a session ticket from the server, then it
ansond 0:137634ff4186 2727 * discards any Session ID that was sent in the ServerHello."
ansond 0:137634ff4186 2728 */
ansond 0:137634ff4186 2729 SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
ansond 0:137634ff4186 2730 ssl->session_negotiate->length = 0;
ansond 0:137634ff4186 2731
ansond 0:137634ff4186 2732 SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
ansond 0:137634ff4186 2733
ansond 0:137634ff4186 2734 return( 0 );
ansond 0:137634ff4186 2735 }
ansond 0:137634ff4186 2736 #endif /* POLARSSL_SSL_SESSION_TICKETS */
ansond 0:137634ff4186 2737
ansond 0:137634ff4186 2738 /*
ansond 0:137634ff4186 2739 * SSL handshake -- client side -- single step
ansond 0:137634ff4186 2740 */
ansond 0:137634ff4186 2741 int ssl_handshake_client_step( ssl_context *ssl )
ansond 0:137634ff4186 2742 {
ansond 0:137634ff4186 2743 int ret = 0;
ansond 0:137634ff4186 2744
ansond 0:137634ff4186 2745 if( ssl->state == SSL_HANDSHAKE_OVER )
ansond 0:137634ff4186 2746 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
ansond 0:137634ff4186 2747
ansond 0:137634ff4186 2748 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
ansond 0:137634ff4186 2749
ansond 0:137634ff4186 2750 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
ansond 0:137634ff4186 2751 return( ret );
ansond 0:137634ff4186 2752
ansond 0:137634ff4186 2753 switch( ssl->state )
ansond 0:137634ff4186 2754 {
ansond 0:137634ff4186 2755 case SSL_HELLO_REQUEST:
ansond 0:137634ff4186 2756 ssl->state = SSL_CLIENT_HELLO;
ansond 0:137634ff4186 2757 break;
ansond 0:137634ff4186 2758
ansond 0:137634ff4186 2759 /*
ansond 0:137634ff4186 2760 * ==> ClientHello
ansond 0:137634ff4186 2761 */
ansond 0:137634ff4186 2762 case SSL_CLIENT_HELLO:
ansond 0:137634ff4186 2763 ret = ssl_write_client_hello( ssl );
ansond 0:137634ff4186 2764 break;
ansond 0:137634ff4186 2765
ansond 0:137634ff4186 2766 /*
ansond 0:137634ff4186 2767 * <== ServerHello
ansond 0:137634ff4186 2768 * Certificate
ansond 0:137634ff4186 2769 * ( ServerKeyExchange )
ansond 0:137634ff4186 2770 * ( CertificateRequest )
ansond 0:137634ff4186 2771 * ServerHelloDone
ansond 0:137634ff4186 2772 */
ansond 0:137634ff4186 2773 case SSL_SERVER_HELLO:
ansond 0:137634ff4186 2774 ret = ssl_parse_server_hello( ssl );
ansond 0:137634ff4186 2775 break;
ansond 0:137634ff4186 2776
ansond 0:137634ff4186 2777 case SSL_SERVER_CERTIFICATE:
ansond 0:137634ff4186 2778 ret = ssl_parse_certificate( ssl );
ansond 0:137634ff4186 2779 break;
ansond 0:137634ff4186 2780
ansond 0:137634ff4186 2781 case SSL_SERVER_KEY_EXCHANGE:
ansond 0:137634ff4186 2782 ret = ssl_parse_server_key_exchange( ssl );
ansond 0:137634ff4186 2783 break;
ansond 0:137634ff4186 2784
ansond 0:137634ff4186 2785 case SSL_CERTIFICATE_REQUEST:
ansond 0:137634ff4186 2786 ret = ssl_parse_certificate_request( ssl );
ansond 0:137634ff4186 2787 break;
ansond 0:137634ff4186 2788
ansond 0:137634ff4186 2789 case SSL_SERVER_HELLO_DONE:
ansond 0:137634ff4186 2790 ret = ssl_parse_server_hello_done( ssl );
ansond 0:137634ff4186 2791 break;
ansond 0:137634ff4186 2792
ansond 0:137634ff4186 2793 /*
ansond 0:137634ff4186 2794 * ==> ( Certificate/Alert )
ansond 0:137634ff4186 2795 * ClientKeyExchange
ansond 0:137634ff4186 2796 * ( CertificateVerify )
ansond 0:137634ff4186 2797 * ChangeCipherSpec
ansond 0:137634ff4186 2798 * Finished
ansond 0:137634ff4186 2799 */
ansond 0:137634ff4186 2800 case SSL_CLIENT_CERTIFICATE:
ansond 0:137634ff4186 2801 ret = ssl_write_certificate( ssl );
ansond 0:137634ff4186 2802 break;
ansond 0:137634ff4186 2803
ansond 0:137634ff4186 2804 case SSL_CLIENT_KEY_EXCHANGE:
ansond 0:137634ff4186 2805 ret = ssl_write_client_key_exchange( ssl );
ansond 0:137634ff4186 2806 break;
ansond 0:137634ff4186 2807
ansond 0:137634ff4186 2808 case SSL_CERTIFICATE_VERIFY:
ansond 0:137634ff4186 2809 ret = ssl_write_certificate_verify( ssl );
ansond 0:137634ff4186 2810 break;
ansond 0:137634ff4186 2811
ansond 0:137634ff4186 2812 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ansond 0:137634ff4186 2813 ret = ssl_write_change_cipher_spec( ssl );
ansond 0:137634ff4186 2814 break;
ansond 0:137634ff4186 2815
ansond 0:137634ff4186 2816 case SSL_CLIENT_FINISHED:
ansond 0:137634ff4186 2817 ret = ssl_write_finished( ssl );
ansond 0:137634ff4186 2818 break;
ansond 0:137634ff4186 2819
ansond 0:137634ff4186 2820 /*
ansond 0:137634ff4186 2821 * <== ( NewSessionTicket )
ansond 0:137634ff4186 2822 * ChangeCipherSpec
ansond 0:137634ff4186 2823 * Finished
ansond 0:137634ff4186 2824 */
ansond 0:137634ff4186 2825 case SSL_SERVER_CHANGE_CIPHER_SPEC:
ansond 0:137634ff4186 2826 #if defined(POLARSSL_SSL_SESSION_TICKETS)
ansond 0:137634ff4186 2827 if( ssl->handshake->new_session_ticket != 0 )
ansond 0:137634ff4186 2828 ret = ssl_parse_new_session_ticket( ssl );
ansond 0:137634ff4186 2829 else
ansond 0:137634ff4186 2830 #endif
ansond 0:137634ff4186 2831 ret = ssl_parse_change_cipher_spec( ssl );
ansond 0:137634ff4186 2832 break;
ansond 0:137634ff4186 2833
ansond 0:137634ff4186 2834 case SSL_SERVER_FINISHED:
ansond 0:137634ff4186 2835 ret = ssl_parse_finished( ssl );
ansond 0:137634ff4186 2836 break;
ansond 0:137634ff4186 2837
ansond 0:137634ff4186 2838 case SSL_FLUSH_BUFFERS:
ansond 0:137634ff4186 2839 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ansond 0:137634ff4186 2840 ssl->state = SSL_HANDSHAKE_WRAPUP;
ansond 0:137634ff4186 2841 break;
ansond 0:137634ff4186 2842
ansond 0:137634ff4186 2843 case SSL_HANDSHAKE_WRAPUP:
ansond 0:137634ff4186 2844 ssl_handshake_wrapup( ssl );
ansond 0:137634ff4186 2845 break;
ansond 0:137634ff4186 2846
ansond 0:137634ff4186 2847 default:
ansond 0:137634ff4186 2848 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
ansond 0:137634ff4186 2849 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
ansond 0:137634ff4186 2850 }
ansond 0:137634ff4186 2851
ansond 0:137634ff4186 2852 return( ret );
ansond 0:137634ff4186 2853 }
ansond 0:137634ff4186 2854 #endif /* POLARSSL_SSL_CLI_C */
ansond 0:137634ff4186 2855