]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: support for ECDA+RSA certificate selection with AWS-LC
authorWilliam Lallemand <wlallemand@haproxy.com>
Thu, 13 Jun 2024 17:11:52 +0000 (19:11 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 13 Jun 2024 17:36:40 +0000 (19:36 +0200)
AWS-LC does not support the SSL_CTX_set_client_hello_cb() function from
OpenSSL which allows to analyze ciphers and signatures algorithm of the
ClientHello. However it supports the SSL_CTX_set_select_certificate_cb()
which allows the same thing but was the implementation from the
boringSSL side.

This patch uses the SSL_CTX_set_select_certificate_cb() as well as the
SSL_early_callback_ctx_extension_get() function to get the signature
algorithms.

This was successfully tested with openssl s_client as well as
testssl.sh.

This should allow to enable more reg-tests that depend on certificate
selection.

Require at least AWS-LC 1.22.0.

include/haproxy/openssl-compat.h
include/haproxy/ssl_sock.h
src/quic_ssl.c
src/ssl_clienthello.c
src/ssl_sock.c

index d145fb485271a222c9ff745bea3167c6c87c8e26..66c30ff09122166bb2e5463a496f4ef4073e00d2 100644 (file)
@@ -79,7 +79,7 @@
 #define HAVE_ASN1_TIME_TO_TM
 #endif
 
-#if (defined(SSL_CLIENT_HELLO_CB) || defined(OPENSSL_IS_BORINGSSL))
+#if (defined(SSL_CLIENT_HELLO_CB) || defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC))
 #define HAVE_SSL_CLIENT_HELLO_CB
 #endif
 
index 6f9d439726a7a7288aed25a814d8f8f3a8f40c5e..c846fe0342b5349e8ec2cf814a551b272c5c138f 100644 (file)
@@ -104,7 +104,7 @@ void ssl_unload_providers(void);
 
 #ifdef HAVE_SSL_CLIENT_HELLO_CB
 int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv);
-# ifdef OPENSSL_IS_BORINGSSL
+# if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
 int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx);
 # else /* ! OPENSSL_IS_BORINGSSL */
 int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg);
index 66eb68eb2bc5d99d684e98cc0d5b8dfff2a27829..0b27c7403b81a43feebfd2d456267ecee74eac24 100644 (file)
@@ -459,7 +459,10 @@ int ssl_quic_initial_ctx(struct bind_conf *bind_conf)
        }
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-# if defined(HAVE_SSL_CLIENT_HELLO_CB)
+# if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
+       SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
+       SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
+# elif defined(HAVE_SSL_CLIENT_HELLO_CB)
        SSL_CTX_set_client_hello_cb(ctx, ssl_sock_switchctx_cbk, NULL);
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
 # else /* ! HAVE_SSL_CLIENT_HELLO_CB */
index 23719558e94ff6e62f406373aefc1df8c8cc06e8..4044a672040b0338639c9e7530d19f3fe25264a2 100644 (file)
@@ -131,7 +131,7 @@ int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
        return SSL_TLSEXT_ERR_NOACK;
 }
 
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
 int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 {
        SSL *ssl = ctx->ssl;
@@ -170,7 +170,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
 #ifdef USE_QUIC
        if (qc) {
                /* Look for the QUIC transport parameters. */
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
                if (!SSL_early_callback_ctx_extension_get(ctx, qc->tps_tls_ext,
                                                          &extension_data, &extension_len))
 #else
@@ -182,7 +182,9 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                         * <*al>, this has as side effect to generate another TLS alert
                         * which would be set after calling quic_set_tls_alert().
                         */
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(USE_OPENSSL_AWSLC)
                        *al = SSL_AD_MISSING_EXTENSION;
+#endif
                        quic_set_tls_alert(qc, SSL_AD_MISSING_EXTENSION);
                        return 0;
                }
@@ -197,7 +199,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
 
        if (s->ssl_conf.early_data)
                allow_early = 1;
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
        if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
                                                 &extension_data, &extension_len)) {
 #else
@@ -251,7 +253,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
        }
 
        /* extract/check clientHello information */
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
        if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
 #else
        if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
@@ -296,7 +298,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                ha_ciphers = SSL_get_ciphers(ssl);
                has_ecdsa_sig = 0;
 
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
                len = ctx->cipher_suites_len;
                cipher_suites = ctx->cipher_suites;
 #else
@@ -305,7 +307,7 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                if (len % 2 != 0)
                        goto abort;
                for (; len != 0; len -= 2, cipher_suites += 2) {
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
                        uint16_t cipher_suite = (cipher_suites[0] << 8) | cipher_suites[1];
                        cipher = SSL_get_cipher_by_value(cipher_suite);
 #else
@@ -392,7 +394,7 @@ sni_lookup:
        /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
        if (conn)
                conn->err_code = CO_ER_SSL_HANDSHAKE;
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
        return ssl_select_cert_error;
 #else
        *al = SSL_AD_UNRECOGNIZED_NAME;
@@ -400,7 +402,7 @@ sni_lookup:
 #endif
 
 allow_early:
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
        if (allow_early)
                SSL_set_early_data_enabled(ssl, 1);
 #else
index 87ee42f1a700bfb1c301ba2dd41cceccb6b1be14..e5eb746cf5e4c7b76a865462ab39f3245e2e80cf 100644 (file)
@@ -3440,7 +3440,7 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
                SSL_CTX_set_timeout(ctx, global_ssl.life_time);
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-# ifdef OPENSSL_IS_BORINGSSL
+# if defined(OPENSSL_IS_BORINGSSL) || defined(USE_OPENSSL_AWSLC)
        SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
 # elif defined(HAVE_SSL_CLIENT_HELLO_CB)