diff --git a/.cirrus.yml b/.cirrus.yml index 572d5182e9..5eddbeff6a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -204,6 +204,8 @@ centos7_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE << : *SKIP_TASK_ON_PR + env: + ZEEK_CI_CONFIGURE_FLAGS: *NO_SPICY_CONFIG debian12_task: container: diff --git a/CHANGES b/CHANGES index 13e625f3c3..48b9c67c6c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,26 @@ +6.1.0-dev.547 | 2023-10-11 18:02:25 +0200 + + * ci/btest: Remove spicy-quic helper, disable Spicy on CentOS 7 (Arne Welzel, Corelight) + + The have-quic pattern wasn't great and it wouldn't scale. + + * btest/core/ppp: Run test in bare mode (Arne Welzel, Corelight) + + * btest/quic: Update other tests (Arne Welzel, Corelight) + + * testing/quic: Fixups and simplification after Zeek integration (Arne Welzel, Corelight) + + * quic: Integrate as default analyzer (Arne Welzel, Corelight) + + * quic: Include Copyright lines to the analyzer's source code contributed by Fox-IT (Arne Welzel, Corelight) + + This is primarily such that they stay intact when importing into the + Zeek project. Also move LICENSE to COPYING. + + * quic: Squashed follow-ups: quic.log, tests, various fixes, performance (Arne Welzel, Corelight) + + * quic: Initial implementation (Joost) + 6.1.0-dev.538 | 2023-10-11 15:20:27 +0200 * ci/update-zeekygen-docs.sh: Do output stderr by default (Arne Welzel, Corelight) diff --git a/NEWS b/NEWS index 1abeab5789..938eb2d748 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,27 @@ New Functionality necessary in your environment. We're also open to general feedback about the structure of the new logs. +- Zeek now includes the QUIC protocol analyzer from the zeek/spicy-quic + project (https://github.com/zeek/spicy-quic). This project is a fork of + Fox-IT's initial implementation (https://github.com/fox-ds/spicy-quic). + + As for the LDAP analyzer, the analyzer's events and the new ``quic.log`` + should be considered preliminary and experimental until the arrival of + Zeek's next long-term-stable release (7.0). As above, any feedback and + contributions to this analyzer and the new log are welcome. + + The analyzer's functionality is limited to decryption of the INITIAL packets + of QUIC version 1. If decryption of these packets is successful, the + handshake data is forwarded to Zeek's SSL analyzer. An ``ssl.log`` entry + will appear in ``ssl.log`` for QUIC connections. The entry in the ``conn.log`` + will contain ``quic`` and ``ssl`` in the service field. + + To disable the analyzer in case of issues, use the following snippet: + + redef Analyzer::disabled_analyzers += { + Analyzer::ANALYZER_QUIC, + }; + - Added a new ``assert`` statement for assertion based testing and asserting runtime state. diff --git a/VERSION b/VERSION index e649eeac10..401674db65 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.1.0-dev.538 +6.1.0-dev.547 diff --git a/doc b/doc index 6492aaeaca..44565c3d63 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 6492aaeaca49ee434f03984af47310c70d96dafc +Subproject commit 44565c3d638ac6e5ebe3445a55244f54c96eefae diff --git a/scripts/base/init-default.zeek b/scripts/base/init-default.zeek index b7d11dfbd2..95b1c64628 100644 --- a/scripts/base/init-default.zeek +++ b/scripts/base/init-default.zeek @@ -66,6 +66,7 @@ @load base/protocols/ntlm @load base/protocols/ntp @load base/protocols/pop3 +@load base/protocols/quic @load base/protocols/radius @load base/protocols/rdp @load base/protocols/rfb diff --git a/scripts/base/protocols/quic/__load__.zeek b/scripts/base/protocols/quic/__load__.zeek new file mode 100644 index 0000000000..6a5d24e0c3 --- /dev/null +++ b/scripts/base/protocols/quic/__load__.zeek @@ -0,0 +1,4 @@ +@ifdef ( Analyzer::ANALYZER_QUIC ) +@load ./consts +@load ./main +@endif diff --git a/scripts/base/protocols/quic/consts.zeek b/scripts/base/protocols/quic/consts.zeek new file mode 100644 index 0000000000..b502b04be1 --- /dev/null +++ b/scripts/base/protocols/quic/consts.zeek @@ -0,0 +1,7 @@ +module QUIC; + +export { + const version_strings: table[count] of string = { + [0x00000001] = "1", + } &default=function(version: count): string { return fmt("unknown-%x", version); }; +} diff --git a/scripts/base/protocols/quic/main.zeek b/scripts/base/protocols/quic/main.zeek new file mode 100644 index 0000000000..ddd34a51e6 --- /dev/null +++ b/scripts/base/protocols/quic/main.zeek @@ -0,0 +1,215 @@ +##! Initial idea for a quic.log. + +@load base/frameworks/notice/weird +@load base/protocols/conn/removal-hooks + +@load ./consts + +module QUIC; + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + ## Timestamp of first QUIC packet for this entry. + ts: time &log; + ## Unique ID for the connection. + uid: string &log; + ## The connection's 4-tuple of endpoint addresses/ports. + id: conn_id &log; + + ## QUIC version as found in the first INITIAL packet from + ## the client. + version: string &log; + + ## First Destination Connection ID used by client. This is + ## random and unpredictable, but used for packet protection + ## by client and server. + client_initial_dcid: string &log &optional; + + ## Server chosen Connection ID usually from server's first + ## INITIAL packet. This is to be used by the client in + ## subsequent packets. + server_scid: string &log &optional; + + ## Server name extracted from SNI extension in ClientHello + ## packet if available. + server_name: string &log &optional; + + ## First protocol extracted from ALPN extension in ClientHello + ## packet if available. + client_protocol: string &log &optional; + + ## Experimental QUIC history. + ## + ## Letters have the following meaning with client-sent + ## letters being capitalized: + ## + ## ====== ==================================================== + ## Letter Meaning + ## ====== ==================================================== + ## I INIT packet + ## H HANDSHAKE packet + ## Z 0RTT packet + ## R RETRY packet + ## C CONNECTION_CLOSE packet + ## S SSL Client/Server Hello + ## ====== ==================================================== + history: string &log &default=""; + + # Internal state for the history field. + history_state: vector of string; + + # Internal state if this record has already been logged. + logged: bool &default=F; + }; + + global log_quic: event(rec: Info); + + global log_policy: Log::PolicyHook; + + global finalize_quic: Conn::RemovalHook; +} + +redef record connection += { + # XXX: We may have multiple QUIC connections with different + # Connection ID over the same UDP connection. + quic: Info &optional; +}; + +# Faster to modify here than re-compiling .evt files. +const quic_ports = { + 443/udp, # HTTP3-over-QUIC + 853/udp, # DNS-over-QUIC + 784/udp, # DNS-over-QUIC early +}; + +function add_to_history(quic: Info, is_orig: bool, what: string) + { + if ( |quic$history_state| == 10 ) + return; + + quic$history_state += is_orig ? to_upper(what[0]) : to_lower(what[0]); + } + +function log_record(quic: Info) + { + quic$history = join_string_vec(quic$history_state, ""); + Log::write(LOG, quic); + quic$logged = T; + } + +function set_conn(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + if ( ! c?$quic ) + { + c$quic = Info( + $ts=network_time(), + $uid=c$uid, + $id=c$id, + $version=version_strings[version], + ); + + Conn::register_removal_hook(c, finalize_quic); + } + + if ( is_orig && |dcid| > 0 && ! c$quic?$client_initial_dcid ) + c$quic$client_initial_dcid = bytestring_to_hexstr(dcid); + + if ( ! is_orig && |scid| > 0 ) + c$quic$server_scid = bytestring_to_hexstr(scid); + } + +event QUIC::initial_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + set_conn(c, is_orig, version, dcid, scid); + add_to_history(c$quic, is_orig, "INIT"); + } + +event QUIC::handshake_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + set_conn(c, is_orig, version, dcid, scid); + add_to_history(c$quic, is_orig, "HANDSHAKE"); + } + +event QUIC::zero_rtt_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + set_conn(c, is_orig, version, dcid, scid); + add_to_history(c$quic, is_orig, "ZeroRTT"); + } + +# RETRY packets trigger a log entry and state reset. +event QUIC::retry_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string, retry_token: string, integrity_tag: string) + { + if ( ! c?$quic ) + set_conn(c, is_orig, version, dcid, scid); + + add_to_history(c$quic, is_orig, "RETRY"); + + log_record(c$quic); + + delete c$quic; + } + +# Upon a connection_close_frame(), if any c$quic state is pending to be logged, do so +# now and prepare for a new entry. +event QUIC::connection_close_frame(c: connection, is_orig: bool, version: count, dcid: string, scid: string, error_code: count, reason_phrase: string) + { + if ( ! c?$quic ) + return; + + add_to_history(c$quic, is_orig, "CONNECTION_CLOSE"); + + log_record(c$quic); + + delete c$quic; + } + +event ssl_extension_server_name(c: connection, is_client: bool, names: string_vec) &priority=5 + { + if ( is_client && c?$quic && |names| > 0 ) + c$quic$server_name = names[0]; + } + +event ssl_extension_application_layer_protocol_negotiation(c: connection, is_client: bool, protocols: string_vec) + { + if ( c?$quic && is_client ) + { + c$quic$client_protocol = protocols[0]; + if ( |protocols| > 1 ) + # Probably not overly weird, but the quic.log only + # works with the first one in the hope to avoid + # vector or concatenation. + Reporter::conn_weird("QUIC_many_protocols", c, cat(protocols)); + } + } + +event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) + { + if ( ! c?$quic ) + return; + + add_to_history(c$quic, T, "SSL"); + } + +event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=-5 + { + if ( ! c?$quic ) + return; + + add_to_history(c$quic, F, "SSL"); + } + +hook finalize_quic(c: connection) + { + if ( ! c?$quic || c$quic$logged ) + return; + + log_record(c$quic); + } + +event zeek_init() + { + Log::create_stream(LOG, [$columns=Info, $ev=log_quic, $path="quic", $policy=log_policy]); + Analyzer::register_for_ports(Analyzer::ANALYZER_QUIC, quic_ports); + } diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index 314a965730..79e5b6cea0 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -28,6 +28,7 @@ add_subdirectory(ntlm) add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) +add_subdirectory(quic) add_subdirectory(radius) add_subdirectory(rdp) add_subdirectory(rfb) diff --git a/src/analyzer/protocol/quic/CMakeLists.txt b/src/analyzer/protocol/quic/CMakeLists.txt new file mode 100644 index 0000000000..30940524d0 --- /dev/null +++ b/src/analyzer/protocol/quic/CMakeLists.txt @@ -0,0 +1,15 @@ +if (OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.0") + spicy_add_analyzer(NAME QUIC PACKAGE_NAME QUIC SOURCES QUIC.spicy QUIC.evt decrypt_crypto.cc) + + # spicy_QUIC target is conditionally created by spicy_add_analyzer() + if (TARGET spicy_QUIC) + # I don't think this is actually needed as there's an unconditional + # include_directories(BEFORE ${OPENSSL_INCLUDE_DIR}) at the top-level. + target_include_directories(spicy_QUIC PRIVATE "${OPENSSL_INCLUDE_DIR}") + endif () +else () + message( + STATUS + "Warning: QUIC analyzer unavailable - requires OpenSSL 1.1 or later (found ${OPENSSL_VERSION})" + ) +endif () diff --git a/src/analyzer/protocol/quic/QUIC.evt b/src/analyzer/protocol/quic/QUIC.evt new file mode 100644 index 0000000000..cea08fc8d8 --- /dev/null +++ b/src/analyzer/protocol/quic/QUIC.evt @@ -0,0 +1,22 @@ +# Copyright (c) 2023, NCC Group / Fox-IT. See COPYING for details. +# Copyright (c) 2023 by the Zeek Project. See COPYING for details. + +protocol analyzer QUIC over UDP: + parse originator with QUIC::RequestFrame, + parse responder with QUIC::ResponseFrame; + +import QUIC; + +# Make the enum available. +export QUIC::LongPacketType; + +on QUIC::InitialPacket -> event QUIC::initial_packet($conn, $is_orig, self.header.version, self.header.dest_conn_id, self.header.src_conn_id); + +on QUIC::RetryPacket -> event QUIC::retry_packet($conn, $is_orig, self.header.version, self.header.dest_conn_id, self.header.src_conn_id, self.retry_token, self.integrity_tag); + +on QUIC::HandshakePacket -> event QUIC::handshake_packet($conn, $is_orig, self.header.version, self.header.dest_conn_id, self.header.src_conn_id); + +on QUIC::ZeroRTTPacket -> event QUIC::zero_rtt_packet($conn, $is_orig, self.header.version, self.header.dest_conn_id, self.header.src_conn_id); + +on QUIC::ConnectionClosePayload -> event QUIC::connection_close_frame($conn, $is_orig, self.header.version, self.header.dest_conn_id, self.header.src_conn_id, + self.error_code.result, self.reason_phrase); diff --git a/src/analyzer/protocol/quic/QUIC.spicy b/src/analyzer/protocol/quic/QUIC.spicy new file mode 100644 index 0000000000..e7276f2471 --- /dev/null +++ b/src/analyzer/protocol/quic/QUIC.spicy @@ -0,0 +1,533 @@ +# Copyright (c) 2023, NCC Group / Fox-IT. See COPYING for details. +# Copyright (c) 2023 by the Zeek Project. See COPYING for details. + +module QUIC; + +import spicy; +import zeek; + +# The interface to the C++ code that handles the decryption of the INITIAL packet payload using well-known keys +public function decrypt_crypto_payload( + all_data: bytes, + connection_id: bytes, + encrypted_offset: uint64, + payload_offset: uint64, + from_client: bool +): 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 { + + if ( long_header.first_byte.packet_type != LongPacketType::INITIAL ) + return False; + + # decrypt_crypto_payload() has known secrets for version 1, nothing else. + if ( long_header.version != 0x00000001 ) + return False; + + if ( is_client ) + return ! context.client_initial_processed; + + # 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; +} + +type ConnectionIDInfo = struct { + client_cid_len: uint8; + server_cid_len: uint8; + + # The DCID used by the client is employed by client and + # server for packet protection. Packet re-ordering + # will make life miserable. + # + # https://quicwg.org/base-drafts/rfc9001.html#appendix-A + initial_destination_conn_id: bytes; + + # 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; + +@if SPICY_VERSION >= 10800 + ssl_handle: zeek::ProtocolHandle &optional; +@else + did_ssl_begin: bool; +@endif +}; + +############## +# Definitions +############## + +type LongPacketType = enum { + INITIAL = 0, + ZERO_RTT = 1, + HANDSHAKE = 2, + RETRY = 3, +}; + +type HeaderForm = enum { + SHORT = 0, + LONG = 1, +}; + +type FrameType = enum { + PADDING = 0x00, + PING = 0x01, + ACK1 = 0x02, + ACK2 = 0x03, + RESET_STREAM = 0x04, + STOP_SENDING = 0x05, + CRYPTO = 0x06, + NEW_TOKEN = 0x07, + STREAM1 = 0x08, + STREAM2 = 0x09, + STREAM3 = 0x0a, + STREAM4 = 0x0b, + STREAM5 = 0x0c, + STREAM6 = 0x0d, + STREAM7 = 0x0e, + STREAM8 = 0x0f, + MAX_DATA = 0x10, + MAX_STREAM_DATA = 0x11, + MAX_STREAMS1 = 0x12, + MAX_STREAMS2 = 0x13, + DATA_BLOCKED = 0x14, + STREAM_DATA_BLOCKED = 0x15, + STREAMS_BLOCKED1 = 0x16, + STREAMS_BLOCKED2 = 0x17, + NEW_CONNECTION_ID = 0x18, + RETIRE_CONNECTION_ID = 0x19, + PATH_CHALLENGE = 0x1a, + PATH_RESPONSE = 0x1b, + CONNECTION_CLOSE1 = 0x1c, + CONNECTION_CLOSE2 = 0x1d, + HANDSHAKE_DONE = 0x1e, +}; + +############## +# Helper units +############## + +type VariableLengthInteger = unit { + var bytes_to_parse: uint64; + var result: uint64; + + # Value of the two most significant bits indicates number of bytes + # to parse for the variable length integer. + # + # https://datatracker.ietf.org/doc/rfc9000/ + # Section 16 and Appendix A + # + first_byte: bytes &size=1 { + local uint8_val = uint8($$.to_uint(spicy::ByteOrder::Big)); + self.bytes_to_parse = 2**((0xC0 & uint8_val) >> 6); + # Re-pack without most significant two bits for later use. + self.first_byte = pack(0x3f & uint8_val, spicy::ByteOrder::Big); + } + remaining_bytes: bytes &size=self.bytes_to_parse - 1; + + on %done { + self.result = (self.first_byte + self.remaining_bytes).to_uint(spicy::ByteOrder::Big); + } +}; + +############## +# Long packets +# Generic units +############## + +public type LongHeaderPacket = unit { + var encrypted_offset: uint64; + var payload_length: uint64; + var client_conn_id_length: uint8; + var server_conn_id_length: uint8; + + first_byte: bitfield(8) { + header_form: 7 &convert=cast(cast($$)); + fixed_bit: 6; + packet_type: 4..5 &convert=cast(cast($$)); + type_specific_bits: 0..3 &convert=cast($$); + }; + + version: uint32; + dest_conn_id_len: uint8 { self.server_conn_id_length = $$; } + dest_conn_id: bytes &size=self.server_conn_id_length; + src_conn_id_len: uint8 { self.client_conn_id_length = $$; } + src_conn_id: bytes &size=self.client_conn_id_length; + + switch ( self.first_byte.packet_type ) { + LongPacketType::INITIAL -> initial_hdr : InitialPacket(self) { + self.encrypted_offset = self.offset() + + self.initial_hdr.length.bytes_to_parse + + self.initial_hdr.token_length.bytes_to_parse + + self.initial_hdr.token_length.result; + self.payload_length = self.initial_hdr.length.result; + } + + LongPacketType::ZERO_RTT -> zerortt_hdr : ZeroRTTPacket(self); + LongPacketType::HANDSHAKE -> handshake_hdr : HandshakePacket(self); + LongPacketType::RETRY -> retry_hdr : RetryPacket(self); + }; +}; + +# A QUIC Frame. +public type Frame = unit(header: LongHeaderPacket, from_client: bool, 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::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); + } + FrameType::CONNECTION_CLOSE1 -> : ConnectionClosePayload(header); +@if SPICY_VERSION >= 10800 + FrameType::PADDING -> : skip /\x00*/; # eat the padding +@else + FrameType::PADDING -> : /\x00*/; # eat the padding +@endif + FrameType::PING -> : void; + * -> : void { + throw "unhandled frame type %s in %s" % (self.frame_type, header.first_byte.packet_type); + } + }; +}; + +type CRYPTOPayload = unit(from_client: bool) { + offset: VariableLengthInteger; + length: VariableLengthInteger; + cryptodata: bytes &size=self.length.result; +}; + +type ACKPayload = unit { + latest_ack: VariableLengthInteger; + ack_delay: VariableLengthInteger; + ack_range_count: VariableLengthInteger; + first_ack_range: VariableLengthInteger; +}; + +type ConnectionClosePayload = unit(header: LongHeaderPacket) { + var header: LongHeaderPacket = header; + error_code: VariableLengthInteger; + switch { + -> unknown_frame_type: b"\x00"; + -> frame_type: VariableLengthInteger; + }; + reason_phrase_length: VariableLengthInteger; + reason_phrase: bytes &size=self.reason_phrase_length.result; +}; + + +############## +# Long packets +# Specific long packet type units +############## + +# Remainder of an Initial packet +type InitialPacket = unit(header: LongHeaderPacket) { + var header: LongHeaderPacket = header; + token_length: VariableLengthInteger; + token: bytes &size=self.token_length.result; + + # 5.4.2. Header Protection Sample + # + # That is, in sampling packet ciphertext for header + # protection, the Packet Number field is assumed to + # be 4 bytes long (its maximum possible encoded length). + # + # Enforce 4 bytes Packet Number length + 16 bytes sample + # ciphertext available. + length: VariableLengthInteger &requires=self.length.result >= 20; + + # Consume the remainder of payload. This + # includes the packet number field, but we + # do not know its length yet. We need the + # payload for sampling, however. +@if SPICY_VERSION >= 10800 + payload: skip bytes &size=self.length.result; +@else + payload: bytes &size=self.length.result; +@endif +}; + +type ZeroRTTPacket = unit(header: LongHeaderPacket) { + var header: LongHeaderPacket = header; + length: VariableLengthInteger; +@if SPICY_VERSION >= 10800 + payload: skip bytes &size=self.length.result; +@else + payload: bytes &size=self.length.result; +@endif +}; + +type HandshakePacket = unit(header: LongHeaderPacket) { + var header: LongHeaderPacket = header; + length: VariableLengthInteger; +@if SPICY_VERSION >= 10800 + payload: skip bytes &size=self.length.result; +@else + payload: bytes &size=self.length.result; +@endif +}; + + +type RetryPacket = unit(header: LongHeaderPacket) { + var header: LongHeaderPacket = header; + var retry_token: bytes; + var integrity_tag: bytes; + + # A retry packet ends with a 128bit / 16 byte integrity + # tag, but otherwise we do not know anything about the + # size of the retry_token. Slurp the whole datagram and + # post split it into the distinct parts. + data: bytes &eod { + self.retry_token = self.data.sub(0, |self.data| - 16); + self.integrity_tag = self.data.sub(|self.data| - 16, |self.data|); + } +}; + +############## +# Short packets +############## + +# TODO: implement +public type ShortHeader = unit(dest_conn_id_length: uint8) { + first_byte: bitfield(8) { + header_form: 7 &convert=cast(cast($$)); + fixed_bit: 6; + spin_bit: 5; + todo: 0..4; + }; + dest_conn_id: bytes &size=dest_conn_id_length; +}; + +# TODO: investigate whether we can parse something useful out of this +public type ShortPacketPayload = unit { +@if SPICY_VERSION >= 10800 + payload: skip bytes &eod; +@else + payload: bytes &eod; +@endif +}; + +# TODO: investigate whether we can do something useful with this +public type EncryptedLongPacketPayload = unit { +@if SPICY_VERSION >= 10800 + payload: skip bytes &eod; +@else + payload: bytes &eod; +@endif +}; + +# 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&) { + var decrypted_data: bytes; + var full_packet: bytes; + var start: iterator; + + sink crypto_sink; + var crypto_buffer: CryptoBuffer&; + + # Attach an SSL analyzer to this connection once. + on %init { +@if SPICY_VERSION >= 10800 + if ( ! context?.ssl_handle ) { + context.ssl_handle = zeek::protocol_handle_get_or_create("SSL"); + } +@else + if ( ! context.did_ssl_begin ) { + zeek::protocol_begin("SSL"); + context.did_ssl_begin = True; + } +@endif + + self.start = self.input(); + } + + # Peek into the first byte and determine the header type. + first_byte: bitfield(8) { + header_form: 7 &convert=HeaderForm($$); + }; + + # TODO: Consider bitfield based look-ahead-parsing in the switch below + # to avoid this rewinding here. It's a hack. + : void { + 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); + HeaderForm::LONG -> long_header: LongHeaderPacket { + # For now, only allow a change of src/dest ConnectionID's for INITIAL packets. + + # 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.first_byte.packet_type == LongPacketType::RETRY ) { + context.client_initial_processed = False; + context.server_initial_processed = False; + context.initial_destination_conn_id = b""; + + # Allow re-opening the SSL analyzer the next time around. +@if SPICY_VERSION >= 10800 + zeek::protocol_handle_close(context.ssl_handle); + unset context.ssl_handle; +@else + zeek::protocol_end(); + context.did_ssl_begin = False; +@endif + } + } + }; + + # Slurp in the whole packet if we determined we have a chance to decrypt. + all_data: bytes &parse-at=self.start &eod if ( self?.long_header && can_decrypt(self.long_header, context, from_client) ) { + 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 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.all_data, + self.long_header.dest_conn_id, + self.long_header.encrypted_offset, + self.long_header.payload_length, + from_client + ); + + # Set this to be the seed for the decryption + 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; + + # 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 + self.decrypted_data = decrypt_crypto_payload( + self.all_data, + context.initial_destination_conn_id, + self.long_header.encrypted_offset, + self.long_header.payload_length, + from_client + ); + } + + # We attempted decryption, but it failed. Just reject the + # input and assume Zeek will disable the analyzer for this + # connection. + if ( |self.decrypted_data| == 0 ) + throw "decryption failed"; + + # If this was a reply from the server and it's not a RETRY, we assume the keys + # are restablished and decryption is no longer possible + # + # TODO: verify if this is actually correct per RFC + if ( self.long_header.first_byte.packet_type != LongPacketType::RETRY && ! from_client ) { + context.server_initial_processed = True; + context.client_initial_processed = True; + } + } + + # Depending on the type of header and whether we were able to decrypt + # some of it, parse the remaining payload. + : 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 +# With Spicy 1.8.0, can use the SSL handle directly. +@if SPICY_VERSION >= 10800 + , context.ssl_handle +@endif + ); + + # Stop decryption attempts after processing the very first + # INITIAL packet. + if ( from_client ) + context.client_initial_processed = True; + else + context.server_initial_processed = True; + + # Take buffered crypto data as confirmation signal. + spicy::accept_input(); + } + } +}; + +############## +# Entrypoints +############## +public type RequestFrame = unit { + %context = ConnectionIDInfo; + : Packet(True, self.context()); +}; + +public type ResponseFrame = unit { + %context = ConnectionIDInfo; + : Packet(False, self.context()); +}; diff --git a/src/analyzer/protocol/quic/decrypt_crypto.cc b/src/analyzer/protocol/quic/decrypt_crypto.cc new file mode 100644 index 0000000000..7f7a02b80a --- /dev/null +++ b/src/analyzer/protocol/quic/decrypt_crypto.cc @@ -0,0 +1,316 @@ +// Copyright (c) 2023, NCC Group / Fox-IT. See COPYING for details. +// Copyright (c) 2023 by the Zeek Project. See COPYING for details. + +/* +WORK-IN-PROGRESS +Initial working version of decrypting the INITIAL packets from +both client & server to be used by the Spicy parser. Might need a few more +refactors as C++ development is not our main profession. +*/ + +// Default imports +#include +#include +#include +#include +#include +#include + +// OpenSSL imports +#include +#include +#include + +// Import HILTI +#include + +namespace + { + +// Struct to store decryption info for this specific connection +struct DecryptionInformation + { + std::vector unprotected_header; + uint64_t packet_number; + std::vector nonce; + uint8_t packet_number_length; + }; + +// Return rt::hilti::Bytes::data() value as const uint8_t* +// +// This should be alright: https://stackoverflow.com/a/15172304 +inline const uint8_t* data_as_uint8(const hilti::rt::Bytes& b) + { + return reinterpret_cast(b.data()); + } + +/* +Constants used in the HKDF functions. HKDF-Expand-Label uses labels +such as 'quic key' and 'quic hp'. These labels can obviously be +calculated dynamically, but are incluced statically for now, as the +goal of this analyser is only to analyze the INITIAL packets. +*/ + +std::vector INITIAL_SALT_V1 = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, + 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a}; + +std::vector CLIENT_INITIAL_INFO = {0x00, 0x20, 0x0f, 0x74, 0x6c, 0x73, 0x31, + 0x33, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x20, 0x69, 0x6e, 0x00}; + +std::vector SERVER_INITIAL_INFO = {0x00, 0x20, 0x0f, 0x74, 0x6c, 0x73, 0x31, + 0x33, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x69, 0x6e, 0x00}; + +std::vector KEY_INFO = {0x00, 0x10, 0x0e, 0x74, 0x6c, 0x73, 0x31, 0x33, 0x20, + 0x71, 0x75, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79, 0x00}; + +std::vector IV_INFO = {0x00, 0x0c, 0x0d, 0x74, 0x6c, 0x73, 0x31, 0x33, 0x20, + 0x71, 0x75, 0x69, 0x63, 0x20, 0x69, 0x76, 0x00}; + +std::vector HP_INFO = {0x00, 0x10, 0x0d, 0x74, 0x6c, 0x73, 0x31, 0x33, 0x20, + 0x71, 0x75, 0x69, 0x63, 0x20, 0x68, 0x70, 0x00}; + +/* +Constants used by the different functions +*/ +const size_t INITIAL_SECRET_LEN = 32; +const size_t AEAD_KEY_LEN = 16; +const size_t AEAD_IV_LEN = 12; +const size_t AEAD_HP_LEN = 16; +const size_t AEAD_SAMPLE_LENGTH = 16; +const size_t AEAD_TAG_LENGTH = 16; +const size_t MAXIMUM_PACKET_LENGTH = 1500; +const size_t MAXIMUM_PACKET_NUMBER_LENGTH = 4; + +/* +HKDF-Extract as described in https://www.rfc-editor.org/rfc/rfc8446.html#section-7.1 +*/ +std::vector hkdf_extract(const hilti::rt::Bytes& connection_id) + { + std::vector out_temp(INITIAL_SECRET_LEN); + size_t initial_secret_len = out_temp.size(); + const EVP_MD* digest = EVP_sha256(); + EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + EVP_PKEY_derive_init(pctx); + EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY); + EVP_PKEY_CTX_set_hkdf_md(pctx, digest); + EVP_PKEY_CTX_set1_hkdf_key(pctx, data_as_uint8(connection_id), connection_id.size()); + EVP_PKEY_CTX_set1_hkdf_salt(pctx, INITIAL_SALT_V1.data(), INITIAL_SALT_V1.size()); + EVP_PKEY_derive(pctx, out_temp.data(), &initial_secret_len); + EVP_PKEY_CTX_free(pctx); + return out_temp; + } + +/* +HKDF-Expand-Label as described in https://www.rfc-editor.org/rfc/rfc8446.html#section-7.1 +that uses the global constant labels such as 'quic hp'. +*/ +std::vector hkdf_expand(size_t out_len, const std::vector& key, + const std::vector& info) + { + std::vector out_temp(out_len); + const EVP_MD* digest = EVP_sha256(); + EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + EVP_PKEY_derive_init(pctx); + EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); + EVP_PKEY_CTX_set_hkdf_md(pctx, digest); + EVP_PKEY_CTX_set1_hkdf_key(pctx, key.data(), key.size()); + EVP_PKEY_CTX_add1_hkdf_info(pctx, info.data(), info.size()); + EVP_PKEY_derive(pctx, out_temp.data(), &out_len); + EVP_PKEY_CTX_free(pctx); + return out_temp; + } + +/* +Removes the header protection from the INITIAL packet and returns a DecryptionInformation struct +that is partially filled +*/ +DecryptionInformation remove_header_protection(const std::vector& client_hp, + uint64_t encrypted_offset, + const hilti::rt::Bytes& all_data) + { + DecryptionInformation decryptInfo; + int outlen; + auto cipher = EVP_aes_128_ecb(); + auto ctx = EVP_CIPHER_CTX_new(); + EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1); + EVP_CIPHER_CTX_set_key_length(ctx, client_hp.size()); + // Passing an 1 means ENCRYPT + EVP_CipherInit_ex(ctx, NULL, NULL, client_hp.data(), NULL, 1); + + static_assert(AEAD_SAMPLE_LENGTH > 0); + assert(all_data.size() >= encrypted_offset + MAXIMUM_PACKET_NUMBER_LENGTH + AEAD_SAMPLE_LENGTH); + + const uint8_t* sample = data_as_uint8(all_data) + encrypted_offset + + MAXIMUM_PACKET_NUMBER_LENGTH; + + std::array mask; + EVP_CipherUpdate(ctx, mask.data(), &outlen, sample, AEAD_SAMPLE_LENGTH); + EVP_CIPHER_CTX_free(ctx); + + // To determine the actual packet number length, + // we have to remove the mask from the first byte + uint8_t first_byte = data_as_uint8(all_data)[0]; + + if ( first_byte & 0x80 ) + { + first_byte ^= mask[0] & 0x0F; + } + else + { + first_byte ^= first_byte & 0x1F; + } + + // And now we can fully recover the correct packet number length... + int recovered_packet_number_length = (first_byte & 0x03) + 1; + + // .. and use this to reconstruct the (partially) unprotected header + std::vector unprotected_header(data_as_uint8(all_data), + data_as_uint8(all_data) + encrypted_offset + + recovered_packet_number_length); + + uint32_t decoded_packet_number = 0; + + unprotected_header[0] = first_byte; + for ( int i = 0; i < recovered_packet_number_length; ++i ) + { + unprotected_header[encrypted_offset + i] ^= mask[1 + i]; + decoded_packet_number = unprotected_header[encrypted_offset + i] | + (decoded_packet_number << 8); + } + + // Store the information back in the struct + decryptInfo.packet_number = decoded_packet_number; + decryptInfo.packet_number_length = recovered_packet_number_length; + decryptInfo.unprotected_header = std::move(unprotected_header); + return decryptInfo; + } + +/* +Calculate the nonce for the AEAD by XOR'ing the CLIENT_IV and the +decoded packet number, and returns the nonce +*/ +std::vector calculate_nonce(std::vector client_iv, uint64_t packet_number) + { + for ( int i = 0; i < 8; ++i ) + client_iv[AEAD_IV_LEN - 1 - i] ^= (uint8_t)(packet_number >> 8 * i); + + return client_iv; + } + +/* +Function that calls the AEAD decryption routine, and returns the +decrypted data +*/ + +hilti::rt::Bytes decrypt(const std::vector& client_key, const hilti::rt::Bytes& all_data, + uint64_t payload_length, const DecryptionInformation& decryptInfo) + { + int out, out2, res; + + if ( payload_length < decryptInfo.packet_number_length + AEAD_TAG_LENGTH ) + throw hilti::rt::RuntimeError( + hilti::rt::fmt("payload too small %ld < %ld", payload_length, + decryptInfo.packet_number_length + AEAD_TAG_LENGTH)); + + const uint8_t* encrypted_payload = data_as_uint8(all_data) + + decryptInfo.unprotected_header.size(); + + int encrypted_payload_size = payload_length - decryptInfo.packet_number_length - + AEAD_TAG_LENGTH; + + if ( encrypted_payload_size < 0 ) + throw hilti::rt::RuntimeError( + hilti::rt::fmt("encrypted_payload_size underflow %ld", encrypted_payload_size)); + + if ( all_data.size() < + decryptInfo.unprotected_header.size() + encrypted_payload_size + AEAD_TAG_LENGTH ) + throw hilti::rt::RuntimeError( + hilti::rt::fmt("all_data too short %ld < %ld", all_data.size(), + decryptInfo.unprotected_header.size() + encrypted_payload_size)); + + const void* tag_to_check = all_data.data() + decryptInfo.unprotected_header.size() + + encrypted_payload_size; + int tag_to_check_length = AEAD_TAG_LENGTH; + + std::array decrypt_buffer; + + // Setup context + auto cipher = EVP_aes_128_gcm(); + auto ctx = EVP_CIPHER_CTX_new(); + + EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 0); + + // Set the sizes for the IV and KEY + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, decryptInfo.nonce.size(), NULL); + + EVP_CIPHER_CTX_set_key_length(ctx, client_key.size()); + + // Set the KEY and IV + EVP_CipherInit_ex(ctx, NULL, NULL, client_key.data(), decryptInfo.nonce.data(), 0); + + // Set the tag to be validated after decryption + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_to_check_length, + const_cast(tag_to_check)); + + // Setting the second parameter to NULL will pass it as Associated Data + EVP_CipherUpdate(ctx, NULL, &out, decryptInfo.unprotected_header.data(), + decryptInfo.unprotected_header.size()); + + // Set the actual data to decrypt data into the decrypt_buffer. The amount of + // byte decrypted is stored into `out` + EVP_CipherUpdate(ctx, decrypt_buffer.data(), &out, encrypted_payload, encrypted_payload_size); + + // Validate whether the decryption was successful or not + EVP_CipherFinal_ex(ctx, NULL, &out2); + EVP_CIPHER_CTX_free(ctx); + + // Copy the decrypted data from the decrypted buffer into a Bytes instance. + return hilti::rt::Bytes(decrypt_buffer.data(), decrypt_buffer.data() + out); + } + + } + +/* +Function that is called from Spicy. It's a wrapper around `process_data`; +it stores all the passed data in a global struct and then calls `process_data`, +which will eventually return the decrypted data and pass it back to Spicy. +*/ +hilti::rt::Bytes +QUIC_decrypt_crypto_payload(const hilti::rt::Bytes& all_data, const hilti::rt::Bytes& connection_id, + const hilti::rt::integer::safe& encrypted_offset, + const hilti::rt::integer::safe& payload_length, + const hilti::rt::Bool& from_client) + { + + if ( payload_length < 20 ) + throw hilti::rt::RuntimeError(hilti::rt::fmt("payload too small %ld < 20", payload_length)); + + if ( (all_data.size() < encrypted_offset + payload_length) ) + throw hilti::rt::RuntimeError(hilti::rt::fmt("packet too small %ld %ld", all_data.size(), + encrypted_offset + payload_length)); + + std::vector initial_secret = hkdf_extract(connection_id); + + std::vector server_client_secret; + if ( from_client ) + { + server_client_secret = hkdf_expand(INITIAL_SECRET_LEN, initial_secret, CLIENT_INITIAL_INFO); + } + else + { + server_client_secret = hkdf_expand(INITIAL_SECRET_LEN, initial_secret, SERVER_INITIAL_INFO); + } + + std::vector key = hkdf_expand(AEAD_KEY_LEN, server_client_secret, KEY_INFO); + std::vector iv = hkdf_expand(AEAD_IV_LEN, server_client_secret, IV_INFO); + std::vector hp = hkdf_expand(AEAD_HP_LEN, server_client_secret, HP_INFO); + + DecryptionInformation decryptInfo = remove_header_protection(hp, encrypted_offset, all_data); + + // Calculate the correct nonce for the decryption + decryptInfo.nonce = calculate_nonce(iv, decryptInfo.packet_number); + + return decrypt(key, all_data, payload_length, decryptInfo); + } diff --git a/testing/btest/Baseline/core.print-bpf-filters/output2 b/testing/btest/Baseline/core.print-bpf-filters/output2 index dcd56a5e77..48f5a34e63 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output2 +++ b/testing/btest/Baseline/core.print-bpf-filters/output2 @@ -24,7 +24,7 @@ 1 3544 2 389 1 4011 -2 443 +3 443 1 445 1 4789 1 502 @@ -50,11 +50,13 @@ 1 6669 1 67 1 68 +1 784 1 79 1 80 1 8000 1 8080 1 81 +1 853 2 88 1 8888 1 989 @@ -62,8 +64,8 @@ 1 992 1 993 1 995 -70 and -69 or -70 port +73 and +72 or +73 port 46 tcp -24 udp +27 udp diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 985e870bf5..d11129770b 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -424,6 +424,9 @@ scripts/base/init-default.zeek scripts/base/protocols/ntp/main.zeek scripts/base/protocols/ntp/consts.zeek scripts/base/protocols/pop3/__load__.zeek + scripts/base/protocols/quic/__load__.zeek + scripts/base/protocols/quic/consts.zeek + scripts/base/protocols/quic/main.zeek scripts/base/protocols/radius/__load__.zeek scripts/base/protocols/radius/main.zeek scripts/base/protocols/radius/consts.zeek diff --git a/testing/btest/Baseline/coverage.find-bro-logs/out b/testing/btest/Baseline/coverage.find-bro-logs/out index bd3b78858e..efe4d98b6d 100644 --- a/testing/btest/Baseline/coverage.find-bro-logs/out +++ b/testing/btest/Baseline/coverage.find-bro-logs/out @@ -42,6 +42,7 @@ openflow packet_filter pe print_log_path +quic radius rdp reporter diff --git a/testing/btest/Baseline/coverage.record-fields/out.default b/testing/btest/Baseline/coverage.record-fields/out.default index b53dbd29b1..d4f04e20bd 100644 --- a/testing/btest/Baseline/coverage.record-fields/out.default +++ b/testing/btest/Baseline/coverage.record-fields/out.default @@ -508,6 +508,21 @@ connection { * size: count, log=F, optional=F * state: count, log=F, optional=F } + * quic: record QUIC::Info, log=F, optional=T + QUIC::Info { + * client_initial_dcid: string, log=T, optional=T + * client_protocol: string, log=T, optional=T + * history: string, log=T, optional=T + * history_state: vector of string, log=F, optional=F + * id: record conn_id, log=T, optional=F + conn_id { ... } + * logged: bool, log=F, optional=T + * server_name: string, log=T, optional=T + * server_scid: string, log=T, optional=T + * ts: time, log=T, optional=F + * uid: string, log=T, optional=F + * version: string, log=T, optional=F + } * radius: record RADIUS::Info, log=F, optional=T RADIUS::Info { * connect_info: string, log=T, optional=T diff --git a/testing/btest/Baseline/scripts.base.files.x509.files/files.log b/testing/btest/Baseline/scripts.base.files.x509.files/files.log index ce19924fa1..e64dfc52c0 100644 --- a/testing/btest/Baseline/scripts.base.files.x509.files/files.log +++ b/testing/btest/Baseline/scripts.base.files.x509.files/files.log @@ -7,10 +7,10 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts fuid uid id.orig_h id.orig_p id.resp_h id.resp_p source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256 #types time string string addr port addr port string count set[string] string string interval bool bool count count count count bool string string string string -XXXXXXXXXX.XXXXXX FgN3AE3of2TRIqaeQe CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43 -XXXXXXXXXX.XXXXXX Fv2Agc4z5boBOacQi6 CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d -XXXXXXXXXX.XXXXXX Ftmyeg2qgI2V38Dt3g CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0 -XXXXXXXXXX.XXXXXX FUFNf84cduA0IJCp07 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43 -XXXXXXXXXX.XXXXXX F1H4bd2OKGbLPEdHm4 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d -XXXXXXXXXX.XXXXXX Fgsbci2jxFXYMOHOhi ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0 +XXXXXXXXXX.XXXXXX FgN3AE3of2TRIqaeQe CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43 +XXXXXXXXXX.XXXXXX Fv2Agc4z5boBOacQi6 CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d +XXXXXXXXXX.XXXXXX Ftmyeg2qgI2V38Dt3g CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0 +XXXXXXXXXX.XXXXXX FUFNf84cduA0IJCp07 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43 +XXXXXXXXXX.XXXXXX F1H4bd2OKGbLPEdHm4 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d +XXXXXXXXXX.XXXXXX Fgsbci2jxFXYMOHOhi ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.chromium/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/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.chromium/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/quic.log new file mode 100644 index 0000000000..bd6779533d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 82.239.54.117 53727 110.213.53.115 443 1 95412c47018cdfe8 d5412c47018cdfe8 api.cirrus-ci.com h3 ISisH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.chromium/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/ssl.log new file mode 100644 index 0000000000..03e4777402 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.chromium/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 82.239.54.117 53727 110.213.53.115 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 api.cirrus-ci.com T - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/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.curl-http3/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log new file mode 100644 index 0000000000..e5bfa31fe1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.17.0.2 34347 64.233.166.94 443 1 815d62c70884f4b51e8ccadd5beed372 c15d62c70884f4b5 www.google.de h3 ISishIhHhh +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/ssl.log new file mode 100644 index 0000000000..0dfdef9290 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.curl-http3/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.17.0.2 34347 64.233.166.94 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 www.google.de F - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.events/.stderr b/testing/btest/Baseline/scripts.base.protocols.quic.events/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.events/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.events/out b/testing/btest/Baseline/scripts.base.protocols.quic.events/out new file mode 100644 index 0000000000..7b074d32a9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.events/out @@ -0,0 +1,46 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, T, 1, 4a8294bf9201d6cf, +1.0, retry_packet, C4J4Th3PJpwUYZZ6gc, F, 1, , 1b036a11, 98, 9b3ac827ccae092e3f8fdf84ec8ee526 +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, T, 1, 1b036a11, +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, F, 1, , fc674735 +1.0, handshake_packet, F, C4J4Th3PJpwUYZZ6gc, 1, , fc674735 +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, T, 1, fc674735, +1.0, handshake_packet, T, C4J4Th3PJpwUYZZ6gc, 1, ef3a4e06, +zerortt.pcap +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, T, 1, b7c7841c64883e3261d840, +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, F, 1, , 8d2041ac +1.0, handshake_packet, F, C4J4Th3PJpwUYZZ6gc, 1, , 8d2041ac +1.0, initial_packet, C4J4Th3PJpwUYZZ6gc, T, 1, 8d2041ac, +1.0, handshake_packet, T, C4J4Th3PJpwUYZZ6gc, 1, 5b7bc400, +1.0, initial_packet, CtPZjS20MLrsMUOJi2, T, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, initial_packet, CtPZjS20MLrsMUOJi2, F, 1, , e483a751 +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +1.0, zero_rtt_packet, T, CtPZjS20MLrsMUOJi2, 1, 15ae5e5e4962163f410b5529fc125bbc, +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, diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.firefox/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/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.firefox/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/quic.log new file mode 100644 index 0000000000..c4f0a37a2c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 82.239.54.117 44174 250.58.23.113 443 1 c5a5015ae8f479784a 01275b138ee6aca8a6276b132ae6b3547cf7773f blog.cloudflare.com h3 ISiihIhhhH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.firefox/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/ssl.log new file mode 100644 index 0000000000..fec40bbf3a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.firefox/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 82.239.54.117 44174 250.58.23.113 443 - - - blog.cloudflare.com F - - F C - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.fragmented-crypto/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.fragmented-crypto/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.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.fragmented-crypto/ssl.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.fragmented-crypto/ssl.log.cut new file mode 100644 index 0000000000..aa1b155354 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.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 TLSv13 TLS_AES_128_GCM_SHA256 x25519 www.google.de F - - F Cs diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/.stderr b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/conn.log.cut new file mode 100644 index 0000000000..6eadcd2f9d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/conn.log.cut @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +0.015059 ClEkJM2Vm5giqnMf4h - - +0.001000 CHhAvVGS1DHFjwGM9 - - +0.648580 C4J4Th3PJpwUYZZ6gc Dd quic,ssl diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/quic.log new file mode 100644 index 0000000000..621bb65d9e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 40084 193.167.100.100 443 1 a771f6161a4072c0bf10 5911deff server4:443 hq-interop ISishIH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/ssl.log new file mode 100644 index 0000000000..ec635dc9fb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.handshake/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 40084 193.167.100.100 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 server4:443 F - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/.stderr b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/conn.log.cut new file mode 100644 index 0000000000..f60a9d33e6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/conn.log.cut @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +0.000000 CHhAvVGS1DHFjwGM9 - - +0.016059 ClEkJM2Vm5giqnMf4h - - +0.669020 C4J4Th3PJpwUYZZ6gc Dd quic,ssl diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/quic.log new file mode 100644 index 0000000000..69bd69a8a4 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/quic.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 42834 193.167.100.100 443 1 4a8294bf9201d6cf - server4:443 hq-interop ISr +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 42834 193.167.100.100 443 1 1b036a11 fc674735 server4:443 hq-interop ISishIH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/ssl.log new file mode 100644 index 0000000000..fcdb1fe6e5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.retry/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 42834 193.167.100.100 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 server4:443 F - - F CCs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/.stderr b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/conn.log.cut new file mode 100644 index 0000000000..01d1a432a4 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/conn.log.cut @@ -0,0 +1,6 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid history service +0.015059 ClEkJM2Vm5giqnMf4h - - +0.001000 CHhAvVGS1DHFjwGM9 - - +0.790739 CtPZjS20MLrsMUOJi2 Dd quic,ssl +0.718160 C4J4Th3PJpwUYZZ6gc Dd quic,ssl 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 new file mode 100644 index 0000000000..7ed65c4c11 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/quic.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +1.000000 CtPZjS20MLrsMUOJi2 193.167.0.100 49394 193.167.100.100 443 1 15ae5e5e4962163f410b5529fc125bbc e483a751 server4:443 hq-interop ISZisZZZZZ +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 60492 193.167.100.100 443 1 b7c7841c64883e3261d840 8d2041ac server4:443 hq-interop ISishIH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/ssl.log new file mode 100644 index 0000000000..89e25b0914 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.interop.quic-go_quic-go.zerortt/ssl.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +1.000000 CtPZjS20MLrsMUOJi2 193.167.0.100 49394 193.167.100.100 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 server4:443 T - - F Cs - - - +1.000000 C4J4Th3PJpwUYZZ6gc 193.167.0.100 60492 193.167.100.100 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 server4:443 F - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/.stderr b/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/quic.log new file mode 100644 index 0000000000..dfc958bd04 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quic-log/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 669b:cb7a:de99:6a13:4a9b:46ef:3bed:cb6c 57538 6699:ded3:da8c:be73:5a99:ca73:5a99:cadb 443 1 5a37463b0eb7cc5d da37463b0eb7cc5d www.google.de h3 ISishIhHhh +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/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.quicdoq/quic.log b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/quic.log new file mode 100644 index 0000000000..3cc5f1b42e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/quic.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path quic +#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 server_scid server_name client_protocol history +#types time string addr port addr port string string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46907 127.0.0.1 853 1 fda05288ab9ff546 a31f4933d8727231 - doq ISishH +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/ssl.log new file mode 100644 index 0000000000..5897dd238a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.quicdoq/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46907 127.0.0.1 853 TLSv13 TLS_AES_128_GCM_SHA256 secp256r1 - F - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/conn.log.cut new file mode 100644 index 0000000000..46d72b1541 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/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.run-pcap/output b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/output @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/ssl.log b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/ssl.log new file mode 100644 index 0000000000..c58f04e799 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.run-pcap/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 1.2.3.4 49369 4.3.2.1 443 TLSv13 TLS_AES_128_GCM_SHA256 x25519 www.google.com F - - F Cs - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/analyzer.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/analyzer.log.cut new file mode 100644 index 0000000000..2b3de832a7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/analyzer.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 cause analyzer_kind analyzer_name failure_reason +1693925959.000001 CHhAvVGS1DHFjwGM9 violation protocol QUIC &requires failed: self.length.result >= 20 (<...>/QUIC.spicy::) diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/conn.log.cut new file mode 100644 index 0000000000..240a5abdd2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.vector-max-size-crash/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 - diff --git a/testing/btest/Traces/quic/chromium-115.0.5790.110-api-cirrus-com.pcap b/testing/btest/Traces/quic/chromium-115.0.5790.110-api-cirrus-com.pcap new file mode 100644 index 0000000000..cc203de8b9 Binary files /dev/null and b/testing/btest/Traces/quic/chromium-115.0.5790.110-api-cirrus-com.pcap differ diff --git a/testing/btest/Traces/quic/chromium-115.0.5790.110-google-de-fragmented.pcap b/testing/btest/Traces/quic/chromium-115.0.5790.110-google-de-fragmented.pcap new file mode 100644 index 0000000000..96c3ed2af8 Binary files /dev/null and b/testing/btest/Traces/quic/chromium-115.0.5790.110-google-de-fragmented.pcap differ diff --git a/testing/btest/Traces/quic/curl-8.1.2-dev-http3-www-google-de.pcap b/testing/btest/Traces/quic/curl-8.1.2-dev-http3-www-google-de.pcap new file mode 100644 index 0000000000..6cf69b82de Binary files /dev/null and b/testing/btest/Traces/quic/curl-8.1.2-dev-http3-www-google-de.pcap differ diff --git a/testing/btest/Traces/quic/firefox-102.13.0esr-blog-cloudflare-com.pcap b/testing/btest/Traces/quic/firefox-102.13.0esr-blog-cloudflare-com.pcap new file mode 100644 index 0000000000..0ab3758319 Binary files /dev/null and b/testing/btest/Traces/quic/firefox-102.13.0esr-blog-cloudflare-com.pcap differ diff --git a/testing/btest/Traces/quic/interop/attribution.txt b/testing/btest/Traces/quic/interop/attribution.txt new file mode 100644 index 0000000000..776030ae66 --- /dev/null +++ b/testing/btest/Traces/quic/interop/attribution.txt @@ -0,0 +1,10 @@ +PCAP files in this directory were gathered from the QUIC interop project webpage. + +Marten Seemann didn't have any concerns or reservations using these as testing +material. They require DLT_PPP support in Zeek, unfortunately. + +Some references: + +https://interop.seemann.io/ +https://github.com/marten-seemann/quic-network-simulator +https://github.com/marten-seemann/quic-interop-runner diff --git a/testing/btest/Traces/quic/interop/quic-go_quic-go/handshake.pcap b/testing/btest/Traces/quic/interop/quic-go_quic-go/handshake.pcap new file mode 100644 index 0000000000..ea4fccc2c7 Binary files /dev/null and b/testing/btest/Traces/quic/interop/quic-go_quic-go/handshake.pcap differ diff --git a/testing/btest/Traces/quic/interop/quic-go_quic-go/retry.pcap b/testing/btest/Traces/quic/interop/quic-go_quic-go/retry.pcap new file mode 100644 index 0000000000..f929b83621 Binary files /dev/null and b/testing/btest/Traces/quic/interop/quic-go_quic-go/retry.pcap differ diff --git a/testing/btest/Traces/quic/interop/quic-go_quic-go/zerortt.pcap b/testing/btest/Traces/quic/interop/quic-go_quic-go/zerortt.pcap new file mode 100644 index 0000000000..72796e59a5 Binary files /dev/null and b/testing/btest/Traces/quic/interop/quic-go_quic-go/zerortt.pcap differ diff --git a/testing/btest/Traces/quic/quic_win11_firefox_google.pcap b/testing/btest/Traces/quic/quic_win11_firefox_google.pcap new file mode 100644 index 0000000000..a18d821d07 Binary files /dev/null and b/testing/btest/Traces/quic/quic_win11_firefox_google.pcap differ diff --git a/testing/btest/Traces/quic/quicdoq.pcap b/testing/btest/Traces/quic/quicdoq.pcap new file mode 100644 index 0000000000..2d89536ed5 Binary files /dev/null and b/testing/btest/Traces/quic/quicdoq.pcap differ diff --git a/testing/btest/Traces/quic/vector-max-size-crash.pcap b/testing/btest/Traces/quic/vector-max-size-crash.pcap new file mode 100644 index 0000000000..f1c4ffbac4 Binary files /dev/null and b/testing/btest/Traces/quic/vector-max-size-crash.pcap differ diff --git a/testing/btest/core/ppp.test b/testing/btest/core/ppp.test index c5b67b8fb3..74cefb1234 100644 --- a/testing/btest/core/ppp.test +++ b/testing/btest/core/ppp.test @@ -1,4 +1,6 @@ # @TEST-DOC: PCAP from https://interop.seemann.io/ with DLT_PPP linklayer and no HDLC framing. # -# @TEST-EXEC: zeek -r $TRACES/ppp/quic-interop-retry.pcap %INPUT +# @TEST-EXEC: zeek -b -r $TRACES/ppp/quic-interop-retry.pcap %INPUT # @TEST-EXEC: btest-diff conn.log + +@load base/protocols/conn diff --git a/testing/btest/core/print-bpf-filters.zeek b/testing/btest/core/print-bpf-filters.zeek index e755c4347f..3d961b5792 100644 --- a/testing/btest/core/print-bpf-filters.zeek +++ b/testing/btest/core/print-bpf-filters.zeek @@ -1,4 +1,4 @@ -# @TEST-REQUIRES: have-spicy +# @TEST-REQUIRES: $SCRIPTS/have-spicy # # @TEST-EXEC: zeek -r $TRACES/empty.trace >output # @TEST-EXEC: cat packet_filter.log >>output diff --git a/testing/btest/scripts/base/protocols/quic/chromium.zeek b/testing/btest/scripts/base/protocols/quic/chromium.zeek new file mode 100644 index 0000000000..b53055f53f --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/chromium.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Test that runs the pcap + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/chromium-115.0.5790.110-api-cirrus-com.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log diff --git a/testing/btest/scripts/base/protocols/quic/curl-http3.zeek b/testing/btest/scripts/base/protocols/quic/curl-http3.zeek new file mode 100644 index 0000000000..78bc14aa97 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/curl-http3.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Test that runs the pcap + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/curl-8.1.2-dev-http3-www-google-de.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log diff --git a/testing/btest/scripts/base/protocols/quic/events.zeek b/testing/btest/scripts/base/protocols/quic/events.zeek new file mode 100644 index 0000000000..b95c735840 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/events.zeek @@ -0,0 +1,30 @@ +# @TEST-DOC: Supported events so far. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/interop/quic-go_quic-go/retry.pcap base/protocols/quic %INPUT >out +# @TEST-EXEC: echo "zerortt.pcap" >>out +# @TEST-EXEC: zeek -Cr $TRACES/quic/interop/quic-go_quic-go/zerortt.pcap base/protocols/quic %INPUT >>out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff .stderr +# + +function b2hex(s: string):string { return bytestring_to_hexstr(s); } + +event QUIC::initial_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + print network_time(), "initial_packet", c$uid, is_orig, version, b2hex(dcid), b2hex(scid); + } + +event QUIC::retry_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string, retry_token: string, integrity_tag: string) + { + print network_time(), "retry_packet", c$uid, is_orig, version, b2hex(dcid), b2hex(scid), |retry_token|, b2hex(integrity_tag); + } + +event QUIC::handshake_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + print network_time(), "handshake_packet", is_orig, c$uid, version, b2hex(dcid), b2hex(scid); + } +event QUIC::zero_rtt_packet(c: connection, is_orig: bool, version: count, dcid: string, scid: string) + { + print network_time(), "zero_rtt_packet", is_orig, c$uid, version, b2hex(dcid), b2hex(scid); + } diff --git a/testing/btest/scripts/base/protocols/quic/firefox.zeek b/testing/btest/scripts/base/protocols/quic/firefox.zeek new file mode 100644 index 0000000000..31d2358743 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/firefox.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Test that runs the pcap + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/firefox-102.13.0esr-blog-cloudflare-com.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log diff --git a/testing/btest/scripts/base/protocols/quic/fragmented-crypto.zeek b/testing/btest/scripts/base/protocols/quic/fragmented-crypto.zeek new file mode 100644 index 0000000000..b64210fd1b --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/fragmented-crypto.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Pcap with fragmented and unordered CRYPTO frames. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/chromium-115.0.5790.110-google-de-fragmented.pcap base/protocols/quic +# @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 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/interop/quic-go_quic-go/handshake.zeek b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/handshake.zeek new file mode 100644 index 0000000000..0def3cf306 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/handshake.zeek @@ -0,0 +1,10 @@ +# @TEST-DOC: Test interop pcap containing RETRY packet from server side. + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/interop/quic-go_quic-go/handshake.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log +# @TEST-EXEC: btest-diff .stderr +# @TEST-EXEC: test ! -f analyzer.log diff --git a/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/retry.zeek b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/retry.zeek new file mode 100644 index 0000000000..2fa6e34017 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/retry.zeek @@ -0,0 +1,10 @@ +# @TEST-DOC: Test interop pcap containing RETRY packet from server side. +# +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/interop/quic-go_quic-go/retry.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log +# @TEST-EXEC: btest-diff .stderr +# @TEST-EXEC: test ! -f analyzer.log diff --git a/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/zerortt.zeek b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/zerortt.zeek new file mode 100644 index 0000000000..e1d5c698a2 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/interop/quic-go_quic-go/zerortt.zeek @@ -0,0 +1,10 @@ +# @TEST-DOC: Test that client initiating connection using 0RTT packet doesn't cause analyzer errors trying to decrypt server side. +# +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/interop/quic-go_quic-go/zerortt.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log +# @TEST-EXEC: btest-diff .stderr +# @TEST-EXEC: test ! -f analyzer.log diff --git a/testing/btest/scripts/base/protocols/quic/quic-log.zeek b/testing/btest/scripts/base/protocols/quic/quic-log.zeek new file mode 100644 index 0000000000..7bce29a66f --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/quic-log.zeek @@ -0,0 +1,6 @@ +# @TEST-DOC: Smoke test the quic.log production + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/chromium-115.0.5790.110-google-de-fragmented.pcap base/protocols/quic +# @TEST-EXEC: btest-diff quic.log +# @TEST-EXEC: btest-diff .stderr diff --git a/testing/btest/scripts/base/protocols/quic/quicdoq.zeek b/testing/btest/scripts/base/protocols/quic/quicdoq.zeek new file mode 100644 index 0000000000..a9bc28dd39 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/quicdoq.zeek @@ -0,0 +1,8 @@ +# @TEST-DOC: Pcap with dns-over-quic lookup using https://github.com/private-octopus/quicdoq + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/quicdoq.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff quic.log diff --git a/testing/btest/scripts/base/protocols/quic/run-pcap.zeek b/testing/btest/scripts/base/protocols/quic/run-pcap.zeek new file mode 100644 index 0000000000..d280dd6043 --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/run-pcap.zeek @@ -0,0 +1,7 @@ +# @TEST-DOC: Test that runs the pcap + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/quic_win11_firefox_google.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: btest-diff ssl.log diff --git a/testing/btest/scripts/base/protocols/quic/vector-max-size-crash.zeek b/testing/btest/scripts/base/protocols/quic/vector-max-size-crash.zeek new file mode 100644 index 0000000000..78e9adeb9b --- /dev/null +++ b/testing/btest/scripts/base/protocols/quic/vector-max-size-crash.zeek @@ -0,0 +1,11 @@ +# @TEST-DOC: Test that runs the pcap + +# @TEST-REQUIRES: ${SCRIPTS}/have-spicy +# @TEST-EXEC: zeek -Cr $TRACES/quic/vector-max-size-crash.pcap base/protocols/quic +# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut +# @TEST-EXEC: zeek-cut -m ts uid cause analyzer_kind analyzer_name failure_reason < analyzer.log > analyzer.log.cut +# @TEST-EXEC: btest-diff conn.log.cut + +# Only run btest-ddiff on analyzer.log with 6.1-dev or later. The violation +# reporting has more detail in later versions. +# @TEST-EXEC: zeek -b -e 'exit(Version::info$version_number < 60100 ? 0 : 1)' || TEST_DIFF_CANONIFIER='sed -r "s/\((.+)\.spicy:[0-9]+:[0-9]+\)/(\1.spicy::)/g" | $SCRIPTS/diff-remove-abspath' btest-diff analyzer.log.cut