From d7d8d14e953a13f8c236d6eba2f268de67584980 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 7 Jun 2024 10:00:33 +1000 Subject: [PATCH] TLS: wrong TLS version in alert after ClientHello Ignore protocol version being less than expected when received directly after ClientHello. Protocol version negotiation hasn't taken place and a lower version can be sent to cover minimum supported protocol version. --- src/internal.c | 15 ++++++++++++++- tests/api.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 3620954ff1..95e50a11c4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11456,7 +11456,20 @@ static int GetRecordHeader(WOLFSSL* ssl, word32* inOutIdx, } } #endif /* WOLFSSL_DTLS13 */ - else { + /* Don't care about protocol version being lower than expected on alerts + * sent back before version negotitation. */ + else if (!(ssl->options.side == WOLFSSL_CLIENT_END && + ssl->options.connectState == CLIENT_HELLO_SENT && + rh->type == alert && + rh->pvMajor == ssl->version.major && + #ifdef WOLFSSL_DTLS + ((ssl->options.dtls && rh->pvMinor == DTLS_MINOR) || + (!ssl->options.dtls && + rh->pvMinor < ssl->version.minor)) + #else + rh->pvMinor < ssl->version.minor + #endif + )) { WOLFSSL_MSG("SSL version error"); WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; /* only use requested version */ diff --git a/tests/api.c b/tests/api.c index da7adf82ff..abb7cdcac9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -70460,6 +70460,34 @@ static int test_dtls_no_extensions(void) return EXPECT_RESULT(); } +static int test_tls_alert_no_server_hello(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) + WOLFSSL *ssl_c = NULL; + WOLFSSL_CTX *ctx_c = NULL; + struct test_memio_ctx test_ctx; + unsigned char alert_msg[] = { 0x15, 0x03, 0x01, 0x00, 0x02, 0x02, 0x28 }; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ssl_c = NULL; + ctx_c = NULL; + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL, + wolfTLSv1_2_client_method, NULL), 0); + + XMEMCPY(test_ctx.c_buff, alert_msg, sizeof(alert_msg)); + test_ctx.c_len = sizeof(alert_msg); + + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), FATAL_ERROR); + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); +#endif + return EXPECT_RESULT(); +} + static int test_TLSX_CA_NAMES_bad_extension(void) { EXPECT_DECLS; @@ -74037,6 +74065,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_dtls_ipv6_check), TEST_DECL(test_wolfSSL_SCR_after_resumption), TEST_DECL(test_dtls_no_extensions), + TEST_DECL(test_tls_alert_no_server_hello), TEST_DECL(test_TLSX_CA_NAMES_bad_extension), TEST_DECL(test_dtls_1_0_hvr_downgrade), TEST_DECL(test_session_ticket_no_id),