add ECH test (at the moment, only for TCP)

This commit is contained in:
Kazuho Oku 2022-12-08 16:30:17 +09:00
parent 7a7d3d3b39
commit 0cfa660de1
3 changed files with 97 additions and 0 deletions

5
examples/h2o/ech.key Normal file
View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg885/2uV+GjENh/Hr
vebzKL4Kmc28rfTWWJzyneS4/9KhRANCAAT+jBnOCQUZHrwpipJFeSUx8m8M7OJG
BjnovDnLf3Bqgmp3m0z5abig5TnH9i+z0wrWqo+A4w8dEoqv1oos5y6g
-----END PRIVATE KEY-----

View File

@ -738,6 +738,7 @@
08819C2C218C9FA90057ED23 /* qif */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = qif; sourceTree = BUILT_PRODUCTS_DIR; };
08819C2D218C9FF70057ED23 /* qif.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = qif.c; sourceTree = "<group>"; };
08B3297E29407664009D6766 /* hpke.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hpke.c; sourceTree = "<group>"; };
08B329832941B407009D6766 /* 40tls-ech.t */ = {isa = PBXFileReference; lastKnownFileType = text; path = "40tls-ech.t"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
08B3D43A26042CAF002F195C /* 50connect-deadlock.t */ = {isa = PBXFileReference; lastKnownFileType = text; path = "50connect-deadlock.t"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
08C7C365262AB30F009C944C /* 40mtls.t */ = {isa = PBXFileReference; lastKnownFileType = text; path = 40mtls.t; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
08CEA9CF2662136B00B4BB6B /* 80http3-header-linefeed.t */ = {isa = PBXFileReference; lastKnownFileType = text; path = "80http3-header-linefeed.t"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
@ -2249,6 +2250,7 @@
107D4D501B58B342004A9B21 /* 40session-ticket.t */,
0810E6AB286DACB600333FA4 /* 40soft-connection-limit.t */,
104B9A321A59E27A009EEE64 /* 40ssl-cipher-suite.t */,
08B329832941B407009D6766 /* 40tls-ech.t */,
086001CC273BBBCF0043886F /* 40tls-multiple-certs.t */,
E93BB6D025E09504009C24D8 /* 40tls-raw-pubkey.t */,
E9F677D82008686B006476D3 /* 40tls13-early-data.t */,

90
t/40tls-ech.t Normal file
View File

@ -0,0 +1,90 @@
use strict;
use warnings;
use File::Temp qw(tempdir);
use Net::EmptyPort qw(empty_port);
use Test::More;
use Time::HiRes qw(sleep);
use t::Util;
my $tempdir = tempdir(CLEANUP => 1);
my $tls_port = empty_port();
my $server = spawn_h2o_raw(<<"EOT", [ $tls_port ]);
num-threads: 1
listen:
port: $tls_port
ssl: &ssl
identity:
- key-file: deps/picotls/t/assets/secp256r1/key.pem
certificate-file: deps/picotls/t/assets/secp256r1/cert.pem
- key-file: examples/h2o/server.key
certificate-file: examples/h2o/server.crt
ech:
- key-file: examples/h2o/ech.key
config-id: 0
public-name: ech.examp1e.net
listen:
port: $tls_port
type: quic
ssl:
<<: *ssl
hosts:
default:
paths:
/:
file.dir: t/assets/doc_root
EOT
my $req_fn = "$tempdir/req";
my $ech_config_fn = "$tempdir/echconfig";
my $trace_fn = "$tempdir/trace.out";
{ # build request
open my $fh, ">", $req_fn
or die "failed to create file:$req_fn:$!";
print $fh "GET /index.txt HTTP/1.0\r\n\r\n";
}
subtest "tcp" => sub {
create_empty_file($ech_config_fn);
create_empty_file($trace_fn);
# first connection is grease ECH
my $resp = fetch();
like $resp, qr{\r\n\r\nhello\n$}s, "response";
sleep 0.1;
ok !trace_says_ech(), "connection is non-ECH";
isnt +(stat $ech_config_fn)[7], 0, "got retry_configs";
create_empty_file($trace_fn);
# second connection is ECH
$resp = fetch();
like $resp, qr{\r\n\r\nhello\n$}s, "response";
sleep 0.1;
ok trace_says_ech(), "connection is ECH";
isnt +(stat $ech_config_fn)[7], 0, "got retry_configs";
};
done_testing;
sub fetch {
open my $fh, "@{[bindir()]}/picotls/cli -j $trace_fn -I -E $ech_config_fn localhost.examp1e.net $tls_port < $req_fn |"
or die "failed to launch @{[bindir()]}/picotls/cli:$!";
join "", <$fh>;
}
sub trace_says_ech {
open my $fh, "<", $trace_fn
or die "failed to open file:$trace_fn:$!";
my $lines = join "", <$fh>;
$lines =~ /[{,]"type":"ech_selection".*,"is_ech":(true|false)[,}]/
or die "unexpected trace:$lines";
$1 eq "true";
}
sub create_empty_file {
my $fn = shift;
open my $fh, ">", $fn
or die "failed to create file:$fn:$!";
}