Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

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