annotate lib/Test/Nginx/HTTP3.pm @ 1874:d57a0fd293a3

Tests: basic QUIC support. - handshake using X25519 TLS secrets - TLS PSK, session tickets, session resumption, early data, retry support - packet numbers and packet acknowledgment - QUIC frames handling
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 01 Feb 2022 14:54:32 +0300
parents
children f50c2a65ccc0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1874
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1 package Test::Nginx::HTTP3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
2
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
3 # (C) Sergey Kandaurov
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
4 # (C) Nginx, Inc.
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
5
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
6 # Module for nginx QUIC tests.
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
7
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
8 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
9
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
10 use warnings;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
11 use strict;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
12
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
13 use IO::Socket::INET;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
14 use IO::Select;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
15 use Data::Dumper;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
16
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
17 use Test::Nginx;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
18
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
19 sub new {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
20 my $self = {};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
21 bless $self, shift @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
22
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
23 my ($port, %extra) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
24
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
25 require Crypt::KeyDerivation;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
26 require Crypt::PK::X25519;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
27 require Crypt::PRNG;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
28 require Crypt::AuthEnc::GCM;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
29 require Crypt::Mode::CTR;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
30 require Crypt::Digest;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
31 require Crypt::Mac::HMAC;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
32
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
33 $self->{socket} = IO::Socket::INET->new(
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
34 Proto => "udp",
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
35 PeerAddr => '127.0.0.1:' . port($port || 8980),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
36 );
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
37
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
38 $self->{repeat} = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
39 $self->{token} = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
40 $self->{psk_list} = $extra{psk_list} || [];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
41
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
42 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
43 $self->{opts} = $extra{opts};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
44
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
45 $self->{zero} = pack("x5");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
46
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
47 $self->{buf} = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
48
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
49 $self->init();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
50 $self->init_key_schedule();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
51 $self->initial();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
52 $self->handshake() or return;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
53
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
54 return $self;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
55 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
56
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
57 sub init {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
58 my ($self, $early_data) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
59 $self->{keys} = [];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
60 $self->{pn} = [[-1, -1, -1, -1], [-1, -1, -1, -1]];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
61 $self->{crypto_in} = [[],[],[],[]];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
62 $self->{stream_in} = [];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
63 $self->{frames_in} = [];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
64 $self->{tlsm} = ();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
65 $self->{tlsm}{$_} = ''
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
66 for 'ch', 'sh', 'ee', 'cert', 'cv', 'sf', 'cf', 'nst';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
67 $self->{requests} = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
68
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
69 # Initial
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
70
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
71 $self->{odcid} = undef;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
72 $self->{scid} = Crypt::PRNG::random_bytes(17);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
73 $self->{dcid} = Crypt::PRNG::random_bytes(18);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
74 $self->{salt} = "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17"
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
75 . "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
76 $self->{ncid} = [];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
77 $self->{early_data} = $early_data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
78
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
79 $self->retry();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
80 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
81
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
82 sub retry {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
83 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
84 my $prk = Crypt::KeyDerivation::hkdf_extract($self->{dcid},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
85 $self->{salt}, 'SHA256');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
86
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
87 Test::Nginx::log_core('||', "scid = " . unpack("H*", $self->{scid}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
88 Test::Nginx::log_core('||', "dcid = " . unpack("H*", $self->{dcid}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
89 Test::Nginx::log_core('||', "prk = " . unpack("H*", $prk));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
90
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
91 $self->set_traffic_keys('tls13 client in', 0, 'w', $prk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
92 $self->set_traffic_keys('tls13 server in', 0, 'r', $prk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
93 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
94
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
95 sub init_key_schedule {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
96 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
97 $self->{psk} = $self->{psk_list}[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
98 $self->{es_prk} = Crypt::KeyDerivation::hkdf_extract(
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
99 $self->{psk}->{secret} || pack("x32"), pack("x32"), 'SHA256');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
100 $self->{sk} = Crypt::PK::X25519->new->generate_key;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
101 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
102
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
103 sub initial {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
104 my ($self, $ed) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
105 $self->{tlsm}{ch} = $self->build_tls_client_hello();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
106 my $ch = $self->{tlsm}{ch};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
107 my $crypto = build_crypto($ch);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
108 my $padding = 1200 - length($crypto);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
109 $padding = 0 if $padding < 0 || $self->{psk}->{ed};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
110 my $payload = $crypto . pack("x$padding");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
111 my $initial = $self->encrypt_aead($payload, 0);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
112
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
113 if ($ed && $self->{psk}->{ed}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
114 $self->set_traffic_keys('tls13 c e traffic', 1, 'w',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
115 $self->{es_prk}, Crypt::Digest::digest_data('SHA256',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
116 $self->{tlsm}{ch}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
117
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
118 # my $ed = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a"
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
119 # . $self->build_stream("\x01\x06\x00\x00\xc0");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
120 $payload = $ed;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
121 # $payload = $self->build_stream("GET /\n");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
122 $padding = 1200 - length($crypto) - length($payload);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
123 $payload .= pack("x$padding") if $padding > 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
124 $initial .= $self->encrypt_aead($payload, 1);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
125 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
126
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
127 $self->{socket}->syswrite($initial);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
128 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
129
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
130 sub handshake {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
131 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
132 my $buf = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
133
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
134 $self->read_tls_message(\$buf, \&parse_tls_server_hello) or return;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
135
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
136 my $sh = $self->{tlsm}{sh};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
137 my $extens_len = unpack("C*", substr($sh, 6 + 32 + 4, 2)) * 8
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
138 + unpack("C*", substr($sh, 6 + 32 + 5, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
139 my $extens = substr($sh, 6 + 32 + 4 + 2, $extens_len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
140 my $pub = key_share($extens);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
141 Test::Nginx::log_core('||', "pub = " . unpack("H*", $pub));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
142
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
143 my $pk = Crypt::PK::X25519->new;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
144 $pk->import_key_raw($pub, "public");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
145 my $shared_secret = $self->{sk}->shared_secret($pk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
146 Test::Nginx::log_core('||', "shared = " . unpack("H*", $shared_secret));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
147
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
148 # tls13_advance_key_schedule
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
149
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
150 $self->{hs_prk} = hkdf_advance($shared_secret, $self->{es_prk});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
151 Test::Nginx::log_core('||', "hs = " . unpack("H*", $self->{hs_prk}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
152
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
153 # derive_secret_with_transcript
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
154
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
155 my $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
156 . $self->{tlsm}{sh});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
157 $self->set_traffic_keys('tls13 c hs traffic', 2, 'w',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
158 $self->{hs_prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
159 $self->set_traffic_keys('tls13 s hs traffic', 2, 'r',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
160 $self->{hs_prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
161
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
162 $self->read_tls_message(\$buf, \&parse_tls_encrypted_extensions);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
163
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
164 unless (keys %{$self->{psk}}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
165 $self->read_tls_message(\$buf, \&parse_tls_certificate);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
166 $self->read_tls_message(\$buf, \&parse_tls_certificate_verify);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
167 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
168
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
169 $self->read_tls_message(\$buf, \&parse_tls_finished);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
170
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
171 # tls13_advance_key_schedule(application)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
172
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
173 $self->{ms_prk} = hkdf_advance(pack("x32"), $self->{hs_prk});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
174 Test::Nginx::log_core('||',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
175 "master = " . unpack("H*", $self->{ms_prk}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
176
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
177 # derive_secret_with_transcript(application)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
178
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
179 $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
180 . $self->{tlsm}{sh} . $self->{tlsm}{ee} . $self->{tlsm}{cert}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
181 . $self->{tlsm}{cv} . $self->{tlsm}{sf});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
182 $self->set_traffic_keys('tls13 c ap traffic', 3, 'w',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
183 $self->{ms_prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
184 $self->set_traffic_keys('tls13 s ap traffic', 3, 'r',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
185 $self->{ms_prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
186
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
187 # client finished
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
188
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
189 my $finished = tls13_finished($self->{keys}[2]{w}{prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
190 Test::Nginx::log_core('||', "finished = " . unpack("H*", $finished));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
191
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
192 $self->{tlsm}{cf} = $finished;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
193
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
194 $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
195 . $self->{tlsm}{sh} . $self->{tlsm}{ee} . $self->{tlsm}{cert}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
196 . $self->{tlsm}{cv} . $self->{tlsm}{sf} . $self->{tlsm}{cf});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
197 $self->{rms_prk} = hkdf_expand_label("tls13 res master", 32,
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
198 $self->{ms_prk}, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
199 Test::Nginx::log_core('||',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
200 "resumption = " . unpack("H*", $self->{rms_prk}));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
201
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
202 my $crypto = build_crypto($finished);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
203 $self->{socket}->syswrite($self->encrypt_aead($crypto, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
204 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
205
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
206 #if (!$psk->{ed}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
207 # my $r = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
208 # $s->syswrite(encrypt_aead($r, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
209 # $r = "\x01\x06\x00\x00\xc0";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
210 # $s->syswrite(encrypt_aead($self->build_stream($r), 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
211 #}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
212
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
213 sub DESTROY {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
214 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
215
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
216 return unless $self->{socket};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
217 return unless $self->{keys}[3];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
218 my $frame = build_cc(0, "graceful shutdown");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
219 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
220 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
221
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
222 sub ping {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
223 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
224 my $frame = "\x01\x00\x00\x00";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
225 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
226 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
227
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
228 sub reset_stream {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
229 my ($self, $sid, $code) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
230 my $final_size = $self->{streams}{$sid}{sent};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
231 my $frame = "\x04" . build_int($sid) . build_int($code)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
232 . build_int($final_size);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
233 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
234 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
235
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
236 sub stop_sending {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
237 my ($self, $sid, $code) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
238 my $frame = "\x05" . build_int($sid) . build_int($code);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
239 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
240 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
241
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
242 sub new_connection_id {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
243 my ($self, $seqno, $ret, $id, $token) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
244 my $frame = "\x18" . build_int($seqno) . build_int($ret)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
245 . pack("C", length($id)) . $id . $token;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
246 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
247 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
248
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
249 sub path_challenge {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
250 my ($self, $data) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
251 my $frame = "\x1a" . $data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
252 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
253 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
254
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
255 sub path_response {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
256 my ($self, $data) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
257 my $frame = "\x1b" . $data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
258 $self->{socket}->syswrite($self->encrypt_aead($frame, 3));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
259 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
260
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
261 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
262
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
263 sub parse_frames {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
264 my ($buf) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
265 my @frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
266 my $offset = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
267
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
268 while ($offset < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
269 my ($tlen, $type) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
270 $offset += $tlen;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
271 next if $type == 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
272 my $frame = { type => $type };
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
273
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
274 if ($type == 1) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
275 $frame->{type} = 'PING';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
276 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
277 if ($type == 2) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
278 $frame->{type} = 'ACK';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
279 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
280 $frame->{largest} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
281 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
282 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
283 $frame->{delay} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
284 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
285 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
286 $frame->{count} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
287 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
288 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
289 $frame->{first} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
290 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
291 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
292 if ($type == 4) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
293 $frame->{type} = 'RESET_STREAM';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
294 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
295 $frame->{sid} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
296 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
297 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
298 $frame->{code} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
299 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
300 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
301 $frame->{final_size} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
302 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
303 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
304 if ($type == 5) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
305 $frame->{type} = 'STOP_SENDING';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
306 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
307 $frame->{sid} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
308 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
309 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
310 $frame->{code} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
311 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
312 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
313 if ($type == 6) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
314 my ($olen, $off) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
315 $offset += $olen;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
316 my ($llen, $len) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
317 $offset += $llen;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
318 $frame->{type} = 'CRYPTO';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
319 $frame->{length} = $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
320 $frame->{offset} = $off;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
321 $frame->{payload} = substr($buf, $offset, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
322 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
323 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
324 if ($type == 7) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
325 $frame->{type} = 'NEW_TOKEN';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
326 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
327 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
328 $frame->{token} = substr($buf, $offset, $val);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
329 $offset += $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
330 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
331 if (($type & 0xf8) == 0x08) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
332 $frame->{type} = 'STREAM';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
333 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
334 $frame->{id} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
335 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
336 if ($type & 0x4) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
337 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
338 $frame->{offset} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
339 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
340 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
341 $frame->{offset} = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
342 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
343 if ($type & 0x2) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
344 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
345 $frame->{length} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
346 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
347 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
348 $frame->{length} = length($buf) - $offset;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
349 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
350 if ($type & 0x1) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
351 $frame->{fin} = 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
352 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
353 $frame->{payload} =
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
354 substr($buf, $offset, $frame->{length});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
355 $offset += $frame->{length};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
356 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
357 if ($type == 18 || $type == 19) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
358 $frame->{type} = 'MAX_STREAMS';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
359 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
360 $frame->{val} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
361 $frame->{uni} = 1 if $type == 19;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
362 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
363 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
364 if ($type == 24) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
365 $frame->{type} = 'NCID';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
366 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
367 $frame->{seqno} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
368 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
369 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
370 $frame->{rpt} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
371 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
372 $len = unpack("C", substr($buf, $offset, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
373 $frame->{length} = $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
374 $offset += 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
375 $frame->{cid} = substr($buf, $offset, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
376 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
377 $frame->{token} = substr($buf, $offset, 16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
378 $offset += 16;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
379 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
380 if ($type == 26) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
381 $frame->{type} = 'PATH_CHALLENGE';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
382 $frame->{data} = substr($buf, $offset, 8);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
383 $offset += 8;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
384 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
385 if ($type == 27) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
386 $frame->{type} = 'PATH_RESPONSE';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
387 $frame->{data} = substr($buf, $offset, 8);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
388 $offset += 8;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
389 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
390 if ($type == 28 || $type == 29) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
391 $frame->{type} = 'CONNECTION_CLOSE';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
392 my ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
393 $frame->{error} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
394 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
395 if ($type == 28) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
396 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
397 $frame->{frame_type} = $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
398 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
399 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
400 ($len, $val) = parse_int(substr($buf, $offset));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
401 $offset += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
402 $frame->{phrase} = substr($buf, $offset, $val);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
403 $offset += $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
404 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
405 if ($type == 30) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
406 $frame->{type} = 'HANDSHAKE_DONE';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
407 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
408 push @frames, $frame;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
409 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
410 return \@frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
411 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
412
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
413 sub handle_frames {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
414 my ($self, $frames, $level) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
415
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
416 my @frames = grep { $_->{type} eq 'CRYPTO' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
417 while (my $frame = shift @frames) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
418 insert_crypto($self->{crypto_in}[$level], [
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
419 $frame->{offset},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
420 $frame->{length},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
421 $frame->{payload},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
422 ]);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
423
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
424 $self->parse_tls_nst() if $level == 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
425 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
426
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
427 @frames = grep { $_->{type} eq 'STREAM' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
428 while (my $frame = shift @frames) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
429 $self->{stream_in}[$frame->{id}] ||= { buf => [], pos => 0 };
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
430 insert_crypto($self->{stream_in}[$frame->{id}]->{buf}, [
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
431 $frame->{offset},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
432 $frame->{length},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
433 $frame->{payload},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
434 $frame->{fin},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
435 ]);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
436 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
437
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
438 @frames = grep { $_->{type} eq 'NCID' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
439 while (my $frame = shift @frames) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
440 push @{$self->{ncid}}, $frame;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
441 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
442
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
443 my $ack = $self->{ack}[$level];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
444
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
445 # stop tracking acknowledged ACK ranges
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
446
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
447 @frames = grep { $_->{type} eq 'ACK' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
448 while (my $frame = shift @frames) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
449 my $max = $frame->{largest};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
450 my $min = $max - $frame->{first};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
451
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
452 for my $num ($min .. $max) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
453 for my $pn (keys %$ack) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
454 delete $ack->{$pn} if $ack->{$pn} == $num;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
455 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
456 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
457 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
458
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
459 $self->{socket}->syswrite($self->encrypt_aead(build_ack($ack), $level));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
460
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
461 for my $pn (keys %$ack) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
462 $ack->{$pn} = $self->{pn}[0][$level] if $ack->{$pn} == -1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
463 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
464
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
465 my ($frame) = grep { $_->{type} eq 'NEW_TOKEN' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
466 $self->{token} = $frame->{token} || '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
467
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
468 push @{$self->{frames_in}}, grep { $_->{type} ne 'CRYPTO'
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
469 && $_->{type} ne 'STREAM' } @$frames;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
470 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
471
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
472 sub insert_crypto {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
473 my ($crypto, $frame) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
474 my $i;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
475
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
476 for ($i = 0; $i < scalar @$crypto; $i++) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
477 # frame][crypto][frame
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
478 my $this = @$crypto[$i];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
479 if (@$frame[0] <= @$this[0] &&
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
480 @$frame[0] + @$frame[1] >= @$this[0] + @$this[1])
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
481 {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
482 my $old = substr(@$frame[2], @$this[0] - @$frame[0],
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
483 @$this[1]);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
484 die "bad inner" if $old ne @$this[2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
485 splice @$crypto, $i, 1; $i--;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
486 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
487 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
488
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
489 return push @$crypto, $frame if !@$crypto;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
490
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
491 for ($i = 0; $i < @$crypto; $i++) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
492 if (@$frame[0] <= @{@$crypto[$i]}[0] + @{@$crypto[$i]}[1]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
493 last;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
494 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
495 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
496
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
497 return push @$crypto, $frame if $i == @$crypto;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
498
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
499 my $this = @$crypto[$i];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
500 my $next = @$crypto[$i + 1];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
501
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
502 if (@$frame[0] + @$frame[1] == @$this[0]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
503 # frame][crypto
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
504 @$this[0] = @$frame[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
505 @$this[1] += @$frame[1];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
506 @$this[2] = @$frame[2] . @$this[2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
507
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
508 } elsif (@$this[0] + @$this[1] == @$frame[0]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
509 # crypto][frame
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
510 @$this[1] += @$frame[1];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
511 @$this[2] .= @$frame[2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
512 @$this[3] = @$frame[3];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
513
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
514 } elsif (@$frame[0] + @$frame[1] < @$this[0]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
515 # frame..crypto
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
516 return splice @$crypto, $i, 0, $frame;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
517
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
518 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
519 # overlay
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
520 my ($b1, $b2) = @$this[0] < @$frame[0]
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
521 ? ($this, $frame) : ($frame, $this);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
522 my ($o1, $o2) = @$this[0] + @$this[1] < @$frame[0] + @$frame[1]
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
523 ? ($this, $frame) : ($frame, $this);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
524 my $offset = @$b2[0] - @$b1[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
525 my $length = @$o1[0] + @$o1[1] - @$b2[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
526 my $old = substr @$b1[2], $offset, $length, @$b2[2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
527 die "bad repl" if substr(@$b1[2], $offset, $length) ne $old;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
528 @$this = (@$b1[0], @$o2[0] + @$o2[1] - @$b1[0], @$b1[2]);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
529 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
530
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
531 return if !defined $next;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
532
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
533 # combine with next overlay if any
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
534 if (@$this[0] + @$this[1] >= @$next[0]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
535 my $offset = @$next[0] - @$this[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
536 my $length = @$this[0] + @$this[1] - @$next[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
537 my $old = substr @$this[2], $offset, $length, @$next[2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
538 die "bad repl2" if substr(@$this[2], $offset, $length) ne $old;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
539 @$this[1] = @$next[0] + @$next[1] - @$this[0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
540 splice @$crypto, $i + 1, 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
541 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
542 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
543
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
544 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
545
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
546 sub save_session_tickets {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
547 my ($self, $content) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
548
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
549 my $nst_len = unpack("n", substr($content, 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
550 my $nst = substr($content, 4, $nst_len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
551
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
552 my $psk = {};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
553 my $lifetime = substr($nst, 0, 4);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
554 $psk->{age_add} = substr($nst, 4, 4);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
555 my $nonce_len = unpack("C", substr($nst, 8, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
556 my $nonce = substr($nst, 9, $nonce_len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
557 my $len = unpack("n", substr($nst, 8 + 1 + $nonce_len, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
558 $psk->{ticket} = substr($nst, 11 + $nonce_len, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
559
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
560 my $extens_len = unpack("n", substr($nst, 11 + $nonce_len + $len, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
561 my $extens = substr($nst, 11 + $nonce_len + $len + 2, $extens_len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
562
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
563 $psk->{ed} = early_data($extens);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
564 $psk->{secret} = hkdf_expand_label("tls13 resumption", 32,
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
565 $self->{rms_prk}, $nonce);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
566 push @{$self->{psk_list}}, $psk;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
567 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
568
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
569 sub decode_pn {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
570 my ($self, $pn, $pnl, $level) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
571 my $expected = $self->{pn}[1][$level] + 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
572 my $pn_win = 1 << $pnl * 8;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
573 my $pn_hwin = $pn_win / 2;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
574
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
575 $pn |= $expected & ~($pn_win - 1);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
576
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
577 if ($pn <= $expected - $pn_hwin && $pn < (1 << 62) - $pn_win) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
578 $pn += $pn_win;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
579
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
580 } elsif ($pn > $expected + $pn_hwin && $pn >= $pn_win) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
581 $pn -= $pn_win;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
582 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
583
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
584 return $pn;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
585 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
586
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
587 sub decrypt_aead {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
588 my ($self, $buf) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
589 my $flags = unpack("C", substr($buf, 0, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
590 return 0, $self->decrypt_retry($buf) if ($flags & 0xf0) == 0xf0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
591 my $level = $flags & 0x80 ? $flags - 0xc0 >> 4 : 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
592 my $offpn = 1 + length($self->{scid}) if $level == 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
593 $offpn = (
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
594 $offpn = unpack("C", substr($buf, 5, 1)),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
595 $self->{scid} = substr($buf, 6, $offpn),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
596 $offpn = unpack("C", substr($buf, 6 + length($self->{scid}), 1)),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
597 $self->{dcid} =
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
598 substr($buf, 6 + length($self->{scid}) + 1, $offpn),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
599 7 + ($level == 0) + length($self->{scid})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
600 + length($self->{dcid})) if $level != 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
601 my ($len, $val) = $level != 3
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
602 ? parse_int(substr($buf, $offpn))
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
603 : (0, length($buf) - $offpn);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
604 $offpn += $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
605
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
606 my $sample = substr($buf, $offpn + 4, 16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
607 my ($ad, $pnl, $pn) = $self->decrypt_ad($buf,
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
608 $self->{keys}[$level]{r}{hp}, $sample, $offpn, $level == 3);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
609 Test::Nginx::log_core('||', "ad = " . unpack("H*", $ad));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
610 $pn = $self->decode_pn($pn, $pnl, $level);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
611 my $nonce = substr(pack("x12") . pack("N", $pn), -12)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
612 ^ $self->{keys}[$level]{r}{iv};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
613 my $ciphertext = substr($buf, $offpn + $pnl, $val - 16 - $pnl);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
614 my $tag = substr($buf, $offpn + $val - 16, 16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
615 my $plaintext = Crypt::AuthEnc::GCM::gcm_decrypt_verify('AES',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
616 $self->{keys}[$level]{r}{key}, $nonce, $ad, $ciphertext, $tag);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
617 return if !defined $plaintext;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
618 Test::Nginx::log_core('||',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
619 "pn = $pn, level = $level, length = " . length($plaintext));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
620
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
621 $self->{pn}[1][$level] = $pn;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
622 $self->{ack}[$level]{$pn} = -1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
623 $self->{ack}[$_] = undef for (0 .. $level - 1);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
624
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
625 return ($level, $plaintext,
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
626 substr($buf, length($ad . $ciphertext . $tag)), '');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
627 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
628
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
629 sub decrypt_ad {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
630 my ($self, $buf, $hp, $sample, $offset, $short) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
631 my $m = Crypt::Mode::CTR->new('AES');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
632 my $mask = $m->encrypt($self->{zero}, $hp, $sample);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
633 substr($buf, 0, 1) ^= substr($mask, 0, 1) & ($short ? "\x1f" : "\x0f");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
634 my $pnl = unpack("C", substr($buf, 0, 1) & "\x03") + 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
635 for (my $i = 0; $i < $pnl; $i++) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
636 substr($buf, $offset + $i, 1) ^= substr($mask, $i + 1, 1);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
637 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
638 my $pn = unpack("C", substr($buf, $offset, $pnl));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
639 my $ad = substr($buf, 0, $offset + $pnl);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
640 return ($ad, $pnl, $pn);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
641 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
642
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
643 sub encrypt_aead {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
644 my ($self, $payload, $level) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
645 my $pn = ++$self->{pn}[0][$level];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
646 my $ad = pack("C", $level == 3 ? 0x40 : 0xc + $level << 4) | "\x03";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
647 $ad .= "\x00\x00\x00\x01" unless $level == 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
648 $ad .= $level == 3 ? $self->{dcid} :
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
649 pack("C", length($self->{dcid})) . $self->{dcid}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
650 . pack("C", length($self->{scid})) . $self->{scid};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
651 $ad .= build_int(length($self->{token})) . $self->{token}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
652 if $level == 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
653 $ad .= build_int(length($payload) + 16 + 4) unless $level == 3;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
654 $ad .= pack("N", $pn);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
655 my $nonce = substr(pack("x12") . pack("N", $pn), -12)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
656 ^ $self->{keys}[$level]{w}{iv};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
657 my ($ciphertext, $tag) = Crypt::AuthEnc::GCM::gcm_encrypt_authenticate(
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
658 'AES', $self->{keys}[$level]{w}{key}, $nonce, $ad, $payload);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
659 my $sample = substr($ciphertext . $tag, 0, 16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
660
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
661 $ad = $self->encrypt_ad($ad, $self->{keys}[$level]{w}{hp},
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
662 $sample, $level == 3);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
663 return $ad . $ciphertext . $tag;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
664 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
665
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
666 sub encrypt_ad {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
667 my ($self, $ad, $hp, $sample, $short) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
668 my $m = Crypt::Mode::CTR->new('AES');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
669 my $mask = $m->encrypt($self->{zero}, $hp, $sample);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
670 substr($ad, 0, 1) ^= substr($mask, 0, 1) & ($short ? "\x1f" : "\x0f");
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
671 substr($ad, -4) ^= substr($mask, 1);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
672 return $ad;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
673 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
674
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
675 sub decrypt_retry {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
676 my ($self, $buf) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
677 my $off = unpack("C", substr($buf, 5, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
678 $self->{scid} = substr($buf, 6, $off);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
679 $self->{odcid} = $self->{dcid};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
680 $self->{dcid} = unpack("C", substr($buf, 6 + $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
681 $self->{dcid} = substr($buf, 6 + $off + 1, $self->{dcid});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
682 my $token = substr($buf, 6 + $off + 1 + length($self->{dcid}), -16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
683 my $tag = substr($buf, -16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
684 my $pseudo = pack("C", length($self->{odcid})) . $self->{odcid}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
685 . substr($buf, 0, -16);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
686 return ($tag, retry_verify_tag($pseudo), $token);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
687 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
688
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
689 sub retry_verify_tag {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
690 my $key = "\xbe\x0c\x69\x0b\x9f\x66\x57\x5a"
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
691 . "\x1d\x76\x6b\x54\xe3\x68\xc8\x4e";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
692 my $nonce = "\x46\x15\x99\xd3\x5d\x63\x2b\xf2\x23\x98\x25\xbb";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
693 my (undef, $tag) = Crypt::AuthEnc::GCM::gcm_encrypt_authenticate('AES',
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
694 $key, $nonce, shift, '');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
695 return $tag;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
696 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
697
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
698 sub set_traffic_keys {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
699 my ($self, $label, $level, $direction, $secret, $digest) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
700 my $prk = hkdf_expand_label($label, 32, $secret, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
701 my $key = hkdf_expand_label("tls13 quic key", 16, $prk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
702 my $iv = hkdf_expand_label("tls13 quic iv", 12, $prk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
703 my $hp = hkdf_expand_label("tls13 quic hp", 16, $prk);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
704 $self->{keys}[$level]{$direction}{prk} = $prk;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
705 $self->{keys}[$level]{$direction}{key} = $key;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
706 $self->{keys}[$level]{$direction}{iv} = $iv;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
707 $self->{keys}[$level]{$direction}{hp} = $hp;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
708 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
709
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
710 sub hmac_finished {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
711 my ($key, $digest) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
712 my $finished_key = hkdf_expand_label("tls13 finished", 32, $key);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
713 Crypt::Mac::HMAC::hmac('SHA256', $finished_key, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
714 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
715
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
716 sub tls13_finished {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
717 my ($key, $digest) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
718 my $hmac = hmac_finished($key, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
719 "\x14\x00" . pack('n', length($hmac)) . $hmac;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
720 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
721
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
722 sub binders {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
723 my ($key, $digest) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
724 my $hmac = hmac_finished($key, $digest);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
725 pack('n', length($hmac) + 1) . pack('C', length($hmac)) . $hmac;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
726 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
727
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
728 sub hkdf_advance {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
729 my ($secret, $prk) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
730 my $digest0 = Crypt::Digest::digest_data('SHA256', '');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
731 my $expand = hkdf_expand_label("tls13 derived", 32, $prk, $digest0);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
732 Crypt::KeyDerivation::hkdf_extract($secret, $expand, 'SHA256');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
733 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
734
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
735 sub hkdf_expand_label {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
736 my ($label, $len, $prk, $context) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
737 $context = '' if !defined $context;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
738 my $info = pack("C3", 0, $len, length($label)) . $label
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
739 . pack("C", length($context)) . $context;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
740 return Crypt::KeyDerivation::hkdf_expand($prk, 'SHA256', $len, $info);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
741 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
742
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
743 sub key_share {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
744 my ($extens) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
745 my $offset = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
746 while ($offset < length($extens)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
747 my $ext = substr($extens, $offset, 2);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
748 my $len = unpack("C", substr($extens, $offset + 2, 1)) * 8 +
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
749 unpack("C", substr($extens, $offset + 3, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
750 if ($ext eq "\x00\x33") {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
751 return substr($extens, $offset + 4 + 4, $len - 4);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
752 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
753 $offset += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
754 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
755 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
756
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
757 sub early_data {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
758 my ($extens) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
759 my $offset = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
760 while ($offset < length($extens)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
761 my $ext = substr($extens, $offset, 2);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
762 my $len = unpack("C", substr($extens, $offset + 2, 1)) * 8 +
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
763 unpack("C", substr($extens, $offset + 3, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
764 if ($ext eq "\x00\x2a") {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
765 return substr($extens, $offset + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
766 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
767 $offset += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
768 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
769 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
770
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
771 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
772
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
773 sub build_cc {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
774 my ($code, $reason) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
775 "\x1d" . build_int($code) . build_int(length($reason)) . $reason;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
776 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
777
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
778 sub build_ack {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
779 my ($ack) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
780 my @keys = sort { $b <=> $a } keys %$ack;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
781
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
782 return "\x02" . build_int($keys[0]) . "\x00\x00\x00" if @keys == 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
783
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
784 my $min = my $max = shift @keys;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
785 my @acks = ();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
786 for my $next (@keys) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
787 if ($next == $min - 1) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
788 $min = $next;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
789 next if $next != $keys[-1];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
790 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
791 push @acks, $max, $min;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
792 $min = $max = $next;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
793 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
794
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
795 ($max, $min) = splice @acks, 0, 2;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
796 my $ranges = @acks / 2;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
797
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
798 $ack = "\x02" . build_int($max) . "\x00" . build_int($ranges)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
799 . build_int($max - $min);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
800
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
801 for (my $smallest = $min; $ranges--; ) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
802 my ($max, $min) = splice @acks, 0, 2;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
803 $ack .= build_int($smallest - $max - 2);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
804 $ack .= build_int($max - $min);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
805 $smallest = $min;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
806 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
807
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
808 return $ack;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
809 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
810
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
811 sub build_crypto {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
812 my ($tlsm) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
813 "\x06\x00" . build_int(length($tlsm)) . $tlsm;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
814 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
815
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
816 sub build_stream {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
817 my ($self, $r, %extra) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
818 my $stream = $extra{start} ? 0xe : 0xf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
819 my $length = $extra{length} ? $extra{length} : build_int(length($r));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
820 my $offset = build_int($extra{offset} ? $extra{offset} : 0);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
821 my $sid = defined $extra{sid} ? $extra{sid} : $self->{requests}++;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
822 pack("CC", $stream, 4 * $sid) . $offset . $length . $r;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
823 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
824
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
825 sub parse_int {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
826 my ($buf) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
827 my $val = unpack("C", substr($buf, 0, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
828 my $len = my $plen = 1 << ($val >> 6);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
829 $val = $val & 0x3f;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
830 while (--$len) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
831 $val = ($val << 8) + unpack("C", substr($buf, $plen - $len, 1))
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
832 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
833 return ($plen, $val);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
834 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
835
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
836 sub build_int {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
837 my ($value) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
838
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
839 my $build_int_set = sub {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
840 my ($value, $len, $bits) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
841 (($value >> ($len * 8)) & 0xff) | ($bits << 6);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
842 };
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
843
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
844 if ($value < 1 << 6) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
845 pack("C", $build_int_set->($value, 0, 0));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
846
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
847 } elsif ($value < 1 << 14) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
848 pack("C*",
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
849 $build_int_set->($value, 1, 1),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
850 $build_int_set->($value, 0, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
851 );
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
852
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
853 } elsif ($value < 1 << 30) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
854 pack("C*",
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
855 $build_int_set->($value, 3, 2),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
856 $build_int_set->($value, 2, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
857 $build_int_set->($value, 1, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
858 $build_int_set->($value, 0, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
859 );
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
860
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
861 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
862 pack("C*",
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
863 build_int_set->($value, 7, 3),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
864 build_int_set->($value, 6, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
865 build_int_set->($value, 5, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
866 build_int_set->($value, 4, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
867 build_int_set->($value, 3, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
868 build_int_set->($value, 2, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
869 build_int_set->($value, 1, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
870 build_int_set->($value, 0, 0),
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
871 );
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
872 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
873 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
874
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
875 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
876
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
877 sub read_stream_message {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
878 my ($self, $timo) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
879 my ($level, $plaintext, @data);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
880 my $s = $self->{socket};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
881
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
882 while (1) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
883 @data = $self->parse_stream();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
884 return @data if $#data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
885 return if scalar @{$self->{frames_in}};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
886
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
887 my $txt;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
888
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
889 if (!length($self->{buf})) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
890 return unless IO::Select->new($s)->can_read($timo || 3);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
891 $s->sysread($self->{buf}, 65527);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
892 $txt = "recv";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
893 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
894 $txt = "remaining";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
895 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
896 my $len = length $self->{buf};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
897 Test::Nginx::log_core('||', sprintf("$txt = [%d]", $len));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
898
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
899 while ($self->{buf}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
900 ($level, $plaintext, $self->{buf}, $self->{token})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
901 = $self->decrypt_aead($self->{buf});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
902 return if !defined $plaintext;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
903 goto retry if $self->{token};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
904 $self->handle_frames(parse_frames($plaintext), $level);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
905 @data = $self->parse_stream();
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
906 return @data if $#data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
907 return if scalar @{$self->{frames_in}};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
908 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
909 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
910 return;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
911 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
912
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
913 sub parse_stream {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
914 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
915 my $data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
916
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
917 for my $i (0 .. $#{$self->{stream_in}}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
918 my $stream = $self->{stream_in}[$i];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
919 next if !defined $stream;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
920
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
921 my $buf = $stream->{buf}[0][2];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
922
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
923 if ($stream->{buf}[0][3]) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
924 $stream->{buf}[0][3] = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
925 $stream->{eof} = 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
926 $data = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
927 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
928
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
929 if (length($buf) > $stream->{pos}) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
930 $data = substr($buf, $stream->{pos});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
931 $stream->{pos} = length($buf);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
932 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
933
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
934 next if !defined $data;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
935
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
936 return ($i, $data, $stream->{eof} ? 1 : 0);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
937 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
938 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
939
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
940 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
941
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
942 sub read_tls_message {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
943 my ($self, $buf, $type) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
944 my $s = $self->{socket};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
945
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
946 while (!$type->($self)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
947 my $txt;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
948
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
949 if (!length($$buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
950 return unless IO::Select->new($s)->can_read(3);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
951 $s->sysread($$buf, 65527);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
952 $txt = "recv";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
953 } else {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
954 $txt = "remaining";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
955 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
956 my $len = length $$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
957 Test::Nginx::log_core('||', sprintf("$txt = [%d]", $len));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
958
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
959 while ($$buf) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
960 (my $level, my $plaintext, $$buf, $self->{token})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
961 = $self->decrypt_aead($$buf);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
962 return if !defined $plaintext;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
963 goto retry if $self->{token};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
964 $self->handle_frames(parse_frames($plaintext), $level);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
965 return 1 if $type->($self);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
966 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
967 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
968 return;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
969 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
970
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
971 sub parse_tls_server_hello {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
972 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
973 my $buf = $self->{crypto_in}[0][0][2] if $self->{crypto_in}[0][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
974 return 0 if !$buf || length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
975 my $type = unpack("C", substr($buf, 0, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
976 my $len = unpack("n", substr($buf, 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
977 my $content = substr($buf, 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
978 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
979 $self->{tlsm}{sh} = substr($buf, 0, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
980 return $self->{tlsm}{sh};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
981 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
982
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
983 sub parse_tls_encrypted_extensions {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
984 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
985 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
986 return 0 if !$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
987 my $off = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
988 my $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
989
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
990 while ($off < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
991 return 0 if length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
992 my $type = unpack("C", substr($buf, $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
993 my $len = unpack("n", substr($buf, $off + 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
994 $content = substr($buf, $off + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
995 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
996 last if $type == 8;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
997 $off += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
998 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
999 $self->{tlsm}{ee} = substr($buf, $off, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1000 return $self->{tlsm}{ee};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1001 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1002
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1003 sub parse_tls_certificate {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1004 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1005 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1006 return 0 if !$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1007 my $off = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1008 my $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1009
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1010 while ($off < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1011 return 0 if length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1012 my $type = unpack("C", substr($buf, $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1013 my $len = unpack("n", substr($buf, $off + 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1014 $content = substr($buf, $off + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1015 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1016 last if $type == 11;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1017 $off += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1018 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1019 $self->{tlsm}{cert} = substr($buf, $off, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1020 return $self->{tlsm}{cert};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1021 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1022
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1023 sub parse_tls_certificate_verify {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1024 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1025 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1026 return 0 if !$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1027 my $off = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1028 my $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1029
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1030 while ($off < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1031 return 0 if length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1032 my $type = unpack("C", substr($buf, $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1033 my $len = unpack("n", substr($buf, $off + 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1034 $content = substr($buf, $off + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1035 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1036 last if $type == 15;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1037 $off += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1038 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1039 $self->{tlsm}{cv} = substr($buf, $off, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1040 return $self->{tlsm}{cv};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1041 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1042
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1043 sub parse_tls_finished {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1044 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1045 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1046 return 0 if !$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1047 my $off = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1048 my $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1049
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1050 while ($off < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1051 return 0 if length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1052 my $type = unpack("C", substr($buf, $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1053 my $len = unpack("n", substr($buf, $off + 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1054 $content = substr($buf, $off + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1055 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1056 last if $type == 20;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1057 $off += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1058 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1059 $self->{tlsm}{sf} = substr($buf, $off, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1060 return $self->{tlsm}{sf};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1061 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1062
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1063 sub parse_tls_nst {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1064 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1065 my $buf = $self->{crypto_in}[3][0][2] if $self->{crypto_in}[3][0];
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1066 return 0 if !$buf;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1067 my $off = 0;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1068 my $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1069
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1070 while ($off < length($buf)) {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1071 return 0 if length($buf) < 4;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1072 my $type = unpack("C", substr($buf, $off, 1));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1073 my $len = unpack("n", substr($buf, $off + 2, 2));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1074 $content = substr($buf, $off + 4, $len);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1075 return 0 if length($content) < $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1076 $self->{tlsm}{nst} .= substr($buf, $off, 4) . $content;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1077 $self->save_session_tickets(substr($buf, $off, 4) . $content);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1078 $off += 4 + $len;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1079 substr($self->{crypto_in}[3][0][2], 0, $off) = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1080 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1081 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1082
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1083 sub build_tls_client_hello {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1084 my ($self) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1085 my $key_share = $self->{sk}->export_key_raw('public');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1086
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1087 my $version = "\x03\x03";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1088 my $random = Crypt::PRNG::random_bytes(32);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1089 my $session = "\x00";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1090 my $cipher = "\x00\x02\x13\x01";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1091 my $compr = "\x01\x00";
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1092 my $ext = build_tlsext_server_name($self->{sni})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1093 . build_tlsext_supported_groups(29)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1094 . build_tlsext_alpn("h3", "hq-interop")
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1095 . build_tlsext_sigalgs(0x0804, 0x0805, 0x0806)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1096 . build_tlsext_supported_versions(0x0304)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1097 . build_tlsext_ke_modes(1)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1098 . build_tlsext_key_share(29, $key_share)
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1099 . build_tlsext_quic_tp($self->{scid}, $self->{opts});
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1100
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1101 $ext .= build_tlsext_early_data($self->{psk})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1102 . build_tlsext_psk($self->{psk}) if keys %{$self->{psk}};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1103
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1104 my $len = pack('n', length($ext));
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1105 my $ch = $version . $random . $session . $cipher . $compr . $len . $ext;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1106 $ch = "\x01\x00" . pack('n', length($ch)) . $ch;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1107 $ch = build_tls_ch_with_binder($ch, $self->{es_prk})
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1108 if keys %{$self->{psk}};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1109 return $ch;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1110 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1111
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1112 sub build_tlsext_server_name {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1113 my ($name) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1114 my $sname = pack('xn', length($name)) . $name;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1115 my $snamelist = pack('n', length($sname)) . $sname;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1116 pack('n2', 0, length($snamelist)) . $snamelist;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1117 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1118
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1119 sub build_tlsext_supported_groups {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1120 my $ngrouplist = pack('n*', @_ * 2, @_);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1121 pack('n2', 10, length($ngrouplist)) . $ngrouplist;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1122 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1123
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1124 sub build_tlsext_alpn {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1125 my $protoname = pack('(C/a*)*', @_);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1126 my $protonamelist = pack('n', length($protoname)) . $protoname;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1127 pack('n2', 16, length($protonamelist)) . $protonamelist;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1128 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1129
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1130 sub build_tlsext_sigalgs {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1131 my $sschemelist = pack('n*', @_ * 2, @_);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1132 pack('n2', 13, length($sschemelist)) . $sschemelist;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1133 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1134
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1135 sub build_tlsext_supported_versions {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1136 my $versions = pack('Cn*', @_ * 2, @_);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1137 pack('n2', 43, length($versions)) . $versions;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1138 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1139
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1140 sub build_tlsext_ke_modes {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1141 my $versions = pack('C*', scalar(@_), @_);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1142 pack('n2', 45, length($versions)) . $versions;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1143 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1144
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1145 sub build_tlsext_key_share {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1146 my ($group, $share) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1147 my $kse = pack("n2", $group, length($share)) . $share;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1148 my $ksch = pack("n", length($kse)) . $kse;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1149 pack('n2', 51, length($ksch)) . $ksch;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1150 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1151
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1152 sub build_tlsext_quic_tp {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1153 my ($scid, $opts) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1154 my $tp = '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1155 my $quic_tp_tlv = sub {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1156 my ($id, $val) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1157 $val = $opts->{$id} // $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1158 $val = build_int($val) unless $id == 15;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1159 $tp .= build_int($id) . pack("C*", length($val)) . $val;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1160 };
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1161 $quic_tp_tlv->(1, 30000);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1162 $quic_tp_tlv->(4, 1048576);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1163 $quic_tp_tlv->(5, 262144);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1164 $quic_tp_tlv->(7, 262144);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1165 $quic_tp_tlv->(9, 100);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1166 $quic_tp_tlv->(15, $scid);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1167 pack('n2', 57, length($tp)) . $tp;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1168 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1169
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1170 sub build_tlsext_early_data {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1171 my ($psk) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1172 $psk->{ed} ? pack('n2', 42, 0) : '';
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1173 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1174
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1175 sub build_tlsext_psk {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1176 my ($psk) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1177 my $identity = pack('n', length($psk->{ticket})) . $psk->{ticket}
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1178 . $psk->{age_add};
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1179 my $identities = pack('n', length($identity)) . $identity;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1180 my $hash = pack('x32'); # SHA256
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1181 my $binder = pack('C', length($hash)) . $hash;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1182 my $binders = pack('n', length($binder)) . $binder;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1183 pack('n2', 41, length($identities . $binders)) . $identities . $binders;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1184 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1185
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1186 sub build_tls_ch_with_binder {
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1187 my ($ch, $prk) = @_;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1188 my $digest0 = Crypt::Digest::digest_data('SHA256', '');
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1189 my $key = hkdf_expand_label("tls13 res binder", 32, $prk, $digest0);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1190 my $truncated = substr($ch, 0, -35);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1191 my $context = Crypt::Digest::digest_data('SHA256', $truncated);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1192 $truncated . binders($key, $context);
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1193 }
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1194
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1195 ###############################################################################
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1196
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1197 1;
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1198
d57a0fd293a3 Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff changeset
1199 ###############################################################################