From e68904e468fe47e9e1ff4220eac3dfb998ed3675 Mon Sep 17 00:00:00 2001 From: Kareem Date: Mon, 29 Jun 2026 16:53:28 -0700 Subject: [PATCH 1/2] Send missing_extension alert when the server does not include supported_versions in HelloRetryRequest for TLS 1.3. Partially fixes #10746. --- src/tls13.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tls13.c b/src/tls13.c index ecfd5946dd8..e76fe71ace3 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5586,6 +5586,21 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } if (!foundVersion) { + /* RFC 8446 4.1.4: "The server's extensions MUST contain + * 'supported_versions'." (also 9.2: "supported_versions" is + * REQUIRED for all ... HelloRetryRequest messages). The HRR random + * unambiguously identifies a TLS 1.3 server, so its absence is not + * a downgrade attempt but a missing mandatory extension, which per + * the "missing_extension" alert definition must be reported as + * such. Return INCOMPLETE_DATA (which maps to a missing_extension + * alert) and let the caller emit the alert via + * TranslateErrorToAlert(). */ + if (*extMsgType == hello_retry_request) { + WOLFSSL_MSG("HelloRetryRequest missing supported_versions " + "extension"); + WOLFSSL_ERROR_VERBOSE(INCOMPLETE_DATA); + return INCOMPLETE_DATA; + } if (!ssl->options.downgrade) { WOLFSSL_MSG("Server trying to downgrade to version less than " "TLS v1.3"); From 4252dfa36c2162a81e799894ed93f74726362a51 Mon Sep 17 00:00:00 2001 From: Kareem Date: Mon, 29 Jun 2026 16:54:53 -0700 Subject: [PATCH 2/2] Avoid sending duplicate protocol_version alert in DoTls13ClientHello. DoTls13ClientHello was explicitly sending a protocol_version alert, then returning VERSION_ERROR which TranslateErrorToAlert then mapped to protocol_version, causing a duplicate alert to be sent. Remove all protocol_version alerts from DoTls13ClientHello itself and instead return VERSION_ERROR and allow TranslateErrorToAlert to handle sending the alerts. Fixes #10746. --- src/tls13.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index e76fe71ace3..518d7e4aa15 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5452,7 +5452,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (args->pv.major != ssl->version.major || args->pv.minor != tls12minor) { - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; } @@ -5557,14 +5556,14 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif ssl->options.haveEMS = 0; if (args->pv.minor < ssl->options.minDowngrade) { - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); + WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; } #ifndef WOLFSSL_NO_TLS12 ssl->options.tls1_3 = 0; return DoServerHello(ssl, input, inOutIdx, helloSz); #else - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); + WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; #endif } @@ -5604,7 +5603,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!ssl->options.downgrade) { WOLFSSL_MSG("Server trying to downgrade to version less than " "TLS v1.3"); - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; } @@ -5623,14 +5621,12 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!ssl->options.dtls && args->pv.minor < ssl->options.minDowngrade) { - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; } if (ssl->options.dtls && args->pv.minor > ssl->options.minDowngrade) { - SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; }