Commit f45c7fe0dd for openssl.org
commit f45c7fe0ddaf6d17ad443b2860f916f689eb3432
Author: sftcd <stephen.farrell@cs.tcd.ie>
Date: Thu Dec 18 13:48:28 2025 +0000
ech_test.c: Add test for trying ECH with TLSv1.2
Fixes DEF-02-006
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
MergeDate: Wed Feb 11 17:19:13 2026
(Merged from https://github.com/openssl/openssl/pull/29593)
diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod
index cc7cb932d4..97bb373c18 100644
--- a/doc/man3/SSL_CTX_set_options.pod
+++ b/doc/man3/SSL_CTX_set_options.pod
@@ -385,16 +385,17 @@ received.
Note that a server that has loaded many ECH configurations and that enables ECH
trial decryption will attempt decryption with every ECH key when presented with
-a GREASEd ECH, and with possibly that many even when presented with a real ECH.
-That could easily become an accidental denial of service.
+a GREASEd ECH, (see B<SSL_OP_ECH_GREASE>) and with possibly that many even
+when presented with a real ECH. That could easily become an accidental denial
+of service.
Note also that the ECH specification recommends that servers that enable this
option consider implementing some form of rate limiting mechanism to limit the
potential damage caused in such scenarios.
If trial decryption is enabled then decryption will be attempted with the ECH
-configurations in the order they were loaded. So, were it possible to load the
-configuration most likely to be used first, that would improve efficiency.
+configurations in the order they were loaded. So, where it is possible to load
+the configuration most likely to be used first, that would improve efficiency.
=item SSL_OP_ECH_GREASE_RETRY_CONFIG
diff --git a/test/ech_test.c b/test/ech_test.c
index 2b6c83a543..6db85bc668 100644
--- a/test/ech_test.c
+++ b/test/ech_test.c
@@ -1192,6 +1192,7 @@ end:
#define OSSL_ECH_TEST_CUSTOM 3
#define OSSL_ECH_TEST_ENOE 4 /* early + no-ech */
#define OSSL_ECH_TEST_CBS 5 /* test callbacks */
+#define OSSL_ECH_TEST_V12 6 /* test TLSv1.2 */
/* note: early-data is prohibited after HRR so no tests for that */
/*
@@ -1247,6 +1248,13 @@ static int test_ech_roundtrip_helper(int idx, int combo)
TLS1_3_VERSION, TLS1_3_VERSION,
&sctx, &cctx, cert, privkey)))
goto end;
+ if (combo == OSSL_ECH_TEST_V12) {
+ /* force client to TLSv1.2 and later fail as expected */
+ if (!TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION)))
+ goto end;
+ if (!TEST_true(SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION)))
+ goto end;
+ }
if (combo == OSSL_ECH_TEST_EARLY || combo == OSSL_ECH_TEST_ENOE) {
if (!TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_ANTI_REPLAY))
|| !TEST_true(SSL_CTX_set_max_early_data(sctx,
@@ -1287,9 +1295,17 @@ static int test_ech_roundtrip_helper(int idx, int combo)
goto end;
if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "server.example")))
goto end;
- if (!TEST_true(create_ssl_connection(serverssl, clientssl,
- SSL_ERROR_NONE)))
+ if (combo == OSSL_ECH_TEST_V12) {
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+ res = 1;
goto end;
+ } else {
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+ }
/* override cert verification */
SSL_set_verify_result(clientssl, X509_V_OK);
clientstatus = SSL_ech_get1_status(clientssl, &cinner, &couter);
@@ -1439,6 +1455,14 @@ static int ech_cb_test(int idx)
return test_ech_roundtrip_helper(idx, OSSL_ECH_TEST_CBS);
}
+/* Test a roundtrip (fails) with ECH but a TLSv1.2 SSL_CTX */
+static int ech_v12_test(int idx)
+{
+ if (verbose)
+ TEST_info("Doing: ech TLSv1.2 test ");
+ return test_ech_roundtrip_helper(idx, OSSL_ECH_TEST_V12);
+}
+
#endif
int setup_tests(void)
@@ -1483,6 +1507,7 @@ int setup_tests(void)
ADD_ALL_TESTS(ech_custom_test, suite_combos);
ADD_ALL_TESTS(ech_enoe_test, suite_combos);
ADD_ALL_TESTS(ech_cb_test, suite_combos);
+ ADD_ALL_TESTS(ech_v12_test, suite_combos);
/* TODO(ECH): add more test code as other PRs done */
return 1;
err: