]> git.ipfire.org Git - thirdparty/haproxy.git/commit
MEDIUM: ssl: allow multiple fallback certificate to allow ECDSA/RSA selection
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 10 Jan 2024 13:05:59 +0000 (14:05 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 12 Jan 2024 16:40:42 +0000 (17:40 +0100)
commit30592168e5fc9111976510bc6bc0ec87065d70c2
treed490de3bd49fe55598e63be5157dfb05f772cae6
parent333f2cababa36f4289493647fed4f7dce0babc77
MEDIUM: ssl: allow multiple fallback certificate to allow ECDSA/RSA selection

This patch changes the default certificate mechanism.

Since the beginning of SSL in HAProxy, the default certificate was the first
certificate of a bind line. This allowed to fallback on this certificate
when no servername extension was sent by the server, or when no SAN nor
CN was available in the certificate.

When using a multi-certificate bundle (ecdsa+rsa), it was possible to
have both certificates as the fallback one, leting openssl chose the
right one. This was possible because a multi-certificate bundle
was generating a unique SSL_CTX for both certificates.

When the haproxy and openssl architecture evolved, we decided to
use multiple SSL_CTX for a multi-cert bundle, in order to simplify the
code and allow updates over the CLI.

However only one default_ctx was allowed, so we lost the ability to
chose between ECDSA and RSA for the default certificate.

This patch allows to use a '*' filter for a certificate, which allow to
lookup between multiple '*' filter, and have one in RSA and another one
in ECDSA. It replaces the default_ctx mechanism in the ClientHello
callback and use the standard algorithm to look for a default cert and
chose between ECDSA and RSA.

/!\ This patch breaks the automatic setting of the default certificate, which
will be introduce in the next patch. So the first certificate of a bind
line won't be used as a defaullt anymore.

To use this feature, one could use crt-list with '*' filters:

$ cat foo.crtlist
foobar.pem.rsa   *
foobar.pem.ecdsa *

In order to test the feature, it's easy to send a request without
the servername extension and use ECDSA or RSA compatible ciphers:

$ openssl s_client -connect localhost:8443 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384
$ openssl s_client -connect localhost:8443 -tls1_2 -cipher ECDHE-ECDSA-AES256-GCM-SHA384
src/ssl_sock.c