From 4ed4b1d0a971b7821493c9b246f09fa60e69cf70 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 22 Nov 2023 14:12:13 +0000 Subject: [PATCH] Spicy TLS: generate same file IDs as binpac analyzer This reduces the amount of failing tests to... still 39. A lot of them are due to QUIC nowadays. --- .../protocol/ssl/spicy/CMakeLists.txt | 2 +- src/analyzer/protocol/ssl/spicy/SSL.spicy | 30 ++++++++++++++++--- src/analyzer/protocol/ssl/spicy/support.cc | 28 +++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/analyzer/protocol/ssl/spicy/support.cc diff --git a/src/analyzer/protocol/ssl/spicy/CMakeLists.txt b/src/analyzer/protocol/ssl/spicy/CMakeLists.txt index 2b7e766f7f..c607dc64a4 100644 --- a/src/analyzer/protocol/ssl/spicy/CMakeLists.txt +++ b/src/analyzer/protocol/ssl/spicy/CMakeLists.txt @@ -1 +1 @@ -spicy_add_analyzer(NAME SSL SOURCES SSL.spicy SSL.evt) +spicy_add_analyzer(NAME SSL SOURCES SSL.spicy SSL.evt support.cc) diff --git a/src/analyzer/protocol/ssl/spicy/SSL.spicy b/src/analyzer/protocol/ssl/spicy/SSL.spicy index 764223d492..693039f9ff 100644 --- a/src/analyzer/protocol/ssl/spicy/SSL.spicy +++ b/src/analyzer/protocol/ssl/spicy/SSL.spicy @@ -2,6 +2,11 @@ module SSL; import spicy; +public function get_fuid( + is_client: bool, + pos: uint32 +): string &cxxname="ssl_get_fuid"; + type ContentType = enum { change_cipher_spec = 20, alert = 21, @@ -570,6 +575,8 @@ type Share = unit { var server_encrypted: bool; var both_sides_encrypted_first_time: bool; var established: bool; + var client_certificate_depth: uint32; + var server_certificate_depth: uint32; on %init { self.ccs_seen = 0; @@ -582,6 +589,8 @@ type Share = unit { self.client_encrypted = False; self.both_sides_encrypted_first_time = False; self.established = False; + self.client_certificate_depth = 0; + self.server_certificate_depth = 0; } }; @@ -827,7 +836,7 @@ type Handshake_message = unit(inout msg: Message, inout sh: Share) { HandshakeType::server_hello_done -> : bytes &size=self.length; # Fixme: alert if length != 0 HandshakeType::hello_verify_request -> hello_verify_request: HelloVerifyRequest; HandshakeType::server_hello -> server_hello: ServerHelloChoice(self.length, msg, sh); - HandshakeType::certificate -> certificate: Certificate; + HandshakeType::certificate -> certificate: Certificate(sh); HandshakeType::certificate_request -> certificate_request: CertificateRequest(sh); HandshakeType::certificate_verify -> : bytes &size=self.length; # opaque encrypted data HandshakeType::client_key_exchange -> client_key_exchange: ClientKeyExchange(sh, self.length); @@ -1728,7 +1737,7 @@ type NewSessionTicket = unit { ticket: bytes &size=self.ticket_length; }; -type Certificate = unit { +type Certificate = unit(inout sh: Share) { length: bytes &size=3 &convert=$$.to_uint(spicy::ByteOrder::Network); certificate_list: SingleCertificate[] &size=self.length; }; @@ -1812,6 +1821,19 @@ public function get_direction(sh: Share) : bool { return zeek::is_orig(); } +# returns the current certificate depth and increases it by one +public function get_and_increase_certificate_depth(inout sh: Share) : uint32 { + local certificate_depth: uint32 = 0; + if ( get_direction(sh) ) { + certificate_depth = sh.client_certificate_depth; + sh.client_certificate_depth += 1; + } else { + certificate_depth = sh.server_certificate_depth; + sh.server_certificate_depth += 1; + } + return certificate_depth; +} + # If this function returns True, you have to send the ssl_connection_flipped event! public function check_direction(inout sh: Share, desired: bool) : bool { if ( sh.flipped ) { @@ -1854,9 +1876,9 @@ on SSL::Certificate::%done { for ( i in self.certificate_list ) { if ( first ) - zeek::file_begin("application/x-x509-user-cert"); + zeek::file_begin("application/x-x509-user-cert", get_fuid(get_direction(sh), get_and_increase_certificate_depth(sh))); else - zeek::file_begin("application/x-x509-ca-cert"); + zeek::file_begin("application/x-x509-ca-cert", get_fuid(get_direction(sh), get_and_increase_certificate_depth(sh))); zeek::file_data_in(i.cert); zeek::file_end(); first = False; diff --git a/src/analyzer/protocol/ssl/spicy/support.cc b/src/analyzer/protocol/ssl/spicy/support.cc new file mode 100644 index 0000000000..e9c40ffc40 --- /dev/null +++ b/src/analyzer/protocol/ssl/spicy/support.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2023 by the Zeek Project. See COPYING for details. + +#include + +#include "zeek/Desc.h" +#include "zeek/file_analysis/Manager.h" +#include "zeek/spicy/cookie.h" +#include "zeek/spicy/runtime-support.h" + +std::string ssl_get_fuid(const hilti::rt::Bool& is_client, const hilti::rt::integer::safe& pos) { + auto cookie = static_cast(hilti::rt::context::cookie()); + assert(cookie); + + auto c = cookie->protocol; + if ( ! c ) + throw zeek::spicy::rt::ValueUnavailable("connection not available"); + + zeek::ODesc common; + common.AddRaw("Analyzer::ANALYZER_SSL"); + common.Add(c->analyzer->Conn()->StartTime()); + common.AddRaw(is_client ? "T" : "F", 1); + c->analyzer->Conn()->IDString(&common); + + // zeek::ODesc file_handle; + common.Add((uint32_t)pos); + std::string file_id = zeek::file_mgr->HashHandle(common.Description()); + return file_id; +}