]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ECH: chunk-size bug fix and non-regression changes
authorsftcd <stephen.farrell@cs.tcd.ie>
Fri, 13 Mar 2026 22:02:29 +0000 (22:02 +0000)
committerNorbert Pocs <norbertp@openssl.org>
Thu, 19 Mar 2026 10:37:14 +0000 (11:37 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Thu Mar 19 10:37:16 2026
(Merged from https://github.com/openssl/openssl/pull/30417)

apps/s_server.c
ssl/ech/ech_store.c
test/certs/echdir/ech-b511.pem [new file with mode: 0644]
test/certs/echdir/ech-b512.pem [new file with mode: 0644]
test/certs/echdir/ech-b513.pem [new file with mode: 0644]
test/recipes/82-test_ech_client_server.t

index 586c47bc9bd34fe951d1ca3f6e635f40ef627180..996d7626418db81c4d7c912601dd83ffc705b858 100644 (file)
@@ -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;
 }
index 1c43ee68046fb426e6aab746778cfc48aa70a387..fb0b72bde8dad9f768754bb14045994dfe999552 100644 (file)
@@ -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 (file)
index 0000000..2c65574
--- /dev/null
@@ -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 (file)
index 0000000..fbb2ee8
--- /dev/null
@@ -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 (file)
index 0000000..1c1fa9a
--- /dev/null
@@ -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-----
index dbeeb55d872bbbf0d1243ab5ced997c71194e4e2..b988d8de718a09eb81ca83875bd7a24bc31a405e 100644 (file)
@@ -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();