diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index cfd987b41..5969cf939 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -830,6 +830,8 @@ struct _ssl_context #if defined(POLARSSL_SSL_RENEGOTIATION) int disable_renegotiation; /*!< enable/disable renegotiation */ int renego_max_records; /*!< grace period for renegotiation */ + unsigned char renego_period[8]; /*!< value of the record counters + that triggers renegotiation */ #endif int allow_legacy_renegotiation; /*!< allow legacy renegotiation */ const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */ @@ -1543,6 +1545,26 @@ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ); * it but allow for a grace period of max_records records. */ void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records ); + +/** + * \brief Set record counter threshold for periodic renegotiation. + * (Default: 2^64 - 256.) + * + * Renegotiation is automatically triggered when a record + * counter (outgoing or ingoing) crosses the defined + * threshold. The default value is meant to prevent the + * connection from being closed when the counter is about to + * reached its maximal value (it is not allowed to wrap). + * + * Lower values can be used to enforce policies such as "keys + * must be refreshed every N packets with cipher X". + * + * \param ssl SSL context + * \param period The threshold value: a big-endian 64-bit number. + * Set to 2^64 - 1 to disable periodic renegotiation + */ +void ssl_set_renegotiation_period( ssl_context *ssl, + const unsigned char period[8] ); #endif /* POLARSSL_SSL_RENEGOTIATION */ /** diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 0e97c1110..3d16e1c9b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3404,6 +3404,8 @@ int ssl_init( ssl_context *ssl ) #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) @@ -4031,6 +4033,12 @@ 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) @@ -4279,10 +4287,6 @@ int ssl_renegotiate( ssl_context *ssl ) */ static int ssl_check_ctr_renegotiate( ssl_context *ssl ) { - static const unsigned char ctr_limit[8] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 - }; - if( ssl->state != SSL_HANDSHAKE_OVER || ssl->renegotiation == SSL_RENEGOTIATION_PENDING || ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED ) @@ -4291,13 +4295,13 @@ static int ssl_check_ctr_renegotiate( ssl_context *ssl ) } // TODO: adapt for DTLS - if( memcmp( ssl->in_ctr, ctr_limit, 8 ) <= 0 && - memcmp( ssl->out_ctr, ctr_limit, 8 ) <= 0 ) + if( memcmp( ssl->in_ctr, ssl->renego_period, 8 ) <= 0 && + memcmp( ssl->out_ctr, ssl->renego_period, 8 ) <= 0 ) { return( 0 ); } - SSL_DEBUG_MSG( 2, ( "record counter about to wrap: renegotiate" ) ); + SSL_DEBUG_MSG( 0, ( "record counter limit reached: renegotiate" ) ); return( ssl_renegotiate( ssl ) ); } #endif /* POLARSSL_SSL_RENEGOTIATION */