]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUILD: quic: allow USE_QUIC to work with AWSLC
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 4 Oct 2023 14:32:08 +0000 (16:32 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Wed, 4 Oct 2023 14:55:19 +0000 (16:55 +0200)
This patch fixes the build with AWSLC and USE_QUIC=1, this is only meant
to be able to build for now and it's not feature complete.

The set_encryption_secrets callback has been split in set_read_secret
and set_write_secret.

Missing features:

- 0RTT was disabled.
- TLS1_3_CK_CHACHA20_POLY1305_SHA256, TLS1_3_CK_AES_128_CCM_SHA256 were disabled
- clienthello callback is missing, certificate selection could be
  limited (RSA + ECDSA at the same time)

include/haproxy/quic_tls-t.h
include/haproxy/quic_tls.h
src/quic_ssl.c

index 3a0c27ac50b63c5d65092dd787abcb5464354bab..ef3232aea17e7db5423be40b7db9c49bfebe1afe 100644 (file)
@@ -26,7 +26,7 @@
 
 /* It seems TLS 1.3 ciphersuites macros differ between openssl and boringssl */
 
-#if defined(OPENSSL_IS_BORINGSSL)
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
 #if !defined(TLS1_3_CK_AES_128_GCM_SHA256)
 #define TLS1_3_CK_AES_128_GCM_SHA256       TLS1_CK_AES_128_GCM_SHA256
 #endif
index f82f3f3973f3427da5adb63cb6a915bbbce7022e..1a316b282a0d6206739019e522391e7c01802b36 100644 (file)
@@ -141,9 +141,11 @@ static inline const EVP_CIPHER *tls_aead(const SSL_CIPHER *cipher)
                return EVP_aes_128_gcm();
        case TLS1_3_CK_AES_256_GCM_SHA384:
                return EVP_aes_256_gcm();
+#if !defined(OPENSSL_IS_AWSLC)
        case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
                return EVP_chacha20_poly1305();
-#ifndef USE_OPENSSL_WOLFSSL
+#endif
+#if !defined(USE_OPENSSL_WOLFSSL) && !defined(OPENSSL_IS_AWSLC)
        case TLS1_3_CK_AES_128_CCM_SHA256:
                return EVP_aes_128_ccm();
 #endif
@@ -169,8 +171,10 @@ static inline const EVP_MD *tls_md(const SSL_CIPHER *cipher)
 static inline const EVP_CIPHER *tls_hp(const SSL_CIPHER *cipher)
 {
        switch (SSL_CIPHER_get_id(cipher)) {
+#if !defined(OPENSSL_IS_AWSLC)
        case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
                return EVP_chacha20();
+#endif
        case TLS1_3_CK_AES_128_CCM_SHA256:
        case TLS1_3_CK_AES_128_GCM_SHA256:
                return EVP_aes_128_ctr();
@@ -367,7 +371,7 @@ static inline const char *ssl_error_str(int err)
                return "WANT_CONNECT";
        case SSL_ERROR_WANT_ACCEPT:
                return "WANT_ACCEPT";
-#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(USE_OPENSSL_WOLFSSL)
+#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(USE_OPENSSL_WOLFSSL) && !defined(OPENSSL_IS_AWSLC)
        case SSL_ERROR_WANT_ASYNC:
                return "WANT_ASYNC";
        case SSL_ERROR_WANT_ASYNC_JOB:
index 7043c8c62c8d5097dd42db59e8ecf35fde472f8a..37116ca1a843a0677ddddd89801697c6b3f1a9a1 100644 (file)
@@ -302,6 +302,27 @@ write:
        return ret;
 }
 
+#if defined(OPENSSL_IS_AWSLC)
+/* compatibility function for split read/write encryption secrets to be used
+ * with the API which uses 2 callbacks. */
+static inline int ha_quic_set_read_secret(SSL *ssl, enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER *cipher, const uint8_t *secret,
+                                   size_t secret_len)
+{
+       return ha_quic_set_encryption_secrets(ssl, level, secret, NULL, secret_len);
+
+}
+
+static inline int ha_quic_set_write_secret(SSL *ssl, enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER *cipher, const uint8_t *secret,
+                                   size_t secret_len)
+{
+
+       return ha_quic_set_encryption_secrets(ssl, level, NULL, secret, secret_len);
+
+}
+#endif
+
 /* ->add_handshake_data QUIC TLS callback used by the QUIC TLS stack when it
  * wants to provide the QUIC layer with CRYPTO data.
  * Returns 1 if succeeded, 0 if not.
@@ -367,12 +388,25 @@ static int ha_quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8
 }
 
 /* QUIC TLS methods */
+#if defined(OPENSSL_IS_AWSLC)
+/* write/read set secret splitted */
+static SSL_QUIC_METHOD ha_quic_method = {
+       .set_read_secret        = ha_quic_set_read_secret,
+       .set_write_secret       = ha_quic_set_write_secret,
+       .add_handshake_data     = ha_quic_add_handshake_data,
+       .flush_flight           = ha_quic_flush_flight,
+       .send_alert             = ha_quic_send_alert,
+};
+
+#else
+
 static SSL_QUIC_METHOD ha_quic_method = {
        .set_encryption_secrets = ha_quic_set_encryption_secrets,
        .add_handshake_data     = ha_quic_add_handshake_data,
        .flush_flight           = ha_quic_flush_flight,
        .send_alert             = ha_quic_send_alert,
 };
+#endif
 
 /* Initialize the TLS context of a listener with <bind_conf> as configuration.
  * Returns an error count.
@@ -401,7 +435,7 @@ int ssl_quic_initial_ctx(struct bind_conf *bind_conf)
 #  if defined(SSL_OP_NO_ANTI_REPLAY)
        if (bind_conf->ssl_conf.early_data) {
                SSL_CTX_set_options(ctx, SSL_OP_NO_ANTI_REPLAY);
-#   ifdef USE_QUIC_OPENSSL_COMPAT
+#   if defined(USE_QUIC_OPENSSL_COMPAT) || defined(OPENSSL_IS_AWSLC)
                ha_warning("Binding [%s:%d] for %s %s: 0-RTT is not supported in limited QUIC compatibility mode, ignored.\n",
                           bind_conf->file, bind_conf->line, proxy_type_str(bind_conf->frontend), bind_conf->frontend->id);
 #   else
@@ -662,7 +696,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
        if (qc_is_listener(qc)) {
                if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl) == -1)
                        goto err;
-#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L)
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(OPENSSL_IS_AWSLC)
 #ifndef USE_QUIC_OPENSSL_COMPAT
                /* Enabling 0-RTT */
                if (bc->ssl_conf.early_data)