From 3833db7c7cb167e8eda2ec5e07da70cd834e88d4 Mon Sep 17 00:00:00 2001 From: Viktor Sokolovskiy Date: Fri, 17 Apr 2026 18:52:34 +0300 Subject: [PATCH] ssl: narrow TLS 1.2 RSA-PSS handling and add interop coverage Narrow TLS 1.2 RSA-PSS handling to the client ServerKeyExchange parse path and add OpenSSL and GnuTLS interoperability tests. Signed-off-by: Viktor Sokolovskiy --- ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt | 3 +- library/ssl_misc.h | 19 ------- library/ssl_tls12_client.c | 63 +++++++++++++++++++---- tests/ssl-opt.sh | 38 +++++++++++++- tests/suites/test_suite_ssl.data | 12 ----- tests/suites/test_suite_ssl.function | 8 --- 6 files changed, 91 insertions(+), 52 deletions(-) diff --git a/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt index 29400b2c46..34296b602e 100644 --- a/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt +++ b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt @@ -1,3 +1,4 @@ Bugfix * Fix a TLS 1.2 regression that caused clients to reject valid - ServerKeyExchange signatures using RSA-PSS signature scheme values. + ServerKeyExchange signatures using RSA-PSS signature algorithms. + Fixes #10668. diff --git a/library/ssl_misc.h b/library/ssl_misc.h index fdb7013347..218a30d408 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2591,25 +2591,6 @@ static inline int mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( static inline int mbedtls_ssl_tls12_sig_alg_is_supported( const uint16_t sig_alg) { -#if defined(PSA_WANT_ALG_RSA_PSS) - switch (sig_alg) { -#if defined(PSA_WANT_ALG_SHA_256) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_384) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_512) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - return 1; -#endif - default: - break; - } -#endif /* PSA_WANT_ALG_RSA_PSS */ - /* High byte is hash */ unsigned char hash = MBEDTLS_BYTE_1(sig_alg); unsigned char sig = MBEDTLS_BYTE_0(sig_alg); diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 0196c0cc53..b9f01db3af 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -13,6 +13,7 @@ #include "mbedtls/ssl.h" #include "ssl_client.h" +#include "ssl_debug_helpers.h" #include "ssl_misc.h" #include "debug_internal.h" #include "mbedtls/error.h" @@ -2087,32 +2088,72 @@ static int ssl_parse_signature_algorithm(mbedtls_ssl_context *ssl, { if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(sig_alg, pk_alg, md_alg) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); + ("Server used unsupported %s signature algorithm", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; } /* - * mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg() understands sig_alg code points across - * TLS versions. Make sure that the received sig_alg extension is valid in TLS 1.2. + * mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg() understands + * signature algorithm code points from both TLS 1.2 and TLS 1.3. Make sure + * that the selected signature algorithm is acceptable when TLS 1.2 is + * negotiated. + * + * In TLS 1.2, RSA-PSS signature algorithms (rsa_pss_rsae_*) are not + * defined by RFC 5246. However, RFC 8446 Section 4.2.3 requires that + * implementations which advertise support for RSASSA-PSS must be + * prepared to accept such signatures even when TLS 1.2 is negotiated, + * provided they were offered in the signature_algorithms extension. + * + * Therefore, we allow rsa_pss_rsae_* here if: + * - the implementation supports them, and + * - they were offered in the signature_algorithms extension (checked by + * `mbedtls_ssl_sig_alg_is_offered()` below). + * + * If we were to add full support for rsa_pss_rsae_* signature algorithms + * in TLS 1.2, we should then integrate RSA-PSS into the TLS 1.2 signature + * algorithm support logic (`mbedtls_ssl_tls12_sig_alg_is_supported()`) + * instead of handling it as a special case here. */ if (!mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); - return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + switch (sig_alg) { +#if defined(PSA_WANT_ALG_RSA_PSS) +#if defined(PSA_WANT_ALG_SHA_256) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: +#endif +#if defined(PSA_WANT_ALG_SHA_384) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: +#endif +#if defined(PSA_WANT_ALG_SHA_512) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: +#endif +#if defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA_512) + MBEDTLS_SSL_DEBUG_MSG(3, + ("Accepting TLS 1.2 RSA-PSS signature algorithm %s via compatibility exception", + mbedtls_ssl_sig_alg_to_str(sig_alg))); + break; +#endif +#endif /* PSA_WANT_ALG_RSA_PSS */ + default: + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used unsupported %s signature algorithm", + mbedtls_ssl_sig_alg_to_str(sig_alg))); + return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + } } /* * Check if the signature algorithm is acceptable */ if (!mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Server used SigAlg value 0x%04x that was not offered", sig_alg)); + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used the signature algorithm %s that was not offered", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; } - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used SignatureAlgorithm %d", sig_alg & 0x00FF)); - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used HashAlgorithm %d", sig_alg >> 8)); + MBEDTLS_SSL_DEBUG_MSG(2, ("Server used the signature algorithm %s", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return 0; } diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 6ea8db1e01..73515b4a92 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -14948,7 +14948,6 @@ run_test "TLS 1.2: Check rsa_pss_rsae compatibility issue, m->O" \ -c "Protocol is TLSv1.2" \ -c "HTTP/1.0 200 [Oo][Kk]" - requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_DEBUG_C @@ -14964,6 +14963,43 @@ run_test "TLS 1.2: Check rsa_pss_rsae compatibility issue, m->G" \ -c "Protocol is TLSv1.2" \ -c "HTTP/1.0 200 [Oo][Kk]" +requires_openssl_tls1_3_with_compatible_ephemeral +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled PSA_WANT_ALG_RSA_PSS +requires_config_enabled PSA_WANT_ALG_SHA_256 +run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->O" \ + "$O_NEXT_SRV_NO_CERT -cert $DATA_FILES_PATH/server2-sha256.crt -key $DATA_FILES_PATH/server2.key + -tls1_2 -sigalgs rsa_pss_rsae_sha256 " \ + "$P_CLI debug_level=3" \ + 0 \ + -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \ + -c "Perform .* computation of digest of ServerKeyExchange" \ + -c "Server used the signature algorithm rsa_pss_rsae_sha256" \ + -c "Protocol is TLSv1.2" \ + -c "HTTP/1.0 200 [Oo][Kk]" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled PSA_WANT_ALG_RSA_PSS +requires_config_enabled PSA_WANT_ALG_SHA_256 +run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->G" \ + "$G_NEXT_SRV_NO_CERT --x509certfile $DATA_FILES_PATH/server2-sha256.crt --x509keyfile $DATA_FILES_PATH/server2.key + --disable-client-cert + --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256" \ + "$P_CLI debug_level=3" \ + 0 \ + -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \ + -c "Perform .* computation of digest of ServerKeyExchange" \ + -c "Server used the signature algorithm rsa_pss_rsae_sha256" \ + -c "Protocol is TLSv1.2" \ + -c "HTTP/1.0 200 [Oo][Kk]" + requires_config_enabled MBEDTLS_SSL_SRV_C requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 5a3fe446e6..06e8b62303 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3546,15 +3546,3 @@ send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECDSA:MBEDTLS_SSL_HASH_SHA512:MBEDTLS_ERR_S Default verify_result before doing a handshake verify_result_without_handshake - -TLS 1.2 accepts rsa_pss_rsae_sha256 in signature_algorithm -depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256 -ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:1 - -TLS 1.2 accepts rsa_pss_rsae_sha384 in signature_algorithm -depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_384 -ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:1 - -TLS 1.2 accepts rsa_pss_rsae_sha512 in signature_algorithm -depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512 -ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:1 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index c11fad428e..ae7ab55366 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5861,14 +5861,6 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -void ssl_tls12_sig_alg_supported(int sig_alg, int expected) -{ - TEST_EQUAL(mbedtls_ssl_tls12_sig_alg_is_supported((uint16_t) sig_alg), - expected); -} -/* END_CASE */ - /* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context) {