Commit dc449562f4 for openssl.org
commit dc449562f42db8d20f2d3153580a0292f07bfc3e
Author: sftcd <stephen.farrell@cs.tcd.ie>
Date: Fri Mar 13 22:02:29 2026 +0000
ECH: chunk-size bug fix and non-regression changes
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Thu Mar 19 10:35:56 2026
(Merged from https://github.com/openssl/openssl/pull/30417)
diff --git a/apps/s_server.c b/apps/s_server.c
index 586c47bc9b..996d762641 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -630,6 +630,8 @@ static int ssl_ech_servername_cb(SSL *s, int *ad, void *arg)
"ssl_ech_servername_cb: Not switching context "
"- no name match (%d).\n",
check_host);
+ if (OPENSSL_strcasecmp(servername, p->servername) != 0)
+ return p->extension_error;
}
}
} else {
@@ -637,6 +639,14 @@ static int ssl_ech_servername_cb(SSL *s, int *ad, void *arg)
BIO_printf(p->biodebug,
"ssl_ech_servername_cb: Not switching context "
"- no ECH SUCCESS\n");
+ if (servername != NULL) {
+ if (OPENSSL_strcasecmp(servername, p->servername))
+ return p->extension_error;
+ if (ctx2 != NULL) {
+ BIO_puts(p->biodebug, "Switching server context.\n");
+ SSL_set_SSL_CTX(s, ctx2);
+ }
+ }
}
return SSL_TLSEXT_ERR_OK;
}
diff --git a/ssl/ech/ech_store.c b/ssl/ech/ech_store.c
index 1c43ee6804..fb0b72bde8 100644
--- a/ssl/ech/ech_store.c
+++ b/ssl/ech/ech_store.c
@@ -120,7 +120,7 @@ static int ech_bio2buf(BIO *in, unsigned char **buf, size_t *len)
brv = BIO_read_ex(in, lptr, OSSL_ECH_BUFCHUNK, &readbytes);
if (brv != 1)
goto err;
- if (readbytes < OSSL_ECH_BUFCHUNK) {
+ if (BIO_eof(in) || readbytes < OSSL_ECH_BUFCHUNK) {
done = 1;
break;
}
diff --git a/test/certs/echdir/ech-b511.pem b/test/certs/echdir/ech-b511.pem
new file mode 100644
index 0000000000..2c655740ae
--- /dev/null
+++ b/test/certs/echdir/ech-b511.pem
@@ -0,0 +1,14 @@
+-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VuBCIEIFjwv041TaYyaBLXwW5i3qdRjVfp2jgDt0rjTNW+CEJw
+-----END PRIVATE KEY-----
+-----BEGIN ECHCONFIG-----
+Af3+DQA6RAAgACBaXlSMpzC72pccyR1s4ggNF6ZcoNMEatXUKlHUMtmebwAEAAIAAwALZXhhbXBs
+ZS5jb20AAP4NAEOFACAAIHoLrQGbajMQMAqajIXtnRjjHkAM4xy66Zo7OvfLJnwcAAQAAgADAA5l
+eGFtcGxlNTEyLmNvbQAGAAAAAv///g0AOt0AIAAgPj//c1cJ3yIi34Dvp8imA8ItbgXlMS9tOm+c
+K79t7U0ABAABAAEAC2V4YW1wbGUuY29tAAD+DQA6rQAgACDVBjfG9x8BtxGxkTZQdZv5cE4k2f2D
+QW3MyiVzRAxNSQAEAAIAAgALZXhhbXBsZS5jb20AAP4NADppACAAIKZcX2LKexw85KRYIchUmgZp
+HbFTXq15r7qdOgljpTtjAAQAAgADAAtleGFtcGxlLmNvbQAA/g0AukQAIAAgWl5UjKcwu9qXHMkd
+bOIIDRemXKDTBGrV1CpR1DLZnm8ABAACAAMAC2V4YW1wbGUuY29tAIAAAAB8AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
+-----END ECHCONFIG-----
diff --git a/test/certs/echdir/ech-b512.pem b/test/certs/echdir/ech-b512.pem
new file mode 100644
index 0000000000..fbb2ee84a4
--- /dev/null
+++ b/test/certs/echdir/ech-b512.pem
@@ -0,0 +1,14 @@
+-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VuBCIEIFjwv041TaYyaBLXwW5i3qdRjVfp2jgDt0rjTNW+CEJw
+-----END PRIVATE KEY-----
+-----BEGIN ECHCONFIG-----
+Af7+DQA6RAAgACBaXlSMpzC72pccyR1s4ggNF6ZcoNMEatXUKlHUMtmebwAEAAIAAwALZXhhbXBs
+ZS5jb20AAP4NAEOFACAAIHoLrQGbajMQMAqajIXtnRjjHkAM4xy66Zo7OvfLJnwcAAQAAgADAA5l
+eGFtcGxlNTEyLmNvbQAGAAAAAv///g0AOt0AIAAgPj//c1cJ3yIi34Dvp8imA8ItbgXlMS9tOm+c
+K79t7U0ABAABAAEAC2V4YW1wbGUuY29tAAD+DQA6rQAgACDVBjfG9x8BtxGxkTZQdZv5cE4k2f2D
+QW3MyiVzRAxNSQAEAAIAAgALZXhhbXBsZS5jb20AAP4NADppACAAIKZcX2LKexw85KRYIchUmgZp
+HbFTXq15r7qdOgljpTtjAAQAAgADAAtleGFtcGxlLmNvbQAA/g0Au0QAIAAgWl5UjKcwu9qXHMkd
+bOIIDRemXKDTBGrV1CpR1DLZnm8ABAACAAMAC2V4YW1wbGUuY29tAIEAAAB9AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+-----END ECHCONFIG-----
diff --git a/test/certs/echdir/ech-b513.pem b/test/certs/echdir/ech-b513.pem
new file mode 100644
index 0000000000..1c1fa9acf7
--- /dev/null
+++ b/test/certs/echdir/ech-b513.pem
@@ -0,0 +1,14 @@
+-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VuBCIEIFjwv041TaYyaBLXwW5i3qdRjVfp2jgDt0rjTNW+CEJw
+-----END PRIVATE KEY-----
+-----BEGIN ECHCONFIG-----
+Af/+DQA6RAAgACBaXlSMpzC72pccyR1s4ggNF6ZcoNMEatXUKlHUMtmebwAEAAIAAwALZXhhbXBs
+ZS5jb20AAP4NAEOFACAAIHoLrQGbajMQMAqajIXtnRjjHkAM4xy66Zo7OvfLJnwcAAQAAgADAA5l
+eGFtcGxlNTEyLmNvbQAGAAAAAv///g0AOt0AIAAgPj//c1cJ3yIi34Dvp8imA8ItbgXlMS9tOm+c
+K79t7U0ABAABAAEAC2V4YW1wbGUuY29tAAD+DQA6rQAgACDVBjfG9x8BtxGxkTZQdZv5cE4k2f2D
+QW3MyiVzRAxNSQAEAAIAAgALZXhhbXBsZS5jb20AAP4NADppACAAIKZcX2LKexw85KRYIchUmgZp
+HbFTXq15r7qdOgljpTtjAAQAAgADAAtleGFtcGxlLmNvbQAA/g0AvEQAIAAgWl5UjKcwu9qXHMkd
+bOIIDRemXKDTBGrV1CpR1DLZnm8ABAACAAMAC2V4YW1wbGUuY29tAIIAAAB+AAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+-----END ECHCONFIG-----
diff --git a/test/recipes/82-test_ech_client_server.t b/test/recipes/82-test_ech_client_server.t
index dbeeb55d87..b988d8de71 100644
--- a/test/recipes/82-test_ech_client_server.t
+++ b/test/recipes/82-test_ech_client_server.t
@@ -33,7 +33,7 @@ plan skip_all => "$test_name requires TLSv1.3 enabled"
plan skip_all => "$test_name is not available Windows or VMS"
if $^O =~ /^(VMS|MSWin32|msys)$/;
-plan tests => 22;
+plan tests => 26;
my $shlib_wrap = bldtop_file("util", "shlib_wrap.sh");
my $apps_openssl = bldtop_file("apps", "openssl");
@@ -94,6 +94,26 @@ sub start_ech_client_server
"-ech_noretry_dir", $ech_dir,
"-servername", "example.com",
"-tls1_3");
+ } elsif ($test_type eq "servername_fatal" ) {
+ # load keys from key dir (some will fail)
+ @s_server_cmd = ("s_server", "-accept", "0", "-naccept", "1",
+ "-cert", $server_pem, "-key", $server_key,
+ "-cert2", $server_pem, "-key2", $server_key,
+ "-ech_dir", $ech_dir,
+ "-ech_noretry_dir", $ech_dir,
+ "-servername", "example.com",
+ "-servername_fatal",
+ "-tls1_3");
+ } elsif ($test_type eq "servername_fatal2" ) {
+ # load keys from key dir (some will fail)
+ @s_server_cmd = ("s_server", "-accept", "0", "-naccept", "1",
+ "-cert", $server_pem, "-key", $server_key,
+ "-cert2", $server_pem, "-key2", $server_key,
+ "-ech_dir", $ech_dir,
+ "-ech_noretry_dir", $ech_dir,
+ "-servername", "example.com",
+ "-servername_fatal",
+ "-tls1_3");
} else {
# default for all other tests (for now)
@s_server_cmd = ("s_server", "-accept", "0", "-naccept", "1",
@@ -222,6 +242,15 @@ sub start_ech_client_server
"-ech_config_list", $good_b64,
"-ech_ignore_cid",
"-prexit");
+
+ } elsif ($test_type eq "servername_fatal2" ) {
+ # Real ECH, but mismatching servername
+ @s_client_cmd = ("s_client",
+ "-connect", "localhost:$s_server_port",
+ "-servername", "server.not-the-example",
+ "-CAfile", $root_pem,
+ "-ech_config_list", $good_b64,
+ "-prexit");
} else {
# Real ECH, and default
@s_client_cmd = ("s_client",
@@ -380,6 +409,26 @@ sub keydir_test {
ok($s_client_match == 1, "s_server using ech keydir on command line");
}
+sub servernamefatal_test {
+ print("\n\nServer using servername_fatal test.\n");
+ my $tt = "servername_fatal";
+ my $win = "^ECH: success";
+ start_ech_client_server($tt, $win);
+ ok($s_server_port ne "0", "s_server port check");
+ print("s_server ready, on port $s_server_port pid: $s_server_pid\n");
+ ok($s_client_match == 1, "s_server using ech servername_fatal on command line");
+}
+
+sub servernamefatal_test2 {
+ print("\n\nServer using servername_fatal test.\n");
+ my $tt = "servername_fatal2";
+ my $win = "^ECH: tried but failed";
+ start_ech_client_server($tt, $win);
+ ok($s_server_port ne "0", "s_server port check");
+ print("s_server ready, on port $s_server_port pid: $s_server_pid\n");
+ ok($s_client_match == 1, "s_server using ech servername_fatal and bad name on command line");
+}
+
basic_test();
wrong_test();
grease_test();
@@ -391,4 +440,6 @@ no_outer_test();
cid_free_test();
cid_wrong_test();
keydir_test();
+servernamefatal_test();
+servernamefatal_test2();