--- /dev/null
+#REGTEST_TYPE=bug
+varnishtest "Test for per-certificate ciphersuites in a crt-list over QUIC"
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.8)'"
+feature cmd "$HAPROXY_PROGRAM -cc 'feature(QUIC) && !feature(QUIC_OPENSSL_COMPAT) && !feature(OPENSSL_WOLFSSL) && !ssllib_name_startswith(LibreSSL) && !ssllib_name_startswith(BoringSSL)'"
+# This test checks that the ciphersuites set on a crt-list line are enforced
+# over QUIC, even when the bind line allows more of them.
+# See GitHub issue #3500.
+
+setenv VTC_SOCK_TYPE quic
+include ${testdir}/../ssl/ssl_crt-list_ciphersuites.vtci
--- /dev/null
+common.pem [ciphers ECDHE-RSA-AES128-GCM-SHA256] restricted.bug3500.domain.tld
+common.pem open.bug3500.domain.tld
--- /dev/null
+common.pem [ciphersuites TLS_AES_128_GCM_SHA256] restricted.bug3500.domain.tld
+common.pem open.bug3500.domain.tld
--- /dev/null
+#REGTEST_TYPE=bug
+varnishtest "Test for per-certificate ciphers in a crt-list"
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.8)'"
+feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && !feature(OPENSSL_WOLFSSL)'"
+# This test checks that the ciphers set on a crt-list line are enforced, even
+# when the bind line allows more of them. It uses TLSv1.2, so there is no QUIC
+# variant.
+# See GitHub issue #3500.
+feature ignore_unknown_macro
+
+server s1 -repeat 2 {
+ rxreq
+ txresp
+} -start
+
+haproxy h1 -conf {
+ global
+ .if feature(THREAD)
+ thread-groups 1
+ .endif
+ crt-base ${testdir}/certs
+
+ defaults
+ mode http
+ option httplog
+ retries 0
+ log stderr local0 debug err
+ option logasap
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ listen clear-lst
+ bind "fd@${clearlst}"
+ use_backend allowed if { path /allowed }
+ use_backend excluded if { path /excluded }
+ use_backend open if { path /open }
+
+ # cipher allowed by the crt-list line
+ backend allowed
+ server s1 ${h1_ssllst_sock} ssl verify none sni str(restricted.bug3500.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers ECDHE-RSA-AES128-GCM-SHA256
+
+ # cipher allowed by the bind line but excluded by the crt-list line
+ backend excluded
+ server s1 ${h1_ssllst_sock} ssl verify none sni str(restricted.bug3500.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers ECDHE-RSA-AES256-GCM-SHA384
+
+ # same excluded cipher, but for a certificate without restriction
+ backend open
+ server s1 ${h1_ssllst_sock} ssl verify none sni str(open.bug3500.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers ECDHE-RSA-AES256-GCM-SHA384
+
+ listen ssl-lst
+ http-response add-header x-cipher %[ssl_fc_cipher]
+ bind "fd@${ssllst}" ssl strict-sni crt-list ${testdir}/certs/ciphers.crt-list ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
+ server s1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/allowed"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-cipher == ECDHE-RSA-AES128-GCM-SHA256
+} -run
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/excluded"
+ rxresp
+ expect resp.status == 503
+} -run
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/open"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-cipher == ECDHE-RSA-AES256-GCM-SHA384
+} -run
--- /dev/null
+#REGTEST_TYPE=bug
+varnishtest "Test for per-certificate ciphersuites in a crt-list"
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.8)'"
+feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && !ssllib_name_startswith(LibreSSL) && !ssllib_name_startswith(BoringSSL) && !feature(OPENSSL_WOLFSSL)'"
+# This test checks that the ciphersuites set on a crt-list line are enforced,
+# even when the bind line allows more of them.
+# See GitHub issue #3500.
+
+setenv VTC_SOCK_TYPE stream
+include ${testdir}/ssl_crt-list_ciphersuites.vtci
--- /dev/null
+feature ignore_unknown_macro
+
+server s1 -repeat 2 {
+ rxreq
+ txresp
+} -start
+
+haproxy h1 -conf {
+ global
+ .if streq("$VTC_SOCK_TYPE",quic)
+ # required for backend connections
+ expose-experimental-directives
+ .endif
+ .if feature(THREAD)
+ thread-groups 1
+ .endif
+ crt-base ${testdir}/certs
+
+ defaults
+ mode http
+ option httplog
+ retries 0
+ log stderr local0 debug err
+ option logasap
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ listen clear-lst
+ bind "fd@${clearlst}"
+ use_backend allowed if { path /allowed }
+ use_backend excluded if { path /excluded }
+ use_backend open if { path /open }
+
+ # ciphersuite allowed by the crt-list line
+ backend allowed
+ server s1 ${VTC_SOCK_TYPE}+${h1_ssllst_sock} ssl verify none sni str(restricted.bug3500.domain.tld) ssl-min-ver TLSv1.3 ciphersuites TLS_AES_128_GCM_SHA256
+
+ # ciphersuite allowed by the bind line but excluded by the crt-list line
+ backend excluded
+ server s1 ${VTC_SOCK_TYPE}+${h1_ssllst_sock} ssl verify none sni str(restricted.bug3500.domain.tld) ssl-min-ver TLSv1.3 ciphersuites TLS_AES_256_GCM_SHA384
+
+ # same excluded ciphersuite, but for a certificate without restriction
+ backend open
+ server s1 ${VTC_SOCK_TYPE}+${h1_ssllst_sock} ssl verify none sni str(open.bug3500.domain.tld) ssl-min-ver TLSv1.3 ciphersuites TLS_AES_256_GCM_SHA384
+
+ listen ssl-lst
+ http-response add-header x-cipher %[ssl_fc_cipher]
+ bind ${VTC_SOCK_TYPE}+fd@${ssllst} ssl strict-sni crt-list ${testdir}/certs/ciphersuites.crt-list ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
+ server s1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/allowed"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-cipher == TLS_AES_128_GCM_SHA256
+} -run
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/excluded"
+ rxresp
+ expect resp.status == 503
+} -run
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/open"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-cipher == TLS_AES_256_GCM_SHA384
+} -run
methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX);
if (conf->early_data)
allow_early = 1;
+#if defined(OPENSSL_IS_AWSLC) && AWSLC_API_VERSION > 30
+ /* AWS-LC copies the cipher lists at SSL_new() time and does
+ * not update them on SSL_set_SSL_CTX(). Reapply the crt-list
+ * options. API version 30 (AWS-LC 3.x) uses the SSL_CTX
+ * cipher lists directly and does not need this workaround.
+ * These calls are inefficient as they parse the cipher
+ * configuration strings for each connection.
+ */
+ if ((conf->ciphers && !SSL_set_cipher_list(ssl, conf->ciphers)) ||
+ (conf->ciphersuites && !SSL_set_ciphersuites(ssl, conf->ciphersuites))) {
+ HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
+ TRACE_ERROR("Cannot set the crt-list ciphers on the SSL object",
+ SSL_EV_CONN_SWITCHCTX_CB|SSL_EV_CONN_ERR, conn);
+ goto abort;
+ }
+#endif
}
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
goto allow_early;