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 server-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_SRV_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 #if defined(POLARSSL_ECP_C)
HannesTschofenig 0:796d0f61a05b 37 #include "polarssl/ecp.h"
HannesTschofenig 0:796d0f61a05b 38 #endif
HannesTschofenig 0:796d0f61a05b 39
HannesTschofenig 0:796d0f61a05b 40 #if defined(POLARSSL_PLATFORM_C)
HannesTschofenig 0:796d0f61a05b 41 #include "polarssl/platform.h"
HannesTschofenig 0:796d0f61a05b 42 #else
HannesTschofenig 0:796d0f61a05b 43 #define polarssl_malloc malloc
HannesTschofenig 0:796d0f61a05b 44 #define polarssl_free free
HannesTschofenig 0:796d0f61a05b 45 #endif
HannesTschofenig 0:796d0f61a05b 46
HannesTschofenig 0:796d0f61a05b 47 #include <stdlib.h>
HannesTschofenig 0:796d0f61a05b 48 #include <stdio.h>
HannesTschofenig 0:796d0f61a05b 49
HannesTschofenig 0:796d0f61a05b 50 #if defined(POLARSSL_HAVE_TIME)
HannesTschofenig 0:796d0f61a05b 51 #include <time.h>
HannesTschofenig 0:796d0f61a05b 52 #endif
HannesTschofenig 0:796d0f61a05b 53
HannesTschofenig 0:796d0f61a05b 54 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 55 /*
HannesTschofenig 0:796d0f61a05b 56 * Serialize a session in the following format:
HannesTschofenig 0:796d0f61a05b 57 * 0 . n-1 session structure, n = sizeof(ssl_session)
HannesTschofenig 0:796d0f61a05b 58 * n . n+2 peer_cert length = m (0 if no certificate)
HannesTschofenig 0:796d0f61a05b 59 * n+3 . n+2+m peer cert ASN.1
HannesTschofenig 0:796d0f61a05b 60 *
HannesTschofenig 0:796d0f61a05b 61 * Assumes ticket is NULL (always true on server side).
HannesTschofenig 0:796d0f61a05b 62 */
HannesTschofenig 0:796d0f61a05b 63 static int ssl_save_session( const ssl_session *session,
HannesTschofenig 0:796d0f61a05b 64 unsigned char *buf, size_t buf_len,
HannesTschofenig 0:796d0f61a05b 65 size_t *olen )
HannesTschofenig 0:796d0f61a05b 66 {
HannesTschofenig 0:796d0f61a05b 67 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 68 size_t left = buf_len;
HannesTschofenig 0:796d0f61a05b 69 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 70 size_t cert_len;
HannesTschofenig 0:796d0f61a05b 71 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 72
HannesTschofenig 0:796d0f61a05b 73 if( left < sizeof( ssl_session ) )
HannesTschofenig 0:796d0f61a05b 74 return( -1 );
HannesTschofenig 0:796d0f61a05b 75
HannesTschofenig 0:796d0f61a05b 76 memcpy( p, session, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 77 p += sizeof( ssl_session );
HannesTschofenig 0:796d0f61a05b 78 left -= sizeof( ssl_session );
HannesTschofenig 0:796d0f61a05b 79
HannesTschofenig 0:796d0f61a05b 80 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 81 if( session->peer_cert == NULL )
HannesTschofenig 0:796d0f61a05b 82 cert_len = 0;
HannesTschofenig 0:796d0f61a05b 83 else
HannesTschofenig 0:796d0f61a05b 84 cert_len = session->peer_cert->raw.len;
HannesTschofenig 0:796d0f61a05b 85
HannesTschofenig 0:796d0f61a05b 86 if( left < 3 + cert_len )
HannesTschofenig 0:796d0f61a05b 87 return( -1 );
HannesTschofenig 0:796d0f61a05b 88
HannesTschofenig 0:796d0f61a05b 89 *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
HannesTschofenig 0:796d0f61a05b 90 *p++ = (unsigned char)( cert_len >> 8 & 0xFF );
HannesTschofenig 0:796d0f61a05b 91 *p++ = (unsigned char)( cert_len & 0xFF );
HannesTschofenig 0:796d0f61a05b 92
HannesTschofenig 0:796d0f61a05b 93 if( session->peer_cert != NULL )
HannesTschofenig 0:796d0f61a05b 94 memcpy( p, session->peer_cert->raw.p, cert_len );
HannesTschofenig 0:796d0f61a05b 95
HannesTschofenig 0:796d0f61a05b 96 p += cert_len;
HannesTschofenig 0:796d0f61a05b 97 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 98
HannesTschofenig 0:796d0f61a05b 99 *olen = p - buf;
HannesTschofenig 0:796d0f61a05b 100
HannesTschofenig 0:796d0f61a05b 101 return( 0 );
HannesTschofenig 0:796d0f61a05b 102 }
HannesTschofenig 0:796d0f61a05b 103
HannesTschofenig 0:796d0f61a05b 104 /*
HannesTschofenig 0:796d0f61a05b 105 * Unserialise session, see ssl_save_session()
HannesTschofenig 0:796d0f61a05b 106 */
HannesTschofenig 0:796d0f61a05b 107 static int ssl_load_session( ssl_session *session,
HannesTschofenig 0:796d0f61a05b 108 const unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 109 {
HannesTschofenig 0:796d0f61a05b 110 const unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 111 const unsigned char * const end = buf + len;
HannesTschofenig 0:796d0f61a05b 112 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 113 size_t cert_len;
HannesTschofenig 0:796d0f61a05b 114 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 115
HannesTschofenig 0:796d0f61a05b 116 if( p + sizeof( ssl_session ) > end )
HannesTschofenig 0:796d0f61a05b 117 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 118
HannesTschofenig 0:796d0f61a05b 119 memcpy( session, p, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 120 p += sizeof( ssl_session );
HannesTschofenig 0:796d0f61a05b 121
HannesTschofenig 0:796d0f61a05b 122 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 123 if( p + 3 > end )
HannesTschofenig 0:796d0f61a05b 124 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 125
HannesTschofenig 0:796d0f61a05b 126 cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
HannesTschofenig 0:796d0f61a05b 127 p += 3;
HannesTschofenig 0:796d0f61a05b 128
HannesTschofenig 0:796d0f61a05b 129 if( cert_len == 0 )
HannesTschofenig 0:796d0f61a05b 130 {
HannesTschofenig 0:796d0f61a05b 131 session->peer_cert = NULL;
HannesTschofenig 0:796d0f61a05b 132 }
HannesTschofenig 0:796d0f61a05b 133 else
HannesTschofenig 0:796d0f61a05b 134 {
HannesTschofenig 0:796d0f61a05b 135 int ret;
HannesTschofenig 0:796d0f61a05b 136
HannesTschofenig 0:796d0f61a05b 137 if( p + cert_len > end )
HannesTschofenig 0:796d0f61a05b 138 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 139
HannesTschofenig 0:796d0f61a05b 140 session->peer_cert = polarssl_malloc( sizeof( x509_crt ) );
HannesTschofenig 0:796d0f61a05b 141
HannesTschofenig 0:796d0f61a05b 142 if( session->peer_cert == NULL )
HannesTschofenig 0:796d0f61a05b 143 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 144
HannesTschofenig 0:796d0f61a05b 145 x509_crt_init( session->peer_cert );
HannesTschofenig 0:796d0f61a05b 146
HannesTschofenig 0:796d0f61a05b 147 if( ( ret = x509_crt_parse( session->peer_cert, p, cert_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 148 {
HannesTschofenig 0:796d0f61a05b 149 x509_crt_free( session->peer_cert );
HannesTschofenig 0:796d0f61a05b 150 polarssl_free( session->peer_cert );
HannesTschofenig 0:796d0f61a05b 151 session->peer_cert = NULL;
HannesTschofenig 0:796d0f61a05b 152 return( ret );
HannesTschofenig 0:796d0f61a05b 153 }
HannesTschofenig 0:796d0f61a05b 154
HannesTschofenig 0:796d0f61a05b 155 p += cert_len;
HannesTschofenig 0:796d0f61a05b 156 }
HannesTschofenig 0:796d0f61a05b 157 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 158
HannesTschofenig 0:796d0f61a05b 159 if( p != end )
HannesTschofenig 0:796d0f61a05b 160 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 161
HannesTschofenig 0:796d0f61a05b 162 return( 0 );
HannesTschofenig 0:796d0f61a05b 163 }
HannesTschofenig 0:796d0f61a05b 164
HannesTschofenig 0:796d0f61a05b 165 /*
HannesTschofenig 0:796d0f61a05b 166 * Create session ticket, secured as recommended in RFC 5077 section 4:
HannesTschofenig 0:796d0f61a05b 167 *
HannesTschofenig 0:796d0f61a05b 168 * struct {
HannesTschofenig 0:796d0f61a05b 169 * opaque key_name[16];
HannesTschofenig 0:796d0f61a05b 170 * opaque iv[16];
HannesTschofenig 0:796d0f61a05b 171 * opaque encrypted_state<0..2^16-1>;
HannesTschofenig 0:796d0f61a05b 172 * opaque mac[32];
HannesTschofenig 0:796d0f61a05b 173 * } ticket;
HannesTschofenig 0:796d0f61a05b 174 *
HannesTschofenig 0:796d0f61a05b 175 * (the internal state structure differs, however).
HannesTschofenig 0:796d0f61a05b 176 */
HannesTschofenig 0:796d0f61a05b 177 static int ssl_write_ticket( ssl_context *ssl, size_t *tlen )
HannesTschofenig 0:796d0f61a05b 178 {
HannesTschofenig 0:796d0f61a05b 179 int ret;
HannesTschofenig 0:796d0f61a05b 180 unsigned char * const start = ssl->out_msg + 10;
HannesTschofenig 0:796d0f61a05b 181 unsigned char *p = start;
HannesTschofenig 0:796d0f61a05b 182 unsigned char *state;
HannesTschofenig 0:796d0f61a05b 183 unsigned char iv[16];
HannesTschofenig 0:796d0f61a05b 184 size_t clear_len, enc_len, pad_len, i;
HannesTschofenig 0:796d0f61a05b 185
HannesTschofenig 0:796d0f61a05b 186 *tlen = 0;
HannesTschofenig 0:796d0f61a05b 187
HannesTschofenig 0:796d0f61a05b 188 if( ssl->ticket_keys == NULL )
HannesTschofenig 0:796d0f61a05b 189 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 190
HannesTschofenig 0:796d0f61a05b 191 /* Write key name */
HannesTschofenig 0:796d0f61a05b 192 memcpy( p, ssl->ticket_keys->key_name, 16 );
HannesTschofenig 0:796d0f61a05b 193 p += 16;
HannesTschofenig 0:796d0f61a05b 194
HannesTschofenig 0:796d0f61a05b 195 /* Generate and write IV (with a copy for aes_crypt) */
HannesTschofenig 0:796d0f61a05b 196 if( ( ret = ssl->f_rng( ssl->p_rng, p, 16 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 197 return( ret );
HannesTschofenig 0:796d0f61a05b 198 memcpy( iv, p, 16 );
HannesTschofenig 0:796d0f61a05b 199 p += 16;
HannesTschofenig 0:796d0f61a05b 200
HannesTschofenig 0:796d0f61a05b 201 /*
HannesTschofenig 0:796d0f61a05b 202 * Dump session state
HannesTschofenig 0:796d0f61a05b 203 *
HannesTschofenig 0:796d0f61a05b 204 * After the session state itself, we still need room for 16 bytes of
HannesTschofenig 0:796d0f61a05b 205 * padding and 32 bytes of MAC, so there's only so much room left
HannesTschofenig 0:796d0f61a05b 206 */
HannesTschofenig 0:796d0f61a05b 207 state = p + 2;
HannesTschofenig 0:796d0f61a05b 208 if( ssl_save_session( ssl->session_negotiate, state,
HannesTschofenig 0:796d0f61a05b 209 SSL_MAX_CONTENT_LEN - (state - ssl->out_ctr) - 48,
HannesTschofenig 0:796d0f61a05b 210 &clear_len ) != 0 )
HannesTschofenig 0:796d0f61a05b 211 {
HannesTschofenig 0:796d0f61a05b 212 return( POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE );
HannesTschofenig 0:796d0f61a05b 213 }
HannesTschofenig 0:796d0f61a05b 214 SSL_DEBUG_BUF( 3, "session ticket cleartext", state, clear_len );
HannesTschofenig 0:796d0f61a05b 215
HannesTschofenig 0:796d0f61a05b 216 /* Apply PKCS padding */
HannesTschofenig 0:796d0f61a05b 217 pad_len = 16 - clear_len % 16;
HannesTschofenig 0:796d0f61a05b 218 enc_len = clear_len + pad_len;
HannesTschofenig 0:796d0f61a05b 219 for( i = clear_len; i < enc_len; i++ )
HannesTschofenig 0:796d0f61a05b 220 state[i] = (unsigned char) pad_len;
HannesTschofenig 0:796d0f61a05b 221
HannesTschofenig 0:796d0f61a05b 222 /* Encrypt */
HannesTschofenig 0:796d0f61a05b 223 if( ( ret = aes_crypt_cbc( &ssl->ticket_keys->enc, AES_ENCRYPT,
HannesTschofenig 0:796d0f61a05b 224 enc_len, iv, state, state ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 225 {
HannesTschofenig 0:796d0f61a05b 226 return( ret );
HannesTschofenig 0:796d0f61a05b 227 }
HannesTschofenig 0:796d0f61a05b 228
HannesTschofenig 0:796d0f61a05b 229 /* Write length */
HannesTschofenig 0:796d0f61a05b 230 *p++ = (unsigned char)( ( enc_len >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 231 *p++ = (unsigned char)( ( enc_len ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 232 p = state + enc_len;
HannesTschofenig 0:796d0f61a05b 233
HannesTschofenig 0:796d0f61a05b 234 /* Compute and write MAC( key_name + iv + enc_state_len + enc_state ) */
HannesTschofenig 0:796d0f61a05b 235 sha256_hmac( ssl->ticket_keys->mac_key, 16, start, p - start, p, 0 );
HannesTschofenig 0:796d0f61a05b 236 p += 32;
HannesTschofenig 0:796d0f61a05b 237
HannesTschofenig 0:796d0f61a05b 238 *tlen = p - start;
HannesTschofenig 0:796d0f61a05b 239
HannesTschofenig 0:796d0f61a05b 240 SSL_DEBUG_BUF( 3, "session ticket structure", start, *tlen );
HannesTschofenig 0:796d0f61a05b 241
HannesTschofenig 0:796d0f61a05b 242 return( 0 );
HannesTschofenig 0:796d0f61a05b 243 }
HannesTschofenig 0:796d0f61a05b 244
HannesTschofenig 0:796d0f61a05b 245 /*
HannesTschofenig 0:796d0f61a05b 246 * Load session ticket (see ssl_write_ticket for structure)
HannesTschofenig 0:796d0f61a05b 247 */
HannesTschofenig 0:796d0f61a05b 248 static int ssl_parse_ticket( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 249 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 250 size_t len )
HannesTschofenig 0:796d0f61a05b 251 {
HannesTschofenig 0:796d0f61a05b 252 int ret;
HannesTschofenig 0:796d0f61a05b 253 ssl_session session;
HannesTschofenig 0:796d0f61a05b 254 unsigned char *key_name = buf;
HannesTschofenig 0:796d0f61a05b 255 unsigned char *iv = buf + 16;
HannesTschofenig 0:796d0f61a05b 256 unsigned char *enc_len_p = iv + 16;
HannesTschofenig 0:796d0f61a05b 257 unsigned char *ticket = enc_len_p + 2;
HannesTschofenig 0:796d0f61a05b 258 unsigned char *mac;
HannesTschofenig 0:796d0f61a05b 259 unsigned char computed_mac[32];
HannesTschofenig 0:796d0f61a05b 260 size_t enc_len, clear_len, i;
HannesTschofenig 0:796d0f61a05b 261 unsigned char pad_len, diff;
HannesTschofenig 0:796d0f61a05b 262
HannesTschofenig 0:796d0f61a05b 263 SSL_DEBUG_BUF( 3, "session ticket structure", buf, len );
HannesTschofenig 0:796d0f61a05b 264
HannesTschofenig 0:796d0f61a05b 265 if( len < 34 || ssl->ticket_keys == NULL )
HannesTschofenig 0:796d0f61a05b 266 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 267
HannesTschofenig 0:796d0f61a05b 268 enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
HannesTschofenig 0:796d0f61a05b 269 mac = ticket + enc_len;
HannesTschofenig 0:796d0f61a05b 270
HannesTschofenig 0:796d0f61a05b 271 if( len != enc_len + 66 )
HannesTschofenig 0:796d0f61a05b 272 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 273
HannesTschofenig 0:796d0f61a05b 274 /* Check name, in constant time though it's not a big secret */
HannesTschofenig 0:796d0f61a05b 275 diff = 0;
HannesTschofenig 0:796d0f61a05b 276 for( i = 0; i < 16; i++ )
HannesTschofenig 0:796d0f61a05b 277 diff |= key_name[i] ^ ssl->ticket_keys->key_name[i];
HannesTschofenig 0:796d0f61a05b 278 /* don't return yet, check the MAC anyway */
HannesTschofenig 0:796d0f61a05b 279
HannesTschofenig 0:796d0f61a05b 280 /* Check mac, with constant-time buffer comparison */
HannesTschofenig 0:796d0f61a05b 281 sha256_hmac( ssl->ticket_keys->mac_key, 16, buf, len - 32,
HannesTschofenig 0:796d0f61a05b 282 computed_mac, 0 );
HannesTschofenig 0:796d0f61a05b 283
HannesTschofenig 0:796d0f61a05b 284 for( i = 0; i < 32; i++ )
HannesTschofenig 0:796d0f61a05b 285 diff |= mac[i] ^ computed_mac[i];
HannesTschofenig 0:796d0f61a05b 286
HannesTschofenig 0:796d0f61a05b 287 /* Now return if ticket is not authentic, since we want to avoid
HannesTschofenig 0:796d0f61a05b 288 * decrypting arbitrary attacker-chosen data */
HannesTschofenig 0:796d0f61a05b 289 if( diff != 0 )
HannesTschofenig 0:796d0f61a05b 290 return( POLARSSL_ERR_SSL_INVALID_MAC );
HannesTschofenig 0:796d0f61a05b 291
HannesTschofenig 0:796d0f61a05b 292 /* Decrypt */
HannesTschofenig 0:796d0f61a05b 293 if( ( ret = aes_crypt_cbc( &ssl->ticket_keys->dec, AES_DECRYPT,
HannesTschofenig 0:796d0f61a05b 294 enc_len, iv, ticket, ticket ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 295 {
HannesTschofenig 0:796d0f61a05b 296 return( ret );
HannesTschofenig 0:796d0f61a05b 297 }
HannesTschofenig 0:796d0f61a05b 298
HannesTschofenig 0:796d0f61a05b 299 /* Check PKCS padding */
HannesTschofenig 0:796d0f61a05b 300 pad_len = ticket[enc_len - 1];
HannesTschofenig 0:796d0f61a05b 301
HannesTschofenig 0:796d0f61a05b 302 ret = 0;
HannesTschofenig 0:796d0f61a05b 303 for( i = 2; i < pad_len; i++ )
HannesTschofenig 0:796d0f61a05b 304 if( ticket[enc_len - i] != pad_len )
HannesTschofenig 0:796d0f61a05b 305 ret = POLARSSL_ERR_SSL_BAD_INPUT_DATA;
HannesTschofenig 0:796d0f61a05b 306 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 307 return( ret );
HannesTschofenig 0:796d0f61a05b 308
HannesTschofenig 0:796d0f61a05b 309 clear_len = enc_len - pad_len;
HannesTschofenig 0:796d0f61a05b 310
HannesTschofenig 0:796d0f61a05b 311 SSL_DEBUG_BUF( 3, "session ticket cleartext", ticket, clear_len );
HannesTschofenig 0:796d0f61a05b 312
HannesTschofenig 0:796d0f61a05b 313 /* Actually load session */
HannesTschofenig 0:796d0f61a05b 314 if( ( ret = ssl_load_session( &session, ticket, clear_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 315 {
HannesTschofenig 0:796d0f61a05b 316 SSL_DEBUG_MSG( 1, ( "failed to parse ticket content" ) );
HannesTschofenig 0:796d0f61a05b 317 ssl_session_free( &session );
HannesTschofenig 0:796d0f61a05b 318 return( ret );
HannesTschofenig 0:796d0f61a05b 319 }
HannesTschofenig 0:796d0f61a05b 320
HannesTschofenig 0:796d0f61a05b 321 #if defined(POLARSSL_HAVE_TIME)
HannesTschofenig 0:796d0f61a05b 322 /* Check if still valid */
HannesTschofenig 0:796d0f61a05b 323 if( (int) ( time( NULL) - session.start ) > ssl->ticket_lifetime )
HannesTschofenig 0:796d0f61a05b 324 {
HannesTschofenig 0:796d0f61a05b 325 SSL_DEBUG_MSG( 1, ( "session ticket expired" ) );
HannesTschofenig 0:796d0f61a05b 326 ssl_session_free( &session );
HannesTschofenig 0:796d0f61a05b 327 return( POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED );
HannesTschofenig 0:796d0f61a05b 328 }
HannesTschofenig 0:796d0f61a05b 329 #endif
HannesTschofenig 0:796d0f61a05b 330
HannesTschofenig 0:796d0f61a05b 331 /*
HannesTschofenig 0:796d0f61a05b 332 * Keep the session ID sent by the client, since we MUST send it back to
HannesTschofenig 0:796d0f61a05b 333 * inform him we're accepting the ticket (RFC 5077 section 3.4)
HannesTschofenig 0:796d0f61a05b 334 */
HannesTschofenig 0:796d0f61a05b 335 session.length = ssl->session_negotiate->length;
HannesTschofenig 0:796d0f61a05b 336 memcpy( &session.id, ssl->session_negotiate->id, session.length );
HannesTschofenig 0:796d0f61a05b 337
HannesTschofenig 0:796d0f61a05b 338 ssl_session_free( ssl->session_negotiate );
HannesTschofenig 0:796d0f61a05b 339 memcpy( ssl->session_negotiate, &session, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 340 memset( &session, 0, sizeof( ssl_session ) );
HannesTschofenig 0:796d0f61a05b 341
HannesTschofenig 0:796d0f61a05b 342 return( 0 );
HannesTschofenig 0:796d0f61a05b 343 }
HannesTschofenig 0:796d0f61a05b 344 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 345
HannesTschofenig 0:796d0f61a05b 346 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 347 /*
HannesTschofenig 0:796d0f61a05b 348 * Wrapper around f_sni, allowing use of ssl_set_own_cert() but
HannesTschofenig 0:796d0f61a05b 349 * making it act on ssl->hanshake->sni_key_cert instead.
HannesTschofenig 0:796d0f61a05b 350 */
HannesTschofenig 0:796d0f61a05b 351 static int ssl_sni_wrapper( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 352 const unsigned char* name, size_t len )
HannesTschofenig 0:796d0f61a05b 353 {
HannesTschofenig 0:796d0f61a05b 354 int ret;
HannesTschofenig 0:796d0f61a05b 355 ssl_key_cert *key_cert_ori = ssl->key_cert;
HannesTschofenig 0:796d0f61a05b 356
HannesTschofenig 0:796d0f61a05b 357 ssl->key_cert = NULL;
HannesTschofenig 0:796d0f61a05b 358 ret = ssl->f_sni( ssl->p_sni, ssl, name, len );
HannesTschofenig 0:796d0f61a05b 359 ssl->handshake->sni_key_cert = ssl->key_cert;
HannesTschofenig 0:796d0f61a05b 360
HannesTschofenig 0:796d0f61a05b 361 ssl->key_cert = key_cert_ori;
HannesTschofenig 0:796d0f61a05b 362
HannesTschofenig 0:796d0f61a05b 363 return( ret );
HannesTschofenig 0:796d0f61a05b 364 }
HannesTschofenig 0:796d0f61a05b 365
HannesTschofenig 0:796d0f61a05b 366 static int ssl_parse_servername_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 367 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 368 size_t len )
HannesTschofenig 0:796d0f61a05b 369 {
HannesTschofenig 0:796d0f61a05b 370 int ret;
HannesTschofenig 0:796d0f61a05b 371 size_t servername_list_size, hostname_len;
HannesTschofenig 0:796d0f61a05b 372 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 373
HannesTschofenig 0:796d0f61a05b 374 SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
HannesTschofenig 0:796d0f61a05b 375
HannesTschofenig 0:796d0f61a05b 376 servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
HannesTschofenig 0:796d0f61a05b 377 if( servername_list_size + 2 != len )
HannesTschofenig 0:796d0f61a05b 378 {
HannesTschofenig 0:796d0f61a05b 379 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 380 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 381 }
HannesTschofenig 0:796d0f61a05b 382
HannesTschofenig 0:796d0f61a05b 383 p = buf + 2;
HannesTschofenig 0:796d0f61a05b 384 while( servername_list_size > 0 )
HannesTschofenig 0:796d0f61a05b 385 {
HannesTschofenig 0:796d0f61a05b 386 hostname_len = ( ( p[1] << 8 ) | p[2] );
HannesTschofenig 0:796d0f61a05b 387 if( hostname_len + 3 > servername_list_size )
HannesTschofenig 0:796d0f61a05b 388 {
HannesTschofenig 0:796d0f61a05b 389 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 390 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 391 }
HannesTschofenig 0:796d0f61a05b 392
HannesTschofenig 0:796d0f61a05b 393 if( p[0] == TLS_EXT_SERVERNAME_HOSTNAME )
HannesTschofenig 0:796d0f61a05b 394 {
HannesTschofenig 0:796d0f61a05b 395 ret = ssl_sni_wrapper( ssl, p + 3, hostname_len );
HannesTschofenig 0:796d0f61a05b 396 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 397 {
HannesTschofenig 0:796d0f61a05b 398 SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
HannesTschofenig 0:796d0f61a05b 399 ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 400 SSL_ALERT_MSG_UNRECOGNIZED_NAME );
HannesTschofenig 0:796d0f61a05b 401 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 402 }
HannesTschofenig 0:796d0f61a05b 403 return( 0 );
HannesTschofenig 0:796d0f61a05b 404 }
HannesTschofenig 0:796d0f61a05b 405
HannesTschofenig 0:796d0f61a05b 406 servername_list_size -= hostname_len + 3;
HannesTschofenig 0:796d0f61a05b 407 p += hostname_len + 3;
HannesTschofenig 0:796d0f61a05b 408 }
HannesTschofenig 0:796d0f61a05b 409
HannesTschofenig 0:796d0f61a05b 410 if( servername_list_size != 0 )
HannesTschofenig 0:796d0f61a05b 411 {
HannesTschofenig 0:796d0f61a05b 412 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 413 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 414 }
HannesTschofenig 0:796d0f61a05b 415
HannesTschofenig 0:796d0f61a05b 416 return( 0 );
HannesTschofenig 0:796d0f61a05b 417 }
HannesTschofenig 0:796d0f61a05b 418 #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
HannesTschofenig 0:796d0f61a05b 419
HannesTschofenig 0:796d0f61a05b 420 static int ssl_parse_renegotiation_info( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 421 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 422 size_t len )
HannesTschofenig 0:796d0f61a05b 423 {
HannesTschofenig 0:796d0f61a05b 424 int ret;
HannesTschofenig 0:796d0f61a05b 425
HannesTschofenig 0:796d0f61a05b 426 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 427 {
HannesTschofenig 0:796d0f61a05b 428 if( len != 1 || buf[0] != 0x0 )
HannesTschofenig 0:796d0f61a05b 429 {
HannesTschofenig 0:796d0f61a05b 430 SSL_DEBUG_MSG( 1, ( "non-zero length renegotiated connection field" ) );
HannesTschofenig 0:796d0f61a05b 431
HannesTschofenig 0:796d0f61a05b 432 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 433 return( ret );
HannesTschofenig 0:796d0f61a05b 434
HannesTschofenig 0:796d0f61a05b 435 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 436 }
HannesTschofenig 0:796d0f61a05b 437
HannesTschofenig 0:796d0f61a05b 438 ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
HannesTschofenig 0:796d0f61a05b 439 }
HannesTschofenig 0:796d0f61a05b 440 else
HannesTschofenig 0:796d0f61a05b 441 {
HannesTschofenig 0:796d0f61a05b 442 /* Check verify-data in constant-time. The length OTOH is no secret */
HannesTschofenig 0:796d0f61a05b 443 if( len != 1 + ssl->verify_data_len ||
HannesTschofenig 0:796d0f61a05b 444 buf[0] != ssl->verify_data_len ||
HannesTschofenig 0:796d0f61a05b 445 safer_memcmp( buf + 1, ssl->peer_verify_data,
HannesTschofenig 0:796d0f61a05b 446 ssl->verify_data_len ) != 0 )
HannesTschofenig 0:796d0f61a05b 447 {
HannesTschofenig 0:796d0f61a05b 448 SSL_DEBUG_MSG( 1, ( "non-matching renegotiated connection field" ) );
HannesTschofenig 0:796d0f61a05b 449
HannesTschofenig 0:796d0f61a05b 450 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 451 return( ret );
HannesTschofenig 0:796d0f61a05b 452
HannesTschofenig 0:796d0f61a05b 453 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 454 }
HannesTschofenig 0:796d0f61a05b 455 }
HannesTschofenig 0:796d0f61a05b 456
HannesTschofenig 0:796d0f61a05b 457 return( 0 );
HannesTschofenig 0:796d0f61a05b 458 }
HannesTschofenig 0:796d0f61a05b 459
HannesTschofenig 0:796d0f61a05b 460 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 461 static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 462 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 463 size_t len )
HannesTschofenig 0:796d0f61a05b 464 {
HannesTschofenig 0:796d0f61a05b 465 size_t sig_alg_list_size;
HannesTschofenig 0:796d0f61a05b 466 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 467
HannesTschofenig 0:796d0f61a05b 468 sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
HannesTschofenig 0:796d0f61a05b 469 if( sig_alg_list_size + 2 != len ||
HannesTschofenig 0:796d0f61a05b 470 sig_alg_list_size %2 != 0 )
HannesTschofenig 0:796d0f61a05b 471 {
HannesTschofenig 0:796d0f61a05b 472 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 473 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 474 }
HannesTschofenig 0:796d0f61a05b 475
HannesTschofenig 0:796d0f61a05b 476 p = buf + 2;
HannesTschofenig 0:796d0f61a05b 477 while( sig_alg_list_size > 0 )
HannesTschofenig 0:796d0f61a05b 478 {
HannesTschofenig 0:796d0f61a05b 479 /*
HannesTschofenig 0:796d0f61a05b 480 * For now, just ignore signature algorithm and rely on offered
HannesTschofenig 0:796d0f61a05b 481 * ciphersuites only. To be fixed later.
HannesTschofenig 0:796d0f61a05b 482 */
HannesTschofenig 0:796d0f61a05b 483 #if defined(POLARSSL_SHA512_C)
HannesTschofenig 0:796d0f61a05b 484 if( p[0] == SSL_HASH_SHA512 )
HannesTschofenig 0:796d0f61a05b 485 {
HannesTschofenig 0:796d0f61a05b 486 ssl->handshake->sig_alg = SSL_HASH_SHA512;
HannesTschofenig 0:796d0f61a05b 487 break;
HannesTschofenig 0:796d0f61a05b 488 }
HannesTschofenig 0:796d0f61a05b 489 if( p[0] == SSL_HASH_SHA384 )
HannesTschofenig 0:796d0f61a05b 490 {
HannesTschofenig 0:796d0f61a05b 491 ssl->handshake->sig_alg = SSL_HASH_SHA384;
HannesTschofenig 0:796d0f61a05b 492 break;
HannesTschofenig 0:796d0f61a05b 493 }
HannesTschofenig 0:796d0f61a05b 494 #endif /* POLARSSL_SHA512_C */
HannesTschofenig 0:796d0f61a05b 495 #if defined(POLARSSL_SHA256_C)
HannesTschofenig 0:796d0f61a05b 496 if( p[0] == SSL_HASH_SHA256 )
HannesTschofenig 0:796d0f61a05b 497 {
HannesTschofenig 0:796d0f61a05b 498 ssl->handshake->sig_alg = SSL_HASH_SHA256;
HannesTschofenig 0:796d0f61a05b 499 break;
HannesTschofenig 0:796d0f61a05b 500 }
HannesTschofenig 0:796d0f61a05b 501 if( p[0] == SSL_HASH_SHA224 )
HannesTschofenig 0:796d0f61a05b 502 {
HannesTschofenig 0:796d0f61a05b 503 ssl->handshake->sig_alg = SSL_HASH_SHA224;
HannesTschofenig 0:796d0f61a05b 504 break;
HannesTschofenig 0:796d0f61a05b 505 }
HannesTschofenig 0:796d0f61a05b 506 #endif /* POLARSSL_SHA256_C */
HannesTschofenig 0:796d0f61a05b 507 if( p[0] == SSL_HASH_SHA1 )
HannesTschofenig 0:796d0f61a05b 508 {
HannesTschofenig 0:796d0f61a05b 509 ssl->handshake->sig_alg = SSL_HASH_SHA1;
HannesTschofenig 0:796d0f61a05b 510 break;
HannesTschofenig 0:796d0f61a05b 511 }
HannesTschofenig 0:796d0f61a05b 512 if( p[0] == SSL_HASH_MD5 )
HannesTschofenig 0:796d0f61a05b 513 {
HannesTschofenig 0:796d0f61a05b 514 ssl->handshake->sig_alg = SSL_HASH_MD5;
HannesTschofenig 0:796d0f61a05b 515 break;
HannesTschofenig 0:796d0f61a05b 516 }
HannesTschofenig 0:796d0f61a05b 517
HannesTschofenig 0:796d0f61a05b 518 sig_alg_list_size -= 2;
HannesTschofenig 0:796d0f61a05b 519 p += 2;
HannesTschofenig 0:796d0f61a05b 520 }
HannesTschofenig 0:796d0f61a05b 521
HannesTschofenig 0:796d0f61a05b 522 SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
HannesTschofenig 0:796d0f61a05b 523 ssl->handshake->sig_alg ) );
HannesTschofenig 0:796d0f61a05b 524
HannesTschofenig 0:796d0f61a05b 525 return( 0 );
HannesTschofenig 0:796d0f61a05b 526 }
HannesTschofenig 0:796d0f61a05b 527 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 528
HannesTschofenig 0:796d0f61a05b 529 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 530 static int ssl_parse_supported_elliptic_curves( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 531 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 532 size_t len )
HannesTschofenig 0:796d0f61a05b 533 {
HannesTschofenig 0:796d0f61a05b 534 size_t list_size, our_size;
HannesTschofenig 0:796d0f61a05b 535 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 536 const ecp_curve_info *curve_info, **curves;
HannesTschofenig 0:796d0f61a05b 537
HannesTschofenig 0:796d0f61a05b 538 list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
HannesTschofenig 0:796d0f61a05b 539 if( list_size + 2 != len ||
HannesTschofenig 0:796d0f61a05b 540 list_size % 2 != 0 )
HannesTschofenig 0:796d0f61a05b 541 {
HannesTschofenig 0:796d0f61a05b 542 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 543 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 544 }
HannesTschofenig 0:796d0f61a05b 545
HannesTschofenig 0:796d0f61a05b 546 /* Don't allow our peer to make us allocate too much memory,
HannesTschofenig 0:796d0f61a05b 547 * and leave room for a final 0 */
HannesTschofenig 0:796d0f61a05b 548 our_size = list_size / 2 + 1;
HannesTschofenig 0:796d0f61a05b 549 if( our_size > POLARSSL_ECP_DP_MAX )
HannesTschofenig 0:796d0f61a05b 550 our_size = POLARSSL_ECP_DP_MAX;
HannesTschofenig 0:796d0f61a05b 551
HannesTschofenig 0:796d0f61a05b 552 if( ( curves = polarssl_malloc( our_size * sizeof( *curves ) ) ) == NULL )
HannesTschofenig 0:796d0f61a05b 553 return( POLARSSL_ERR_SSL_MALLOC_FAILED );
HannesTschofenig 0:796d0f61a05b 554
HannesTschofenig 0:796d0f61a05b 555 /* explicit void pointer cast for buggy MS compiler */
HannesTschofenig 0:796d0f61a05b 556 memset( (void *) curves, 0, our_size * sizeof( *curves ) );
HannesTschofenig 0:796d0f61a05b 557 ssl->handshake->curves = curves;
HannesTschofenig 0:796d0f61a05b 558
HannesTschofenig 0:796d0f61a05b 559 p = buf + 2;
HannesTschofenig 0:796d0f61a05b 560 while( list_size > 0 && our_size > 1 )
HannesTschofenig 0:796d0f61a05b 561 {
HannesTschofenig 0:796d0f61a05b 562 curve_info = ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
HannesTschofenig 0:796d0f61a05b 563
HannesTschofenig 0:796d0f61a05b 564 if( curve_info != NULL )
HannesTschofenig 0:796d0f61a05b 565 {
HannesTschofenig 0:796d0f61a05b 566 *curves++ = curve_info;
HannesTschofenig 0:796d0f61a05b 567 our_size--;
HannesTschofenig 0:796d0f61a05b 568 }
HannesTschofenig 0:796d0f61a05b 569
HannesTschofenig 0:796d0f61a05b 570 list_size -= 2;
HannesTschofenig 0:796d0f61a05b 571 p += 2;
HannesTschofenig 0:796d0f61a05b 572 }
HannesTschofenig 0:796d0f61a05b 573
HannesTschofenig 0:796d0f61a05b 574 return( 0 );
HannesTschofenig 0:796d0f61a05b 575 }
HannesTschofenig 0:796d0f61a05b 576
HannesTschofenig 0:796d0f61a05b 577 static int ssl_parse_supported_point_formats( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 578 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 579 size_t len )
HannesTschofenig 0:796d0f61a05b 580 {
HannesTschofenig 0:796d0f61a05b 581 size_t list_size;
HannesTschofenig 0:796d0f61a05b 582 const unsigned char *p;
HannesTschofenig 0:796d0f61a05b 583
HannesTschofenig 0:796d0f61a05b 584 list_size = buf[0];
HannesTschofenig 0:796d0f61a05b 585 if( list_size + 1 != len )
HannesTschofenig 0:796d0f61a05b 586 {
HannesTschofenig 0:796d0f61a05b 587 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 588 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 589 }
HannesTschofenig 0:796d0f61a05b 590
HannesTschofenig 0:796d0f61a05b 591 p = buf + 2;
HannesTschofenig 0:796d0f61a05b 592 while( list_size > 0 )
HannesTschofenig 0:796d0f61a05b 593 {
HannesTschofenig 0:796d0f61a05b 594 if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED ||
HannesTschofenig 0:796d0f61a05b 595 p[0] == POLARSSL_ECP_PF_COMPRESSED )
HannesTschofenig 0:796d0f61a05b 596 {
HannesTschofenig 0:796d0f61a05b 597 ssl->handshake->ecdh_ctx.point_format = p[0];
HannesTschofenig 0:796d0f61a05b 598 SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
HannesTschofenig 0:796d0f61a05b 599 return( 0 );
HannesTschofenig 0:796d0f61a05b 600 }
HannesTschofenig 0:796d0f61a05b 601
HannesTschofenig 0:796d0f61a05b 602 list_size--;
HannesTschofenig 0:796d0f61a05b 603 p++;
HannesTschofenig 0:796d0f61a05b 604 }
HannesTschofenig 0:796d0f61a05b 605
HannesTschofenig 0:796d0f61a05b 606 return( 0 );
HannesTschofenig 0:796d0f61a05b 607 }
HannesTschofenig 0:796d0f61a05b 608 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
HannesTschofenig 0:796d0f61a05b 609
HannesTschofenig 0:796d0f61a05b 610 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 611 static int ssl_parse_max_fragment_length_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 612 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 613 size_t len )
HannesTschofenig 0:796d0f61a05b 614 {
HannesTschofenig 0:796d0f61a05b 615 if( len != 1 || buf[0] >= SSL_MAX_FRAG_LEN_INVALID )
HannesTschofenig 0:796d0f61a05b 616 {
HannesTschofenig 0:796d0f61a05b 617 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 618 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 619 }
HannesTschofenig 0:796d0f61a05b 620
HannesTschofenig 0:796d0f61a05b 621 ssl->session_negotiate->mfl_code = buf[0];
HannesTschofenig 0:796d0f61a05b 622
HannesTschofenig 0:796d0f61a05b 623 return( 0 );
HannesTschofenig 0:796d0f61a05b 624 }
HannesTschofenig 0:796d0f61a05b 625 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 626
HannesTschofenig 0:796d0f61a05b 627 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 628 static int ssl_parse_truncated_hmac_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 629 const unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 630 size_t len )
HannesTschofenig 0:796d0f61a05b 631 {
HannesTschofenig 0:796d0f61a05b 632 if( len != 0 )
HannesTschofenig 0:796d0f61a05b 633 {
HannesTschofenig 0:796d0f61a05b 634 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 635 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 636 }
HannesTschofenig 0:796d0f61a05b 637
HannesTschofenig 0:796d0f61a05b 638 ((void) buf);
HannesTschofenig 0:796d0f61a05b 639
HannesTschofenig 0:796d0f61a05b 640 ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
HannesTschofenig 0:796d0f61a05b 641
HannesTschofenig 0:796d0f61a05b 642 return( 0 );
HannesTschofenig 0:796d0f61a05b 643 }
HannesTschofenig 0:796d0f61a05b 644 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
HannesTschofenig 0:796d0f61a05b 645
HannesTschofenig 0:796d0f61a05b 646 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 647 static int ssl_parse_session_ticket_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 648 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 649 size_t len )
HannesTschofenig 0:796d0f61a05b 650 {
HannesTschofenig 0:796d0f61a05b 651 int ret;
HannesTschofenig 0:796d0f61a05b 652
HannesTschofenig 0:796d0f61a05b 653 if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED )
HannesTschofenig 0:796d0f61a05b 654 return( 0 );
HannesTschofenig 0:796d0f61a05b 655
HannesTschofenig 0:796d0f61a05b 656 /* Remember the client asked us to send a new ticket */
HannesTschofenig 0:796d0f61a05b 657 ssl->handshake->new_session_ticket = 1;
HannesTschofenig 0:796d0f61a05b 658
HannesTschofenig 0:796d0f61a05b 659 SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
HannesTschofenig 0:796d0f61a05b 660
HannesTschofenig 0:796d0f61a05b 661 if( len == 0 )
HannesTschofenig 0:796d0f61a05b 662 return( 0 );
HannesTschofenig 0:796d0f61a05b 663
HannesTschofenig 0:796d0f61a05b 664 if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 665 {
HannesTschofenig 0:796d0f61a05b 666 SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
HannesTschofenig 0:796d0f61a05b 667 return( 0 );
HannesTschofenig 0:796d0f61a05b 668 }
HannesTschofenig 0:796d0f61a05b 669
HannesTschofenig 0:796d0f61a05b 670 /*
HannesTschofenig 0:796d0f61a05b 671 * Failures are ok: just ignore the ticket and proceed.
HannesTschofenig 0:796d0f61a05b 672 */
HannesTschofenig 0:796d0f61a05b 673 if( ( ret = ssl_parse_ticket( ssl, buf, len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 674 {
HannesTschofenig 0:796d0f61a05b 675 SSL_DEBUG_RET( 1, "ssl_parse_ticket", ret );
HannesTschofenig 0:796d0f61a05b 676 return( 0 );
HannesTschofenig 0:796d0f61a05b 677 }
HannesTschofenig 0:796d0f61a05b 678
HannesTschofenig 0:796d0f61a05b 679 SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
HannesTschofenig 0:796d0f61a05b 680
HannesTschofenig 0:796d0f61a05b 681 ssl->handshake->resume = 1;
HannesTschofenig 0:796d0f61a05b 682
HannesTschofenig 0:796d0f61a05b 683 /* Don't send a new ticket after all, this one is OK */
HannesTschofenig 0:796d0f61a05b 684 ssl->handshake->new_session_ticket = 0;
HannesTschofenig 0:796d0f61a05b 685
HannesTschofenig 0:796d0f61a05b 686 return( 0 );
HannesTschofenig 0:796d0f61a05b 687 }
HannesTschofenig 0:796d0f61a05b 688 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 689
HannesTschofenig 0:796d0f61a05b 690 #if defined(POLARSSL_SSL_ALPN)
HannesTschofenig 0:796d0f61a05b 691 static int ssl_parse_alpn_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 692 unsigned char *buf, size_t len )
HannesTschofenig 0:796d0f61a05b 693 {
HannesTschofenig 0:796d0f61a05b 694 size_t list_len, cur_len;
HannesTschofenig 0:796d0f61a05b 695 const unsigned char *theirs, *start, *end;
HannesTschofenig 0:796d0f61a05b 696 const char **ours;
HannesTschofenig 0:796d0f61a05b 697
HannesTschofenig 0:796d0f61a05b 698 /* If ALPN not configured, just ignore the extension */
HannesTschofenig 0:796d0f61a05b 699 if( ssl->alpn_list == NULL )
HannesTschofenig 0:796d0f61a05b 700 return( 0 );
HannesTschofenig 0:796d0f61a05b 701
HannesTschofenig 0:796d0f61a05b 702 /*
HannesTschofenig 0:796d0f61a05b 703 * opaque ProtocolName<1..2^8-1>;
HannesTschofenig 0:796d0f61a05b 704 *
HannesTschofenig 0:796d0f61a05b 705 * struct {
HannesTschofenig 0:796d0f61a05b 706 * ProtocolName protocol_name_list<2..2^16-1>
HannesTschofenig 0:796d0f61a05b 707 * } ProtocolNameList;
HannesTschofenig 0:796d0f61a05b 708 */
HannesTschofenig 0:796d0f61a05b 709
HannesTschofenig 0:796d0f61a05b 710 /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
HannesTschofenig 0:796d0f61a05b 711 if( len < 4 )
HannesTschofenig 0:796d0f61a05b 712 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 713
HannesTschofenig 0:796d0f61a05b 714 list_len = ( buf[0] << 8 ) | buf[1];
HannesTschofenig 0:796d0f61a05b 715 if( list_len != len - 2 )
HannesTschofenig 0:796d0f61a05b 716 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 717
HannesTschofenig 0:796d0f61a05b 718 /*
HannesTschofenig 0:796d0f61a05b 719 * Use our order of preference
HannesTschofenig 0:796d0f61a05b 720 */
HannesTschofenig 0:796d0f61a05b 721 start = buf + 2;
HannesTschofenig 0:796d0f61a05b 722 end = buf + len;
HannesTschofenig 0:796d0f61a05b 723 for( ours = ssl->alpn_list; *ours != NULL; ours++ )
HannesTschofenig 0:796d0f61a05b 724 {
HannesTschofenig 0:796d0f61a05b 725 for( theirs = start; theirs != end; theirs += cur_len )
HannesTschofenig 0:796d0f61a05b 726 {
HannesTschofenig 0:796d0f61a05b 727 /* If the list is well formed, we should get equality first */
HannesTschofenig 0:796d0f61a05b 728 if( theirs > end )
HannesTschofenig 0:796d0f61a05b 729 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 730
HannesTschofenig 0:796d0f61a05b 731 cur_len = *theirs++;
HannesTschofenig 0:796d0f61a05b 732
HannesTschofenig 0:796d0f61a05b 733 /* Empty strings MUST NOT be included */
HannesTschofenig 0:796d0f61a05b 734 if( cur_len == 0 )
HannesTschofenig 0:796d0f61a05b 735 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 736
HannesTschofenig 0:796d0f61a05b 737 if( cur_len == strlen( *ours ) &&
HannesTschofenig 0:796d0f61a05b 738 memcmp( theirs, *ours, cur_len ) == 0 )
HannesTschofenig 0:796d0f61a05b 739 {
HannesTschofenig 0:796d0f61a05b 740 ssl->alpn_chosen = *ours;
HannesTschofenig 0:796d0f61a05b 741 return( 0 );
HannesTschofenig 0:796d0f61a05b 742 }
HannesTschofenig 0:796d0f61a05b 743 }
HannesTschofenig 0:796d0f61a05b 744 }
HannesTschofenig 0:796d0f61a05b 745
HannesTschofenig 0:796d0f61a05b 746 /* If we get there, no match was found */
HannesTschofenig 0:796d0f61a05b 747 ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 748 SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
HannesTschofenig 0:796d0f61a05b 749 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 750 }
HannesTschofenig 0:796d0f61a05b 751 #endif /* POLARSSL_SSL_ALPN */
HannesTschofenig 0:796d0f61a05b 752
HannesTschofenig 0:796d0f61a05b 753 /*
HannesTschofenig 0:796d0f61a05b 754 * Auxiliary functions for ServerHello parsing and related actions
HannesTschofenig 0:796d0f61a05b 755 */
HannesTschofenig 0:796d0f61a05b 756
HannesTschofenig 0:796d0f61a05b 757 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 758 /*
HannesTschofenig 0:796d0f61a05b 759 * Return 1 if the given EC key uses the given curve, 0 otherwise
HannesTschofenig 0:796d0f61a05b 760 */
HannesTschofenig 0:796d0f61a05b 761 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 762 static int ssl_key_matches_curves( pk_context *pk,
HannesTschofenig 0:796d0f61a05b 763 const ecp_curve_info **curves )
HannesTschofenig 0:796d0f61a05b 764 {
HannesTschofenig 0:796d0f61a05b 765 const ecp_curve_info **crv = curves;
HannesTschofenig 0:796d0f61a05b 766 ecp_group_id grp_id = pk_ec( *pk )->grp.id;
HannesTschofenig 0:796d0f61a05b 767
HannesTschofenig 0:796d0f61a05b 768 while( *crv != NULL )
HannesTschofenig 0:796d0f61a05b 769 {
HannesTschofenig 0:796d0f61a05b 770 if( (*crv)->grp_id == grp_id )
HannesTschofenig 0:796d0f61a05b 771 return( 1 );
HannesTschofenig 0:796d0f61a05b 772 crv++;
HannesTschofenig 0:796d0f61a05b 773 }
HannesTschofenig 0:796d0f61a05b 774
HannesTschofenig 0:796d0f61a05b 775 return( 0 );
HannesTschofenig 0:796d0f61a05b 776 }
HannesTschofenig 0:796d0f61a05b 777 #endif /* POLARSSL_ECDSA_C */
HannesTschofenig 0:796d0f61a05b 778
HannesTschofenig 0:796d0f61a05b 779 /*
HannesTschofenig 0:796d0f61a05b 780 * Try picking a certificate for this ciphersuite,
HannesTschofenig 0:796d0f61a05b 781 * return 0 on success and -1 on failure.
HannesTschofenig 0:796d0f61a05b 782 */
HannesTschofenig 0:796d0f61a05b 783 static int ssl_pick_cert( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 784 const ssl_ciphersuite_t * ciphersuite_info )
HannesTschofenig 0:796d0f61a05b 785 {
HannesTschofenig 0:796d0f61a05b 786 ssl_key_cert *cur, *list;
HannesTschofenig 0:796d0f61a05b 787 pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
HannesTschofenig 0:796d0f61a05b 788
HannesTschofenig 0:796d0f61a05b 789 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 790 if( ssl->handshake->sni_key_cert != NULL )
HannesTschofenig 0:796d0f61a05b 791 list = ssl->handshake->sni_key_cert;
HannesTschofenig 0:796d0f61a05b 792 else
HannesTschofenig 0:796d0f61a05b 793 #endif
HannesTschofenig 0:796d0f61a05b 794 list = ssl->handshake->key_cert;
HannesTschofenig 0:796d0f61a05b 795
HannesTschofenig 0:796d0f61a05b 796 if( pk_alg == POLARSSL_PK_NONE )
HannesTschofenig 0:796d0f61a05b 797 return( 0 );
HannesTschofenig 0:796d0f61a05b 798
HannesTschofenig 0:796d0f61a05b 799 for( cur = list; cur != NULL; cur = cur->next )
HannesTschofenig 0:796d0f61a05b 800 {
HannesTschofenig 0:796d0f61a05b 801 if( ! pk_can_do( cur->key, pk_alg ) )
HannesTschofenig 0:796d0f61a05b 802 continue;
HannesTschofenig 0:796d0f61a05b 803
HannesTschofenig 0:796d0f61a05b 804 /*
HannesTschofenig 0:796d0f61a05b 805 * This avoids sending the client a cert it'll reject based on
HannesTschofenig 0:796d0f61a05b 806 * keyUsage or other extensions.
HannesTschofenig 0:796d0f61a05b 807 *
HannesTschofenig 0:796d0f61a05b 808 * It also allows the user to provision different certificates for
HannesTschofenig 0:796d0f61a05b 809 * different uses based on keyUsage, eg if they want to avoid signing
HannesTschofenig 0:796d0f61a05b 810 * and decrypting with the same RSA key.
HannesTschofenig 0:796d0f61a05b 811 */
HannesTschofenig 0:796d0f61a05b 812 if( ssl_check_cert_usage( cur->cert, ciphersuite_info,
HannesTschofenig 0:796d0f61a05b 813 SSL_IS_SERVER ) != 0 )
HannesTschofenig 0:796d0f61a05b 814 {
HannesTschofenig 0:796d0f61a05b 815 continue;
HannesTschofenig 0:796d0f61a05b 816 }
HannesTschofenig 0:796d0f61a05b 817
HannesTschofenig 0:796d0f61a05b 818 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 819 if( pk_alg == POLARSSL_PK_ECDSA )
HannesTschofenig 0:796d0f61a05b 820 {
HannesTschofenig 0:796d0f61a05b 821 if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) )
HannesTschofenig 0:796d0f61a05b 822 break;
HannesTschofenig 0:796d0f61a05b 823 }
HannesTschofenig 0:796d0f61a05b 824 else
HannesTschofenig 0:796d0f61a05b 825 #endif
HannesTschofenig 0:796d0f61a05b 826 break;
HannesTschofenig 0:796d0f61a05b 827 }
HannesTschofenig 0:796d0f61a05b 828
HannesTschofenig 0:796d0f61a05b 829 if( cur == NULL )
HannesTschofenig 0:796d0f61a05b 830 return( -1 );
HannesTschofenig 0:796d0f61a05b 831
HannesTschofenig 0:796d0f61a05b 832 ssl->handshake->key_cert = cur;
HannesTschofenig 0:796d0f61a05b 833 return( 0 );
HannesTschofenig 0:796d0f61a05b 834 }
HannesTschofenig 0:796d0f61a05b 835 #endif /* POLARSSL_X509_CRT_PARSE_C */
HannesTschofenig 0:796d0f61a05b 836
HannesTschofenig 0:796d0f61a05b 837 /*
HannesTschofenig 0:796d0f61a05b 838 * Check if a given ciphersuite is suitable for use with our config/keys/etc
HannesTschofenig 0:796d0f61a05b 839 * Sets ciphersuite_info only if the suite matches.
HannesTschofenig 0:796d0f61a05b 840 */
HannesTschofenig 0:796d0f61a05b 841 static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id,
HannesTschofenig 0:796d0f61a05b 842 const ssl_ciphersuite_t **ciphersuite_info )
HannesTschofenig 0:796d0f61a05b 843 {
HannesTschofenig 0:796d0f61a05b 844 const ssl_ciphersuite_t *suite_info;
HannesTschofenig 0:796d0f61a05b 845
HannesTschofenig 0:796d0f61a05b 846 suite_info = ssl_ciphersuite_from_id( suite_id );
HannesTschofenig 0:796d0f61a05b 847 if( suite_info == NULL )
HannesTschofenig 0:796d0f61a05b 848 {
HannesTschofenig 0:796d0f61a05b 849 SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", suite_id ) );
HannesTschofenig 0:796d0f61a05b 850 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 851 }
HannesTschofenig 0:796d0f61a05b 852
HannesTschofenig 0:796d0f61a05b 853 if( suite_info->min_minor_ver > ssl->minor_ver ||
HannesTschofenig 0:796d0f61a05b 854 suite_info->max_minor_ver < ssl->minor_ver )
HannesTschofenig 0:796d0f61a05b 855 return( 0 );
HannesTschofenig 0:796d0f61a05b 856
HannesTschofenig 0:796d0f61a05b 857 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 858 if( ssl_ciphersuite_uses_ec( suite_info ) &&
HannesTschofenig 0:796d0f61a05b 859 ( ssl->handshake->curves == NULL ||
HannesTschofenig 0:796d0f61a05b 860 ssl->handshake->curves[0] == NULL ) )
HannesTschofenig 0:796d0f61a05b 861 return( 0 );
HannesTschofenig 0:796d0f61a05b 862 #endif
HannesTschofenig 0:796d0f61a05b 863
HannesTschofenig 0:796d0f61a05b 864 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 865 /* If the ciphersuite requires a pre-shared key and we don't
HannesTschofenig 0:796d0f61a05b 866 * have one, skip it now rather than failing later */
HannesTschofenig 0:796d0f61a05b 867 if( ssl_ciphersuite_uses_psk( suite_info ) &&
HannesTschofenig 0:796d0f61a05b 868 ssl->f_psk == NULL &&
HannesTschofenig 0:796d0f61a05b 869 ( ssl->psk == NULL || ssl->psk_identity == NULL ||
HannesTschofenig 0:796d0f61a05b 870 ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) )
HannesTschofenig 0:796d0f61a05b 871 return( 0 );
HannesTschofenig 0:796d0f61a05b 872 #endif
HannesTschofenig 0:796d0f61a05b 873
HannesTschofenig 0:796d0f61a05b 874 #if defined(POLARSSL_X509_CRT_PARSE_C)
HannesTschofenig 0:796d0f61a05b 875 /*
HannesTschofenig 0:796d0f61a05b 876 * Final check: if ciphersuite requires us to have a
HannesTschofenig 0:796d0f61a05b 877 * certificate/key of a particular type:
HannesTschofenig 0:796d0f61a05b 878 * - select the appropriate certificate if we have one, or
HannesTschofenig 0:796d0f61a05b 879 * - try the next ciphersuite if we don't
HannesTschofenig 0:796d0f61a05b 880 * This must be done last since we modify the key_cert list.
HannesTschofenig 0:796d0f61a05b 881 */
HannesTschofenig 0:796d0f61a05b 882 if( ssl_pick_cert( ssl, suite_info ) != 0 )
HannesTschofenig 0:796d0f61a05b 883 return( 0 );
HannesTschofenig 0:796d0f61a05b 884 #endif
HannesTschofenig 0:796d0f61a05b 885
HannesTschofenig 0:796d0f61a05b 886 *ciphersuite_info = suite_info;
HannesTschofenig 0:796d0f61a05b 887 return( 0 );
HannesTschofenig 0:796d0f61a05b 888 }
HannesTschofenig 0:796d0f61a05b 889
HannesTschofenig 0:796d0f61a05b 890 #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
HannesTschofenig 0:796d0f61a05b 891 static int ssl_parse_client_hello_v2( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 892 {
HannesTschofenig 0:796d0f61a05b 893 int ret;
HannesTschofenig 0:796d0f61a05b 894 unsigned int i, j;
HannesTschofenig 0:796d0f61a05b 895 size_t n;
HannesTschofenig 0:796d0f61a05b 896 unsigned int ciph_len, sess_len, chal_len;
HannesTschofenig 0:796d0f61a05b 897 unsigned char *buf, *p;
HannesTschofenig 0:796d0f61a05b 898 const int *ciphersuites;
HannesTschofenig 0:796d0f61a05b 899 const ssl_ciphersuite_t *ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 900
HannesTschofenig 0:796d0f61a05b 901 SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
HannesTschofenig 0:796d0f61a05b 902
HannesTschofenig 0:796d0f61a05b 903 if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 904 {
HannesTschofenig 0:796d0f61a05b 905 SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
HannesTschofenig 0:796d0f61a05b 906
HannesTschofenig 0:796d0f61a05b 907 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 908 return( ret );
HannesTschofenig 0:796d0f61a05b 909
HannesTschofenig 0:796d0f61a05b 910 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 911 }
HannesTschofenig 0:796d0f61a05b 912
HannesTschofenig 0:796d0f61a05b 913 buf = ssl->in_hdr;
HannesTschofenig 0:796d0f61a05b 914
HannesTschofenig 0:796d0f61a05b 915 SSL_DEBUG_BUF( 4, "record header", buf, 5 );
HannesTschofenig 0:796d0f61a05b 916
HannesTschofenig 0:796d0f61a05b 917 SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d",
HannesTschofenig 0:796d0f61a05b 918 buf[2] ) );
HannesTschofenig 0:796d0f61a05b 919 SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d",
HannesTschofenig 0:796d0f61a05b 920 ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) );
HannesTschofenig 0:796d0f61a05b 921 SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]",
HannesTschofenig 0:796d0f61a05b 922 buf[3], buf[4] ) );
HannesTschofenig 0:796d0f61a05b 923
HannesTschofenig 0:796d0f61a05b 924 /*
HannesTschofenig 0:796d0f61a05b 925 * SSLv2 Client Hello
HannesTschofenig 0:796d0f61a05b 926 *
HannesTschofenig 0:796d0f61a05b 927 * Record layer:
HannesTschofenig 0:796d0f61a05b 928 * 0 . 1 message length
HannesTschofenig 0:796d0f61a05b 929 *
HannesTschofenig 0:796d0f61a05b 930 * SSL layer:
HannesTschofenig 0:796d0f61a05b 931 * 2 . 2 message type
HannesTschofenig 0:796d0f61a05b 932 * 3 . 4 protocol version
HannesTschofenig 0:796d0f61a05b 933 */
HannesTschofenig 0:796d0f61a05b 934 if( buf[2] != SSL_HS_CLIENT_HELLO ||
HannesTschofenig 0:796d0f61a05b 935 buf[3] != SSL_MAJOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 936 {
HannesTschofenig 0:796d0f61a05b 937 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 938 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 939 }
HannesTschofenig 0:796d0f61a05b 940
HannesTschofenig 0:796d0f61a05b 941 n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF;
HannesTschofenig 0:796d0f61a05b 942
HannesTschofenig 0:796d0f61a05b 943 if( n < 17 || n > 512 )
HannesTschofenig 0:796d0f61a05b 944 {
HannesTschofenig 0:796d0f61a05b 945 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 946 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 947 }
HannesTschofenig 0:796d0f61a05b 948
HannesTschofenig 0:796d0f61a05b 949 ssl->major_ver = SSL_MAJOR_VERSION_3;
HannesTschofenig 0:796d0f61a05b 950 ssl->minor_ver = ( buf[4] <= ssl->max_minor_ver )
HannesTschofenig 0:796d0f61a05b 951 ? buf[4] : ssl->max_minor_ver;
HannesTschofenig 0:796d0f61a05b 952
HannesTschofenig 0:796d0f61a05b 953 if( ssl->minor_ver < ssl->min_minor_ver )
HannesTschofenig 0:796d0f61a05b 954 {
HannesTschofenig 0:796d0f61a05b 955 SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
HannesTschofenig 0:796d0f61a05b 956 " [%d:%d] < [%d:%d]",
HannesTschofenig 0:796d0f61a05b 957 ssl->major_ver, ssl->minor_ver,
HannesTschofenig 0:796d0f61a05b 958 ssl->min_major_ver, ssl->min_minor_ver ) );
HannesTschofenig 0:796d0f61a05b 959
HannesTschofenig 0:796d0f61a05b 960 ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 961 SSL_ALERT_MSG_PROTOCOL_VERSION );
HannesTschofenig 0:796d0f61a05b 962 return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
HannesTschofenig 0:796d0f61a05b 963 }
HannesTschofenig 0:796d0f61a05b 964
HannesTschofenig 0:796d0f61a05b 965 ssl->handshake->max_major_ver = buf[3];
HannesTschofenig 0:796d0f61a05b 966 ssl->handshake->max_minor_ver = buf[4];
HannesTschofenig 0:796d0f61a05b 967
HannesTschofenig 0:796d0f61a05b 968 if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 969 {
HannesTschofenig 0:796d0f61a05b 970 SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
HannesTschofenig 0:796d0f61a05b 971 return( ret );
HannesTschofenig 0:796d0f61a05b 972 }
HannesTschofenig 0:796d0f61a05b 973
HannesTschofenig 0:796d0f61a05b 974 ssl->handshake->update_checksum( ssl, buf + 2, n );
HannesTschofenig 0:796d0f61a05b 975
HannesTschofenig 0:796d0f61a05b 976 buf = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 977 n = ssl->in_left - 5;
HannesTschofenig 0:796d0f61a05b 978
HannesTschofenig 0:796d0f61a05b 979 /*
HannesTschofenig 0:796d0f61a05b 980 * 0 . 1 ciphersuitelist length
HannesTschofenig 0:796d0f61a05b 981 * 2 . 3 session id length
HannesTschofenig 0:796d0f61a05b 982 * 4 . 5 challenge length
HannesTschofenig 0:796d0f61a05b 983 * 6 . .. ciphersuitelist
HannesTschofenig 0:796d0f61a05b 984 * .. . .. session id
HannesTschofenig 0:796d0f61a05b 985 * .. . .. challenge
HannesTschofenig 0:796d0f61a05b 986 */
HannesTschofenig 0:796d0f61a05b 987 SSL_DEBUG_BUF( 4, "record contents", buf, n );
HannesTschofenig 0:796d0f61a05b 988
HannesTschofenig 0:796d0f61a05b 989 ciph_len = ( buf[0] << 8 ) | buf[1];
HannesTschofenig 0:796d0f61a05b 990 sess_len = ( buf[2] << 8 ) | buf[3];
HannesTschofenig 0:796d0f61a05b 991 chal_len = ( buf[4] << 8 ) | buf[5];
HannesTschofenig 0:796d0f61a05b 992
HannesTschofenig 0:796d0f61a05b 993 SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
HannesTschofenig 0:796d0f61a05b 994 ciph_len, sess_len, chal_len ) );
HannesTschofenig 0:796d0f61a05b 995
HannesTschofenig 0:796d0f61a05b 996 /*
HannesTschofenig 0:796d0f61a05b 997 * Make sure each parameter length is valid
HannesTschofenig 0:796d0f61a05b 998 */
HannesTschofenig 0:796d0f61a05b 999 if( ciph_len < 3 || ( ciph_len % 3 ) != 0 )
HannesTschofenig 0:796d0f61a05b 1000 {
HannesTschofenig 0:796d0f61a05b 1001 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1002 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1003 }
HannesTschofenig 0:796d0f61a05b 1004
HannesTschofenig 0:796d0f61a05b 1005 if( sess_len > 32 )
HannesTschofenig 0:796d0f61a05b 1006 {
HannesTschofenig 0:796d0f61a05b 1007 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1008 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1009 }
HannesTschofenig 0:796d0f61a05b 1010
HannesTschofenig 0:796d0f61a05b 1011 if( chal_len < 8 || chal_len > 32 )
HannesTschofenig 0:796d0f61a05b 1012 {
HannesTschofenig 0:796d0f61a05b 1013 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1014 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1015 }
HannesTschofenig 0:796d0f61a05b 1016
HannesTschofenig 0:796d0f61a05b 1017 if( n != 6 + ciph_len + sess_len + chal_len )
HannesTschofenig 0:796d0f61a05b 1018 {
HannesTschofenig 0:796d0f61a05b 1019 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1020 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1021 }
HannesTschofenig 0:796d0f61a05b 1022
HannesTschofenig 0:796d0f61a05b 1023 SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
HannesTschofenig 0:796d0f61a05b 1024 buf + 6, ciph_len );
HannesTschofenig 0:796d0f61a05b 1025 SSL_DEBUG_BUF( 3, "client hello, session id",
HannesTschofenig 0:796d0f61a05b 1026 buf + 6 + ciph_len, sess_len );
HannesTschofenig 0:796d0f61a05b 1027 SSL_DEBUG_BUF( 3, "client hello, challenge",
HannesTschofenig 0:796d0f61a05b 1028 buf + 6 + ciph_len + sess_len, chal_len );
HannesTschofenig 0:796d0f61a05b 1029
HannesTschofenig 0:796d0f61a05b 1030 p = buf + 6 + ciph_len;
HannesTschofenig 0:796d0f61a05b 1031 ssl->session_negotiate->length = sess_len;
HannesTschofenig 0:796d0f61a05b 1032 memset( ssl->session_negotiate->id, 0,
HannesTschofenig 0:796d0f61a05b 1033 sizeof( ssl->session_negotiate->id ) );
HannesTschofenig 0:796d0f61a05b 1034 memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->length );
HannesTschofenig 0:796d0f61a05b 1035
HannesTschofenig 0:796d0f61a05b 1036 p += sess_len;
HannesTschofenig 0:796d0f61a05b 1037 memset( ssl->handshake->randbytes, 0, 64 );
HannesTschofenig 0:796d0f61a05b 1038 memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
HannesTschofenig 0:796d0f61a05b 1039
HannesTschofenig 0:796d0f61a05b 1040 /*
HannesTschofenig 0:796d0f61a05b 1041 * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
HannesTschofenig 0:796d0f61a05b 1042 */
HannesTschofenig 0:796d0f61a05b 1043 for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
HannesTschofenig 0:796d0f61a05b 1044 {
HannesTschofenig 0:796d0f61a05b 1045 if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO )
HannesTschofenig 0:796d0f61a05b 1046 {
HannesTschofenig 0:796d0f61a05b 1047 SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
HannesTschofenig 0:796d0f61a05b 1048 if( ssl->renegotiation == SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 1049 {
HannesTschofenig 0:796d0f61a05b 1050 SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) );
HannesTschofenig 0:796d0f61a05b 1051
HannesTschofenig 0:796d0f61a05b 1052 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1053 return( ret );
HannesTschofenig 0:796d0f61a05b 1054
HannesTschofenig 0:796d0f61a05b 1055 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1056 }
HannesTschofenig 0:796d0f61a05b 1057 ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
HannesTschofenig 0:796d0f61a05b 1058 break;
HannesTschofenig 0:796d0f61a05b 1059 }
HannesTschofenig 0:796d0f61a05b 1060 }
HannesTschofenig 0:796d0f61a05b 1061
HannesTschofenig 0:796d0f61a05b 1062 ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
HannesTschofenig 0:796d0f61a05b 1063 ciphersuite_info = NULL;
HannesTschofenig 0:796d0f61a05b 1064 #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
HannesTschofenig 0:796d0f61a05b 1065 for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
HannesTschofenig 0:796d0f61a05b 1066 {
HannesTschofenig 0:796d0f61a05b 1067 for( i = 0; ciphersuites[i] != 0; i++ )
HannesTschofenig 0:796d0f61a05b 1068 #else
HannesTschofenig 0:796d0f61a05b 1069 for( i = 0; ciphersuites[i] != 0; i++ )
HannesTschofenig 0:796d0f61a05b 1070 {
HannesTschofenig 0:796d0f61a05b 1071 for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
HannesTschofenig 0:796d0f61a05b 1072 #endif
HannesTschofenig 0:796d0f61a05b 1073 {
HannesTschofenig 0:796d0f61a05b 1074 if( p[0] != 0 ||
HannesTschofenig 0:796d0f61a05b 1075 p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
HannesTschofenig 0:796d0f61a05b 1076 p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
HannesTschofenig 0:796d0f61a05b 1077 continue;
HannesTschofenig 0:796d0f61a05b 1078
HannesTschofenig 0:796d0f61a05b 1079 if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
HannesTschofenig 0:796d0f61a05b 1080 &ciphersuite_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1081 return( ret );
HannesTschofenig 0:796d0f61a05b 1082
HannesTschofenig 0:796d0f61a05b 1083 if( ciphersuite_info != NULL )
HannesTschofenig 0:796d0f61a05b 1084 goto have_ciphersuite_v2;
HannesTschofenig 0:796d0f61a05b 1085 }
HannesTschofenig 0:796d0f61a05b 1086 }
HannesTschofenig 0:796d0f61a05b 1087
HannesTschofenig 0:796d0f61a05b 1088 SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
HannesTschofenig 0:796d0f61a05b 1089
HannesTschofenig 0:796d0f61a05b 1090 return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
HannesTschofenig 0:796d0f61a05b 1091
HannesTschofenig 0:796d0f61a05b 1092 have_ciphersuite_v2:
HannesTschofenig 0:796d0f61a05b 1093 ssl->session_negotiate->ciphersuite = ciphersuites[i];
HannesTschofenig 0:796d0f61a05b 1094 ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 1095 ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
HannesTschofenig 0:796d0f61a05b 1096
HannesTschofenig 0:796d0f61a05b 1097 /*
HannesTschofenig 0:796d0f61a05b 1098 * SSLv2 Client Hello relevant renegotiation security checks
HannesTschofenig 0:796d0f61a05b 1099 */
HannesTschofenig 0:796d0f61a05b 1100 if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1101 ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 1102 {
HannesTschofenig 0:796d0f61a05b 1103 SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
HannesTschofenig 0:796d0f61a05b 1104
HannesTschofenig 0:796d0f61a05b 1105 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1106 return( ret );
HannesTschofenig 0:796d0f61a05b 1107
HannesTschofenig 0:796d0f61a05b 1108 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1109 }
HannesTschofenig 0:796d0f61a05b 1110
HannesTschofenig 0:796d0f61a05b 1111 ssl->in_left = 0;
HannesTschofenig 0:796d0f61a05b 1112 ssl->state++;
HannesTschofenig 0:796d0f61a05b 1113
HannesTschofenig 0:796d0f61a05b 1114 SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) );
HannesTschofenig 0:796d0f61a05b 1115
HannesTschofenig 0:796d0f61a05b 1116 return( 0 );
HannesTschofenig 0:796d0f61a05b 1117 }
HannesTschofenig 0:796d0f61a05b 1118 #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
HannesTschofenig 0:796d0f61a05b 1119
HannesTschofenig 0:796d0f61a05b 1120 static int ssl_parse_client_hello( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1121 {
HannesTschofenig 0:796d0f61a05b 1122 int ret;
HannesTschofenig 0:796d0f61a05b 1123 unsigned int i, j;
HannesTschofenig 0:796d0f61a05b 1124 size_t n;
HannesTschofenig 0:796d0f61a05b 1125 unsigned int ciph_len, sess_len;
HannesTschofenig 0:796d0f61a05b 1126 unsigned int comp_len;
HannesTschofenig 0:796d0f61a05b 1127 unsigned int ext_len = 0;
HannesTschofenig 0:796d0f61a05b 1128 unsigned char *buf, *p, *ext;
HannesTschofenig 0:796d0f61a05b 1129 int renegotiation_info_seen = 0;
HannesTschofenig 0:796d0f61a05b 1130 int handshake_failure = 0;
HannesTschofenig 0:796d0f61a05b 1131 const int *ciphersuites;
HannesTschofenig 0:796d0f61a05b 1132 const ssl_ciphersuite_t *ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 1133
HannesTschofenig 0:796d0f61a05b 1134 SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
HannesTschofenig 0:796d0f61a05b 1135
HannesTschofenig 0:796d0f61a05b 1136 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
HannesTschofenig 0:796d0f61a05b 1137 ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1138 {
HannesTschofenig 0:796d0f61a05b 1139 SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
HannesTschofenig 0:796d0f61a05b 1140 return( ret );
HannesTschofenig 0:796d0f61a05b 1141 }
HannesTschofenig 0:796d0f61a05b 1142
HannesTschofenig 0:796d0f61a05b 1143 buf = ssl->in_hdr;
HannesTschofenig 0:796d0f61a05b 1144
HannesTschofenig 0:796d0f61a05b 1145 #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
HannesTschofenig 0:796d0f61a05b 1146 if( ( buf[0] & 0x80 ) != 0 )
HannesTschofenig 0:796d0f61a05b 1147 return ssl_parse_client_hello_v2( ssl );
HannesTschofenig 0:796d0f61a05b 1148 #endif
HannesTschofenig 0:796d0f61a05b 1149
HannesTschofenig 0:796d0f61a05b 1150 SSL_DEBUG_BUF( 4, "record header", buf, 5 );
HannesTschofenig 0:796d0f61a05b 1151
HannesTschofenig 0:796d0f61a05b 1152 SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d",
HannesTschofenig 0:796d0f61a05b 1153 buf[0] ) );
HannesTschofenig 0:796d0f61a05b 1154 SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d",
HannesTschofenig 0:796d0f61a05b 1155 ( buf[3] << 8 ) | buf[4] ) );
HannesTschofenig 0:796d0f61a05b 1156 SSL_DEBUG_MSG( 3, ( "client hello v3, protocol ver: [%d:%d]",
HannesTschofenig 0:796d0f61a05b 1157 buf[1], buf[2] ) );
HannesTschofenig 0:796d0f61a05b 1158
HannesTschofenig 0:796d0f61a05b 1159 /*
HannesTschofenig 0:796d0f61a05b 1160 * SSLv3/TLS Client Hello
HannesTschofenig 0:796d0f61a05b 1161 *
HannesTschofenig 0:796d0f61a05b 1162 * Record layer:
HannesTschofenig 0:796d0f61a05b 1163 * 0 . 0 message type
HannesTschofenig 0:796d0f61a05b 1164 * 1 . 2 protocol version
HannesTschofenig 0:796d0f61a05b 1165 * 3 . 4 message length
HannesTschofenig 0:796d0f61a05b 1166 */
HannesTschofenig 0:796d0f61a05b 1167
HannesTschofenig 0:796d0f61a05b 1168 /* According to RFC 5246 Appendix E.1, the version here is typically
HannesTschofenig 0:796d0f61a05b 1169 * "{03,00}, the lowest version number supported by the client, [or] the
HannesTschofenig 0:796d0f61a05b 1170 * value of ClientHello.client_version", so the only meaningful check here
HannesTschofenig 0:796d0f61a05b 1171 * is the major version shouldn't be less than 3 */
HannesTschofenig 0:796d0f61a05b 1172 if( buf[0] != SSL_MSG_HANDSHAKE ||
HannesTschofenig 0:796d0f61a05b 1173 buf[1] < SSL_MAJOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 1174 {
HannesTschofenig 0:796d0f61a05b 1175 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1176 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1177 }
HannesTschofenig 0:796d0f61a05b 1178
HannesTschofenig 0:796d0f61a05b 1179 n = ( buf[3] << 8 ) | buf[4];
HannesTschofenig 0:796d0f61a05b 1180
HannesTschofenig 0:796d0f61a05b 1181 if( n < 45 || n > SSL_MAX_CONTENT_LEN )
HannesTschofenig 0:796d0f61a05b 1182 {
HannesTschofenig 0:796d0f61a05b 1183 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1184 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1185 }
HannesTschofenig 0:796d0f61a05b 1186
HannesTschofenig 0:796d0f61a05b 1187 if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
HannesTschofenig 0:796d0f61a05b 1188 ( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1189 {
HannesTschofenig 0:796d0f61a05b 1190 SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
HannesTschofenig 0:796d0f61a05b 1191 return( ret );
HannesTschofenig 0:796d0f61a05b 1192 }
HannesTschofenig 0:796d0f61a05b 1193
HannesTschofenig 0:796d0f61a05b 1194 buf = ssl->in_msg;
HannesTschofenig 0:796d0f61a05b 1195 if( !ssl->renegotiation )
HannesTschofenig 0:796d0f61a05b 1196 n = ssl->in_left - 5;
HannesTschofenig 0:796d0f61a05b 1197 else
HannesTschofenig 0:796d0f61a05b 1198 n = ssl->in_msglen;
HannesTschofenig 0:796d0f61a05b 1199
HannesTschofenig 0:796d0f61a05b 1200 ssl->handshake->update_checksum( ssl, buf, n );
HannesTschofenig 0:796d0f61a05b 1201
HannesTschofenig 0:796d0f61a05b 1202 /*
HannesTschofenig 0:796d0f61a05b 1203 * SSL layer:
HannesTschofenig 0:796d0f61a05b 1204 * 0 . 0 handshake type
HannesTschofenig 0:796d0f61a05b 1205 * 1 . 3 handshake length
HannesTschofenig 0:796d0f61a05b 1206 * 4 . 5 protocol version
HannesTschofenig 0:796d0f61a05b 1207 * 6 . 9 UNIX time()
HannesTschofenig 0:796d0f61a05b 1208 * 10 . 37 random bytes
HannesTschofenig 0:796d0f61a05b 1209 * 38 . 38 session id length
HannesTschofenig 0:796d0f61a05b 1210 * 39 . 38+x session id
HannesTschofenig 0:796d0f61a05b 1211 * 39+x . 40+x ciphersuitelist length
HannesTschofenig 0:796d0f61a05b 1212 * 41+x . .. ciphersuitelist
HannesTschofenig 0:796d0f61a05b 1213 * .. . .. compression alg.
HannesTschofenig 0:796d0f61a05b 1214 * .. . .. extensions
HannesTschofenig 0:796d0f61a05b 1215 */
HannesTschofenig 0:796d0f61a05b 1216 SSL_DEBUG_BUF( 4, "record contents", buf, n );
HannesTschofenig 0:796d0f61a05b 1217
HannesTschofenig 0:796d0f61a05b 1218 SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d",
HannesTschofenig 0:796d0f61a05b 1219 buf[0] ) );
HannesTschofenig 0:796d0f61a05b 1220 SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
HannesTschofenig 0:796d0f61a05b 1221 ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
HannesTschofenig 0:796d0f61a05b 1222 SSL_DEBUG_MSG( 3, ( "client hello v3, max. version: [%d:%d]",
HannesTschofenig 0:796d0f61a05b 1223 buf[4], buf[5] ) );
HannesTschofenig 0:796d0f61a05b 1224
HannesTschofenig 0:796d0f61a05b 1225 /*
HannesTschofenig 0:796d0f61a05b 1226 * Check the handshake type and protocol version
HannesTschofenig 0:796d0f61a05b 1227 */
HannesTschofenig 0:796d0f61a05b 1228 if( buf[0] != SSL_HS_CLIENT_HELLO )
HannesTschofenig 0:796d0f61a05b 1229 {
HannesTschofenig 0:796d0f61a05b 1230 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1231 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1232 }
HannesTschofenig 0:796d0f61a05b 1233
HannesTschofenig 0:796d0f61a05b 1234 ssl->major_ver = buf[4];
HannesTschofenig 0:796d0f61a05b 1235 ssl->minor_ver = buf[5];
HannesTschofenig 0:796d0f61a05b 1236
HannesTschofenig 0:796d0f61a05b 1237 ssl->handshake->max_major_ver = ssl->major_ver;
HannesTschofenig 0:796d0f61a05b 1238 ssl->handshake->max_minor_ver = ssl->minor_ver;
HannesTschofenig 0:796d0f61a05b 1239
HannesTschofenig 0:796d0f61a05b 1240 if( ssl->major_ver < ssl->min_major_ver ||
HannesTschofenig 0:796d0f61a05b 1241 ssl->minor_ver < ssl->min_minor_ver )
HannesTschofenig 0:796d0f61a05b 1242 {
HannesTschofenig 0:796d0f61a05b 1243 SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
HannesTschofenig 0:796d0f61a05b 1244 " [%d:%d] < [%d:%d]",
HannesTschofenig 0:796d0f61a05b 1245 ssl->major_ver, ssl->minor_ver,
HannesTschofenig 0:796d0f61a05b 1246 ssl->min_major_ver, ssl->min_minor_ver ) );
HannesTschofenig 0:796d0f61a05b 1247
HannesTschofenig 0:796d0f61a05b 1248 ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 1249 SSL_ALERT_MSG_PROTOCOL_VERSION );
HannesTschofenig 0:796d0f61a05b 1250
HannesTschofenig 0:796d0f61a05b 1251 return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
HannesTschofenig 0:796d0f61a05b 1252 }
HannesTschofenig 0:796d0f61a05b 1253
HannesTschofenig 0:796d0f61a05b 1254 if( ssl->major_ver > ssl->max_major_ver )
HannesTschofenig 0:796d0f61a05b 1255 {
HannesTschofenig 0:796d0f61a05b 1256 ssl->major_ver = ssl->max_major_ver;
HannesTschofenig 0:796d0f61a05b 1257 ssl->minor_ver = ssl->max_minor_ver;
HannesTschofenig 0:796d0f61a05b 1258 }
HannesTschofenig 0:796d0f61a05b 1259 else if( ssl->minor_ver > ssl->max_minor_ver )
HannesTschofenig 0:796d0f61a05b 1260 ssl->minor_ver = ssl->max_minor_ver;
HannesTschofenig 0:796d0f61a05b 1261
HannesTschofenig 0:796d0f61a05b 1262 memcpy( ssl->handshake->randbytes, buf + 6, 32 );
HannesTschofenig 0:796d0f61a05b 1263
HannesTschofenig 0:796d0f61a05b 1264 /*
HannesTschofenig 0:796d0f61a05b 1265 * Check the handshake message length
HannesTschofenig 0:796d0f61a05b 1266 */
HannesTschofenig 0:796d0f61a05b 1267 if( buf[1] != 0 || n != (unsigned int) 4 + ( ( buf[2] << 8 ) | buf[3] ) )
HannesTschofenig 0:796d0f61a05b 1268 {
HannesTschofenig 0:796d0f61a05b 1269 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1270 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1271 }
HannesTschofenig 0:796d0f61a05b 1272
HannesTschofenig 0:796d0f61a05b 1273 /*
HannesTschofenig 0:796d0f61a05b 1274 * Check the session length
HannesTschofenig 0:796d0f61a05b 1275 */
HannesTschofenig 0:796d0f61a05b 1276 sess_len = buf[38];
HannesTschofenig 0:796d0f61a05b 1277
HannesTschofenig 0:796d0f61a05b 1278 if( sess_len > 32 )
HannesTschofenig 0:796d0f61a05b 1279 {
HannesTschofenig 0:796d0f61a05b 1280 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1281 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1282 }
HannesTschofenig 0:796d0f61a05b 1283
HannesTschofenig 0:796d0f61a05b 1284 ssl->session_negotiate->length = sess_len;
HannesTschofenig 0:796d0f61a05b 1285 memset( ssl->session_negotiate->id, 0,
HannesTschofenig 0:796d0f61a05b 1286 sizeof( ssl->session_negotiate->id ) );
HannesTschofenig 0:796d0f61a05b 1287 memcpy( ssl->session_negotiate->id, buf + 39,
HannesTschofenig 0:796d0f61a05b 1288 ssl->session_negotiate->length );
HannesTschofenig 0:796d0f61a05b 1289
HannesTschofenig 0:796d0f61a05b 1290 /*
HannesTschofenig 0:796d0f61a05b 1291 * Check the ciphersuitelist length
HannesTschofenig 0:796d0f61a05b 1292 */
HannesTschofenig 0:796d0f61a05b 1293 ciph_len = ( buf[39 + sess_len] << 8 )
HannesTschofenig 0:796d0f61a05b 1294 | ( buf[40 + sess_len] );
HannesTschofenig 0:796d0f61a05b 1295
HannesTschofenig 0:796d0f61a05b 1296 if( ciph_len < 2 || ( ciph_len % 2 ) != 0 )
HannesTschofenig 0:796d0f61a05b 1297 {
HannesTschofenig 0:796d0f61a05b 1298 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1299 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1300 }
HannesTschofenig 0:796d0f61a05b 1301
HannesTschofenig 0:796d0f61a05b 1302 /*
HannesTschofenig 0:796d0f61a05b 1303 * Check the compression algorithms length
HannesTschofenig 0:796d0f61a05b 1304 */
HannesTschofenig 0:796d0f61a05b 1305 comp_len = buf[41 + sess_len + ciph_len];
HannesTschofenig 0:796d0f61a05b 1306
HannesTschofenig 0:796d0f61a05b 1307 if( comp_len < 1 || comp_len > 16 )
HannesTschofenig 0:796d0f61a05b 1308 {
HannesTschofenig 0:796d0f61a05b 1309 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1310 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1311 }
HannesTschofenig 0:796d0f61a05b 1312
HannesTschofenig 0:796d0f61a05b 1313 /*
HannesTschofenig 0:796d0f61a05b 1314 * Check the extension length
HannesTschofenig 0:796d0f61a05b 1315 */
HannesTschofenig 0:796d0f61a05b 1316 if( n > 42 + sess_len + ciph_len + comp_len )
HannesTschofenig 0:796d0f61a05b 1317 {
HannesTschofenig 0:796d0f61a05b 1318 ext_len = ( buf[42 + sess_len + ciph_len + comp_len] << 8 )
HannesTschofenig 0:796d0f61a05b 1319 | ( buf[43 + sess_len + ciph_len + comp_len] );
HannesTschofenig 0:796d0f61a05b 1320
HannesTschofenig 0:796d0f61a05b 1321 if( ( ext_len > 0 && ext_len < 4 ) ||
HannesTschofenig 0:796d0f61a05b 1322 n != 44 + sess_len + ciph_len + comp_len + ext_len )
HannesTschofenig 0:796d0f61a05b 1323 {
HannesTschofenig 0:796d0f61a05b 1324 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1325 SSL_DEBUG_BUF( 3, "Ext", buf + 44 + sess_len + ciph_len + comp_len, ext_len);
HannesTschofenig 0:796d0f61a05b 1326 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1327 }
HannesTschofenig 0:796d0f61a05b 1328 }
HannesTschofenig 0:796d0f61a05b 1329
HannesTschofenig 0:796d0f61a05b 1330 ssl->session_negotiate->compression = SSL_COMPRESS_NULL;
HannesTschofenig 0:796d0f61a05b 1331 #if defined(POLARSSL_ZLIB_SUPPORT)
HannesTschofenig 0:796d0f61a05b 1332 for( i = 0; i < comp_len; ++i )
HannesTschofenig 0:796d0f61a05b 1333 {
HannesTschofenig 0:796d0f61a05b 1334 if( buf[42 + sess_len + ciph_len + i] == SSL_COMPRESS_DEFLATE )
HannesTschofenig 0:796d0f61a05b 1335 {
HannesTschofenig 0:796d0f61a05b 1336 ssl->session_negotiate->compression = SSL_COMPRESS_DEFLATE;
HannesTschofenig 0:796d0f61a05b 1337 break;
HannesTschofenig 0:796d0f61a05b 1338 }
HannesTschofenig 0:796d0f61a05b 1339 }
HannesTschofenig 0:796d0f61a05b 1340 #endif
HannesTschofenig 0:796d0f61a05b 1341
HannesTschofenig 0:796d0f61a05b 1342 SSL_DEBUG_BUF( 3, "client hello, random bytes",
HannesTschofenig 0:796d0f61a05b 1343 buf + 6, 32 );
HannesTschofenig 0:796d0f61a05b 1344 SSL_DEBUG_BUF( 3, "client hello, session id",
HannesTschofenig 0:796d0f61a05b 1345 buf + 38, sess_len );
HannesTschofenig 0:796d0f61a05b 1346 SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
HannesTschofenig 0:796d0f61a05b 1347 buf + 41 + sess_len, ciph_len );
HannesTschofenig 0:796d0f61a05b 1348 SSL_DEBUG_BUF( 3, "client hello, compression",
HannesTschofenig 0:796d0f61a05b 1349 buf + 42 + sess_len + ciph_len, comp_len );
HannesTschofenig 0:796d0f61a05b 1350
HannesTschofenig 0:796d0f61a05b 1351 /*
HannesTschofenig 0:796d0f61a05b 1352 * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
HannesTschofenig 0:796d0f61a05b 1353 */
HannesTschofenig 0:796d0f61a05b 1354 for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 )
HannesTschofenig 0:796d0f61a05b 1355 {
HannesTschofenig 0:796d0f61a05b 1356 if( p[0] == 0 && p[1] == SSL_EMPTY_RENEGOTIATION_INFO )
HannesTschofenig 0:796d0f61a05b 1357 {
HannesTschofenig 0:796d0f61a05b 1358 SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
HannesTschofenig 0:796d0f61a05b 1359 if( ssl->renegotiation == SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 1360 {
HannesTschofenig 0:796d0f61a05b 1361 SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) );
HannesTschofenig 0:796d0f61a05b 1362
HannesTschofenig 0:796d0f61a05b 1363 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1364 return( ret );
HannesTschofenig 0:796d0f61a05b 1365
HannesTschofenig 0:796d0f61a05b 1366 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1367 }
HannesTschofenig 0:796d0f61a05b 1368 ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
HannesTschofenig 0:796d0f61a05b 1369 break;
HannesTschofenig 0:796d0f61a05b 1370 }
HannesTschofenig 0:796d0f61a05b 1371 }
HannesTschofenig 0:796d0f61a05b 1372
HannesTschofenig 0:796d0f61a05b 1373 ext = buf + 44 + sess_len + ciph_len + comp_len;
HannesTschofenig 0:796d0f61a05b 1374
HannesTschofenig 0:796d0f61a05b 1375 while( ext_len )
HannesTschofenig 0:796d0f61a05b 1376 {
HannesTschofenig 0:796d0f61a05b 1377 unsigned int ext_id = ( ( ext[0] << 8 )
HannesTschofenig 0:796d0f61a05b 1378 | ( ext[1] ) );
HannesTschofenig 0:796d0f61a05b 1379 unsigned int ext_size = ( ( ext[2] << 8 )
HannesTschofenig 0:796d0f61a05b 1380 | ( ext[3] ) );
HannesTschofenig 0:796d0f61a05b 1381
HannesTschofenig 0:796d0f61a05b 1382 if( ext_size + 4 > ext_len )
HannesTschofenig 0:796d0f61a05b 1383 {
HannesTschofenig 0:796d0f61a05b 1384 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1385 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1386 }
HannesTschofenig 0:796d0f61a05b 1387 switch( ext_id )
HannesTschofenig 0:796d0f61a05b 1388 {
HannesTschofenig 0:796d0f61a05b 1389 #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
HannesTschofenig 0:796d0f61a05b 1390 case TLS_EXT_SERVERNAME:
HannesTschofenig 0:796d0f61a05b 1391 SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
HannesTschofenig 0:796d0f61a05b 1392 if( ssl->f_sni == NULL )
HannesTschofenig 0:796d0f61a05b 1393 break;
HannesTschofenig 0:796d0f61a05b 1394
HannesTschofenig 0:796d0f61a05b 1395 ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1396 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1397 return( ret );
HannesTschofenig 0:796d0f61a05b 1398 break;
HannesTschofenig 0:796d0f61a05b 1399 #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
HannesTschofenig 0:796d0f61a05b 1400
HannesTschofenig 0:796d0f61a05b 1401 case TLS_EXT_RENEGOTIATION_INFO:
HannesTschofenig 0:796d0f61a05b 1402 SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
HannesTschofenig 0:796d0f61a05b 1403 renegotiation_info_seen = 1;
HannesTschofenig 0:796d0f61a05b 1404
HannesTschofenig 0:796d0f61a05b 1405 ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1406 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1407 return( ret );
HannesTschofenig 0:796d0f61a05b 1408 break;
HannesTschofenig 0:796d0f61a05b 1409
HannesTschofenig 0:796d0f61a05b 1410 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 1411 case TLS_EXT_SIG_ALG:
HannesTschofenig 0:796d0f61a05b 1412 SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
HannesTschofenig 0:796d0f61a05b 1413 if( ssl->renegotiation == SSL_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 1414 break;
HannesTschofenig 0:796d0f61a05b 1415
HannesTschofenig 0:796d0f61a05b 1416 ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1417 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1418 return( ret );
HannesTschofenig 0:796d0f61a05b 1419 break;
HannesTschofenig 0:796d0f61a05b 1420 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 1421
HannesTschofenig 0:796d0f61a05b 1422 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 1423 case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
HannesTschofenig 0:796d0f61a05b 1424 SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
HannesTschofenig 0:796d0f61a05b 1425
HannesTschofenig 0:796d0f61a05b 1426 ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1427 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1428 return( ret );
HannesTschofenig 0:796d0f61a05b 1429 break;
HannesTschofenig 0:796d0f61a05b 1430
HannesTschofenig 0:796d0f61a05b 1431 case TLS_EXT_SUPPORTED_POINT_FORMATS:
HannesTschofenig 0:796d0f61a05b 1432 SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
HannesTschofenig 0:796d0f61a05b 1433 ssl->handshake->cli_exts |= TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
HannesTschofenig 0:796d0f61a05b 1434
HannesTschofenig 0:796d0f61a05b 1435 ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1436 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1437 return( ret );
HannesTschofenig 0:796d0f61a05b 1438 break;
HannesTschofenig 0:796d0f61a05b 1439 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
HannesTschofenig 0:796d0f61a05b 1440
HannesTschofenig 0:796d0f61a05b 1441 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 1442 case TLS_EXT_MAX_FRAGMENT_LENGTH:
HannesTschofenig 0:796d0f61a05b 1443 SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
HannesTschofenig 0:796d0f61a05b 1444
HannesTschofenig 0:796d0f61a05b 1445 ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1446 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1447 return( ret );
HannesTschofenig 0:796d0f61a05b 1448 break;
HannesTschofenig 0:796d0f61a05b 1449 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 1450
HannesTschofenig 0:796d0f61a05b 1451 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 1452 case TLS_EXT_TRUNCATED_HMAC:
HannesTschofenig 0:796d0f61a05b 1453 SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
HannesTschofenig 0:796d0f61a05b 1454
HannesTschofenig 0:796d0f61a05b 1455 ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1456 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1457 return( ret );
HannesTschofenig 0:796d0f61a05b 1458 break;
HannesTschofenig 0:796d0f61a05b 1459 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
HannesTschofenig 0:796d0f61a05b 1460
HannesTschofenig 0:796d0f61a05b 1461 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 1462 case TLS_EXT_SESSION_TICKET:
HannesTschofenig 0:796d0f61a05b 1463 SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
HannesTschofenig 0:796d0f61a05b 1464
HannesTschofenig 0:796d0f61a05b 1465 ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1466 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1467 return( ret );
HannesTschofenig 0:796d0f61a05b 1468 break;
HannesTschofenig 0:796d0f61a05b 1469 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 1470
HannesTschofenig 0:796d0f61a05b 1471 #if defined(POLARSSL_SSL_ALPN)
HannesTschofenig 0:796d0f61a05b 1472 case TLS_EXT_ALPN:
HannesTschofenig 0:796d0f61a05b 1473 SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
HannesTschofenig 0:796d0f61a05b 1474
HannesTschofenig 0:796d0f61a05b 1475 ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
HannesTschofenig 0:796d0f61a05b 1476 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 1477 return( ret );
HannesTschofenig 0:796d0f61a05b 1478 break;
HannesTschofenig 0:796d0f61a05b 1479 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 1480
HannesTschofenig 0:796d0f61a05b 1481 default:
HannesTschofenig 0:796d0f61a05b 1482 SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
HannesTschofenig 0:796d0f61a05b 1483 ext_id ) );
HannesTschofenig 0:796d0f61a05b 1484 }
HannesTschofenig 0:796d0f61a05b 1485
HannesTschofenig 0:796d0f61a05b 1486 ext_len -= 4 + ext_size;
HannesTschofenig 0:796d0f61a05b 1487 ext += 4 + ext_size;
HannesTschofenig 0:796d0f61a05b 1488
HannesTschofenig 0:796d0f61a05b 1489 if( ext_len > 0 && ext_len < 4 )
HannesTschofenig 0:796d0f61a05b 1490 {
HannesTschofenig 0:796d0f61a05b 1491 SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
HannesTschofenig 0:796d0f61a05b 1492 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1493 }
HannesTschofenig 0:796d0f61a05b 1494 }
HannesTschofenig 0:796d0f61a05b 1495
HannesTschofenig 0:796d0f61a05b 1496 /*
HannesTschofenig 0:796d0f61a05b 1497 * Renegotiation security checks
HannesTschofenig 0:796d0f61a05b 1498 */
HannesTschofenig 0:796d0f61a05b 1499 if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1500 ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 1501 {
HannesTschofenig 0:796d0f61a05b 1502 SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
HannesTschofenig 0:796d0f61a05b 1503 handshake_failure = 1;
HannesTschofenig 0:796d0f61a05b 1504 }
HannesTschofenig 0:796d0f61a05b 1505 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1506 ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1507 renegotiation_info_seen == 0 )
HannesTschofenig 0:796d0f61a05b 1508 {
HannesTschofenig 0:796d0f61a05b 1509 SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
HannesTschofenig 0:796d0f61a05b 1510 handshake_failure = 1;
HannesTschofenig 0:796d0f61a05b 1511 }
HannesTschofenig 0:796d0f61a05b 1512 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1513 ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1514 ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 1515 {
HannesTschofenig 0:796d0f61a05b 1516 SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
HannesTschofenig 0:796d0f61a05b 1517 handshake_failure = 1;
HannesTschofenig 0:796d0f61a05b 1518 }
HannesTschofenig 0:796d0f61a05b 1519 else if( ssl->renegotiation == SSL_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1520 ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
HannesTschofenig 0:796d0f61a05b 1521 renegotiation_info_seen == 1 )
HannesTschofenig 0:796d0f61a05b 1522 {
HannesTschofenig 0:796d0f61a05b 1523 SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
HannesTschofenig 0:796d0f61a05b 1524 handshake_failure = 1;
HannesTschofenig 0:796d0f61a05b 1525 }
HannesTschofenig 0:796d0f61a05b 1526
HannesTschofenig 0:796d0f61a05b 1527 if( handshake_failure == 1 )
HannesTschofenig 0:796d0f61a05b 1528 {
HannesTschofenig 0:796d0f61a05b 1529 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1530 return( ret );
HannesTschofenig 0:796d0f61a05b 1531
HannesTschofenig 0:796d0f61a05b 1532 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
HannesTschofenig 0:796d0f61a05b 1533 }
HannesTschofenig 0:796d0f61a05b 1534
HannesTschofenig 0:796d0f61a05b 1535 /*
HannesTschofenig 0:796d0f61a05b 1536 * Search for a matching ciphersuite
HannesTschofenig 0:796d0f61a05b 1537 * (At the end because we need information from the EC-based extensions
HannesTschofenig 0:796d0f61a05b 1538 * and certificate from the SNI callback triggered by the SNI extension.)
HannesTschofenig 0:796d0f61a05b 1539 */
HannesTschofenig 0:796d0f61a05b 1540 ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
HannesTschofenig 0:796d0f61a05b 1541 ciphersuite_info = NULL;
HannesTschofenig 0:796d0f61a05b 1542 #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
HannesTschofenig 0:796d0f61a05b 1543 for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 )
HannesTschofenig 0:796d0f61a05b 1544 {
HannesTschofenig 0:796d0f61a05b 1545 for( i = 0; ciphersuites[i] != 0; i++ )
HannesTschofenig 0:796d0f61a05b 1546 #else
HannesTschofenig 0:796d0f61a05b 1547 for( i = 0; ciphersuites[i] != 0; i++ )
HannesTschofenig 0:796d0f61a05b 1548 {
HannesTschofenig 0:796d0f61a05b 1549 for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 )
HannesTschofenig 0:796d0f61a05b 1550 #endif
HannesTschofenig 0:796d0f61a05b 1551 {
HannesTschofenig 0:796d0f61a05b 1552 if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
HannesTschofenig 0:796d0f61a05b 1553 p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
HannesTschofenig 0:796d0f61a05b 1554 continue;
HannesTschofenig 0:796d0f61a05b 1555
HannesTschofenig 0:796d0f61a05b 1556 if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
HannesTschofenig 0:796d0f61a05b 1557 &ciphersuite_info ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1558 return( ret );
HannesTschofenig 0:796d0f61a05b 1559
HannesTschofenig 0:796d0f61a05b 1560 if( ciphersuite_info != NULL )
HannesTschofenig 0:796d0f61a05b 1561 goto have_ciphersuite;
HannesTschofenig 0:796d0f61a05b 1562 }
HannesTschofenig 0:796d0f61a05b 1563 }
HannesTschofenig 0:796d0f61a05b 1564
HannesTschofenig 0:796d0f61a05b 1565 SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
HannesTschofenig 0:796d0f61a05b 1566
HannesTschofenig 0:796d0f61a05b 1567 if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1568 return( ret );
HannesTschofenig 0:796d0f61a05b 1569
HannesTschofenig 0:796d0f61a05b 1570 return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
HannesTschofenig 0:796d0f61a05b 1571
HannesTschofenig 0:796d0f61a05b 1572 have_ciphersuite:
HannesTschofenig 0:796d0f61a05b 1573 ssl->session_negotiate->ciphersuite = ciphersuites[i];
HannesTschofenig 0:796d0f61a05b 1574 ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 1575 ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
HannesTschofenig 0:796d0f61a05b 1576
HannesTschofenig 0:796d0f61a05b 1577 ssl->in_left = 0;
HannesTschofenig 0:796d0f61a05b 1578 ssl->state++;
HannesTschofenig 0:796d0f61a05b 1579
HannesTschofenig 0:796d0f61a05b 1580 SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
HannesTschofenig 0:796d0f61a05b 1581
HannesTschofenig 0:796d0f61a05b 1582 return( 0 );
HannesTschofenig 0:796d0f61a05b 1583 }
HannesTschofenig 0:796d0f61a05b 1584
HannesTschofenig 0:796d0f61a05b 1585 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 1586 static void ssl_write_truncated_hmac_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1587 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 1588 size_t *olen )
HannesTschofenig 0:796d0f61a05b 1589 {
HannesTschofenig 0:796d0f61a05b 1590 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 1591
HannesTschofenig 0:796d0f61a05b 1592 if( ssl->session_negotiate->trunc_hmac == SSL_TRUNC_HMAC_DISABLED )
HannesTschofenig 0:796d0f61a05b 1593 {
HannesTschofenig 0:796d0f61a05b 1594 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1595 return;
HannesTschofenig 0:796d0f61a05b 1596 }
HannesTschofenig 0:796d0f61a05b 1597
HannesTschofenig 0:796d0f61a05b 1598 SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
HannesTschofenig 0:796d0f61a05b 1599
HannesTschofenig 0:796d0f61a05b 1600 *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1601 *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1602
HannesTschofenig 0:796d0f61a05b 1603 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1604 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1605
HannesTschofenig 0:796d0f61a05b 1606 *olen = 4;
HannesTschofenig 0:796d0f61a05b 1607 }
HannesTschofenig 0:796d0f61a05b 1608 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
HannesTschofenig 0:796d0f61a05b 1609
HannesTschofenig 0:796d0f61a05b 1610 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 1611 static void ssl_write_session_ticket_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1612 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 1613 size_t *olen )
HannesTschofenig 0:796d0f61a05b 1614 {
HannesTschofenig 0:796d0f61a05b 1615 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 1616
HannesTschofenig 0:796d0f61a05b 1617 if( ssl->handshake->new_session_ticket == 0 )
HannesTschofenig 0:796d0f61a05b 1618 {
HannesTschofenig 0:796d0f61a05b 1619 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1620 return;
HannesTschofenig 0:796d0f61a05b 1621 }
HannesTschofenig 0:796d0f61a05b 1622
HannesTschofenig 0:796d0f61a05b 1623 SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
HannesTschofenig 0:796d0f61a05b 1624
HannesTschofenig 0:796d0f61a05b 1625 *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1626 *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1627
HannesTschofenig 0:796d0f61a05b 1628 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1629 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1630
HannesTschofenig 0:796d0f61a05b 1631 *olen = 4;
HannesTschofenig 0:796d0f61a05b 1632 }
HannesTschofenig 0:796d0f61a05b 1633 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 1634
HannesTschofenig 0:796d0f61a05b 1635 static void ssl_write_renegotiation_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1636 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 1637 size_t *olen )
HannesTschofenig 0:796d0f61a05b 1638 {
HannesTschofenig 0:796d0f61a05b 1639 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 1640
HannesTschofenig 0:796d0f61a05b 1641 if( ssl->secure_renegotiation != SSL_SECURE_RENEGOTIATION )
HannesTschofenig 0:796d0f61a05b 1642 {
HannesTschofenig 0:796d0f61a05b 1643 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1644 return;
HannesTschofenig 0:796d0f61a05b 1645 }
HannesTschofenig 0:796d0f61a05b 1646
HannesTschofenig 0:796d0f61a05b 1647 SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
HannesTschofenig 0:796d0f61a05b 1648
HannesTschofenig 0:796d0f61a05b 1649 *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1650 *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1651
HannesTschofenig 0:796d0f61a05b 1652 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1653 *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 1654 *p++ = ssl->verify_data_len * 2 & 0xFF;
HannesTschofenig 0:796d0f61a05b 1655
HannesTschofenig 0:796d0f61a05b 1656 memcpy( p, ssl->peer_verify_data, ssl->verify_data_len );
HannesTschofenig 0:796d0f61a05b 1657 p += ssl->verify_data_len;
HannesTschofenig 0:796d0f61a05b 1658 memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
HannesTschofenig 0:796d0f61a05b 1659 p += ssl->verify_data_len;
HannesTschofenig 0:796d0f61a05b 1660
HannesTschofenig 0:796d0f61a05b 1661 *olen = 5 + ssl->verify_data_len * 2;
HannesTschofenig 0:796d0f61a05b 1662 }
HannesTschofenig 0:796d0f61a05b 1663
HannesTschofenig 0:796d0f61a05b 1664 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 1665 static void ssl_write_max_fragment_length_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1666 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 1667 size_t *olen )
HannesTschofenig 0:796d0f61a05b 1668 {
HannesTschofenig 0:796d0f61a05b 1669 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 1670
HannesTschofenig 0:796d0f61a05b 1671 if( ssl->session_negotiate->mfl_code == SSL_MAX_FRAG_LEN_NONE )
HannesTschofenig 0:796d0f61a05b 1672 {
HannesTschofenig 0:796d0f61a05b 1673 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1674 return;
HannesTschofenig 0:796d0f61a05b 1675 }
HannesTschofenig 0:796d0f61a05b 1676
HannesTschofenig 0:796d0f61a05b 1677 SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
HannesTschofenig 0:796d0f61a05b 1678
HannesTschofenig 0:796d0f61a05b 1679 *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1680 *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1681
HannesTschofenig 0:796d0f61a05b 1682 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1683 *p++ = 1;
HannesTschofenig 0:796d0f61a05b 1684
HannesTschofenig 0:796d0f61a05b 1685 *p++ = ssl->session_negotiate->mfl_code;
HannesTschofenig 0:796d0f61a05b 1686
HannesTschofenig 0:796d0f61a05b 1687 *olen = 5;
HannesTschofenig 0:796d0f61a05b 1688 }
HannesTschofenig 0:796d0f61a05b 1689 #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
HannesTschofenig 0:796d0f61a05b 1690
HannesTschofenig 0:796d0f61a05b 1691 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 1692 static void ssl_write_supported_point_formats_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1693 unsigned char *buf,
HannesTschofenig 0:796d0f61a05b 1694 size_t *olen )
HannesTschofenig 0:796d0f61a05b 1695 {
HannesTschofenig 0:796d0f61a05b 1696 unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 1697 ((void) ssl);
HannesTschofenig 0:796d0f61a05b 1698
HannesTschofenig 0:796d0f61a05b 1699 if( ( ssl->handshake->cli_exts &
HannesTschofenig 0:796d0f61a05b 1700 TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 )
HannesTschofenig 0:796d0f61a05b 1701 {
HannesTschofenig 0:796d0f61a05b 1702 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1703 return;
HannesTschofenig 0:796d0f61a05b 1704 }
HannesTschofenig 0:796d0f61a05b 1705
HannesTschofenig 0:796d0f61a05b 1706 SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
HannesTschofenig 0:796d0f61a05b 1707
HannesTschofenig 0:796d0f61a05b 1708 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1709 *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1710
HannesTschofenig 0:796d0f61a05b 1711 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 1712 *p++ = 2;
HannesTschofenig 0:796d0f61a05b 1713
HannesTschofenig 0:796d0f61a05b 1714 *p++ = 1;
HannesTschofenig 0:796d0f61a05b 1715 *p++ = POLARSSL_ECP_PF_UNCOMPRESSED;
HannesTschofenig 0:796d0f61a05b 1716
HannesTschofenig 0:796d0f61a05b 1717 *olen = 6;
HannesTschofenig 0:796d0f61a05b 1718 }
HannesTschofenig 0:796d0f61a05b 1719 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
HannesTschofenig 0:796d0f61a05b 1720
HannesTschofenig 0:796d0f61a05b 1721 #if defined(POLARSSL_SSL_ALPN )
HannesTschofenig 0:796d0f61a05b 1722 static void ssl_write_alpn_ext( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 1723 unsigned char *buf, size_t *olen )
HannesTschofenig 0:796d0f61a05b 1724 {
HannesTschofenig 0:796d0f61a05b 1725 if( ssl->alpn_chosen == NULL )
HannesTschofenig 0:796d0f61a05b 1726 {
HannesTschofenig 0:796d0f61a05b 1727 *olen = 0;
HannesTschofenig 0:796d0f61a05b 1728 return;
HannesTschofenig 0:796d0f61a05b 1729 }
HannesTschofenig 0:796d0f61a05b 1730
HannesTschofenig 0:796d0f61a05b 1731 SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) );
HannesTschofenig 0:796d0f61a05b 1732
HannesTschofenig 0:796d0f61a05b 1733 /*
HannesTschofenig 0:796d0f61a05b 1734 * 0 . 1 ext identifier
HannesTschofenig 0:796d0f61a05b 1735 * 2 . 3 ext length
HannesTschofenig 0:796d0f61a05b 1736 * 4 . 5 protocol list length
HannesTschofenig 0:796d0f61a05b 1737 * 6 . 6 protocol name length
HannesTschofenig 0:796d0f61a05b 1738 * 7 . 7+n protocol name
HannesTschofenig 0:796d0f61a05b 1739 */
HannesTschofenig 0:796d0f61a05b 1740 buf[0] = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1741 buf[1] = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1742
HannesTschofenig 0:796d0f61a05b 1743 *olen = 7 + strlen( ssl->alpn_chosen );
HannesTschofenig 0:796d0f61a05b 1744
HannesTschofenig 0:796d0f61a05b 1745 buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1746 buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1747
HannesTschofenig 0:796d0f61a05b 1748 buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1749 buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1750
HannesTschofenig 0:796d0f61a05b 1751 buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1752
HannesTschofenig 0:796d0f61a05b 1753 memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
HannesTschofenig 0:796d0f61a05b 1754 }
HannesTschofenig 0:796d0f61a05b 1755 #endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
HannesTschofenig 0:796d0f61a05b 1756
HannesTschofenig 0:796d0f61a05b 1757 static int ssl_write_server_hello( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1758 {
HannesTschofenig 0:796d0f61a05b 1759 #if defined(POLARSSL_HAVE_TIME)
HannesTschofenig 0:796d0f61a05b 1760 time_t t;
HannesTschofenig 0:796d0f61a05b 1761 #endif
HannesTschofenig 0:796d0f61a05b 1762 int ret;
HannesTschofenig 0:796d0f61a05b 1763 size_t olen, ext_len = 0, n;
HannesTschofenig 0:796d0f61a05b 1764 unsigned char *buf, *p;
HannesTschofenig 0:796d0f61a05b 1765
HannesTschofenig 0:796d0f61a05b 1766 SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
HannesTschofenig 0:796d0f61a05b 1767
HannesTschofenig 0:796d0f61a05b 1768 if( ssl->f_rng == NULL )
HannesTschofenig 0:796d0f61a05b 1769 {
HannesTschofenig 0:796d0f61a05b 1770 SSL_DEBUG_MSG( 1, ( "no RNG provided") );
HannesTschofenig 0:796d0f61a05b 1771 return( POLARSSL_ERR_SSL_NO_RNG );
HannesTschofenig 0:796d0f61a05b 1772 }
HannesTschofenig 0:796d0f61a05b 1773
HannesTschofenig 0:796d0f61a05b 1774 /*
HannesTschofenig 0:796d0f61a05b 1775 * 0 . 0 handshake type
HannesTschofenig 0:796d0f61a05b 1776 * 1 . 3 handshake length
HannesTschofenig 0:796d0f61a05b 1777 * 4 . 5 protocol version
HannesTschofenig 0:796d0f61a05b 1778 * 6 . 9 UNIX time()
HannesTschofenig 0:796d0f61a05b 1779 * 10 . 37 random bytes
HannesTschofenig 0:796d0f61a05b 1780 */
HannesTschofenig 0:796d0f61a05b 1781 buf = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 1782 p = buf + 4;
HannesTschofenig 0:796d0f61a05b 1783
HannesTschofenig 0:796d0f61a05b 1784 *p++ = (unsigned char) ssl->major_ver;
HannesTschofenig 0:796d0f61a05b 1785 *p++ = (unsigned char) ssl->minor_ver;
HannesTschofenig 0:796d0f61a05b 1786
HannesTschofenig 0:796d0f61a05b 1787 SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
HannesTschofenig 0:796d0f61a05b 1788 buf[4], buf[5] ) );
HannesTschofenig 0:796d0f61a05b 1789
HannesTschofenig 0:796d0f61a05b 1790 #if defined(POLARSSL_HAVE_TIME)
HannesTschofenig 0:796d0f61a05b 1791 t = time( NULL );
HannesTschofenig 0:796d0f61a05b 1792 *p++ = (unsigned char)( t >> 24 );
HannesTschofenig 0:796d0f61a05b 1793 *p++ = (unsigned char)( t >> 16 );
HannesTschofenig 0:796d0f61a05b 1794 *p++ = (unsigned char)( t >> 8 );
HannesTschofenig 0:796d0f61a05b 1795 *p++ = (unsigned char)( t );
HannesTschofenig 0:796d0f61a05b 1796
HannesTschofenig 0:796d0f61a05b 1797 SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
HannesTschofenig 0:796d0f61a05b 1798 #else
HannesTschofenig 0:796d0f61a05b 1799 if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1800 return( ret );
HannesTschofenig 0:796d0f61a05b 1801
HannesTschofenig 0:796d0f61a05b 1802 p += 4;
HannesTschofenig 0:796d0f61a05b 1803 #endif /* POLARSSL_HAVE_TIME */
HannesTschofenig 0:796d0f61a05b 1804
HannesTschofenig 0:796d0f61a05b 1805 if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1806 return( ret );
HannesTschofenig 0:796d0f61a05b 1807
HannesTschofenig 0:796d0f61a05b 1808 p += 28;
HannesTschofenig 0:796d0f61a05b 1809
HannesTschofenig 0:796d0f61a05b 1810 memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
HannesTschofenig 0:796d0f61a05b 1811
HannesTschofenig 0:796d0f61a05b 1812 SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
HannesTschofenig 0:796d0f61a05b 1813
HannesTschofenig 0:796d0f61a05b 1814 /*
HannesTschofenig 0:796d0f61a05b 1815 * Resume is 0 by default, see ssl_handshake_init().
HannesTschofenig 0:796d0f61a05b 1816 * It may be already set to 1 by ssl_parse_session_ticket_ext().
HannesTschofenig 0:796d0f61a05b 1817 * If not, try looking up session ID in our cache.
HannesTschofenig 0:796d0f61a05b 1818 */
HannesTschofenig 0:796d0f61a05b 1819 if( ssl->handshake->resume == 0 &&
HannesTschofenig 0:796d0f61a05b 1820 ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
HannesTschofenig 0:796d0f61a05b 1821 ssl->session_negotiate->length != 0 &&
HannesTschofenig 0:796d0f61a05b 1822 ssl->f_get_cache != NULL &&
HannesTschofenig 0:796d0f61a05b 1823 ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 )
HannesTschofenig 0:796d0f61a05b 1824 {
HannesTschofenig 0:796d0f61a05b 1825 SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
HannesTschofenig 0:796d0f61a05b 1826 ssl->handshake->resume = 1;
HannesTschofenig 0:796d0f61a05b 1827 }
HannesTschofenig 0:796d0f61a05b 1828
HannesTschofenig 0:796d0f61a05b 1829 if( ssl->handshake->resume == 0 )
HannesTschofenig 0:796d0f61a05b 1830 {
HannesTschofenig 0:796d0f61a05b 1831 /*
HannesTschofenig 0:796d0f61a05b 1832 * New session, create a new session id,
HannesTschofenig 0:796d0f61a05b 1833 * unless we're about to issue a session ticket
HannesTschofenig 0:796d0f61a05b 1834 */
HannesTschofenig 0:796d0f61a05b 1835 ssl->state++;
HannesTschofenig 0:796d0f61a05b 1836
HannesTschofenig 0:796d0f61a05b 1837 #if defined(POLARSSL_HAVE_TIME)
HannesTschofenig 0:796d0f61a05b 1838 ssl->session_negotiate->start = time( NULL );
HannesTschofenig 0:796d0f61a05b 1839 #endif
HannesTschofenig 0:796d0f61a05b 1840
HannesTschofenig 0:796d0f61a05b 1841 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 1842 if( ssl->handshake->new_session_ticket != 0 )
HannesTschofenig 0:796d0f61a05b 1843 {
HannesTschofenig 0:796d0f61a05b 1844 ssl->session_negotiate->length = n = 0;
HannesTschofenig 0:796d0f61a05b 1845 memset( ssl->session_negotiate->id, 0, 32 );
HannesTschofenig 0:796d0f61a05b 1846 }
HannesTschofenig 0:796d0f61a05b 1847 else
HannesTschofenig 0:796d0f61a05b 1848 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 1849 {
HannesTschofenig 0:796d0f61a05b 1850 ssl->session_negotiate->length = n = 32;
HannesTschofenig 0:796d0f61a05b 1851 if( ( ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id,
HannesTschofenig 0:796d0f61a05b 1852 n ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1853 return( ret );
HannesTschofenig 0:796d0f61a05b 1854 }
HannesTschofenig 0:796d0f61a05b 1855 }
HannesTschofenig 0:796d0f61a05b 1856 else
HannesTschofenig 0:796d0f61a05b 1857 {
HannesTschofenig 0:796d0f61a05b 1858 /*
HannesTschofenig 0:796d0f61a05b 1859 * Resuming a session
HannesTschofenig 0:796d0f61a05b 1860 */
HannesTschofenig 0:796d0f61a05b 1861 n = ssl->session_negotiate->length;
HannesTschofenig 0:796d0f61a05b 1862 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
HannesTschofenig 0:796d0f61a05b 1863
HannesTschofenig 0:796d0f61a05b 1864 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 1865 {
HannesTschofenig 0:796d0f61a05b 1866 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
HannesTschofenig 0:796d0f61a05b 1867 return( ret );
HannesTschofenig 0:796d0f61a05b 1868 }
HannesTschofenig 0:796d0f61a05b 1869 }
HannesTschofenig 0:796d0f61a05b 1870
HannesTschofenig 0:796d0f61a05b 1871 /*
HannesTschofenig 0:796d0f61a05b 1872 * 38 . 38 session id length
HannesTschofenig 0:796d0f61a05b 1873 * 39 . 38+n session id
HannesTschofenig 0:796d0f61a05b 1874 * 39+n . 40+n chosen ciphersuite
HannesTschofenig 0:796d0f61a05b 1875 * 41+n . 41+n chosen compression alg.
HannesTschofenig 0:796d0f61a05b 1876 * 42+n . 43+n extensions length
HannesTschofenig 0:796d0f61a05b 1877 * 44+n . 43+n+m extensions
HannesTschofenig 0:796d0f61a05b 1878 */
HannesTschofenig 0:796d0f61a05b 1879 *p++ = (unsigned char) ssl->session_negotiate->length;
HannesTschofenig 0:796d0f61a05b 1880 memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->length );
HannesTschofenig 0:796d0f61a05b 1881 p += ssl->session_negotiate->length;
HannesTschofenig 0:796d0f61a05b 1882
HannesTschofenig 0:796d0f61a05b 1883 SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
HannesTschofenig 0:796d0f61a05b 1884 SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
HannesTschofenig 0:796d0f61a05b 1885 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
HannesTschofenig 0:796d0f61a05b 1886 ssl->handshake->resume ? "a" : "no" ) );
HannesTschofenig 0:796d0f61a05b 1887
HannesTschofenig 0:796d0f61a05b 1888 *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
HannesTschofenig 0:796d0f61a05b 1889 *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite );
HannesTschofenig 0:796d0f61a05b 1890 *p++ = (unsigned char)( ssl->session_negotiate->compression );
HannesTschofenig 0:796d0f61a05b 1891
HannesTschofenig 0:796d0f61a05b 1892 SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
HannesTschofenig 0:796d0f61a05b 1893 ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
HannesTschofenig 0:796d0f61a05b 1894 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
HannesTschofenig 0:796d0f61a05b 1895 ssl->session_negotiate->compression ) );
HannesTschofenig 0:796d0f61a05b 1896
HannesTschofenig 0:796d0f61a05b 1897 /*
HannesTschofenig 0:796d0f61a05b 1898 * First write extensions, then the total length
HannesTschofenig 0:796d0f61a05b 1899 */
HannesTschofenig 0:796d0f61a05b 1900 ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1901 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1902
HannesTschofenig 0:796d0f61a05b 1903 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
HannesTschofenig 0:796d0f61a05b 1904 ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1905 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1906 #endif
HannesTschofenig 0:796d0f61a05b 1907
HannesTschofenig 0:796d0f61a05b 1908 #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
HannesTschofenig 0:796d0f61a05b 1909 ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1910 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1911 #endif
HannesTschofenig 0:796d0f61a05b 1912
HannesTschofenig 0:796d0f61a05b 1913 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 1914 ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1915 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1916 #endif
HannesTschofenig 0:796d0f61a05b 1917
HannesTschofenig 0:796d0f61a05b 1918 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 1919 ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1920 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1921 #endif
HannesTschofenig 0:796d0f61a05b 1922
HannesTschofenig 0:796d0f61a05b 1923 #if defined(POLARSSL_SSL_ALPN)
HannesTschofenig 0:796d0f61a05b 1924 ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
HannesTschofenig 0:796d0f61a05b 1925 ext_len += olen;
HannesTschofenig 0:796d0f61a05b 1926 #endif
HannesTschofenig 0:796d0f61a05b 1927
HannesTschofenig 0:796d0f61a05b 1928 SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
HannesTschofenig 0:796d0f61a05b 1929
HannesTschofenig 0:796d0f61a05b 1930 if( ext_len > 0 )
HannesTschofenig 0:796d0f61a05b 1931 {
HannesTschofenig 0:796d0f61a05b 1932 *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1933 *p++ = (unsigned char)( ( ext_len ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 1934 p += ext_len;
HannesTschofenig 0:796d0f61a05b 1935 }
HannesTschofenig 0:796d0f61a05b 1936
HannesTschofenig 0:796d0f61a05b 1937 ssl->out_msglen = p - buf;
HannesTschofenig 0:796d0f61a05b 1938 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 1939 ssl->out_msg[0] = SSL_HS_SERVER_HELLO;
HannesTschofenig 0:796d0f61a05b 1940
HannesTschofenig 0:796d0f61a05b 1941 ret = ssl_write_record( ssl );
HannesTschofenig 0:796d0f61a05b 1942
HannesTschofenig 0:796d0f61a05b 1943 SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
HannesTschofenig 0:796d0f61a05b 1944
HannesTschofenig 0:796d0f61a05b 1945 return( ret );
HannesTschofenig 0:796d0f61a05b 1946 }
HannesTschofenig 0:796d0f61a05b 1947
HannesTschofenig 0:796d0f61a05b 1948 #if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 1949 !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 1950 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 1951 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 1952 static int ssl_write_certificate_request( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1953 {
HannesTschofenig 0:796d0f61a05b 1954 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 1955 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 1956
HannesTschofenig 0:796d0f61a05b 1957 SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
HannesTschofenig 0:796d0f61a05b 1958
HannesTschofenig 0:796d0f61a05b 1959 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 1960 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
HannesTschofenig 0:796d0f61a05b 1961 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 1962 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 1963 {
HannesTschofenig 0:796d0f61a05b 1964 SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
HannesTschofenig 0:796d0f61a05b 1965 ssl->state++;
HannesTschofenig 0:796d0f61a05b 1966 return( 0 );
HannesTschofenig 0:796d0f61a05b 1967 }
HannesTschofenig 0:796d0f61a05b 1968
HannesTschofenig 0:796d0f61a05b 1969 SSL_DEBUG_MSG( 1, ( "should not happen" ) );
HannesTschofenig 0:796d0f61a05b 1970 return( ret );
HannesTschofenig 0:796d0f61a05b 1971 }
HannesTschofenig 0:796d0f61a05b 1972 #else
HannesTschofenig 0:796d0f61a05b 1973 static int ssl_write_certificate_request( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 1974 {
HannesTschofenig 0:796d0f61a05b 1975 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 1976 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 1977 size_t dn_size, total_dn_size; /* excluding length bytes */
HannesTschofenig 0:796d0f61a05b 1978 size_t ct_len, sa_len; /* including length bytes */
HannesTschofenig 0:796d0f61a05b 1979 unsigned char *buf, *p;
HannesTschofenig 0:796d0f61a05b 1980 const x509_crt *crt;
HannesTschofenig 0:796d0f61a05b 1981
HannesTschofenig 0:796d0f61a05b 1982 SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
HannesTschofenig 0:796d0f61a05b 1983
HannesTschofenig 0:796d0f61a05b 1984 ssl->state++;
HannesTschofenig 0:796d0f61a05b 1985
HannesTschofenig 0:796d0f61a05b 1986 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 1987 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
HannesTschofenig 0:796d0f61a05b 1988 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 1989 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
HannesTschofenig 0:796d0f61a05b 1990 ssl->authmode == SSL_VERIFY_NONE )
HannesTschofenig 0:796d0f61a05b 1991 {
HannesTschofenig 0:796d0f61a05b 1992 SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
HannesTschofenig 0:796d0f61a05b 1993 return( 0 );
HannesTschofenig 0:796d0f61a05b 1994 }
HannesTschofenig 0:796d0f61a05b 1995
HannesTschofenig 0:796d0f61a05b 1996 /*
HannesTschofenig 0:796d0f61a05b 1997 * 0 . 0 handshake type
HannesTschofenig 0:796d0f61a05b 1998 * 1 . 3 handshake length
HannesTschofenig 0:796d0f61a05b 1999 * 4 . 4 cert type count
HannesTschofenig 0:796d0f61a05b 2000 * 5 .. m-1 cert types
HannesTschofenig 0:796d0f61a05b 2001 * m .. m+1 sig alg length (TLS 1.2 only)
HannesTschofenig 0:796d0f61a05b 2002 * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only)
HannesTschofenig 0:796d0f61a05b 2003 * n .. n+1 length of all DNs
HannesTschofenig 0:796d0f61a05b 2004 * n+2 .. n+3 length of DN 1
HannesTschofenig 0:796d0f61a05b 2005 * n+4 .. ... Distinguished Name #1
HannesTschofenig 0:796d0f61a05b 2006 * ... .. ... length of DN 2, etc.
HannesTschofenig 0:796d0f61a05b 2007 */
HannesTschofenig 0:796d0f61a05b 2008 buf = ssl->out_msg;
HannesTschofenig 0:796d0f61a05b 2009 p = buf + 4;
HannesTschofenig 0:796d0f61a05b 2010
HannesTschofenig 0:796d0f61a05b 2011 /*
HannesTschofenig 0:796d0f61a05b 2012 * Supported certificate types
HannesTschofenig 0:796d0f61a05b 2013 *
HannesTschofenig 0:796d0f61a05b 2014 * ClientCertificateType certificate_types<1..2^8-1>;
HannesTschofenig 0:796d0f61a05b 2015 * enum { (255) } ClientCertificateType;
HannesTschofenig 0:796d0f61a05b 2016 */
HannesTschofenig 0:796d0f61a05b 2017 ct_len = 0;
HannesTschofenig 0:796d0f61a05b 2018
HannesTschofenig 0:796d0f61a05b 2019 #if defined(POLARSSL_RSA_C)
HannesTschofenig 0:796d0f61a05b 2020 p[1 + ct_len++] = SSL_CERT_TYPE_RSA_SIGN;
HannesTschofenig 0:796d0f61a05b 2021 #endif
HannesTschofenig 0:796d0f61a05b 2022 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 2023 p[1 + ct_len++] = SSL_CERT_TYPE_ECDSA_SIGN;
HannesTschofenig 0:796d0f61a05b 2024 #endif
HannesTschofenig 0:796d0f61a05b 2025
HannesTschofenig 0:796d0f61a05b 2026 p[0] = (unsigned char) ct_len++;
HannesTschofenig 0:796d0f61a05b 2027 p += ct_len;
HannesTschofenig 0:796d0f61a05b 2028
HannesTschofenig 0:796d0f61a05b 2029 sa_len = 0;
HannesTschofenig 0:796d0f61a05b 2030 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2031 /*
HannesTschofenig 0:796d0f61a05b 2032 * Add signature_algorithms for verify (TLS 1.2)
HannesTschofenig 0:796d0f61a05b 2033 *
HannesTschofenig 0:796d0f61a05b 2034 * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
HannesTschofenig 0:796d0f61a05b 2035 *
HannesTschofenig 0:796d0f61a05b 2036 * struct {
HannesTschofenig 0:796d0f61a05b 2037 * HashAlgorithm hash;
HannesTschofenig 0:796d0f61a05b 2038 * SignatureAlgorithm signature;
HannesTschofenig 0:796d0f61a05b 2039 * } SignatureAndHashAlgorithm;
HannesTschofenig 0:796d0f61a05b 2040 *
HannesTschofenig 0:796d0f61a05b 2041 * enum { (255) } HashAlgorithm;
HannesTschofenig 0:796d0f61a05b 2042 * enum { (255) } SignatureAlgorithm;
HannesTschofenig 0:796d0f61a05b 2043 */
HannesTschofenig 0:796d0f61a05b 2044 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 2045 {
HannesTschofenig 0:796d0f61a05b 2046 /*
HannesTschofenig 0:796d0f61a05b 2047 * Only use current running hash algorithm that is already required
HannesTschofenig 0:796d0f61a05b 2048 * for requested ciphersuite.
HannesTschofenig 0:796d0f61a05b 2049 */
HannesTschofenig 0:796d0f61a05b 2050 ssl->handshake->verify_sig_alg = SSL_HASH_SHA256;
HannesTschofenig 0:796d0f61a05b 2051
HannesTschofenig 0:796d0f61a05b 2052 if( ssl->transform_negotiate->ciphersuite_info->mac ==
HannesTschofenig 0:796d0f61a05b 2053 POLARSSL_MD_SHA384 )
HannesTschofenig 0:796d0f61a05b 2054 {
HannesTschofenig 0:796d0f61a05b 2055 ssl->handshake->verify_sig_alg = SSL_HASH_SHA384;
HannesTschofenig 0:796d0f61a05b 2056 }
HannesTschofenig 0:796d0f61a05b 2057
HannesTschofenig 0:796d0f61a05b 2058 /*
HannesTschofenig 0:796d0f61a05b 2059 * Supported signature algorithms
HannesTschofenig 0:796d0f61a05b 2060 */
HannesTschofenig 0:796d0f61a05b 2061 #if defined(POLARSSL_RSA_C)
HannesTschofenig 0:796d0f61a05b 2062 p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
HannesTschofenig 0:796d0f61a05b 2063 p[2 + sa_len++] = SSL_SIG_RSA;
HannesTschofenig 0:796d0f61a05b 2064 #endif
HannesTschofenig 0:796d0f61a05b 2065 #if defined(POLARSSL_ECDSA_C)
HannesTschofenig 0:796d0f61a05b 2066 p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
HannesTschofenig 0:796d0f61a05b 2067 p[2 + sa_len++] = SSL_SIG_ECDSA;
HannesTschofenig 0:796d0f61a05b 2068 #endif
HannesTschofenig 0:796d0f61a05b 2069
HannesTschofenig 0:796d0f61a05b 2070 p[0] = (unsigned char)( sa_len >> 8 );
HannesTschofenig 0:796d0f61a05b 2071 p[1] = (unsigned char)( sa_len );
HannesTschofenig 0:796d0f61a05b 2072 sa_len += 2;
HannesTschofenig 0:796d0f61a05b 2073 p += sa_len;
HannesTschofenig 0:796d0f61a05b 2074 }
HannesTschofenig 0:796d0f61a05b 2075 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2076
HannesTschofenig 0:796d0f61a05b 2077 /*
HannesTschofenig 0:796d0f61a05b 2078 * DistinguishedName certificate_authorities<0..2^16-1>;
HannesTschofenig 0:796d0f61a05b 2079 * opaque DistinguishedName<1..2^16-1>;
HannesTschofenig 0:796d0f61a05b 2080 */
HannesTschofenig 0:796d0f61a05b 2081 p += 2;
HannesTschofenig 0:796d0f61a05b 2082 crt = ssl->ca_chain;
HannesTschofenig 0:796d0f61a05b 2083
HannesTschofenig 0:796d0f61a05b 2084 total_dn_size = 0;
HannesTschofenig 0:796d0f61a05b 2085 while( crt != NULL && crt->version != 0 )
HannesTschofenig 0:796d0f61a05b 2086 {
HannesTschofenig 0:796d0f61a05b 2087 if( p - buf > 4096 )
HannesTschofenig 0:796d0f61a05b 2088 break;
HannesTschofenig 0:796d0f61a05b 2089
HannesTschofenig 0:796d0f61a05b 2090 dn_size = crt->subject_raw.len;
HannesTschofenig 0:796d0f61a05b 2091 *p++ = (unsigned char)( dn_size >> 8 );
HannesTschofenig 0:796d0f61a05b 2092 *p++ = (unsigned char)( dn_size );
HannesTschofenig 0:796d0f61a05b 2093 memcpy( p, crt->subject_raw.p, dn_size );
HannesTschofenig 0:796d0f61a05b 2094 p += dn_size;
HannesTschofenig 0:796d0f61a05b 2095
HannesTschofenig 0:796d0f61a05b 2096 SSL_DEBUG_BUF( 3, "requested DN", p, dn_size );
HannesTschofenig 0:796d0f61a05b 2097
HannesTschofenig 0:796d0f61a05b 2098 total_dn_size += 2 + dn_size;
HannesTschofenig 0:796d0f61a05b 2099 crt = crt->next;
HannesTschofenig 0:796d0f61a05b 2100 }
HannesTschofenig 0:796d0f61a05b 2101
HannesTschofenig 0:796d0f61a05b 2102 ssl->out_msglen = p - buf;
HannesTschofenig 0:796d0f61a05b 2103 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 2104 ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
HannesTschofenig 0:796d0f61a05b 2105 ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
HannesTschofenig 0:796d0f61a05b 2106 ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
HannesTschofenig 0:796d0f61a05b 2107
HannesTschofenig 0:796d0f61a05b 2108 ret = ssl_write_record( ssl );
HannesTschofenig 0:796d0f61a05b 2109
HannesTschofenig 0:796d0f61a05b 2110 SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
HannesTschofenig 0:796d0f61a05b 2111
HannesTschofenig 0:796d0f61a05b 2112 return( ret );
HannesTschofenig 0:796d0f61a05b 2113 }
HannesTschofenig 0:796d0f61a05b 2114 #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED &&
HannesTschofenig 0:796d0f61a05b 2115 !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
HannesTschofenig 0:796d0f61a05b 2116 !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
HannesTschofenig 0:796d0f61a05b 2117 !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2118
HannesTschofenig 0:796d0f61a05b 2119 #if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2120 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2121 static int ssl_get_ecdh_params_from_cert( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2122 {
HannesTschofenig 0:796d0f61a05b 2123 int ret;
HannesTschofenig 0:796d0f61a05b 2124
HannesTschofenig 0:796d0f61a05b 2125 if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECKEY ) )
HannesTschofenig 0:796d0f61a05b 2126 {
HannesTschofenig 0:796d0f61a05b 2127 SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
HannesTschofenig 0:796d0f61a05b 2128 return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
HannesTschofenig 0:796d0f61a05b 2129 }
HannesTschofenig 0:796d0f61a05b 2130
HannesTschofenig 0:796d0f61a05b 2131 if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx,
HannesTschofenig 0:796d0f61a05b 2132 pk_ec( *ssl_own_key( ssl ) ),
HannesTschofenig 0:796d0f61a05b 2133 POLARSSL_ECDH_OURS ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2134 {
HannesTschofenig 0:796d0f61a05b 2135 SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret );
HannesTschofenig 0:796d0f61a05b 2136 return( ret );
HannesTschofenig 0:796d0f61a05b 2137 }
HannesTschofenig 0:796d0f61a05b 2138
HannesTschofenig 0:796d0f61a05b 2139 return( 0 );
HannesTschofenig 0:796d0f61a05b 2140 }
HannesTschofenig 0:796d0f61a05b 2141 #endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
HannesTschofenig 0:796d0f61a05b 2142 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2143
HannesTschofenig 0:796d0f61a05b 2144 static int ssl_write_server_key_exchange( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2145 {
HannesTschofenig 0:796d0f61a05b 2146 int ret;
HannesTschofenig 0:796d0f61a05b 2147 size_t n = 0;
HannesTschofenig 0:796d0f61a05b 2148 const ssl_ciphersuite_t *ciphersuite_info =
HannesTschofenig 0:796d0f61a05b 2149 ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2150
HannesTschofenig 0:796d0f61a05b 2151 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2152 defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2153 defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2154 defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2155 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2156 unsigned char *p = ssl->out_msg + 4;
HannesTschofenig 0:796d0f61a05b 2157 unsigned char *dig_signed = p;
HannesTschofenig 0:796d0f61a05b 2158 size_t dig_signed_len = 0, len;
HannesTschofenig 0:796d0f61a05b 2159 ((void) dig_signed);
HannesTschofenig 0:796d0f61a05b 2160 ((void) dig_signed_len);
HannesTschofenig 0:796d0f61a05b 2161 #endif
HannesTschofenig 0:796d0f61a05b 2162
HannesTschofenig 0:796d0f61a05b 2163 SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2164
HannesTschofenig 0:796d0f61a05b 2165 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2166 defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2167 defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2168 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ||
HannesTschofenig 0:796d0f61a05b 2169 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2170 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
HannesTschofenig 0:796d0f61a05b 2171 {
HannesTschofenig 0:796d0f61a05b 2172 SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2173 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2174 return( 0 );
HannesTschofenig 0:796d0f61a05b 2175 }
HannesTschofenig 0:796d0f61a05b 2176 #endif
HannesTschofenig 0:796d0f61a05b 2177
HannesTschofenig 0:796d0f61a05b 2178 #if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2179 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2180 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
HannesTschofenig 0:796d0f61a05b 2181 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
HannesTschofenig 0:796d0f61a05b 2182 {
HannesTschofenig 0:796d0f61a05b 2183 ssl_get_ecdh_params_from_cert( ssl );
HannesTschofenig 0:796d0f61a05b 2184
HannesTschofenig 0:796d0f61a05b 2185 SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2186 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2187 return( 0 );
HannesTschofenig 0:796d0f61a05b 2188 }
HannesTschofenig 0:796d0f61a05b 2189 #endif
HannesTschofenig 0:796d0f61a05b 2190
HannesTschofenig 0:796d0f61a05b 2191 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2192 defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2193 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2194 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2195 {
HannesTschofenig 0:796d0f61a05b 2196 /* TODO: Support identity hints */
HannesTschofenig 0:796d0f61a05b 2197 *(p++) = 0x00;
HannesTschofenig 0:796d0f61a05b 2198 *(p++) = 0x00;
HannesTschofenig 0:796d0f61a05b 2199
HannesTschofenig 0:796d0f61a05b 2200 n += 2;
HannesTschofenig 0:796d0f61a05b 2201 }
HannesTschofenig 0:796d0f61a05b 2202 #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2203 POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2204
HannesTschofenig 0:796d0f61a05b 2205 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2206 defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2207 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
HannesTschofenig 0:796d0f61a05b 2208 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
HannesTschofenig 0:796d0f61a05b 2209 {
HannesTschofenig 0:796d0f61a05b 2210 /*
HannesTschofenig 0:796d0f61a05b 2211 * Ephemeral DH parameters:
HannesTschofenig 0:796d0f61a05b 2212 *
HannesTschofenig 0:796d0f61a05b 2213 * struct {
HannesTschofenig 0:796d0f61a05b 2214 * opaque dh_p<1..2^16-1>;
HannesTschofenig 0:796d0f61a05b 2215 * opaque dh_g<1..2^16-1>;
HannesTschofenig 0:796d0f61a05b 2216 * opaque dh_Ys<1..2^16-1>;
HannesTschofenig 0:796d0f61a05b 2217 * } ServerDHParams;
HannesTschofenig 0:796d0f61a05b 2218 */
HannesTschofenig 0:796d0f61a05b 2219 if( ( ret = mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->dhm_P ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 2220 ( ret = mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->dhm_G ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2221 {
HannesTschofenig 0:796d0f61a05b 2222 SSL_DEBUG_RET( 1, "mpi_copy", ret );
HannesTschofenig 0:796d0f61a05b 2223 return( ret );
HannesTschofenig 0:796d0f61a05b 2224 }
HannesTschofenig 0:796d0f61a05b 2225
HannesTschofenig 0:796d0f61a05b 2226 if( ( ret = dhm_make_params( &ssl->handshake->dhm_ctx,
HannesTschofenig 0:796d0f61a05b 2227 (int) mpi_size( &ssl->handshake->dhm_ctx.P ),
HannesTschofenig 0:796d0f61a05b 2228 p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2229 {
HannesTschofenig 0:796d0f61a05b 2230 SSL_DEBUG_RET( 1, "dhm_make_params", ret );
HannesTschofenig 0:796d0f61a05b 2231 return( ret );
HannesTschofenig 0:796d0f61a05b 2232 }
HannesTschofenig 0:796d0f61a05b 2233
HannesTschofenig 0:796d0f61a05b 2234 dig_signed = p;
HannesTschofenig 0:796d0f61a05b 2235 dig_signed_len = len;
HannesTschofenig 0:796d0f61a05b 2236
HannesTschofenig 0:796d0f61a05b 2237 p += len;
HannesTschofenig 0:796d0f61a05b 2238 n += len;
HannesTschofenig 0:796d0f61a05b 2239
HannesTschofenig 0:796d0f61a05b 2240 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
HannesTschofenig 0:796d0f61a05b 2241 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
HannesTschofenig 0:796d0f61a05b 2242 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
HannesTschofenig 0:796d0f61a05b 2243 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
HannesTschofenig 0:796d0f61a05b 2244 }
HannesTschofenig 0:796d0f61a05b 2245 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2246 POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2247
HannesTschofenig 0:796d0f61a05b 2248 #if defined(POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
HannesTschofenig 0:796d0f61a05b 2249 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
HannesTschofenig 0:796d0f61a05b 2250 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ||
HannesTschofenig 0:796d0f61a05b 2251 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2252 {
HannesTschofenig 0:796d0f61a05b 2253 /*
HannesTschofenig 0:796d0f61a05b 2254 * Ephemeral ECDH parameters:
HannesTschofenig 0:796d0f61a05b 2255 *
HannesTschofenig 0:796d0f61a05b 2256 * struct {
HannesTschofenig 0:796d0f61a05b 2257 * ECParameters curve_params;
HannesTschofenig 0:796d0f61a05b 2258 * ECPoint public;
HannesTschofenig 0:796d0f61a05b 2259 * } ServerECDHParams;
HannesTschofenig 0:796d0f61a05b 2260 */
HannesTschofenig 0:796d0f61a05b 2261 const ecp_curve_info **curve = NULL;
HannesTschofenig 0:796d0f61a05b 2262 #if defined(POLARSSL_SSL_SET_CURVES)
HannesTschofenig 0:796d0f61a05b 2263 const ecp_group_id *gid;
HannesTschofenig 0:796d0f61a05b 2264
HannesTschofenig 0:796d0f61a05b 2265 /* Match our preference list against the offered curves */
HannesTschofenig 0:796d0f61a05b 2266 for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ )
HannesTschofenig 0:796d0f61a05b 2267 for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
HannesTschofenig 0:796d0f61a05b 2268 if( (*curve)->grp_id == *gid )
HannesTschofenig 0:796d0f61a05b 2269 goto curve_matching_done;
HannesTschofenig 0:796d0f61a05b 2270
HannesTschofenig 0:796d0f61a05b 2271 curve_matching_done:
HannesTschofenig 0:796d0f61a05b 2272 #else
HannesTschofenig 0:796d0f61a05b 2273 curve = ssl->handshake->curves;
HannesTschofenig 0:796d0f61a05b 2274 #endif
HannesTschofenig 0:796d0f61a05b 2275
HannesTschofenig 0:796d0f61a05b 2276 if( *curve == NULL )
HannesTschofenig 0:796d0f61a05b 2277 {
HannesTschofenig 0:796d0f61a05b 2278 SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
HannesTschofenig 0:796d0f61a05b 2279 return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
HannesTschofenig 0:796d0f61a05b 2280 }
HannesTschofenig 0:796d0f61a05b 2281
HannesTschofenig 0:796d0f61a05b 2282 SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
HannesTschofenig 0:796d0f61a05b 2283
HannesTschofenig 0:796d0f61a05b 2284 if( ( ret = ecp_use_known_dp( &ssl->handshake->ecdh_ctx.grp,
HannesTschofenig 0:796d0f61a05b 2285 (*curve)->grp_id ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2286 {
HannesTschofenig 0:796d0f61a05b 2287 SSL_DEBUG_RET( 1, "ecp_use_known_dp", ret );
HannesTschofenig 0:796d0f61a05b 2288 return( ret );
HannesTschofenig 0:796d0f61a05b 2289 }
HannesTschofenig 0:796d0f61a05b 2290
HannesTschofenig 0:796d0f61a05b 2291 if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
HannesTschofenig 0:796d0f61a05b 2292 p, SSL_MAX_CONTENT_LEN - n,
HannesTschofenig 0:796d0f61a05b 2293 ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2294 {
HannesTschofenig 0:796d0f61a05b 2295 SSL_DEBUG_RET( 1, "ecdh_make_params", ret );
HannesTschofenig 0:796d0f61a05b 2296 return( ret );
HannesTschofenig 0:796d0f61a05b 2297 }
HannesTschofenig 0:796d0f61a05b 2298
HannesTschofenig 0:796d0f61a05b 2299 dig_signed = p;
HannesTschofenig 0:796d0f61a05b 2300 dig_signed_len = len;
HannesTschofenig 0:796d0f61a05b 2301
HannesTschofenig 0:796d0f61a05b 2302 p += len;
HannesTschofenig 0:796d0f61a05b 2303 n += len;
HannesTschofenig 0:796d0f61a05b 2304
HannesTschofenig 0:796d0f61a05b 2305 SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
HannesTschofenig 0:796d0f61a05b 2306 }
HannesTschofenig 0:796d0f61a05b 2307 #endif /* POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
HannesTschofenig 0:796d0f61a05b 2308
HannesTschofenig 0:796d0f61a05b 2309 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2310 defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2311 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2312 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
HannesTschofenig 0:796d0f61a05b 2313 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
HannesTschofenig 0:796d0f61a05b 2314 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
HannesTschofenig 0:796d0f61a05b 2315 {
HannesTschofenig 0:796d0f61a05b 2316 size_t signature_len = 0;
HannesTschofenig 0:796d0f61a05b 2317 unsigned int hashlen = 0;
HannesTschofenig 0:796d0f61a05b 2318 unsigned char hash[64];
HannesTschofenig 0:796d0f61a05b 2319 md_type_t md_alg = POLARSSL_MD_NONE;
HannesTschofenig 0:796d0f61a05b 2320
HannesTschofenig 0:796d0f61a05b 2321 /*
HannesTschofenig 0:796d0f61a05b 2322 * Choose hash algorithm. NONE means MD5 + SHA1 here.
HannesTschofenig 0:796d0f61a05b 2323 */
HannesTschofenig 0:796d0f61a05b 2324 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2325 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 2326 {
HannesTschofenig 0:796d0f61a05b 2327 md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg );
HannesTschofenig 0:796d0f61a05b 2328
HannesTschofenig 0:796d0f61a05b 2329 if( md_alg == POLARSSL_MD_NONE )
HannesTschofenig 0:796d0f61a05b 2330 {
HannesTschofenig 0:796d0f61a05b 2331 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 2332 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 2333 }
HannesTschofenig 0:796d0f61a05b 2334 }
HannesTschofenig 0:796d0f61a05b 2335 else
HannesTschofenig 0:796d0f61a05b 2336 #endif
HannesTschofenig 0:796d0f61a05b 2337 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 2338 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 2339 if ( ciphersuite_info->key_exchange ==
HannesTschofenig 0:796d0f61a05b 2340 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
HannesTschofenig 0:796d0f61a05b 2341 {
HannesTschofenig 0:796d0f61a05b 2342 md_alg = POLARSSL_MD_SHA1;
HannesTschofenig 0:796d0f61a05b 2343 }
HannesTschofenig 0:796d0f61a05b 2344 else
HannesTschofenig 0:796d0f61a05b 2345 #endif
HannesTschofenig 0:796d0f61a05b 2346 {
HannesTschofenig 0:796d0f61a05b 2347 md_alg = POLARSSL_MD_NONE;
HannesTschofenig 0:796d0f61a05b 2348 }
HannesTschofenig 0:796d0f61a05b 2349
HannesTschofenig 0:796d0f61a05b 2350 /*
HannesTschofenig 0:796d0f61a05b 2351 * Compute the hash to be signed
HannesTschofenig 0:796d0f61a05b 2352 */
HannesTschofenig 0:796d0f61a05b 2353 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 2354 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 2355 if( md_alg == POLARSSL_MD_NONE )
HannesTschofenig 0:796d0f61a05b 2356 {
HannesTschofenig 0:796d0f61a05b 2357 md5_context md5;
HannesTschofenig 0:796d0f61a05b 2358 sha1_context sha1;
HannesTschofenig 0:796d0f61a05b 2359
HannesTschofenig 0:796d0f61a05b 2360 /*
HannesTschofenig 0:796d0f61a05b 2361 * digitally-signed struct {
HannesTschofenig 0:796d0f61a05b 2362 * opaque md5_hash[16];
HannesTschofenig 0:796d0f61a05b 2363 * opaque sha_hash[20];
HannesTschofenig 0:796d0f61a05b 2364 * };
HannesTschofenig 0:796d0f61a05b 2365 *
HannesTschofenig 0:796d0f61a05b 2366 * md5_hash
HannesTschofenig 0:796d0f61a05b 2367 * MD5(ClientHello.random + ServerHello.random
HannesTschofenig 0:796d0f61a05b 2368 * + ServerParams);
HannesTschofenig 0:796d0f61a05b 2369 * sha_hash
HannesTschofenig 0:796d0f61a05b 2370 * SHA(ClientHello.random + ServerHello.random
HannesTschofenig 0:796d0f61a05b 2371 * + ServerParams);
HannesTschofenig 0:796d0f61a05b 2372 */
HannesTschofenig 0:796d0f61a05b 2373 md5_starts( &md5 );
HannesTschofenig 0:796d0f61a05b 2374 md5_update( &md5, ssl->handshake->randbytes, 64 );
HannesTschofenig 0:796d0f61a05b 2375 md5_update( &md5, dig_signed, dig_signed_len );
HannesTschofenig 0:796d0f61a05b 2376 md5_finish( &md5, hash );
HannesTschofenig 0:796d0f61a05b 2377
HannesTschofenig 0:796d0f61a05b 2378 sha1_starts( &sha1 );
HannesTschofenig 0:796d0f61a05b 2379 sha1_update( &sha1, ssl->handshake->randbytes, 64 );
HannesTschofenig 0:796d0f61a05b 2380 sha1_update( &sha1, dig_signed, dig_signed_len );
HannesTschofenig 0:796d0f61a05b 2381 sha1_finish( &sha1, hash + 16 );
HannesTschofenig 0:796d0f61a05b 2382
HannesTschofenig 0:796d0f61a05b 2383 hashlen = 36;
HannesTschofenig 0:796d0f61a05b 2384 }
HannesTschofenig 0:796d0f61a05b 2385 else
HannesTschofenig 0:796d0f61a05b 2386 #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
HannesTschofenig 0:796d0f61a05b 2387 POLARSSL_SSL_PROTO_TLS1_1 */
HannesTschofenig 0:796d0f61a05b 2388 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 2389 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2390 if( md_alg != POLARSSL_MD_NONE )
HannesTschofenig 0:796d0f61a05b 2391 {
HannesTschofenig 0:796d0f61a05b 2392 md_context_t ctx;
HannesTschofenig 0:796d0f61a05b 2393
HannesTschofenig 0:796d0f61a05b 2394 /* Info from md_alg will be used instead */
HannesTschofenig 0:796d0f61a05b 2395 hashlen = 0;
HannesTschofenig 0:796d0f61a05b 2396
HannesTschofenig 0:796d0f61a05b 2397 /*
HannesTschofenig 0:796d0f61a05b 2398 * digitally-signed struct {
HannesTschofenig 0:796d0f61a05b 2399 * opaque client_random[32];
HannesTschofenig 0:796d0f61a05b 2400 * opaque server_random[32];
HannesTschofenig 0:796d0f61a05b 2401 * ServerDHParams params;
HannesTschofenig 0:796d0f61a05b 2402 * };
HannesTschofenig 0:796d0f61a05b 2403 */
HannesTschofenig 0:796d0f61a05b 2404 if( ( ret = md_init_ctx( &ctx, md_info_from_type(md_alg) ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2405 {
HannesTschofenig 0:796d0f61a05b 2406 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
HannesTschofenig 0:796d0f61a05b 2407 return( ret );
HannesTschofenig 0:796d0f61a05b 2408 }
HannesTschofenig 0:796d0f61a05b 2409
HannesTschofenig 0:796d0f61a05b 2410 md_starts( &ctx );
HannesTschofenig 0:796d0f61a05b 2411 md_update( &ctx, ssl->handshake->randbytes, 64 );
HannesTschofenig 0:796d0f61a05b 2412 md_update( &ctx, dig_signed, dig_signed_len );
HannesTschofenig 0:796d0f61a05b 2413 md_finish( &ctx, hash );
HannesTschofenig 0:796d0f61a05b 2414
HannesTschofenig 0:796d0f61a05b 2415 if( ( ret = md_free_ctx( &ctx ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2416 {
HannesTschofenig 0:796d0f61a05b 2417 SSL_DEBUG_RET( 1, "md_free_ctx", ret );
HannesTschofenig 0:796d0f61a05b 2418 return( ret );
HannesTschofenig 0:796d0f61a05b 2419 }
HannesTschofenig 0:796d0f61a05b 2420
HannesTschofenig 0:796d0f61a05b 2421 }
HannesTschofenig 0:796d0f61a05b 2422 else
HannesTschofenig 0:796d0f61a05b 2423 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
HannesTschofenig 0:796d0f61a05b 2424 POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2425 {
HannesTschofenig 0:796d0f61a05b 2426 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 2427 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 2428 }
HannesTschofenig 0:796d0f61a05b 2429
HannesTschofenig 0:796d0f61a05b 2430 SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
HannesTschofenig 0:796d0f61a05b 2431 (unsigned int) ( md_info_from_type( md_alg ) )->size );
HannesTschofenig 0:796d0f61a05b 2432
HannesTschofenig 0:796d0f61a05b 2433 /*
HannesTschofenig 0:796d0f61a05b 2434 * Make the signature
HannesTschofenig 0:796d0f61a05b 2435 */
HannesTschofenig 0:796d0f61a05b 2436 if( ssl_own_key( ssl ) == NULL )
HannesTschofenig 0:796d0f61a05b 2437 {
HannesTschofenig 0:796d0f61a05b 2438 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
HannesTschofenig 0:796d0f61a05b 2439 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
HannesTschofenig 0:796d0f61a05b 2440 }
HannesTschofenig 0:796d0f61a05b 2441
HannesTschofenig 0:796d0f61a05b 2442 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2443 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 2444 {
HannesTschofenig 0:796d0f61a05b 2445 *(p++) = ssl->handshake->sig_alg;
HannesTschofenig 0:796d0f61a05b 2446 *(p++) = ssl_sig_from_pk( ssl_own_key( ssl ) );
HannesTschofenig 0:796d0f61a05b 2447
HannesTschofenig 0:796d0f61a05b 2448 n += 2;
HannesTschofenig 0:796d0f61a05b 2449 }
HannesTschofenig 0:796d0f61a05b 2450 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 2451
HannesTschofenig 0:796d0f61a05b 2452 if( ( ret = pk_sign( ssl_own_key( ssl ), md_alg, hash, hashlen,
HannesTschofenig 0:796d0f61a05b 2453 p + 2 , &signature_len,
HannesTschofenig 0:796d0f61a05b 2454 ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2455 {
HannesTschofenig 0:796d0f61a05b 2456 SSL_DEBUG_RET( 1, "pk_sign", ret );
HannesTschofenig 0:796d0f61a05b 2457 return( ret );
HannesTschofenig 0:796d0f61a05b 2458 }
HannesTschofenig 0:796d0f61a05b 2459
HannesTschofenig 0:796d0f61a05b 2460 *(p++) = (unsigned char)( signature_len >> 8 );
HannesTschofenig 0:796d0f61a05b 2461 *(p++) = (unsigned char)( signature_len );
HannesTschofenig 0:796d0f61a05b 2462 n += 2;
HannesTschofenig 0:796d0f61a05b 2463
HannesTschofenig 0:796d0f61a05b 2464 SSL_DEBUG_BUF( 3, "my signature", p, signature_len );
HannesTschofenig 0:796d0f61a05b 2465
HannesTschofenig 0:796d0f61a05b 2466 p += signature_len;
HannesTschofenig 0:796d0f61a05b 2467 n += signature_len;
HannesTschofenig 0:796d0f61a05b 2468 }
HannesTschofenig 0:796d0f61a05b 2469 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||
HannesTschofenig 0:796d0f61a05b 2470 POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2471 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2472
HannesTschofenig 0:796d0f61a05b 2473 ssl->out_msglen = 4 + n;
HannesTschofenig 0:796d0f61a05b 2474 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 2475 ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE;
HannesTschofenig 0:796d0f61a05b 2476
HannesTschofenig 0:796d0f61a05b 2477 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2478
HannesTschofenig 0:796d0f61a05b 2479 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2480 {
HannesTschofenig 0:796d0f61a05b 2481 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 2482 return( ret );
HannesTschofenig 0:796d0f61a05b 2483 }
HannesTschofenig 0:796d0f61a05b 2484
HannesTschofenig 0:796d0f61a05b 2485 SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2486
HannesTschofenig 0:796d0f61a05b 2487 return( 0 );
HannesTschofenig 0:796d0f61a05b 2488 }
HannesTschofenig 0:796d0f61a05b 2489
HannesTschofenig 0:796d0f61a05b 2490 static int ssl_write_server_hello_done( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2491 {
HannesTschofenig 0:796d0f61a05b 2492 int ret;
HannesTschofenig 0:796d0f61a05b 2493
HannesTschofenig 0:796d0f61a05b 2494 SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
HannesTschofenig 0:796d0f61a05b 2495
HannesTschofenig 0:796d0f61a05b 2496 ssl->out_msglen = 4;
HannesTschofenig 0:796d0f61a05b 2497 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 2498 ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE;
HannesTschofenig 0:796d0f61a05b 2499
HannesTschofenig 0:796d0f61a05b 2500 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2501
HannesTschofenig 0:796d0f61a05b 2502 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2503 {
HannesTschofenig 0:796d0f61a05b 2504 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 2505 return( ret );
HannesTschofenig 0:796d0f61a05b 2506 }
HannesTschofenig 0:796d0f61a05b 2507
HannesTschofenig 0:796d0f61a05b 2508 SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
HannesTschofenig 0:796d0f61a05b 2509
HannesTschofenig 0:796d0f61a05b 2510 return( 0 );
HannesTschofenig 0:796d0f61a05b 2511 }
HannesTschofenig 0:796d0f61a05b 2512
HannesTschofenig 0:796d0f61a05b 2513 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2514 defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2515 static int ssl_parse_client_dh_public( ssl_context *ssl, unsigned char **p,
HannesTschofenig 0:796d0f61a05b 2516 const unsigned char *end )
HannesTschofenig 0:796d0f61a05b 2517 {
HannesTschofenig 0:796d0f61a05b 2518 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2519 size_t n;
HannesTschofenig 0:796d0f61a05b 2520
HannesTschofenig 0:796d0f61a05b 2521 /*
HannesTschofenig 0:796d0f61a05b 2522 * Receive G^Y mod P, premaster = (G^Y)^X mod P
HannesTschofenig 0:796d0f61a05b 2523 */
HannesTschofenig 0:796d0f61a05b 2524 if( *p + 2 > end )
HannesTschofenig 0:796d0f61a05b 2525 {
HannesTschofenig 0:796d0f61a05b 2526 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2527 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2528 }
HannesTschofenig 0:796d0f61a05b 2529
HannesTschofenig 0:796d0f61a05b 2530 n = ( (*p)[0] << 8 ) | (*p)[1];
HannesTschofenig 0:796d0f61a05b 2531 *p += 2;
HannesTschofenig 0:796d0f61a05b 2532
HannesTschofenig 0:796d0f61a05b 2533 if( *p + n > end )
HannesTschofenig 0:796d0f61a05b 2534 {
HannesTschofenig 0:796d0f61a05b 2535 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2536 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2537 }
HannesTschofenig 0:796d0f61a05b 2538
HannesTschofenig 0:796d0f61a05b 2539 if( ( ret = dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2540 {
HannesTschofenig 0:796d0f61a05b 2541 SSL_DEBUG_RET( 1, "dhm_read_public", ret );
HannesTschofenig 0:796d0f61a05b 2542 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
HannesTschofenig 0:796d0f61a05b 2543 }
HannesTschofenig 0:796d0f61a05b 2544
HannesTschofenig 0:796d0f61a05b 2545 *p += n;
HannesTschofenig 0:796d0f61a05b 2546
HannesTschofenig 0:796d0f61a05b 2547 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
HannesTschofenig 0:796d0f61a05b 2548
HannesTschofenig 0:796d0f61a05b 2549 return( ret );
HannesTschofenig 0:796d0f61a05b 2550 }
HannesTschofenig 0:796d0f61a05b 2551 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2552 POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2553
HannesTschofenig 0:796d0f61a05b 2554 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2555 defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2556 static int ssl_parse_encrypted_pms( ssl_context *ssl,
HannesTschofenig 0:796d0f61a05b 2557 const unsigned char *p,
HannesTschofenig 0:796d0f61a05b 2558 const unsigned char *end,
HannesTschofenig 0:796d0f61a05b 2559 size_t pms_offset )
HannesTschofenig 0:796d0f61a05b 2560 {
HannesTschofenig 0:796d0f61a05b 2561 int ret;
HannesTschofenig 0:796d0f61a05b 2562 size_t len = pk_get_len( ssl_own_key( ssl ) );
HannesTschofenig 0:796d0f61a05b 2563 unsigned char *pms = ssl->handshake->premaster + pms_offset;
HannesTschofenig 0:796d0f61a05b 2564
HannesTschofenig 0:796d0f61a05b 2565 if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) )
HannesTschofenig 0:796d0f61a05b 2566 {
HannesTschofenig 0:796d0f61a05b 2567 SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
HannesTschofenig 0:796d0f61a05b 2568 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
HannesTschofenig 0:796d0f61a05b 2569 }
HannesTschofenig 0:796d0f61a05b 2570
HannesTschofenig 0:796d0f61a05b 2571 /*
HannesTschofenig 0:796d0f61a05b 2572 * Decrypt the premaster using own private RSA key
HannesTschofenig 0:796d0f61a05b 2573 */
HannesTschofenig 0:796d0f61a05b 2574 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
HannesTschofenig 0:796d0f61a05b 2575 defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2576 if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
HannesTschofenig 0:796d0f61a05b 2577 {
HannesTschofenig 0:796d0f61a05b 2578 if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
HannesTschofenig 0:796d0f61a05b 2579 *p++ != ( ( len ) & 0xFF ) )
HannesTschofenig 0:796d0f61a05b 2580 {
HannesTschofenig 0:796d0f61a05b 2581 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2582 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2583 }
HannesTschofenig 0:796d0f61a05b 2584 }
HannesTschofenig 0:796d0f61a05b 2585 #endif
HannesTschofenig 0:796d0f61a05b 2586
HannesTschofenig 0:796d0f61a05b 2587 if( p + len != end )
HannesTschofenig 0:796d0f61a05b 2588 {
HannesTschofenig 0:796d0f61a05b 2589 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2590 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2591 }
HannesTschofenig 0:796d0f61a05b 2592
HannesTschofenig 0:796d0f61a05b 2593 ret = pk_decrypt( ssl_own_key( ssl ), p, len,
HannesTschofenig 0:796d0f61a05b 2594 pms, &ssl->handshake->pmslen,
HannesTschofenig 0:796d0f61a05b 2595 sizeof( ssl->handshake->premaster ) - pms_offset,
HannesTschofenig 0:796d0f61a05b 2596 ssl->f_rng, ssl->p_rng );
HannesTschofenig 0:796d0f61a05b 2597
HannesTschofenig 0:796d0f61a05b 2598 if( ret != 0 || ssl->handshake->pmslen != 48 ||
HannesTschofenig 0:796d0f61a05b 2599 pms[0] != ssl->handshake->max_major_ver ||
HannesTschofenig 0:796d0f61a05b 2600 pms[1] != ssl->handshake->max_minor_ver )
HannesTschofenig 0:796d0f61a05b 2601 {
HannesTschofenig 0:796d0f61a05b 2602 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2603
HannesTschofenig 0:796d0f61a05b 2604 /*
HannesTschofenig 0:796d0f61a05b 2605 * Protection against Bleichenbacher's attack:
HannesTschofenig 0:796d0f61a05b 2606 * invalid PKCS#1 v1.5 padding must not cause
HannesTschofenig 0:796d0f61a05b 2607 * the connection to end immediately; instead,
HannesTschofenig 0:796d0f61a05b 2608 * send a bad_record_mac later in the handshake.
HannesTschofenig 0:796d0f61a05b 2609 */
HannesTschofenig 0:796d0f61a05b 2610 ssl->handshake->pmslen = 48;
HannesTschofenig 0:796d0f61a05b 2611
HannesTschofenig 0:796d0f61a05b 2612 ret = ssl->f_rng( ssl->p_rng, pms, ssl->handshake->pmslen );
HannesTschofenig 0:796d0f61a05b 2613 if( ret != 0 )
HannesTschofenig 0:796d0f61a05b 2614 return( ret );
HannesTschofenig 0:796d0f61a05b 2615 }
HannesTschofenig 0:796d0f61a05b 2616
HannesTschofenig 0:796d0f61a05b 2617 return( ret );
HannesTschofenig 0:796d0f61a05b 2618 }
HannesTschofenig 0:796d0f61a05b 2619 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2620 POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2621
HannesTschofenig 0:796d0f61a05b 2622 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2623 static int ssl_parse_client_psk_identity( ssl_context *ssl, unsigned char **p,
HannesTschofenig 0:796d0f61a05b 2624 const unsigned char *end )
HannesTschofenig 0:796d0f61a05b 2625 {
HannesTschofenig 0:796d0f61a05b 2626 int ret = 0;
HannesTschofenig 0:796d0f61a05b 2627 size_t n;
HannesTschofenig 0:796d0f61a05b 2628
HannesTschofenig 0:796d0f61a05b 2629 if( ssl->f_psk == NULL &&
HannesTschofenig 0:796d0f61a05b 2630 ( ssl->psk == NULL || ssl->psk_identity == NULL ||
HannesTschofenig 0:796d0f61a05b 2631 ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) )
HannesTschofenig 0:796d0f61a05b 2632 {
HannesTschofenig 0:796d0f61a05b 2633 SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
HannesTschofenig 0:796d0f61a05b 2634 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
HannesTschofenig 0:796d0f61a05b 2635 }
HannesTschofenig 0:796d0f61a05b 2636
HannesTschofenig 0:796d0f61a05b 2637 /*
HannesTschofenig 0:796d0f61a05b 2638 * Receive client pre-shared key identity name
HannesTschofenig 0:796d0f61a05b 2639 */
HannesTschofenig 0:796d0f61a05b 2640 if( *p + 2 > end )
HannesTschofenig 0:796d0f61a05b 2641 {
HannesTschofenig 0:796d0f61a05b 2642 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2643 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2644 }
HannesTschofenig 0:796d0f61a05b 2645
HannesTschofenig 0:796d0f61a05b 2646 n = ( (*p)[0] << 8 ) | (*p)[1];
HannesTschofenig 0:796d0f61a05b 2647 *p += 2;
HannesTschofenig 0:796d0f61a05b 2648
HannesTschofenig 0:796d0f61a05b 2649 if( n < 1 || n > 65535 || *p + n > end )
HannesTschofenig 0:796d0f61a05b 2650 {
HannesTschofenig 0:796d0f61a05b 2651 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2652 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2653 }
HannesTschofenig 0:796d0f61a05b 2654
HannesTschofenig 0:796d0f61a05b 2655 if( ssl->f_psk != NULL )
HannesTschofenig 0:796d0f61a05b 2656 {
HannesTschofenig 0:796d0f61a05b 2657 if( ( ret != ssl->f_psk( ssl->p_psk, ssl, *p, n ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2658 ret = POLARSSL_ERR_SSL_UNKNOWN_IDENTITY;
HannesTschofenig 0:796d0f61a05b 2659 }
HannesTschofenig 0:796d0f61a05b 2660
HannesTschofenig 0:796d0f61a05b 2661 if( ret == 0 )
HannesTschofenig 0:796d0f61a05b 2662 {
HannesTschofenig 0:796d0f61a05b 2663 /* Identity is not a big secret since clients send it in the clear,
HannesTschofenig 0:796d0f61a05b 2664 * but treat it carefully anyway, just in case */
HannesTschofenig 0:796d0f61a05b 2665 if( n != ssl->psk_identity_len ||
HannesTschofenig 0:796d0f61a05b 2666 safer_memcmp( ssl->psk_identity, *p, n ) != 0 )
HannesTschofenig 0:796d0f61a05b 2667 {
HannesTschofenig 0:796d0f61a05b 2668 ret = POLARSSL_ERR_SSL_UNKNOWN_IDENTITY;
HannesTschofenig 0:796d0f61a05b 2669 }
HannesTschofenig 0:796d0f61a05b 2670 }
HannesTschofenig 0:796d0f61a05b 2671
HannesTschofenig 0:796d0f61a05b 2672 if( ret == POLARSSL_ERR_SSL_UNKNOWN_IDENTITY )
HannesTschofenig 0:796d0f61a05b 2673 {
HannesTschofenig 0:796d0f61a05b 2674 SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
HannesTschofenig 0:796d0f61a05b 2675 if( ( ret = ssl_send_alert_message( ssl,
HannesTschofenig 0:796d0f61a05b 2676 SSL_ALERT_LEVEL_FATAL,
HannesTschofenig 0:796d0f61a05b 2677 SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2678 {
HannesTschofenig 0:796d0f61a05b 2679 return( ret );
HannesTschofenig 0:796d0f61a05b 2680 }
HannesTschofenig 0:796d0f61a05b 2681
HannesTschofenig 0:796d0f61a05b 2682 return( POLARSSL_ERR_SSL_UNKNOWN_IDENTITY );
HannesTschofenig 0:796d0f61a05b 2683 }
HannesTschofenig 0:796d0f61a05b 2684
HannesTschofenig 0:796d0f61a05b 2685 *p += n;
HannesTschofenig 0:796d0f61a05b 2686 ret = 0;
HannesTschofenig 0:796d0f61a05b 2687
HannesTschofenig 0:796d0f61a05b 2688 return( ret );
HannesTschofenig 0:796d0f61a05b 2689 }
HannesTschofenig 0:796d0f61a05b 2690 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2691
HannesTschofenig 0:796d0f61a05b 2692 static int ssl_parse_client_key_exchange( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2693 {
HannesTschofenig 0:796d0f61a05b 2694 int ret;
HannesTschofenig 0:796d0f61a05b 2695 const ssl_ciphersuite_t *ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2696
HannesTschofenig 0:796d0f61a05b 2697 ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2698
HannesTschofenig 0:796d0f61a05b 2699 SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2700
HannesTschofenig 0:796d0f61a05b 2701 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2702 {
HannesTschofenig 0:796d0f61a05b 2703 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 2704 return( ret );
HannesTschofenig 0:796d0f61a05b 2705 }
HannesTschofenig 0:796d0f61a05b 2706
HannesTschofenig 0:796d0f61a05b 2707 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 2708 {
HannesTschofenig 0:796d0f61a05b 2709 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2710 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2711 }
HannesTschofenig 0:796d0f61a05b 2712
HannesTschofenig 0:796d0f61a05b 2713 if( ssl->in_msg[0] != SSL_HS_CLIENT_KEY_EXCHANGE )
HannesTschofenig 0:796d0f61a05b 2714 {
HannesTschofenig 0:796d0f61a05b 2715 SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
HannesTschofenig 0:796d0f61a05b 2716 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2717 }
HannesTschofenig 0:796d0f61a05b 2718
HannesTschofenig 0:796d0f61a05b 2719 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2720 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
HannesTschofenig 0:796d0f61a05b 2721 {
HannesTschofenig 0:796d0f61a05b 2722 unsigned char *p = ssl->in_msg + 4;
HannesTschofenig 0:796d0f61a05b 2723 unsigned char *end = ssl->in_msg + ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2724
HannesTschofenig 0:796d0f61a05b 2725 if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2726 {
HannesTschofenig 0:796d0f61a05b 2727 SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
HannesTschofenig 0:796d0f61a05b 2728 return( ret );
HannesTschofenig 0:796d0f61a05b 2729 }
HannesTschofenig 0:796d0f61a05b 2730
HannesTschofenig 0:796d0f61a05b 2731 if( p != end )
HannesTschofenig 0:796d0f61a05b 2732 {
HannesTschofenig 0:796d0f61a05b 2733 SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2734 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2735 }
HannesTschofenig 0:796d0f61a05b 2736
HannesTschofenig 0:796d0f61a05b 2737 ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
HannesTschofenig 0:796d0f61a05b 2738
HannesTschofenig 0:796d0f61a05b 2739 if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
HannesTschofenig 0:796d0f61a05b 2740 ssl->handshake->premaster,
HannesTschofenig 0:796d0f61a05b 2741 &ssl->handshake->pmslen,
HannesTschofenig 0:796d0f61a05b 2742 ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2743 {
HannesTschofenig 0:796d0f61a05b 2744 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
HannesTschofenig 0:796d0f61a05b 2745 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
HannesTschofenig 0:796d0f61a05b 2746 }
HannesTschofenig 0:796d0f61a05b 2747
HannesTschofenig 0:796d0f61a05b 2748 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
HannesTschofenig 0:796d0f61a05b 2749 }
HannesTschofenig 0:796d0f61a05b 2750 else
HannesTschofenig 0:796d0f61a05b 2751 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2752 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2753 defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2754 defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
HannesTschofenig 0:796d0f61a05b 2755 defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2756 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
HannesTschofenig 0:796d0f61a05b 2757 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ||
HannesTschofenig 0:796d0f61a05b 2758 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
HannesTschofenig 0:796d0f61a05b 2759 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
HannesTschofenig 0:796d0f61a05b 2760 {
HannesTschofenig 0:796d0f61a05b 2761 if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx,
HannesTschofenig 0:796d0f61a05b 2762 ssl->in_msg + 4, ssl->in_hslen - 4 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2763 {
HannesTschofenig 0:796d0f61a05b 2764 SSL_DEBUG_RET( 1, "ecdh_read_public", ret );
HannesTschofenig 0:796d0f61a05b 2765 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
HannesTschofenig 0:796d0f61a05b 2766 }
HannesTschofenig 0:796d0f61a05b 2767
HannesTschofenig 0:796d0f61a05b 2768 SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
HannesTschofenig 0:796d0f61a05b 2769
HannesTschofenig 0:796d0f61a05b 2770 if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
HannesTschofenig 0:796d0f61a05b 2771 &ssl->handshake->pmslen,
HannesTschofenig 0:796d0f61a05b 2772 ssl->handshake->premaster,
HannesTschofenig 0:796d0f61a05b 2773 POLARSSL_MPI_MAX_SIZE,
HannesTschofenig 0:796d0f61a05b 2774 ssl->f_rng, ssl->p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2775 {
HannesTschofenig 0:796d0f61a05b 2776 SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
HannesTschofenig 0:796d0f61a05b 2777 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
HannesTschofenig 0:796d0f61a05b 2778 }
HannesTschofenig 0:796d0f61a05b 2779
HannesTschofenig 0:796d0f61a05b 2780 SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z );
HannesTschofenig 0:796d0f61a05b 2781 }
HannesTschofenig 0:796d0f61a05b 2782 else
HannesTschofenig 0:796d0f61a05b 2783 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2784 POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2785 POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
HannesTschofenig 0:796d0f61a05b 2786 POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2787 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2788 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
HannesTschofenig 0:796d0f61a05b 2789 {
HannesTschofenig 0:796d0f61a05b 2790 unsigned char *p = ssl->in_msg + 4;
HannesTschofenig 0:796d0f61a05b 2791 unsigned char *end = ssl->in_msg + ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2792
HannesTschofenig 0:796d0f61a05b 2793 if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2794 {
HannesTschofenig 0:796d0f61a05b 2795 SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
HannesTschofenig 0:796d0f61a05b 2796 return( ret );
HannesTschofenig 0:796d0f61a05b 2797 }
HannesTschofenig 0:796d0f61a05b 2798
HannesTschofenig 0:796d0f61a05b 2799 if( p != end )
HannesTschofenig 0:796d0f61a05b 2800 {
HannesTschofenig 0:796d0f61a05b 2801 SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2802 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2803 }
HannesTschofenig 0:796d0f61a05b 2804
HannesTschofenig 0:796d0f61a05b 2805 if( ( ret = ssl_psk_derive_premaster( ssl,
HannesTschofenig 0:796d0f61a05b 2806 ciphersuite_info->key_exchange ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2807 {
HannesTschofenig 0:796d0f61a05b 2808 SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
HannesTschofenig 0:796d0f61a05b 2809 return( ret );
HannesTschofenig 0:796d0f61a05b 2810 }
HannesTschofenig 0:796d0f61a05b 2811 }
HannesTschofenig 0:796d0f61a05b 2812 else
HannesTschofenig 0:796d0f61a05b 2813 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2814 #if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2815 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
HannesTschofenig 0:796d0f61a05b 2816 {
HannesTschofenig 0:796d0f61a05b 2817 unsigned char *p = ssl->in_msg + 4;
HannesTschofenig 0:796d0f61a05b 2818 unsigned char *end = ssl->in_msg + ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2819
HannesTschofenig 0:796d0f61a05b 2820 if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2821 {
HannesTschofenig 0:796d0f61a05b 2822 SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
HannesTschofenig 0:796d0f61a05b 2823 return( ret );
HannesTschofenig 0:796d0f61a05b 2824 }
HannesTschofenig 0:796d0f61a05b 2825
HannesTschofenig 0:796d0f61a05b 2826 if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2827 {
HannesTschofenig 0:796d0f61a05b 2828 SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
HannesTschofenig 0:796d0f61a05b 2829 return( ret );
HannesTschofenig 0:796d0f61a05b 2830 }
HannesTschofenig 0:796d0f61a05b 2831
HannesTschofenig 0:796d0f61a05b 2832 if( ( ret = ssl_psk_derive_premaster( ssl,
HannesTschofenig 0:796d0f61a05b 2833 ciphersuite_info->key_exchange ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2834 {
HannesTschofenig 0:796d0f61a05b 2835 SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
HannesTschofenig 0:796d0f61a05b 2836 return( ret );
HannesTschofenig 0:796d0f61a05b 2837 }
HannesTschofenig 0:796d0f61a05b 2838 }
HannesTschofenig 0:796d0f61a05b 2839 else
HannesTschofenig 0:796d0f61a05b 2840 #endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2841 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2842 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
HannesTschofenig 0:796d0f61a05b 2843 {
HannesTschofenig 0:796d0f61a05b 2844 unsigned char *p = ssl->in_msg + 4;
HannesTschofenig 0:796d0f61a05b 2845 unsigned char *end = ssl->in_msg + ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2846
HannesTschofenig 0:796d0f61a05b 2847 if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2848 {
HannesTschofenig 0:796d0f61a05b 2849 SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
HannesTschofenig 0:796d0f61a05b 2850 return( ret );
HannesTschofenig 0:796d0f61a05b 2851 }
HannesTschofenig 0:796d0f61a05b 2852 if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2853 {
HannesTschofenig 0:796d0f61a05b 2854 SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
HannesTschofenig 0:796d0f61a05b 2855 return( ret );
HannesTschofenig 0:796d0f61a05b 2856 }
HannesTschofenig 0:796d0f61a05b 2857
HannesTschofenig 0:796d0f61a05b 2858 if( p != end )
HannesTschofenig 0:796d0f61a05b 2859 {
HannesTschofenig 0:796d0f61a05b 2860 SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2861 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
HannesTschofenig 0:796d0f61a05b 2862 }
HannesTschofenig 0:796d0f61a05b 2863
HannesTschofenig 0:796d0f61a05b 2864 if( ( ret = ssl_psk_derive_premaster( ssl,
HannesTschofenig 0:796d0f61a05b 2865 ciphersuite_info->key_exchange ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2866 {
HannesTschofenig 0:796d0f61a05b 2867 SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
HannesTschofenig 0:796d0f61a05b 2868 return( ret );
HannesTschofenig 0:796d0f61a05b 2869 }
HannesTschofenig 0:796d0f61a05b 2870 }
HannesTschofenig 0:796d0f61a05b 2871 else
HannesTschofenig 0:796d0f61a05b 2872 #endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2873 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
HannesTschofenig 0:796d0f61a05b 2874 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
HannesTschofenig 0:796d0f61a05b 2875 {
HannesTschofenig 0:796d0f61a05b 2876 unsigned char *p = ssl->in_msg + 4;
HannesTschofenig 0:796d0f61a05b 2877 unsigned char *end = ssl->in_msg + ssl->in_hslen;
HannesTschofenig 0:796d0f61a05b 2878
HannesTschofenig 0:796d0f61a05b 2879 if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2880 {
HannesTschofenig 0:796d0f61a05b 2881 SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
HannesTschofenig 0:796d0f61a05b 2882 return( ret );
HannesTschofenig 0:796d0f61a05b 2883 }
HannesTschofenig 0:796d0f61a05b 2884
HannesTschofenig 0:796d0f61a05b 2885 if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx,
HannesTschofenig 0:796d0f61a05b 2886 p, end - p ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2887 {
HannesTschofenig 0:796d0f61a05b 2888 SSL_DEBUG_RET( 1, "ecdh_read_public", ret );
HannesTschofenig 0:796d0f61a05b 2889 return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
HannesTschofenig 0:796d0f61a05b 2890 }
HannesTschofenig 0:796d0f61a05b 2891
HannesTschofenig 0:796d0f61a05b 2892 SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
HannesTschofenig 0:796d0f61a05b 2893
HannesTschofenig 0:796d0f61a05b 2894 if( ( ret = ssl_psk_derive_premaster( ssl,
HannesTschofenig 0:796d0f61a05b 2895 ciphersuite_info->key_exchange ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2896 {
HannesTschofenig 0:796d0f61a05b 2897 SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
HannesTschofenig 0:796d0f61a05b 2898 return( ret );
HannesTschofenig 0:796d0f61a05b 2899 }
HannesTschofenig 0:796d0f61a05b 2900 }
HannesTschofenig 0:796d0f61a05b 2901 else
HannesTschofenig 0:796d0f61a05b 2902 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
HannesTschofenig 0:796d0f61a05b 2903 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2904 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
HannesTschofenig 0:796d0f61a05b 2905 {
HannesTschofenig 0:796d0f61a05b 2906 if( ( ret = ssl_parse_encrypted_pms( ssl,
HannesTschofenig 0:796d0f61a05b 2907 ssl->in_msg + 4,
HannesTschofenig 0:796d0f61a05b 2908 ssl->in_msg + ssl->in_hslen,
HannesTschofenig 0:796d0f61a05b 2909 0 ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2910 {
HannesTschofenig 0:796d0f61a05b 2911 SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret );
HannesTschofenig 0:796d0f61a05b 2912 return( ret );
HannesTschofenig 0:796d0f61a05b 2913 }
HannesTschofenig 0:796d0f61a05b 2914 }
HannesTschofenig 0:796d0f61a05b 2915 else
HannesTschofenig 0:796d0f61a05b 2916 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 2917 {
HannesTschofenig 0:796d0f61a05b 2918 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 2919 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 2920 }
HannesTschofenig 0:796d0f61a05b 2921
HannesTschofenig 0:796d0f61a05b 2922 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2923 {
HannesTschofenig 0:796d0f61a05b 2924 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
HannesTschofenig 0:796d0f61a05b 2925 return( ret );
HannesTschofenig 0:796d0f61a05b 2926 }
HannesTschofenig 0:796d0f61a05b 2927
HannesTschofenig 0:796d0f61a05b 2928 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2929
HannesTschofenig 0:796d0f61a05b 2930 SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) );
HannesTschofenig 0:796d0f61a05b 2931
HannesTschofenig 0:796d0f61a05b 2932 return( 0 );
HannesTschofenig 0:796d0f61a05b 2933 }
HannesTschofenig 0:796d0f61a05b 2934
HannesTschofenig 0:796d0f61a05b 2935 #if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2936 !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2937 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
HannesTschofenig 0:796d0f61a05b 2938 !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
HannesTschofenig 0:796d0f61a05b 2939 static int ssl_parse_certificate_verify( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2940 {
HannesTschofenig 0:796d0f61a05b 2941 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2942 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2943
HannesTschofenig 0:796d0f61a05b 2944 SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 2945
HannesTschofenig 0:796d0f61a05b 2946 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2947 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
HannesTschofenig 0:796d0f61a05b 2948 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2949 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
HannesTschofenig 0:796d0f61a05b 2950 {
HannesTschofenig 0:796d0f61a05b 2951 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 2952 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2953 return( 0 );
HannesTschofenig 0:796d0f61a05b 2954 }
HannesTschofenig 0:796d0f61a05b 2955
HannesTschofenig 0:796d0f61a05b 2956 SSL_DEBUG_MSG( 1, ( "should not happen" ) );
HannesTschofenig 0:796d0f61a05b 2957 return( ret );
HannesTschofenig 0:796d0f61a05b 2958 }
HannesTschofenig 0:796d0f61a05b 2959 #else
HannesTschofenig 0:796d0f61a05b 2960 static int ssl_parse_certificate_verify( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 2961 {
HannesTschofenig 0:796d0f61a05b 2962 int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
HannesTschofenig 0:796d0f61a05b 2963 size_t sa_len, sig_len;
HannesTschofenig 0:796d0f61a05b 2964 unsigned char hash[48];
HannesTschofenig 0:796d0f61a05b 2965 unsigned char *hash_start = hash;
HannesTschofenig 0:796d0f61a05b 2966 size_t hashlen;
HannesTschofenig 0:796d0f61a05b 2967 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 2968 pk_type_t pk_alg;
HannesTschofenig 0:796d0f61a05b 2969 #endif
HannesTschofenig 0:796d0f61a05b 2970 md_type_t md_alg;
HannesTschofenig 0:796d0f61a05b 2971 const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
HannesTschofenig 0:796d0f61a05b 2972
HannesTschofenig 0:796d0f61a05b 2973 SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 2974
HannesTschofenig 0:796d0f61a05b 2975 if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
HannesTschofenig 0:796d0f61a05b 2976 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
HannesTschofenig 0:796d0f61a05b 2977 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
HannesTschofenig 0:796d0f61a05b 2978 ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
HannesTschofenig 0:796d0f61a05b 2979 {
HannesTschofenig 0:796d0f61a05b 2980 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 2981 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2982 return( 0 );
HannesTschofenig 0:796d0f61a05b 2983 }
HannesTschofenig 0:796d0f61a05b 2984
HannesTschofenig 0:796d0f61a05b 2985 if( ssl->session_negotiate->peer_cert == NULL )
HannesTschofenig 0:796d0f61a05b 2986 {
HannesTschofenig 0:796d0f61a05b 2987 SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 2988 ssl->state++;
HannesTschofenig 0:796d0f61a05b 2989 return( 0 );
HannesTschofenig 0:796d0f61a05b 2990 }
HannesTschofenig 0:796d0f61a05b 2991
HannesTschofenig 0:796d0f61a05b 2992 ssl->handshake->calc_verify( ssl, hash );
HannesTschofenig 0:796d0f61a05b 2993
HannesTschofenig 0:796d0f61a05b 2994 if( ( ret = ssl_read_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 2995 {
HannesTschofenig 0:796d0f61a05b 2996 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
HannesTschofenig 0:796d0f61a05b 2997 return( ret );
HannesTschofenig 0:796d0f61a05b 2998 }
HannesTschofenig 0:796d0f61a05b 2999
HannesTschofenig 0:796d0f61a05b 3000 ssl->state++;
HannesTschofenig 0:796d0f61a05b 3001
HannesTschofenig 0:796d0f61a05b 3002 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
HannesTschofenig 0:796d0f61a05b 3003 {
HannesTschofenig 0:796d0f61a05b 3004 SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
HannesTschofenig 0:796d0f61a05b 3005 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3006 }
HannesTschofenig 0:796d0f61a05b 3007
HannesTschofenig 0:796d0f61a05b 3008 if( ssl->in_msg[0] != SSL_HS_CERTIFICATE_VERIFY )
HannesTschofenig 0:796d0f61a05b 3009 {
HannesTschofenig 0:796d0f61a05b 3010 SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
HannesTschofenig 0:796d0f61a05b 3011 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3012 }
HannesTschofenig 0:796d0f61a05b 3013
HannesTschofenig 0:796d0f61a05b 3014 /*
HannesTschofenig 0:796d0f61a05b 3015 * 0 . 0 handshake type
HannesTschofenig 0:796d0f61a05b 3016 * 1 . 3 handshake length
HannesTschofenig 0:796d0f61a05b 3017 * 4 . 5 sig alg (TLS 1.2 only)
HannesTschofenig 0:796d0f61a05b 3018 * 4+n . 5+n signature length (n = sa_len)
HannesTschofenig 0:796d0f61a05b 3019 * 6+n . 6+n+m signature (m = sig_len)
HannesTschofenig 0:796d0f61a05b 3020 */
HannesTschofenig 0:796d0f61a05b 3021
HannesTschofenig 0:796d0f61a05b 3022 #if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
HannesTschofenig 0:796d0f61a05b 3023 defined(POLARSSL_SSL_PROTO_TLS1_1)
HannesTschofenig 0:796d0f61a05b 3024 if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 3025 {
HannesTschofenig 0:796d0f61a05b 3026 sa_len = 0;
HannesTschofenig 0:796d0f61a05b 3027
HannesTschofenig 0:796d0f61a05b 3028 md_alg = POLARSSL_MD_NONE;
HannesTschofenig 0:796d0f61a05b 3029 hashlen = 36;
HannesTschofenig 0:796d0f61a05b 3030
HannesTschofenig 0:796d0f61a05b 3031 /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
HannesTschofenig 0:796d0f61a05b 3032 if( pk_can_do( &ssl->session_negotiate->peer_cert->pk,
HannesTschofenig 0:796d0f61a05b 3033 POLARSSL_PK_ECDSA ) )
HannesTschofenig 0:796d0f61a05b 3034 {
HannesTschofenig 0:796d0f61a05b 3035 hash_start += 16;
HannesTschofenig 0:796d0f61a05b 3036 hashlen -= 16;
HannesTschofenig 0:796d0f61a05b 3037 md_alg = POLARSSL_MD_SHA1;
HannesTschofenig 0:796d0f61a05b 3038 }
HannesTschofenig 0:796d0f61a05b 3039 }
HannesTschofenig 0:796d0f61a05b 3040 else
HannesTschofenig 0:796d0f61a05b 3041 #endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 ||
HannesTschofenig 0:796d0f61a05b 3042 POLARSSL_SSL_PROTO_TLS1_1 */
HannesTschofenig 0:796d0f61a05b 3043 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
HannesTschofenig 0:796d0f61a05b 3044 if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
HannesTschofenig 0:796d0f61a05b 3045 {
HannesTschofenig 0:796d0f61a05b 3046 sa_len = 2;
HannesTschofenig 0:796d0f61a05b 3047
HannesTschofenig 0:796d0f61a05b 3048 /*
HannesTschofenig 0:796d0f61a05b 3049 * Hash
HannesTschofenig 0:796d0f61a05b 3050 */
HannesTschofenig 0:796d0f61a05b 3051 if( ssl->in_msg[4] != ssl->handshake->verify_sig_alg )
HannesTschofenig 0:796d0f61a05b 3052 {
HannesTschofenig 0:796d0f61a05b 3053 SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
HannesTschofenig 0:796d0f61a05b 3054 " for verify message" ) );
HannesTschofenig 0:796d0f61a05b 3055 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3056 }
HannesTschofenig 0:796d0f61a05b 3057
HannesTschofenig 0:796d0f61a05b 3058 md_alg = ssl_md_alg_from_hash( ssl->handshake->verify_sig_alg );
HannesTschofenig 0:796d0f61a05b 3059
HannesTschofenig 0:796d0f61a05b 3060 /* Info from md_alg will be used instead */
HannesTschofenig 0:796d0f61a05b 3061 hashlen = 0;
HannesTschofenig 0:796d0f61a05b 3062
HannesTschofenig 0:796d0f61a05b 3063 /*
HannesTschofenig 0:796d0f61a05b 3064 * Signature
HannesTschofenig 0:796d0f61a05b 3065 */
HannesTschofenig 0:796d0f61a05b 3066 if( ( pk_alg = ssl_pk_alg_from_sig( ssl->in_msg[5] ) )
HannesTschofenig 0:796d0f61a05b 3067 == POLARSSL_PK_NONE )
HannesTschofenig 0:796d0f61a05b 3068 {
HannesTschofenig 0:796d0f61a05b 3069 SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
HannesTschofenig 0:796d0f61a05b 3070 " for verify message" ) );
HannesTschofenig 0:796d0f61a05b 3071 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3072 }
HannesTschofenig 0:796d0f61a05b 3073
HannesTschofenig 0:796d0f61a05b 3074 /*
HannesTschofenig 0:796d0f61a05b 3075 * Check the certificate's key type matches the signature alg
HannesTschofenig 0:796d0f61a05b 3076 */
HannesTschofenig 0:796d0f61a05b 3077 if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
HannesTschofenig 0:796d0f61a05b 3078 {
HannesTschofenig 0:796d0f61a05b 3079 SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
HannesTschofenig 0:796d0f61a05b 3080 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3081 }
HannesTschofenig 0:796d0f61a05b 3082 }
HannesTschofenig 0:796d0f61a05b 3083 else
HannesTschofenig 0:796d0f61a05b 3084 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
HannesTschofenig 0:796d0f61a05b 3085 {
HannesTschofenig 0:796d0f61a05b 3086 SSL_DEBUG_MSG( 1, ( "should never happen" ) );
HannesTschofenig 0:796d0f61a05b 3087 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
HannesTschofenig 0:796d0f61a05b 3088 }
HannesTschofenig 0:796d0f61a05b 3089
HannesTschofenig 0:796d0f61a05b 3090 sig_len = ( ssl->in_msg[4 + sa_len] << 8 ) | ssl->in_msg[5 + sa_len];
HannesTschofenig 0:796d0f61a05b 3091
HannesTschofenig 0:796d0f61a05b 3092 if( sa_len + sig_len + 6 != ssl->in_hslen )
HannesTschofenig 0:796d0f61a05b 3093 {
HannesTschofenig 0:796d0f61a05b 3094 SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
HannesTschofenig 0:796d0f61a05b 3095 return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
HannesTschofenig 0:796d0f61a05b 3096 }
HannesTschofenig 0:796d0f61a05b 3097
HannesTschofenig 0:796d0f61a05b 3098 if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
HannesTschofenig 0:796d0f61a05b 3099 md_alg, hash_start, hashlen,
HannesTschofenig 0:796d0f61a05b 3100 ssl->in_msg + 6 + sa_len, sig_len ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3101 {
HannesTschofenig 0:796d0f61a05b 3102 SSL_DEBUG_RET( 1, "pk_verify", ret );
HannesTschofenig 0:796d0f61a05b 3103 return( ret );
HannesTschofenig 0:796d0f61a05b 3104 }
HannesTschofenig 0:796d0f61a05b 3105
HannesTschofenig 0:796d0f61a05b 3106 SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
HannesTschofenig 0:796d0f61a05b 3107
HannesTschofenig 0:796d0f61a05b 3108 return( ret );
HannesTschofenig 0:796d0f61a05b 3109 }
HannesTschofenig 0:796d0f61a05b 3110 #endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED &&
HannesTschofenig 0:796d0f61a05b 3111 !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
HannesTschofenig 0:796d0f61a05b 3112 !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
HannesTschofenig 0:796d0f61a05b 3113
HannesTschofenig 0:796d0f61a05b 3114 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 3115 static int ssl_write_new_session_ticket( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3116 {
HannesTschofenig 0:796d0f61a05b 3117 int ret;
HannesTschofenig 0:796d0f61a05b 3118 size_t tlen;
HannesTschofenig 0:796d0f61a05b 3119 uint32_t lifetime = (uint32_t) ssl->ticket_lifetime;
HannesTschofenig 0:796d0f61a05b 3120
HannesTschofenig 0:796d0f61a05b 3121 SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) );
HannesTschofenig 0:796d0f61a05b 3122
HannesTschofenig 0:796d0f61a05b 3123 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
HannesTschofenig 0:796d0f61a05b 3124 ssl->out_msg[0] = SSL_HS_NEW_SESSION_TICKET;
HannesTschofenig 0:796d0f61a05b 3125
HannesTschofenig 0:796d0f61a05b 3126 /*
HannesTschofenig 0:796d0f61a05b 3127 * struct {
HannesTschofenig 0:796d0f61a05b 3128 * uint32 ticket_lifetime_hint;
HannesTschofenig 0:796d0f61a05b 3129 * opaque ticket<0..2^16-1>;
HannesTschofenig 0:796d0f61a05b 3130 * } NewSessionTicket;
HannesTschofenig 0:796d0f61a05b 3131 *
HannesTschofenig 0:796d0f61a05b 3132 * 4 . 7 ticket_lifetime_hint (0 = unspecified)
HannesTschofenig 0:796d0f61a05b 3133 * 8 . 9 ticket_len (n)
HannesTschofenig 0:796d0f61a05b 3134 * 10 . 9+n ticket content
HannesTschofenig 0:796d0f61a05b 3135 */
HannesTschofenig 0:796d0f61a05b 3136
HannesTschofenig 0:796d0f61a05b 3137 ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 3138 ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 3139 ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 3140 ssl->out_msg[7] = ( lifetime ) & 0xFF;
HannesTschofenig 0:796d0f61a05b 3141
HannesTschofenig 0:796d0f61a05b 3142 if( ( ret = ssl_write_ticket( ssl, &tlen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3143 {
HannesTschofenig 0:796d0f61a05b 3144 SSL_DEBUG_RET( 1, "ssl_write_ticket", ret );
HannesTschofenig 0:796d0f61a05b 3145 tlen = 0;
HannesTschofenig 0:796d0f61a05b 3146 }
HannesTschofenig 0:796d0f61a05b 3147
HannesTschofenig 0:796d0f61a05b 3148 ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 3149 ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF );
HannesTschofenig 0:796d0f61a05b 3150
HannesTschofenig 0:796d0f61a05b 3151 ssl->out_msglen = 10 + tlen;
HannesTschofenig 0:796d0f61a05b 3152
HannesTschofenig 0:796d0f61a05b 3153 /*
HannesTschofenig 0:796d0f61a05b 3154 * Morally equivalent to updating ssl->state, but NewSessionTicket and
HannesTschofenig 0:796d0f61a05b 3155 * ChangeCipherSpec share the same state.
HannesTschofenig 0:796d0f61a05b 3156 */
HannesTschofenig 0:796d0f61a05b 3157 ssl->handshake->new_session_ticket = 0;
HannesTschofenig 0:796d0f61a05b 3158
HannesTschofenig 0:796d0f61a05b 3159 if( ( ret = ssl_write_record( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3160 {
HannesTschofenig 0:796d0f61a05b 3161 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
HannesTschofenig 0:796d0f61a05b 3162 return( ret );
HannesTschofenig 0:796d0f61a05b 3163 }
HannesTschofenig 0:796d0f61a05b 3164
HannesTschofenig 0:796d0f61a05b 3165 SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
HannesTschofenig 0:796d0f61a05b 3166
HannesTschofenig 0:796d0f61a05b 3167 return( 0 );
HannesTschofenig 0:796d0f61a05b 3168 }
HannesTschofenig 0:796d0f61a05b 3169 #endif /* POLARSSL_SSL_SESSION_TICKETS */
HannesTschofenig 0:796d0f61a05b 3170
HannesTschofenig 0:796d0f61a05b 3171 /*
HannesTschofenig 0:796d0f61a05b 3172 * SSL handshake -- server side -- single step
HannesTschofenig 0:796d0f61a05b 3173 */
HannesTschofenig 0:796d0f61a05b 3174 int ssl_handshake_server_step( ssl_context *ssl )
HannesTschofenig 0:796d0f61a05b 3175 {
HannesTschofenig 0:796d0f61a05b 3176 int ret = 0;
HannesTschofenig 0:796d0f61a05b 3177
HannesTschofenig 0:796d0f61a05b 3178 if( ssl->state == SSL_HANDSHAKE_OVER )
HannesTschofenig 0:796d0f61a05b 3179 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3180
HannesTschofenig 0:796d0f61a05b 3181 SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
HannesTschofenig 0:796d0f61a05b 3182
HannesTschofenig 0:796d0f61a05b 3183 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 3184 return( ret );
HannesTschofenig 0:796d0f61a05b 3185
HannesTschofenig 0:796d0f61a05b 3186 switch( ssl->state )
HannesTschofenig 0:796d0f61a05b 3187 {
HannesTschofenig 0:796d0f61a05b 3188 case SSL_HELLO_REQUEST:
HannesTschofenig 0:796d0f61a05b 3189 ssl->state = SSL_CLIENT_HELLO;
HannesTschofenig 0:796d0f61a05b 3190 break;
HannesTschofenig 0:796d0f61a05b 3191
HannesTschofenig 0:796d0f61a05b 3192 /*
HannesTschofenig 0:796d0f61a05b 3193 * <== ClientHello
HannesTschofenig 0:796d0f61a05b 3194 */
HannesTschofenig 0:796d0f61a05b 3195 case SSL_CLIENT_HELLO:
HannesTschofenig 0:796d0f61a05b 3196 ret = ssl_parse_client_hello( ssl );
HannesTschofenig 0:796d0f61a05b 3197 break;
HannesTschofenig 0:796d0f61a05b 3198
HannesTschofenig 0:796d0f61a05b 3199 /*
HannesTschofenig 0:796d0f61a05b 3200 * ==> ServerHello
HannesTschofenig 0:796d0f61a05b 3201 * Certificate
HannesTschofenig 0:796d0f61a05b 3202 * ( ServerKeyExchange )
HannesTschofenig 0:796d0f61a05b 3203 * ( CertificateRequest )
HannesTschofenig 0:796d0f61a05b 3204 * ServerHelloDone
HannesTschofenig 0:796d0f61a05b 3205 */
HannesTschofenig 0:796d0f61a05b 3206 case SSL_SERVER_HELLO:
HannesTschofenig 0:796d0f61a05b 3207 ret = ssl_write_server_hello( ssl );
HannesTschofenig 0:796d0f61a05b 3208 break;
HannesTschofenig 0:796d0f61a05b 3209
HannesTschofenig 0:796d0f61a05b 3210 case SSL_SERVER_CERTIFICATE:
HannesTschofenig 0:796d0f61a05b 3211 ret = ssl_write_certificate( ssl );
HannesTschofenig 0:796d0f61a05b 3212 break;
HannesTschofenig 0:796d0f61a05b 3213
HannesTschofenig 0:796d0f61a05b 3214 case SSL_SERVER_KEY_EXCHANGE:
HannesTschofenig 0:796d0f61a05b 3215 ret = ssl_write_server_key_exchange( ssl );
HannesTschofenig 0:796d0f61a05b 3216 break;
HannesTschofenig 0:796d0f61a05b 3217
HannesTschofenig 0:796d0f61a05b 3218 case SSL_CERTIFICATE_REQUEST:
HannesTschofenig 0:796d0f61a05b 3219 ret = ssl_write_certificate_request( ssl );
HannesTschofenig 0:796d0f61a05b 3220 break;
HannesTschofenig 0:796d0f61a05b 3221
HannesTschofenig 0:796d0f61a05b 3222 case SSL_SERVER_HELLO_DONE:
HannesTschofenig 0:796d0f61a05b 3223 ret = ssl_write_server_hello_done( ssl );
HannesTschofenig 0:796d0f61a05b 3224 break;
HannesTschofenig 0:796d0f61a05b 3225
HannesTschofenig 0:796d0f61a05b 3226 /*
HannesTschofenig 0:796d0f61a05b 3227 * <== ( Certificate/Alert )
HannesTschofenig 0:796d0f61a05b 3228 * ClientKeyExchange
HannesTschofenig 0:796d0f61a05b 3229 * ( CertificateVerify )
HannesTschofenig 0:796d0f61a05b 3230 * ChangeCipherSpec
HannesTschofenig 0:796d0f61a05b 3231 * Finished
HannesTschofenig 0:796d0f61a05b 3232 */
HannesTschofenig 0:796d0f61a05b 3233 case SSL_CLIENT_CERTIFICATE:
HannesTschofenig 0:796d0f61a05b 3234 ret = ssl_parse_certificate( ssl );
HannesTschofenig 0:796d0f61a05b 3235 break;
HannesTschofenig 0:796d0f61a05b 3236
HannesTschofenig 0:796d0f61a05b 3237 case SSL_CLIENT_KEY_EXCHANGE:
HannesTschofenig 0:796d0f61a05b 3238 ret = ssl_parse_client_key_exchange( ssl );
HannesTschofenig 0:796d0f61a05b 3239 break;
HannesTschofenig 0:796d0f61a05b 3240
HannesTschofenig 0:796d0f61a05b 3241 case SSL_CERTIFICATE_VERIFY:
HannesTschofenig 0:796d0f61a05b 3242 ret = ssl_parse_certificate_verify( ssl );
HannesTschofenig 0:796d0f61a05b 3243 break;
HannesTschofenig 0:796d0f61a05b 3244
HannesTschofenig 0:796d0f61a05b 3245 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
HannesTschofenig 0:796d0f61a05b 3246 ret = ssl_parse_change_cipher_spec( ssl );
HannesTschofenig 0:796d0f61a05b 3247 break;
HannesTschofenig 0:796d0f61a05b 3248
HannesTschofenig 0:796d0f61a05b 3249 case SSL_CLIENT_FINISHED:
HannesTschofenig 0:796d0f61a05b 3250 ret = ssl_parse_finished( ssl );
HannesTschofenig 0:796d0f61a05b 3251 break;
HannesTschofenig 0:796d0f61a05b 3252
HannesTschofenig 0:796d0f61a05b 3253 /*
HannesTschofenig 0:796d0f61a05b 3254 * ==> ( NewSessionTicket )
HannesTschofenig 0:796d0f61a05b 3255 * ChangeCipherSpec
HannesTschofenig 0:796d0f61a05b 3256 * Finished
HannesTschofenig 0:796d0f61a05b 3257 */
HannesTschofenig 0:796d0f61a05b 3258 case SSL_SERVER_CHANGE_CIPHER_SPEC:
HannesTschofenig 0:796d0f61a05b 3259 #if defined(POLARSSL_SSL_SESSION_TICKETS)
HannesTschofenig 0:796d0f61a05b 3260 if( ssl->handshake->new_session_ticket != 0 )
HannesTschofenig 0:796d0f61a05b 3261 ret = ssl_write_new_session_ticket( ssl );
HannesTschofenig 0:796d0f61a05b 3262 else
HannesTschofenig 0:796d0f61a05b 3263 #endif
HannesTschofenig 0:796d0f61a05b 3264 ret = ssl_write_change_cipher_spec( ssl );
HannesTschofenig 0:796d0f61a05b 3265 break;
HannesTschofenig 0:796d0f61a05b 3266
HannesTschofenig 0:796d0f61a05b 3267 case SSL_SERVER_FINISHED:
HannesTschofenig 0:796d0f61a05b 3268 ret = ssl_write_finished( ssl );
HannesTschofenig 0:796d0f61a05b 3269 break;
HannesTschofenig 0:796d0f61a05b 3270
HannesTschofenig 0:796d0f61a05b 3271 case SSL_FLUSH_BUFFERS:
HannesTschofenig 0:796d0f61a05b 3272 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
HannesTschofenig 0:796d0f61a05b 3273 ssl->state = SSL_HANDSHAKE_WRAPUP;
HannesTschofenig 0:796d0f61a05b 3274 break;
HannesTschofenig 0:796d0f61a05b 3275
HannesTschofenig 0:796d0f61a05b 3276 case SSL_HANDSHAKE_WRAPUP:
HannesTschofenig 0:796d0f61a05b 3277 ssl_handshake_wrapup( ssl );
HannesTschofenig 0:796d0f61a05b 3278 break;
HannesTschofenig 0:796d0f61a05b 3279
HannesTschofenig 0:796d0f61a05b 3280 default:
HannesTschofenig 0:796d0f61a05b 3281 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
HannesTschofenig 0:796d0f61a05b 3282 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 3283 }
HannesTschofenig 0:796d0f61a05b 3284
HannesTschofenig 0:796d0f61a05b 3285 return( ret );
HannesTschofenig 0:796d0f61a05b 3286 }
HannesTschofenig 0:796d0f61a05b 3287 #endif /* POLARSSL_SSL_SRV_C */
HannesTschofenig 0:796d0f61a05b 3288
HannesTschofenig 0:796d0f61a05b 3289