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
commit f6080b8557
14 changed files with 498 additions and 95 deletions

View file

@ -27,6 +27,7 @@ Features
* Add x509_crl_parse_der(). * Add x509_crl_parse_der().
* Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the * Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the
length of an X.509 verification chain. length of an X.509 verification chain.
* Support for renegotiation can now be disabled at compile-time
Bugfix Bugfix
* Stack buffer overflow if ctr_drbg_update() is called with too large * Stack buffer overflow if ctr_drbg_update() is called with too large

View file

@ -19,6 +19,7 @@
/* PolarSSL feature support */ /* PolarSSL feature support */
#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED #define POLARSSL_KEY_EXCHANGE_PSK_ENABLED
#define POLARSSL_SSL_PROTO_TLS1_2 #define POLARSSL_SSL_PROTO_TLS1_2
#define POLARSSL_SSL_DISABLE_RENEGOTIATION
/* PolarSSL modules */ /* PolarSSL modules */
#define POLARSSL_AES_C #define POLARSSL_AES_C

View file

@ -18,6 +18,7 @@
#define POLARSSL_PKCS1_V15 #define POLARSSL_PKCS1_V15
#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED #define POLARSSL_KEY_EXCHANGE_RSA_ENABLED
#define POLARSSL_SSL_PROTO_TLS1_1 #define POLARSSL_SSL_PROTO_TLS1_1
#define POLARSSL_SSL_DISABLE_RENEGOTIATION
/* PolarSSL modules */ /* PolarSSL modules */
#define POLARSSL_AES_C #define POLARSSL_AES_C

View file

@ -19,6 +19,7 @@
/* PolarSSL feature support */ /* PolarSSL feature support */
#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED #define POLARSSL_KEY_EXCHANGE_PSK_ENABLED
#define POLARSSL_SSL_PROTO_TLS1 #define POLARSSL_SSL_PROTO_TLS1
#define POLARSSL_SSL_DISABLE_RENEGOTIATION
/* PolarSSL modules */ /* PolarSSL modules */
#define POLARSSL_AES_C #define POLARSSL_AES_C

View file

@ -25,6 +25,7 @@
#define POLARSSL_ECP_DP_SECP384R1_ENABLED #define POLARSSL_ECP_DP_SECP384R1_ENABLED
#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define POLARSSL_SSL_PROTO_TLS1_2 #define POLARSSL_SSL_PROTO_TLS1_2
#define POLARSSL_SSL_DISABLE_RENEGOTIATION
/* PolarSSL modules */ /* PolarSSL modules */
#define POLARSSL_AES_C #define POLARSSL_AES_C

View file

