Add ssl_set_renegotiation_enforced()

This commit is contained in:
Manuel Pégourié-Gonnard 2014-07-03 19:29:16 +02:00
parent 31855456f9
commit a9964dbcd5
3 changed files with 55 additions and 5 deletions

View File

@ -221,6 +221,9 @@
#define SSL_RENEGOTIATION_DISABLED 0 #define SSL_RENEGOTIATION_DISABLED 0
#define SSL_RENEGOTIATION_ENABLED 1 #define SSL_RENEGOTIATION_ENABLED 1
#define SSL_RENEGOTIATION_NOT_ENFORCED -1
#define SSL_RENEGO_MAX_RECORDS_DEFAULT 16
#define SSL_LEGACY_NO_RENEGOTIATION 0 #define SSL_LEGACY_NO_RENEGOTIATION 0
#define SSL_LEGACY_ALLOW_RENEGOTIATION 1 #define SSL_LEGACY_ALLOW_RENEGOTIATION 1
#define SSL_LEGACY_BREAK_HANDSHAKE 2 #define SSL_LEGACY_BREAK_HANDSHAKE 2
@ -620,6 +623,7 @@ struct _ssl_context
*/ */
int state; /*!< SSL handshake: current state */ int state; /*!< SSL handshake: current state */
int renegotiation; /*!< Initial or renegotiation */ int renegotiation; /*!< Initial or renegotiation */
int renego_records_seen; /*!< Records since renego request */
int major_ver; /*!< equal to SSL_MAJOR_VERSION_3 */ int major_ver; /*!< equal to SSL_MAJOR_VERSION_3 */
int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */
@ -744,6 +748,7 @@ struct _ssl_context
int verify_result; /*!< verification result */ int verify_result; /*!< verification result */
int disable_renegotiation; /*!< enable/disable renegotiation */ int disable_renegotiation; /*!< enable/disable renegotiation */
int allow_legacy_renegotiation; /*!< allow legacy renegotiation */ int allow_legacy_renegotiation; /*!< allow legacy renegotiation */
int renego_max_records; /*!< grace period for renegotiation */
const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */ const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */
#if defined(POLARSSL_SSL_SET_CURVES) #if defined(POLARSSL_SSL_SET_CURVES)
const ecp_group_id *curve_list; /*!< allowed curves */ const ecp_group_id *curve_list; /*!< allowed curves */
@ -1421,6 +1426,33 @@ void ssl_set_renegotiation( ssl_context *ssl, int renegotiation );
*/ */
void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ); void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy );
/**
* \brief Enforce server-requested renegotiation.
* (Default: enforced, max_records = 16)
* (No effect on client.)
*
* When a server requests a renegotiation, the client can
* comply or ignore the request. This function allows the
* server to decide if it should enforce its renegotiation
* requests by closing the connection if the client doesn't
* initiate a renegotiation.
*
* However, records could already be in transit from the
* client to the server when the request is emitted. In order
* to increase reliability, the server can accept a number of
* records containing application data before the ClientHello
* that was requested.
*
* The optimal value is highly dependent on the specific usage
* scenario.
*
* \param ssl SSL context
* \param max_records Use SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
* enforce renegotiation, or a non-negative value to enforce
* it but allow for a grace period of max_records records.
*/
void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records );
/** /**
* \brief Return the number of data bytes available to read * \brief Return the number of data bytes available to read
* *

View File

@ -3055,7 +3055,10 @@ void ssl_handshake_wrapup( ssl_context *ssl )
ssl->handshake = NULL; ssl->handshake = NULL;
if( ssl->renegotiation == SSL_RENEGOTIATION ) if( ssl->renegotiation == SSL_RENEGOTIATION )
{
ssl->renegotiation = SSL_RENEGOTIATION_DONE; ssl->renegotiation = SSL_RENEGOTIATION_DONE;
ssl->renego_records_seen = 0;
}
/* /*
* Switch in our now active transform context * Switch in our now active transform context
@ -3345,6 +3348,8 @@ int ssl_init( ssl_context *ssl )
ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT;
#if defined(POLARSSL_DHM_C) #if defined(POLARSSL_DHM_C)
if( ( ret = mpi_read_string( &ssl->dhm_P, 16, if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 || POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 ||
@ -3435,6 +3440,8 @@ int ssl_session_reset( ssl_context *ssl )
ssl->transform_in = NULL; ssl->transform_in = NULL;
ssl->transform_out = NULL; ssl->transform_out = NULL;
ssl->renego_records_seen = 0;
memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
memset( ssl->in_ctr, 0, SSL_BUFFER_LEN ); memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
@ -3952,6 +3959,11 @@ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
ssl->allow_legacy_renegotiation = allow_legacy; ssl->allow_legacy_renegotiation = allow_legacy;
} }
void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records )
{
ssl->renego_max_records = max_records;
}
#if defined(POLARSSL_SSL_SESSION_TICKETS) #if defined(POLARSSL_SSL_SESSION_TICKETS)
int ssl_set_session_tickets( ssl_context *ssl, int use_tickets ) int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
{ {
@ -4296,9 +4308,15 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
} }
else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING ) else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
{ {
SSL_DEBUG_MSG( 1, ( "renegotiation requested, " ssl->renego_records_seen++;
"but not honored by client" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); if( ssl->renego_max_records >= 0 &&
ssl->renego_records_seen > ssl->renego_max_records )
{
SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
"but not honored by client" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
} }
else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA ) else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
{ {

View File

@ -630,8 +630,8 @@ run_test "Renegotiation #5 (server-initiated, client-rejected)" \
-C "=> renegotiate" \ -C "=> renegotiate" \
-S "=> renegotiate" \ -S "=> renegotiate" \
-s "write hello request" \ -s "write hello request" \
-s "SSL - An unexpected message was received from our peer" \ -S "SSL - An unexpected message was received from our peer" \
-s "failed" -S "failed"
# Tests for auth_mode # Tests for auth_mode