From ec18da8baac452887089a680dcb5ac0833ee6c02 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Mon, 5 May 2025 14:38:58 +0200 Subject: [PATCH] Merge remote-tracking branch 'origin/topic/awelzel/4405-quic-fragmented-crypto' * origin/topic/awelzel/4405-quic-fragmented-crypto: Bump external/zeek-testing QUIC: Extract reset_crypto() function QUIC: Rename ConnectionIDInfo to Context QUIC: Switch initial_destination_conn_id to optional QUIC: Use initial destination conn_id for decryption QUIC: Handle CRYPTO frames across multiple INITIAL packets QUIC: Do not consume EncryptedLongPacketPayload QUIC: Fix ACK frame parsing (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) --- .typos.toml | 2 + CHANGES | 50 ++++ VERSION | 2 +- src/analyzer/protocol/quic/QUIC.spicy | 274 +++++++++++------- .../quic.log | 2 +- .../conn.log.cut | 3 + .../quic.log.cut | 3 + .../ssl.log.cut | 3 + .../scripts.base.protocols.quic.events/out | 1 + .../quic.log | 2 +- .../conn.log.cut | 3 + .../quic.log.cut | 3 + .../ssl.log.cut | 3 + .../conn.log.cut | 3 + .../quic.log.cut | 3 + .../ssl.log.cut | 3 + .../quic.log | 2 +- .../quic-decrypt-fail-google-de-51833.pcap | Bin 0 -> 26858 bytes ...nitial-fragmented-crypto-only-initial.pcap | Bin 0 -> 3948 bytes ...ic-multiple-initial-fragmented-crypto.pcap | Bin 0 -> 15611 bytes .../quic/decrypt-fail-google-de-51833.zeek | 12 + ...nitial-fragmented-crypto-only-initial.zeek | 12 + .../multiple-initial-fragmented-crypto.zeek | 12 + 23 files changed, 288 insertions(+), 110 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/conn.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/quic.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/ssl.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/conn.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/quic.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/ssl.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/conn.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/quic.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/ssl.log.cut create mode 100644 testing/btest/Traces/quic/quic-decrypt-fail-google-de-51833.pcap create mode 100644 testing/btest/Traces/quic/quic-multiple-initial-fragmented-crypto-only-initial.pcap create mode 100644 testing/btest/Traces/quic/quic-multiple-initial-fragmented-crypto.pcap create mode 100644 testing/btest/scripts/base/protocols/quic/decrypt-fail-google-de-51833.zeek create mode 100644 testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto-only-initial.zeek create mode 100644 testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto.zeek diff --git a/.typos.toml b/.typos.toml index d162b1d842..79ff7aeb73 100644 --- a/.typos.toml +++ b/.typos.toml @@ -65,6 +65,8 @@ have_2nd = "have_2nd" ot1 = "ot1" ot2 = "ot2" uses_seh = "uses_seh" +ect0 = "ect0" +ect1 = "ect1" [default.extend-words] caf = "caf" diff --git a/CHANGES b/CHANGES index 2128898070..a959fb7190 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,53 @@ +7.0.6-4 | 2025-05-05 12:56:17 -0700 + + * QUIC: Extract reset_crypto() function (Arne Welzel, Corelight) + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Rename ConnectionIDInfo to Context (Arne Welzel, Corelight) + + Lets just call it what it is given that it contains more than just + connection IDs. + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Switch initial_destination_conn_id to optional (Arne Welzel, Corelight) + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Use initial destination conn_id for decryption (Arne Welzel, Corelight) + + Ensure the client side also uses the initial destination connection ID + for decryption purposes instead of the one from the current long header + packet. PCAP from local WiFi hotspot. + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Handle CRYPTO frames across multiple INITIAL packets (Arne Welzel, Corelight) + + Instead of sending the accumulated CRYPTO frames after processing an + INITIAL packet, add logic to determine the total length of the TLS + Client or Server Hello (by peeking into the first 4 byte). Once all + CRYPTO frames have arrived, flush the reassembled data to the TLS + analyzer at once. + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Do not consume EncryptedLongPacketPayload (Arne Welzel, Corelight) + + The payload is already consumed within the InitialPacket unit. Consuming + it again resulted in UDP datagrams with multiple packets to ignore + the remaining packets in the same UDP datagram. The baseline changes + showing I being followed by a new H indicates that the INITIAL packet + was followed by a HANDSHAKE packet, but previously Zeek discarded + these. + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + + * QUIC: Fix ACK frame parsing (Arne Welzel, Corelight) + + (cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda) + 7.0.6-3 | 2025-05-05 12:54:30 -0700 * broker/main: Adapt enum values to agree with comm.bif (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 226650143e..bfe3dd60f5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.6-3 +7.0.6-4 diff --git a/src/analyzer/protocol/quic/QUIC.spicy b/src/analyzer/protocol/quic/QUIC.spicy index 2fdc816f67..16cd933462 100644 --- a/src/analyzer/protocol/quic/QUIC.spicy +++ b/src/analyzer/protocol/quic/QUIC.spicy @@ -17,27 +17,104 @@ public function decrypt_crypto_payload( ): bytes &cxxname="QUIC_decrypt_crypto_payload"; -############## -## Context - tracked in one connection -############## - # Can we decrypt? -function can_decrypt(long_header: LongHeaderPacket, context: ConnectionIDInfo, is_client: bool): bool { +function can_decrypt(long_header: LongHeaderPacket, context: Context, crypto: CryptoSinkUnit&): bool { if ( ! long_header.is_initial ) return False; - if ( is_client ) - return ! context.client_initial_processed; + if ( crypto == Null ) + return False; - # This is the responder, can only decrypt if we have an initial - # destination_id from the client - return context.client_initial_processed - && |context.initial_destination_conn_id| > 0 - && ! context.server_initial_processed; + # Can only decrypt the responder if we've seen the initial destination conn id. + if ( ! crypto.is_orig && ! context.initial_destination_conn_id ) + return False; + + # Only attempt decryption if we haven't flushed some SSL data yet. + return ! crypto.finished; } -type ConnectionIDInfo = struct { +function reset_crypto(context: Context&) { + # Recreate all the crypto state on the next %init of Packet. + zeek::protocol_handle_close(context.ssl_handle); + unset context.ssl_handle; + context.client_crypto = Null; + context.server_crypto = Null; + context.client_sink = Null; + context.server_sink = Null; + context.initial_destination_conn_id = Null; +} + +# This unit is connected with the server and client sinks receiving +# CRYPTO frames and forwards data to the SSL handle in the context. +type CryptoSinkUnit = unit(is_orig: bool, context: Context&) { + var buffered: bytes; + var length: uint32 = 0; + var is_orig: bool = is_orig; + var finished: bool; + + # The first 4 bytes of crypto data contain the expected tag and a + # 24bit length from the TLS HandshakeMessage. Extract the length + # so we can determine when all CRYPTO frames have arrived. + # + # https://datatracker.ietf.org/doc/html/rfc8446#section-4 + # + # struct { + # HandshakeType msg_type; /* handshake type */ + # uint24 length; /* remaining bytes in message */ + # ... + # + : uint8 { + self.buffered += $$; + } + + len: uint8[3] { + self.length = (cast($$[0]) << 16) + (cast($$[1]) << 8) + cast($$[2]) + 4; + + self.buffered += $$[0]; + self.buffered += $$[1]; + self.buffered += $$[2]; + } + + : void &requires=(self.length <= 2**14 + 256) { # The length MUST NOT exceed 2^14 + 256 bytes (RFC 8446) + + # The client or server hello data is forwarded to the SSL analyzer as a + # TLSPlaintext record with legacy_record_version set to \x03\x03 (1.3). + # + # enum { + # invalid(0), + # change_cipher_spec(20), + # alert(21), + # handshake(22), + # application_data(23), + # (255) + # } ContentType; + # + # struct { + # ContentType type; + # ProtocolVersion legacy_record_version; + # uint16 length; + # opaque fragment[TLSPlaintext.length]; + # } TLSPlaintext; + # + # https://datatracker.ietf.org/doc/html/rfc8446#section-5.1 + local length_bytes = pack(cast(self.length), spicy::ByteOrder::Big); + zeek::protocol_data_in(is_orig, b"\x16\x03\x03" + length_bytes + self.buffered, context.ssl_handle); + } + + : bytes &chunked &size=(self.length - 4) { + zeek::protocol_data_in(is_orig, $$, context.ssl_handle); + } + + : void { + self.finished = True; + } +}; + +############## +## Context +############## +type Context = struct { client_cid_len: uint8; server_cid_len: uint8; @@ -46,26 +123,13 @@ type ConnectionIDInfo = struct { # will make life miserable. # # https://quicwg.org/base-drafts/rfc9001.html#appendix-A - initial_destination_conn_id: bytes; + initial_destination_conn_id: optional; - # Currently, this analyzer assumes that ClientHello - # and ServerHello fit into the first INITIAL packet (and - # that there is only one that we're interested in. - # - # But minimally the following section sounds like this might not - # hold in general and the Wireshark has samples showing - # the handshake spanning across more than two INITIAL packets. - # (quic-fragmented-handshakes.pcapng.gz) - # - # https://datatracker.ietf.org/doc/html/rfc9001#section-4.3 - # - # Possible fix is to buffer up all CRYPTO frames across multiple - # INITIAL packets until we see a non-INITIAL frame. - # - # We also rely heavily on getting originator and responder right. - # - client_initial_processed: bool; - server_initial_processed: bool; + # Track crypto state. + client_crypto: CryptoSinkUnit&; + client_sink: sink&; + server_crypto: CryptoSinkUnit&; + server_sink: sink&; ssl_handle: zeek::ProtocolHandle &optional; }; @@ -272,16 +336,28 @@ public type LongHeaderPacket = unit { }; # A QUIC Frame. -public type Frame = unit(header: LongHeaderPacket, from_client: bool, crypto_sink: sink&) { +public type Frame = unit(header: LongHeaderPacket, from_client: bool, crypto: CryptoSinkUnit, crypto_sink: sink&) { frame_type : uint8 &convert=cast($$); # TODO: add other FrameTypes as well switch ( self.frame_type ) { - FrameType::ACK1 -> a: ACKPayload; - FrameType::ACK2 -> b: ACKPayload; + FrameType::ACK1 -> a: ACKPayload(FrameType::ACK1); + FrameType::ACK2 -> b: ACKPayload(FrameType::ACK2); FrameType::CRYPTO -> c: CRYPTOPayload(from_client) { # Have the sink re-assemble potentially out-of-order cryptodata crypto_sink.write(self.c.cryptodata, self.c.offset.result_); + + # If the crypto unit has determined a valid length, ensure we + # don't attempt to write more bytes into the sink. If it doesn't, + # use 2000 bytes as an arbitrary limit required to observe the + # length of the contained Client Hello or Server Hello. + if ( crypto.length > 0 ) { + if ( |crypto_sink| > crypto.length ) + throw "too much crypto data received %s > %s" % ( |crypto_sink|, crypto.length); + } else { + if ( |crypto_sink| > 2000 ) + throw "too much crypto data without length received %s" % |crypto_sink|; + } } FrameType::CONNECTION_CLOSE1 -> : ConnectionClosePayload(header); FrameType::PADDING -> : skip /\x00*/; # eat the padding @@ -298,11 +374,26 @@ type CRYPTOPayload = unit(from_client: bool) { cryptodata: bytes &size=self.length.result_; }; -type ACKPayload = unit { +# https://datatracker.ietf.org/doc/html/rfc9000#ack-ranges +type ACKRange = unit { + gap: VariableLengthInteger; + ack_range_length: VariableLengthInteger; +}; + +type ACKECNCounts = unit { + ect0: VariableLengthInteger; + ect1: VariableLengthInteger; + ecn_ce: VariableLengthInteger; +}; + +# https://datatracker.ietf.org/doc/html/rfc9000#name-ack-frames +type ACKPayload = unit(frame_type: FrameType) { latest_ack: VariableLengthInteger; ack_delay: VariableLengthInteger; ack_range_count: VariableLengthInteger; first_ack_range: VariableLengthInteger; + ack_ranges: ACKRange[self.ack_range_count.result_]; + ecn_counts: ACKECNCounts if(frame_type == FrameType::ACK2); }; type ConnectionClosePayload = unit(header: LongHeaderPacket) { @@ -393,35 +484,18 @@ public type ShortPacketPayload = unit { payload: skip bytes &eod; }; -# TODO: investigate whether we can do something useful with this -public type EncryptedLongPacketPayload = unit { - payload: skip bytes &eod; -}; - -# Buffer all crypto messages (which might be fragmented and unordered) -# into the following unit. -type CryptoBuffer = unit() { - - var buffered: bytes; - - : bytes &chunked &eod { - self.buffered += $$; - # print "crypto_buffer got data", |$$|, |self.buffered|; - } -}; - ############## # QUIC packet parsing # # A UDP datagram contains one or more QUIC packets. ############## -type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { +type Packet = unit(from_client: bool, context: Context&) { var decrypted_data: bytes; var packet_size: uint64 = 0; var start: iterator; - sink crypto_sink; - var crypto_buffer: CryptoBuffer&; + var crypto: CryptoSinkUnit&; + var crypto_sink: sink&; # Attach an SSL analyzer to this connection once. on %init { @@ -430,6 +504,26 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { } self.start = self.input(); + + # Initialize crypto state in context for both sides if not already done. + if ( context.client_crypto == Null ) { + assert ! context.server_crypto; + context.client_crypto = new CryptoSinkUnit(True, context); + context.client_sink = new sink; + context.client_sink.connect(context.client_crypto); + + context.server_crypto = new CryptoSinkUnit(False, context); + context.server_sink = new sink; + context.server_sink.connect(context.server_crypto); + } + + if ( from_client ) { + self.crypto = context.client_crypto; + self.crypto_sink = context.client_sink; + } else { + self.crypto = context.server_crypto; + self.crypto_sink = context.server_sink; + } } # Peek into the first byte and determine the header type. @@ -443,7 +537,6 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { self.set_input(self.start); # rewind } - # Depending on the header, parse it and update the src/dest ConnectionID's switch ( self.first_byte.header_form ) { HeaderForm::SHORT -> short_header: ShortHeader(context.client_cid_len); @@ -453,19 +546,16 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { # If we see a retry packet from the responder, reset the decryption # context such that the next DCID from the client is used for decryption. if ( self.long_header.is_retry ) { - context.client_initial_processed = False; - context.server_initial_processed = False; - context.initial_destination_conn_id = b""; + reset_crypto(context); - # Allow re-opening the SSL analyzer the next time around. - zeek::protocol_handle_close(context.ssl_handle); - unset context.ssl_handle; + self.crypto = Null; + self.crypto_sink = Null; } } }; : void { - if (self?.long_header && can_decrypt(self.long_header, context, from_client)) + if ( self?.long_header && can_decrypt(self.long_header, context, self.crypto ) ) # If we have parsed an initial packet that we can decrypt the payload, # determine the size to store into a buffer. self.packet_size = self.offset(); @@ -473,30 +563,29 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { # Buffer the whole packet if we determined we have a chance to decrypt. packet_data: bytes &parse-at=self.start &size=self.packet_size if ( self.packet_size > 0 ) { - self.crypto_buffer = new CryptoBuffer(); - self.crypto_sink.connect(self.crypto_buffer); if ( from_client ) { context.server_cid_len = self.long_header.dest_conn_id_len; context.client_cid_len = self.long_header.src_conn_id_len; + # This is the first INITIAL packet we attempt to decrypt and it is + # coming from the client. Use its destination connection ID for + # decryption purposes. + if ( ! context.initial_destination_conn_id ) { + context.initial_destination_conn_id = self.long_header.dest_conn_id; + } + # This means that here, we can try to decrypt the initial packet! # All data is accessible via the `long_header` unit self.decrypted_data = decrypt_crypto_payload( self.long_header.version, self.packet_data, - self.long_header.dest_conn_id, + *context.initial_destination_conn_id, self.long_header.encrypted_offset, self.long_header.payload_length, from_client ); - # Assuming that the client set up the connection, this can be considered the first - # received Initial from the client. So disable change of ConnectionID's afterwards - if ( |context.initial_destination_conn_id| == 0 ) { - context.initial_destination_conn_id = self.long_header.dest_conn_id; - } - } else { context.server_cid_len = self.long_header.src_conn_id_len; context.client_cid_len = self.long_header.dest_conn_id_len; @@ -504,7 +593,7 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { self.decrypted_data = decrypt_crypto_payload( self.long_header.version, self.packet_data, - context.initial_destination_conn_id, + *context.initial_destination_conn_id, self.long_header.encrypted_offset, self.long_header.payload_length, from_client @@ -521,51 +610,24 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) { spicy::accept_input(); } - # Depending on the type of header and whether we were able to decrypt - # some of it, parse the remaining payload. + # If this packet has a SHORT header, consume until &eod, there's nothing + # we can do with it anyhow. : ShortPacketPayload if (self.first_byte.header_form == HeaderForm::SHORT); - : EncryptedLongPacketPayload if (self.first_byte.header_form == HeaderForm::LONG && |self.decrypted_data| == 0); # If this was packet with a long header and decrypted data exists, attempt # to parse the plain QUIC frames from it. - frames: Frame(self.long_header, from_client, self.crypto_sink)[] &parse-from=self.decrypted_data if (self.first_byte.header_form == HeaderForm::LONG && |self.decrypted_data| > 0); - - # Once the Packet is fully parsed, pass the accumulated CRYPTO frames - # to the SSL analyzer as handshake data. - on %done { - # print "packet done", zeek::is_orig(), self.first_byte.header_form, |self.decrypted_data|; - - if ( self.crypto_buffer != Null && |self.crypto_buffer.buffered| > 0 ) { - local handshake_data = self.crypto_buffer.buffered; - - # The data is passed to the SSL analyzer as part of a HANDSHAKE (0x16) message with TLS1.3 (\x03\x03). - # The 2 length bytes are also passed, followed by the actual CRYPTO blob which contains a CLIENT HELLO or SERVER HELLO - local length_bytes = pack(cast(|handshake_data|), spicy::ByteOrder::Big); - zeek::protocol_data_in( - from_client - , b"\x16\x03\x03" + length_bytes + handshake_data - , context.ssl_handle - ); - - # Stop decryption attempts after processing the very first INITIAL - # INITIAL packet for which we forwarded data to the SSL analyzer. - if ( from_client ) - context.client_initial_processed = True; - else - context.server_initial_processed = True; - } - } + frames: Frame(self.long_header, from_client, self.crypto, self.crypto_sink)[] &parse-from=self.decrypted_data if (self.first_byte.header_form == HeaderForm::LONG && |self.decrypted_data| > 0); }; ############## # Entrypoints ############## public type RequestFrame = unit { - %context = ConnectionIDInfo; + %context = Context; : Packet(True, self.context())[]; }; public type ResponseFrame = unit { - %context = ConnectionIDInfo; + %context = Context; : Packet(False, self.context())[]; }; diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log index 29f634519b..9a2bc00efd 100644 --- a/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log +++ b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log @@ -7,5 +7,5 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version client_initial_dcid client_scid server_scid server_name client_protocol history #types time string addr port addr port string string string string string string string -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.17.0.2 34347 64.233.166.94 443 1 815d62c70884f4b51e8ccadd5beed372 e5ec6b26584229be98a164349ae910351c40d10b c15d62c70884f4b5 www.google.de h3 ISishIhHhhH +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.17.0.2 34347 64.233.166.94 443 1 815d62c70884f4b51e8ccadd5beed372 e5ec6b26584229be98a164349ae910351c40d10b c15d62c70884f4b5 www.google.de h3 ISishIHhHhhH #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/conn.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 Dd quic,ssl diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/quic.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/quic.log.cut new file mode 100644 index 0000000000..6199e7117b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/quic.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid server_name history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 www.google.de ZZZIiIIIISiIIIiiiiiishIIHH diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/ssl.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/ssl.log.cut new file mode 100644 index 0000000000..e72550284a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-fail-google-de-51833/ssl.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 TLSv13 TLS_AES_128_GCM_SHA256 X25519MLKEM768 www.google.de T - - F Cs diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.events/out b/testing/btest/Baseline/scripts.base.protocols.quic.events/out index e377ed39d4..6178826346 100644 --- a/testing/btest/Baseline/scripts.base.protocols.quic.events/out +++ b/testing/btest/Baseline/scripts.base.protocols.quic.events/out @@ -47,3 +47,4 @@ zerortt.pcap 1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, 1.0, initial_packet, CtPZjS20MLrsMUOJi2, T, 1, 3ec82f67, 1.0, handshake_packet, T, CtPZjS20MLrsMUOJi2, 1, 3ec82f67, +1.0, handshake_packet, T, CtPZjS20MLrsMUOJi2, 1, 3ec82f67, diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/quic.log index f2f8098294..b09e3ac209 100644 --- a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/quic.log +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/quic.log @@ -7,6 +7,6 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version client_initial_dcid client_scid server_scid server_name client_protocol history #types time string addr port addr port string string string string string string string -1.000000 CtPZjS20MLrsMUOJi2 193.167.0.100 49394 193.167.100.100 443 1 15ae5e5e4962163f410b5529fc125bbc (empty) e483a751 server4:443 hq-interop ISZishZZZZZZZZZZZZZZZZZZZZZZZZZZZIH +1.000000 CtPZjS20MLrsMUOJi2 193.167.0.100 49394 193.167.100.100 443 1 15ae5e5e4962163f410b5529fc125bbc (empty) e483a751 server4:443 hq-interop ISZishZZZZZZZZZZZZZZZZZZZZZZZZZZZIHH 1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 60492 193.167.100.100 443 1 b7c7841c64883e3261d840 (empty) 8d2041ac server4:443 hq-interop ISishhIH #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/conn.log.cut new file mode 100644 index 0000000000..06445c01a5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/conn.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 D quic,ssl diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/quic.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/quic.log.cut new file mode 100644 index 0000000000..13f1e1fa45 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/quic.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid server_name history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 googleads.g.doubleclick.net IIIS diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/ssl.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/ssl.log.cut new file mode 100644 index 0000000000..1929143aa1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto-only-initial/ssl.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 - - - googleads.g.doubleclick.net F - - F C diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/conn.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 Dd quic,ssl diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/quic.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/quic.log.cut new file mode 100644 index 0000000000..b8cd8237eb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/quic.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid server_name history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 googleads.g.doubleclick.net IIISZZZiIiIIIIIIZ diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/ssl.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/ssl.log.cut new file mode 100644 index 0000000000..1929143aa1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.multiple-initial-fragmented-crypto/ssl.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 - - - googleads.g.doubleclick.net F - - F C diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.quicv2-echo-443/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.quicv2-echo-443/quic.log index a460e7fec8..1d3ecea7b2 100644 --- a/testing/btest/Baseline/scripts.base.protocols.quic.quicv2-echo-443/quic.log +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quicv2-echo-443/quic.log @@ -7,5 +7,5 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version client_initial_dcid client_scid server_scid server_name client_protocol history #types time string addr port addr port string string string string string string string -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 49320 127.0.0.1 443 quicv2 fa603212c8688817af3d3238735bc7 (empty) b168b5cc localhost quic-echo-example ISIIishIH +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 49320 127.0.0.1 443 quicv2 fa603212c8688817af3d3238735bc7 (empty) b168b5cc localhost quic-echo-example ISIIishIHH #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/quic/quic-decrypt-fail-google-de-51833.pcap b/testing/btest/Traces/quic/quic-decrypt-fail-google-de-51833.pcap new file mode 100644 index 0000000000000000000000000000000000000000..cc7d2fec1a6e0543e3d9b8f8268e7225062e4e24 GIT binary patch literal 26858 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/quic/quic-multiple-initial-fragmented-crypto-only-initial.pcap b/testing/btest/Traces/quic/quic-multiple-initial-fragmented-crypto-only-initial.pcap new file mode 100644 index 0000000000000000000000000000000000000000..aecc0c7eb96a38c4615a1e77d60a85eaf5c04199 GIT binary patch literal 3948 zcmcK6*E<}Hwgzx5YLtxLdyJkaQAckvx)C+HVDwI8q8puHp>FxnUqMvN{*?=|@J zXdw(ad!KW0{(-&M^Sl@Dx>%RLXH9=Yej>ml!u$Ur!o&YpX_KXPTO59f_wWJU|0ZEa z1s%!w_O*5h>23UqJq7a#(d;7?A#zPP*Ar4k7mr(WWB!qJAv`)G6?{^G|GUOT&>V)} zNi=J>-1n~qKB=9TcxBZzi5i}Y7T!i**PICZ3`!!IJ%sx%vm0!HPtYj?1C3rvcMcFR zkJX$(FCR4V2#7PA@)#=+InQ` zhIjEWyjFbNHAL31R%TA(%g@9l zq?vG+lg+pNl$WJ%BAc69F$JTc=#Qi<>qYp(ZQ>*K*qEuh)HceS-l#rv zwvY67>>?3N%g@ziF)@2Txi}dzONG(7KaR-N@zY_^8WU)VeJAo#`_-PyQ|Z6JqU!nm z^+~4(7VRZ<2bFO`Um*IS)FgkskB{DuY=s?o=!R_T7){8<1~D-nz|j#jiNF5;)N2Nc5s{S?k_*~i0S!3hAab`3ViO#ufzij$p=W|RPVq# z_y0g%)xt7Xe-aZ#gLz*SMo;Vcv-W^ULjt^NNG6E*djzc^(xfMqvy1@5ko%xBQ?YDV zf-Tvk@JAH1VpQ*O6xLJFK>x=&d!SJRqfkFXs(Q2k#$$7J!N2I7)uhne%{hNTjcxs* zsNw*DQ^Lml9(M`Oi^VUMp`P&g7j0p03{Hr9yr zT*^DNX>+{`LS1i)L&?eUHt&Gp*fKz=7JvuZo5fg9uI&@GgrLxoyAE@2&hg8o#iLeh z2S<=lBSDQIX5=kZLzAC?+^;+cXBL4N2S)0o-*R~-;f(V zcgAp zW|jb9dhDiVwhe;sby_y$nXH|&H2vD9zLzcCDWd^$q<)xm7SgNOi29f$GC!?Qp;zsi zn24y2giU#QrFOiMYo@8Mkp*^e>7F<}?yqCxPZyS@w|1&n4N)7$DY>d}T znEIJ8#!VB{hy4QAr=stwrOct6K@ZCc1ImYBN%3W2M_sEEF7X*7(RsUv==5H1_oSYD z^Izza1RK|b?ov{Zbv}G$yV`ktwGf=ybDdrUh{et|N;?IdAh$3FBFmA&Y3ooebR4?{ zJXmCT+&yfYo{DQjAd~fLgz08IED~m^?lK0o5-34uzTvx$TFSlI8{sug&4dLSHpDQO ztx@&TW>S4vpRAqERHgp|h$paNhI>f6Vm#$0Y>&U^Ldh5D1kE#pNgk9QD zZ?@7O;mcpy&I69ubMYhT#xTT{_Pn*+Gd{Z!yl&MM_8GRsnz0VkHZow<>&6@#;-|sZ zuWF4jjePvOyI3new^)(aWNQ6#nO5v_v_A75W=X$@0Z}%i9e5kAg}Uz@mY0dMw%x;s z;`9SHFA;^IlHLY;R|PaPsEm(_EDKG9sQ%|$Ki&`B_ZFGE?Je_eDUW&pdjcu@d#N*4 zpLKQ$YdGwBw|(#%=Wd6)iAj}H*`%8U(Qzqb4d7l#=H&M%TrSu-Mig)@xWV+~3h)fn*GoTL>RJU}Az5*#ATJU67QmQ%+FGI(jYVfX^wD*ZgHYof@9s7S`3m)Q zM(tE=bjY&{=o3{=KiWk4KjnPa<|3C%;P*2!LMiBu*jm2 ze;1*GAkfU@tW7Y0dvNBxj5<-dk5R^5Yv6|cjW25|9x*Vlpz_#V~BG z_OHv87=NvZWo(;Lnk;((*gRJDTuUHd=5m84dq|sfrTX&I`J_YX_JrP^LSo5z2KGW~ ztP0L@yaPT5=5No_4uay%t#i~15|AQ5tgi+DM?h;eJ&zXDm6CGvTrO+@}1_u z(b%oaYW$QxSIW`OA9!ddn8tZm8a4%~Tz~ZvI(#qDaw}V_#P;hTIvXU^C%G=EA{siT z#>gKa*lXBs3W&qfv}lSC3b+K8r@XJ2^?BbE6<8(K+^qf37TYO_=Mfh6z=2L3B%HTu z>W*KfNX5C`>eITG$yq*3I_=hAq>ZEbgVZJf z&(Yv;qUY(Iv%$pDE-J%*po_U?30s7FzNc7jf{jXh8|#=WeCy*o?7wXskfr>O{EZlz z|C)`jkD(>f)#q^9MNc8N{HF%6I_8~l@V*>w)@^*qmCMV}=LO+gPK9hrgfk_q{}Lw) zA@^7`-U0B-$DW#OCc*gkf}Aoe!A)mx%G)k}sv6Zo3Jr=8gztYy+|<8yyJ*7aB-1V+ zo&N&xa=I!Z@9D<^*jWiM(FXKh@A7`UxZ7xe=gcn=2n{6tmID{bJQ-Ng9*Pn}YY2!Y z2iLhRlk4#?$2!ei5Hyf-!?BDE?}n0p96S1CD^d^N_?Qq0iB!Ph{J}Av8(>~ zhbSHHCPAG)X|#0Zd%X*;PA9oEjUWD$ z*x3&oUln7o{TuQ3L-Kv?U&%=Ede>WlWW~LR8-fl-HfVTe>hh*_1I~x;<2}udT%f2@ z>CU2f?ZdYY17qdK#e<6WWSGnMGk2nwocs>?5ein_I7`dpL533AVB-dB0Tm3%;2wj_ z05-9~4roa~HEDIT`l2y7G5)X{X?vd`4}=+t?jWOg;? z_~k;dK>L^%nDbi)A&?kmQe3Ziq5pn-sEaw(N<=oa3_^0toOM>G2)b}m#(^jUp z(4SS#?E4CL47&?WQWsgzI|yK~p~YgfYYgWz@))sj1*{`VVLk6?f7r`*Fq~HeSYC~Y z)gC)6*$OWMN-DHWNL&P9GTC%>!aT5fjiJu((zpg2Al}?BJE?3W4+9*mn37bkJwH#V ztw;=T?7r*{)b4`5Ce>9c%b1248B{-2a6o^`1Bol_0BcV;dDE>G0C21QMB+-!XT}Fn zm8_|G>Vi0#vuPCF*JDOY`p&WCoZS~77gF10 zL#o;-2h2`ht5FVVzNRlW)hV{ft3%nI;~+c*pgX0< zc`b>o`lji#_spBEz75omxBUuNbwCb0A5HH?l(_*boury`ia^Fv%cF)1F4oj!GqKjK zn0_Xn(Ia(x%VWFI5Ngvv(?2p@zQKlG1ybiM>g32S>IF4x{67k}c~HtZD^a><=WZv0 zRD;n8`AVCOk9I|-Y!iTuRVJkU?y1VoY%X2x0MzIX*a@<%w>kKC0T4pZny$2L z5nK>}Uld?(uzQ6Xcd3mr64#aRE1_3P77(bD&6{WPiKTM{2y?3XKHMb%HV3)dFgmfI zf8F(%4ZYBtOmjvi(yj!B20J~Ci&M*7*tv+BTWs~jT@=7&3&9tf8L5jbe*GSY-~sv` z%XQB?eEosP?uHy=j~0k<>)klT&NKk1uvbd>GGh$atzU50uX)cV?|vXRRINcq?o0KH zFc(_6vrprT469jg9lPGHoXGF$+GABTB=}XCU9OUCg|X`}JfcB`s@q8W&v}$ip_gA{ zeRF@-q+3T$^Q8QP&a|i0)?K%-dpRoX3iY2ffk0FuDuR&j#L`>m@~eb42j=`I?x^hL zqa7UGnl=f%&r=Y?qs1^~T{sG{D%~ip$QOEoMSM63x@Yc$)5fYo_2XzHg>Je=$#Lfo z8HKLP42Eia{SfW$Enu6k~b;N$3nJ}>Ykmr`Kp6|{ZfvUF_R9%z?Q+6rK zxWR+}*j!&FO&qviSW3DciObJ&1UX}%Uxaq}B0yox2J1>)4FxiJk@3j`y_nG5Enh&7 z{~CriHcP!8H@uf3laLI(NtMGI5#b^+kNi#Nlnpfk5iIZ}CH{S?{JYXSZu<}nBtVMz zcXq&{v;%e@4}`0ubp`k=2x%XMmNE;(P3bZ^QsS8Ts4+$!yL*@}?RMC@A@ri(Vd_&Sg{Anf~Nu^?W8e5(T^AnirnD1Wz#^!xhnh3#{4Dzxm8 z?Ae1){s?=|s96*qa#j;P?Rxt1BH2<^lS*VxB0C*!c3+e!%N~n1m#H$InST!(m6*r=Q)~JTVmI8%W*rtf+4U&JxxJ^ENq{6e?_lkntX5 z*ArhTbpTbiBClB@9209_a&c?uALzG#ri*D1=wU0fQ%)tMzhQB-6X17OIW;;C$1!1vOV!7HY+dDkJAMc2{KsJW|IT`AvRM?!jX zGNegj7DVjEB^ zAs8N{h=Q4uM4_W9cmhke`m$PBYwi0BVTc?Ot@I$#R*yV9&Ky#aMk<^bt!mtq$wPbh zngV{le2m#oY|^wVm(AIl8np>&iZf;>ToggQGsFV%HP?W$ZiV>d2oGut{xz<0At=C= z_0fV}0N)-t9QCc3|QUY;RbWBa*W;ZE=Pev zPe~AZ%L4Cwkt)*uHJ{Z^7}O?#S!kpsi(+@Q9Vv=!tOd#$rO%ym5ERkKnQMh+)_s~a zP%Z&cF)wu(wK1wR$>N|2_(TY^S(7{tV zVAR_SUx0Bk5%Mg?4DnXYJ_VfV?EtXBbb+W@(N5{muy|r;4WrOJ!4sTsP5Z(W6lfxD z1)%n# z!Db&a$fiXc8ZZ%ey~60o!3b}OXB&tPi7{=vuO~4C6MD2J_|KBXop1>jwV+-gxQ4p; z4Q+lVtfeLXRYAY}9v3-%`7 zBw{<4UBFmO_{Z&e9#&1-HH+?lR?(I3iH@g>YU?q*=%Oal)zffRu$L>pDPtM(HPcy`00~f8Om~9 z;TVaOGw4onKf;^z%-JYTL#qDXtGMOyP(Z#?Ia@X_5jbg%@x9u|?6DpYA5ts}Vzmp& z+UTVKs&9A*2^SlvKR_1MIzD4g^=q#tG;MVQh;k(2nL{dq)V0A zCX_T0W{}a+BTx+lVdxM#TKrh#+_j-?DmVQ2yR9M!6`jg#gLz^00Amd!;U9e-LFv8o z$4T8{0s*wh9ku6Fq?21tV?tJ1W1`28TxPD?rWPC^4?60noxwUmUWazl?J}j2$GRgD zI3io&RCS;8>amky=WnR*2&cAUHPh0_QTQrI;^ACzlM{tpQH0#234=X01yh-6m^N|3 zdJ6Hk7-W>(VP2PHJ`R9Io}BH98NU6g~#i3 zl`uXABU8oKd86F=ko`|dOJ6ik_@oAzzFeBUpBft1qi6-lE($eTzxeyXN6*mMMux&` z^vE?(7v?qJ5A4`ykJ@z=DvmAv+_92T;$o1_86*ii>O(gKa)Y!;n$9r>5bumf3YND6uXWa3 zezi_nOX2@%2POyeR?MsBew0a?8S6$(B`RuH;(yRpB7duU5oLs)UYI_xxogJou{bO< z#y#iyLOWTjXMRkPXb1B49$U}rFb%|Kg$ktg`%av6nD2A%BXWQj*lT2tx>ii)aiuNX1a7V(8P$~f3>Qe72IMR z!8_6EbrS2g@PLryEs9(8mX|GO;4y}Cp)sw-WKOEAj(ntrsg9=+UkT5S>Yx}FVwiIc_hG&j#Qy-J_sDf zAey`q($~1wn{$Y=|v(93Ez!HLL=!Rbt)B=3t`pB?=UD2dLVSO;Wp@16= z2+QQ%uk$l@h_I+&Bqr__@g~;CO+~xZD=P26sn>79{d021f4tlq=)h6Z+0WS|Vij|Y z061;jG-Gt7i(nfCoL>GCGOLVesEmXF5oi6yQ-_eEXsSO;X+hdhqAVJkHQ;P`_zxSy zIbZ>z|8{);=zn@@0JZ;}rv^~79AE!$eIxI{01bJ4Ips_<0zaui>$RpFp&-gnxhUFE zMQYMvY{w@nzaN!jOl~_&QTv`}DQzm0kWe*xD9CszM=R$W%|FGp>cav+{5Aal=zkUm zGXK9T4rG3uYT^GbPPn~qWux__+QFJY%YwGNZU|ll%0t+J36jS=!+-Ka0!n0}O^%W2 zll0Mu<=r|c@E~brXEnk1q!8CFSkj@ur24*gkX<=OZ?#9osF@Nf7~aYma6nkXwr;yi zz4;?NGC7{$G_*|H2-}1)FD&^7QS}+?luPUsEiWM(&;DxR<+J(;D{m9`9M!I$Z9v~| zZu}jwj7J(=$tngAz3S-M`od&C(?a(?aZ_Ejs3Nz%@Z{B9sIJ zwVK>provu0POPtZ$y-Hrmq=SI77dHm?6iV4F~sA!uz86W#&{Q%zMdQZ5+hw?8lqy3 z4vGS))P+9564UTBIr&Fosi~-Dn*L5O%9J`ud^oraXtx{)EjSwjCKx}Y3N?J|<|o$! zc=H$24wmjN51y2xWlVjL9qmH&?_QMWIj1qb6+Z zCjnzZs$4m%gu&F1Eh#JyobQNPi=UwASZ5CsY&(NFVP+SOzHJ!?f~P&p(R)e9y_^1~ zS+fBr*)X;@7PN8i14eh{DdX|~{ku`3_nEb+wYHM+ebxo^!^5q7b)U*ZN8I6^sg z9l1Kbl+!U!e0o068_0@wgwf73%*C8z$uZm3rOggN!ywFIN{d!-LzjotEUja?RvOnB zv5OC5Zr3C({@b12$|HhKN}dsgYXQzhMI1*kZC-vlw1z9DdE{_xD#-$C?^0r8EPLl+ z;gz1oiRBt$Db0i4d<}8-D&friZ|an!e?Yy~*uj*_*3&#Ob<%?aP~NOC9a2nUTDE7E z!Sx~~a!idGE@DgM^C3Jg0tygO4M0CW-h7GQD2E#=9E0L;lasxviSE>WM6?1a#O zXSwXJ-kF--;S44FFbER3*nfSl7I^I_yJ^9vl)nwJ*jXa@Xb=f}#&fyz0cj;$m9l<% z^M_&%H9__EEIRRJ%_;Gutj&R(+>XF}P}{WX(EW0hZ?shZLoWIwPgMqe1K#vvp>$3e zqELA?3Tr;hylMT$6VQ{}CTxt#ECepcKJ0zGhKUZ0^^gWlDC#-+5trYA+^@QLgp!O@ zu_$hAI8@#`oqiYHa)}-rmV9R;CFfQWFUKZVUN7_J***3}vd;&Lwvfwv2%`2u6TRRI zQ)0r4Aq=S&YXW~8_V}a;v$IkIE3(7gQxlq^wP)PcxFIJrv?Y=(X{ssnF<=&mlmPI~ z^h$G+g=-PoU|r=~LLY8%AzsLZHv&C73j00XYjRFE>2+CRZhwpIT0oO6lB@JKg>N%Np8m=;B-`d# z5Y0IPf8LucOtWKBu6w-v^i&Qb=zdfJ0zuGF>K`ti8NmWz00aC>|C5VA`~N#G0__i7 z&;Q?C6dap_0ZM^Ati@S@Gc@qF{tDBN2;D2(RYNiyARZgEJMmx=)`V2)S`3(Adf0~f zmH+%ELJ4h$((#*N|7oO;@l7< zMH)tDisoJKpP(KpOTXORrahcwo?cC`!l_i>vMGuot*x4P9#Q`(jy%p&?n5R}_Oa{w z5FmJ?{&(VuvQA@>oc%@Htv#G0uNO4Yof8$aFeHu+&-XREh!7u0DXA?mdc7LXE8Yp$ zSYlZ&33wa!Cu7*_72%ptVAf^bre0{5d-$5M#vxlChR>apjFm)V2VC5}4YW;4*kWw*L9IR?Zazeb9E!Z}yLBX@lZdRNzGR;A zOkgI4;9W`!#hoT^&p+*>@w1b$P#3AK+3*yGa&M1A^h`|($hAIh^5o;{3==UJNCvzy z#TJHgp4GhbI+tO5!a`5vecd2xr;tLRe&NzfDq2wwN-=7#8AcW>dp*oznW5A_>88A> zdo3m0DoY!T#gC;edN_ftTAwUZmRMoEeokjS=&w|AX9<$F;Lf$%GJ$b&?B<`_kiHP2MB72rb|F_spik0!dMFRdGoBrEkibFlB>J2jR?OZcYIEt@& zU09NEA$N=4Gv_2b-QGiD>lVgC$v`h3mk_!J^>9uL+K{0jFJ3}yr{%wk*Eoh@4iQ?x zu_U%RkIt00ezjpjY`_vPDk(G|;vvZw8#BYzu8;$_UyOhE1RWN+N#C$vzU7GT=ndVp zV_Pc*;9LiP*>nBc_A1LS1*V6h|5D%$X#i%Ys?L~3x7)pvx33CbXhSk>o z?jRjgqG|czG}RSP%Fy5^Ro(_$>&hN&6m>LGTbMo7*uObvBDHJB{D8{EMi7i{hNpbK z97AT3Y;}7~6NdSqdVBN1WKG!shtrHpnD`DJJkMY4N}`O!1R;A7 z^0a*x*WjM9HqH@i2u7>sHIn{4HJ@pqe)hPF0ZKdOPg05dz?AFG=b^C>MS=q{G1xth zC3{7Rg`O^!cfBCo#*Z(t#vD8@C3IYu4&K8f{u*`ha)uO*@-TBF)dn1v;gQHmagGf$ zj&JSW4&7dM=-?UIq3kiLM5)|uXS!#XC$uY~JwGL!PMu-F^}e(WN{V?SfeE}!xei~3 zg^jKbmORP}iWjcAk@&!I4Wl%An0vIn$jUi3pR+;_xfq{}eF4_Sn<7g(T{9>xBwMuV_kv5V`XzUy`p!;23J#3_UT-5^FaN z9hv!R`F+UPqUSx~aoIK-105Yl>eQ5;kb&sNHF5It(uaISee1m1oo2dZ`o-;Ln7QzT zIQG@lt3EC%c3f26=MAjuR68W!>9nMXDMry)UE14d`yzdeY?dI^!n8~WcsGeo{YSUL zgmFLZW|cy3?QxWmFBd>5yezxnE+>9G3i&m4#~V-2|4E~Nuq(g@nNOH*H6%JgZA`x` zb3S5nbuMcpkP~r*H_{mJ(Dl=;!PEcHVj)5fJ0)^4m=IU5W49f6DDZ*VzkH5No(9pW z*?xO;0YnM-MDr|v!(npt?1T{HIIwdmxCRG8mDl#-GVOL*VzBON6?nd948lZ<^hw2R zyB70$GL3)!DI*|$c3Ymc+kl(7+Et6zj`)@hrW#?g*4$*jRm?9BUZwSqlbZ-t9-?f8g&ev;x!J|(Uex}UpB5s0s{QQ-hcG}LuAJP zC6O5qQ-}Xy!R%=P%)6harg0sTZ|@zyVkpSY^kStAF;juLb~9LPhysLodPrCy`r!lneTkBBK!f-(LsR4*X1~FA#s0K^M9iD6P$qGR38L>wBMWjez+io`!JSwL5 z{=Psfx_N0s!sQYThJ}oGFY-Hf&_!6&*r*>61TwFuPWeFgz%k@Jk1+|~cnWW~p^vf$ zo!<$s2FKY^R~e&AKeFjdmlh_vlOj{ulpB%<=Y)GFI-5X$`z!PJvr)?4*$q4!%}b$9 z*Zl_R6g*SEBf-2issgNYnSFN}c^Tq~xFSByE>_V)FRtgQvL_CNj~A*2bTfj(HR7}M zVj!GrGiA)qs0DwFg6o2ZBpg(FyWP52)iHv4CSY*7rfiv@=C7yYNj06taAYh*mndI;Mt^tFhg zK#bV$Y8W?Bx%>l72Z9d5+~1Y+Gxs`R4t-;D{pr_BcGe%v0?c$(tLZJ)7#=gmq1D$n zGqR#Qf`%bKgr>$)@mHXgP1>m=`e9w?&>AuUbb}-;n+(Hu&H2%zH>Tz?JYb@H=#%7Q z%St58HmIw3#DZ&XYvqd!!rSiyc?7fg`Y%DhF*nif~3I%HQhH|0h+Qe@Jy2T+_9)7d6`_DzIf(BE8%C|S0=|for9pguB|rb z;KkCPst64X{x~(+^a(=ytc92?=rvvR!;p|CVF5Yv{xt8VfF%<(4jn#xz3Mz8Wiq!; zKOB4>nzlV)d_nE;t=s+6A*jJWmQS6YEYuonpO{N-7Q?8DHOh*FDP3jODC1E0wP4l|cJ8j;)A zDJZm9kxLN)^4EXxb#G-1*;yU-TwrcD1T4>F(6HW&Vy?eXav|)G9ieuVyNZ`|FgQH81%ixP*Q?B@H)cxf z4zi-yBEbL%ukbfrfgm|!-{RpAHz`&1b>bKsPZ9zF;adYj2)zao8$yCeR(yZ z(rhQxw3lT4|kbxScEup-pTVHyCr<>&|fsNU5Qwt(#P#dlKn*jap`NJ8{FPw#fj{R$H zjok?{xZRtJK&RGyE?5R}V4P1dusA`exu+j9O2kL1RP}bEPxaG3T zjFCe*JGfPFDX;A2Y*7J&1?XW-cP=;$3GP<-PV1$Yi-rsG_VZm@>r=0H zbYyDrqL22ZR-*9=B~3R=F>RfcLaA2D<^H~B`NhmOlSLf89A5Qlp|iN2-h{6^M~jLZ z!A%!Pg{EL(bSgs$wU8i0Qd=Cbc{rrPg$1&)hEy7Iaj|lR|mc4wrZ3*etrs=R6XV;}9nmyoS zmdE5^xqFhszO=hNU{(FSufM`&c&pl2S`w9WNZ>_pNaZhM_FIMG@iQAx{Q=GqidZVn ziDH}UUN(t&#m&6~Ti~;k`1HbUEVhtw1q4;bMjn&AVtOT^8{1Mg{gSPo>;jwL9{L!t z5oR12g+L&1O>Q*QrUKT))W5wJDk}t(2cMvbOxmhw)Y`iG4#0HFUCHcqk){HNGRy@U=ci@X6k{Sx*O;v-8&g9p#euX;(U ze;7fr@pkN@#tBm8pLd{@?<8lEY=!pNElr3^^uj37*ISShlm9kitwSOj)|oh8o2dD# zrNQ4?-`RSowj)J`^Xr*j;NIhytw-wJb8tpP&(&8wk?h?`^@dWGXO~>vkB0rqhlKGD zsJ~xGa92RoG!SrCRsw`~oVjjOzkGlElr~U1Thq7KzC9WaySpb*D{%`2Ae_qrz(`v= zyBD!pGgT`t2DgSA)mA)}k&+$%|LyebM?yGM27{DW! zKcD_XN~Fq_VP2hTfA&mt#uR(hoH?*(d>!4lNYDT-s(0$IB2XEAYb$h+4;hac16E8ML>2KXyD#csa*|s^jP(uUY+>kTR%6pc?tIqcozbp z6kk$ARu&3orj#sNGs0VnPJlcbu3wx{e>|>v*+L2bOj)FBL`K57%&{aNO&ZJB@5D>} zsTuj(iOEyW4#;}se_<8fS#$=!GBq`jZE!(kPRm&&<)8IJA`&fZDF^0^lM{}v6Oujr zY2}XW300o+k@XlTS2;3O=@eLOavg``-CaITV*$1u0dL21Tz?!}N627#uSFs!o@gLA z<8Og64}xI@sSs2v$v#`}RKw~Bns35)y$A<&-Ua#VEiZN4)hAU%r-8)8ufI>us{j$e zULDGAkT7B>WiCwOeA0Iqu7V}BuEYX=a2Fl9L1DI96GD1I0cFuu@b1o&X#I#G*Q`f@ z6bp^snV}6;!p!^)W7UG1W8gHsz{{Tp-1~?yIIBrW3&cC;I2Bn7b;WNR57Jcx+1`g4 zTYWkb9(PrFd+ScDNKVqJbS(ES^%&k&i!`Sgy`RVz_$XA{?b`HSQbMD)_YvNkdAB|t zREom$(dVD1BBuu54SGT<`D*%T<0W>=>|A4_+2G!XuSy7G&g+z1o1P)M@|n@eob=8i z_SGybA5y&z3RhZo87><0A$;W-;S=)^&g9wISbWgl&B8Y8m}tuVZWzWiN;B)xo91L4 zrdvAyWHTjeVNS7;iopYTBhl$?k?7Q_#wYta!hw!=ygu_!4!IP{zzne65_SCwH(fg= zyJN6_uvRD?i_dauHsf47ypVPIB{WT`GdNu7Yx7u)+;f6|@x70i5+rn9PR|xDpbZ7} zVRk=Xk-DYozzL|~&&%616#M{Q5lsC6+)EN|D>5_DN19FJpM4@+&X zk@u?}Z#0Mdgc26ctHd?}kG7(NX?WaPRp)L0MG=G~7x7$f`?vRfR2W1pBpJ|f0_0eB=RSR(t+?iBwQTQ8 zCD}^V9~4=0Vt`Lvbk7T^P z;MjJpb^f#&bzx93^G#t4466z0#pHmN_v(69O?mxfcN>`?3`Do{R=99ezF)@hyIy~g zm~(wPcu*RQM##Onr}teY?u{wC302q3uNp_65jbKDOeDR~j%>P~pl%&_r#h?&X_?d* zqQ=~?qd*cY=DNiCwjBU|ubJC@0H~WC@@r=i+?S~K(29p=T zg}|%*&Do0BHdPL{!X@WvKq%FpCr3 z{TZ&auMvzO?1N=bhIB@A0gc+C2UF-snV{SY^Z?+*4T#11c3w-OiNZj)kA{bG1JSRy zw&&p{cC`1mevq<;%v{f5!Q^AdyoTqKMMe4^tlKl=wC>v_T;P6Ju8a`6szkCeFXpztnR^0I(ZiN8;xHAsR?-Z2 zqHtLjmGBNBtVMQi);*e9IeA8c-SN4gdW|qzh!?L*CqiQNJaOFc%F35!iX3Dxq&RK7 zqA_QjiVQXC|NV!7%-g#tEpap|yFOL#WgC4v0uj*w;voZsM&`uK^pM=U2B>oePHOX# zQ>~3m|86uSR=8-}o|NhCZPzNujqEu&XLCE`n>rev>{8TIGsA%%3XQb4(h& zziUR{mpW72*y(S8MNkc(=_Vz?5Zove@}b==!E@lbL1~%~SKce0isPmdT!urex|s>P zmSQ^TtUmGBYoDVj8My(mU>DU{Q1dgmCWG>Vr3ekAe@S2d>c?ScirJlHEBz|z1%6SG zNXSbjxV(O7u0BFy;s0WtkVTCXScnH*FAzwkEuAl>kDPgGcl+U@*(``Po0KfjXsjr4 zf}MYes#fdkjL3-=(o>v+<$}2^l~w;nGsj}!dDq)2nLTxm3l?CNXvD5yV8&tBI%RCu9p&F*(XHq>fr}PvBZ!mgi{_P6q_oULl2^2w(#@^m;Li zjpLBV013eE)h0sHSioW2@bG+-@QQSe?}l+n@TdB|7rJynnEwx|pjYh7XU=`~1WY(M zlA3XPHlKA}K&LZXp(v-Y4P9wGeUCGrCg%N$ECSLh#Nv8W=6IsVfEM(x8E?G9)Q^jJ zGEL4;{TP13*y308d>69gxfDk<{uuM4_&OY9-4UrB%RC^#lN4L~xs(3f~qd;!-F8Py{>h@ga zj75p2c*DyPHS#f^8|fU%_w#D(vb$p(X2BtF`r()Y#g^sBDFpK7os5$FM?#9&JoHx{ zYQd9n@zuix5UZOnqR?jJE{BX*NX*%{;FtcUosQJyHb;pWyIWi(MYEIgcZ(OW3D?jF z=O32OokuErqWOQ8(rynHBikN933{LpYM&vr1T$VSyM6Ot`z~GJZugfQ3Yg_&a^JAk z_Q)8zZ^!q20Y}2FhmOm~qpe)$p-b%?I>t4o_HRrbtRW5*31%l?lkd>>5EaexJ^Mv) zi*N>RE~UdCAp>^QKSGAy#ivk*9j#rpwK$+|mY}#@q`fTqlXqpGHpo0Wo5;E7<)obt zp@00!Fw3$(%yN9V5RNfRH^{ae_uFhSdyrM?;?K2b3Nz4bF|d9=5-GSg<2NFs#nOfi z0v!H=*y`iw{<-4}Otk4Zc>CP@(PGdOvPb+pcCOf$B?*s`u>GldS@CvLDP?7G^KdHY z9rdB;{L9AohJQ~Mqr>ta%EyJCD7tm+4R&YW8+44oJEd5DiY2ULSWL;(9O;^pvYBA} ziC-_8L-6%9L|Tf$_U=j@ANw}1i7*j?+3AGc_2u^*IDm5swu(C3D}KiZ94HPhYN#dN zO;TQ}yajSSXz;9Heh|HSn^frZ-`b|5-nTkU+@#3y8p@YfR1+HYfzXMb(bzB2Gm?6Q z&1bjTwn|_CB-h9qT#KOx5GC%t|1PN#+erNxdhSYXEE3gpKgZVkV~iasQ#Tfla58N7!8#F)H^&B&tb~I1=S%GTa{<>*m7vx|93s>j2mO^!9WFGZ`=(XtXVzVr^%*9~i8*fINL5GbJh6ysL5ZZ4WX!Rem+r=4 zZouF+V?+4HOlUbr@?;>i`g;nGx+KSf0sbVQ(Wzc6t%-z0H<+>HuCcU{#(O!}bI@&& z3LVbD6j;-~YN9%cBuA_U9ZG*JAuDN9Rw#215|_jhyW^2m`kuF;-L)IyF^kJ>t;Rv9}5 zW<5TbU6ZM|_67C3*GOE#ljg0!*eVzE%EKlm4YuV-j*YR69VXB zXF9lP@}!o3BK)u^V>r=17M`alc*Yevl@J~tl}}ms^p(4G(>ixo4EPKZ%slfBhK?VI zY-tt{u>&=?2hQng!fVZGB47PcDb&X#`R`}}V(-j;ktCTTsOQcFIE~Q+&+vk)Q>TeZ zp@nPAsd=4^xU_8w6BMXGB5}d&DY_e!^xK~5-PK`IBlDN}=v8eU|IBx&^()v1R6K*t z^SX(yABMpo)BLRWvnG8~QM~%)k!rHG=Y#i(zVOgFqPs2ye>of%?HMn&zKvyR0`KFf}*nfJz9zE zUg`l7|Mup_Omcos-|w8&^nSBf_=``e-YCO23pIspDP2}4A|8V`<0VI{dac#}Hlee{ zxnwQl4K;wxI}f~j**hjCYw@FM#nbRyBAH`IvFM5)?^{LUw^ zDO!CWpSHGW65HWCK*qw7aU6uDZQ^*3Gn7^{jwlid^kdE8N%gxYG?K(~8G-{qua`Yh MUDbi&)Z71m0ABeFVE_OC literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/quic/decrypt-fail-google-de-51833.zeek b/testing/btest/scripts/base/protocols/quic/decrypt-fail-google-de-51833.zeek new file mode 100644 index 0000000000..23c9cdaf0e --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/decrypt-fail-google-de-51833.zeek @@ -0,0 +1,12 @@ +# @TEST-DOC: PCAP for which decryption failed due to not using the initial destination connection ID consistently. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/quic-decrypt-fail-google-de-51833.pcap base/protocols/quic +# @TEST-EXEC: test ! -f analyzer.log +# @TEST-EXEC: test ! -f dpd.log +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: zeek-cut -m ts uid server_name history < quic.log > quic.log.cut +# @TEST-EXEC: btest-diff quic.log.cut +# @TEST-EXEC: zeek-cut -m ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history < ssl.log > ssl.log.cut +# @TEST-EXEC: btest-diff ssl.log.cut diff --git a/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto-only-initial.zeek b/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto-only-initial.zeek new file mode 100644 index 0000000000..0537353ecb --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto-only-initial.zeek @@ -0,0 +1,12 @@ +# @TEST-DOC: Pcap with CRYPTO frames fragemented over multiple INITIAL packets. The pcap only contains 3 INITIAL packets. Check what logs are created. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/quic-multiple-initial-fragmented-crypto-only-initial.pcap base/protocols/quic +# @TEST-EXEC: test ! -f analyzer.log +# @TEST-EXEC: test ! -f dpd.log +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: zeek-cut -m ts uid server_name history < quic.log > quic.log.cut +# @TEST-EXEC: btest-diff quic.log.cut +# @TEST-EXEC: zeek-cut -m ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history < ssl.log > ssl.log.cut +# @TEST-EXEC: btest-diff ssl.log.cut diff --git a/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto.zeek b/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto.zeek new file mode 100644 index 0000000000..98696053bd --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/multiple-initial-fragmented-crypto.zeek @@ -0,0 +1,12 @@ +# @TEST-DOC: Pcap with CRYPTO frames fragemented over multiple INITIAL packets. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/quic-multiple-initial-fragmented-crypto.pcap base/protocols/quic +# @TEST-EXEC: test ! -f analyzer.log +# @TEST-EXEC: test ! -f dpd.log +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: zeek-cut -m ts uid server_name history < quic.log > quic.log.cut +# @TEST-EXEC: btest-diff quic.log.cut +# @TEST-EXEC: zeek-cut -m ts uid version cipher curve server_name resumed last_alert next_protocol established ssl_history < ssl.log > ssl.log.cut +# @TEST-EXEC: btest-diff ssl.log.cut