/* * Flush any data not yet written */ int ssl_flush_output(ssl_context * ssl) { int ret; uint8_t *buf; SSL_DEBUG_MSG(2, ("=> flush output")); while (ssl->out_left > 0) { SSL_DEBUG_MSG(2, ("message length: %d, out_left: %d", 5 + ssl->out_msglen, ssl->out_left)); buf = ssl->out_hdr + 5 + ssl->out_msglen - ssl->out_left; ret = ssl->f_send(ssl->p_send, buf, ssl->out_left); SSL_DEBUG_RET(2, "ssl->f_send", ret); if (ret <= 0) return (ret); ssl->out_left -= ret; } SSL_DEBUG_MSG(2, ("<= flush output")); return (0); }
/* * Fill the input message buffer */ int ssl_fetch_input(ssl_context * ssl, size_t nb_want) { int ret; size_t len; SSL_DEBUG_MSG(2, ("=> fetch input")); while (ssl->in_left < nb_want) { len = nb_want - ssl->in_left; ret = ssl->f_recv(ssl->p_recv, ssl->in_hdr + ssl->in_left, len); SSL_DEBUG_MSG(2, ("in_left: %d, nb_want: %d", ssl->in_left, nb_want)); SSL_DEBUG_RET(2, "ssl->f_recv", ret); if (ret < 0) return (ret); ssl->in_left += ret; } SSL_DEBUG_MSG(2, ("<= fetch input")); return (0); }
static int ssl_write_server_hello( ssl_context *ssl ) { time_t t; int ret, n; size_t ext_len = 0; unsigned char *buf, *p; SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); /* * 0 . 0 handshake type * 1 . 3 handshake length * 4 . 5 protocol version * 6 . 9 UNIX time() * 10 . 37 random bytes */ buf = ssl->out_msg; p = buf + 4; *p++ = (unsigned char) ssl->major_ver; *p++ = (unsigned char) ssl->minor_ver; SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", buf[4], buf[5] ) ); t = time( NULL ); *p++ = (unsigned char)( t >> 24 ); *p++ = (unsigned char)( t >> 16 ); *p++ = (unsigned char)( t >> 8 ); *p++ = (unsigned char)( t ); SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 ) return( ret ); p += 28; memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); /* * 38 . 38 session id length * 39 . 38+n session id * 39+n . 40+n chosen ciphersuite * 41+n . 41+n chosen compression alg. */ ssl->session_negotiate->length = n = 32; *p++ = (unsigned char) ssl->session_negotiate->length; if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE || ssl->f_get_cache == NULL || ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) != 0 ) { /* * Not found, create a new session id */ ssl->handshake->resume = 0; ssl->state++; if( ( ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, n ) ) != 0 ) return( ret ); } else { /* * Found a matching session, resuming it */ ssl->handshake->resume = 1; ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC; if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_derive_keys", ret ); return( ret ); } } memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->length ); p += ssl->session_negotiate->length; SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); SSL_DEBUG_MSG( 3, ( "%s session has been resumed", ssl->handshake->resume ? "a" : "no" ) ); *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); *p++ = (unsigned char)( ssl->session_negotiate->compression ); SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", ssl->session_negotiate->ciphersuite ) ); SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", ssl->session_negotiate->compression ) ); if( ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION ) { SSL_DEBUG_MSG( 3, ( "server hello, prepping for secure renegotiation extension" ) ); ext_len += 5 + ssl->verify_data_len * 2; SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( ext_len ) & 0xFF ); /* * Secure renegotiation */ SSL_DEBUG_MSG( 3, ( "client hello, secure renegotiation extension" ) ); *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); *p++ = 0x00; *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; *p++ = ssl->verify_data_len * 2 & 0xFF; memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); p += ssl->verify_data_len; memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); p += ssl->verify_data_len; }
static int ssl_parse_client_hello( ssl_context *ssl ) { int ret; unsigned int i, j; size_t n; unsigned int ciph_len, sess_len; unsigned int comp_len; unsigned int ext_len = 0; unsigned char *buf, *p, *ext; int renegotiation_info_seen = 0; int handshake_failure = 0; SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); return( ret ); } buf = ssl->in_hdr; #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) if( ( buf[0] & 0x80 ) != 0 ) return ssl_parse_client_hello_v2( ssl ); #endif SSL_DEBUG_BUF( 4, "record header", buf, 5 ); SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", buf[0] ) ); SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", ( buf[3] << 8 ) | buf[4] ) ); SSL_DEBUG_MSG( 3, ( "client hello v3, protocol ver: [%d:%d]", buf[1], buf[2] ) ); /* * SSLv3 Client Hello * * Record layer: * 0 . 0 message type * 1 . 2 protocol version * 3 . 4 message length */ if( buf[0] != SSL_MSG_HANDSHAKE || buf[1] != SSL_MAJOR_VERSION_3 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } n = ( buf[3] << 8 ) | buf[4]; if( n < 45 || n > 512 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && ( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); return( ret ); } buf = ssl->in_msg; if( !ssl->renegotiation ) n = ssl->in_left - 5; else n = ssl->in_msglen; ssl->handshake->update_checksum( ssl, buf, n ); /* * SSL layer: * 0 . 0 handshake type * 1 . 3 handshake length * 4 . 5 protocol version * 6 . 9 UNIX time() * 10 . 37 random bytes * 38 . 38 session id length * 39 . 38+x session id * 39+x . 40+x ciphersuitelist length * 41+x . .. ciphersuitelist * .. . .. compression alg. * .. . .. extensions */ SSL_DEBUG_BUF( 4, "record contents", buf, n ); SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); SSL_DEBUG_MSG( 3, ( "client hello v3, max. version: [%d:%d]", buf[4], buf[5] ) ); /* * Check the handshake type and protocol version */ if( buf[0] != SSL_HS_CLIENT_HELLO || buf[4] != SSL_MAJOR_VERSION_3 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->major_ver = SSL_MAJOR_VERSION_3; ssl->minor_ver = ( buf[5] <= SSL_MINOR_VERSION_3 ) ? buf[5] : SSL_MINOR_VERSION_3; if( ssl->minor_ver < ssl->min_minor_ver ) { SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, ssl->min_major_ver, ssl->min_minor_ver ) ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, SSL_ALERT_MSG_PROTOCOL_VERSION ); return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } ssl->max_major_ver = buf[4]; ssl->max_minor_ver = buf[5]; memcpy( ssl->handshake->randbytes, buf + 6, 32 ); /* * Check the handshake message length */ if( buf[1] != 0 || n != (unsigned int) 4 + ( ( buf[2] << 8 ) | buf[3] ) ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } /* * Check the session length */ sess_len = buf[38]; if( sess_len > 32 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->session_negotiate->length = sess_len; memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) ); memcpy( ssl->session_negotiate->id, buf + 39, ssl->session_negotiate->length ); /* * Check the ciphersuitelist length */ ciph_len = ( buf[39 + sess_len] << 8 ) | ( buf[40 + sess_len] ); if( ciph_len < 2 || ciph_len > 256 || ( ciph_len % 2 ) != 0 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } /* * Check the compression algorithms length */ comp_len = buf[41 + sess_len + ciph_len]; if( comp_len < 1 || comp_len > 16 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } /* * Check the extension length */ if( n > 42 + sess_len + ciph_len + comp_len ) { ext_len = ( buf[42 + sess_len + ciph_len + comp_len] << 8 ) | ( buf[43 + sess_len + ciph_len + comp_len] ); if( ( ext_len > 0 && ext_len < 4 ) || n != 44 + sess_len + ciph_len + comp_len + ext_len ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); SSL_DEBUG_BUF( 3, "Ext", buf + 44 + sess_len + ciph_len + comp_len, ext_len); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } ssl->session_negotiate->compression = SSL_COMPRESS_NULL; #if defined(POLARSSL_ZLIB_SUPPORT) for( i = 0; i < comp_len; ++i ) { if( buf[42 + sess_len + ciph_len + i] == SSL_COMPRESS_DEFLATE ) { ssl->session_negotiate->compression = SSL_COMPRESS_DEFLATE; break; } } #endif SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 ); SSL_DEBUG_BUF( 3, "client hello, session id", buf + 38, sess_len ); SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", buf + 41 + sess_len, ciph_len ); SSL_DEBUG_BUF( 3, "client hello, compression", buf + 42 + sess_len + ciph_len, comp_len ); /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 ) { if( p[0] == 0 && p[1] == SSL_EMPTY_RENEGOTIATION_INFO ) { SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); if( ssl->renegotiation == SSL_RENEGOTIATION ) { SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) return( ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; break; } } /* * Search for a matching ciphersuite */ for( i = 0; ssl->ciphersuites[ssl->minor_ver][i] != 0; i++ ) { for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 ) { if( p[0] == 0 && p[1] == ssl->ciphersuites[ssl->minor_ver][i] && ssl_get_ciphersuite_min_version( p[1] ) <= ssl->minor_ver ) goto have_ciphersuite; } } SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); have_ciphersuite: ssl->session_negotiate->ciphersuite = ssl->ciphersuites[ssl->minor_ver][i]; ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite ); ext = buf + 44 + sess_len + ciph_len + comp_len; while( ext_len ) { unsigned int ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); unsigned int ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); if( ext_size + 4 > ext_len ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } switch( ext_id ) { case TLS_EXT_SERVERNAME: SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); if( ssl->f_sni == NULL ) break; ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); if( ret != 0 ) return( ret ); break; case TLS_EXT_RENEGOTIATION_INFO: SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); renegotiation_info_seen = 1; ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); if( ret != 0 ) return( ret ); break; case TLS_EXT_SIG_ALG: SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); if( ssl->renegotiation == SSL_RENEGOTIATION ) break; ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); if( ret != 0 ) return( ret ); break; default: SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); } ext_len -= 4 + ext_size; ext += 4 + ext_size; if( ext_len > 0 && ext_len < 4 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } /* * Renegotiation security checks */ if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE ) { SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; } else if( ssl->renegotiation == SSL_RENEGOTIATION && ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION && renegotiation_info_seen == 0 ) { SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); handshake_failure = 1; } else if( ssl->renegotiation == SSL_RENEGOTIATION && ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION ) { SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; } else if( ssl->renegotiation == SSL_RENEGOTIATION && ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && renegotiation_info_seen == 1 ) { SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); handshake_failure = 1; } if( handshake_failure == 1 ) { if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) return( ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->in_left = 0; ssl->state++; SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); return( 0 ); }
static int ssl_parse_client_hello_v2( ssl_context *ssl ) { int ret; unsigned int i, j; size_t n; unsigned int ciph_len, sess_len, chal_len; unsigned char *buf, *p; SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ) { SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) return( ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } buf = ssl->in_hdr; SSL_DEBUG_BUF( 4, "record header", buf, 5 ); SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", buf[2] ) ); SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]", buf[3], buf[4] ) ); /* * SSLv2 Client Hello * * Record layer: * 0 . 1 message length * * SSL layer: * 2 . 2 message type * 3 . 4 protocol version */ if( buf[2] != SSL_HS_CLIENT_HELLO || buf[3] != SSL_MAJOR_VERSION_3 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; if( n < 17 || n > 512 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->major_ver = SSL_MAJOR_VERSION_3; ssl->minor_ver = ( buf[4] <= SSL_MINOR_VERSION_3 ) ? buf[4] : SSL_MINOR_VERSION_3; if( ssl->minor_ver < ssl->min_minor_ver ) { SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, ssl->min_major_ver, ssl->min_minor_ver ) ); ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, SSL_ALERT_MSG_PROTOCOL_VERSION ); return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } ssl->max_major_ver = buf[3]; ssl->max_minor_ver = buf[4]; if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); return( ret ); } ssl->handshake->update_checksum( ssl, buf + 2, n ); buf = ssl->in_msg; n = ssl->in_left - 5; /* * 0 . 1 ciphersuitelist length * 2 . 3 session id length * 4 . 5 challenge length * 6 . .. ciphersuitelist * .. . .. session id * .. . .. challenge */ SSL_DEBUG_BUF( 4, "record contents", buf, n ); ciph_len = ( buf[0] << 8 ) | buf[1]; sess_len = ( buf[2] << 8 ) | buf[3]; chal_len = ( buf[4] << 8 ) | buf[5]; SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", ciph_len, sess_len, chal_len ) ); /* * Make sure each parameter length is valid */ if( ciph_len < 3 || ( ciph_len % 3 ) != 0 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } if( sess_len > 32 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } if( chal_len < 8 || chal_len > 32 ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } if( n != 6 + ciph_len + sess_len + chal_len ) { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", buf + 6, ciph_len ); SSL_DEBUG_BUF( 3, "client hello, session id", buf + 6 + ciph_len, sess_len ); SSL_DEBUG_BUF( 3, "client hello, challenge", buf + 6 + ciph_len + sess_len, chal_len ); p = buf + 6 + ciph_len; ssl->session_negotiate->length = sess_len; memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) ); memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->length ); p += sess_len; memset( ssl->handshake->randbytes, 0, 64 ); memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) { if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO ) { SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); if( ssl->renegotiation == SSL_RENEGOTIATION ) { SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) return( ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; break; } } for( i = 0; ssl->ciphersuites[ssl->minor_ver][i] != 0; i++ ) { for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) { if( p[0] == 0 && p[1] == 0 && p[2] == ssl->ciphersuites[ssl->minor_ver][i] ) goto have_ciphersuite_v2; } } SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); have_ciphersuite_v2: ssl->session_negotiate->ciphersuite = ssl->ciphersuites[ssl->minor_ver][i]; ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite ); /* * SSLv2 Client Hello relevant renegotiation security checks */ if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE ) { SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) return( ret ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); } ssl->in_left = 0; ssl->state++; SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); return( 0 ); }