mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 11:08:20 +00:00
Compare commits
21 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e76a08524b | ||
![]() |
61f094e928 | ||
![]() |
589f146549 | ||
![]() |
9369a6e3dd | ||
![]() |
7330606b74 | ||
![]() |
1807710a8c | ||
![]() |
6b5b2d1c77 | ||
![]() |
0d70dde10b | ||
![]() |
e326e31d7e | ||
![]() |
3ee6a3d6c0 | ||
![]() |
01747191b6 | ||
![]() |
182641ccc1 | ||
![]() |
4f683ee1f8 | ||
![]() |
99acfc6534 | ||
![]() |
b3166c9379 | ||
![]() |
85e2a2fc1e | ||
![]() |
fb443815fa | ||
![]() |
35140ada29 | ||
![]() |
05baf8858b | ||
![]() |
8d294f83ad | ||
![]() |
6e47186c4a |
58 changed files with 1065 additions and 190 deletions
|
@ -80,6 +80,8 @@ have_2nd = "have_2nd"
|
||||||
ot1 = "ot1"
|
ot1 = "ot1"
|
||||||
ot2 = "ot2"
|
ot2 = "ot2"
|
||||||
uses_seh = "uses_seh"
|
uses_seh = "uses_seh"
|
||||||
|
ect0 = "ect0"
|
||||||
|
ect1 = "ect1"
|
||||||
|
|
||||||
[default.extend-words]
|
[default.extend-words]
|
||||||
caf = "caf"
|
caf = "caf"
|
||||||
|
|
175
CHANGES
175
CHANGES
|
@ -1,3 +1,178 @@
|
||||||
|
7.2.0 | 2025-05-08 15:15:25 -0700
|
||||||
|
|
||||||
|
* Release 7.2.0.
|
||||||
|
|
||||||
|
7.2.0-rc1.19 | 2025-05-08 15:14:29 -0700
|
||||||
|
|
||||||
|
* Bugfix: accurately track Broker buffer overflows w/ multiple peerings (Christian Kreibich, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 8d7942955573673a1eedd98d027a1efcaec485c8)
|
||||||
|
|
||||||
|
7.2.0-rc1.18 | 2025-05-08 14:47:17 -0700
|
||||||
|
|
||||||
|
* Bump auxil/spicy to latest release (Benjamin Bannier, Corelight)
|
||||||
|
|
||||||
|
7.2.0-rc1.16 | 2025-05-08 13:47:36 -0700
|
||||||
|
|
||||||
|
* Downgrade broker clone FatalError to an Error (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 2c17c85f557245b6163ced014fc1d8089e1fcdf2)
|
||||||
|
|
||||||
|
7.2.0-rc1.14 | 2025-05-07 14:11:04 -0700
|
||||||
|
|
||||||
|
* Fix Broker metrics naming bugs that snuck in w/ last-minute renaming [skip ci] (Christian Kreibich, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 507974a1d80442f5d5b2e7c5f4d3c45d44752d76)
|
||||||
|
|
||||||
|
7.2.0-rc1.13 | 2025-05-07 10:32:36 -0700
|
||||||
|
|
||||||
|
* Fix policy/protocols/conn/failed-service-logging.zeek (Johanna Amann, Corelight)
|
||||||
|
|
||||||
|
In GH-4422 it was pointed out that the protocols/conn/failed-service-logging.zeek
|
||||||
|
policy script only works when
|
||||||
|
`DPD::track_removed_services_in_connection=T` is set.
|
||||||
|
|
||||||
|
This was caused by a logic error in the script. This commit fixes this
|
||||||
|
logic error and introduces an additional test that checks that
|
||||||
|
failed-service-logging works even when the option is not set to true.
|
||||||
|
|
||||||
|
(cherry picked from commit 6f8924596fb86ee0c25fe26c810f3a8e3f9068a9)
|
||||||
|
|
||||||
|
7.2.0-rc1.12 | 2025-05-07 17:25:07 +0200
|
||||||
|
|
||||||
|
* btest/cluster/generic/publish-any: Apply Christian's fix from broker/publish-any (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 8089f5bed422e0da38dde631f88d6371c3d66c2f)
|
||||||
|
|
||||||
|
* wstest/terminate-while-queueing: Patch close_socket() (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 8089f5bed422e0da38dde631f88d6371c3d66c2f)
|
||||||
|
|
||||||
|
7.2.0-rc1.11 | 2025-05-07 14:06:06 +0200
|
||||||
|
|
||||||
|
* cluster/websocket: Stop and wait for reply thread during Terminate() (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 135acc7c6d2cd150b9090ca7563519ffadc2148e)
|
||||||
|
|
||||||
|
7.2.0-rc1.10 | 2025-05-07 11:10:09 +0200
|
||||||
|
|
||||||
|
* Websocket: Close onloop during Terminate() (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 4afb0ffeebd000211feb1e30891a3439235977bf)
|
||||||
|
|
||||||
|
* OnLoop: notify_all() instead of notify_one() (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 4afb0ffeebd000211feb1e30891a3439235977bf)
|
||||||
|
|
||||||
|
7.2.0-rc1.9 | 2025-05-06 11:42:23 -0700
|
||||||
|
|
||||||
|
* Add comments to the static methods for the Redis implementation (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit f9aa9a430d93841f0fa8dd55f84ce16954a8cbd3)
|
||||||
|
|
||||||
|
* Redis: Check server version when connecting (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit f9aa9a430d93841f0fa8dd55f84ce16954a8cbd3)
|
||||||
|
|
||||||
|
7.2.0-rc1.8 | 2025-05-05 11:21:13 -0700
|
||||||
|
|
||||||
|
* Use std::string_view in Redis::DoExpire to avoid copies (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 58d71d2fa35007695cd0f6ea3ec975df67c91bab)
|
||||||
|
|
||||||
|
7.2.0-rc1.7 | 2025-05-05 11:17:50 -0700
|
||||||
|
|
||||||
|
* QUIC: Extract reset_crypto() function (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 50ac8d1468603c710e109f1c050b3966dd91deda)
|
||||||
|
|
||||||
|
* QUIC: Rename ConnectionIDInfo to Context (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(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.2.0-rc1.6 | 2025-04-29 17:51:10 -0700
|
||||||
|
|
||||||
|
* fixed incorrect ZAM optimization of expressions seen in single-statement inlined functions (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit e56de061f9f59272d83b9ffa0540e965d47e4399)
|
||||||
|
|
||||||
|
7.2.0-rc1.5 | 2025-04-29 08:53:37 -0700
|
||||||
|
|
||||||
|
* External tests: add removed logs to CT list to prevent baseline changes (Johanna Amann, Corelight)
|
||||||
|
|
||||||
|
* Update Mozilla CA list and CT list to NSS 3.110 (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
7.2.0-rc1.3 | 2025-04-28 19:48:58 +0200
|
||||||
|
|
||||||
|
* broker/WebSocketShim: Check RegisterFd() return (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 5bf660a9ce6599581033e80b829d1103388b91cb)
|
||||||
|
|
||||||
|
* cluster/OnLoop: Fix coverity report about proc accessed without lock (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit 5bf660a9ce6599581033e80b829d1103388b91cb)
|
||||||
|
|
||||||
|
* GH-3045: broker/Data/data_to_val: Fail on vectors/lists with holes (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
Instead of simply removing holes from vectors or lists when converting
|
||||||
|
from Val to Broker format, error out as the receiver has no chance to
|
||||||
|
reconstruct where the hole might have been.
|
||||||
|
|
||||||
|
We could encode holes with broker::none, but this will put unnecessary
|
||||||
|
burden on language bindings and users due to the potential optionality.
|
||||||
|
Think a std::vector<uint64_t> that technically needs to be a
|
||||||
|
std::vector<std::optional<uint64_t>> to represent optional elements
|
||||||
|
properly.
|
||||||
|
|
||||||
|
(cherry picked from commit 540baa89afc68038a2af1f0ff09bc57e361970ab)
|
||||||
|
|
||||||
|
7.2.0-rc1.1 | 2025-04-25 16:12:46 -0700
|
||||||
|
|
||||||
|
* Fix use-after-move in recent broker changes (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
(cherry picked from commit b9b268bd866b117f097413db9e80f80858cce0e0)
|
||||||
|
|
||||||
|
7.2.0-rc1 | 2025-04-25 11:10:16 -0700
|
||||||
|
|
||||||
|
* Update docs submodule [nomail] [skip ci] (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
7.2.0-dev.659 | 2025-04-25 10:33:32 -0700
|
7.2.0-dev.659 | 2025-04-25 10:33:32 -0700
|
||||||
|
|
||||||
* Ignore case when matching prefix in http analyzer (Kshitiz Bartariya)
|
* Ignore case when matching prefix in http analyzer (Kshitiz Bartariya)
|
||||||
|
|
15
NEWS
15
NEWS
|
@ -36,6 +36,8 @@ New Functionality
|
||||||
|
|
||||||
- The bundled version of ZeekJS has been updated to v0.17.0.
|
- The bundled version of ZeekJS has been updated to v0.17.0.
|
||||||
|
|
||||||
|
- The bundled version of Spicy has been updated to v1.13.0.
|
||||||
|
|
||||||
- Some DNS events are not raised when ``dns_skip_all_addl`` is set to true. Zeek now
|
- Some DNS events are not raised when ``dns_skip_all_addl`` is set to true. Zeek now
|
||||||
raises a warning when a script declares these events while this option is set to true.
|
raises a warning when a script declares these events while this option is set to true.
|
||||||
|
|
||||||
|
@ -72,6 +74,9 @@ New Functionality
|
||||||
backend for NATS that will be available as an external plugin, but it is not quite
|
backend for NATS that will be available as an external plugin, but it is not quite
|
||||||
ready yet. Both of the existing backends support usage in a cluster environment.
|
ready yet. Both of the existing backends support usage in a cluster environment.
|
||||||
|
|
||||||
|
- The Redis backend requires at least redis-server version 6.2.0 or an equivalent
|
||||||
|
implementation.
|
||||||
|
|
||||||
- Improved alternative cluster backend support.
|
- Improved alternative cluster backend support.
|
||||||
|
|
||||||
The ZeroMQ cluster backend added in Zeek 7.1 has received various correctness,
|
The ZeroMQ cluster backend added in Zeek 7.1 has received various correctness,
|
||||||
|
@ -106,9 +111,9 @@ New Functionality
|
||||||
metrics are available to understand the health of each peering's buffer,
|
metrics are available to understand the health of each peering's buffer,
|
||||||
regardless of the overflow policy active. These are:
|
regardless of the overflow policy active. These are:
|
||||||
|
|
||||||
- zeek_broker_peer_buffer_levels: a gauge of the current buffer fill level,
|
- zeek_broker_peer_buffer_messages: a gauge of the current buffer fill level,
|
||||||
|
|
||||||
- zeek_broker_peer_buffer_recent_max_levels: a gauge that tracks the maximum
|
- zeek_broker_peer_buffer_recent_max_messages: a gauge that tracks the maximum
|
||||||
buffer fill level seen over the last ``Broker::buffer_stats_reset_interval`.
|
buffer fill level seen over the last ``Broker::buffer_stats_reset_interval`.
|
||||||
|
|
||||||
- zeek_broker_peer_buffer_overflows_total: a counter that tracks the number
|
- zeek_broker_peer_buffer_overflows_total: a counter that tracks the number
|
||||||
|
@ -256,6 +261,12 @@ Changed Functionality
|
||||||
our switch to use the C-Ares library back in the 5.0 release, but we never removed the
|
our switch to use the C-Ares library back in the 5.0 release, but we never removed the
|
||||||
requirement from CMake.
|
requirement from CMake.
|
||||||
|
|
||||||
|
- Publishing remote events with vector arguments that contain holes is now
|
||||||
|
rejected. The receiver side never had a chance to figure out where these
|
||||||
|
holes would have been. There's a chance this breaks scripts that accidentally
|
||||||
|
published vectors with holes. A reporter error is produced at runtime when
|
||||||
|
serialization of vectors with holes is attempted.
|
||||||
|
|
||||||
Removed Functionality
|
Removed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
7.2.0-dev.659
|
7.2.0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e15e0bd959a03d06822ae76b53eef6181daf01a2
|
Subproject commit d594c99e7efcf8d02d8f4f0336c3253585c9f609
|
2
doc
2
doc
|
@ -1 +1 @@
|
||||||
Subproject commit 858dd108b10a7d88852e01dc0134d6c0032f3c60
|
Subproject commit 9e34f868932eea34f0f2fab245da2d8237808c50
|
|
@ -44,26 +44,61 @@ global broker_peer_buffer_overflows_cf = Telemetry::register_counter_family([
|
||||||
$help_text="Number of overflows in Broker's send buffers",
|
$help_text="Number of overflows in Broker's send buffers",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
# A helper to track overflow counts over past peerings as well as the current
|
||||||
|
# one. The peer_id field allows us to identify when the counter has reset: a
|
||||||
|
# Broker ID different from the one on file means it's a new peering.
|
||||||
|
type EpochData: record {
|
||||||
|
peer_id: string;
|
||||||
|
num_overflows: count &default=0;
|
||||||
|
num_past_overflows: count &default=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
# This maps from a cluster node name to its EpochData.
|
||||||
|
global peering_epoch_data: table[string] of EpochData;
|
||||||
|
|
||||||
hook Telemetry::sync()
|
hook Telemetry::sync()
|
||||||
{
|
{
|
||||||
local peers = Broker::peering_stats();
|
local peers = Broker::peering_stats();
|
||||||
local nn: NamedNode;
|
local nn: NamedNode;
|
||||||
|
local labels: vector of string;
|
||||||
|
local ed: EpochData;
|
||||||
|
|
||||||
for ( peer, stats in peers )
|
for ( peer_id, stats in peers )
|
||||||
{
|
{
|
||||||
# Translate the Broker IDs to Zeek-level node names. We skip
|
# Translate the Broker IDs to Zeek-level node names. We skip
|
||||||
# telemetry for peers where this mapping fails, i.e. ones for
|
# telemetry for peers where this mapping fails, i.e. ones for
|
||||||
# connections to external systems.
|
# connections to external systems.
|
||||||
nn = nodeid_to_node(peer);
|
nn = nodeid_to_node(peer_id);
|
||||||
|
|
||||||
|
if ( |nn$name| == 0 )
|
||||||
|
next;
|
||||||
|
|
||||||
|
labels = vector(nn$name);
|
||||||
|
|
||||||
if ( |nn$name| > 0 )
|
|
||||||
{
|
|
||||||
Telemetry::gauge_family_set(broker_peer_buffer_messages_gf,
|
Telemetry::gauge_family_set(broker_peer_buffer_messages_gf,
|
||||||
vector(nn$name), stats$num_queued);
|
labels, stats$num_queued);
|
||||||
Telemetry::gauge_family_set(broker_peer_buffer_recent_max_messages_gf,
|
Telemetry::gauge_family_set(broker_peer_buffer_recent_max_messages_gf,
|
||||||
vector(nn$name), stats$max_queued_recently);
|
labels, stats$max_queued_recently);
|
||||||
|
|
||||||
|
if ( nn$name !in peering_epoch_data )
|
||||||
|
peering_epoch_data[nn$name] = EpochData($peer_id=peer_id);
|
||||||
|
|
||||||
|
ed = peering_epoch_data[nn$name];
|
||||||
|
|
||||||
|
if ( peer_id != ed$peer_id )
|
||||||
|
{
|
||||||
|
# A new peering. Ensure that we account for overflows in
|
||||||
|
# past ones. There is a risk here that we might have
|
||||||
|
# missed a peering altogether if we scrape infrequently,
|
||||||
|
# but re-peering should be a rare event.
|
||||||
|
ed$peer_id = peer_id;
|
||||||
|
ed$num_past_overflows += ed$num_overflows;
|
||||||
|
}
|
||||||
|
|
||||||
|
ed$num_overflows = stats$num_overflows;
|
||||||
|
|
||||||
Telemetry::counter_family_set(broker_peer_buffer_overflows_cf,
|
Telemetry::counter_family_set(broker_peer_buffer_overflows_cf,
|
||||||
vector(nn$name), stats$num_overflows);
|
labels, ed$num_past_overflows + ed$num_overflows);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#
|
#
|
||||||
# Do not edit this file. This file is automatically generated by gen-ct-list.pl
|
# Do not edit this file. This file is automatically generated by gen-ct-list.pl
|
||||||
# File generated at Tue Jul 23 16:04:45 2024
|
# File generated at Wed Apr 23 09:34:55 2025
|
||||||
# File generated from https://www.gstatic.com/ct/log_list/v3/log_list.json
|
# File generated from https://www.gstatic.com/ct/log_list/v3/log_list.json
|
||||||
# Source file generated at: 2024-07-23T13:06:08Z
|
# Source file generated at: 2025-04-23T12:55:20Z
|
||||||
# Source file version: 39.1
|
# Source file version: 53.22
|
||||||
#
|
#
|
||||||
|
|
||||||
@load base/protocols/ssl
|
@load base/protocols/ssl
|
||||||
|
@ -11,45 +11,39 @@ module SSL;
|
||||||
|
|
||||||
## @docs-omit-value
|
## @docs-omit-value
|
||||||
redef ct_logs += {
|
redef ct_logs += {
|
||||||
["\xee\xcd\xd0\x64\xd5\xdb\x1a\xce\xc5\x5c\xb7\x9d\xb4\xcd\x13\xa2\x32\x87\x46\x7c\xbc\xec\xde\xc3\x51\x48\x59\x46\x71\x1f\xb5\x9b"] = CTInfo($description="Google 'Argon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1d\xb9\x6c\xa9\xcb\x69\x94\xc5\x5c\xe6\xb6\xa6\x03\xbb\xd2\xb8\xdc\x54\x43\x17\x28\x99\x0c\x06\x01\x50\x1d\x9d\x64\xc0\x59\x46\x2b\xdc\xc8\x03\x1d\x05\xb4\x2d\xa8\x09\xf7\x99\x41\xed\x04\xfb\xe5\x57\xba\x26\x04\xf6\x11\x52\xce\x14\x65\x3b\x2f\x76\x2b\xc0"),
|
|
||||||
["\x4e\x75\xa3\x27\x5c\x9a\x10\xc3\x38\x5b\x6c\xd4\xdf\x3f\x52\xeb\x1d\xf0\xe0\x8e\x1b\x8d\x69\xc0\xb1\xfa\x64\xb1\x62\x9a\x39\xdf"] = CTInfo($description="Google 'Argon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x82\xa1\xf9\x67\x68\xa8\xe4\xdb\x94\x98\xe2\xe1\x68\x87\xe4\x09\x6d\x20\x35\x33\x38\x3c\xaf\x14\xaa\xd7\x08\x18\xf0\xfd\x16\x9b\xd3\xff\x7c\x27\x82\xd4\x87\xb7\x4e\x24\x46\x3b\xfb\xae\xbe\xc8\x23\x52\x20\x2b\xaa\x44\x05\xfe\x54\xf9\xd5\xf1\x1d\x45\x9a"),
|
["\x4e\x75\xa3\x27\x5c\x9a\x10\xc3\x38\x5b\x6c\xd4\xdf\x3f\x52\xeb\x1d\xf0\xe0\x8e\x1b\x8d\x69\xc0\xb1\xfa\x64\xb1\x62\x9a\x39\xdf"] = CTInfo($description="Google 'Argon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x82\xa1\xf9\x67\x68\xa8\xe4\xdb\x94\x98\xe2\xe1\x68\x87\xe4\x09\x6d\x20\x35\x33\x38\x3c\xaf\x14\xaa\xd7\x08\x18\xf0\xfd\x16\x9b\xd3\xff\x7c\x27\x82\xd4\x87\xb7\x4e\x24\x46\x3b\xfb\xae\xbe\xc8\x23\x52\x20\x2b\xaa\x44\x05\xfe\x54\xf9\xd5\xf1\x1d\x45\x9a"),
|
||||||
["\x12\xf1\x4e\x34\xbd\x53\x72\x4c\x84\x06\x19\xc3\x8f\x3f\x7a\x13\xf8\xe7\xb5\x62\x87\x88\x9c\x6d\x30\x05\x84\xeb\xe5\x86\x26\x3a"] = CTInfo($description="Google 'Argon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaf\xe4\xf3\x94\x2c\xdf\xa6\x27\xb5\xfe\xb2\x61\x83\x19\xc8\x21\x3a\x23\xa8\xa9\x3d\x54\xaf\xbc\x31\x9a\x1c\xd3\xc1\xe3\xb6\xc2\xf3\x0f\xc7\xb9\xca\x3b\x1d\x79\x65\x61\x22\x25\x82\x56\x4e\x98\xe8\xaa\x26\x29\x36\x1e\x28\x60\x6f\xeb\x15\x6e\xf7\x7c\xd0\xba"),
|
["\x12\xf1\x4e\x34\xbd\x53\x72\x4c\x84\x06\x19\xc3\x8f\x3f\x7a\x13\xf8\xe7\xb5\x62\x87\x88\x9c\x6d\x30\x05\x84\xeb\xe5\x86\x26\x3a"] = CTInfo($description="Google 'Argon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaf\xe4\xf3\x94\x2c\xdf\xa6\x27\xb5\xfe\xb2\x61\x83\x19\xc8\x21\x3a\x23\xa8\xa9\x3d\x54\xaf\xbc\x31\x9a\x1c\xd3\xc1\xe3\xb6\xc2\xf3\x0f\xc7\xb9\xca\x3b\x1d\x79\x65\x61\x22\x25\x82\x56\x4e\x98\xe8\xaa\x26\x29\x36\x1e\x28\x60\x6f\xeb\x15\x6e\xf7\x7c\xd0\xba"),
|
||||||
["\x0e\x57\x94\xbc\xf3\xae\xa9\x3e\x33\x1b\x2c\x99\x07\xb3\xf7\x90\xdf\x9b\xc2\x3d\x71\x32\x25\xdd\x21\xa9\x25\xac\x61\xc5\x4e\x21"] = CTInfo($description="Google 'Argon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xfc\x1e\xe8\x63\x8e\xff\x1c\x31\x8a\xfc\xb8\x1e\x19\x2b\x60\x50\x00\x3e\x8e\x9e\xda\x77\x37\xe3\xa5\xa8\xda\x8d\x94\xf8\x6b\xe8\x3d\x64\x8f\x27\x3f\x75\xb3\xfc\x6b\x12\xf0\x37\x06\x4f\x64\x58\x75\x14\x5d\x56\x52\xe6\x6a\x2b\x14\x4c\xec\x81\xd1\xea\x3e"),
|
["\x0e\x57\x94\xbc\xf3\xae\xa9\x3e\x33\x1b\x2c\x99\x07\xb3\xf7\x90\xdf\x9b\xc2\x3d\x71\x32\x25\xdd\x21\xa9\x25\xac\x61\xc5\x4e\x21"] = CTInfo($description="Google 'Argon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xfc\x1e\xe8\x63\x8e\xff\x1c\x31\x8a\xfc\xb8\x1e\x19\x2b\x60\x50\x00\x3e\x8e\x9e\xda\x77\x37\xe3\xa5\xa8\xda\x8d\x94\xf8\x6b\xe8\x3d\x64\x8f\x27\x3f\x75\xb3\xfc\x6b\x12\xf0\x37\x06\x4f\x64\x58\x75\x14\x5d\x56\x52\xe6\x6a\x2b\x14\x4c\xec\x81\xd1\xea\x3e"),
|
||||||
["\xd7\x6d\x7d\x10\xd1\xa7\xf5\x77\xc2\xc7\xe9\x5f\xd7\x00\xbf\xf9\x82\xc9\x33\x5a\x65\xe1\xd0\xb3\x01\x73\x17\xc0\xc8\xc5\x69\x77"] = CTInfo($description="Google 'Argon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2a\x3a\x67\x8b\xfe\xba\x0c\x86\x2b\x4a\x51\x8a\xe9\x17\xfe\x7b\xa1\x76\x73\xfd\xbc\x65\x4b\xc3\x27\xbf\x4d\xf3\x5f\xa0\xca\x29\x80\x11\x20\x32\x78\xd6\x7e\xf9\x34\x60\x8c\x75\xa0\xf5\x35\x50\x9c\xa1\xd3\x49\x4d\x13\xd5\x3b\x6a\x0e\xea\x45\x9d\x24\x13\x22"),
|
["\xd7\x6d\x7d\x10\xd1\xa7\xf5\x77\xc2\xc7\xe9\x5f\xd7\x00\xbf\xf9\x82\xc9\x33\x5a\x65\xe1\xd0\xb3\x01\x73\x17\xc0\xc8\xc5\x69\x77"] = CTInfo($description="Google 'Argon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2a\x3a\x67\x8b\xfe\xba\x0c\x86\x2b\x4a\x51\x8a\xe9\x17\xfe\x7b\xa1\x76\x73\xfd\xbc\x65\x4b\xc3\x27\xbf\x4d\xf3\x5f\xa0\xca\x29\x80\x11\x20\x32\x78\xd6\x7e\xf9\x34\x60\x8c\x75\xa0\xf5\x35\x50\x9c\xa1\xd3\x49\x4d\x13\xd5\x3b\x6a\x0e\xea\x45\x9d\x24\x13\x22"),
|
||||||
["\x76\xff\x88\x3f\x0a\xb6\xfb\x95\x51\xc2\x61\xcc\xf5\x87\xba\x34\xb4\xa4\xcd\xbb\x29\xdc\x68\x42\x0a\x9f\xe6\x67\x4c\x5a\x3a\x74"] = CTInfo($description="Google 'Xenon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb9\x60\xe0\x34\x1e\x35\xe4\x65\x00\x93\x4f\x90\x09\xbd\x5a\xec\x44\xdd\x8c\x0f\xce\xed\x11\x3e\x2a\x59\x46\x9a\x31\xb6\xc7\x99\xf7\xdc\xef\x3d\xcd\x8f\x86\xc2\x35\xa5\x3e\xdc\x29\xba\xbb\xf2\x54\xe2\xa8\x0c\x83\x08\x51\x06\xde\x21\x6d\x36\x50\x8e\x38\x4d"),
|
|
||||||
["\xcf\x11\x56\xee\xd5\x2e\x7c\xaf\xf3\x87\x5b\xd9\x69\x2e\x9b\xe9\x1a\x71\x67\x4a\xb0\x17\xec\xac\x01\xd2\x5b\x77\xce\xcc\x3b\x08"] = CTInfo($description="Google 'Xenon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x82\xe2\xce\x90\x40\x3f\x81\x0e\xdf\xea\xe1\x20\x2b\x5e\x2e\x30\x54\x46\x81\xb9\x58\xed\xaf\xbd\xff\x36\xa7\x9e\x0b\x5f\x6a\x6b\x91\xa5\xc1\x98\xe1\xf2\xcd\xeb\x17\x20\x70\xca\x2a\x12\xe6\x54\x78\x50\xdc\xff\x6d\xfd\x1c\xa7\xb6\x3a\x1f\xf9\x26\xa9\x1b\xbd"),
|
["\xcf\x11\x56\xee\xd5\x2e\x7c\xaf\xf3\x87\x5b\xd9\x69\x2e\x9b\xe9\x1a\x71\x67\x4a\xb0\x17\xec\xac\x01\xd2\x5b\x77\xce\xcc\x3b\x08"] = CTInfo($description="Google 'Xenon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x82\xe2\xce\x90\x40\x3f\x81\x0e\xdf\xea\xe1\x20\x2b\x5e\x2e\x30\x54\x46\x81\xb9\x58\xed\xaf\xbd\xff\x36\xa7\x9e\x0b\x5f\x6a\x6b\x91\xa5\xc1\x98\xe1\xf2\xcd\xeb\x17\x20\x70\xca\x2a\x12\xe6\x54\x78\x50\xdc\xff\x6d\xfd\x1c\xa7\xb6\x3a\x1f\xf9\x26\xa9\x1b\xbd"),
|
||||||
["\xdd\xdc\xca\x34\x95\xd7\xe1\x16\x05\xe7\x95\x32\xfa\xc7\x9f\xf8\x3d\x1c\x50\xdf\xdb\x00\x3a\x14\x12\x76\x0a\x2c\xac\xbb\xc8\x2a"] = CTInfo($description="Google 'Xenon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6b\xe0\xaf\xed\x06\x7c\x3d\xef\xd9\x0e\xe4\x58\x4b\x04\xd8\x2a\x47\x99\x90\x89\x7a\xb9\x36\xa5\x75\xc8\x04\xb8\xcb\xe2\xaa\x2b\xb5\x68\x9d\x88\x29\xa2\xa5\xcf\xce\x2b\x9a\x15\x9b\xa0\x3e\x9d\x94\x1c\xb2\xb7\x4a\xf2\x51\xec\x40\xed\x62\x47\xa4\x03\x49\x86"),
|
["\xdd\xdc\xca\x34\x95\xd7\xe1\x16\x05\xe7\x95\x32\xfa\xc7\x9f\xf8\x3d\x1c\x50\xdf\xdb\x00\x3a\x14\x12\x76\x0a\x2c\xac\xbb\xc8\x2a"] = CTInfo($description="Google 'Xenon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6b\xe0\xaf\xed\x06\x7c\x3d\xef\xd9\x0e\xe4\x58\x4b\x04\xd8\x2a\x47\x99\x90\x89\x7a\xb9\x36\xa5\x75\xc8\x04\xb8\xcb\xe2\xaa\x2b\xb5\x68\x9d\x88\x29\xa2\xa5\xcf\xce\x2b\x9a\x15\x9b\xa0\x3e\x9d\x94\x1c\xb2\xb7\x4a\xf2\x51\xec\x40\xed\x62\x47\xa4\x03\x49\x86"),
|
||||||
["\x96\x97\x64\xbf\x55\x58\x97\xad\xf7\x43\x87\x68\x37\x08\x42\x77\xe9\xf0\x3a\xd5\xf6\xa4\xf3\x36\x6e\x46\xa4\x3f\x0f\xca\xa9\xc6"] = CTInfo($description="Google 'Xenon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x3a\x1f\xc8\xbb\xce\xd5\x90\x47\x34\xca\xca\x01\x04\x27\x21\x1c\xe2\x29\x3d\x92\xbb\x91\x45\xc7\x5a\x3e\xa5\xd4\xf2\x12\xe6\xe8\xe6\x43\xba\xf3\x7b\xc2\x38\xaf\xfc\x23\x8a\x05\x56\xeb\x03\x0a\x30\xcc\x63\x6c\xd9\x3c\xbe\xf5\x7b\x94\xba\x94\xd3\xbf\x88\x4c"),
|
["\x96\x97\x64\xbf\x55\x58\x97\xad\xf7\x43\x87\x68\x37\x08\x42\x77\xe9\xf0\x3a\xd5\xf6\xa4\xf3\x36\x6e\x46\xa4\x3f\x0f\xca\xa9\xc6"] = CTInfo($description="Google 'Xenon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x3a\x1f\xc8\xbb\xce\xd5\x90\x47\x34\xca\xca\x01\x04\x27\x21\x1c\xe2\x29\x3d\x92\xbb\x91\x45\xc7\x5a\x3e\xa5\xd4\xf2\x12\xe6\xe8\xe6\x43\xba\xf3\x7b\xc2\x38\xaf\xfc\x23\x8a\x05\x56\xeb\x03\x0a\x30\xcc\x63\x6c\xd9\x3c\xbe\xf5\x7b\x94\xba\x94\xd3\xbf\x88\x4c"),
|
||||||
["\xd8\x09\x55\x3b\x94\x4f\x7a\xff\xc8\x16\x19\x6f\x94\x4f\x85\xab\xb0\xf8\xfc\x5e\x87\x55\x26\x0f\x15\xd1\x2e\x72\xbb\x45\x4b\x14"] = CTInfo($description="Google 'Xenon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe5\x77\x78\x95\x71\x28\xb3\x95\xc9\xa5\xcc\x7a\x4c\xe8\x32\x03\x96\x7b\xfc\x2e\x1d\xb9\xa4\xdb\x43\xa0\xbd\x69\x72\xf9\x45\xba\x9a\xc3\xe9\x96\xd5\x70\xe7\x0d\x7e\xc9\x95\x15\x27\x8a\x72\x30\x65\x86\x43\x53\xdc\x11\x44\x18\x49\x98\x25\x68\xa7\x3c\x05\xbf"),
|
["\xd8\x09\x55\x3b\x94\x4f\x7a\xff\xc8\x16\x19\x6f\x94\x4f\x85\xab\xb0\xf8\xfc\x5e\x87\x55\x26\x0f\x15\xd1\x2e\x72\xbb\x45\x4b\x14"] = CTInfo($description="Google 'Xenon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe5\x77\x78\x95\x71\x28\xb3\x95\xc9\xa5\xcc\x7a\x4c\xe8\x32\x03\x96\x7b\xfc\x2e\x1d\xb9\xa4\xdb\x43\xa0\xbd\x69\x72\xf9\x45\xba\x9a\xc3\xe9\x96\xd5\x70\xe7\x0d\x7e\xc9\x95\x15\x27\x8a\x72\x30\x65\x86\x43\x53\xdc\x11\x44\x18\x49\x98\x25\x68\xa7\x3c\x05\xbf"),
|
||||||
["\xda\xb6\xbf\x6b\x3f\xb5\xb6\x22\x9f\x9b\xc2\xbb\x5c\x6b\xe8\x70\x91\x71\x6c\xbb\x51\x84\x85\x34\xbd\xa4\x3d\x30\x48\xd7\xfb\xab"] = CTInfo($description="Cloudflare 'Nimbus2024' Log", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x77\xb1\x9b\x7b\x8f\xe6\x8b\x35\xfe\x3a\x92\x29\x2d\xac\x8a\x8d\x51\x8a\x25\xfc\x93\xb6\xd7\xa0\x8b\x29\x37\x71\x1d\x33\xca\xcc\x33\xea\x28\xb9\x1f\xe2\xac\xc3\xa9\x5d\xdd\x97\xbe\xf6\x9e\x94\x25\xdd\x36\x81\xd1\xeb\x5d\x29\xc3\x2b\x44\xf1\x5b\xca\x15\x48"),
|
|
||||||
["\xcc\xfb\x0f\x6a\x85\x71\x09\x65\xfe\x95\x9b\x53\xce\xe9\xb2\x7c\x22\xe9\x85\x5c\x0d\x97\x8d\xb6\xa9\x7e\x54\xc0\xfe\x4c\x0d\xb0"] = CTInfo($description="Cloudflare 'Nimbus2025'", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2025/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1a\x80\x1a\x15\x19\x19\x23\x79\xb4\xfa\xa0\x79\x8e\x8d\xd5\xc1\xdc\xc2\xb5\x96\x92\x7e\x94\xe0\xc3\x7e\x14\x7c\x0a\x0d\x2d\x46\xa8\x9d\x1b\xb1\x41\x65\x0c\x5f\x98\xc4\x5a\x17\x79\x81\x5b\x4a\x14\x41\xec\xaf\xa9\x5d\x0e\xab\x12\x19\x71\xcd\x43\xef\xbb\x97"),
|
["\xcc\xfb\x0f\x6a\x85\x71\x09\x65\xfe\x95\x9b\x53\xce\xe9\xb2\x7c\x22\xe9\x85\x5c\x0d\x97\x8d\xb6\xa9\x7e\x54\xc0\xfe\x4c\x0d\xb0"] = CTInfo($description="Cloudflare 'Nimbus2025'", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2025/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1a\x80\x1a\x15\x19\x19\x23\x79\xb4\xfa\xa0\x79\x8e\x8d\xd5\xc1\xdc\xc2\xb5\x96\x92\x7e\x94\xe0\xc3\x7e\x14\x7c\x0a\x0d\x2d\x46\xa8\x9d\x1b\xb1\x41\x65\x0c\x5f\x98\xc4\x5a\x17\x79\x81\x5b\x4a\x14\x41\xec\xaf\xa9\x5d\x0e\xab\x12\x19\x71\xcd\x43\xef\xbb\x97"),
|
||||||
["\x48\xb0\xe3\x6b\xda\xa6\x47\x34\x0f\xe5\x6a\x02\xfa\x9d\x30\xeb\x1c\x52\x01\xcb\x56\xdd\x2c\x81\xd9\xbb\xbf\xab\x39\xd8\x84\x73"] = CTInfo($description="DigiCert Yeti2024 Log", $operator="DigiCert", $url="https://yeti2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x57\xb8\xc1\x6f\x30\xa4\x7f\x2e\xe4\xf0\xd0\xd9\x60\x62\x13\x95\xe3\x7a\xe3\x4e\x53\xc3\xb3\xb8\x73\x85\xc1\x18\x0d\x23\x0e\x58\x84\xd2\x78\xef\x9b\xb3\x1e\x2c\x1a\xde\xc1\x8f\x81\x1b\x19\x44\x58\xb7\x00\x77\x60\x20\x1a\x72\xd8\x82\xde\xae\x9e\xb1\xc6\x4b"),
|
["\xcb\x38\xf7\x15\x89\x7c\x84\xa1\x44\x5f\x5b\xc1\xdd\xfb\xc9\x6e\xf2\x9a\x59\xcd\x47\x0a\x69\x05\x85\xb0\xcb\x14\xc3\x14\x58\xe7"] = CTInfo($description="Cloudflare 'Nimbus2026'", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2026/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd8\x5c\x61\x4f\xac\x6a\xd2\x20\x80\x4e\x8a\x42\xf6\x04\xad\x4b\xd4\xb1\x1c\x79\x8e\x29\x32\xde\x69\x53\x59\xeb\xad\x78\xf3\xc0\x2a\xf2\xd0\x11\x5d\x05\x7e\xeb\xe8\xc1\xd3\xdf\x37\xbf\x91\x64\x46\x6e\x0e\x27\x13\xea\xbb\x6f\x46\x27\x58\x86\xef\x40\x21\xa3"),
|
||||||
["\x7d\x59\x1e\x12\xe1\x78\x2a\x7b\x1c\x61\x67\x7c\x5e\xfd\xf8\xd0\x87\x5c\x14\xa0\x4e\x95\x9e\xb9\x03\x2f\xd9\x0e\x8c\x2e\x79\xb8"] = CTInfo($description="DigiCert Yeti2025 Log", $operator="DigiCert", $url="https://yeti2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdf\x95\x00\x5e\x10\xc1\x01\xf7\x37\xe3\x10\x74\xd1\xff\xb2\xca\x90\xed\x32\x99\x5f\x0c\x39\xfe\xa1\xd1\x13\x11\xac\xd1\xb3\x73\x93\x20\xc2\x13\x3c\x4c\xb5\x7a\x52\x86\x86\x3d\xe3\x95\x24\x7c\xd8\x91\x98\x48\x3b\xf0\xf0\xdf\x21\xf1\xb0\x81\x5a\x59\x25\x43"),
|
["\x7d\x59\x1e\x12\xe1\x78\x2a\x7b\x1c\x61\x67\x7c\x5e\xfd\xf8\xd0\x87\x5c\x14\xa0\x4e\x95\x9e\xb9\x03\x2f\xd9\x0e\x8c\x2e\x79\xb8"] = CTInfo($description="DigiCert Yeti2025 Log", $operator="DigiCert", $url="https://yeti2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdf\x95\x00\x5e\x10\xc1\x01\xf7\x37\xe3\x10\x74\xd1\xff\xb2\xca\x90\xed\x32\x99\x5f\x0c\x39\xfe\xa1\xd1\x13\x11\xac\xd1\xb3\x73\x93\x20\xc2\x13\x3c\x4c\xb5\x7a\x52\x86\x86\x3d\xe3\x95\x24\x7c\xd8\x91\x98\x48\x3b\xf0\xf0\xdf\x21\xf1\xb0\x81\x5a\x59\x25\x43"),
|
||||||
["\x73\xd9\x9e\x89\x1b\x4c\x96\x78\xa0\x20\x7d\x47\x9d\xe6\xb2\xc6\x1c\xd0\x51\x5e\x71\x19\x2a\x8c\x6b\x80\x10\x7a\xc1\x77\x72\xb5"] = CTInfo($description="DigiCert Nessie2024 Log", $operator="DigiCert", $url="https://nessie2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2d\xfc\xa2\x7b\x36\xbf\x56\x91\xe9\xfe\x3f\xe8\x3d\xfc\xc3\xa7\xe0\x61\x52\xea\x2c\xe9\x05\xa3\x9f\x27\x17\x81\x05\x70\x6b\x81\x61\x44\x8a\xf8\x3b\x10\x80\x42\xed\x03\x2f\x00\x50\x21\xfc\x41\x54\x84\xa3\x54\xd5\x2e\xb2\x7a\x16\x4b\x2a\x1f\x2b\x66\x04\x2b"),
|
|
||||||
["\xe6\xd2\x31\x63\x40\x77\x8c\xc1\x10\x41\x06\xd7\x71\xb9\xce\xc1\xd2\x40\xf6\x96\x84\x86\xfb\xba\x87\x32\x1d\xfd\x1e\x37\x8e\x50"] = CTInfo($description="DigiCert Nessie2025 Log", $operator="DigiCert", $url="https://nessie2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\xf0\xf0\xa7\x8b\x81\x2e\x09\x39\x3b\x9f\x42\xda\x38\x44\x5f\xb4\xcc\xed\x36\xbb\xd8\x43\x7f\x16\x49\x57\x87\x04\x7f\xa5\x01\x34\xf7\xe8\x68\x3f\xb7\x78\x1f\x60\x66\x2d\x67\x9a\x75\x80\xb7\x53\xa7\x85\xd5\xbc\xab\x47\x06\x55\xdb\xb5\xdf\x88\xa1\x6f\x38"),
|
["\xe6\xd2\x31\x63\x40\x77\x8c\xc1\x10\x41\x06\xd7\x71\xb9\xce\xc1\xd2\x40\xf6\x96\x84\x86\xfb\xba\x87\x32\x1d\xfd\x1e\x37\x8e\x50"] = CTInfo($description="DigiCert Nessie2025 Log", $operator="DigiCert", $url="https://nessie2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\xf0\xf0\xa7\x8b\x81\x2e\x09\x39\x3b\x9f\x42\xda\x38\x44\x5f\xb4\xcc\xed\x36\xbb\xd8\x43\x7f\x16\x49\x57\x87\x04\x7f\xa5\x01\x34\xf7\xe8\x68\x3f\xb7\x78\x1f\x60\x66\x2d\x67\x9a\x75\x80\xb7\x53\xa7\x85\xd5\xbc\xab\x47\x06\x55\xdb\xb5\xdf\x88\xa1\x6f\x38"),
|
||||||
["\xb6\x9d\xdc\xbc\x3c\x1a\xbd\xef\x6f\x9f\xd6\x0c\x88\xb1\x06\x7b\x77\xf0\x82\x68\x8b\x2d\x78\x65\xd0\x4b\x39\xab\xe9\x27\xa5\x75"] = CTInfo($description="DigiCert 'Wyvern2024h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x68\xa6\x79\x14\xd1\x58\xe7\xab\xaa\x29\x69\x7f\x60\xed\x68\xe8\x10\xf6\x07\x84\xc0\xfb\x59\x04\x5a\x09\xc9\x1d\xe1\x4b\xfb\xcd\xdc\x03\xf3\xa8\x2a\x46\xb9\x84\x4d\x69\x30\xec\x23\x35\xc1\x8e\xfc\x9f\xb4\x20\x24\xd7\x15\xac\x87\xf7\x1e\xc1\x0b\x3c\x76\x1a"),
|
|
||||||
["\x0c\x2a\xef\x2c\x4a\x5b\x98\x83\xd4\xdd\xa3\x82\xfe\x50\xfb\x51\x88\xb3\xe9\x73\x33\xa1\xec\x53\xa0\x9d\xc9\xa7\x9d\x0d\x08\x20"] = CTInfo($description="DigiCert 'Wyvern2024h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa8\x73\x12\x9c\x54\xd0\x7a\x7d\xc5\xb5\x17\x2b\x71\x52\x89\x04\x90\xbb\x42\xf1\x9d\xf8\x1c\xde\x4c\xcf\x82\x3c\xbd\x37\x1b\x74\x4c\x3c\xc7\xa3\x13\x87\x01\x51\x13\x14\xda\xa2\x12\x98\x84\xce\x1c\xbe\xcf\x4f\x7a\xef\x15\xfa\xd0\xee\xed\xed\x07\xad\x71\x6d"),
|
|
||||||
["\x73\x20\x22\x0f\x08\x16\x8a\xf9\xf3\xc4\xa6\x8b\x0a\xb2\x6a\x9a\x4a\x00\xee\xf5\x77\x85\x8a\x08\x4d\x05\x00\xd4\xa5\x42\x44\x59"] = CTInfo($description="DigiCert 'Wyvern2025h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\xcb\x80\x61\x86\x1b\x1f\xb5\xab\x2b\x20\x76\x59\x83\x66\x0e\xce\xae\xb8\x6f\x3b\x88\x02\xeb\x43\xf4\x87\x90\xcb\x8b\xda\xac\x0e\x19\x50\xe0\xf9\x24\x0e\xab\x26\x93\x8c\x3f\x9e\x0d\x96\x58\x44\x9d\x3b\x8a\x80\xc5\xc8\xbe\xe1\x89\x46\x6b\x48\x4c\xd6\x09"),
|
["\x73\x20\x22\x0f\x08\x16\x8a\xf9\xf3\xc4\xa6\x8b\x0a\xb2\x6a\x9a\x4a\x00\xee\xf5\x77\x85\x8a\x08\x4d\x05\x00\xd4\xa5\x42\x44\x59"] = CTInfo($description="DigiCert 'Wyvern2025h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\xcb\x80\x61\x86\x1b\x1f\xb5\xab\x2b\x20\x76\x59\x83\x66\x0e\xce\xae\xb8\x6f\x3b\x88\x02\xeb\x43\xf4\x87\x90\xcb\x8b\xda\xac\x0e\x19\x50\xe0\xf9\x24\x0e\xab\x26\x93\x8c\x3f\x9e\x0d\x96\x58\x44\x9d\x3b\x8a\x80\xc5\xc8\xbe\xe1\x89\x46\x6b\x48\x4c\xd6\x09"),
|
||||||
["\xed\x3c\x4b\xd6\xe8\x06\xc2\xa4\xa2\x00\x57\xdb\xcb\x24\xe2\x38\x01\xdf\x51\x2f\xed\xc4\x86\xc5\x70\x0f\x20\xdd\xb7\x3e\x3f\xe0"] = CTInfo($description="DigiCert 'Wyvern2025h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe0\xdb\x41\xef\xe4\x04\xbd\xcb\x6b\x2e\x4c\xcc\xf1\x6c\xde\x41\x58\x7f\xfe\x94\xf6\x7a\xf6\x60\xed\x8b\x76\x72\xa3\xa2\x1c\x31\x13\x32\x35\xa1\xf2\x08\xd2\x68\xc5\x34\xa7\x56\x08\x1c\x63\xde\x95\xe2\x81\x69\x97\x8d\x1e\xa8\xb7\x66\x51\x25\x75\x4d\x78\x2e"),
|
["\xed\x3c\x4b\xd6\xe8\x06\xc2\xa4\xa2\x00\x57\xdb\xcb\x24\xe2\x38\x01\xdf\x51\x2f\xed\xc4\x86\xc5\x70\x0f\x20\xdd\xb7\x3e\x3f\xe0"] = CTInfo($description="DigiCert 'Wyvern2025h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe0\xdb\x41\xef\xe4\x04\xbd\xcb\x6b\x2e\x4c\xcc\xf1\x6c\xde\x41\x58\x7f\xfe\x94\xf6\x7a\xf6\x60\xed\x8b\x76\x72\xa3\xa2\x1c\x31\x13\x32\x35\xa1\xf2\x08\xd2\x68\xc5\x34\xa7\x56\x08\x1c\x63\xde\x95\xe2\x81\x69\x97\x8d\x1e\xa8\xb7\x66\x51\x25\x75\x4d\x78\x2e"),
|
||||||
["\xdb\x07\x6c\xde\x6a\x8b\x78\xec\x58\xd6\x05\x64\x96\xeb\x6a\x26\xa8\xc5\x9e\x72\x12\x93\xe8\xac\x03\x27\xdd\xde\x89\xdb\x5a\x2a"] = CTInfo($description="DigiCert 'Sphinx2024h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc6\xe4\x29\x69\x98\xfe\x28\x92\x57\x12\x4d\x9e\xed\x0e\xe7\x32\xa2\xe6\x9c\x27\x78\xa4\x29\x7c\x99\xd5\xdb\xfa\x22\xc1\xdd\x5e\xa7\xf4\xd8\xea\xc8\xd7\x44\x8d\xe0\xf1\x8c\x0a\x01\x1d\xd8\x22\xa8\xd3\xeb\xc9\x22\x8e\x36\xfb\x4a\xb1\x70\x9c\x5d\xc1\xe8\x33"),
|
["\x64\x11\xc4\x6c\xa4\x12\xec\xa7\x89\x1c\xa2\x02\x2e\x00\xbc\xab\x4f\x28\x07\xd4\x1e\x35\x27\xab\xea\xfe\xd5\x03\xc9\x7d\xcd\xf0"] = CTInfo($description="DigiCert 'Wyvern2026h1'", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xec\xbc\x34\x39\xe2\x9a\x8d\xb7\x99\x7a\x91\xf1\x05\x72\x52\xda\x93\x89\x5d\x3a\x07\x8b\x99\xed\x80\xa5\x16\xda\x73\x21\x20\xeb\x86\x96\x87\xc5\xc6\xd9\x17\xba\x6e\xb9\x4c\x13\x58\xd5\xd1\x83\xf8\x7a\xdf\x1e\x07\xbc\x15\xcd\xc0\x4a\xcd\x2a\x31\x71\x07\x55"),
|
||||||
["\xdc\xc9\x5e\x6f\xa2\x99\xb9\xb0\xfd\xbd\x6c\xa6\xa3\x6e\x1d\x72\xc4\x21\x2f\xdd\x1e\x0f\x47\x55\x3a\x36\xd6\xcf\x1a\xd1\x1d\x8d"] = CTInfo($description="DigiCert 'Sphinx2024h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdb\x09\x41\x84\xe7\xd1\xf1\x5b\x25\x09\x7b\xe8\xc6\x98\x51\x5e\x29\x85\xfd\x81\xde\x89\xd7\xd0\x86\xa4\xb0\xe5\x15\xec\x5d\x7b\x17\x55\x5f\xc9\x79\x8d\xe4\x22\x36\xe7\xe9\xbf\x38\x3f\xd1\xe9\xd4\x09\x84\x81\xbe\xb6\xc1\xed\x1b\x17\xea\x26\x97\xba\xe9\x9a"),
|
["\xc2\x31\x7e\x57\x45\x19\xa3\x45\xee\x7f\x38\xde\xb2\x90\x41\xeb\xc7\xc2\x21\x5a\x22\xbf\x7f\xd5\xb5\xad\x76\x9a\xd9\x0e\x52\xcd"] = CTInfo($description="DigiCert 'Wyvern2026h2'", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7a\x73\xdb\x4a\xf2\xde\x4f\xec\xe1\x14\x1b\xbe\xa6\xa9\x3c\x21\xb8\x45\x12\xcd\x7a\x88\x26\x91\x20\x56\xf5\x49\x32\xc3\x75\x6c\xcb\xe9\x7c\x13\x75\x35\x9c\x6c\xec\xf1\x31\x3c\xc1\xde\x9b\x8c\x13\x92\xb7\xad\x3d\x0f\xa1\x9c\x8f\x48\xce\x74\x27\x18\x23\x99"),
|
||||||
["\xde\x85\x81\xd7\x50\x24\x7c\x6b\xcd\xcb\xaf\x56\x37\xc5\xe7\x81\xc6\x4c\xe4\x6e\xd6\x17\x63\x9f\x8f\x34\xa7\x26\xc9\xe2\xbd\x37"] = CTInfo($description="DigiCert 'Sphinx2025h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe3\x2f\x1f\x4d\x89\x05\x75\x29\x78\xbb\x22\x3d\x07\x62\x51\x14\x70\x94\xe7\x3c\xea\xf5\xee\xae\xa6\x48\x9a\x86\x52\x4e\x9e\x5c\xe3\x95\x97\x28\xbb\x52\x4b\x2a\xfd\xc8\xc9\x89\x4e\x45\x31\x17\xd3\x8d\xf2\xe7\xce\x18\x11\x58\x98\x2c\x60\x6f\x58\x20\x36\x6e"),
|
["\xde\x85\x81\xd7\x50\x24\x7c\x6b\xcd\xcb\xaf\x56\x37\xc5\xe7\x81\xc6\x4c\xe4\x6e\xd6\x17\x63\x9f\x8f\x34\xa7\x26\xc9\xe2\xbd\x37"] = CTInfo($description="DigiCert 'Sphinx2025h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe3\x2f\x1f\x4d\x89\x05\x75\x29\x78\xbb\x22\x3d\x07\x62\x51\x14\x70\x94\xe7\x3c\xea\xf5\xee\xae\xa6\x48\x9a\x86\x52\x4e\x9e\x5c\xe3\x95\x97\x28\xbb\x52\x4b\x2a\xfd\xc8\xc9\x89\x4e\x45\x31\x17\xd3\x8d\xf2\xe7\xce\x18\x11\x58\x98\x2c\x60\x6f\x58\x20\x36\x6e"),
|
||||||
["\xa4\x42\xc5\x06\x49\x60\x61\x54\x8f\x0f\xd4\xea\x9c\xfb\x7a\x2d\x26\x45\x4d\x87\xa9\x7f\x2f\xdf\x45\x59\xf6\x27\x4f\x3a\x84\x54"] = CTInfo($description="DigiCert 'Sphinx2025h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x41\x8c\x50\x13\x54\xb1\x19\x05\xb7\x7f\x4a\x20\x6e\xa3\x75\x63\xca\x34\xf4\xcc\x74\xea\x32\x3b\xb6\x8b\x03\x14\xa8\x52\x7f\x32\x87\x5e\x59\x9e\x0f\xab\x18\x9e\x29\x6c\xb5\x72\x77\x1a\x27\x54\x85\x5d\xc1\x7b\x24\xa8\x34\xe3\xcd\x88\xce\xd4\x50\x1b\xbe\x69"),
|
["\xa4\x42\xc5\x06\x49\x60\x61\x54\x8f\x0f\xd4\xea\x9c\xfb\x7a\x2d\x26\x45\x4d\x87\xa9\x7f\x2f\xdf\x45\x59\xf6\x27\x4f\x3a\x84\x54"] = CTInfo($description="DigiCert 'Sphinx2025h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x41\x8c\x50\x13\x54\xb1\x19\x05\xb7\x7f\x4a\x20\x6e\xa3\x75\x63\xca\x34\xf4\xcc\x74\xea\x32\x3b\xb6\x8b\x03\x14\xa8\x52\x7f\x32\x87\x5e\x59\x9e\x0f\xab\x18\x9e\x29\x6c\xb5\x72\x77\x1a\x27\x54\x85\x5d\xc1\x7b\x24\xa8\x34\xe3\xcd\x88\xce\xd4\x50\x1b\xbe\x69"),
|
||||||
|
["\x49\x9c\x9b\x69\xde\x1d\x7c\xec\xfc\x36\xde\xcd\x87\x64\xa6\xb8\x5b\xaf\x0a\x87\x80\x19\xd1\x55\x52\xfb\xe9\xeb\x29\xdd\xf8\xc3"] = CTInfo($description="DigiCert 'Sphinx2026h1'", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xab\x84\xbe\xf8\x3c\x87\xa2\x42\x25\x9a\x66\x9c\xae\x2b\x52\xe7\x5a\xf9\x21\x1b\x19\x03\xa5\x07\xe2\x46\x0b\x1f\x8a\x5e\x7c\x6c\xae\xff\x19\x77\x86\xe8\x7b\xfc\xee\x6b\x36\x4f\xf2\xbc\xc3\x9e\x05\x02\x9a\x08\x01\xb5\x49\x23\x35\xc4\xd3\x50\x2b\x51\xe9\xf4"),
|
||||||
|
["\x94\x4e\x43\x87\xfa\xec\xc1\xef\x81\xf3\x19\x24\x26\xa8\x18\x65\x01\xc7\xd3\x5f\x38\x02\x01\x3f\x72\x67\x7d\x55\x37\x2e\x19\xd8"] = CTInfo($description="DigiCert 'Sphinx2026h2'", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaa\xe0\xf4\x26\x44\x50\x4f\xfd\xa2\x9e\xe6\x80\xe0\x70\xb5\xb1\xce\x94\xa5\xf8\x97\x81\x44\x55\x42\x64\x1c\x22\x79\xa7\x64\x59\xd3\x89\x93\x21\x66\xfb\x09\x81\x60\x1f\x62\x55\x34\x38\x8c\xa4\x38\x2e\xac\x95\x0c\xeb\xed\x4f\x64\xbc\x45\x42\xf7\x06\x7a\xcd"),
|
||||||
["\x55\x81\xd4\xc2\x16\x90\x36\x01\x4a\xea\x0b\x9b\x57\x3c\x53\xf0\xc0\xe4\x38\x78\x70\x25\x08\x17\x2f\xa3\xaa\x1d\x07\x13\xd3\x0c"] = CTInfo($description="Sectigo 'Sabre' CT log", $operator="Sectigo", $url="https://sabre.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2\xc5\x71\xb3\xd1\xa9\x2f\x28\x3e\x83\x10\xbf\x12\xd0\x44\x66\x15\xef\x54\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda\x80"),
|
["\x55\x81\xd4\xc2\x16\x90\x36\x01\x4a\xea\x0b\x9b\x57\x3c\x53\xf0\xc0\xe4\x38\x78\x70\x25\x08\x17\x2f\xa3\xaa\x1d\x07\x13\xd3\x0c"] = CTInfo($description="Sectigo 'Sabre' CT log", $operator="Sectigo", $url="https://sabre.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2\xc5\x71\xb3\xd1\xa9\x2f\x28\x3e\x83\x10\xbf\x12\xd0\x44\x66\x15\xef\x54\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda\x80"),
|
||||||
["\xa2\xe2\xbf\xd6\x1e\xde\x2f\x2f\x07\xa0\xd6\x4e\x6d\x37\xa7\xdc\x65\x43\xb0\xc6\xb5\x2e\xa2\xda\xb7\x8a\xf8\x9a\x6d\xf5\x17\xd8"] = CTInfo($description="Sectigo 'Sabre2024h1'", $operator="Sectigo", $url="https://sabre2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\x01\xf6\xce\x31\xbc\xaa\x14\x61\x51\xfe\x6b\x7a\x87\xae\xa6\xd3\x9b\xc7\x87\x2d\x0a\x5a\xc8\x4f\xb5\x54\xdc\xc9\x93\xa0\x00\xee\xca\x1c\xb9\xa7\xb6\x7b\x47\x3b\xe5\x4f\xaa\x6c\x16\x1c\x70\x2e\xc8\xec\x53\x5a\x4c\x21\x4c\x7e\x27\x0b\x13\x14\x5e\xfc\x85"),
|
|
||||||
["\x19\x98\x10\x71\x09\xf0\xd6\x52\x2e\x30\x80\xd2\x9e\x3f\x64\xbb\x83\x6e\x28\xcc\xf9\x0f\x52\x8e\xee\xdf\xce\x4a\x3f\x16\xb4\xca"] = CTInfo($description="Sectigo 'Sabre2024h2'", $operator="Sectigo", $url="https://sabre2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7a\x10\x4c\x8a\xe7\x22\x7b\x6d\x2a\xba\x8e\xfa\x6b\x4a\x81\xd5\x85\xae\x03\xef\xff\x4b\xfc\x4d\x53\x3d\xb7\x8c\xbb\x75\x09\xc9\xea\x16\x7e\xc1\x77\x16\xd2\xc2\x45\x74\x6d\x8d\xc4\xe1\x88\x37\xdf\xd4\xf3\x60\x65\xfc\xa0\x75\xf0\x20\x66\x8e\x4a\xcc\x19\xda"),
|
|
||||||
["\xe0\x92\xb3\xfc\x0c\x1d\xc8\xe7\x68\x36\x1f\xde\x61\xb9\x96\x4d\x0a\x52\x78\x19\x8a\x72\xd6\x72\xc4\xb0\x4d\xa5\x6d\x6f\x54\x04"] = CTInfo($description="Sectigo 'Sabre2025h1'", $operator="Sectigo", $url="https://sabre2025h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7e\x2f\x39\xf1\xe8\x23\x8e\xb3\x32\x04\xaf\x4d\x57\xf6\xdb\xc5\x74\xa4\x7a\x6d\x3b\x07\x51\x0c\x5a\xfb\x80\x30\x05\xc6\x5a\x0c\xc4\x76\xd6\x06\xa8\x57\x4d\xfb\xdf\xe4\x82\x90\xc2\x41\xae\x70\xb3\x31\xa2\xe3\xfa\x3d\x5f\x2c\x5d\x04\xcd\xb4\x9d\x55\xab\x41"),
|
["\xe0\x92\xb3\xfc\x0c\x1d\xc8\xe7\x68\x36\x1f\xde\x61\xb9\x96\x4d\x0a\x52\x78\x19\x8a\x72\xd6\x72\xc4\xb0\x4d\xa5\x6d\x6f\x54\x04"] = CTInfo($description="Sectigo 'Sabre2025h1'", $operator="Sectigo", $url="https://sabre2025h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7e\x2f\x39\xf1\xe8\x23\x8e\xb3\x32\x04\xaf\x4d\x57\xf6\xdb\xc5\x74\xa4\x7a\x6d\x3b\x07\x51\x0c\x5a\xfb\x80\x30\x05\xc6\x5a\x0c\xc4\x76\xd6\x06\xa8\x57\x4d\xfb\xdf\xe4\x82\x90\xc2\x41\xae\x70\xb3\x31\xa2\xe3\xfa\x3d\x5f\x2c\x5d\x04\xcd\xb4\x9d\x55\xab\x41"),
|
||||||
["\x1a\x04\xff\x49\xd0\x54\x1d\x40\xaf\xf6\xa0\xc3\xbf\xf1\xd8\xc4\x67\x2f\x4e\xec\xee\x23\x40\x68\x98\x6b\x17\x40\x2e\xdc\x89\x7d"] = CTInfo($description="Sectigo 'Sabre2025h2'", $operator="Sectigo", $url="https://sabre2025h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x13\x11\x2d\x7b\xf3\x93\x81\xe4\xb9\x7c\xd9\x64\x3b\xe7\xb5\x83\x99\x66\x79\x59\x47\x6a\x42\x5e\xd6\xbd\x63\x2e\xb7\x91\x4b\xae\xbc\x56\xc4\xc5\x6e\x09\xa0\xd7\x64\x1a\xc8\xc1\xaf\x89\x8b\xf5\x58\xd8\xba\xeb\x7b\x83\x52\xe9\xf4\xe0\xa5\xcd\xcd\x92\xcc"),
|
["\x1a\x04\xff\x49\xd0\x54\x1d\x40\xaf\xf6\xa0\xc3\xbf\xf1\xd8\xc4\x67\x2f\x4e\xec\xee\x23\x40\x68\x98\x6b\x17\x40\x2e\xdc\x89\x7d"] = CTInfo($description="Sectigo 'Sabre2025h2'", $operator="Sectigo", $url="https://sabre2025h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x13\x11\x2d\x7b\xf3\x93\x81\xe4\xb9\x7c\xd9\x64\x3b\xe7\xb5\x83\x99\x66\x79\x59\x47\x6a\x42\x5e\xd6\xbd\x63\x2e\xb7\x91\x4b\xae\xbc\x56\xc4\xc5\x6e\x09\xa0\xd7\x64\x1a\xc8\xc1\xaf\x89\x8b\xf5\x58\xd8\xba\xeb\x7b\x83\x52\xe9\xf4\xe0\xa5\xcd\xcd\x92\xcc"),
|
||||||
["\x29\xd0\x3a\x1b\xb6\x74\xaa\x71\x1c\xd3\x03\x5b\x65\x57\xc1\x4f\x8a\xa7\x8b\x4f\xe8\x38\x94\x49\xec\xa4\x53\xf9\x44\xbd\x24\x68"] = CTInfo($description="Sectigo 'Mammoth2024h1'", $operator="Sectigo", $url="https://mammoth2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa4\x59\x90\xf3\x71\x24\x24\xf7\xc3\x55\x27\x56\x9c\xa3\x59\x1e\xf7\xb7\x9f\xce\xab\x4e\x19\x66\x4d\xd0\x8a\xfa\x9d\x62\xa4\x24\xf0\x3b\x20\xe4\x1d\x14\x67\xc8\xfc\xe4\x37\xf2\x4b\x38\x54\x5a\xcf\x9f\x6b\x07\x90\xd0\x0e\x7e\x3d\x4c\x87\xb2\xe8\x3f\x07\xcc"),
|
|
||||||
["\x50\x85\x01\x58\xdc\xb6\x05\x95\xc0\x0e\x92\xa8\x11\x02\xec\xcd\xfe\x3f\x6b\x78\x58\x42\x9f\x57\x98\x35\x38\xc9\xda\x52\x50\x63"] = CTInfo($description="Sectigo 'Mammoth2024h1b'", $operator="Sectigo", $url="https://mammoth2024h1b.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\xd5\x07\x28\x7a\x04\x34\xae\xca\xbe\x80\x79\x4f\x3e\xf6\x41\xf4\x24\x04\xe1\xd6\x36\x5a\x1a\x09\xf2\xd1\xba\x84\x17\xae\x1e\xa1\x7c\x00\x1d\x54\x73\x90\x75\x21\xa8\xd1\xda\x5e\x10\xe1\x8c\xec\xb2\x8a\x8c\xc8\xe7\xdd\xcd\xe2\x07\xf0\x4e\x16\x02\x57\x37"),
|
|
||||||
["\xdf\xe1\x56\xeb\xaa\x05\xaf\xb5\x9c\x0f\x86\x71\x8d\xa8\xc0\x32\x4e\xae\x56\xd9\x6e\xa7\xf5\xa5\x6a\x01\xd1\xc1\x3b\xbe\x52\x5c"] = CTInfo($description="Sectigo 'Mammoth2024h2'", $operator="Sectigo", $url="https://mammoth2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x66\x22\x24\x6e\xbe\x52\x62\x0a\xa0\xaf\xc3\x25\x1a\x36\x2e\xa7\x60\x89\xa2\x65\xbf\xa4\x5f\xbd\x85\x6a\x94\x05\x81\x35\x90\x54\x31\x95\xe7\x11\x9e\xa3\x2e\x0f\x85\xef\xa7\x88\x57\x8b\x63\x1a\x81\xc1\x41\x9d\x7d\xec\x01\x3a\xdb\xb9\xc1\x27\xf4\x65\x1e"),
|
|
||||||
["\x13\x4a\xdf\x1a\xb5\x98\x42\x09\x78\x0c\x6f\xef\x4c\x7a\x91\xa4\x16\xb7\x23\x49\xce\x58\x57\x6a\xdf\xae\xda\xa7\xc2\xab\xe0\x22"] = CTInfo($description="Sectigo 'Mammoth2025h1'", $operator="Sectigo", $url="https://mammoth2025h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x13\x3c\x41\xb5\x30\x7d\x2e\x4a\xa1\xa8\x6b\xd2\xc5\x57\x6b\x98\xfe\x7e\xef\xd5\x21\xe2\xba\x5d\xb0\xba\x85\x11\x6e\x94\xe0\x3d\xa8\x8e\x6d\x56\x8d\x44\x02\x9e\xb0\x83\xcc\x54\xdf\x9b\x4e\x72\x62\x4b\x3c\x0c\x32\xdd\x86\xfb\xeb\x3e\x66\xcd\x77\x58\x5b\xe5"),
|
["\x13\x4a\xdf\x1a\xb5\x98\x42\x09\x78\x0c\x6f\xef\x4c\x7a\x91\xa4\x16\xb7\x23\x49\xce\x58\x57\x6a\xdf\xae\xda\xa7\xc2\xab\xe0\x22"] = CTInfo($description="Sectigo 'Mammoth2025h1'", $operator="Sectigo", $url="https://mammoth2025h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x13\x3c\x41\xb5\x30\x7d\x2e\x4a\xa1\xa8\x6b\xd2\xc5\x57\x6b\x98\xfe\x7e\xef\xd5\x21\xe2\xba\x5d\xb0\xba\x85\x11\x6e\x94\xe0\x3d\xa8\x8e\x6d\x56\x8d\x44\x02\x9e\xb0\x83\xcc\x54\xdf\x9b\x4e\x72\x62\x4b\x3c\x0c\x32\xdd\x86\xfb\xeb\x3e\x66\xcd\x77\x58\x5b\xe5"),
|
||||||
["\xaf\x18\x1a\x28\xd6\x8c\xa3\xe0\xa9\x8a\x4c\x9c\x67\xab\x09\xf8\xbb\xbc\x22\xba\xae\xbc\xb1\x38\xa3\xa1\x9d\xd3\xf9\xb6\x03\x0d"] = CTInfo($description="Sectigo 'Mammoth2025h2'", $operator="Sectigo", $url="https://mammoth2025h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x88\xe2\xc7\xb3\xd7\x37\xa3\x91\xd7\xb3\xc5\xda\x07\x51\x04\x2b\x81\xed\xc2\x44\x3b\x75\xa0\xe6\x65\xe1\x4a\xba\x1b\xb1\x9c\xa9\x2a\x84\x31\x29\xae\x1d\x8b\xf1\x33\x9f\x12\x2e\x90\xb1\x15\x67\x66\xa0\x7c\x0b\x5b\x62\x7f\x6c\x9a\x6a\x30\x9b\x68\x02\x16\x6f"),
|
["\xaf\x18\x1a\x28\xd6\x8c\xa3\xe0\xa9\x8a\x4c\x9c\x67\xab\x09\xf8\xbb\xbc\x22\xba\xae\xbc\xb1\x38\xa3\xa1\x9d\xd3\xf9\xb6\x03\x0d"] = CTInfo($description="Sectigo 'Mammoth2025h2'", $operator="Sectigo", $url="https://mammoth2025h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x88\xe2\xc7\xb3\xd7\x37\xa3\x91\xd7\xb3\xc5\xda\x07\x51\x04\x2b\x81\xed\xc2\x44\x3b\x75\xa0\xe6\x65\xe1\x4a\xba\x1b\xb1\x9c\xa9\x2a\x84\x31\x29\xae\x1d\x8b\xf1\x33\x9f\x12\x2e\x90\xb1\x15\x67\x66\xa0\x7c\x0b\x5b\x62\x7f\x6c\x9a\x6a\x30\x9b\x68\x02\x16\x6f"),
|
||||||
["\x3b\x53\x77\x75\x3e\x2d\xb9\x80\x4e\x8b\x30\x5b\x06\xfe\x40\x3b\x67\xd8\x4f\xc3\xf4\xc7\xbd\x00\x0d\x2d\x72\x6f\xe1\xfa\xd4\x17"] = CTInfo($description="Let's Encrypt 'Oak2024H1' log", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x56\x43\xd7\x7e\x7b\xd4\x72\xb7\xba\xa9\x51\xbd\x36\x93\xb7\xe9\xb5\x92\x0f\xea\x5e\xb7\x45\xa3\x92\xfd\xc9\xa5\x3c\x80\xac\x1a\x20\xef\x25\x2f\xb8\xe1\x20\xf7\xa8\x3a\x2e\x07\x8d\xe6\xeb\xa4\xe2\x7d\x24\x63\x9f\x46\xbf\x94\x73\x52\x8d\x96\xae\xa9\x26\xfd"),
|
["\x25\x2f\x94\xc2\x2b\x29\xe9\x6e\x9f\x41\x1a\x72\x07\x2b\x69\x5c\x5b\x52\xff\x97\xa9\x0d\x25\x40\xbb\xfc\xdc\x51\xec\x4d\xee\x0b"] = CTInfo($description="Sectigo 'Mammoth2026h1'", $operator="Sectigo", $url="https://mammoth2026h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x9e\xcb\x0c\x8a\x51\xcc\x8a\xe2\x0b\xce\x85\xe6\xaf\x4d\x31\xdb\x1b\x6a\x4c\xfd\xb0\x79\x6b\x99\x97\xc0\x5d\xfb\x6e\x45\x50\x1d\x62\xaa\xc6\x9f\x9b\x6b\x05\x3d\xa2\xab\x2b\x5d\x88\x9b\x50\x28\xe2\x9e\x58\xa5\xa5\xfa\xf9\xe3\xfa\x15\x25\xe3\x14\x13\x32\xc4"),
|
||||||
["\x3f\x17\x4b\x4f\xd7\x22\x47\x58\x94\x1d\x65\x1c\x84\xbe\x0d\x12\xed\x90\x37\x7f\x1f\x85\x6a\xeb\xc1\xbf\x28\x85\xec\xf8\x64\x6e"] = CTInfo($description="Let's Encrypt 'Oak2024H2' log", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\x73\xd6\x53\x47\xe9\xf3\xc9\xd5\x7c\x16\xc2\xd6\x8f\x70\x65\xfa\xf2\x51\x36\xa9\x13\x80\x2f\xed\xf9\x94\xd3\x5a\x8b\xe8\x4f\x33\xcf\xc3\xd3\x89\xd4\x5f\x5a\x66\x89\xba\x20\x1f\x71\xcb\xca\xbb\x9f\x9f\xf3\x5c\x2d\x1e\xa3\x81\x59\xaf\x92\xb3\x6d\x30\x68"),
|
["\x94\xb1\xc1\x8a\xb0\xd0\x57\xc4\x7b\xe0\xac\x04\x0e\x1f\x2c\xbc\x8d\xc3\x75\x72\x7b\xc9\x51\xf2\x0a\x52\x61\x26\x86\x3b\xa7\x3c"] = CTInfo($description="Sectigo 'Mammoth2026h2'", $operator="Sectigo", $url="https://mammoth2026h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xec\x83\x61\xf2\xd7\xb4\xbb\xe4\xe4\x3b\xeb\xc8\x63\x75\x98\xcf\x61\x90\x63\x14\x3d\x5f\x22\xdf\x74\xba\x50\xa7\x58\x9b\x69\x7d\xe6\x63\x89\x6d\xd9\xd7\x51\x84\x3f\xf8\x02\xd8\xc8\xff\xc2\x97\x71\xe5\x7e\x27\xf5\x72\xb1\x8f\x24\x27\x57\x0a\x0d\x74\xc0\xb6"),
|
||||||
|
["\x56\x6c\xd5\xa3\x76\xbe\x83\xdf\xe3\x42\xb6\x75\xc4\x9c\x23\x24\x98\xa7\x69\xba\xc3\x82\xcb\xab\x49\xa3\x87\x7d\x9a\xb3\x2d\x01"] = CTInfo($description="Sectigo 'Sabre2026h1'", $operator="Sectigo", $url="https://sabre2026h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x84\x26\xbc\x36\xbd\xd8\x8d\x3c\x87\x9e\xe0\x10\xaf\xcd\x94\xd9\xd7\xb9\x51\x80\x34\x7e\xf7\x58\x5c\x73\xea\xeb\x09\x93\xb8\x10\x7b\x90\x9c\x7d\xc7\xcd\x96\x43\xed\x53\x6e\x95\x21\x46\x67\x51\xf0\xde\xb6\xc9\x9e\xaa\xe2\x80\x6d\xce\x25\x81\x34\xd7\x6a\x60"),
|
||||||
|
["\x1f\x56\xd1\xab\x94\x70\x4a\x41\xdd\x3f\xea\xfd\xf4\x69\x93\x55\x30\x2c\x14\x31\xbf\xe6\x13\x46\x08\x9f\xff\xae\x79\x5d\xcc\x2f"] = CTInfo($description="Sectigo 'Sabre2026h2'", $operator="Sectigo", $url="https://sabre2026h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xce\x35\xca\xec\x39\x07\x82\xda\x77\x27\x86\xe4\xf2\x7e\xc5\xdc\x38\xf2\x9b\xa9\xab\x8c\xa7\xc0\xed\x83\x1e\x3e\x6a\x1b\xc0\xf0\x95\x56\xba\x32\x33\x4c\x75\x7c\x09\x07\xe9\xe1\x3e\x65\x35\x63\xf0\x49\xbe\x72\xd1\xaa\x9d\xaf\x7d\x08\xc4\xb4\x8d\x59\x3d\x73"),
|
||||||
["\xa2\xe3\x0a\xe4\x45\xef\xbd\xad\x9b\x7e\x38\xed\x47\x67\x77\x53\xd7\x82\x5b\x84\x94\xd7\x2b\x5e\x1b\x2c\xc4\xb9\x50\xa4\x47\xe7"] = CTInfo($description="Let's Encrypt 'Oak2025h1'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x29\xe0\x69\x53\xd7\xa3\x9c\x26\x88\x65\xe5\xf7\xf4\x4b\x1d\x17\x9b\xc3\xbd\xff\x04\x2d\x31\xdd\x2c\xfc\x62\x92\x5e\x32\xe0\x48\x91\x38\x84\x1f\x4b\x87\xab\x72\x99\xcc\x1d\xf8\x7c\xf9\x3c\x58\x54\x5b\x37\x10\xb1\xab\xd8\x83\xfb\x84\xf1\x95\x3f\x2e\x2f\x1c"),
|
["\xa2\xe3\x0a\xe4\x45\xef\xbd\xad\x9b\x7e\x38\xed\x47\x67\x77\x53\xd7\x82\x5b\x84\x94\xd7\x2b\x5e\x1b\x2c\xc4\xb9\x50\xa4\x47\xe7"] = CTInfo($description="Let's Encrypt 'Oak2025h1'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x29\xe0\x69\x53\xd7\xa3\x9c\x26\x88\x65\xe5\xf7\xf4\x4b\x1d\x17\x9b\xc3\xbd\xff\x04\x2d\x31\xdd\x2c\xfc\x62\x92\x5e\x32\xe0\x48\x91\x38\x84\x1f\x4b\x87\xab\x72\x99\xcc\x1d\xf8\x7c\xf9\x3c\x58\x54\x5b\x37\x10\xb1\xab\xd8\x83\xfb\x84\xf1\x95\x3f\x2e\x2f\x1c"),
|
||||||
["\x0d\xe1\xf2\x30\x2b\xd3\x0d\xc1\x40\x62\x12\x09\xea\x55\x2e\xfc\x47\x74\x7c\xb1\xd7\xe9\x30\xef\x0e\x42\x1e\xb4\x7e\x4e\xaa\x34"] = CTInfo($description="Let's Encrypt 'Oak2025h2'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb5\x76\x30\x07\xad\xc6\xc8\xd2\xe4\x4b\xd2\xf5\xbe\xa2\x8d\x9c\xfd\x74\xfa\x3a\xd6\xfa\x59\x5d\xb6\x1c\x60\xd3\xdd\x1f\x63\x87\x86\xe3\x45\xe0\xd5\x1b\xc0\x35\x6a\xab\x27\x91\x95\xc9\xd7\x3d\xbb\xc1\xf7\x71\x86\x69\xf4\xb3\x5f\x90\x09\xaa\xae\xbd\x8d\xa9"),
|
["\x0d\xe1\xf2\x30\x2b\xd3\x0d\xc1\x40\x62\x12\x09\xea\x55\x2e\xfc\x47\x74\x7c\xb1\xd7\xe9\x30\xef\x0e\x42\x1e\xb4\x7e\x4e\xaa\x34"] = CTInfo($description="Let's Encrypt 'Oak2025h2'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb5\x76\x30\x07\xad\xc6\xc8\xd2\xe4\x4b\xd2\xf5\xbe\xa2\x8d\x9c\xfd\x74\xfa\x3a\xd6\xfa\x59\x5d\xb6\x1c\x60\xd3\xdd\x1f\x63\x87\x86\xe3\x45\xe0\xd5\x1b\xc0\x35\x6a\xab\x27\x91\x95\xc9\xd7\x3d\xbb\xc1\xf7\x71\x86\x69\xf4\xb3\x5f\x90\x09\xaa\xae\xbd\x8d\xa9"),
|
||||||
["\x87\x4f\xb5\x0d\xc0\x29\xd9\x93\x1d\xe5\x73\xe9\xf2\x89\x9e\x8e\x45\x33\xb3\x92\xd3\x8b\x0a\x46\x25\x74\xbf\x0f\xee\xb2\xfc\x1e"] = CTInfo($description="Trust Asia Log2024-2", $operator="TrustAsia", $url="https://ct2024.trustasia.com/log2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x64\xe2\x79\x81\x3f\x61\xd7\xec\xc6\xf8\x65\x28\x1d\xa0\xb4\x66\x33\xc3\x25\xd5\x0a\x95\x78\x9c\x8f\xfe\xa4\x2a\xd8\x8f\x7e\x72\xe0\xfe\xa8\x7f\xf8\xb1\x2d\x85\xc0\x8e\x12\x74\x0d\x2f\x8c\xab\xd7\x7f\x7a\x1e\xd9\x84\x33\x39\xe8\xfd\x89\x5f\x96\x48\x08"),
|
["\x19\x86\xd4\xc7\x28\xaa\x6f\xfe\xba\x03\x6f\x78\x2a\x4d\x01\x91\xaa\xce\x2d\x72\x31\x0f\xae\xce\x5d\x70\x41\x2d\x25\x4c\xc7\xd4"] = CTInfo($description="Let's Encrypt 'Oak2026h1'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x99\xd4\x61\x70\x22\xfa\x77\x93\x0d\xb3\xc7\x80\x96\x22\x51\xbf\x25\x79\xb1\x01\x42\xe9\x41\x7b\x8b\x0c\xc7\xb2\x65\x5a\x89\xf4\xfa\xe2\x02\x46\xd4\x8a\xc7\xcc\x10\x07\x11\x27\x45\x48\x90\x23\x40\xde\x7a\x4d\x89\x32\xfb\xd7\x0a\xeb\x5e\x8c\xa2\xf1\xf6\x49"),
|
||||||
|
["\xac\xab\x30\x70\x6c\xeb\xec\x84\x31\xf4\x13\xd2\xf4\x91\x5f\x11\x1e\x42\x24\x43\xb1\xf2\xa6\x8c\x4f\x3c\x2b\x3b\xa7\x1e\x02\xc3"] = CTInfo($description="Let's Encrypt 'Oak2026h2'", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6a\x70\x9d\xb3\x96\xe3\xec\x85\x36\x95\xc3\x4f\x9c\x8b\xd9\x7c\xc9\xd5\x91\x29\xae\xeb\xd6\x87\xdc\x04\xbc\x3b\xf6\x34\x0f\xf6\xdb\x08\xf7\x52\xa9\x88\xef\xbb\x3f\x59\xd6\xd4\xf6\xf4\xfc\x5c\xa9\x8c\x5f\xfb\x0d\x60\xe4\x2c\x0f\x16\xec\x2a\xb2\x6d\xeb\x15"),
|
||||||
["\x28\xe2\x81\x38\xfd\x83\x21\x45\xe9\xa9\xd6\xaa\x75\x37\x6d\x83\x77\xa8\x85\x12\xb3\xc0\x7f\x72\x41\x48\x21\xdc\xbd\xe9\x8c\x66"] = CTInfo($description="TrustAsia Log2025a", $operator="TrustAsia", $url="https://ct2025-a.trustasia.com/log2025a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x70\xe5\xb1\xa4\x09\x79\x2b\x9d\xf8\xa3\xa0\xdf\x18\xef\x95\x5d\x03\x6c\x7b\xa1\x91\xa9\xb8\x80\x7d\xec\x5c\x02\x08\xe2\x6e\x2f\x7c\x32\x70\xbd\x96\x84\x5f\xa6\x62\xe9\x65\xb5\x7c\x90\x58\xba\x22\xd5\xf9\xf5\x69\x54\xb7\xa8\x94\x4e\x32\x09\xae\x26\x11\x4d"),
|
["\x28\xe2\x81\x38\xfd\x83\x21\x45\xe9\xa9\xd6\xaa\x75\x37\x6d\x83\x77\xa8\x85\x12\xb3\xc0\x7f\x72\x41\x48\x21\xdc\xbd\xe9\x8c\x66"] = CTInfo($description="TrustAsia Log2025a", $operator="TrustAsia", $url="https://ct2025-a.trustasia.com/log2025a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x70\xe5\xb1\xa4\x09\x79\x2b\x9d\xf8\xa3\xa0\xdf\x18\xef\x95\x5d\x03\x6c\x7b\xa1\x91\xa9\xb8\x80\x7d\xec\x5c\x02\x08\xe2\x6e\x2f\x7c\x32\x70\xbd\x96\x84\x5f\xa6\x62\xe9\x65\xb5\x7c\x90\x58\xba\x22\xd5\xf9\xf5\x69\x54\xb7\xa8\x94\x4e\x32\x09\xae\x26\x11\x4d"),
|
||||||
["\x28\x2c\x8b\xdd\x81\x0f\xf9\x09\x12\x0a\xce\x16\xd6\xe0\xec\x20\x1b\xea\x82\xa3\xa4\xaf\x19\xd9\xef\xfb\x59\xe8\x3f\xdc\x42\x68"] = CTInfo($description="TrustAsia Log2025b", $operator="TrustAsia", $url="https://ct2025-b.trustasia.com/log2025b/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaa\xa0\x8b\xdb\x67\x14\x5d\x97\x89\x1d\x08\x8d\x06\xd7\xc1\x94\x8e\xb0\xfa\x4c\x46\xd5\x53\x08\x78\x2b\x04\x53\x6c\xf3\xde\xb1\xd1\x53\x40\xda\x90\x57\xe6\x1a\x9e\x3c\xc7\x03\xb8\xbd\x2f\xa9\xcf\xe8\x7b\x5e\xe1\x4b\x60\xe5\x38\x43\x60\x97\xc1\x5b\x2f\x65"),
|
["\x28\x2c\x8b\xdd\x81\x0f\xf9\x09\x12\x0a\xce\x16\xd6\xe0\xec\x20\x1b\xea\x82\xa3\xa4\xaf\x19\xd9\xef\xfb\x59\xe8\x3f\xdc\x42\x68"] = CTInfo($description="TrustAsia Log2025b", $operator="TrustAsia", $url="https://ct2025-b.trustasia.com/log2025b/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaa\xa0\x8b\xdb\x67\x14\x5d\x97\x89\x1d\x08\x8d\x06\xd7\xc1\x94\x8e\xb0\xfa\x4c\x46\xd5\x53\x08\x78\x2b\x04\x53\x6c\xf3\xde\xb1\xd1\x53\x40\xda\x90\x57\xe6\x1a\x9e\x3c\xc7\x03\xb8\xbd\x2f\xa9\xcf\xe8\x7b\x5e\xe1\x4b\x60\xe5\x38\x43\x60\x97\xc1\x5b\x2f\x65"),
|
||||||
["\x74\xdb\x9d\x58\xf7\xd4\x7e\x9d\xfd\x78\x7a\x16\x2a\x99\x1c\x18\xcf\x69\x8d\xa7\xc7\x29\x91\x8c\x9a\x18\xb0\x45\x0d\xba\x44\xbc"] = CTInfo($description="TrustAsia 'log2026a'", $operator="TrustAsia", $url="https://ct2026-a.trustasia.com/log2026a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x4e\x7a\xc9\xa6\x07\xf9\xff\x74\xec\x98\xcb\x49\xe1\x00\x24\xb3\x59\x2e\x83\xfd\xc0\x70\x35\x33\x4c\x63\xca\x74\x83\xc0\x3c\x5b\x53\x40\x7c\x31\x1f\x35\xa4\x5f\x0f\xe4\xee\x4f\x89\x17\xe8\x5b\x2e\xc5\xac\x00\x05\xc9\x76\x37\x45\x97\x03\x15\xff\x60\x59"),
|
["\x74\xdb\x9d\x58\xf7\xd4\x7e\x9d\xfd\x78\x7a\x16\x2a\x99\x1c\x18\xcf\x69\x8d\xa7\xc7\x29\x91\x8c\x9a\x18\xb0\x45\x0d\xba\x44\xbc"] = CTInfo($description="TrustAsia 'log2026a'", $operator="TrustAsia", $url="https://ct2026-a.trustasia.com/log2026a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x4e\x7a\xc9\xa6\x07\xf9\xff\x74\xec\x98\xcb\x49\xe1\x00\x24\xb3\x59\x2e\x83\xfd\xc0\x70\x35\x33\x4c\x63\xca\x74\x83\xc0\x3c\x5b\x53\x40\x7c\x31\x1f\x35\xa4\x5f\x0f\xe4\xee\x4f\x89\x17\xe8\x5b\x2e\xc5\xac\x00\x05\xc9\x76\x37\x45\x97\x03\x15\xff\x60\x59"),
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@ hook Analyzer::disabling_analyzer(c: connection, atype: AllAnalyzers::Tag, aid:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# Only add if previously confirmed
|
# Only add if previously confirmed
|
||||||
if ( Analyzer::name(atype) !in c$service || Analyzer::name(atype) !in c$service_violation )
|
if ( Analyzer::name(atype) !in c$service && Analyzer::name(atype) !in c$service_violation )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# Only log if dpd.zeek will disable
|
# Only log if dpd.zeek will disable
|
||||||
|
|
|
@ -17,27 +17,104 @@ public function decrypt_crypto_payload(
|
||||||
): bytes &cxxname="QUIC_decrypt_crypto_payload";
|
): bytes &cxxname="QUIC_decrypt_crypto_payload";
|
||||||
|
|
||||||
|
|
||||||
##############
|
|
||||||
## Context - tracked in one connection
|
|
||||||
##############
|
|
||||||
|
|
||||||
# Can we decrypt?
|
# 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 )
|
if ( ! long_header.is_initial )
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
if ( is_client )
|
if ( crypto == Null )
|
||||||
return ! context.client_initial_processed;
|
return False;
|
||||||
|
|
||||||
# This is the responder, can only decrypt if we have an initial
|
# Can only decrypt the responder if we've seen the initial destination conn id.
|
||||||
# destination_id from the client
|
if ( ! crypto.is_orig && ! context.initial_destination_conn_id )
|
||||||
return context.client_initial_processed
|
return False;
|
||||||
&& |context.initial_destination_conn_id| > 0
|
|
||||||
&& ! context.server_initial_processed;
|
# 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<uint32>($$[0]) << 16) + (cast<uint32>($$[1]) << 8) + cast<uint32>($$[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<uint16>(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;
|
client_cid_len: uint8;
|
||||||
server_cid_len: uint8;
|
server_cid_len: uint8;
|
||||||
|
|
||||||
|
@ -46,26 +123,13 @@ type ConnectionIDInfo = struct {
|
||||||
# will make life miserable.
|
# will make life miserable.
|
||||||
#
|
#
|
||||||
# https://quicwg.org/base-drafts/rfc9001.html#appendix-A
|
# https://quicwg.org/base-drafts/rfc9001.html#appendix-A
|
||||||
initial_destination_conn_id: bytes;
|
initial_destination_conn_id: optional<bytes>;
|
||||||
|
|
||||||
# Currently, this analyzer assumes that ClientHello
|
# Track crypto state.
|
||||||
# and ServerHello fit into the first INITIAL packet (and
|
client_crypto: CryptoSinkUnit&;
|
||||||
# that there is only one that we're interested in.
|
client_sink: sink&;
|
||||||
#
|
server_crypto: CryptoSinkUnit&;
|
||||||
# But minimally the following section sounds like this might not
|
server_sink: sink&;
|
||||||
# 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;
|
|
||||||
|
|
||||||
ssl_handle: zeek::ProtocolHandle &optional;
|
ssl_handle: zeek::ProtocolHandle &optional;
|
||||||
};
|
};
|
||||||
|
@ -272,16 +336,28 @@ public type LongHeaderPacket = unit {
|
||||||
};
|
};
|
||||||
|
|
||||||
# A QUIC Frame.
|
# 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<FrameType>($$);
|
frame_type : uint8 &convert=cast<FrameType>($$);
|
||||||
|
|
||||||
# TODO: add other FrameTypes as well
|
# TODO: add other FrameTypes as well
|
||||||
switch ( self.frame_type ) {
|
switch ( self.frame_type ) {
|
||||||
FrameType::ACK1 -> a: ACKPayload;
|
FrameType::ACK1 -> a: ACKPayload(FrameType::ACK1);
|
||||||
FrameType::ACK2 -> b: ACKPayload;
|
FrameType::ACK2 -> b: ACKPayload(FrameType::ACK2);
|
||||||
FrameType::CRYPTO -> c: CRYPTOPayload(from_client) {
|
FrameType::CRYPTO -> c: CRYPTOPayload(from_client) {
|
||||||
# Have the sink re-assemble potentially out-of-order cryptodata
|
# Have the sink re-assemble potentially out-of-order cryptodata
|
||||||
crypto_sink.write(self.c.cryptodata, self.c.offset.result_);
|
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::CONNECTION_CLOSE1 -> : ConnectionClosePayload(header);
|
||||||
FrameType::PADDING -> : skip /\x00*/; # eat the padding
|
FrameType::PADDING -> : skip /\x00*/; # eat the padding
|
||||||
|
@ -298,11 +374,26 @@ type CRYPTOPayload = unit(from_client: bool) {
|
||||||
cryptodata: bytes &size=self.length.result_;
|
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;
|
latest_ack: VariableLengthInteger;
|
||||||
ack_delay: VariableLengthInteger;
|
ack_delay: VariableLengthInteger;
|
||||||
ack_range_count: VariableLengthInteger;
|
ack_range_count: VariableLengthInteger;
|
||||||
first_ack_range: 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) {
|
type ConnectionClosePayload = unit(header: LongHeaderPacket) {
|
||||||
|
@ -393,35 +484,18 @@ public type ShortPacketPayload = unit {
|
||||||
payload: skip bytes &eod;
|
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
|
# QUIC packet parsing
|
||||||
#
|
#
|
||||||
# A UDP datagram contains one or more QUIC packets.
|
# 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 decrypted_data: bytes;
|
||||||
var packet_size: uint64 = 0;
|
var packet_size: uint64 = 0;
|
||||||
var start: iterator<stream>;
|
var start: iterator<stream>;
|
||||||
|
|
||||||
sink crypto_sink;
|
var crypto: CryptoSinkUnit&;
|
||||||
var crypto_buffer: CryptoBuffer&;
|
var crypto_sink: sink&;
|
||||||
|
|
||||||
# Attach an SSL analyzer to this connection once.
|
# Attach an SSL analyzer to this connection once.
|
||||||
on %init {
|
on %init {
|
||||||
|
@ -430,6 +504,26 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.start = self.input();
|
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.
|
# 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
|
self.set_input(self.start); # rewind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Depending on the header, parse it and update the src/dest ConnectionID's
|
# Depending on the header, parse it and update the src/dest ConnectionID's
|
||||||
switch ( self.first_byte.header_form ) {
|
switch ( self.first_byte.header_form ) {
|
||||||
HeaderForm::SHORT -> short_header: ShortHeader(context.client_cid_len);
|
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
|
# 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.
|
# context such that the next DCID from the client is used for decryption.
|
||||||
if ( self.long_header.is_retry ) {
|
if ( self.long_header.is_retry ) {
|
||||||
context.client_initial_processed = False;
|
reset_crypto(context);
|
||||||
context.server_initial_processed = False;
|
|
||||||
context.initial_destination_conn_id = b"";
|
|
||||||
|
|
||||||
# Allow re-opening the SSL analyzer the next time around.
|
self.crypto = Null;
|
||||||
zeek::protocol_handle_close(context.ssl_handle);
|
self.crypto_sink = Null;
|
||||||
unset context.ssl_handle;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
: void {
|
: 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,
|
# If we have parsed an initial packet that we can decrypt the payload,
|
||||||
# determine the size to store into a buffer.
|
# determine the size to store into a buffer.
|
||||||
self.packet_size = self.offset();
|
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.
|
# 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 ) {
|
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 ) {
|
if ( from_client ) {
|
||||||
context.server_cid_len = self.long_header.dest_conn_id_len;
|
context.server_cid_len = self.long_header.dest_conn_id_len;
|
||||||
context.client_cid_len = self.long_header.src_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!
|
# This means that here, we can try to decrypt the initial packet!
|
||||||
# All data is accessible via the `long_header` unit
|
# All data is accessible via the `long_header` unit
|
||||||
self.decrypted_data = decrypt_crypto_payload(
|
self.decrypted_data = decrypt_crypto_payload(
|
||||||
self.long_header.version,
|
self.long_header.version,
|
||||||
self.packet_data,
|
self.packet_data,
|
||||||
self.long_header.dest_conn_id,
|
*context.initial_destination_conn_id,
|
||||||
self.long_header.encrypted_offset,
|
self.long_header.encrypted_offset,
|
||||||
self.long_header.payload_length,
|
self.long_header.payload_length,
|
||||||
from_client
|
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 {
|
} else {
|
||||||
context.server_cid_len = self.long_header.src_conn_id_len;
|
context.server_cid_len = self.long_header.src_conn_id_len;
|
||||||
context.client_cid_len = self.long_header.dest_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.decrypted_data = decrypt_crypto_payload(
|
||||||
self.long_header.version,
|
self.long_header.version,
|
||||||
self.packet_data,
|
self.packet_data,
|
||||||
context.initial_destination_conn_id,
|
*context.initial_destination_conn_id,
|
||||||
self.long_header.encrypted_offset,
|
self.long_header.encrypted_offset,
|
||||||
self.long_header.payload_length,
|
self.long_header.payload_length,
|
||||||
from_client
|
from_client
|
||||||
|
@ -521,51 +610,24 @@ type Packet = unit(from_client: bool, context: ConnectionIDInfo&) {
|
||||||
spicy::accept_input();
|
spicy::accept_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Depending on the type of header and whether we were able to decrypt
|
# If this packet has a SHORT header, consume until &eod, there's nothing
|
||||||
# some of it, parse the remaining payload.
|
# we can do with it anyhow.
|
||||||
: ShortPacketPayload if (self.first_byte.header_form == HeaderForm::SHORT);
|
: 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
|
# If this was packet with a long header and decrypted data exists, attempt
|
||||||
# to parse the plain QUIC frames from it.
|
# 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);
|
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);
|
||||||
|
|
||||||
# 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<uint16>(|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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
##############
|
##############
|
||||||
# Entrypoints
|
# Entrypoints
|
||||||
##############
|
##############
|
||||||
public type RequestFrame = unit {
|
public type RequestFrame = unit {
|
||||||
%context = ConnectionIDInfo;
|
%context = Context;
|
||||||
: Packet(True, self.context())[];
|
: Packet(True, self.context())[];
|
||||||
};
|
};
|
||||||
|
|
||||||
public type ResponseFrame = unit {
|
public type ResponseFrame = unit {
|
||||||
%context = ConnectionIDInfo;
|
%context = Context;
|
||||||
: Packet(False, self.context())[];
|
: Packet(False, self.context())[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -841,8 +841,10 @@ std::optional<broker::data> val_to_data(const Val* v) {
|
||||||
for ( auto i = 0u; i < vec->Size(); ++i ) {
|
for ( auto i = 0u; i < vec->Size(); ++i ) {
|
||||||
auto item_val = vec->ValAt(i);
|
auto item_val = vec->ValAt(i);
|
||||||
|
|
||||||
if ( ! item_val )
|
if ( ! item_val ) {
|
||||||
continue;
|
reporter->Error("serialization of vectors with holes is unsupported");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
auto item = val_to_data(item_val.get());
|
auto item = val_to_data(item_val.get());
|
||||||
|
|
||||||
|
@ -864,8 +866,10 @@ std::optional<broker::data> val_to_data(const Val* v) {
|
||||||
for ( auto i = 0; i < list->Length(); ++i ) {
|
for ( auto i = 0; i < list->Length(); ++i ) {
|
||||||
const auto& item_val = list->Idx(i);
|
const auto& item_val = list->Idx(i);
|
||||||
|
|
||||||
if ( ! item_val )
|
if ( ! item_val ) {
|
||||||
continue;
|
reporter->Error("serialization of lists with holes is unsupported");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
auto item = val_to_data(item_val.get());
|
auto item = val_to_data(item_val.get());
|
||||||
|
|
||||||
|
|
|
@ -587,7 +587,7 @@ void Manager::DoInitPostScript() {
|
||||||
checkLogSeverity(stderrSeverityVal);
|
checkLogSeverity(stderrSeverityVal);
|
||||||
auto adapterVerbosity = static_cast<BrokerSeverityLevel>(std::max(logSeverityVal, stderrSeverityVal));
|
auto adapterVerbosity = static_cast<BrokerSeverityLevel>(std::max(logSeverityVal, stderrSeverityVal));
|
||||||
auto queue = std::make_shared<LoggerQueue>();
|
auto queue = std::make_shared<LoggerQueue>();
|
||||||
auto pbstate = std::make_shared<PeerBufferState>(options.peer_buffer_size,
|
auto pbstate = std::make_shared<PeerBufferState>(get_option("Broker::peer_buffer_size")->AsCount(),
|
||||||
get_option("Broker::buffer_stats_reset_interval")->AsDouble());
|
get_option("Broker::buffer_stats_reset_interval")->AsDouble());
|
||||||
auto observer = std::make_shared<Observer>(adapterVerbosity, queue, pbstate);
|
auto observer = std::make_shared<Observer>(adapterVerbosity, queue, pbstate);
|
||||||
broker::logger(observer); // *must* be called before creating the BrokerState
|
broker::logger(observer); // *must* be called before creating the BrokerState
|
||||||
|
@ -2086,8 +2086,10 @@ detail::StoreHandleVal* Manager::MakeClone(const string& name, double resync_int
|
||||||
auto handle = new detail::StoreHandleVal{*result};
|
auto handle = new detail::StoreHandleVal{*result};
|
||||||
Ref(handle);
|
Ref(handle);
|
||||||
|
|
||||||
if ( ! handle->proxy.valid() )
|
if ( ! handle->proxy.valid() ) {
|
||||||
reporter->FatalError("Failed to create clone for data store %s", name.c_str());
|
reporter->Error("Failed to create clone for data store %s", name.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
data_stores.emplace(name, handle);
|
data_stores.emplace(name, handle);
|
||||||
if ( ! iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this) )
|
if ( ! iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this) )
|
||||||
|
|
|
@ -88,7 +88,10 @@ bool WebSocketShim::DoInit() {
|
||||||
state = std::make_unique<WebSocketState>();
|
state = std::make_unique<WebSocketState>();
|
||||||
|
|
||||||
zeek::iosource_mgr->Register(iosrc, false);
|
zeek::iosource_mgr->Register(iosrc, false);
|
||||||
zeek::iosource_mgr->RegisterFd(state->hub.read_fd(), iosrc);
|
if ( ! zeek::iosource_mgr->RegisterFd(state->hub.read_fd(), iosrc) ) {
|
||||||
|
zeek::reporter->Error("Failed to register hub.read_fd() with iosource_mgr");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,19 +81,24 @@ public:
|
||||||
* Close the IO source.
|
* Close the IO source.
|
||||||
*/
|
*/
|
||||||
void Close() {
|
void Close() {
|
||||||
|
if ( std::this_thread::get_id() != main_thread_id ) {
|
||||||
|
fprintf(stderr, "OnLoopProcess::Close() not called by main thread!");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
zeek::iosource_mgr->UnregisterFd(flare.FD(), this);
|
zeek::iosource_mgr->UnregisterFd(flare.FD(), this);
|
||||||
|
|
||||||
|
// Ensure Process() is short-circuited from now on.
|
||||||
|
proc = nullptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Close under lock to guarantee visibility for
|
// Close under lock to guarantee visibility for
|
||||||
// any pending queuers QueueForProcessing() calls.
|
// any pending queuers QueueForProcessing() calls.
|
||||||
std::scoped_lock lock(mtx);
|
std::scoped_lock lock(mtx);
|
||||||
SetClosed(true);
|
SetClosed(true);
|
||||||
|
|
||||||
// Wake a process stuck in queueing.
|
// Wake other threads stuck in queueing, if any.
|
||||||
cond.notify_one();
|
cond.notify_all();
|
||||||
|
|
||||||
// Don't attempt to Process anymore.
|
|
||||||
proc = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for any active queuers to vanish, should be quick.
|
// Wait for any active queuers to vanish, should be quick.
|
||||||
|
|
|
@ -247,6 +247,13 @@ void WebSocketEventDispatcher::Terminate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
clients.clear();
|
clients.clear();
|
||||||
|
|
||||||
|
onloop->Close();
|
||||||
|
|
||||||
|
// Wait for the reply_msg_thread to process any outstanding
|
||||||
|
// WebSocketReply messages before returning.
|
||||||
|
reply_msg_thread->SignalStop();
|
||||||
|
reply_msg_thread->WaitForStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketEventDispatcher::QueueForProcessing(WebSocketEvent&& event) {
|
void WebSocketEventDispatcher::QueueForProcessing(WebSocketEvent&& event) {
|
||||||
|
|
|
@ -92,11 +92,18 @@ TraversalCode GenIDDefs::PreStmt(const Stmt* s) {
|
||||||
st->Traverse(this);
|
st->Traverse(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
// If there's just a single statement then there are no
|
// If there's just a single statement then there are two
|
||||||
// expressions computed subsequent to it that we need to
|
// possibilities. If the statement is atomic (no sub-statements)
|
||||||
// worry about, so just do ordinary traversal.
|
// then given that it's in reduced form, it's not going to have
|
||||||
|
// any expressions that we can leverage. OTOH, if it's compound
|
||||||
|
// (if/for/while/switch) then there's no safe re-using of
|
||||||
|
// expressions within it since they may-or-may-not wind up
|
||||||
|
// being computed. So we should always start a new block.
|
||||||
|
StartConfluenceBlock(s);
|
||||||
|
did_confluence = true;
|
||||||
block->Traverse(this);
|
block->Traverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
if ( did_confluence )
|
if ( did_confluence )
|
||||||
EndConfluenceBlock();
|
EndConfluenceBlock();
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "zeek/storage/backend/redis/Redis.h"
|
#include "zeek/storage/backend/redis/Redis.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "zeek/DebugLogger.h"
|
#include "zeek/DebugLogger.h"
|
||||||
#include "zeek/Func.h"
|
#include "zeek/Func.h"
|
||||||
#include "zeek/RunState.h"
|
#include "zeek/RunState.h"
|
||||||
|
@ -23,18 +25,37 @@ public:
|
||||||
std::string where;
|
std::string where;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for OnConnect events from hiredis.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param status The status of the connection attempt.
|
||||||
|
*/
|
||||||
void redisOnConnect(const redisAsyncContext* ctx, int status) {
|
void redisOnConnect(const redisAsyncContext* ctx, int status) {
|
||||||
auto t = Tracer("connect");
|
auto t = Tracer("connect");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
backend->OnConnect(status);
|
backend->OnConnect(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for OnDisconnect events from hiredis.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param status The status of the disconnection attempt.
|
||||||
|
*/
|
||||||
void redisOnDisconnect(const redisAsyncContext* ctx, int status) {
|
void redisOnDisconnect(const redisAsyncContext* ctx, int status) {
|
||||||
auto t = Tracer("disconnect");
|
auto t = Tracer("disconnect");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
backend->OnDisconnect(status);
|
backend->OnDisconnect(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for SET commands.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
void redisPut(redisAsyncContext* ctx, void* reply, void* privdata) {
|
void redisPut(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
auto t = Tracer("put");
|
auto t = Tracer("put");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
|
@ -42,6 +63,13 @@ void redisPut(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
backend->HandlePutResult(static_cast<redisReply*>(reply), callback);
|
backend->HandlePutResult(static_cast<redisReply*>(reply), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for GET commands.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
void redisGet(redisAsyncContext* ctx, void* reply, void* privdata) {
|
void redisGet(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
auto t = Tracer("get");
|
auto t = Tracer("get");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
|
@ -49,6 +77,13 @@ void redisGet(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
backend->HandleGetResult(static_cast<redisReply*>(reply), callback);
|
backend->HandleGetResult(static_cast<redisReply*>(reply), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for DEL commands.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
void redisErase(redisAsyncContext* ctx, void* reply, void* privdata) {
|
void redisErase(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
auto t = Tracer("erase");
|
auto t = Tracer("erase");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
|
@ -56,8 +91,15 @@ void redisErase(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
backend->HandleEraseResult(static_cast<redisReply*>(reply), callback);
|
backend->HandleEraseResult(static_cast<redisReply*>(reply), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for ZADD commands.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
void redisZADD(redisAsyncContext* ctx, void* reply, void* privdata) {
|
void redisZADD(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
auto t = Tracer("generic");
|
auto t = Tracer("zadd");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
|
|
||||||
// We don't care about the reply from the ZADD, mostly because blocking to poll
|
// We don't care about the reply from the ZADD, mostly because blocking to poll
|
||||||
|
@ -67,12 +109,32 @@ void redisZADD(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for commands where there isn't a specific handler in the Redis class.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
void redisGeneric(redisAsyncContext* ctx, void* reply, void* privdata) {
|
void redisGeneric(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
auto t = Tracer("generic");
|
auto t = Tracer("generic");
|
||||||
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
backend->HandleGeneric(static_cast<redisReply*>(reply));
|
backend->HandleGeneric(static_cast<redisReply*>(reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback handler for ZADD commands.
|
||||||
|
*
|
||||||
|
* @param ctx The async context that called this callback.
|
||||||
|
* @param reply The reply from the server for the command.
|
||||||
|
* @param privdata A pointer to private data passed in the command.
|
||||||
|
*/
|
||||||
|
void redisINFO(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
|
auto t = Tracer("generic");
|
||||||
|
auto backend = static_cast<zeek::storage::backend::redis::Redis*>(ctx->data);
|
||||||
|
backend->HandleInfoResult(static_cast<redisReply*>(reply));
|
||||||
|
}
|
||||||
|
|
||||||
// Because we called redisPollAttach in DoOpen(), privdata here is a
|
// Because we called redisPollAttach in DoOpen(), privdata here is a
|
||||||
// redisPollEvents object. We can go through that object to get the context's
|
// redisPollEvents object. We can go through that object to get the context's
|
||||||
// data, which contains the backend. Because we overrode these callbacks in
|
// data, which contains the backend. Because we overrode these callbacks in
|
||||||
|
@ -83,6 +145,14 @@ void redisGeneric(redisAsyncContext* ctx, void* reply, void* privdata) {
|
||||||
// we're reading a pcap, don't add the file descriptor into iosource_mgr. Manual
|
// we're reading a pcap, don't add the file descriptor into iosource_mgr. Manual
|
||||||
// calls to Poll() during that will handle reading/writing any data, and we
|
// calls to Poll() during that will handle reading/writing any data, and we
|
||||||
// don't want the contention with the main loop.
|
// don't want the contention with the main loop.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from hiredis when a new reader is added to the context. This is called when
|
||||||
|
* data is ready to be read from the context for a command.
|
||||||
|
*
|
||||||
|
* @param privdata Private data passed back to the callback when it fires. We use this to
|
||||||
|
* get access to the redis backend object.
|
||||||
|
*/
|
||||||
void redisAddRead(void* privdata) {
|
void redisAddRead(void* privdata) {
|
||||||
auto t = Tracer("addread");
|
auto t = Tracer("addread");
|
||||||
auto rpe = static_cast<redisPollEvents*>(privdata);
|
auto rpe = static_cast<redisPollEvents*>(privdata);
|
||||||
|
@ -93,6 +163,13 @@ void redisAddRead(void* privdata) {
|
||||||
rpe->reading = 1;
|
rpe->reading = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from hiredis when a new reader is added to the context. This is called when no
|
||||||
|
* more data is ready to be read from the context for a command.
|
||||||
|
*
|
||||||
|
* @param privdata Private data passed back to the callback when it fires. We use this to
|
||||||
|
* get access to the redis backend object.
|
||||||
|
*/
|
||||||
void redisDelRead(void* privdata) {
|
void redisDelRead(void* privdata) {
|
||||||
auto t = Tracer("delread");
|
auto t = Tracer("delread");
|
||||||
auto rpe = static_cast<redisPollEvents*>(privdata);
|
auto rpe = static_cast<redisPollEvents*>(privdata);
|
||||||
|
@ -103,6 +180,13 @@ void redisDelRead(void* privdata) {
|
||||||
rpe->reading = 0;
|
rpe->reading = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from hiredis when a new writer is added to the context. This is called when
|
||||||
|
* data is ready to be written to the context for a command.
|
||||||
|
*
|
||||||
|
* @param privdata Private data passed back to the callback when it fires. We use this to
|
||||||
|
* get access to the redis backend object.
|
||||||
|
*/
|
||||||
void redisAddWrite(void* privdata) {
|
void redisAddWrite(void* privdata) {
|
||||||
auto t = Tracer("addwrite");
|
auto t = Tracer("addwrite");
|
||||||
auto rpe = static_cast<redisPollEvents*>(privdata);
|
auto rpe = static_cast<redisPollEvents*>(privdata);
|
||||||
|
@ -113,6 +197,13 @@ void redisAddWrite(void* privdata) {
|
||||||
rpe->writing = 1;
|
rpe->writing = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from hiredis when a writer is removed from the context. This is called when no
|
||||||
|
* more data is ready to be written to the context for a command.
|
||||||
|
*
|
||||||
|
* @param privdata Private data passed back to the callback when it fires. We use this to
|
||||||
|
* get access to the redis backend object.
|
||||||
|
*/
|
||||||
void redisDelWrite(void* privdata) {
|
void redisDelWrite(void* privdata) {
|
||||||
auto rpe = static_cast<redisPollEvents*>(privdata);
|
auto rpe = static_cast<redisPollEvents*>(privdata);
|
||||||
auto t = Tracer("delwrite");
|
auto t = Tracer("delwrite");
|
||||||
|
@ -137,6 +228,8 @@ std::unique_lock<std::mutex> conditionally_lock(bool condition, std::mutex& mute
|
||||||
|
|
||||||
namespace zeek::storage::backend::redis {
|
namespace zeek::storage::backend::redis {
|
||||||
|
|
||||||
|
constexpr char REQUIRED_VERSION[] = "6.2.0";
|
||||||
|
|
||||||
storage::BackendPtr Redis::Instantiate() { return make_intrusive<Redis>(); }
|
storage::BackendPtr Redis::Instantiate() { return make_intrusive<Redis>(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -388,27 +481,33 @@ void Redis::DoExpire(double current_network_time) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> elements;
|
std::vector<std::string_view> elements;
|
||||||
for ( size_t i = 0; i < reply->elements; i++ )
|
elements.reserve(reply->elements);
|
||||||
elements.emplace_back(reply->element[i]->str);
|
|
||||||
|
|
||||||
freeReplyObject(reply);
|
for ( size_t i = 0; i < reply->elements; i++ )
|
||||||
|
elements.emplace_back(reply->element[i]->str, reply->element[i]->len);
|
||||||
|
|
||||||
// TODO: it's possible to pass multiple keys to a DEL operation but it requires
|
// TODO: it's possible to pass multiple keys to a DEL operation but it requires
|
||||||
// building an array of the strings, building up the DEL command with entries,
|
// building an array of the strings, building up the DEL command with entries,
|
||||||
// and passing the array as a block somehow. There's no guarantee it'd be faster
|
// and passing the array as a block somehow. There's no guarantee it'd be faster
|
||||||
// anyways.
|
// anyways.
|
||||||
for ( const auto& e : elements ) {
|
for ( const auto& e : elements ) {
|
||||||
status = redisAsyncCommand(async_ctx, redisGeneric, NULL, "DEL %s:%s", key_prefix.data(), e.c_str());
|
// redisAsyncCommand usually takes a printf-style string, except the parser used by
|
||||||
|
// hiredis doesn't handle lengths passed with strings correctly (it hangs indefinitely).
|
||||||
|
// Use util::fmt here instead it handles it.
|
||||||
|
status = redisAsyncCommand(async_ctx, redisGeneric, NULL,
|
||||||
|
util::fmt("DEL %s:%.*s", key_prefix.data(), static_cast<int>(e.size()), e.data()));
|
||||||
++active_ops;
|
++active_ops;
|
||||||
Poll();
|
Poll();
|
||||||
|
|
||||||
redisReply* reply = reply_queue.front();
|
redisReply* del_reply = reply_queue.front();
|
||||||
reply_queue.pop_front();
|
reply_queue.pop_front();
|
||||||
freeReplyObject(reply);
|
freeReplyObject(del_reply);
|
||||||
// TODO: do we care if this failed?
|
// TODO: do we care if this failed?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeReplyObject(reply);
|
||||||
|
|
||||||
// Remove all of the elements from the range-set that match the time range.
|
// Remove all of the elements from the range-set that match the time range.
|
||||||
redisAsyncCommand(async_ctx, redisGeneric, NULL, "ZREMRANGEBYSCORE %s_expire -inf %f", key_prefix.data(),
|
redisAsyncCommand(async_ctx, redisGeneric, NULL, "ZREMRANGEBYSCORE %s_expire -inf %f", key_prefix.data(),
|
||||||
current_network_time);
|
current_network_time);
|
||||||
|
@ -416,9 +515,9 @@ void Redis::DoExpire(double current_network_time) {
|
||||||
++active_ops;
|
++active_ops;
|
||||||
Poll();
|
Poll();
|
||||||
|
|
||||||
reply = reply_queue.front();
|
redisReply* rem_range_reply = reply_queue.front();
|
||||||
reply_queue.pop_front();
|
reply_queue.pop_front();
|
||||||
freeReplyObject(reply);
|
freeReplyObject(rem_range_reply);
|
||||||
// TODO: do we care if this failed?
|
// TODO: do we care if this failed?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,19 +586,67 @@ void Redis::HandleGeneric(redisReply* reply) {
|
||||||
reply_queue.push_back(reply);
|
reply_queue.push_back(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Redis::HandleInfoResult(redisReply* reply) {
|
||||||
|
DBG_LOG(DBG_STORAGE, "Redis backend: info event");
|
||||||
|
--active_ops;
|
||||||
|
|
||||||
|
auto lines = util::split(std::string{reply->str}, "\r\n");
|
||||||
|
|
||||||
|
OperationResult res = {ReturnCode::CONNECTION_FAILED};
|
||||||
|
if ( lines.empty() )
|
||||||
|
res.err_str = "INFO command return zero entries";
|
||||||
|
else {
|
||||||
|
std::string_view version_sv{REQUIRED_VERSION};
|
||||||
|
|
||||||
|
for ( const auto& e : lines ) {
|
||||||
|
// Skip empty lines and comments
|
||||||
|
if ( e.empty() || e[0] == '#' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We only care about the redis_version entry. Skip anything else.
|
||||||
|
if ( ! util::starts_with(e, "redis_version:") )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto splits = util::split(e, ':');
|
||||||
|
DBG_LOG(DBG_STORAGE, "Redis backend: found server version %s", splits[1].c_str());
|
||||||
|
if ( std::lexicographical_compare(splits[1].begin(), splits[1].end(), version_sv.begin(),
|
||||||
|
version_sv.end()) )
|
||||||
|
res.err_str = util::fmt("Redis server version is too low: Found %s, need %s", splits[1].c_str(),
|
||||||
|
REQUIRED_VERSION);
|
||||||
|
else {
|
||||||
|
connected = true;
|
||||||
|
res.code = ReturnCode::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! connected && res.err_str.empty() )
|
||||||
|
res.err_str = "INFO command did not return server version";
|
||||||
|
|
||||||
|
freeReplyObject(reply);
|
||||||
|
CompleteCallback(open_cb, res);
|
||||||
|
}
|
||||||
|
|
||||||
void Redis::OnConnect(int status) {
|
void Redis::OnConnect(int status) {
|
||||||
DBG_LOG(DBG_STORAGE, "Redis backend: connection event");
|
DBG_LOG(DBG_STORAGE, "Redis backend: connection event");
|
||||||
--active_ops;
|
--active_ops;
|
||||||
|
|
||||||
|
connected = false;
|
||||||
if ( status == REDIS_OK ) {
|
if ( status == REDIS_OK ) {
|
||||||
connected = true;
|
// Request the INFO block from the server that should contain the version information.
|
||||||
CompleteCallback(open_cb, {ReturnCode::SUCCESS});
|
status = redisAsyncCommand(async_ctx, redisINFO, NULL, "INFO server");
|
||||||
// The connection_established event is sent via the open callback handler.
|
|
||||||
|
if ( status == REDIS_ERR ) {
|
||||||
|
// TODO: do something with the error?
|
||||||
|
DBG_LOG(DBG_STORAGE, "INFO command failed: %s", async_ctx->errstr);
|
||||||
|
CompleteCallback(open_cb,
|
||||||
|
{ReturnCode::OPERATION_FAILED,
|
||||||
|
util::fmt("INFO command failed to retrieve server info: %s", async_ctx->errstr)});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connected = false;
|
++active_ops;
|
||||||
CompleteCallback(open_cb, {ReturnCode::CONNECTION_FAILED});
|
}
|
||||||
|
|
||||||
// TODO: we could attempt to reconnect here
|
// TODO: we could attempt to reconnect here
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
void HandleGetResult(redisReply* reply, ResultCallback* callback);
|
void HandleGetResult(redisReply* reply, ResultCallback* callback);
|
||||||
void HandleEraseResult(redisReply* reply, ResultCallback* callback);
|
void HandleEraseResult(redisReply* reply, ResultCallback* callback);
|
||||||
void HandleGeneric(redisReply* reply);
|
void HandleGeneric(redisReply* reply);
|
||||||
|
void HandleInfoResult(redisReply* reply);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the backend is opened.
|
* Returns whether the backend is opened.
|
||||||
|
@ -60,6 +61,7 @@ private:
|
||||||
void DoPoll() override;
|
void DoPoll() override;
|
||||||
|
|
||||||
OperationResult ParseReplyError(std::string_view op_str, std::string_view reply_err_str) const;
|
OperationResult ParseReplyError(std::string_view op_str, std::string_view reply_err_str) const;
|
||||||
|
OperationResult CheckServerVersion();
|
||||||
|
|
||||||
redisAsyncContext* async_ctx = nullptr;
|
redisAsyncContext* async_ctx = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
error in ../manager.zeek, line 12: serialization of vectors with holes is unsupported
|
||||||
|
received termination signal
|
|
@ -0,0 +1,6 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
node_up, worker-1
|
||||||
|
got pong, with, [1, 2, 3], 3
|
||||||
|
got pong, with, [1, 2, 3], 3
|
||||||
|
got pong, with, [4, 5, 6], 3
|
||||||
|
got pong, with, [4, 5, 6], 3
|
|
@ -0,0 +1,2 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
received termination signal
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
got ping, vector of count, [1, 2, 3], 3
|
||||||
|
got ping, vector of count, [4, 5, 6], 3
|
||||||
|
got finish!
|
|
@ -0,0 +1 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
connection closed ok
|
||||||
|
connection closed ok
|
||||||
|
connection closed ok
|
|
@ -0,0 +1,2 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
received termination signal
|
|
@ -0,0 +1,5 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
B Cluster::websocket_client_added, [/zeek/wstest/ws1/]
|
||||||
|
B Cluster::websocket_client_added, [/zeek/wstest/ws2/]
|
||||||
|
B Cluster::websocket_client_added, [/zeek/wstest/ws3/]
|
||||||
|
D got 1000 pings from 3 clients, terminating
|
2
testing/btest/Baseline/opt.regress-inlining-temps/output
Normal file
2
testing/btest/Baseline/opt.regress-inlining-temps/output
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
T, [field1=3], 3
|
|
@ -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 conn
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents ip_proto failed_service
|
||||||
|
#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] count set[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51354 127.0.0.1 21 tcp - 9.891089 34 71 SF T T 0 ShAdDaFf 13 718 10 599 - 6 ftp
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -7,5 +7,5 @@
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#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
|
#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
|
#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
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -47,3 +47,4 @@ zerortt.pcap
|
||||||
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, initial_packet, CtPZjS20MLrsMUOJi2, T, 1, 3ec82f67,
|
||||||
1.0, handshake_packet, T, CtPZjS20MLrsMUOJi2, 1, 3ec82f67,
|
1.0, handshake_packet, T, CtPZjS20MLrsMUOJi2, 1, 3ec82f67,
|
||||||
|
1.0, handshake_packet, T, CtPZjS20MLrsMUOJi2, 1, 3ec82f67,
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#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
|
#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
|
#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
|
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
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -7,5 +7,5 @@
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#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
|
#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
|
#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
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -28,6 +28,7 @@ The wstest.main() helper will retry running test_fun on ConnectionRefusedError.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
import time
|
import time
|
||||||
from typing import Any, Callable, Optional, Union
|
from typing import Any, Callable, Optional, Union
|
||||||
|
|
||||||
|
@ -221,3 +222,58 @@ def main(f: Callable, *args, **kwargs):
|
||||||
break
|
break
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
time.sleep(MAIN_SLEEP)
|
time.sleep(MAIN_SLEEP)
|
||||||
|
|
||||||
|
|
||||||
|
def monkey_patch_close_socket():
|
||||||
|
"""
|
||||||
|
Monkey patch websockets.sync.ClientConnection.close_socket()
|
||||||
|
|
||||||
|
What's commented out from the original implementation is calling
|
||||||
|
receive_eof() on self.protocol as well as acknowledge_pending_pings().
|
||||||
|
|
||||||
|
The reason for doing this is that in the scneario where the websockets
|
||||||
|
library detects a closed socket during sending, it'll call close_socket()
|
||||||
|
which in turn invokes protocol.receive_eof().
|
||||||
|
|
||||||
|
However, when the concurrently running recv_events() thread is racing
|
||||||
|
and has just successfully received the server's CLOSE frame, the EOF
|
||||||
|
set on protocol results in an EOFError for the receiving thread instead
|
||||||
|
of processing the CLOSE frame. It then further reports an
|
||||||
|
"unexpected internal error".
|
||||||
|
|
||||||
|
Changing the close_socket() implemenation allows the EOF condition
|
||||||
|
to be set only on the receiving side, avoiding the race.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __custom_close_socket(self):
|
||||||
|
"""
|
||||||
|
The original implementation is taken from Connection.close_socket()
|
||||||
|
in sync/connection.py (version 15.0.1).
|
||||||
|
|
||||||
|
"""
|
||||||
|
# shutdown() is required to interrupt recv() on Linux.
|
||||||
|
try:
|
||||||
|
self.socket.shutdown(socket.SHUT_RDWR)
|
||||||
|
except OSError:
|
||||||
|
pass # socket is already closed
|
||||||
|
self.socket.close()
|
||||||
|
|
||||||
|
# Calling protocol.receive_eof() is safe because it's idempotent.
|
||||||
|
# This guarantees that the protocol state becomes CLOSED.
|
||||||
|
#
|
||||||
|
# Commented out: Let the recv_events() threads do EOF handling.
|
||||||
|
#
|
||||||
|
# with self.protocol_mutex:
|
||||||
|
# self.protocol.receive_eof()
|
||||||
|
# assert self.protocol.state is CLOSED
|
||||||
|
|
||||||
|
# Abort recv() with a ConnectionClosed exception.
|
||||||
|
self.recv_messages.close()
|
||||||
|
|
||||||
|
# Acknowledge pings sent with the ack_on_close option.
|
||||||
|
#
|
||||||
|
# Commented out: Asserts on protcol.state is CLOSED
|
||||||
|
#
|
||||||
|
# self.acknowledge_pending_pings()
|
||||||
|
|
||||||
|
ClientConnection.close_socket = __custom_close_socket
|
||||||
|
|
BIN
testing/btest/Traces/quic/quic-decrypt-fail-google-de-51833.pcap
Normal file
BIN
testing/btest/Traces/quic/quic-decrypt-fail-google-de-51833.pcap
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -57,8 +57,6 @@ event send_any()
|
||||||
local e = Cluster::make_event(ping, i, type_name(val), val);
|
local e = Cluster::make_event(ping, i, type_name(val), val);
|
||||||
Cluster::publish_hrw(Cluster::worker_pool, cat(i), e);
|
Cluster::publish_hrw(Cluster::worker_pool, cat(i), e);
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
schedule 0.05sec { send_any() };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event pong(c: count, what: string, val: any)
|
event pong(c: count, what: string, val: any)
|
||||||
|
@ -66,10 +64,16 @@ event pong(c: count, what: string, val: any)
|
||||||
++pongs;
|
++pongs;
|
||||||
print "got pong", pongs, "with", c, what, type_name(val), val;
|
print "got pong", pongs, "with", c, what, type_name(val), val;
|
||||||
|
|
||||||
# We send 5 pings in 3 different variations and
|
# The manager sends 5 types of pings, in 3 different ways. The worker
|
||||||
# get two pongs for each.
|
# answers each ping in two ways, for a total of 30 expected pongs at the
|
||||||
|
# manager. Every batch of pings involves 6 pongs.
|
||||||
if ( pongs == 30 )
|
if ( pongs == 30 )
|
||||||
Cluster::publish(Cluster::worker_topic, finish);
|
Cluster::publish(Cluster::worker_topic, finish);
|
||||||
|
else if ( pongs > 0 && pongs % 6 == 0 )
|
||||||
|
{
|
||||||
|
# Wait for a batch to complete before sending the next.
|
||||||
|
event send_any();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event Cluster::node_up(name: string, id: string)
|
event Cluster::node_up(name: string, id: string)
|
||||||
|
|
92
testing/btest/cluster/generic/publish-vec-hole.zeek
Normal file
92
testing/btest/cluster/generic/publish-vec-hole.zeek
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
# @TEST-DOC: Attempt to send an event with holes. It should fail.
|
||||||
|
#
|
||||||
|
# @TEST-REQUIRES: have-zeromq
|
||||||
|
#
|
||||||
|
# @TEST-PORT: XPUB_PORT
|
||||||
|
# @TEST-PORT: XSUB_PORT
|
||||||
|
# @TEST-PORT: LOG_PULL_PORT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: cp $FILES/zeromq/cluster-layout-no-logger.zeek cluster-layout.zeek
|
||||||
|
# @TEST-EXEC: cp $FILES/zeromq/test-bootstrap.zeek zeromq-test-bootstrap.zeek
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b --parse-only common.zeek manager.zeek worker.zeek
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=manager zeek -b ../manager.zeek"
|
||||||
|
# @TEST-EXEC: btest-bg-run worker-1 "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=worker-1 zeek -b ../worker.zeek"
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-wait 30
|
||||||
|
# @TEST-EXEC: btest-diff ./manager/.stderr
|
||||||
|
# @TEST-EXEC: btest-diff ./manager/.stdout
|
||||||
|
# @TEST-EXEC: btest-diff ./worker-1/.stdout
|
||||||
|
# @TEST-EXEC: btest-diff ./worker-1/.stderr
|
||||||
|
|
||||||
|
# @TEST-START-FILE common.zeek
|
||||||
|
@load ./zeromq-test-bootstrap.zeek
|
||||||
|
|
||||||
|
redef Log::default_rotation_interval = 0sec;
|
||||||
|
|
||||||
|
global finish: event() &is_used;
|
||||||
|
global ping: event(v: vector of count) &is_used;
|
||||||
|
global pong: event(v: vector of count) &is_used;
|
||||||
|
# @TEST-END-FILE
|
||||||
|
|
||||||
|
# @TEST-START-FILE manager.zeek
|
||||||
|
@load ./common.zeek
|
||||||
|
|
||||||
|
event send_pings()
|
||||||
|
{
|
||||||
|
local v1 = vector(1, 2, 3);
|
||||||
|
|
||||||
|
assert Cluster::publish(Cluster::worker_topic, ping, v1);
|
||||||
|
|
||||||
|
# Publish with a vector with a hole, fails!
|
||||||
|
local v2 = vector(1);
|
||||||
|
v2[2] = 3;
|
||||||
|
assert ! Cluster::publish(Cluster::worker_topic, ping, v2);
|
||||||
|
local v3 = vector(4, 5, 6);
|
||||||
|
assert Cluster::publish(Cluster::worker_topic, ping, v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
global pongs = 0;
|
||||||
|
|
||||||
|
event pong(v: vector of count)
|
||||||
|
{
|
||||||
|
++pongs;
|
||||||
|
print "got pong", "with", v, |v|;
|
||||||
|
|
||||||
|
# Two of the three pings go through, the worker sends 2 pongs
|
||||||
|
# for each ping, so stop after 4.
|
||||||
|
if ( pongs == 4 )
|
||||||
|
Cluster::publish(Cluster::worker_topic, finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
event Cluster::node_up(name: string, id: string)
|
||||||
|
{
|
||||||
|
print "node_up", name;
|
||||||
|
event send_pings();
|
||||||
|
}
|
||||||
|
|
||||||
|
event Cluster::node_down(name: string, id: string)
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
# @TEST-END-FILE
|
||||||
|
|
||||||
|
|
||||||
|
# @TEST-START-FILE worker.zeek
|
||||||
|
@load ./common.zeek
|
||||||
|
|
||||||
|
event ping(v: vector of count)
|
||||||
|
{
|
||||||
|
print "got ping", type_name(v), cat(v), |v|;
|
||||||
|
Cluster::publish(Cluster::manager_topic, pong, v);
|
||||||
|
local e = Cluster::make_event(pong, v);
|
||||||
|
Cluster::publish(Cluster::manager_topic, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
event finish()
|
||||||
|
{
|
||||||
|
print "got finish!";
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
# @TEST-END-FILE
|
103
testing/btest/cluster/websocket/terminate-while-queuing.zeek
Normal file
103
testing/btest/cluster/websocket/terminate-while-queuing.zeek
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# @TEST-DOC: Regression test for #4420. Clients publish fast and Zeek terminates after receiving 1000 events. Previously this would result in a hang at Zeek shutdown.
|
||||||
|
#
|
||||||
|
# @TEST-REQUIRES: python3 -c 'import websockets.sync'
|
||||||
|
#
|
||||||
|
# @TEST-PORT: WEBSOCKET_PORT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: cp $FILES/ws/wstest.py .
|
||||||
|
# @TEST-EXEC: zeek -b --parse-only manager.zeek
|
||||||
|
# @TEST-EXEC: python3 -m py_compile client.py
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && zeek -b ../manager.zeek >out"
|
||||||
|
# @TEST-EXEC: btest-bg-run client "python3 ../client.py >out"
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-wait 30
|
||||||
|
# @TEST-EXEC: sort ./manager/out > ./manager/out.sorted
|
||||||
|
# @TEST-EXEC: btest-diff ./manager/out.sorted
|
||||||
|
# @TEST-EXEC: btest-diff ./manager/.stderr
|
||||||
|
# @TEST-EXEC: btest-diff ./client/out
|
||||||
|
# @TEST-EXEC: btest-diff ./client/.stderr
|
||||||
|
|
||||||
|
# @TEST-START-FILE manager.zeek
|
||||||
|
redef exit_only_after_terminate = T;
|
||||||
|
|
||||||
|
# Force dispatcher queue being full quickly!
|
||||||
|
redef Cluster::default_websocket_max_event_queue_size = 1;
|
||||||
|
|
||||||
|
global ping_count = 0;
|
||||||
|
global ping: event(msg: string, c: count) &is_used;
|
||||||
|
|
||||||
|
global clients: set[string] = set();
|
||||||
|
|
||||||
|
event ping(client: string, n: count) &is_used
|
||||||
|
{
|
||||||
|
++ping_count;
|
||||||
|
add clients[client];
|
||||||
|
|
||||||
|
if ( ping_count == 1000 )
|
||||||
|
{
|
||||||
|
print fmt("D got 1000 pings from %s clients, terminating", |clients|);
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event Cluster::websocket_client_added(info: Cluster::EndpointInfo, subscriptions: string_vec)
|
||||||
|
{
|
||||||
|
print "B Cluster::websocket_client_added", subscriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
event Cluster::websocket_client_lost(info: Cluster::EndpointInfo)
|
||||||
|
{
|
||||||
|
print "E Cluster::websocket_client_lost";
|
||||||
|
}
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]);
|
||||||
|
Cluster::subscribe("/test/pings/");
|
||||||
|
}
|
||||||
|
# @TEST-END-FILE
|
||||||
|
|
||||||
|
|
||||||
|
# @TEST-START-FILE client.py
|
||||||
|
import websockets.exceptions
|
||||||
|
|
||||||
|
import wstest
|
||||||
|
|
||||||
|
wstest.monkey_patch_close_socket()
|
||||||
|
|
||||||
|
def run(ws_url):
|
||||||
|
with (
|
||||||
|
wstest.connect("ws1", ws_url) as tc1,
|
||||||
|
wstest.connect("ws2", ws_url) as tc2,
|
||||||
|
wstest.connect("ws3", ws_url) as tc3,
|
||||||
|
):
|
||||||
|
clients = [tc1, tc2, tc3]
|
||||||
|
for tc in clients:
|
||||||
|
tc.hello_v1([])
|
||||||
|
|
||||||
|
stop = False;
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
saw_closed_ok = set()
|
||||||
|
|
||||||
|
while len(saw_closed_ok) < 3:
|
||||||
|
for idx, tc in enumerate(clients, 1):
|
||||||
|
if idx in saw_closed_ok: # Have seen a ConnectionClosedOK for this client?
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
i += 1
|
||||||
|
tc.send_json(wstest.build_event_v1("/test/pings/", "ping", [f"tc{idx}", i]))
|
||||||
|
except websockets.exceptions.ConnectionClosedOK as e:
|
||||||
|
print("connection closed ok")
|
||||||
|
assert e.code == 1001, f"expected code 1001, got {e.code} - {e}" # Remote going away
|
||||||
|
i -= 1
|
||||||
|
saw_closed_ok.add(idx)
|
||||||
|
|
||||||
|
assert len(saw_closed_ok) == 3
|
||||||
|
assert i >= 1000, f"expected to send at least 1000 events, only sent {i}"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
wstest.main(run, wstest.WS4_URL_V1)
|
||||||
|
# @TEST-END-FILE
|
30
testing/btest/opt/regress-inlining-temps.zeek
Normal file
30
testing/btest/opt/regress-inlining-temps.zeek
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# @TEST-DOC: Regression test for incorrect reuse of temporaries when inlining
|
||||||
|
# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1"
|
||||||
|
# @TEST-EXEC: zeek -b -O ZAM %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
field1: count;
|
||||||
|
};
|
||||||
|
|
||||||
|
global yes = T;
|
||||||
|
|
||||||
|
function pred(my_R: R): bool
|
||||||
|
{
|
||||||
|
# In the following, my_R$field1 will never be evaluated ...
|
||||||
|
if ( yes || my_R$field1 == 4 )
|
||||||
|
return T;
|
||||||
|
else
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
local my_R = R($field1=3);
|
||||||
|
|
||||||
|
# ... prior to the regression, the third argument in this print
|
||||||
|
# was taken from the temporary in pred() that *would* have held
|
||||||
|
# my_R$field1 had that ever been evaluated, but instead it holds
|
||||||
|
# the default ZVal value of 0.
|
||||||
|
print pred(my_R), my_R, my_R$field1;
|
||||||
|
}
|
|
@ -5,3 +5,7 @@
|
||||||
@load policy/protocols/conn/failed-service-logging
|
@load policy/protocols/conn/failed-service-logging
|
||||||
|
|
||||||
redef DPD::track_removed_services_in_connection = T;
|
redef DPD::track_removed_services_in_connection = T;
|
||||||
|
|
||||||
|
# @TEST-START-NEXT
|
||||||
|
|
||||||
|
@load policy/protocols/conn/failed-service-logging
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
2
testing/external/commit-hash.zeek-testing
vendored
2
testing/external/commit-hash.zeek-testing
vendored
|
@ -1 +1 @@
|
||||||
b7c465d5a208546bd27801496eb7e6035b208f27
|
5fd78ecbdd834feff545f3a3c19b974d927ffb91
|
||||||
|
|
1
testing/external/scripts/external-ct-list.zeek
vendored
Symbolic link
1
testing/external/scripts/external-ct-list.zeek
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../scripts/external-ct-list.zeek
|
1
testing/external/scripts/testing-setup.zeek
vendored
1
testing/external/scripts/testing-setup.zeek
vendored
|
@ -1,6 +1,7 @@
|
||||||
# Sets some testing specific options.
|
# Sets some testing specific options.
|
||||||
|
|
||||||
@load external-ca-list
|
@load external-ca-list
|
||||||
|
@load external-ct-list
|
||||||
|
|
||||||
@load protocols/conn/failed-service-logging
|
@load protocols/conn/failed-service-logging
|
||||||
redef DPD::track_removed_services_in_connection=T;
|
redef DPD::track_removed_services_in_connection=T;
|
||||||
|
|
22
testing/scripts/external-ct-list.zeek
Normal file
22
testing/scripts/external-ct-list.zeek
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Re-add CT logs that we need for tests
|
||||||
|
|
||||||
|
module SSL;
|
||||||
|
|
||||||
|
redef SSL::ct_logs += {
|
||||||
|
["\xee\xcd\xd0\x64\xd5\xdb\x1a\xce\xc5\x5c\xb7\x9d\xb4\xcd\x13\xa2\x32\x87\x46\x7c\xbc\xec\xde\xc3\x51\x48\x59\x46\x71\x1f\xb5\x9b"] = CTInfo($description="Google 'Argon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1d\xb9\x6c\xa9\xcb\x69\x94\xc5\x5c\xe6\xb6\xa6\x03\xbb\xd2\xb8\xdc\x54\x43\x17\x28\x99\x0c\x06\x01\x50\x1d\x9d\x64\xc0\x59\x46\x2b\xdc\xc8\x03\x1d\x05\xb4\x2d\xa8\x09\xf7\x99\x41\xed\x04\xfb\xe5\x57\xba\x26\x04\xf6\x11\x52\xce\x14\x65\x3b\x2f\x76\x2b\xc0"),
|
||||||
|
["\x76\xff\x88\x3f\x0a\xb6\xfb\x95\x51\xc2\x61\xcc\xf5\x87\xba\x34\xb4\xa4\xcd\xbb\x29\xdc\x68\x42\x0a\x9f\xe6\x67\x4c\x5a\x3a\x74"] = CTInfo($description="Google 'Xenon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb9\x60\xe0\x34\x1e\x35\xe4\x65\x00\x93\x4f\x90\x09\xbd\x5a\xec\x44\xdd\x8c\x0f\xce\xed\x11\x3e\x2a\x59\x46\x9a\x31\xb6\xc7\x99\xf7\xdc\xef\x3d\xcd\x8f\x86\xc2\x35\xa5\x3e\xdc\x29\xba\xbb\xf2\x54\xe2\xa8\x0c\x83\x08\x51\x06\xde\x21\x6d\x36\x50\x8e\x38\x4d"),
|
||||||
|
["\xda\xb6\xbf\x6b\x3f\xb5\xb6\x22\x9f\x9b\xc2\xbb\x5c\x6b\xe8\x70\x91\x71\x6c\xbb\x51\x84\x85\x34\xbd\xa4\x3d\x30\x48\xd7\xfb\xab"] = CTInfo($description="Cloudflare 'Nimbus2024' Log", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x77\xb1\x9b\x7b\x8f\xe6\x8b\x35\xfe\x3a\x92\x29\x2d\xac\x8a\x8d\x51\x8a\x25\xfc\x93\xb6\xd7\xa0\x8b\x29\x37\x71\x1d\x33\xca\xcc\x33\xea\x28\xb9\x1f\xe2\xac\xc3\xa9\x5d\xdd\x97\xbe\xf6\x9e\x94\x25\xdd\x36\x81\xd1\xeb\x5d\x29\xc3\x2b\x44\xf1\x5b\xca\x15\x48"),
|
||||||
|
["\x48\xb0\xe3\x6b\xda\xa6\x47\x34\x0f\xe5\x6a\x02\xfa\x9d\x30\xeb\x1c\x52\x01\xcb\x56\xdd\x2c\x81\xd9\xbb\xbf\xab\x39\xd8\x84\x73"] = CTInfo($description="DigiCert Yeti2024 Log", $operator="DigiCert", $url="https://yeti2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x57\xb8\xc1\x6f\x30\xa4\x7f\x2e\xe4\xf0\xd0\xd9\x60\x62\x13\x95\xe3\x7a\xe3\x4e\x53\xc3\xb3\xb8\x73\x85\xc1\x18\x0d\x23\x0e\x58\x84\xd2\x78\xef\x9b\xb3\x1e\x2c\x1a\xde\xc1\x8f\x81\x1b\x19\x44\x58\xb7\x00\x77\x60\x20\x1a\x72\xd8\x82\xde\xae\x9e\xb1\xc6\x4b"),
|
||||||
|
["\x73\xd9\x9e\x89\x1b\x4c\x96\x78\xa0\x20\x7d\x47\x9d\xe6\xb2\xc6\x1c\xd0\x51\x5e\x71\x19\x2a\x8c\x6b\x80\x10\x7a\xc1\x77\x72\xb5"] = CTInfo($description="DigiCert Nessie2024 Log", $operator="DigiCert", $url="https://nessie2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2d\xfc\xa2\x7b\x36\xbf\x56\x91\xe9\xfe\x3f\xe8\x3d\xfc\xc3\xa7\xe0\x61\x52\xea\x2c\xe9\x05\xa3\x9f\x27\x17\x81\x05\x70\x6b\x81\x61\x44\x8a\xf8\x3b\x10\x80\x42\xed\x03\x2f\x00\x50\x21\xfc\x41\x54\x84\xa3\x54\xd5\x2e\xb2\x7a\x16\x4b\x2a\x1f\x2b\x66\x04\x2b"),
|
||||||
|
["\xb6\x9d\xdc\xbc\x3c\x1a\xbd\xef\x6f\x9f\xd6\x0c\x88\xb1\x06\x7b\x77\xf0\x82\x68\x8b\x2d\x78\x65\xd0\x4b\x39\xab\xe9\x27\xa5\x75"] = CTInfo($description="DigiCert 'Wyvern2024h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x68\xa6\x79\x14\xd1\x58\xe7\xab\xaa\x29\x69\x7f\x60\xed\x68\xe8\x10\xf6\x07\x84\xc0\xfb\x59\x04\x5a\x09\xc9\x1d\xe1\x4b\xfb\xcd\xdc\x03\xf3\xa8\x2a\x46\xb9\x84\x4d\x69\x30\xec\x23\x35\xc1\x8e\xfc\x9f\xb4\x20\x24\xd7\x15\xac\x87\xf7\x1e\xc1\x0b\x3c\x76\x1a"),
|
||||||
|
["\x0c\x2a\xef\x2c\x4a\x5b\x98\x83\xd4\xdd\xa3\x82\xfe\x50\xfb\x51\x88\xb3\xe9\x73\x33\xa1\xec\x53\xa0\x9d\xc9\xa7\x9d\x0d\x08\x20"] = CTInfo($description="DigiCert 'Wyvern2024h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa8\x73\x12\x9c\x54\xd0\x7a\x7d\xc5\xb5\x17\x2b\x71\x52\x89\x04\x90\xbb\x42\xf1\x9d\xf8\x1c\xde\x4c\xcf\x82\x3c\xbd\x37\x1b\x74\x4c\x3c\xc7\xa3\x13\x87\x01\x51\x13\x14\xda\xa2\x12\x98\x84\xce\x1c\xbe\xcf\x4f\x7a\xef\x15\xfa\xd0\xee\xed\xed\x07\xad\x71\x6d"),
|
||||||
|
["\xdb\x07\x6c\xde\x6a\x8b\x78\xec\x58\xd6\x05\x64\x96\xeb\x6a\x26\xa8\xc5\x9e\x72\x12\x93\xe8\xac\x03\x27\xdd\xde\x89\xdb\x5a\x2a"] = CTInfo($description="DigiCert 'Sphinx2024h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc6\xe4\x29\x69\x98\xfe\x28\x92\x57\x12\x4d\x9e\xed\x0e\xe7\x32\xa2\xe6\x9c\x27\x78\xa4\x29\x7c\x99\xd5\xdb\xfa\x22\xc1\xdd\x5e\xa7\xf4\xd8\xea\xc8\xd7\x44\x8d\xe0\xf1\x8c\x0a\x01\x1d\xd8\x22\xa8\xd3\xeb\xc9\x22\x8e\x36\xfb\x4a\xb1\x70\x9c\x5d\xc1\xe8\x33"),
|
||||||
|
["\xdc\xc9\x5e\x6f\xa2\x99\xb9\xb0\xfd\xbd\x6c\xa6\xa3\x6e\x1d\x72\xc4\x21\x2f\xdd\x1e\x0f\x47\x55\x3a\x36\xd6\xcf\x1a\xd1\x1d\x8d"] = CTInfo($description="DigiCert 'Sphinx2024h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdb\x09\x41\x84\xe7\xd1\xf1\x5b\x25\x09\x7b\xe8\xc6\x98\x51\x5e\x29\x85\xfd\x81\xde\x89\xd7\xd0\x86\xa4\xb0\xe5\x15\xec\x5d\x7b\x17\x55\x5f\xc9\x79\x8d\xe4\x22\x36\xe7\xe9\xbf\x38\x3f\xd1\xe9\xd4\x09\x84\x81\xbe\xb6\xc1\xed\x1b\x17\xea\x26\x97\xba\xe9\x9a"),
|
||||||
|
["\xa2\xe2\xbf\xd6\x1e\xde\x2f\x2f\x07\xa0\xd6\x4e\x6d\x37\xa7\xdc\x65\x43\xb0\xc6\xb5\x2e\xa2\xda\xb7\x8a\xf8\x9a\x6d\xf5\x17\xd8"] = CTInfo($description="Sectigo 'Sabre2024h1'", $operator="Sectigo", $url="https://sabre2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\x01\xf6\xce\x31\xbc\xaa\x14\x61\x51\xfe\x6b\x7a\x87\xae\xa6\xd3\x9b\xc7\x87\x2d\x0a\x5a\xc8\x4f\xb5\x54\xdc\xc9\x93\xa0\x00\xee\xca\x1c\xb9\xa7\xb6\x7b\x47\x3b\xe5\x4f\xaa\x6c\x16\x1c\x70\x2e\xc8\xec\x53\x5a\x4c\x21\x4c\x7e\x27\x0b\x13\x14\x5e\xfc\x85"),
|
||||||
|
["\x19\x98\x10\x71\x09\xf0\xd6\x52\x2e\x30\x80\xd2\x9e\x3f\x64\xbb\x83\x6e\x28\xcc\xf9\x0f\x52\x8e\xee\xdf\xce\x4a\x3f\x16\xb4\xca"] = CTInfo($description="Sectigo 'Sabre2024h2'", $operator="Sectigo", $url="https://sabre2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7a\x10\x4c\x8a\xe7\x22\x7b\x6d\x2a\xba\x8e\xfa\x6b\x4a\x81\xd5\x85\xae\x03\xef\xff\x4b\xfc\x4d\x53\x3d\xb7\x8c\xbb\x75\x09\xc9\xea\x16\x7e\xc1\x77\x16\xd2\xc2\x45\x74\x6d\x8d\xc4\xe1\x88\x37\xdf\xd4\xf3\x60\x65\xfc\xa0\x75\xf0\x20\x66\x8e\x4a\xcc\x19\xda"),
|
||||||
|
["\x29\xd0\x3a\x1b\xb6\x74\xaa\x71\x1c\xd3\x03\x5b\x65\x57\xc1\x4f\x8a\xa7\x8b\x4f\xe8\x38\x94\x49\xec\xa4\x53\xf9\x44\xbd\x24\x68"] = CTInfo($description="Sectigo 'Mammoth2024h1'", $operator="Sectigo", $url="https://mammoth2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa4\x59\x90\xf3\x71\x24\x24\xf7\xc3\x55\x27\x56\x9c\xa3\x59\x1e\xf7\xb7\x9f\xce\xab\x4e\x19\x66\x4d\xd0\x8a\xfa\x9d\x62\xa4\x24\xf0\x3b\x20\xe4\x1d\x14\x67\xc8\xfc\xe4\x37\xf2\x4b\x38\x54\x5a\xcf\x9f\x6b\x07\x90\xd0\x0e\x7e\x3d\x4c\x87\xb2\xe8\x3f\x07\xcc"),
|
||||||
|
["\x50\x85\x01\x58\xdc\xb6\x05\x95\xc0\x0e\x92\xa8\x11\x02\xec\xcd\xfe\x3f\x6b\x78\x58\x42\x9f\x57\x98\x35\x38\xc9\xda\x52\x50\x63"] = CTInfo($description="Sectigo 'Mammoth2024h1b'", $operator="Sectigo", $url="https://mammoth2024h1b.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\xd5\x07\x28\x7a\x04\x34\xae\xca\xbe\x80\x79\x4f\x3e\xf6\x41\xf4\x24\x04\xe1\xd6\x36\x5a\x1a\x09\xf2\xd1\xba\x84\x17\xae\x1e\xa1\x7c\x00\x1d\x54\x73\x90\x75\x21\xa8\xd1\xda\x5e\x10\xe1\x8c\xec\xb2\x8a\x8c\xc8\xe7\xdd\xcd\xe2\x07\xf0\x4e\x16\x02\x57\x37"),
|
||||||
|
["\xdf\xe1\x56\xeb\xaa\x05\xaf\xb5\x9c\x0f\x86\x71\x8d\xa8\xc0\x32\x4e\xae\x56\xd9\x6e\xa7\xf5\xa5\x6a\x01\xd1\xc1\x3b\xbe\x52\x5c"] = CTInfo($description="Sectigo 'Mammoth2024h2'", $operator="Sectigo", $url="https://mammoth2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x66\x22\x24\x6e\xbe\x52\x62\x0a\xa0\xaf\xc3\x25\x1a\x36\x2e\xa7\x60\x89\xa2\x65\xbf\xa4\x5f\xbd\x85\x6a\x94\x05\x81\x35\x90\x54\x31\x95\xe7\x11\x9e\xa3\x2e\x0f\x85\xef\xa7\x88\x57\x8b\x63\x1a\x81\xc1\x41\x9d\x7d\xec\x01\x3a\xdb\xb9\xc1\x27\xf4\x65\x1e"),
|
||||||
|
["\x3b\x53\x77\x75\x3e\x2d\xb9\x80\x4e\x8b\x30\x5b\x06\xfe\x40\x3b\x67\xd8\x4f\xc3\xf4\xc7\xbd\x00\x0d\x2d\x72\x6f\xe1\xfa\xd4\x17"] = CTInfo($description="Let's Encrypt 'Oak2024H1' log", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x56\x43\xd7\x7e\x7b\xd4\x72\xb7\xba\xa9\x51\xbd\x36\x93\xb7\xe9\xb5\x92\x0f\xea\x5e\xb7\x45\xa3\x92\xfd\xc9\xa5\x3c\x80\xac\x1a\x20\xef\x25\x2f\xb8\xe1\x20\xf7\xa8\x3a\x2e\x07\x8d\xe6\xeb\xa4\xe2\x7d\x24\x63\x9f\x46\xbf\x94\x73\x52\x8d\x96\xae\xa9\x26\xfd"),
|
||||||
|
["\x3f\x17\x4b\x4f\xd7\x22\x47\x58\x94\x1d\x65\x1c\x84\xbe\x0d\x12\xed\x90\x37\x7f\x1f\x85\x6a\xeb\xc1\xbf\x28\x85\xec\xf8\x64\x6e"] = CTInfo($description="Let's Encrypt 'Oak2024H2' log", $operator="Let's Encrypt", $url="https://oak.ct.letsencrypt.org/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\x73\xd6\x53\x47\xe9\xf3\xc9\xd5\x7c\x16\xc2\xd6\x8f\x70\x65\xfa\xf2\x51\x36\xa9\x13\x80\x2f\xed\xf9\x94\xd3\x5a\x8b\xe8\x4f\x33\xcf\xc3\xd3\x89\xd4\x5f\x5a\x66\x89\xba\x20\x1f\x71\xcb\xca\xbb\x9f\x9f\xf3\x5c\x2d\x1e\xa3\x81\x59\xaf\x92\xb3\x6d\x30\x68"),
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue