Merge support for enabling / disabling renegotiation support at compile-time
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7eec364..91ce32d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2797,7 +2797,7 @@
* 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 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 @@
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 @@
}
#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 @@
return( ret );
}
+#if defined(POLARSSL_SSL_RENEGOTIATION)
#if defined(POLARSSL_SSL_SRV_C)
/*
* Write HelloRequest to request renegotiation on server
@@ -4513,6 +4534,30 @@
}
/*
+ * 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
*/
int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
@@ -4522,6 +4567,14 @@
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 @@
}
}
+#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
@@ -4648,6 +4702,7 @@
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 @@
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 )