Skip to content

Commit 773637b

Browse files
committed
Tests: TLS early data tests with HTTP/3.
1 parent cfdf4e8 commit 773637b

File tree

2 files changed

+121
-18
lines changed

2 files changed

+121
-18
lines changed

h3_ssl_early_data.t

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/perl
2+
3+
# (C) Sergey Kandaurov
4+
# (C) Nginx, Inc.
5+
6+
# Tests for TLS early data with HTTP/3.
7+
8+
###############################################################################
9+
10+
use warnings;
11+
use strict;
12+
13+
use Test::More;
14+
15+
BEGIN { use FindBin; chdir($FindBin::Bin); }
16+
17+
use lib 'lib';
18+
use Test::Nginx;
19+
use Test::Nginx::HTTP3;
20+
21+
###############################################################################
22+
23+
select STDERR; $| = 1;
24+
select STDOUT; $| = 1;
25+
26+
my $t = Test::Nginx->new()->has(qw/http http_v3 cryptx/)
27+
->has_daemon('openssl')->plan(5)
28+
->write_file_expand('nginx.conf', <<'EOF');
29+
30+
%%TEST_GLOBALS%%
31+
32+
daemon off;
33+
34+
events {
35+
}
36+
37+
http {
38+
%%TEST_GLOBALS_HTTP%%
39+
40+
ssl_certificate_key localhost.key;
41+
ssl_certificate localhost.crt;
42+
ssl_early_data on;
43+
44+
add_header X-Session $ssl_session_reused always;
45+
add_header X-Early $ssl_early_data always;
46+
47+
server {
48+
listen 127.0.0.1:%%PORT_8980_UDP%% quic;
49+
server_name localhost;
50+
}
51+
}
52+
53+
EOF
54+
55+
$t->write_file('openssl.conf', <<EOF);
56+
[ req ]
57+
default_bits = 2048
58+
encrypt_key = no
59+
distinguished_name = req_distinguished_name
60+
[ req_distinguished_name ]
61+
EOF
62+
63+
my $d = $t->testdir();
64+
65+
foreach my $name ('localhost') {
66+
system('openssl req -x509 -new '
67+
. "-config $d/openssl.conf -subj /CN=$name/ "
68+
. "-out $d/$name.crt -keyout $d/$name.key "
69+
. ">>$d/openssl.out 2>&1") == 0
70+
or die "Can't create certificate for $name: $!\n";
71+
}
72+
73+
$t->run();
74+
75+
###############################################################################
76+
77+
my $s = Test::Nginx::HTTP3->new(8980);
78+
my $frames = $s->read(all => [{ sid => $s->new_stream(), fin => 1 }]);
79+
80+
my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
81+
is($frame->{headers}->{'x-session'}, '.', 'new session');
82+
83+
local $TODO = 'no TLSv1.3 sessions in LibreSSL' if $t->has_module('LibreSSL');
84+
85+
my $psk_list = $s->{psk_list};
86+
my $ed = $s->build_new_stream();
87+
88+
$s = Test::Nginx::HTTP3->new(8980, psk_list => $psk_list, early_data => {});
89+
90+
TODO: {
91+
local $TODO = 'no 0-RTT in OpenSSL compat layer'
92+
unless $t->has_module('OpenSSL [.0-9]+\+quic')
93+
or $t->has_module('BoringSSL')
94+
or $t->has_module('LibreSSL');
95+
96+
$frames = $s->read(all => [{ sid => 0, fin => 1 }]);
97+
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
98+
is($frame->{headers}->{'x-session'}, 'r', 'reused session 0rtt');
99+
is($frame->{headers}->{'x-early'}, '1', 'reused session is early');
100+
101+
}
102+
103+
$frames = $s->read(all => [{ sid => $s->new_stream(), fin => 1 }]);
104+
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
105+
is($frame->{headers}->{'x-session'}, 'r', 'reused session 1rtt');
106+
is($frame->{headers}->{'x-early'}, undef, 'reused session not early');
107+
108+
###############################################################################

