Ignore failures when sending fatal alerts
In many places in TLS handling, some code detects a fatal error, sends
a fatal alert message, and returns to the caller. If sending the alert
fails, then return the error that triggered the alert, rather than
overriding the return status. This effectively causes alert sending
failures to be ignored. Formerly the code was inconsistently sometimes
doing one, sometimes the other.
In general ignoring the alert is the right thing: what matters to the
caller is the original error. A typical alert failure is that the
connection is already closed.
One case which remains not handled correctly is if the alert remains
in the output buffer (WANT_WRITE). Then it won't be sent, or will be
truncated. We'd need to either delay the application error or record
the write buffering notice; to be done later.
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 451370c..89afbce 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -152,8 +152,6 @@
const unsigned char *buf,
size_t len )
{
- int ret;
-
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
{
@@ -164,10 +162,8 @@
ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
-
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
@@ -177,10 +173,8 @@
if( len != 1 || buf[0] != 0x0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
-
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -857,10 +851,8 @@
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
-
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -1006,9 +998,8 @@
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
"during renegotiation" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -1092,10 +1083,8 @@
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
-
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -1794,10 +1783,8 @@
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) );
-
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
#endif
@@ -1841,9 +1828,8 @@
if( handshake_failure == 1 )
{
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -1881,13 +1867,15 @@
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
"but none of them usable" ) );
- mbedtls_ssl_send_fatal_handshake_failure( ssl );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
- mbedtls_ssl_send_fatal_handshake_failure( ssl );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
}
@@ -3314,13 +3302,8 @@
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
{
MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 )
- {
- return( ret );
- }
-
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY );
return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
}