@ -886,6 +886,24 @@
*/ */
//#define POLARSSL_SSL_HW_RECORD_ACCEL //#define POLARSSL_SSL_HW_RECORD_ACCEL
/**
* \def POLARSSL_SSL_DISABLE_RENEGOTIATION
*
* Disable support for TLS renegotiation.
*
* The two main uses of renegotiation are (1) refresh keys on long-lived
* connections and (2) client authentication after the initial handshake.
* If you don't need renegotiation, it's probably better to disable it, since
* it has been associated with security issues in the past and is easy to
* misuse/misunderstand.
*
* Warning: in the next stable branch, this switch will be replaced by
* POLARSSL_SSL_RENEGOTIATION to enable support for renegotiation.
*
* Uncomment this to disable support for renegotiation.
*/
//#define POLARSSL_SSL_DISABLE_RENEGOTIATION
/** /**
* \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
* *

View file

@ -32,6 +32,12 @@
#else #else
#include POLARSSL_CONFIG_FILE #include POLARSSL_CONFIG_FILE
#endif #endif
/* Temporary compatibility trick for the current stable branch */
#if !defined(POLARSSL_SSL_DISABLE_RENEGOTIATION)
#define POLARSSL_SSL_RENEGOTIATION
#endif
#include "net.h" #include "net.h"
#include "bignum.h" #include "bignum.h"
#include "ecp.h" #include "ecp.h"
@ -313,6 +319,15 @@
+ SSL_PADDING_ADD \ + SSL_PADDING_ADD \
) )
/*
* Length of the verify data for secure renegotiation
*/
#if defined(POLARSSL_SSL_PROTO_SSL3)
#define SSL_VERIFY_DATA_MAX_LEN 36
#else
#define SSL_VERIFY_DATA_MAX_LEN 12
#endif
/* /*
* Signaling ciphersuite values (SCSV) * Signaling ciphersuite values (SCSV)
*/ */
@ -708,7 +723,9 @@ 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 */
#if defined(POLARSSL_SSL_RENEGOTIATION)
int renego_records_seen; /*!< Records since renego request */ int renego_records_seen; /*!< Records since renego request */
#endif
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) */
@ -841,9 +858,13 @@ struct _ssl_context
int authmode; /*!< verification mode */ int authmode; /*!< verification mode */
int client_auth; /*!< flag for client auth. */ int client_auth; /*!< flag for client auth. */
int verify_result; /*!< verification result */ int verify_result; /*!< verification result */
#if defined(POLARSSL_SSL_RENEGOTIATION)
int disable_renegotiation; /*!< enable/disable renegotiation */ int disable_renegotiation; /*!< enable/disable renegotiation */
int allow_legacy_renegotiation; /*!< allow legacy renegotiation */
int renego_max_records; /*!< grace period for 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 */ 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 */
@ -892,9 +913,11 @@ struct _ssl_context
*/ */
int secure_renegotiation; /*!< does peer support legacy or int secure_renegotiation; /*!< does peer support legacy or
secure renegotiation */ secure renegotiation */
#if defined(POLARSSL_SSL_RENEGOTIATION)
size_t verify_data_len; /*!< length of verify data stored */ size_t verify_data_len; /*!< length of verify data stored */
char own_verify_data[36]; /*!< previous handshake verify data */ char own_verify_data[SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
char peer_verify_data[36]; /*!< previous handshake verify data */ char peer_verify_data[SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
#endif
}; };
#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
@ -1534,6 +1557,7 @@ int ssl_set_session_tickets( ssl_context *ssl, int use_tickets );
void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime ); void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime );
#endif /* POLARSSL_SSL_SESSION_TICKETS */ #endif /* POLARSSL_SSL_SESSION_TICKETS */
#if defined(POLARSSL_SSL_RENEGOTIATION)
/** /**
* \brief Enable / Disable renegotiation support for connection when * \brief Enable / Disable renegotiation support for connection when
* initiated by peer * initiated by peer
@ -1548,6 +1572,7 @@ void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime );
* SSL_RENEGOTIATION_DISABLED) * SSL_RENEGOTIATION_DISABLED)
*/ */
void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ); void ssl_set_renegotiation( ssl_context *ssl, int renegotiation );
#endif /* POLARSSL_SSL_RENEGOTIATION */
/** /**
* \brief Prevent or allow legacy renegotiation. * \brief Prevent or allow legacy renegotiation.
@ -1578,8 +1603,9 @@ 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 );
#if defined(POLARSSL_SSL_RENEGOTIATION)
/** /**
* \brief Enforce server-requested renegotiation. * \brief Enforce requested renegotiation.
* (Default: enforced, max_records = 16) * (Default: enforced, max_records = 16)
* *
* When we request a renegotiation, the peer can comply or * When we request a renegotiation, the peer can comply or
@ -1608,6 +1634,27 @@ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy );
*/ */
void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_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 */
/** /**
* \brief Return the number of data bytes available to read * \brief Return the number of data bytes available to read
* *
@ -1710,6 +1757,7 @@ int ssl_handshake( ssl_context *ssl );
*/ */
int ssl_handshake_step( ssl_context *ssl ); int ssl_handshake_step( ssl_context *ssl );
#if defined(POLARSSL_SSL_RENEGOTIATION)
/** /**
* \brief Initiate an SSL renegotiation on the running connection. * \brief Initiate an SSL renegotiation on the running connection.
* Client: perform the renegotiation right now. * Client: perform the renegotiation right now.
@ -1721,6 +1769,7 @@ int ssl_handshake_step( ssl_context *ssl );
* \return 0 if successful, or any ssl_handshake() return value. * \return 0 if successful, or any ssl_handshake() return value.
*/ */
int ssl_renegotiate( ssl_context *ssl ); int ssl_renegotiate( ssl_context *ssl );
#endif /* POLARSSL_SSL_RENEGOTIATION */
/** /**
* \brief Read at most 'len' application data bytes * \brief Read at most 'len' application data bytes

View file

@ -114,6 +114,7 @@ static void ssl_write_hostname_ext( ssl_context *ssl,
} }
#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ #endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
#if defined(POLARSSL_SSL_RENEGOTIATION)
static void ssl_write_renegotiation_ext( ssl_context *ssl, static void ssl_write_renegotiation_ext( ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
@ -141,6 +142,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl,
*olen = 5 + ssl->verify_data_len; *olen = 5 + ssl->verify_data_len;
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* /*
* Only if we handle at least one key exchange that needs signatures. * 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 ); return( POLARSSL_ERR_SSL_NO_RNG );
} }
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
{ {
ssl->major_ver = ssl->min_major_ver; ssl->major_ver = ssl->min_major_ver;
ssl->minor_ver = ssl->min_minor_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; 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 ) ssl->handshake->resume == 0 )
{ {
n = 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 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
* generate and include a Session ID in the TLS ClientHello." * generate and include a Session ID in the TLS ClientHello."
*/ */
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && #if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->session_negotiate->ticket != NULL && if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
if( ssl->session_negotiate->ticket != NULL &&
ssl->session_negotiate->ticket_len != 0 ) ssl->session_negotiate->ticket_len != 0 )
{ {
ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 ); 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 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
*/ */
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
{ {
*p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
*p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO ); *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO );
@ -693,8 +704,10 @@ static int ssl_write_client_hello( ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \ #if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED) defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
@ -740,6 +753,9 @@ static int ssl_write_client_hello( ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
/* olen unused if all extensions are disabled */
((void) olen);
SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
ext_len ) ); ext_len ) );
@ -773,21 +789,8 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
{ {
int ret; int ret;
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) #if defined(POLARSSL_SSL_RENEGOTIATION)
{ 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
{ {
/* Check verify-data in constant-time. The length OTOH is no secret */ /* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len * 2 || 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, safer_memcmp( buf + 1 + ssl->verify_data_len,
ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) 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 ) if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret ); return( ret );
@ -805,6 +808,21 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); 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 ); return( 0 );
} }
@ -996,7 +1014,9 @@ static int ssl_parse_server_hello( ssl_context *ssl )
size_t n; size_t n;
size_t ext_len; size_t ext_len;
unsigned char *buf, *ext; unsigned char *buf, *ext;
#if defined(POLARSSL_SSL_RENEGOTIATION)
int renegotiation_info_seen = 0; int renegotiation_info_seen = 0;
#endif
int handshake_failure = 0; int handshake_failure = 0;
#if defined(POLARSSL_DEBUG_C) #if defined(POLARSSL_DEBUG_C)
uint32_t t; uint32_t t;
@ -1021,6 +1041,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{ {
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_RENEGOTIATION ) if( ssl->renegotiation == SSL_RENEGOTIATION )
{ {
ssl->renego_records_seen++; 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" ) ); SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_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 * Check if the session can be resumed
*/ */
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE || if( ssl->handshake->resume == 0 || n == 0 ||
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->ciphersuite != i ||
ssl->session_negotiate->compression != comp || ssl->session_negotiate->compression != comp ||
ssl->session_negotiate->length != n || ssl->session_negotiate->length != n ||
@ -1226,7 +1250,9 @@ static int ssl_parse_server_hello( ssl_context *ssl )
{ {
case TLS_EXT_RENEGOTIATION_INFO: case TLS_EXT_RENEGOTIATION_INFO:
SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
renegotiation_info_seen = 1; renegotiation_info_seen = 1;
#endif
if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
ext_size ) ) != 0 ) 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" ) ); SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
handshake_failure = 1; handshake_failure = 1;
} }
#if defined(POLARSSL_SSL_RENEGOTIATION)
else if( ssl->renegotiation == SSL_RENEGOTIATION && else if( ssl->renegotiation == SSL_RENEGOTIATION &&
ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION && ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
renegotiation_info_seen == 0 ) 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)" ) ); SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
handshake_failure = 1; handshake_failure = 1;
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
if( handshake_failure == 1 ) if( handshake_failure == 1 )
{ {

View file

@ -431,11 +431,29 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
{ {
int ret; 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 ) 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 ) if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret ); return( ret );
@ -445,22 +463,6 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; 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 ); return( 0 );
} }
@ -701,11 +703,13 @@ static int ssl_parse_session_ticket_ext( ssl_context *ssl,
if( len == 0 ) if( len == 0 )
return( 0 ); return( 0 );
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ) if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
{ {
SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
return( 0 ); return( 0 );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* /*
* Failures are ok: just ignore the ticket and proceed. * 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" ) ); SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ) if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
{ {
SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); 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 ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
buf = ssl->in_hdr; 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 ) if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO )
{ {
SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == 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 ) if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret ); return( ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
break; break;
} }
@ -1191,15 +1200,19 @@ static int ssl_parse_client_hello( ssl_context *ssl )
unsigned int comp_len; unsigned int comp_len;
unsigned int ext_len = 0; unsigned int ext_len = 0;
unsigned char *buf, *p, *ext; unsigned char *buf, *p, *ext;
#if defined(POLARSSL_SSL_RENEGOTIATION)
int renegotiation_info_seen = 0; int renegotiation_info_seen = 0;
#endif
int handshake_failure = 0; int handshake_failure = 0;
const int *ciphersuites; const int *ciphersuites;
const ssl_ciphersuite_t *ciphersuite_info; const ssl_ciphersuite_t *ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && #if defined(POLARSSL_SSL_RENEGOTIATION)
( ret = ssl_fetch_input( ssl, 5 ) ) != 0 ) if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
{ {
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
return( ret ); return( ret );
@ -1249,18 +1262,22 @@ static int ssl_parse_client_hello( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && #if defined(POLARSSL_SSL_RENEGOTIATION)
( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 ) if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE )
#endif
if( ( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 )
{ {
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
return( ret ); return( ret );
} }
buf = ssl->in_msg; buf = ssl->in_msg;
if( !ssl->renegotiation ) #if defined(POLARSSL_SSL_RENEGOTIATION)
n = ssl->in_left - 5; if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
else
n = ssl->in_msglen; n = ssl->in_msglen;
else
#endif
n = ssl->in_left - 5;
ssl->handshake->update_checksum( ssl, buf, n ); 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 ) if( p[0] == 0 && p[1] == SSL_EMPTY_RENEGOTIATION_INFO )
{ {
SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == 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" ) );
@ -1432,6 +1450,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
renegotiation_info_seen = 1;
#endif /* POLARSSL_SSL_RENEGOTIATION */
ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
break; break;
} }
@ -1490,7 +1510,9 @@ static int ssl_parse_client_hello( ssl_context *ssl )
case TLS_EXT_RENEGOTIATION_INFO: case TLS_EXT_RENEGOTIATION_INFO:
SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
renegotiation_info_seen = 1; renegotiation_info_seen = 1;
#endif
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
@ -1501,8 +1523,10 @@ static int ssl_parse_client_hello( ssl_context *ssl )
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED) defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
case TLS_EXT_SIG_ALG: case TLS_EXT_SIG_ALG:
SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( ssl->renegotiation == SSL_RENEGOTIATION ) if( ssl->renegotiation == SSL_RENEGOTIATION )
break; break;
#endif
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
@ -1608,12 +1632,13 @@ static int ssl_parse_client_hello( ssl_context *ssl )
/* /*
* Renegotiation security checks * 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->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
{ {
SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
handshake_failure = 1; handshake_failure = 1;
} }
#if defined(POLARSSL_SSL_RENEGOTIATION)
else if( ssl->renegotiation == SSL_RENEGOTIATION && else if( ssl->renegotiation == SSL_RENEGOTIATION &&
ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION && ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION &&
renegotiation_info_seen == 0 ) 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)" ) ); SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
handshake_failure = 1; handshake_failure = 1;
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
if( handshake_failure == 1 ) 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 >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
*p++ = 0x00; #if defined(POLARSSL_SSL_RENEGOTIATION)
*p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
*p++ = ssl->verify_data_len * 2 & 0xFF; {
*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 ); memcpy( p, ssl->peer_verify_data, ssl->verify_data_len );
p += ssl->verify_data_len; p += ssl->verify_data_len;
memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
p += 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) #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 not, try looking up session ID in our cache.
*/ */
if( ssl->handshake->resume == 0 && if( ssl->handshake->resume == 0 &&
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->renegotiation == SSL_INITIAL_HANDSHAKE && ssl->renegotiation == SSL_INITIAL_HANDSHAKE &&
#endif
ssl->session_negotiate->length != 0 && ssl->session_negotiate->length != 0 &&
ssl->f_get_cache != NULL && ssl->f_get_cache != NULL &&
ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 ) 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 * On client, make sure the server cert doesn't change during renego to
* avoid "triple handshake" attack: https://secure-resumption.com/ * 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 && if( ssl->endpoint == SSL_IS_CLIENT &&
ssl->renegotiation == SSL_RENEGOTIATION ) ssl->renegotiation == SSL_RENEGOTIATION )
{ {
@ -2817,7 +2817,7 @@ int ssl_parse_certificate( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); 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 ) if( ssl->authmode != SSL_VERIFY_NONE )
{ {
@ -3260,11 +3260,13 @@ void ssl_handshake_wrapup( ssl_context *ssl )
polarssl_free( ssl->handshake ); polarssl_free( ssl->handshake );
ssl->handshake = NULL; ssl->handshake = NULL;
#if defined(POLARSSL_SSL_RENEGOTIATION)
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; ssl->renego_records_seen = 0;
} }
#endif
/* /*
* Switch in our now active transform context * 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) // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12;
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->verify_data_len = hash_len; ssl->verify_data_len = hash_len;
memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
#endif
ssl->out_msglen = 4 + hash_len; ssl->out_msglen = 4 + hash_len;
ssl->out_msgtype = SSL_MSG_HANDSHAKE; ssl->out_msgtype = SSL_MSG_HANDSHAKE;
@ -3454,8 +3458,10 @@ int ssl_parse_finished( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_FINISHED ); return( POLARSSL_ERR_SSL_BAD_HS_FINISHED );
} }
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->verify_data_len = hash_len; ssl->verify_data_len = hash_len;
memcpy( ssl->peer_verify_data, buf, hash_len ); memcpy( ssl->peer_verify_data, buf, hash_len );
#endif
if( ssl->handshake->resume != 0 ) if( ssl->handshake->resume != 0 )
{ {
@ -3607,7 +3613,11 @@ int ssl_init( ssl_context *ssl )
ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT; 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 defined(POLARSSL_DHM_C)
if( ( ret = mpi_read_string( &ssl->dhm_P, 16, if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
@ -3681,12 +3691,16 @@ int ssl_session_reset( ssl_context *ssl )
int ret; int ret;
ssl->state = SSL_HELLO_REQUEST; ssl->state = SSL_HELLO_REQUEST;
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl->renegotiation = SSL_INITIAL_HANDSHAKE; ssl->renegotiation = SSL_INITIAL_HANDSHAKE;
ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION; ssl->renego_records_seen = 0;
ssl->verify_data_len = 0; ssl->verify_data_len = 0;
memset( ssl->own_verify_data, 0, 36 ); memset( ssl->own_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
memset( ssl->peer_verify_data, 0, 36 ); memset( ssl->peer_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
#endif
ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
ssl->in_offt = NULL; ssl->in_offt = NULL;
@ -3707,8 +3721,6 @@ 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 );
@ -4251,21 +4263,29 @@ int ssl_set_truncated_hmac( ssl_context *ssl, int truncate )
} }
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ #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 ) void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
{ {
ssl->allow_legacy_renegotiation = 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 ) void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records )
{ {
ssl->renego_max_records = 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) #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 )
{ {
@ -4400,6 +4420,7 @@ int ssl_handshake( ssl_context *ssl )
return( ret ); return( ret );
} }
#if defined(POLARSSL_SSL_RENEGOTIATION)
#if defined(POLARSSL_SSL_SRV_C) #if defined(POLARSSL_SSL_SRV_C)
/* /*
* Write HelloRequest to request renegotiation on server * Write HelloRequest to request renegotiation on server
@ -4512,6 +4533,30 @@ int ssl_renegotiate( ssl_context *ssl )
return( ret ); 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 * 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" ) ); 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 ) if( ssl->state != SSL_HANDSHAKE_OVER )
{ {
ret = ssl_handshake( ssl ); 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 ) if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
{ {
SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); 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 ); return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
} }
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* Fatal and closure alerts handled by ssl_read_record() */ /* Fatal and closure alerts handled by ssl_read_record() */
if( ssl->in_msgtype == SSL_MSG_ALERT ) 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" ) ); 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( ssl->state != SSL_HANDSHAKE_OVER )
{ {
if( ( ret = ssl_handshake( ssl ) ) != 0 ) if( ( ret = ssl_handshake( ssl ) ) != 0 )

View file

@ -83,7 +83,7 @@ int main( int argc, char *argv[] )
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_RENEGOTIATION SSL_RENEGOTIATION_DISABLED #define DFL_RENEGOTIATION SSL_RENEGOTIATION_DISABLED
#define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION #define DFL_ALLOW_LEGACY -2
#define DFL_RENEGOTIATE 0 #define DFL_RENEGOTIATE 0
#define DFL_EXCHANGES 1 #define DFL_EXCHANGES 1
#define DFL_MIN_VERSION -1 #define DFL_MIN_VERSION -1
@ -311,6 +311,14 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
#define USAGE_ETM "" #define USAGE_ETM ""
#endif #endif
#if defined(POLARSSL_SSL_RENEGOTIATION)
#define USAGE_RENEGO \
" renegotiation=%%d default: 0 (disabled)\n" \
" renegotiate=%%d default: 0 (disabled)\n"
#else
#define USAGE_RENEGO ""
#endif
#define USAGE \ #define USAGE \
"\n usage: ssl_client2 param=<>...\n" \ "\n usage: ssl_client2 param=<>...\n" \
"\n acceptable parameters:\n" \ "\n acceptable parameters:\n" \
@ -330,9 +338,8 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
"\n" \ "\n" \
USAGE_PSK \ USAGE_PSK \
"\n" \ "\n" \
" renegotiation=%%d default: 1 (enabled)\n" \ " allow_legacy=%%d default: (library default: no)\n" \
" allow_legacy=%%d default: 0 (disabled)\n" \ USAGE_RENEGO \
" renegotiate=%%d default: 0 (disabled)\n" \
" exchanges=%%d default: 1\n" \ " exchanges=%%d default: 1\n" \
" reconnect=%%d default: 0 (disabled)\n" \ " reconnect=%%d default: 0 (disabled)\n" \
USAGE_TIME \ USAGE_TIME \
@ -514,9 +521,13 @@ int main( int argc, char *argv[] )
} }
else if( strcmp( p, "allow_legacy" ) == 0 ) else if( strcmp( p, "allow_legacy" ) == 0 )
{ {
opt.allow_legacy = atoi( q ); switch( atoi( q ) )
if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) {
goto usage; case -1: opt.allow_legacy = SSL_LEGACY_BREAK_HANDSHAKE; break;
case 0: opt.allow_legacy = SSL_LEGACY_NO_RENEGOTIATION; break;
case 1: opt.allow_legacy = SSL_LEGACY_ALLOW_RENEGOTIATION; break;
default: goto usage;
}
} }
else if( strcmp( p, "renegotiate" ) == 0 ) else if( strcmp( p, "renegotiate" ) == 0 )
{ {
@ -980,8 +991,11 @@ int main( int argc, char *argv[] )
if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
ssl_set_ciphersuites( &ssl, opt.force_ciphersuite ); ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
if( opt.allow_legacy != DFL_ALLOW_LEGACY )
ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl_set_renegotiation( &ssl, opt.renegotiation ); ssl_set_renegotiation( &ssl, opt.renegotiation );
ssl_legacy_renegotiation( &ssl, opt.allow_legacy ); #endif
#if defined(POLARSSL_X509_CRT_PARSE_C) #if defined(POLARSSL_X509_CRT_PARSE_C)
if( strcmp( opt.ca_path, "none" ) != 0 && if( strcmp( opt.ca_path, "none" ) != 0 &&
@ -1113,6 +1127,7 @@ int main( int argc, char *argv[] )
} }
#endif /* POLARSSL_X509_CRT_PARSE_C */ #endif /* POLARSSL_X509_CRT_PARSE_C */
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( opt.renegotiate ) if( opt.renegotiate )
{ {
/* /*
@ -1132,6 +1147,7 @@ int main( int argc, char *argv[] )
} }
printf( " ok\n" ); printf( " ok\n" );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* /*
* 6. Write the GET request * 6. Write the GET request

View file

@ -101,9 +101,10 @@ int main( int argc, char *argv[] )
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_VERSION_SUITES NULL #define DFL_VERSION_SUITES NULL
#define DFL_RENEGOTIATION SSL_RENEGOTIATION_DISABLED #define DFL_RENEGOTIATION SSL_RENEGOTIATION_DISABLED
#define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION #define DFL_ALLOW_LEGACY -2
#define DFL_RENEGOTIATE 0 #define DFL_RENEGOTIATE 0
#define DFL_RENEGO_DELAY -2 #define DFL_RENEGO_DELAY -2
#define DFL_RENEGO_PERIOD -1
#define DFL_EXCHANGES 1 #define DFL_EXCHANGES 1
#define DFL_MIN_VERSION -1 #define DFL_MIN_VERSION -1
#define DFL_MAX_VERSION -1 #define DFL_MAX_VERSION -1
@ -166,6 +167,7 @@ struct options
int allow_legacy; /* allow legacy renegotiation */ int allow_legacy; /* allow legacy renegotiation */
int renegotiate; /* attempt renegotiation? */ int renegotiate; /* attempt renegotiation? */
int renego_delay; /* delay before enforcing renegotiation */ int renego_delay; /* delay before enforcing renegotiation */
int renego_period; /* period for automatic renegotiation */
int exchanges; /* number of data exchanges */ int exchanges; /* number of data exchanges */
int min_version; /* minimum protocol version accepted */ int min_version; /* minimum protocol version accepted */
int max_version; /* maximum protocol version accepted */ int max_version; /* maximum protocol version accepted */
@ -317,6 +319,16 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
#define USAGE_ETM "" #define USAGE_ETM ""
#endif #endif
#if defined(POLARSSL_SSL_RENEGOTIATION)
#define USAGE_RENEGO \
" renegotiation=%%d default: 0 (disabled)\n" \
" renegotiate=%%d default: 0 (disabled)\n" \
" renego_delay=%%d default: -2 (library default)\n" \
" renego_period=%%d default: (library default)\n"
#else
#define USAGE_RENEGO ""
#endif
#define USAGE \ #define USAGE \
"\n usage: ssl_server2 param=<>...\n" \ "\n usage: ssl_server2 param=<>...\n" \
"\n acceptable parameters:\n" \ "\n acceptable parameters:\n" \
@ -333,10 +345,8 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
"\n" \ "\n" \
USAGE_PSK \ USAGE_PSK \
"\n" \ "\n" \
" renegotiation=%%d default: 1 (enabled)\n" \ " allow_legacy=%%d default: (library default: no)\n" \
" allow_legacy=%%d default: 0 (disabled)\n" \ USAGE_RENEGO \
" renegotiate=%%d default: 0 (disabled)\n" \
" renego_delay=%%d default: -2 (library default)\n" \
" exchanges=%%d default: 1\n" \ " exchanges=%%d default: 1\n" \
USAGE_TICKETS \ USAGE_TICKETS \
USAGE_CACHE \ USAGE_CACHE \
@ -621,6 +631,9 @@ int main( int argc, char *argv[] )
entropy_context entropy; entropy_context entropy;
ctr_drbg_context ctr_drbg; ctr_drbg_context ctr_drbg;
ssl_context ssl; ssl_context ssl;
#if defined(POLARSSL_SSL_RENEGOTIATION)
unsigned char renego_period[8] = { 0 };
#endif
#if defined(POLARSSL_X509_CRT_PARSE_C) #if defined(POLARSSL_X509_CRT_PARSE_C)
x509_crt cacert; x509_crt cacert;
x509_crt srvcert; x509_crt srvcert;
@ -722,6 +735,7 @@ int main( int argc, char *argv[] )
opt.allow_legacy = DFL_ALLOW_LEGACY; opt.allow_legacy = DFL_ALLOW_LEGACY;
opt.renegotiate = DFL_RENEGOTIATE; opt.renegotiate = DFL_RENEGOTIATE;
opt.renego_delay = DFL_RENEGO_DELAY; opt.renego_delay = DFL_RENEGO_DELAY;
opt.renego_period = DFL_RENEGO_PERIOD;
opt.exchanges = DFL_EXCHANGES; opt.exchanges = DFL_EXCHANGES;
opt.min_version = DFL_MIN_VERSION; opt.min_version = DFL_MIN_VERSION;
opt.max_version = DFL_MAX_VERSION; opt.max_version = DFL_MAX_VERSION;
@ -804,9 +818,13 @@ int main( int argc, char *argv[] )
} }
else if( strcmp( p, "allow_legacy" ) == 0 ) else if( strcmp( p, "allow_legacy" ) == 0 )
{ {
opt.allow_legacy = atoi( q ); switch( atoi( q ) )
if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) {
goto usage; case -1: opt.allow_legacy = SSL_LEGACY_BREAK_HANDSHAKE; break;
case 0: opt.allow_legacy = SSL_LEGACY_NO_RENEGOTIATION; break;
case 1: opt.allow_legacy = SSL_LEGACY_ALLOW_RENEGOTIATION; break;
default: goto usage;
}
} }
else if( strcmp( p, "renegotiate" ) == 0 ) else if( strcmp( p, "renegotiate" ) == 0 )
{ {
@ -818,6 +836,12 @@ int main( int argc, char *argv[] )
{ {
opt.renego_delay = atoi( q ); opt.renego_delay = atoi( q );
} }
else if( strcmp( p, "renego_period" ) == 0 )
{
opt.renego_period = atoi( q );
if( opt.renego_period < 2 || opt.renego_period > 255 )
goto usage;
}
else if( strcmp( p, "exchanges" ) == 0 ) else if( strcmp( p, "exchanges" ) == 0 )
{ {
opt.exchanges = atoi( q ); opt.exchanges = atoi( q );
@ -1361,11 +1385,21 @@ int main( int argc, char *argv[] )
SSL_MINOR_VERSION_3 ); SSL_MINOR_VERSION_3 );
} }
if( opt.allow_legacy != DFL_ALLOW_LEGACY )
ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
#if defined(POLARSSL_SSL_RENEGOTIATION)
ssl_set_renegotiation( &ssl, opt.renegotiation ); ssl_set_renegotiation( &ssl, opt.renegotiation );
ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
if( opt.renego_delay != DFL_RENEGO_DELAY ) if( opt.renego_delay != DFL_RENEGO_DELAY )
ssl_set_renegotiation_enforced( &ssl, opt.renego_delay ); ssl_set_renegotiation_enforced( &ssl, opt.renego_delay );
if( opt.renego_period != DFL_RENEGO_PERIOD )
{
renego_period[7] = opt.renego_period;
ssl_set_renegotiation_period( &ssl, renego_period );
}
#endif
#if defined(POLARSSL_X509_CRT_PARSE_C) #if defined(POLARSSL_X509_CRT_PARSE_C)
if( strcmp( opt.ca_path, "none" ) != 0 && if( strcmp( opt.ca_path, "none" ) != 0 &&
strcmp( opt.ca_file, "none" ) != 0 ) strcmp( opt.ca_file, "none" ) != 0 )
@ -1666,6 +1700,7 @@ data_exchange:
* 7a. Request renegotiation while client is waiting for input from us. * 7a. Request renegotiation while client is waiting for input from us.
* (only if we're going to exhange more data afterwards) * (only if we're going to exhange more data afterwards)
*/ */
#if defined(POLARSSL_SSL_RENEGOTIATION)
if( opt.renegotiate && exchanges > 1 ) if( opt.renegotiate && exchanges > 1 )
{ {
printf( " . Requestion renegotiation..." ); printf( " . Requestion renegotiation..." );
@ -1683,6 +1718,7 @@ data_exchange:
printf( " ok\n" ); printf( " ok\n" );
} }
#endif /* POLARSSL_SSL_RENEGOTIATION */
/* /*
* 7. Write the 200 Response * 7. Write the 200 Response

View file

@ -28,6 +28,7 @@ POLARSSL_ECP_DP_M511_ENABLED
POLARSSL_NO_DEFAULT_ENTROPY_SOURCES POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
POLARSSL_NO_PLATFORM_ENTROPY POLARSSL_NO_PLATFORM_ENTROPY
POLARSSL_SSL_HW_RECORD_ACCEL POLARSSL_SSL_HW_RECORD_ACCEL
POLARSSL_SSL_DISABLE_RENEGOTIATION
POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3
POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
POLARSSL_ZLIB_SUPPORT POLARSSL_ZLIB_SUPPORT

View file

@ -20,7 +20,7 @@ set -u
O_SRV="$OPENSSL_CMD s_server -www -cert data_files/server5.crt -key data_files/server5.key" O_SRV="$OPENSSL_CMD s_server -www -cert data_files/server5.crt -key data_files/server5.key"
O_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_CMD s_client" O_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_CMD s_client"
G_SRV="$GNUTLS_SERV --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key" G_SRV="$GNUTLS_SERV --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
G_CLI="$GNUTLS_CLI" G_CLI="echo 'GET / HTTP/1.0' | $GNUTLS_CLI --x509cafile data_files/test-ca_cat12.crt"
TESTS=0 TESTS=0
FAILS=0 FAILS=0
@ -380,7 +380,7 @@ P_CLI="$P_CLI server_port=$PORT"
O_SRV="$O_SRV -accept $PORT" O_SRV="$O_SRV -accept $PORT"
O_CLI="$O_CLI -connect localhost:$PORT" O_CLI="$O_CLI -connect localhost:$PORT"
G_SRV="$G_SRV -p $PORT" G_SRV="$G_SRV -p $PORT"
G_CLI="$G_CLI -p $PORT" G_CLI="$G_CLI -p $PORT localhost"
# Also pick a unique name for intermediate files # Also pick a unique name for intermediate files
SRV_OUT="srv_out.$$" SRV_OUT="srv_out.$$"
@ -1007,6 +1007,70 @@ run_test "Renegotiation: server-initiated, client-accepted, delay 0" \
-S "SSL - An unexpected message was received from our peer" \ -S "SSL - An unexpected message was received from our peer" \
-S "failed" -S "failed"
run_test "Renegotiation: periodic, just below period" \
"$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3" \
"$P_CLI debug_level=3 exchanges=2 renegotiation=1" \
0 \
-C "client hello, adding renegotiation extension" \
-s "received TLS_EMPTY_RENEGOTIATION_INFO" \
-S "found renegotiation extension" \
-s "server hello, secure renegotiation extension" \
-c "found renegotiation extension" \
-S "record counter limit reached: renegotiate" \
-C "=> renegotiate" \
-S "=> renegotiate" \
-S "write hello request" \
-S "SSL - An unexpected message was received from our peer" \
-S "failed"
run_test "Renegotiation: periodic, just above period" \
"$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3" \
"$P_CLI debug_level=3 exchanges=3 renegotiation=1" \
0 \
-c "client hello, adding renegotiation extension" \
-s "received TLS_EMPTY_RENEGOTIATION_INFO" \
-s "found renegotiation extension" \
-s "server hello, secure renegotiation extension" \
-c "found renegotiation extension" \
-s "record counter limit reached: renegotiate" \
-c "=> renegotiate" \
-s "=> renegotiate" \
-s "write hello request" \
-S "SSL - An unexpected message was received from our peer" \
-S "failed"
run_test "Renegotiation: periodic, two times period" \
"$P_SRV debug_level=3 exchanges=9 renegotiation=1 renego_period=3" \
"$P_CLI debug_level=3 exchanges=6 renegotiation=1" \
0 \
-c "client hello, adding renegotiation extension" \
-s "received TLS_EMPTY_RENEGOTIATION_INFO" \
-s "found renegotiation extension" \
-s "server hello, secure renegotiation extension" \
-c "found renegotiation extension" \
-s "record counter limit reached: renegotiate" \
-c "=> renegotiate" \
-s "=> renegotiate" \
-s "write hello request" \
-S "SSL - An unexpected message was received from our peer" \
-S "failed"
run_test "Renegotiation: periodic, above period, disabled" \
"$P_SRV debug_level=3 exchanges=9 renegotiation=0 renego_period=3" \
"$P_CLI debug_level=3 exchanges=4 renegotiation=1" \
0 \
-C "client hello, adding renegotiation extension" \
-s "received TLS_EMPTY_RENEGOTIATION_INFO" \
-S "found renegotiation extension" \
-s "server hello, secure renegotiation extension" \
-c "found renegotiation extension" \
-S "record counter limit reached: renegotiate" \
-C "=> renegotiate" \
-S "=> renegotiate" \
-S "write hello request" \
-S "SSL - An unexpected message was received from our peer" \
-S "failed"
run_test "Renegotiation: nbio, client-initiated" \ run_test "Renegotiation: nbio, client-initiated" \
"$P_SRV debug_level=3 nbio=2 exchanges=2 renegotiation=1" \ "$P_SRV debug_level=3 nbio=2 exchanges=2 renegotiation=1" \
"$P_CLI debug_level=3 nbio=2 exchanges=2 renegotiation=1 renegotiate=1" \ "$P_CLI debug_level=3 nbio=2 exchanges=2 renegotiation=1 renegotiate=1" \
@ -1040,21 +1104,103 @@ run_test "Renegotiation: openssl server, client-initiated" \
-c "client hello, adding renegotiation extension" \ -c "client hello, adding renegotiation extension" \
-c "found renegotiation extension" \ -c "found renegotiation extension" \
-c "=> renegotiate" \ -c "=> renegotiate" \
-C "ssl_handshake returned" \ -C "ssl_hanshake() returned" \
-C "error" \ -C "error" \
-c "HTTP/1.0 200 [Oo][Kk]" -c "HTTP/1.0 200 [Oo][Kk]"
run_test "Renegotiation: gnutls server, client-initiated" \ run_test "Renegotiation: gnutls server strict, client-initiated" \
"$G_SRV" \ "$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \ "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
0 \ 0 \
-c "client hello, adding renegotiation extension" \ -c "client hello, adding renegotiation extension" \
-c "found renegotiation extension" \ -c "found renegotiation extension" \
-c "=> renegotiate" \ -c "=> renegotiate" \
-C "ssl_handshake returned" \ -C "ssl_hanshake() returned" \
-C "error" \ -C "error" \
-c "HTTP/1.0 200 [Oo][Kk]" -c "HTTP/1.0 200 [Oo][Kk]"
run_test "Renegotiation: gnutls server unsafe, client-initiated default" \
"$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
1 \
-c "client hello, adding renegotiation extension" \
-C "found renegotiation extension" \
-c "=> renegotiate" \
-c "ssl_handshake() returned" \
-c "error" \
-C "HTTP/1.0 200 [Oo][Kk]"
run_test "Renegotiation: gnutls server unsafe, client-inititated no legacy" \
"$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
allow_legacy=0" \
1 \
-c "client hello, adding renegotiation extension" \
-C "found renegotiation extension" \
-c "=> renegotiate" \
-c "ssl_handshake() returned" \
-c "error" \
-C "HTTP/1.0 200 [Oo][Kk]"
run_test "Renegotiation: gnutls server unsafe, client-inititated legacy" \
"$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
allow_legacy=1" \
0 \
-c "client hello, adding renegotiation extension" \
-C "found renegotiation extension" \
-c "=> renegotiate" \
-C "ssl_hanshake() returned" \
-C "error" \
-c "HTTP/1.0 200 [Oo][Kk]"
# Test for the "secure renegotation" extension only (no actual renegotiation)
run_test "Renego ext: gnutls server strict, client default" \
"$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3" \
0 \
-c "found renegotiation extension" \
-C "error" \
-c "HTTP/1.0 200 [Oo][Kk]"
run_test "Renego ext: gnutls server unsafe, client default" \
"$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3" \
0 \
-C "found renegotiation extension" \
-C "error" \
-c "HTTP/1.0 200 [Oo][Kk]"
run_test "Renego ext: gnutls server unsafe, client break legacy" \
"$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
"$P_CLI debug_level=3 allow_legacy=-1" \
1 \
-C "found renegotiation extension" \
-c "error" \
-C "HTTP/1.0 200 [Oo][Kk]"
run_test "Renego ext: gnutls client strict, server default" \
"$P_SRV debug_level=3" \
"$G_CLI --priority=NORMAL:%SAFE_RENEGOTIATION" \
0 \
-s "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
-s "server hello, secure renegotiation extension"
run_test "Renego ext: gnutls client unsafe, server default" \
"$P_SRV debug_level=3" \
"$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
0 \
-S "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
-S "server hello, secure renegotiation extension"
run_test "Renego ext: gnutls client unsafe, server break legacy" \
"$P_SRV debug_level=3 allow_legacy=-1" \
"$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
1 \
-S "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
-S "server hello, secure renegotiation extension"
# Tests for auth_mode # Tests for auth_mode
run_test "Authentication: server badcert, client required" \ run_test "Authentication: server badcert, client required" \