--- /dev/null
+#REGTEST_TYPE=bug
+varnishtest "Test for per-certificate curves 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)'"
+# This test checks that the curves set on a crt-list line are enforced over
+# QUIC, even when the bind line allows more of them.
+
+setenv VTC_SOCK_TYPE quic
+include ${testdir}/../ssl/ssl_crt-list_curves.vtci
--- /dev/null
+common.pem [curves P-384] restricted.curves.domain.tld
+common.pem open.curves.domain.tld
--- /dev/null
+#REGTEST_TYPE=bug
+varnishtest "Test for per-certificate curves in a crt-list"
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.8)'"
+feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1) || feature(OPENSSL_AWSLC)'"
+# This test checks that the curves set on a crt-list line are enforced, even
+# when the bind line allows more of them.
+
+setenv VTC_SOCK_TYPE stream
+include ${testdir}/ssl_crt-list_curves.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 }
+
+ # curve allowed by the crt-list line
+ backend allowed
+ server s1 ${VTC_SOCK_TYPE}+${h1_ssllst_sock} ssl verify none sni str(restricted.curves.domain.tld) curves P-384
+
+ # curve 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.curves.domain.tld) curves P-256
+
+ # same excluded curve, but for a certificate without restriction
+ backend open
+ server s1 ${VTC_SOCK_TYPE}+${h1_ssllst_sock} ssl verify none sni str(open.curves.domain.tld) curves P-256
+
+ listen ssl-lst
+ bind ${VTC_SOCK_TYPE}+fd@${ssllst} ssl strict-sni crt-list ${testdir}/certs/curves.crt-list curves P-256:P-384
+ server s1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_clearlst_sock} {
+ txreq -url "/allowed"
+ rxresp
+ expect resp.status == 200
+} -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
+} -run
struct ssl_bind_conf *conf = sni_ctx->conf;
ssl_sock_switchctx_set(ssl, sni_ctx->ctx);
if (conf) {
+#if defined(SSL_CTX_set1_curves_list)
+ const char *curves;
+#endif
+
methodVersions[conf->ssl_methods.min].ssl_set_version(ssl, SET_MIN);
methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX);
if (conf->early_data)
SSL_EV_CONN_SWITCHCTX_CB|SSL_EV_CONN_ERR, conn);
goto abort;
}
+#endif
+#if defined(SSL_CTX_set1_curves_list)
+ /* Reapply the curves copied at SSL_new() time, using the
+ * same precedence as when preparing the SSL_CTX: crt-list
+ * curves, bind curves, crt-list ecdhe, then bind ecdhe.
+ * This call is inefficient as it parses the curves
+ * configuration string for each connection.
+ */
+ curves = conf->curves ? conf->curves : s->ssl_conf.curves;
+ if (!curves)
+ curves = conf->ecdhe ? conf->ecdhe : s->ssl_conf.ecdhe;
+
+ if (curves && !SSL_set1_curves_list(ssl, curves)) {
+ HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
+ TRACE_ERROR("Cannot set the crt-list curves 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);