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 */