| #! /usr/bin/env perl |
| |
| use strict; |
| use warnings; |
| use Digest::MD5 qw(md5_hex); |
| use File::Temp qw(tempdir); |
| use Net::EmptyPort qw(check_port empty_port); |
| use POSIX ":sys_wait_h"; |
| use Scope::Guard qw(scope_guard); |
| use Test::More; |
| use Time::HiRes qw(sleep); |
| |
| $ENV{BINARY_DIR} ||= "."; |
| my $cli = "$ENV{BINARY_DIR}/cli"; |
| my $port = empty_port(); |
| my $tempdir = tempdir(CLEANUP => 1); |
| |
| my @cli_opts = (); |
| if ($ENV{PTLSLOG}) { |
| push @cli_opts, "-j$ENV{PTLSLOG}"; |
| } |
| |
| subtest "hello" => sub { |
| my $guard = spawn_server("rsa", qw(-i t/assets/hello.txt)); |
| subtest "full-handshake" => sub { |
| my $resp = `$cli @cli_opts 127.0.0.1 $port 2> /dev/null`; |
| is $resp, "hello"; |
| }; |
| subtest "resumption" => sub { |
| for (1..10) { |
| my $resp = `$cli @cli_opts -s $tempdir/session 127.0.0.1 $port 2> /dev/null`; |
| is $resp, "hello"; |
| } |
| }; |
| }; |
| |
| unlink "$tempdir/session"; |
| |
| subtest "early-data" => sub { |
| subtest "success" => sub { |
| plan skip_all => "faketime not found" |
| unless system("which faketime > /dev/null 2>&1") == 0; |
| my $guard = spawn_server("rsa", qw(-i t/assets/hello.txt -l), "$tempdir/events"); |
| my $resp = `$cli @cli_opts -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| $resp = `$cli @cli_opts -e -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| like slurp_file("$tempdir/events"), qr/^CLIENT_EARLY_TRAFFIC_SECRET /m; |
| $resp = `$cli @cli_opts -e -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| is 2, (() = slurp_file("$tempdir/events") =~ /^CLIENT_EARLY_TRAFFIC_SECRET /mg); |
| # check +15 seconds jitter |
| $resp = `faketime -f +15 $cli @cli_opts -e -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| is 2, (() = slurp_file("$tempdir/events") =~ /^CLIENT_EARLY_TRAFFIC_SECRET /mg); |
| # re-fetch the ticket |
| unlink "$tempdir/session"; |
| $resp = `$cli @cli_opts -e -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| is 2, (() = slurp_file("$tempdir/events") =~ /^CLIENT_EARLY_TRAFFIC_SECRET /mg); |
| # check -15 seconds jitter |
| $resp = `faketime -f -15 $cli @cli_opts -e -s $tempdir/session 127.0.0.1 $port`; |
| is $resp, "hello"; |
| is 2, (() = slurp_file("$tempdir/events") =~ /^CLIENT_EARLY_TRAFFIC_SECRET /mg); |
| }; |
| }; |
| |
| subtest "certificate-compression" => sub { |
| plan skip_all => "feature disabled" |
| unless system("$cli -b -h > /dev/null 2>&1") == 0; |
| my $guard = spawn_server("rsa", qw(-i t/assets/hello.txt -b)); |
| my $resp = `$cli @cli_opts 127.0.0.1 $port 2> /dev/null`; |
| is $resp, "hello"; |
| $resp = `$cli @cli_opts -b 127.0.0.1 $port 2> /dev/null`; |
| is $resp, "hello"; |
| }; |
| |
| # This test acts as an end-to-end testing of the certificate verifier of the OpenSSL backend. |
| subtest "raw-public-keys" => sub { |
| my @key_types = do { |
| my $help = `$cli -h`; |
| $help =~ /^Supported signature algorithms:\s*(.*)\s*$/m |
| or die "failed to extract list of supported signature algorithms from $cli -h"; |
| split /,\s*/, $1; |
| }; |
| die "unexpected list of supported signature algorithms: @key_types" |
| unless grep /^rsa$/, @key_types; |
| for my $key_type (@key_types) { |
| subtest $key_type => sub { |
| my $guard = spawn_server($key_type, qw(-r - -i t/assets/hello.txt)); |
| my $resp = `$cli @cli_opts -v -r t/assets/$key_type/pub.pem 127.0.0.1 $port 2> /dev/null`; |
| is $resp, "hello"; |
| }; |
| } |
| }; |
| |
| done_testing; |
| |
| sub spawn_server { |
| my $key_type = shift; |
| my $cert_type = grep(/^-r$/, @_) ? "pub" : "cert"; |
| my @cmd = ($cli, @cli_opts, "-k", "t/assets/$key_type/key.pem", "-c", "t/assets/$key_type/$cert_type.pem", @_, "127.0.0.1", $port); |
| my $pid = fork; |
| die "fork failed:$!" |
| unless defined $pid; |
| if ($pid == 0) { |
| exec @cmd; |
| die "failed to exec $cmd[0]:$?"; |
| } |
| while (!check_port($port)) { |
| sleep 0.1; |
| } |
| return scope_guard(sub { |
| kill 9, $pid; |
| while (waitpid($pid, 0) != $pid) {} |
| }); |
| } |
| |
| sub slurp_file { |
| my $fn = shift; |
| open my $fh, "<", $fn |
| or die "failed to open file:$fn:$!"; |
| do { |
| local $/; |
| <$fh>; |
| }; |
| } |