From 03cb14a30ea4e4f4da0d459ed010f88553218d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Wed, 22 Jul 2026 10:17:14 +0200 Subject: [PATCH] Stop offering SHA-1 signature schemes for TLS 1.2 by default InitSuitesHashSigAlgo added the ecdsa_sha1 and rsa_pkcs1_sha1 signature schemes to the signature_algorithms list based only on the build flags, ignoring the negotiated protocol version. Because that list is also the set a peer's signatures are validated against, any build with old TLS compiled in advertised and accepted SHA-1 handshake and certificate signatures for TLS 1.2, which RFC 9155 deprecates. Gate the SHA-1 schemes on the negotiated version so they are offered only for TLS 1.0 and 1.1 handshakes, unless WOLFSSL_ALLOW_TLS_SHA1 is defined to opt back in. The same gate excludes them for TLS 1.3, as required by RFC 8446. Fixes F-6991. --- src/internal.c | 19 +++++++++++++++++-- tests/api.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0fd282a423..2249875276 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3519,6 +3519,16 @@ void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2, int tls1_3, int keySz, word16* len) { word16 idx = 0; +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || defined(WOLFSSL_ALLOW_TLS_SHA1)) + /* RFC 9155 deprecates SHA-1 signatures for TLS 1.2. Offer them only for a + * TLS 1.0/1.1 handshake unless the operator opts in with + * WOLFSSL_ALLOW_TLS_SHA1. */ + #ifdef WOLFSSL_ALLOW_TLS_SHA1 + int offerSha1Sig = 1; + #else + int offerSha1Sig = !tls1_2; + #endif +#endif (void)tls1_2; (void)tls1_3; @@ -3559,7 +3569,10 @@ void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2, #endif #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ defined(WOLFSSL_ALLOW_TLS_SHA1)) - AddSuiteHashSigAlgo(hashSigAlgo, sha_mac, ecc_dsa_sa_algo, keySz, &idx); + if (offerSha1Sig) { + AddSuiteHashSigAlgo(hashSigAlgo, sha_mac, ecc_dsa_sa_algo, keySz, + &idx); + } #endif #endif #ifdef HAVE_ED25519 @@ -3625,7 +3638,9 @@ void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2, #endif #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ defined(WOLFSSL_ALLOW_TLS_SHA1)) - AddSuiteHashSigAlgo(hashSigAlgo, sha_mac, rsa_sa_algo, keySz, &idx); + if (offerSha1Sig) { + AddSuiteHashSigAlgo(hashSigAlgo, sha_mac, rsa_sa_algo, keySz, &idx); + } #endif } diff --git a/tests/api.c b/tests/api.c index 7cf9225e49..0eb785a475 100644 --- a/tests/api.c +++ b/tests/api.c @@ -19470,6 +19470,12 @@ static int test_wolfSSL_sigalg_info(void) word16 len = 0; word16 idx = 0; int allSigAlgs = SIG_ECDSA | SIG_RSA | SIG_SM2 | SIG_FALCON | SIG_MLDSA; +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || defined(WOLFSSL_ALLOW_TLS_SHA1)) + int sawSha1 = 0; +#endif +#ifndef WOLFSSL_ALLOW_TLS_SHA1 + int tls13 = 0; +#endif InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, 1, 0xFFFFFFFF, &len); for (idx = 0; idx < len; idx += 2) { @@ -19495,6 +19501,37 @@ static int test_wolfSSL_sigalg_info(void) ExpectIntNE(hashAlgo, 0); } + /* RFC 9155 deprecates SHA-1 signatures for TLS 1.2, and RFC 8446 forbids + * them for TLS 1.3. When the negotiated version is TLS 1.2 or higher + * (tls1_2 argument set, whether or not tls1_3 is also set) the SHA-1 + * schemes must not be offered unless the operator opts in with + * WOLFSSL_ALLOW_TLS_SHA1. */ +#ifndef WOLFSSL_ALLOW_TLS_SHA1 + for (tls13 = 0; tls13 <= 1; tls13++) { + InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, tls13, 0xFFFFFFFF, + &len); + for (idx = 0; idx < len; idx += 2) { + ExpectFalse((hashSigAlgo[idx] == sha_mac) && + ((hashSigAlgo[idx + 1] == rsa_sa_algo) || + (hashSigAlgo[idx + 1] == ecc_dsa_sa_algo))); + } + } +#endif + + /* For a TLS 1.0/1.1 handshake the SHA-1 schemes remain available when + * they are compiled in. */ +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || defined(WOLFSSL_ALLOW_TLS_SHA1)) + InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 0, 0, 0xFFFFFFFF, &len); + for (idx = 0; idx < len; idx += 2) { + if ((hashSigAlgo[idx] == sha_mac) && + ((hashSigAlgo[idx + 1] == rsa_sa_algo) || + (hashSigAlgo[idx + 1] == ecc_dsa_sa_algo))) { + sawSha1 = 1; + } + } + ExpectIntEQ(sawSha1, 1); +#endif + #endif return EXPECT_RESULT(); }