From e7047819eef8d27285acfdbbd66d2855ab4e18f5 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Mon, 13 Sep 2021 19:26:39 +0800 Subject: [PATCH] add pend fatal alert Signed-off-by: Jerry Yu --- include/mbedtls/ssl.h | 25 +++++++++++++++++++++++++ library/ssl_misc.h | 5 +++++ library/ssl_msg.c | 22 ++++++++++++++++++++++ library/ssl_tls.c | 16 ++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 725b156d5..58cc113b7 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1526,6 +1526,23 @@ struct mbedtls_ssl_context int MBEDTLS_PRIVATE(keep_current_message); /*!< drop or reuse current message on next call to record layer? */ + /* The following three variables indicate if and, if yes, + * what kind of alert or warning is pending to be sent. + * They should not be set manually but through the macro + * MBEDTLS_SSL_PEND_FATAL_ALERT( type, user_return_value ) + * defined below. + */ + unsigned char MBEDTLS_PRIVATE(send_alert); /*!< Determines if either a fatal error + or a warning should be sent. Values: + - \c 0 if no alert is to be sent. + - #MBEDTLS_SSL_ALERT_LEVEL_FATAL + if a fatal alert is to be sent + - #MBEDTLS_SSL_ALERT_LEVEL_WARNING + if a non-fatal alert is to be sent. */ + unsigned char MBEDTLS_PRIVATE(alert_type); /*!< Type of alert if send_alert != 0 */ + int MBEDTLS_PRIVATE(alert_reason); /*!< The error code to be returned to the + * user once the fatal alert has been sent. */ + #if defined(MBEDTLS_SSL_PROTO_DTLS) uint8_t MBEDTLS_PRIVATE(disable_datagram_packing); /*!< Disable packing multiple records * within a single datagram. */ @@ -1624,6 +1641,14 @@ struct mbedtls_ssl_context #endif }; +#define MBEDTLS_SSL_PEND_FATAL_ALERT( type, user_return_value ) \ + do \ + { \ + ssl->send_alert = 1; \ + ssl->alert_reason = (user_return_value); \ + ssl->alert_type = (type); \ + } while( 0 ) + /** * \brief Return the name of the ciphersuite associated with the * given ID diff --git a/library/ssl_misc.h b/library/ssl_misc.h index c338d79ee..8b2698355 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1342,6 +1342,11 @@ void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl ); int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); +/* + * Send pending fatal alerts or warnings. + */ +int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl ); + #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); #endif diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 2fe801a28..3144d9818 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5639,4 +5639,26 @@ void mbedtls_ssl_read_version( int *major, int *minor, int transport, } } +/* + * Send pending fatal alerts or warnings. + */ +int mbedtls_ssl_handle_pending_alert( mbedtls_ssl_context *ssl ) +{ + int ret; + + /* Send alert if requested */ + if( ssl->send_alert != 0 ) + { + ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + ssl->alert_type ); + if( ret != 0 ) + return( ret ); + } + + ssl->send_alert = 0; + ssl->alert_type = 0; + return( 0 ); +} + #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 360419240..7bb5f9fd7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5170,6 +5170,10 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) if( ret != 0 ) return( ret ); + ret = mbedtls_ssl_handle_pending_alert( ssl ); + if( ret != 0 ) + goto cleanup; + #if defined(MBEDTLS_SSL_CLI_C) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) { @@ -5199,6 +5203,18 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) } #endif + if( ret != 0 ) + { + int alert_ret; + alert_ret = mbedtls_ssl_handle_pending_alert( ssl ); + if( alert_ret != 0 ) + { + ret = alert_ret; + goto cleanup; + } + } + +cleanup: return( ret ); }