From 23093c72f139eddfce68ea5580193ee131901591 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Tue, 24 Oct 2023 23:58:02 +0200 Subject: [PATCH] BUG/MINOR: ssl: suboptimal certificate selection with TLSv1.3 and dual ECDSA/RSA When using TLSv1.3, the signature algorithms extension is used to chose the right ECDSA or RSA certificate. However there was an old test for previous version of TLS (< 1.3) which was testing if the cipher is compatible with ECDSA when an ECDSA signature algorithm is used. This test was relying on SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa to verify if the cipher is still good. Problem is, with TLSv1.3, all ciphersuites are compatible with any authentication algorithm, but SSL_CIPHER_get_auth_nid(cipher) does not return NID_auth_ecdsa, but NID_auth_any. Because of this, with TLSv1.3 when both ECDSA and RSA certificates are available for a domain, the ECDSA one is not chosen in priority. This patch also introduces a test on the cipher IDs for the signaling ciphersuites, because they would always return NID_auth_any, and are not relevent for this selection. This patch fixes issue #2300. Must be backported in all stable versions. --- src/ssl_sock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 8a3a1b04f1..0e83253464 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -2487,6 +2487,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) } if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */ const SSL_CIPHER *cipher; + uint32_t cipher_id; size_t len; const uint8_t *cipher_suites; has_ecdsa_sig = 0; @@ -2505,7 +2506,13 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) #else cipher = SSL_CIPHER_find(ssl, cipher_suites); #endif - if (cipher && SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) { + cipher_id = SSL_CIPHER_get_id(cipher); + /* skip the SCSV "fake" signaling ciphersuites because they are NID_auth_any (RFC 7507) */ + if (cipher_id == SSL3_CK_SCSV || cipher_id == SSL3_CK_FALLBACK_SCSV) + continue; + + if (cipher && ( SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa + || SSL_CIPHER_get_auth_nid(cipher) == NID_auth_any)) { has_ecdsa_sig = 1; break; } -- 2.39.5