lib/Test/Nginx/HTTP3.pm

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ sub new {
4141
$self->{repeat} = 0;
4242
$self->{token} = $extra{token} || '';
4343
$self->{psk_list} = $extra{psk_list} || [];
44+
$self->{early_data} = $extra{early_data};
4445

4546
$self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost';
4647
$self->{cipher} = 0x1301;
@@ -62,7 +63,7 @@ sub new {
6263
}
6364

6465
sub init {
65-
my ($self, $early_data) = @_;
66+
my ($self) = @_;
6667
$self->{keys} = [];
6768
$self->{pn} = [[-1, -1, -1, -1], [-1, -1, -1, -1]];
6869
$self->{crypto_in} = [[],[],[],[]];
@@ -82,7 +83,6 @@ sub init {
8283
$self->{salt} = "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17"
8384
. "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a";
8485
$self->{ncid} = [];
85-
$self->{early_data} = $early_data;
8686
}
8787

8888
sub retry {
@@ -129,26 +129,24 @@ sub init_key_schedule {
129129
}
130130

131131
sub initial {
132-
my ($self, $ed) = @_;
132+
my ($self) = @_;
133133
$self->{tlsm}{ch} = $self->build_tls_client_hello();
134134
my $ch = $self->{tlsm}{ch};
135135
my $crypto = build_crypto($ch);
136136
my $padding = 1200 - length($crypto);
137-
$padding = 0 if $padding < 0 || $self->{psk}->{ed};
137+
$padding = 0 if $padding < 0;
138+
$padding = 0 if $self->{psk}{ed} && $self->{early_data};
138139
my $payload = $crypto . pack("x$padding");
139140
my $initial = $self->encrypt_aead($payload, 0);
140141

141-
if ($ed && $self->{psk}->{ed}) {
142+
if ($self->{early_data} && $self->{psk}->{ed}) {
142143
my ($hash, $hlen) = $self->{psk}{cipher} == 0x1302 ?
143144
('SHA384', 48) : ('SHA256', 32);
144145
$self->set_traffic_keys('tls13 c e traffic', $hash, $hlen, 1,
145146
'w', $self->{es_prk}, Crypt::Digest::digest_data($hash,
146147
$self->{tlsm}{ch}));
147148

148-
# my $ed = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a"
149-
# . $self->build_stream("\x01\x06\x00\x00\xc0");
150-
$payload = $ed;
151-
# $payload = $self->build_stream("GET /\n");
149+
$payload = $self->build_new_stream($self->{early_data});
152150
$padding = 1200 - length($crypto) - length($payload);
153151
$payload .= pack("x$padding") if $padding > 0;
154152
$initial .= $self->encrypt_aead($payload, 1);
@@ -248,13 +246,6 @@ sub handshake {
248246
$self->{socket}->syswrite($self->encrypt_aead($crypto, 2));
249247
}
250248

251-
#if (!$psk->{ed}) {
252-
# my $r = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a";
253-
# $s->syswrite(encrypt_aead($r, 3));
254-
# $r = "\x01\x06\x00\x00\xc0";
255-
# $s->syswrite(encrypt_aead($self->build_stream($r), 3));
256-
#}
257-
258249
sub DESTROY {
259250
my ($self) = @_;
260251

@@ -408,7 +399,7 @@ sub cancel_push {
408399
. build_int($offset) . build_int($length) . $buf);
409400
}
410401

411-
sub new_stream {
402+
sub build_new_stream {
412403
my ($self, $uri, $stream) = @_;
413404
my ($input, $buf);
414405

@@ -459,8 +450,12 @@ sub new_stream {
459450
$buf .= pack_body($self, $body) if defined $body;
460451

461452
$self->{streams}{$self->{last_stream}}{sent} = length($buf);
462-
$self->raw_write($self->build_stream($buf, start => $uri->{body_more}));
453+
$self->build_stream($buf, start => $uri->{body_more});
454+
}
463455

456+
sub new_stream {
457+
my ($self, $uri, $stream) = @_;
458+
$self->raw_write($self->build_new_stream($uri, $stream));
464459
return $self->{last_stream};
465460
}
466461

0 commit comments

Comments
 (0)