From 125afcb0604596bc37989df8bc2e297766772664 Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Fri, 28 Oct 2022 06:04:06 +0000 Subject: [PATCH] Add end-of-early-data write Signed-off-by: Xiaokang Qian --- include/mbedtls/ssl.h | 2 + library/ssl_tls13_client.c | 102 ++++++++++++++++++++++++++++-- tests/opt-testcases/tls13-misc.sh | 1 + 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index dbc37e831c..d6e214be11 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -533,6 +533,7 @@ #define MBEDTLS_SSL_HS_SERVER_HELLO 2 #define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 #define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 +#define MBEDTLS_SSL_HS_END_OF_EARLY_DATA 5 // NEW IN TLS 1.3 #define MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS 8 // NEW IN TLS 1.3 #define MBEDTLS_SSL_HS_CERTIFICATE 11 #define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 @@ -671,6 +672,7 @@ typedef enum { MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, MBEDTLS_SSL_HELLO_RETRY_REQUEST, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS, + MBEDTLS_SSL_END_OF_EARLY_DATA, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO, diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 4aea61ca74..e4691743d9 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2108,6 +2108,96 @@ cleanup: } +/* + * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA + * + * RFC 8446: + * + * If the server sent an "early_data" extension in the EncryptedExtensions + * message, the client MUST send an EndOfEarlyData message after receiving + * the server Finished. + * + * If the server does not send an "early_data" extension + * in EncryptedExtensions, then the client MUST NOT send + * an EndOfEarlyData message. + */ + +/* Write end of early data message + * struct {} EndOfEarlyData; + */ + +#define SSL_END_OF_EARLY_DATA_WRITE 0 +#define SSL_END_OF_EARLY_DATA_SKIP 1 + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_write_end_of_early_data_coordinate( + mbedtls_ssl_context *ssl) +{ + ((void) ssl); + +#if defined(MBEDTLS_SSL_EARLY_DATA) + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + return SSL_END_OF_EARLY_DATA_WRITE; + } else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { + MBEDTLS_SSL_DEBUG_MSG(4, ("skip EndOfEarlyData, server rejected")); + return SSL_END_OF_EARLY_DATA_SKIP; + } else { + MBEDTLS_SSL_DEBUG_MSG(4, ("skip write EndOfEarlyData")); + } +#endif /* MBEDTLS_SSL_EARLY_DATA */ + + return SSL_END_OF_EARLY_DATA_SKIP; +} + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_finalize_write_end_of_early_data( + mbedtls_ssl_context *ssl) +{ +#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + mbedtls_ssl_handshake_set_state( + ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED); +#else + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); +#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ + + return 0; +} + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData")); + + MBEDTLS_SSL_PROC_CHK_NEG( + ssl_tls13_write_end_of_early_data_coordinate(ssl)); + if (ret == SSL_END_OF_EARLY_DATA_WRITE) { + unsigned char *buf = NULL; + size_t buf_len; + + MBEDTLS_SSL_DEBUG_MSG(2, ("Client write EndOfEarlyData")); + + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl, + MBEDTLS_SSL_HS_END_OF_EARLY_DATA, &buf, + &buf_len)); + + mbedtls_ssl_add_hs_hdr_to_checksum( + ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0); + + MBEDTLS_SSL_PROC_CHK( + mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0)); + } + + /* Update state */ + MBEDTLS_SSL_PROC_CHK( + ssl_tls13_finalize_write_end_of_early_data(ssl)); + +cleanup: + + MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData")); + return ret; +} + #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) /* * STATE HANDLING: CertificateRequest @@ -2367,13 +2457,7 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) return ret; } -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - mbedtls_ssl_handshake_set_state( - ssl, - MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED); -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); return 0; } @@ -2789,6 +2873,10 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) ret = ssl_tls13_process_server_finished(ssl); break; + case MBEDTLS_SSL_END_OF_EARLY_DATA: + ret = ssl_tls13_write_end_of_early_data(ssl); + break; + case MBEDTLS_SSL_CLIENT_CERTIFICATE: ret = ssl_tls13_write_client_certificate(ssl); break; diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 821a37bf37..b1f214731e 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -281,6 +281,7 @@ run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ -c "ClientHello: early_data(42) extension exists." \ -c "EncryptedExtensions: early_data(42) extension received." \ -c "EncryptedExtensions: early_data(42) extension exists." \ + -c "Client write EndOfEarlyData" \ -s "Parsing extension 'Early Data/42' (0 bytes)" \ -s "Sending extension Early Data/42 (0 bytes)" \ -s "early data accepted"