Mercurial > hg > nginx-tests
comparison lib/Test/Nginx/HTTP3.pm @ 1934:4d13c9e74d04
Tests: added ability to setup QUIC TLS named group.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 22 Aug 2023 14:29:16 +0400 |
parents | 9bafe7cddd3c |
children | e1059682aeef |
comparison
equal
deleted
inserted
replaced
1933:9bafe7cddd3c | 1934:4d13c9e74d04 |
---|---|
21 bless $self, shift @_; | 21 bless $self, shift @_; |
22 | 22 |
23 my ($port, %extra) = @_; | 23 my ($port, %extra) = @_; |
24 | 24 |
25 require Crypt::KeyDerivation; | 25 require Crypt::KeyDerivation; |
26 require Crypt::PK::ECC; | |
26 require Crypt::PK::X25519; | 27 require Crypt::PK::X25519; |
27 require Crypt::PRNG; | 28 require Crypt::PRNG; |
28 require Crypt::AuthEnc::GCM; | 29 require Crypt::AuthEnc::GCM; |
29 require Crypt::AuthEnc::CCM; | 30 require Crypt::AuthEnc::CCM; |
30 require Crypt::AuthEnc::ChaCha20Poly1305; | 31 require Crypt::AuthEnc::ChaCha20Poly1305; |
44 $self->{early_data} = $extra{early_data}; | 45 $self->{early_data} = $extra{early_data}; |
45 | 46 |
46 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost'; | 47 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost'; |
47 $self->{cipher} = 0x1301; | 48 $self->{cipher} = 0x1301; |
48 $self->{ciphers} = $extra{ciphers} || "\x13\x01"; | 49 $self->{ciphers} = $extra{ciphers} || "\x13\x01"; |
50 $self->{group} = $extra{group} || 'x25519'; | |
49 $self->{opts} = $extra{opts}; | 51 $self->{opts} = $extra{opts}; |
50 | 52 |
51 $self->{zero} = pack("x5"); | 53 $self->{zero} = pack("x5"); |
52 | 54 |
53 $self->{static_encode} = [ static_table() ]; | 55 $self->{static_encode} = [ static_table() ]; |
124 ('SHA384', 48) : ('SHA256', 32); | 126 ('SHA384', 48) : ('SHA256', 32); |
125 $self->{es_prk} = Crypt::KeyDerivation::hkdf_extract( | 127 $self->{es_prk} = Crypt::KeyDerivation::hkdf_extract( |
126 $self->{psk}->{secret} || pack("x$hlen"), pack("x$hlen"), | 128 $self->{psk}->{secret} || pack("x$hlen"), pack("x$hlen"), |
127 $hash); | 129 $hash); |
128 Test::Nginx::log_core('||', "es = " . unpack("H*", $self->{es_prk})); | 130 Test::Nginx::log_core('||', "es = " . unpack("H*", $self->{es_prk})); |
129 $self->{sk} = Crypt::PK::X25519->new->generate_key; | 131 |
132 $self->tls_generate_key(); | |
130 } | 133 } |
131 | 134 |
132 sub initial { | 135 sub initial { |
133 my ($self) = @_; | 136 my ($self) = @_; |
134 $self->{tlsm}{ch} = $self->build_tls_client_hello(); | 137 $self->{tlsm}{ch} = $self->build_tls_client_hello(); |
169 + unpack("C*", substr($sh, 6 + 32 + 5, 1)); | 172 + unpack("C*", substr($sh, 6 + 32 + 5, 1)); |
170 my $extens = substr($sh, 6 + 32 + 4 + 2, $extens_len); | 173 my $extens = substr($sh, 6 + 32 + 4 + 2, $extens_len); |
171 my $pub = key_share($extens); | 174 my $pub = key_share($extens); |
172 Test::Nginx::log_core('||', "pub = " . unpack("H*", $pub)); | 175 Test::Nginx::log_core('||', "pub = " . unpack("H*", $pub)); |
173 | 176 |
174 my $pk = Crypt::PK::X25519->new; | 177 my $shared_secret = $self->tls_shared_secret($pub); |
175 $pk->import_key_raw($pub, "public"); | |
176 my $shared_secret = $self->{sk}->shared_secret($pk); | |
177 Test::Nginx::log_core('||', "shared = " . unpack("H*", $shared_secret)); | 178 Test::Nginx::log_core('||', "shared = " . unpack("H*", $shared_secret)); |
178 | 179 |
179 # tls13_advance_key_schedule | 180 # tls13_advance_key_schedule |
180 | 181 |
181 my ($hash, $hlen) = $self->{cipher} == 0x1302 ? | 182 my ($hash, $hlen) = $self->{cipher} == 0x1302 ? |
2305 } | 2306 } |
2306 } | 2307 } |
2307 | 2308 |
2308 sub build_tls_client_hello { | 2309 sub build_tls_client_hello { |
2309 my ($self) = @_; | 2310 my ($self) = @_; |
2310 my $key_share = $self->{sk}->export_key_raw('public'); | 2311 my $named_group = $self->tls_named_group(); |
2312 my $key_share = $self->tls_public_key(); | |
2311 | 2313 |
2312 my $version = "\x03\x03"; | 2314 my $version = "\x03\x03"; |
2313 my $random = Crypt::PRNG::random_bytes(32); | 2315 my $random = Crypt::PRNG::random_bytes(32); |
2314 my $session = "\x00"; | 2316 my $session = "\x00"; |
2315 my $cipher = pack('n', length($self->{ciphers})) . $self->{ciphers}; | 2317 my $cipher = pack('n', length($self->{ciphers})) . $self->{ciphers}; |
2316 my $compr = "\x01\x00"; | 2318 my $compr = "\x01\x00"; |
2317 my $ext = build_tlsext_server_name($self->{sni}) | 2319 my $ext = build_tlsext_server_name($self->{sni}) |
2318 . build_tlsext_supported_groups(29) | 2320 . build_tlsext_supported_groups($named_group) |
2319 . build_tlsext_alpn("h3", "hq-interop") | 2321 . build_tlsext_alpn("h3", "hq-interop") |
2320 . build_tlsext_sigalgs(0x0804, 0x0805, 0x0806) | 2322 . build_tlsext_sigalgs(0x0804, 0x0805, 0x0806) |
2321 . build_tlsext_supported_versions(0x0304) | 2323 . build_tlsext_supported_versions(0x0304) |
2322 . build_tlsext_ke_modes(1) | 2324 . build_tlsext_ke_modes(1) |
2323 . build_tlsext_key_share(29, $key_share) | 2325 . build_tlsext_key_share($named_group, $key_share) |
2324 . build_tlsext_quic_tp($self->{scid}, $self->{opts}); | 2326 . build_tlsext_quic_tp($self->{scid}, $self->{opts}); |
2325 | 2327 |
2326 $ext .= build_tlsext_early_data($self->{psk}) | 2328 $ext .= build_tlsext_early_data($self->{psk}) |
2327 . build_tlsext_psk($self->{psk}) if keys %{$self->{psk}}; | 2329 . build_tlsext_psk($self->{psk}) if keys %{$self->{psk}}; |
2328 | 2330 |
2418 my $truncated = substr($ch, 0, -3 - $hlen); | 2420 my $truncated = substr($ch, 0, -3 - $hlen); |
2419 my $context = Crypt::Digest::digest_data($hash, $truncated); | 2421 my $context = Crypt::Digest::digest_data($hash, $truncated); |
2420 $truncated . binders($hash, $hlen, $key, $context); | 2422 $truncated . binders($hash, $hlen, $key, $context); |
2421 } | 2423 } |
2422 | 2424 |
2425 sub tls_generate_key { | |
2426 my ($self) = @_; | |
2427 $self->{sk} = $self->{group} eq 'x25519' | |
2428 ? Crypt::PK::X25519->new->generate_key | |
2429 : Crypt::PK::ECC->new->generate_key($self->{group}); | |
2430 } | |
2431 | |
2432 sub tls_public_key { | |
2433 my ($self) = @_; | |
2434 $self->{sk}->export_key_raw('public'); | |
2435 } | |
2436 | |
2437 sub tls_shared_secret { | |
2438 my ($self, $pub) = @_; | |
2439 my $pk = $self->{group} eq 'x25519' | |
2440 ? Crypt::PK::X25519->new : Crypt::PK::ECC->new; | |
2441 $pk->import_key_raw($pub, $self->{group} eq 'x25519' | |
2442 ? 'public' : $self->{group}); | |
2443 $self->{sk}->shared_secret($pk); | |
2444 } | |
2445 | |
2446 sub tls_named_group { | |
2447 my ($self) = @_; | |
2448 my $name = $self->{group}; | |
2449 return 0x17 if $name eq 'secp256r1'; | |
2450 return 0x18 if $name eq 'secp384r1'; | |
2451 return 0x19 if $name eq 'secp521r1'; | |
2452 return 0x1d if $name eq 'x25519'; | |
2453 } | |
2454 | |
2423 ############################################################################### | 2455 ############################################################################### |
2424 | 2456 |
2425 1; | 2457 1; |
2426 | 2458 |
2427 ############################################################################### | 2459 ############################################################################### |