From: William Lallemand Date: Thu, 22 Oct 2026 15:12:18 +0000 (+0000) Subject: BUG/MEDIUM: ssl: support SCTL with AWS-LC X-Git-Tag: v3.5-dev10~8 X-Git-Url: https://git.kaiwu.me/$%7BISSUES%7D/static/gitweb.js?a=commitdiff_plain;h=67e01b4a90dc0c9d63d70126d8221ebafbe5a87c;p=haproxy.git BUG/MEDIUM: ssl: support SCTL with AWS-LC AWS-LC owns extension 18 and rejects server custom extension registration. The previous commit skips that registration, leaving .sctl files ignored. Use SSL_CTX_set_signed_cert_timestamp_list(), available in all AWS-LC releases, to set the serialized SCT list. AWS-LC copies the list and handles context switches. Enable HAVE_SSL_SCTL for AWS-LC despite its missing SN_ct_cert_scts OID. AWS-LC also validates the list. Report a rejected list as a warning and omit the extension, allowing the certificate to remain usable. Tested with AWS-LC 4.2.0 and 3.0.0: TLS 1.2 sends the exact SCT payload for the selected certificate with a sidecar and omits it for another certificate on the same bind. This must be backported to 3.0, the first version supporting AWS-LC. --- diff --git a/include/haproxy/openssl-compat.h b/include/haproxy/openssl-compat.h index 5c37d6584..4918024f5 100644 --- a/include/haproxy/openssl-compat.h +++ b/include/haproxy/openssl-compat.h @@ -127,6 +127,11 @@ enum ssl_encryption_level_t { #define HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT #endif +#if (defined(OPENSSL_IS_AWSLC)) +/* AWS-LC owns extension 18; its native SCT API is available in all releases. */ +#define HAVE_SSL_CTX_SET_SIGNED_CERT_TIMESTAMP_LIST +#endif + #if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) && !defined(LIBRESSL_VERSION_NUMBER)) #define HAVE_SSL_CTX_get0_privatekey #endif @@ -141,7 +146,8 @@ enum ssl_encryption_level_t { #define HAVE_VANILLA_OPENSSL #endif -#if (defined(SN_ct_cert_scts) && !defined(OPENSSL_NO_TLSEXT)) +#if ((defined(SN_ct_cert_scts) && !defined(OPENSSL_NO_TLSEXT)) || defined(OPENSSL_IS_AWSLC)) +/* AWS-LC supports SCT lists without defining the CT OID SN_ct_cert_scts. */ #define HAVE_SSL_SCTL #endif diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 4a70975d9..f3bd0f5fd 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1673,6 +1673,8 @@ static int ssl_sock_load_ocsp(const char *path, SSL_CTX *ctx, struct ckch_data * #endif +#if defined(HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT) || defined(HAVE_SSL_CTX_SET_SIGNED_CERT_TIMESTAMP_LIST) + #ifdef HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT #define CT_EXTENSION_TYPE 18 @@ -1703,12 +1705,21 @@ static __maybe_unused int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, return 1; } +#endif /* HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT */ + /* Attaches to . Returns 0 on success or -1 on failure. */ static int ssl_sock_load_sctl(SSL_CTX *ctx, struct buffer *sctl) { +#ifdef HAVE_SSL_CTX_SET_SIGNED_CERT_TIMESTAMP_LIST + /* AWS-LC validates and copies the list, including on context switches. */ + if (!SSL_CTX_set_signed_cert_timestamp_list(ctx, (const uint8_t *)sctl->area, sctl->data)) + return -1; + return 0; +#else if (!SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl)) return -1; return 0; +#endif } #endif @@ -3247,14 +3258,23 @@ static int ssl_sock_put_ckch_into_ctx(const char *path, struct ckch_store *store } #endif -#ifdef HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT - if (sctl_ex_index >= 0 && data->sctl) { +#if defined(HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT) || defined(HAVE_SSL_CTX_SET_SIGNED_CERT_TIMESTAMP_LIST) + if (data->sctl) { +#ifdef HAVE_SSL_CTX_SET_SIGNED_CERT_TIMESTAMP_LIST + /* A list rejected by AWS-LC only disables SCT delivery; warn and continue. */ if (ssl_sock_load_sctl(ctx, data->sctl) < 0) { + memprintf(err, "%s '%s.sctl' is present but cannot be parsed by SSL_CTX_set_signed_cert_timestamp_list, the SCTL extension will not be sent.\n", + err && *err ? *err : "", path); + errcode |= ERR_WARN; + } +#else + if (sctl_ex_index >= 0 && ssl_sock_load_sctl(ctx, data->sctl) < 0) { memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n", err && *err ? *err : "", path); errcode |= ERR_ALERT | ERR_FATAL; goto end; } +#endif } #endif