Merge commit 'f6080b8
' into dtls
* commit 'f6080b8
':
Fix warning in reduced configs
Adapt to "negative" switch for renego
Add tests for periodic renegotiation
Make renego period configurable
Auto-renegotiate before sequence number wrapping
Update Changelog for compile-option renegotiation
Switch from an enable to a disable flag
Save 48 bytes if SSLv3 is not defined
Make renegotiation a compile-time option
Add tests for renego security enforcement
Conflicts:
include/polarssl/ssl.h
library/ssl_cli.c
library/ssl_srv.c
library/ssl_tls.c
programs/ssl/ssl_server2.c
tests/ssl-opt.sh
This commit is contained in:
commit
0af1ba3521
14 changed files with 492 additions and 91 deletions
|
@ -114,6 +114,7 @@ static void ssl_write_hostname_ext( ssl_context *ssl,
|
|||
}
|
||||
#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
static void ssl_write_renegotiation_ext( ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
size_t *olen )
|
||||
|
@ -141,6 +142,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl,
|
|||
|
||||
*olen = 5 + ssl->verify_data_len;
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
/*
|
||||
* Only if we handle at least one key exchange that needs signatures.
|
||||
|
@ -562,7 +564,9 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
return( POLARSSL_ERR_SSL_NO_RNG );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
{
|
||||
ssl->major_ver = ssl->min_major_ver;
|
||||
ssl->minor_ver = ssl->min_minor_ver;
|
||||
|
@ -615,7 +619,10 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
*/
|
||||
n = ssl->session_negotiate->length;
|
||||
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE || n < 16 || n > 32 ||
|
||||
if( n < 16 || n > 32 ||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->renegotiation != SSL_INITIAL_HANDSHAKE ||
|
||||
#endif
|
||||
ssl->handshake->resume == 0 )
|
||||
{
|
||||
n = 0;
|
||||
|
@ -626,8 +633,10 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
* RFC 5077 section 3.4: "When presenting a ticket, the client MAY
|
||||
* generate and include a Session ID in the TLS ClientHello."
|
||||
*/
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
|
||||
ssl->session_negotiate->ticket != NULL &&
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
if( ssl->session_negotiate->ticket != NULL &&
|
||||
ssl->session_negotiate->ticket_len != 0 )
|
||||
{
|
||||
ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 );
|
||||
|
@ -682,8 +691,12 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
q = p;
|
||||
p += 2;
|
||||
|
||||
/* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
|
||||
/*
|
||||
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
|
||||
*/
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
{
|
||||
*p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
|
||||
*p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO );
|
||||
|
@ -775,8 +788,10 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
ext_len += olen;
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
|
||||
ext_len += olen;
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||
|
@ -822,6 +837,9 @@ static int ssl_write_client_hello( ssl_context *ssl )
|
|||
ext_len += olen;
|
||||
#endif
|
||||
|
||||
/* olen unused if all extensions are disabled */
|
||||
((void) olen);
|
||||
|
||||
SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
|
||||
ext_len ) );
|
||||
|
||||
|
@ -860,21 +878,8 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
if( len != 1 || buf[0] != 0x0 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-zero length renegotiated connection field" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
|
||||
}
|
||||
|
||||
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
|
||||
}
|
||||
else
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
/* Check verify-data in constant-time. The length OTOH is no secret */
|
||||
if( len != 1 + ssl->verify_data_len * 2 ||
|
||||
|
@ -884,7 +889,7 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||
safer_memcmp( buf + 1 + ssl->verify_data_len,
|
||||
ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-matching renegotiated connection field" ) );
|
||||
SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
@ -892,6 +897,21 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
{
|
||||
if( len != 1 || buf[0] != 0x00 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
|
||||
}
|
||||
|
||||
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -1150,7 +1170,9 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
size_t ext_len;
|
||||
unsigned char *buf, *ext;
|
||||
unsigned char comp, accept_comp;
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
int renegotiation_info_seen = 0;
|
||||
#endif
|
||||
int handshake_failure = 0;
|
||||
#if defined(POLARSSL_DEBUG_C)
|
||||
uint32_t t;
|
||||
|
@ -1168,6 +1190,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
|
||||
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
|
||||
{
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_RENEGOTIATION )
|
||||
{
|
||||
ssl->renego_records_seen++;
|
||||
|
@ -1183,6 +1206,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
|
||||
return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
|
||||
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
|
||||
|
@ -1336,8 +1360,10 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
/*
|
||||
* Check if the session can be resumed
|
||||
*/
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ||
|
||||
ssl->handshake->resume == 0 || n == 0 ||
|
||||
if( ssl->handshake->resume == 0 || n == 0 ||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->renegotiation != SSL_INITIAL_HANDSHAKE ||
|
||||
#endif
|
||||
ssl->session_negotiate->ciphersuite != i ||
|
||||
ssl->session_negotiate->compression != comp ||
|
||||
ssl->session_negotiate->length != n ||
|
||||
|
@ -1418,7 +1444,9 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
{
|
||||
case TLS_EXT_RENEGOTIATION_INFO:
|
||||
SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
renegotiation_info_seen = 1;
|
||||
#endif
|
||||
|
||||
if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
|
||||
ext_size ) ) != 0 )
|
||||
|
@ -1538,6 +1566,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
|
||||
handshake_failure = 1;
|
||||
}
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
else if( ssl->renegotiation == SSL_RENEGOTIATION &&
|
||||
ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
|
||||
renegotiation_info_seen == 0 )
|
||||
|
@ -1559,6 +1588,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
|
|||
SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
|
||||
handshake_failure = 1;
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
if( handshake_failure == 1 )
|
||||
{
|
||||
|
|
|
@ -461,11 +461,29 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
/* Check verify-data in constant-time. The length OTOH is no secret */
|
||||
if( len != 1 + ssl->verify_data_len ||
|
||||
buf[0] != ssl->verify_data_len ||
|
||||
safer_memcmp( buf + 1, ssl->peer_verify_data,
|
||||
ssl->verify_data_len ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
{
|
||||
if( len != 1 || buf[0] != 0x0 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-zero length renegotiated connection field" ) );
|
||||
SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
@ -475,22 +493,6 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||
|
||||
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check verify-data in constant-time. The length OTOH is no secret */
|
||||
if( len != 1 + ssl->verify_data_len ||
|
||||
buf[0] != ssl->verify_data_len ||
|
||||
safer_memcmp( buf + 1, ssl->peer_verify_data,
|
||||
ssl->verify_data_len ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "non-matching renegotiated connection field" ) );
|
||||
|
||||
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -731,11 +733,13 @@ static int ssl_parse_session_ticket_ext( ssl_context *ssl,
|
|||
if( len == 0 )
|
||||
return( 0 );
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
/*
|
||||
* Failures are ok: just ignore the ticket and proceed.
|
||||
|
@ -977,6 +981,7 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
|
|||
|
||||
SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
|
||||
|
@ -986,6 +991,7 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
|
|||
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
buf = ssl->in_hdr;
|
||||
|
||||
|
@ -1122,15 +1128,18 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
|
|||
if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO )
|
||||
{
|
||||
SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_RENEGOTIATION )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during 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 );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
|
||||
break;
|
||||
}
|
||||
|
@ -1228,7 +1237,9 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||
unsigned int cookie_offset, cookie_len;
|
||||
#endif
|
||||
unsigned char *buf, *p, *ext;
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
int renegotiation_info_seen = 0;
|
||||
#endif
|
||||
int handshake_failure = 0;
|
||||
const int *ciphersuites;
|
||||
const ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
@ -1244,8 +1255,10 @@ read_record_header:
|
|||
* otherwise read it ourselves manually in order to support SSLv2
|
||||
* ClientHello, which doesn't use the same record layer format.
|
||||
*/
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
|
||||
( ret = ssl_fetch_input( ssl, ssl_hdr_len( ssl ) ) ) != 0 )
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
|
||||
return( ret );
|
||||
|
@ -1331,7 +1344,9 @@ read_record_header:
|
|||
|
||||
msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
|
||||
#endif
|
||||
{
|
||||
if( msg_len > SSL_MAX_CONTENT_LEN )
|
||||
{
|
||||
|
@ -1698,7 +1713,9 @@ read_record_header:
|
|||
|
||||
case TLS_EXT_RENEGOTIATION_INFO:
|
||||
SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
renegotiation_info_seen = 1;
|
||||
#endif
|
||||
|
||||
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
|
||||
if( ret != 0 )
|
||||
|
@ -1709,8 +1726,10 @@ read_record_header:
|
|||
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||
case TLS_EXT_SIG_ALG:
|
||||
SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_RENEGOTIATION )
|
||||
break;
|
||||
#endif
|
||||
|
||||
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
|
||||
if( ret != 0 )
|
||||
|
@ -1861,12 +1880,13 @@ read_record_header:
|
|||
/*
|
||||
* Renegotiation security checks
|
||||
*/
|
||||
if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
|
||||
if( ssl->secure_renegotiation != SSL_SECURE_RENEGOTIATION &&
|
||||
ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
|
||||
handshake_failure = 1;
|
||||
}
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
else if( ssl->renegotiation == SSL_RENEGOTIATION &&
|
||||
ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
|
||||
renegotiation_info_seen == 0 )
|
||||
|
@ -1888,6 +1908,7 @@ read_record_header:
|
|||
SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
|
||||
handshake_failure = 1;
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
if( handshake_failure == 1 )
|
||||
{
|
||||
|
@ -2088,16 +2109,29 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl,
|
|||
*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;
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
|
||||
{
|
||||
*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;
|
||||
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;
|
||||
|
||||
*olen = 5 + ssl->verify_data_len * 2;
|
||||
*olen = 5 + ssl->verify_data_len * 2;
|
||||
}
|
||||
else
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
{
|
||||
*p++ = 0x00;
|
||||
*p++ = 0x01;
|
||||
*p++ = 0x00;
|
||||
|
||||
*olen = 5;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
|
||||
|
@ -2331,7 +2365,9 @@ static int ssl_write_server_hello( ssl_context *ssl )
|
|||
* If not, try looking up session ID in our cache.
|
||||
*/
|
||||
if( ssl->handshake->resume == 0 &&
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
|
||||
#endif
|
||||
ssl->session_negotiate->length != 0 &&
|
||||
ssl->f_get_cache != NULL &&
|
||||
ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 )
|
||||
|
|
|
@ -3942,7 +3942,7 @@ int ssl_parse_certificate( ssl_context *ssl )
|
|||
* On client, make sure the server cert doesn't change during renego to
|
||||
* avoid "triple handshake" attack: https://secure-resumption.com/
|
||||
*/
|
||||
#if defined(POLARSSL_SSL_CLI_C)
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION) && defined(POLARSSL_SSL_CLI_C)
|
||||
if( ssl->endpoint == SSL_IS_CLIENT &&
|
||||
ssl->renegotiation == SSL_RENEGOTIATION )
|
||||
{
|
||||
|
@ -3962,7 +3962,7 @@ int ssl_parse_certificate( ssl_context *ssl )
|
|||
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
|
||||
}
|
||||
}
|
||||
#endif /* POLARSSL_SSL_CLI_C */
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION && POLARSSL_SSL_CLI_C */
|
||||
|
||||
if( ssl->authmode != SSL_VERIFY_NONE )
|
||||
{
|
||||
|
@ -4488,11 +4488,13 @@ void ssl_handshake_wrapup( ssl_context *ssl )
|
|||
|
||||
SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->renegotiation == SSL_RENEGOTIATION )
|
||||
{
|
||||
ssl->renegotiation = SSL_RENEGOTIATION_DONE;
|
||||
ssl->renego_records_seen = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Free the previous session and switch in the current one
|
||||
|
@ -4564,8 +4566,10 @@ int ssl_write_finished( ssl_context *ssl )
|
|||
// TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
|
||||
hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12;
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->verify_data_len = hash_len;
|
||||
memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
|
||||
#endif
|
||||
|
||||
ssl->out_msglen = 4 + hash_len;
|
||||
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
|
||||
|
@ -4703,8 +4707,10 @@ int ssl_parse_finished( ssl_context *ssl )
|
|||
return( POLARSSL_ERR_SSL_BAD_HS_FINISHED );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->verify_data_len = hash_len;
|
||||
memcpy( ssl->peer_verify_data, buf, hash_len );
|
||||
#endif
|
||||
|
||||
if( ssl->handshake->resume != 0 )
|
||||
{
|
||||
|
@ -4904,7 +4910,11 @@ int ssl_init( ssl_context *ssl )
|
|||
|
||||
ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT;
|
||||
memset( ssl->renego_period, 0xFF, 7 );
|
||||
ssl->renego_period[7] = 0x00;
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
|
||||
|
@ -4984,12 +4994,16 @@ int ssl_session_reset( ssl_context *ssl )
|
|||
int ret;
|
||||
|
||||
ssl->state = SSL_HELLO_REQUEST;
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
ssl->renegotiation = SSL_INITIAL_HANDSHAKE;
|
||||
ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
|
||||
ssl->renego_records_seen = 0;
|
||||
|
||||
ssl->verify_data_len = 0;
|
||||
memset( ssl->own_verify_data, 0, 36 );
|
||||
memset( ssl->peer_verify_data, 0, 36 );
|
||||
memset( ssl->own_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
|
||||
memset( ssl->peer_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
|
||||
#endif
|
||||
ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
|
||||
|
||||
ssl->in_offt = NULL;
|
||||
|
||||
|
@ -5017,8 +5031,6 @@ int ssl_session_reset( ssl_context *ssl )
|
|||
ssl->transform_in = NULL;
|
||||
ssl->transform_out = NULL;
|
||||
|
||||
ssl->renego_records_seen = 0;
|
||||
|
||||
memset( ssl->out_buf, 0, SSL_BUFFER_LEN );
|
||||
memset( ssl->in_buf, 0, SSL_BUFFER_LEN );
|
||||
|
||||
|
@ -5685,21 +5697,29 @@ int ssl_set_truncated_hmac( ssl_context *ssl, int truncate )
|
|||
}
|
||||
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */
|
||||
|
||||
void ssl_set_renegotiation( ssl_context *ssl, int renegotiation )
|
||||
{
|
||||
ssl->disable_renegotiation = renegotiation;
|
||||
}
|
||||
|
||||
void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
|
||||
{
|
||||
ssl->allow_legacy_renegotiation = allow_legacy;
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
void ssl_set_renegotiation( ssl_context *ssl, int renegotiation )
|
||||
{
|
||||
ssl->disable_renegotiation = renegotiation;
|
||||
}
|
||||
|
||||
void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records )
|
||||
{
|
||||
ssl->renego_max_records = max_records;
|
||||
}
|
||||
|
||||
void ssl_set_renegotiation_period( ssl_context *ssl,
|
||||
const unsigned char period[8] )
|
||||
{
|
||||
memcpy( ssl->renego_period, period, 8 );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||
int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
|
||||
{
|
||||
|
@ -5884,6 +5904,7 @@ int ssl_handshake( ssl_context *ssl )
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
#if defined(POLARSSL_SSL_SRV_C)
|
||||
/*
|
||||
* Write HelloRequest to request renegotiation on server
|
||||
|
@ -6009,6 +6030,30 @@ int ssl_renegotiate( ssl_context *ssl )
|
|||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check record counters and renegotiate if they're above the limit.
|
||||
*/
|
||||
static int ssl_check_ctr_renegotiate( ssl_context *ssl )
|
||||
{
|
||||
if( ssl->state != SSL_HANDSHAKE_OVER ||
|
||||
ssl->renegotiation == SSL_RENEGOTIATION_PENDING ||
|
||||
ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
// TODO: adapt for DTLS
|
||||
if( memcmp( ssl->in_ctr, ssl->renego_period, 8 ) <= 0 &&
|
||||
memcmp( ssl->out_ctr, ssl->renego_period, 8 ) <= 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
SSL_DEBUG_MSG( 0, ( "record counter limit reached: renegotiate" ) );
|
||||
return( ssl_renegotiate( ssl ) );
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
/*
|
||||
* Receive application data decrypted from the SSL layer
|
||||
*/
|
||||
|
@ -6034,6 +6079,14 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ssl->state != SSL_HANDSHAKE_OVER )
|
||||
{
|
||||
ret = ssl_handshake( ssl );
|
||||
|
@ -6084,6 +6137,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
|
||||
|
@ -6194,6 +6248,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* POLARSSL_SSL_RENEGOTIATION */
|
||||
|
||||
/* Fatal and closure alerts handled by ssl_read_record() */
|
||||
if( ssl->in_msgtype == SSL_MSG_ALERT )
|
||||
|
@ -6263,6 +6318,14 @@ int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len )
|
|||
|
||||
SSL_DEBUG_MSG( 2, ( "=> write" ) );
|
||||
|
||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||
if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
|
||||
{
|
||||
SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ssl->state != SSL_HANDSHAKE_OVER )
|
||||
{
|
||||
if( ( ret = ssl_handshake( ssl ) ) != 0 )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue