From 90e223364ca559042710316d4ba4e6eb86178284 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jan 2024 15:24:21 +0100 Subject: [PATCH] tls13: cli: Refine early data status The main purpose of the change is to know from the status, at any point in the handshake, if early data can be sent or not and why. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 6 ++--- library/ssl_misc.h | 32 +++++++++++++++++++++++++++ library/ssl_tls.c | 2 +- library/ssl_tls13_client.c | 45 ++++++++++++++++++++++---------------- 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index e0cd79d02..9583a15be 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5106,9 +5106,9 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); #if defined(MBEDTLS_SSL_EARLY_DATA) -#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2 +#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1 +#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 2 +#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3 #if defined(MBEDTLS_SSL_SRV_C) /** diff --git a/library/ssl_misc.h b/library/ssl_misc.h index dff19c88e..942d4ad22 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2145,6 +2145,38 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); + +#if defined(MBEDTLS_SSL_CLI_C) +/* + * The client has not sent the first ClientHello yet, it is unknown if the + * client will send an early data indication extension or not. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0 + +/* + * The client has sent an early data indication extension in its first + * ClientHello, it has not received the response (ServerHello or + * HelloRetryRequest) from the server yet. The transform to protect early data + * is not set and early data cannot be sent yet. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4 + +/* + * The client has sent an early data indication extension in its first + * ClientHello, it has not received the response (ServerHello or + * HelloRetryRequest) from the server yet. The transform to protect early data + * has been set and early data can be written now. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5 + +/* + * The client has sent an early data indication extension in its first + * ClientHello, the server has accepted them and the client has received the + * server Finished message. It cannot send early data to the server anymore. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6 +#endif /* MBEDTLS_SSL_CLI_C */ + #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8afedde88..3bbd4ca26 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1100,7 +1100,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_CLI_C) - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN; #endif #if defined(MBEDTLS_SSL_SRV_C) ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index e6680c7a6..5d7a49590 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1180,26 +1180,21 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, #endif #if defined(MBEDTLS_SSL_EARLY_DATA) - if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) && - ssl_tls13_early_data_has_valid_ticket(ssl) && - ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED && - ssl->handshake->hello_retry_request_count == 0) { + if (ssl->handshake->hello_retry_request_count == 0) { + if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) && + ssl_tls13_early_data_has_valid_ticket(ssl) && + ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) { + ret = mbedtls_ssl_tls13_write_early_data_ext( + ssl, 0, p, end, &ext_len); + if (ret != 0) { + return ret; + } + p += ext_len; - ret = mbedtls_ssl_tls13_write_early_data_ext( - ssl, 0, p, end, &ext_len); - if (ret != 0) { - return ret; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT; + } else { + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; } - p += ext_len; - - /* Initializes the status to `rejected`. It will be updated to - * `accepted` if the EncryptedExtension message contain an early data - * indication extension. - */ - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension")); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1236,7 +1231,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) size_t psk_len; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) { MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); @@ -1299,6 +1294,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) 1, ("Switch to early data keys for outbound traffic")); mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_earlydata); + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE; #endif } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1971,6 +1967,13 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl) } ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id; + +#if defined(MBEDTLS_SSL_EARLY_DATA) + if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) { + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + } +#endif + return 0; } @@ -2230,6 +2233,8 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) } ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + } else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) { + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; } #endif @@ -2567,6 +2572,7 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_EARLY_DATA) if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED; mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); } else #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -3088,6 +3094,7 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) 1, ("Switch to early data keys for outbound traffic")); mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_earlydata); + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE; } break; #endif /* MBEDTLS_SSL_EARLY_DATA */