Merge pull request #10514 from ng-gsmk/development

mbedtls_ssl_get_alert(): getter for fatal alerts
This commit is contained in:
David Horstmann
2026-01-28 16:49:09 +00:00
committed by GitHub
6 changed files with 89 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
Features
* Add the function mbedtls_ssl_get_fatal_alert(), which returns the type of
the last received fatal alert. This allows callers to retrieve more
detailed information when mbedtls_ssl_handshake(),
mbedtls_ssl_handshake_step(), or mbedtls_ssl_read() returns the generic
MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE error code.

View File

@@ -1715,6 +1715,13 @@ struct mbedtls_ssl_context {
int MBEDTLS_PRIVATE(keep_current_message); /*!< drop or reuse current message
on next call to record layer? */
unsigned char MBEDTLS_PRIVATE(in_fatal_alert_recv); /*!< Determines if a fatal alert has
been received. Values:
- \c 0 , no fatal alert received.
- \c 1 , a fatal alert has been received */
unsigned char MBEDTLS_PRIVATE(in_fatal_alert_type); /*!< Type of fatal alert if in_alert_recv
!= 0 */
/* The following three variables indicate if and, if yes,
* what kind of alert is pending to be sent.
*/
@@ -4911,6 +4918,22 @@ int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t
int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
unsigned char level,
unsigned char message);
/**
* \brief Get the last received fatal alert
*
* \param ssl SSL context
*
* \return The alert description type (MBEDTLS_SSL_ALERT_MSG_*) if a fatal
* alert has been received, MBEDTLS_ERR_SSL_BAD_INPUT_DATA otherwise.
*
* \note This function can be used in case mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step() or mbedtls_ssl_read() returned
* MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE to get the actual alert
* description type.
*/
int mbedtls_ssl_get_fatal_alert(const mbedtls_ssl_context *ssl);
/**
* \brief Notify the peer that the connection is being closed
*

View File

@@ -4931,6 +4931,8 @@ int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) {
MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)",
ssl->in_msg[1]));
ssl->in_fatal_alert_recv = 1;
ssl->in_fatal_alert_type = ssl->in_msg[1];
return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
}
@@ -5015,6 +5017,14 @@ int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
return 0;
}
int mbedtls_ssl_get_fatal_alert(const mbedtls_ssl_context *ssl)
{
if (ssl == NULL || ssl->in_fatal_alert_recv != 1) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
return ssl->in_fatal_alert_type;
}
int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

View File

@@ -1296,6 +1296,8 @@ void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl,
memset(ssl->in_buf, 0, in_buf_len);
}
ssl->in_fatal_alert_recv = 0;
ssl->in_fatal_alert_type = 0;
ssl->send_alert = 0;
/* Reset outgoing message writing */

View File

@@ -3364,3 +3364,6 @@ ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:250:10
TLS 1.3 Keying Material Exporter: Handshake not done
depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT
ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_3:1:MBEDTLS_SSL_SERVER_CERTIFICATE
TLS fatal alert getter
ssl_get_alert_after_fatal

View File

@@ -5936,3 +5936,48 @@ exit:
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
void ssl_get_alert_after_fatal(void)
{
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
/* prepapre ssl context to test on*/
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
MD_OR_USE_PSA_INIT();
TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT), 0);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
/* Invalid ssl context */
TEST_ASSERT(mbedtls_ssl_get_fatal_alert(NULL) == MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
/* No alert has been received yet */
TEST_ASSERT(mbedtls_ssl_get_fatal_alert(&ssl) == MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
// prepare input message buffer with fatal alert
ssl.in_msglen = 2;
ssl.in_msgtype = MBEDTLS_SSL_MSG_ALERT;
ssl.in_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_FATAL;
ssl.in_msg[1] = MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE;
/* import prepared fatal alert and test getter */
TEST_ASSERT(mbedtls_ssl_handle_message_type(&ssl) == MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE);
TEST_ASSERT(mbedtls_ssl_get_fatal_alert(&ssl) == MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
/* Reset the session and check that no alert is present*/
mbedtls_ssl_session_reset_msg_layer(&ssl, 0);
TEST_ASSERT(mbedtls_ssl_get_fatal_alert(&ssl) == MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
exit:
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
USE_PSA_DONE();
}
/* END_CASE */