1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-08-07 06:42:56 +03:00

Merge support for enabling / disabling renegotiation support at compile-time

This commit is contained in:
Paul Bakker
2015-01-13 16:18:23 +01:00
14 changed files with 498 additions and 95 deletions

View File

@@ -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.
@@ -521,7 +523,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;
@@ -585,7 +589,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;
@@ -596,8 +603,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 );
@@ -627,7 +636,9 @@ static int ssl_write_client_hello( ssl_context *ssl )
/*
* 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 );
@@ -693,8 +704,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)
@@ -740,6 +753,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 ) );
@@ -773,21 +789,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 ||
@@ -797,7 +800,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 );
@@ -805,6 +808,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 );
}
@@ -996,7 +1014,9 @@ static int ssl_parse_server_hello( ssl_context *ssl )
size_t n;
size_t ext_len;
unsigned char *buf, *ext;
#if defined(POLARSSL_SSL_RENEGOTIATION)
int renegotiation_info_seen = 0;
#endif
int handshake_failure = 0;
#if defined(POLARSSL_DEBUG_C)
uint32_t t;
@@ -1021,6 +1041,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++;
@@ -1036,6 +1057,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 );
@@ -1144,8 +1166,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 ||
@@ -1226,7 +1250,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 )
@@ -1346,6 +1372,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 )
@@ -1367,6 +1394,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 )
{

View File

@@ -431,11 +431,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 );
@@ -445,22 +463,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 );
}
@@ -701,11 +703,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.
@@ -941,6 +945,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" ) );
@@ -950,6 +955,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;
@@ -1086,15 +1092,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;
}
@@ -1191,15 +1200,19 @@ static int ssl_parse_client_hello( ssl_context *ssl )
unsigned int comp_len;
unsigned int ext_len = 0;
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;
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
( ret = ssl_fetch_input( ssl, 5 ) ) != 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 );
@@ -1249,18 +1262,22 @@ static int ssl_parse_client_hello( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 )
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
if( ( 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
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
n = ssl->in_msglen;
else
#endif
n = ssl->in_left - 5;
ssl->handshake->update_checksum( ssl, buf, n );
@@ -1423,6 +1440,7 @@ static int ssl_parse_client_hello( ssl_context *ssl )
if( p[0] == 0 && p[1] == 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" ) );
@@ -1432,6 +1450,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
renegotiation_info_seen = 1;
#endif /* POLARSSL_SSL_RENEGOTIATION */
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
break;
}
@@ -1490,7 +1510,9 @@ static int ssl_parse_client_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
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
if( ret != 0 )
@@ -1501,8 +1523,10 @@ static int ssl_parse_client_hello( ssl_context *ssl )
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 )
@@ -1608,12 +1632,13 @@ static int ssl_parse_client_hello( ssl_context *ssl )
/*
* 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 )
@@ -1635,6 +1660,7 @@ static int ssl_parse_client_hello( ssl_context *ssl )
SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
handshake_failure = 1;
}
#endif /* POLARSSL_SSL_RENEGOTIATION */
if( handshake_failure == 1 )
{
@@ -1831,16 +1857,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)
@@ -1999,7 +2038,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 )

View File

@@ -2797,7 +2797,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 )
{
@@ -2817,7 +2817,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 )
{
@@ -3260,11 +3260,13 @@ void ssl_handshake_wrapup( ssl_context *ssl )
polarssl_free( ssl->handshake );
ssl->handshake = NULL;
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_RENEGOTIATION )
{
ssl->renegotiation = SSL_RENEGOTIATION_DONE;
ssl->renego_records_seen = 0;
}
#endif
/*
* Switch in our now active transform context
@@ -3329,8 +3331,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;
@@ -3454,8 +3458,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 )
{
@@ -3607,7 +3613,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,
@@ -3681,12 +3691,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;
@@ -3707,8 +3721,6 @@ int ssl_session_reset( ssl_context *ssl )
ssl->transform_in = NULL;
ssl->transform_out = NULL;
ssl->renego_records_seen = 0;
memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
@@ -4251,21 +4263,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 )
{
@@ -4400,6 +4420,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
@@ -4512,6 +4533,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
*/
@@ -4522,6 +4567,14 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
SSL_DEBUG_MSG( 2, ( "=> read" ) );
#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 );
@@ -4566,6 +4619,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" ) );
@@ -4648,6 +4702,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
}
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* Fatal and closure alerts handled by ssl_read_record() */
if( ssl->in_msgtype == SSL_MSG_ALERT )
@@ -4694,6 +4749,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 )