From 96d75e6d86cf1b19466240b83a68e53ad8e7c0f1 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 12 Jun 2025 16:50:08 +0200 Subject: [PATCH] BUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers Patch 23093c72 ("BUG/MINOR: ssl: suboptimal certificate selection with TLSv1.3 and dual ECDSA/RSA") introduced a problem when prioritizing the ECDSA with TLSv1.3. Indeed, when a client with TLSv1.3 capabilities announce a list of ECDSA sigalgs, a list of TLSv1.3 ciphersuites compatible with ECDSA, but only RSA ciphers for TLSv1.2, and haproxy is configured to a ssl-max-ver TLSv1.2, then haproxy would use the ECDSA keypair, but the client wouldn't be able to process it because TLSv1.2 was negociated. HAProxy would be configured like that: ssl-default-bind-options ssl-max-ver TLSv1.2 And a client could be used this way: openssl s_client -connect localhost:8443 -cipher ECDHE-ECDSA-AES128-GCM-SHA256 \ -ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 This patch fixes the issue by checking if TLSv1.3 was configured before allowing ECDSA is an TLSv1.3 ciphersuite is in the list. This could be backported where 23093c72 ("BUG/MINOR: ssl: suboptimal certificate selection with TLSv1.3 and dual ECDSA/RSA") was backported. However this is quite sensible and we should wait a bit before the backport. This should fix issue #2988 --- src/ssl_clienthello.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ssl_clienthello.c b/src/ssl_clienthello.c index ca0d6fb27..9d2f45093 100644 --- a/src/ssl_clienthello.c +++ b/src/ssl_clienthello.c @@ -396,8 +396,16 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) if (cipher_id == SSL3_CK_SCSV || cipher_id == SSL3_CK_FALLBACK_SCSV) continue; - if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa - || SSL_CIPHER_get_auth_nid(cipher) == NID_auth_any) { + if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) { + has_ecdsa_sig = 1; + break; + } + if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_any && + s->ssl_conf.ssl_methods.max >= CONF_TLSV13) { + /* Checking for TLSv1.3 ciphersuites require to check that we allow TLSv1.3, otherwise it would + * chose an ECDSA cipher because of the TLS13 ciphersuites, but the TLS12 ciphers could + * lack ECDSA capabilities. + */ has_ecdsa_sig = 1; break; }