From ed7d4bfda589684c59aaadc14e4bfdba07f7cd3d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 07:55:19 +0100 Subject: [PATCH] tls13: srv: Simplify mbedtls_ssl_read_early_data() API Do not progress the handshake in the API, just read early data if some has been detected by a previous call to mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write(). Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 44 +++++++++----------------------------- library/ssl_msg.c | 42 ++++-------------------------------- library/ssl_tls13_server.c | 4 ++++ 3 files changed, 18 insertions(+), 72 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ccabbc239..5644f08c8 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5141,49 +5141,25 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * same warnings apply to any use of the * early_exporter_master_secret. * - * \note This function behaves mainly as mbedtls_ssl_read(). The - * specification of mbedtls_ssl_read() relevant to TLS 1.3 - * (thus not the parts specific to (D)TLS 1.2) applies to this - * function and the present documentation is restricted to the - * differences with mbedtls_ssl_read(). - * - * \note This function can be used in conjunction with + * \note This function is used in conjunction with * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), * mbedtls_ssl_read() and mbedtls_ssl_write() to read early * data when these functions return * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. * - * \param ssl SSL context + * \param ssl SSL context, it must have been initialized and set up. * \param buf buffer that will hold the data * \param len maximum number of bytes to read * - * \note Unlike mbedtls_ssl_read(), this function does not return + * \return The (positive) number of bytes read if successful. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. + * \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not + * possible to read early data for the SSL context \p ssl. Note + * that this function is intended to be called for an SSL + * context \p ssl only after a call to mbedtls_ssl_handshake(), + * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or + * mbedtls_ssl_write() for \p ssl that has returned * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. - * - * \return One additional specific return value: - * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA. - * - * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it - * is not possible to read early data for the SSL context - * \p ssl. - * - * It may have been possible and it is not possible - * anymore because the server received the End of Early Data - * message or the maximum number of allowed early data for the - * PSK in use has been reached. - * - * It may never have been possible and will never be possible - * for the SSL context \p ssl because the use of early data - * is disabled for that context or more generally the context - * is not suitably configured to enable early data or the - * client does not use early data or the first call to the - * function was done while the handshake was already too - * advanced to gather and accept early data. - * - * It is not possible to read early data for the SSL context - * \p ssl but this does not preclude for using it with - * mbedtls_ssl_write(), mbedtls_ssl_read() or - * mbedtls_ssl_handshake(). */ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index c6ba1158d..3547f6798 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5865,54 +5865,20 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) return ret; } - #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const struct mbedtls_ssl_config *conf; - unsigned char *p = buf; - - if (ssl == NULL || ((conf = ssl->conf) == NULL)) { + if (ssl == NULL || (ssl->conf == NULL)) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } - if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) || - (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) { + if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) || + (ssl->in_offt == NULL)) { return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; } - if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - if ((ssl->early_data_state.srv != - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH) && - (ssl->early_data_state.srv != - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING)) { - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - ret = mbedtls_ssl_handshake(ssl); - if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { - if (ssl->in_offt == NULL) { - /* Set the reading pointer */ - ssl->in_offt = ssl->in_msg; - } - ret = ssl_read_application_data(ssl, p, len); - } else if (ret == 0) { - /* - * If the handshake is completed, return immediately that early data - * cannot be read anymore. This potentially saves another call to this - * API and when the function returns 0, it only means that zero byte - * of early data has been received. - */ - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - return ret; + return ssl_read_application_data(ssl, buf, len); } #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9fcea5821..5b90dd5c7 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2929,6 +2929,10 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) * * TODO: Add received data size check here. */ + if (ssl->in_offt == NULL) { + /* Set the reading pointer */ + ssl->in_offt = ssl->in_msg; + } return SSL_GOT_EARLY_DATA; }