changeset 1884:6f1508d53a26

Tests: fixed extracting QUIC early secret if PSK is not in use. Although, PSK binder values in the pre-shared key extension are constructed with a binder key derived from the early secret extracted with input keying material of the corresponding offered PSK, an actual early secret should be recomputed with a selected PSK. See RFC 8446, section 7.1 and 4.2.11.2. Seen with QuicTLS and disabled session tickets, which, unlike in BoringSSL, still sends session tickets but doesn't accept any pre-shared keys.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 18 Jan 2023 16:04:33 +0400
parents ff50c265a5ac
children 905b1704eb54
files lib/Test/Nginx/HTTP3.pm
diffstat 1 files changed, 20 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/lib/Test/Nginx/HTTP3.pm
+++ b/lib/Test/Nginx/HTTP3.pm
@@ -165,6 +165,11 @@ sub handshake {
 
 	# tls13_advance_key_schedule
 
+	my $psk = pre_shared_key($extens);
+	$self->{psk} = (defined $psk && $self->{psk_list}[$psk]) || undef;
+	$self->{es_prk} = Crypt::KeyDerivation::hkdf_extract(
+		$self->{psk}->{secret} || pack("x32"), pack("x32"), 'SHA256');
+
 	$self->{hs_prk} = hkdf_advance($shared_secret, $self->{es_prk});
 	Test::Nginx::log_core('||', "hs = " . unpack("H*", $self->{hs_prk}));
 
@@ -1804,6 +1809,21 @@ sub early_data {
 	}
 }
 
+sub pre_shared_key {
+	my ($extens) = @_;
+	my $offset = 0;
+	while ($offset < length($extens)) {
+		my $ext = substr($extens, $offset, 2);
+		my $len = unpack("C", substr($extens, $offset + 2, 1)) * 8 +
+			unpack("C", substr($extens, $offset + 3, 1));
+		if ($ext eq "\x00\x29") {
+			return unpack("n", substr($extens, $offset + 4, $len));
+		}
+		$offset += 4 + $len;
+	}
+	return;
+}
+
 ###############################################################################
 
 sub build_cc {