comparison lib/Test/Nginx/HTTP3.pm @ 1917:24fea64f233f

Tests: TLS early data tests with HTTP/3.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 22 Jun 2023 15:35:19 +0400
parents 15131dd931a0
children 0e4ff5f83653
comparison
equal deleted inserted replaced
1916:6ab08c255dd3 1917:24fea64f233f
39 ); 39 );
40 40
41 $self->{repeat} = 0; 41 $self->{repeat} = 0;
42 $self->{token} = $extra{token} || ''; 42 $self->{token} = $extra{token} || '';
43 $self->{psk_list} = $extra{psk_list} || []; 43 $self->{psk_list} = $extra{psk_list} || [];
44 $self->{early_data} = $extra{early_data};
44 45
45 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost'; 46 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost';
46 $self->{cipher} = 0x1301; 47 $self->{cipher} = 0x1301;
47 $self->{ciphers} = $extra{ciphers} || "\x13\x01"; 48 $self->{ciphers} = $extra{ciphers} || "\x13\x01";
48 $self->{opts} = $extra{opts}; 49 $self->{opts} = $extra{opts};
60 61
61 return $self; 62 return $self;
62 } 63 }
63 64
64 sub init { 65 sub init {
65 my ($self, $early_data) = @_; 66 my ($self) = @_;
66 $self->{keys} = []; 67 $self->{keys} = [];
67 $self->{pn} = [[-1, -1, -1, -1], [-1, -1, -1, -1]]; 68 $self->{pn} = [[-1, -1, -1, -1], [-1, -1, -1, -1]];
68 $self->{crypto_in} = [[],[],[],[]]; 69 $self->{crypto_in} = [[],[],[],[]];
69 $self->{stream_in} = []; 70 $self->{stream_in} = [];
70 $self->{frames_in} = []; 71 $self->{frames_in} = [];
80 $self->{scid} = Crypt::PRNG::random_bytes(17); 81 $self->{scid} = Crypt::PRNG::random_bytes(17);
81 $self->{dcid} = Crypt::PRNG::random_bytes(18); 82 $self->{dcid} = Crypt::PRNG::random_bytes(18);
82 $self->{salt} = "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17" 83 $self->{salt} = "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17"
83 . "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a"; 84 . "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a";
84 $self->{ncid} = []; 85 $self->{ncid} = [];
85 $self->{early_data} = $early_data;
86 } 86 }
87 87
88 sub retry { 88 sub retry {
89 my ($self, %extra) = @_; 89 my ($self, %extra) = @_;
90 my $prk = Crypt::KeyDerivation::hkdf_extract($self->{dcid}, 90 my $prk = Crypt::KeyDerivation::hkdf_extract($self->{dcid},
127 Test::Nginx::log_core('||', "es = " . unpack("H*", $self->{es_prk})); 127 Test::Nginx::log_core('||', "es = " . unpack("H*", $self->{es_prk}));
128 $self->{sk} = Crypt::PK::X25519->new->generate_key; 128 $self->{sk} = Crypt::PK::X25519->new->generate_key;
129 } 129 }
130 130
131 sub initial { 131 sub initial {
132 my ($self, $ed) = @_; 132 my ($self) = @_;
133 $self->{tlsm}{ch} = $self->build_tls_client_hello(); 133 $self->{tlsm}{ch} = $self->build_tls_client_hello();
134 my $ch = $self->{tlsm}{ch}; 134 my $ch = $self->{tlsm}{ch};
135 my $crypto = build_crypto($ch); 135 my $crypto = build_crypto($ch);
136 my $padding = 1200 - length($crypto); 136 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};
138 my $payload = $crypto . pack("x$padding"); 139 my $payload = $crypto . pack("x$padding");
139 my $initial = $self->encrypt_aead($payload, 0); 140 my $initial = $self->encrypt_aead($payload, 0);
140 141
141 if ($ed && $self->{psk}->{ed}) { 142 if ($self->{early_data} && $self->{psk}->{ed}) {
142 my ($hash, $hlen) = $self->{psk}{cipher} == 0x1302 ? 143 my ($hash, $hlen) = $self->{psk}{cipher} == 0x1302 ?
143 ('SHA384', 48) : ('SHA256', 32); 144 ('SHA384', 48) : ('SHA256', 32);
144 $self->set_traffic_keys('tls13 c e traffic', $hash, $hlen, 1, 145 $self->set_traffic_keys('tls13 c e traffic', $hash, $hlen, 1,
145 'w', $self->{es_prk}, Crypt::Digest::digest_data($hash, 146 'w', $self->{es_prk}, Crypt::Digest::digest_data($hash,
146 $self->{tlsm}{ch})); 147 $self->{tlsm}{ch}));
147 148
148 # my $ed = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a" 149 $payload = $self->build_new_stream($self->{early_data});
149 # . $self->build_stream("\x01\x06\x00\x00\xc0");
150 $payload = $ed;
151 # $payload = $self->build_stream("GET /\n");
152 $padding = 1200 - length($crypto) - length($payload); 150 $padding = 1200 - length($crypto) - length($payload);
153 $payload .= pack("x$padding") if $padding > 0; 151 $payload .= pack("x$padding") if $padding > 0;
154 $initial .= $self->encrypt_aead($payload, 1); 152 $initial .= $self->encrypt_aead($payload, 1);
155 } 153 }
156 154
245 "resumption = " . unpack("H*", $self->{rms_prk})); 243 "resumption = " . unpack("H*", $self->{rms_prk}));
246 244
247 my $crypto = build_crypto($finished); 245 my $crypto = build_crypto($finished);
248 $self->{socket}->syswrite($self->encrypt_aead($crypto, 2)); 246 $self->{socket}->syswrite($self->encrypt_aead($crypto, 2));
249 } 247 }
250
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 248
258 sub DESTROY { 249 sub DESTROY {
259 my ($self) = @_; 250 my ($self) = @_;
260 251
261 return unless $self->{socket}; 252 return unless $self->{socket};
406 $self->{control_offset} += $length; 397 $self->{control_offset} += $length;
407 $self->raw_write("\x0e\x06" 398 $self->raw_write("\x0e\x06"
408 . build_int($offset) . build_int($length) . $buf); 399 . build_int($offset) . build_int($length) . $buf);
409 } 400 }
410 401
411 sub new_stream { 402 sub build_new_stream {
412 my ($self, $uri, $stream) = @_; 403 my ($self, $uri, $stream) = @_;
413 my ($input, $buf); 404 my ($input, $buf);
414 405
415 $self->{headers} = ''; 406 $self->{headers} = '';
416 407
457 $buf .= build_int(length($input)); 448 $buf .= build_int(length($input));
458 $buf .= $input; 449 $buf .= $input;
459 $buf .= pack_body($self, $body) if defined $body; 450 $buf .= pack_body($self, $body) if defined $body;
460 451
461 $self->{streams}{$self->{last_stream}}{sent} = length($buf); 452 $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});
463 454 }
455
456 sub new_stream {
457 my ($self, $uri, $stream) = @_;
458 $self->raw_write($self->build_new_stream($uri, $stream));
464 return $self->{last_stream}; 459 return $self->{last_stream};
465 } 460 }
466 461
467 sub h3_body { 462 sub h3_body {
468 my ($self, $body, $sid, $extra) = @_; 463 my ($self, $body, $sid, $extra) = @_;