From b56b856da936e52aa51d2576f99dc778587e30e7 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 9 Mar 2023 08:20:50 +0100 Subject: [PATCH 1/2] SSL/TLS: Parse CertificateRequest message This commit introduces parsing of the CertificateRequest message in the TLS handshake. It introduces a new event ssl_certificate_request, as well as a new function parse_distinguished_name, which can be used to parse part of the ssl_certificate_request event parameters. This commit also introduces a new policy script, which appends information about the CAs a TLS server requests in the CertificateRequest message, if it sends it. --- NEWS | 5 ++ .../ssl/certificate-request-info.zeek | 23 +++++++++ scripts/test-all-policy.zeek | 1 + src/analyzer/protocol/ssl/events.bif | 25 +++++++++- src/analyzer/protocol/ssl/functions.bif | 32 +++++++++++++ .../protocol/ssl/tls-handshake-analyzer.pac | 45 ++++++++++++++++++ .../protocol/ssl/tls-handshake-protocol.pac | 23 ++++++++- .../btest/Baseline/bifs.x509_parse_dn/.stdout | 5 ++ .../out | 15 ++++++ .../ssl.log | 11 +++++ .../tls/certificate-request-failed.pcap | Bin 0 -> 5355 bytes .../btest/Traces/tls/client-certificate.pcap | Bin 0 -> 16382 bytes testing/btest/bifs/x509_parse_dn.zeek | 10 ++++ .../protocols/ssl/certificate_request.zeek | 22 +++++++++ .../ssl/certificate-request-info.zeek | 4 ++ testing/external/commit-hash.zeek-testing | 2 +- .../external/commit-hash.zeek-testing-private | 2 +- 17 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 scripts/policy/protocols/ssl/certificate-request-info.zeek create mode 100644 testing/btest/Baseline/bifs.x509_parse_dn/.stdout create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.certificate_request/out create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.certificate-request-info/ssl.log create mode 100644 testing/btest/Traces/tls/certificate-request-failed.pcap create mode 100644 testing/btest/Traces/tls/client-certificate.pcap create mode 100644 testing/btest/bifs/x509_parse_dn.zeek create mode 100644 testing/btest/scripts/base/protocols/ssl/certificate_request.zeek create mode 100644 testing/btest/scripts/policy/protocols/ssl/certificate-request-info.zeek diff --git a/NEWS b/NEWS index cc6929540b..ee4361ba7e 100644 --- a/NEWS +++ b/NEWS @@ -58,6 +58,11 @@ New Functionality - The X.509 certificate parser now exposes the signature type that is given inside the signed portion of the certificate. +- The SSL parser now parses the CertificateRequest handshake message. There is a new + ``ssl_certificate_request`` event and a new ``parse_distinguished_name`` function. + We also added the ``protocols/ssl/certificate-request-info`` policy script, that + adds some additional information to ``ssl.log``. + - Add logging metrics for streams (``zeek-log-stream-writes``) and writers (``zeek-log-writer-writes-total``). diff --git a/scripts/policy/protocols/ssl/certificate-request-info.zeek b/scripts/policy/protocols/ssl/certificate-request-info.zeek new file mode 100644 index 0000000000..6eaa664077 --- /dev/null +++ b/scripts/policy/protocols/ssl/certificate-request-info.zeek @@ -0,0 +1,23 @@ +##! When the server requests a client certificate, it optionally may specify a list of CAs that +##! it accepts. If the server does this, this script adds this list to ssl.log. + +@load base/protocols/ssl + +module SSL; + +redef record SSL::Info += { + ## List of cient certificate CAs accepted by the server + requested_client_certificate_authorities: vector of string &optional &log; +}; + +event ssl_certificate_request(c: connection, is_client: bool, certificate_types: index_vec, supported_signature_algorithms: SSL::SignatureAndHashAlgorithm, certificate_authorities: string_vec) + { + if ( is_client ) + return; + + local out: vector of string = vector(); + for ( i in certificate_authorities ) + out[i] = parse_distinguished_name(certificate_authorities[i]); + + c$ssl$requested_client_certificate_authorities = out; + } diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index 37a9860cb5..87dd2e661c 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -122,6 +122,7 @@ @load protocols/ssh/geo-data.zeek @load protocols/ssh/interesting-hostnames.zeek @load protocols/ssh/software.zeek +@load protocols/ssl/certificate-request-info.zeek @load protocols/ssl/decryption.zeek @load protocols/ssl/expiring-certs.zeek @load protocols/ssl/heartbleed.zeek diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 91248b2648..c7f8beadfe 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -657,7 +657,7 @@ event ssl_stapled_ocsp%(c: connection, is_client: bool, response: string%); ## ## .. zeek:see:: ssl_alert ssl_established ssl_extension ssl_server_hello ## ssl_session_ticket_handshake x509_certificate ssl_client_hello -## ssl_change_cipher_spec ssl_connection_flipped +## ssl_change_cipher_spec ssl_connection_flipped ssl_certificate_request event ssl_handshake_message%(c: connection, is_client: bool, msg_type: count, length: count%); ## This event is raised when a SSL/TLS ChangeCipherSpec message is encountered @@ -687,3 +687,26 @@ event ssl_change_cipher_spec%(c: connection, is_client: bool%); ## ssl_session_ticket_handshake x509_certificate ssl_client_hello ## ssl_handshake_message event ssl_connection_flipped%(c: connection%); + +## This event is raised, when a Certificate Request handshake message is encountered. This +## Message can be used by a TLS server to request a client certificate. +## +## c: The connection. +## +## is_client: True if event is raised for the client side of the connection +## (the side that sends the client hello). This is typically equivalent +## with the originator, but does not have to be in all circumstances. +## +## certificate_types: List of the types of certificates that the client may offer. +## +## supported_signature_algorithms: List of hash/sighature algorithm pairs that the server +## supports, listed in descending order of preferences. +## +## certificate_authorities: List of distinguished names of certificate authorities that are +## acceptable to the server. The individual entries are DER encoded. +## :zeek:id:`parse_distinguished_name` can be used to decode the strings. +## +## .. zeek:see:: ssl_handshake_message x509_certificate ssl_server_hello ssl_client_hello +## parse_distinguished_name +event ssl_certificate_request%(c: connection, is_client: bool, certificate_types: index_vec, supported_signature_algorithms: SSL::SignatureAndHashAlgorithm, certificate_authorities: string_vec%); + diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif index 185d57a941..44d70edf8c 100644 --- a/src/analyzer/protocol/ssl/functions.bif +++ b/src/analyzer/protocol/ssl/functions.bif @@ -65,3 +65,35 @@ function set_keys%(c: connection, keys: string%): bool return zeek::val_mgr->False(); %} + +## Decodes a DER-encoded distinguished name into an ASCII string, +## using the RFC2253 representation +## +## dn: DER encoded distinguished name +## +## Returns: Ascii representation on success, empty string on failure +## +## .. zeek:see:: ssl_certificate_request +function parse_distinguished_name%(dn: string%): string + %{ + std::string out = ""; + const unsigned char* in = dn->Bytes(); + + X509_NAME* dn_x509 = d2i_X509_NAME(nullptr, &in, dn->Len()); + if ( ! dn_x509 ) + { + // we were not able to parse. Let's return an empty string. + return zeek::make_intrusive(""); + } + + char buf[256]; + memset(buf, 0, sizeof(buf)); + BIO* bio = BIO_new(BIO_s_mem()); + + X509_NAME_print_ex(bio, dn_x509, 0, XN_FLAG_RFC2253); + int len = BIO_gets(bio, buf, sizeof(buf)); + out.assign(buf, len); + BIO_free(bio); + X509_NAME_free(dn_x509); + return zeek::make_intrusive(out); + %} diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 9bfca7ac45..aa642e18f7 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -626,6 +626,47 @@ refine connection Handshake_Conn += { return true; %} + function proc_certificate_request(rec: HandshakeRecord, req: CertificateRequest) : bool + %{ + if ( ! ssl_certificate_request ) + return true; + + auto ctlist = zeek::make_intrusive(zeek::id::find_type("index_vec")); + auto ctypes = ${req.certificate_types}; + + if ( ctypes ) + for ( unsigned int i = 0; i < ctypes->size(); ++i) + ctlist->Assign(i, zeek::val_mgr->Count((*ctypes)[i])); + + auto slist = zeek::make_intrusive(zeek::id::find_type("signature_and_hashalgorithm_vec")); + if ( ${req.uses_signature_and_hashalgorithm} ) + { + auto sigalgs = ${req.supported_signature_algorithms.supported_signature_algorithms}; + + if ( sigalgs ) + { + for ( unsigned int i = 0; i < sigalgs->size(); ++i ) + { + auto el = zeek::make_intrusive(zeek::BifType::Record::SSL::SignatureAndHashAlgorithm); + el->Assign(0, (*sigalgs)[i]->HashAlgorithm()); + el->Assign(1, (*sigalgs)[i]->SignatureAlgorithm()); + slist->Assign(i, std::move(el)); + } + } + } + + + auto calist = zeek::make_intrusive(zeek::id::find_type("string_vec")); + auto certificate_authorities = ${req.certificate_authorities.certificate_authorities}; + if ( certificate_authorities ) + for ( unsigned int i = 0; i < certificate_authorities->size(); ++i ) + calist->Assign(i, zeek::make_intrusive((*certificate_authorities)[i]->certificate_authority().length(), (const char*) (*certificate_authorities)[i]->certificate_authority().data())); + + zeek::BifEvent::enqueue_ssl_certificate_request(zeek_analyzer(), zeek_analyzer()->Conn(), ${rec.is_orig} ^ flipped_, ctlist, slist, calist); + + return true; + %} + }; refine typeattr ClientHello += &let { @@ -754,3 +795,7 @@ refine typeattr Handshake += &let { refine typeattr SignedCertificateTimestamp += &let { proc : bool = $context.connection.proc_signedcertificatetimestamp(rec, version, logid, timestamp, digitally_signed_algorithms, digitally_signed_signature); }; + +refine typeattr CertificateRequest += &let { + proc: bool = $context.connection.proc_certificate_request(rec, this); +}; diff --git a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac index 9fd408e070..2aa6b6a45e 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac @@ -439,9 +439,30 @@ type DhAnonServerKeyExchange(rec: HandshakeRecord) = record { # V3 Certificate Request (7.4.4.) ###################################################################### +type CertificateAuthorities = record { + certificate_authority_len: uint16; + certificate_authority: bytestring &length=certificate_authority_len; +}; + +type CertificateAuthoritiesContainer = record { + certificate_authorities: CertificateAuthorities[] &until($input.length() == 0); +}; + # For now, ignore Certificate Request Details; just eat up message. type CertificateRequest(rec: HandshakeRecord) = record { + certificate_types_len: uint8; + certificate_types: uint8[certificate_types_len]; + alg: case uses_signature_and_hashalgorithm of { + true -> supported_signature_algorithms: SignatureAlgorithm(rec); + false -> nothing: bytestring &length=0; + } &requires(uses_signature_and_hashalgorithm); + certificate_authorities_len: uint16; + certificate_authorities: CertificateAuthoritiesContainer &length=certificate_authorities_len; cont : bytestring &restofdata &transient; +} &let { + uses_signature_and_hashalgorithm : bool = + ($context.connection.chosen_version() > TLSv11) && + ($context.connection.chosen_version() != DTLSv10); }; @@ -931,7 +952,7 @@ type PreSharedKey(rec: HandshakeRecord) = case rec.msg_type of { type SignatureAlgorithm(rec: HandshakeRecord) = record { length: uint16; supported_signature_algorithms: SignatureAndHashAlgorithm[] &until($input.length() == 0); -} +} &length=length+2; type EllipticCurves(rec: HandshakeRecord) = record { length: uint16; diff --git a/testing/btest/Baseline/bifs.x509_parse_dn/.stdout b/testing/btest/Baseline/bifs.x509_parse_dn/.stdout new file mode 100644 index 0000000000..b969b22d39 --- /dev/null +++ b/testing/btest/Baseline/bifs.x509_parse_dn/.stdout @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CN=certauth.idrix.fr + +CN=Senate PIV-I CA G4,OU=Office of the Sergeant at Arms,OU=U.S. Senate,O=U.S. Government,C=US +OU=\E3\82\A2\E3\83\97\E3\83\AA\E3\82\B1\E3\83\BC\E3\82\B7\E3\83\A7\E3\83\B3CA,O=\E6\97\A5\E6\9C\AC\E5\9B\BD\E6\94\BF\E5\BA\9C,C=JP diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.certificate_request/out b/testing/btest/Baseline/scripts.base.protocols.ssl.certificate_request/out new file mode 100644 index 0000000000..af3be60949 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.certificate_request/out @@ -0,0 +1,15 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[1, 2, 64] +[[HashAlgorithm=4, SignatureAlgorithm=3], [HashAlgorithm=5, SignatureAlgorithm=3], [HashAlgorithm=6, SignatureAlgorithm=3], [HashAlgorithm=8, SignatureAlgorithm=7], [HashAlgorithm=8, SignatureAlgorithm=8], [HashAlgorithm=8, SignatureAlgorithm=9], [HashAlgorithm=8, SignatureAlgorithm=10], [HashAlgorithm=8, SignatureAlgorithm=11], [HashAlgorithm=8, SignatureAlgorithm=4], [HashAlgorithm=8, SignatureAlgorithm=5], [HashAlgorithm=8, SignatureAlgorithm=6], [HashAlgorithm=4, SignatureAlgorithm=1], [HashAlgorithm=5, SignatureAlgorithm=1], [HashAlgorithm=6, SignatureAlgorithm=1], [HashAlgorithm=3, SignatureAlgorithm=3], [HashAlgorithm=3, SignatureAlgorithm=1], [HashAlgorithm=3, SignatureAlgorithm=2], [HashAlgorithm=4, SignatureAlgorithm=2], [HashAlgorithm=5, SignatureAlgorithm=2], [HashAlgorithm=6, SignatureAlgorithm=2]] +======== +[1] +[[HashAlgorithm=4, SignatureAlgorithm=1]] +0H1\x0b0\x09\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\x0aSome-State1\x120\x10\x06\x03U\x04\x07\x0c\x09Somewhere1\x100\x0e\x06\x03U\x04\x0a\x0c\x07SomeOrg +O=SomeOrg,L=Somewhere,ST=Some-State,C=US +======== +[1, 64, 2] +[] +======== +[1, 2] +[] +======== diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.certificate-request-info/ssl.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.certificate-request-info/ssl.log new file mode 100644 index 0000000000..9898a0b74b --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.certificate-request-info/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert requested_client_certificate_authorities +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 fd42:496a:d659:bb85::1 52464 fd42:496a:d659:bb85:216:3eff:fe6a:a257 3000 TLSv12 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 x25519 - F handshake_failure - F CsxkrnXGIl 0a171ee771a26530c650fe8b8a6bf205177bfb64fbb3e5303ba348c13ffc7dfa,c628dd5aae1f216da6ce4f8f914fb7141c2b0afd3522cce5900bcc4840657bfd (empty) - O=SomeOrg\x2cL=Somewhere\x2cST=Some-State\x2cC=US +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/tls/certificate-request-failed.pcap b/testing/btest/Traces/tls/certificate-request-failed.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0191710fd7b3c0d278e4291004857a5006bd99e6 GIT binary patch literal 5355 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tls/client-certificate.pcap b/testing/btest/Traces/tls/client-certificate.pcap new file mode 100644 index 0000000000000000000000000000000000000000..cef1e8a5052051b541b12ddeb9b2878da064ca44 GIT binary patch literal 16382 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 XcYo*>9gue}m~{Qh5{H2-apeC1x2Ais literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/x509_parse_dn.zeek b/testing/btest/bifs/x509_parse_dn.zeek new file mode 100644 index 0000000000..2a3c169b71 --- /dev/null +++ b/testing/btest/bifs/x509_parse_dn.zeek @@ -0,0 +1,10 @@ +# @TEST-EXEC: zeek -b %INPUT +# @TEST-EXEC: btest-diff .stdout + +event zeek_init() + { + print parse_distinguished_name("0\x1c1\x1a0\x18\x06\x03U\x04\x03\x13\x11certauth.idrix.fr"); + print parse_distinguished_name("00000\x1c1\x1a0\x18\x06\x03U\x04\x03\x13\x11certauth.idrix.fr"); # invalid + print parse_distinguished_name("\x30\x81\x83\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x18\x30\x16\x06\x03\x55\x04\x0A\x13\x0F\x55\x2E\x53\x2E\x20\x47\x6F\x76\x65\x72\x6E\x6D\x65\x6E\x74\x31\x14\x30\x12\x06\x03\x55\x04\x0B\x13\x0B\x55\x2E\x53\x2E\x20\x53\x65\x6E\x61\x74\x65\x31\x27\x30\x25\x06\x03\x55\x04\x0B\x13\x1E\x4F\x66\x66\x69\x63\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x53\x65\x72\x67\x65\x61\x6E\x74\x20\x61\x74\x20\x41\x72\x6D\x73\x31\x1B\x30\x19\x06\x03\x55\x04\x03\x13\x12\x53\x65\x6E\x61\x74\x65\x20\x50\x49\x56\x2D\x49\x20\x43\x41\x20\x47\x34"); + print parse_distinguished_name("\x30\x4C\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x4A\x50\x31\x18\x30\x16\x06\x03\x55\x04\x0A\x0C\x0F\xE6\x97\xA5\xE6\x9C\xAC\xE5\x9B\xBD\xE6\x94\xBF\xE5\xBA\x9C\x31\x23\x30\x21\x06\x03\x55\x04\x0B\x0C\x1A\xE3\x82\xA2\xE3\x83\x97\xE3\x83\xAA\xE3\x82\xB1\xE3\x83\xBC\xE3\x82\xB7\xE3\x83\xA7\xE3\x83\xB3\x43\x41\x30"); + } diff --git a/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek b/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek new file mode 100644 index 0000000000..c6e80fb518 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek @@ -0,0 +1,22 @@ +# This tests the certificate_request message parsing + +# @TEST-EXEC: zeek -b -r $TRACES/tls/client-certificate.pcap %INPUT > out +# @TEST-EXEC: zeek -C -b -r $TRACES/tls/certificate-request-failed.pcap %INPUT >> out +# @TEST-EXEC: zeek -C -b -r $TRACES/tls/webrtc-stun.pcap %INPUT >> out +# @TEST-EXEC: zeek -C -b -r $TRACES/mysql/encrypted.trace %INPUT >> out +# @TEST-EXEC: btest-diff out + +@load base/protocols/ssl +@load base/protocols/mysql + +event ssl_certificate_request(c: connection, is_client: bool, certificate_types: index_vec, supported_signature_algorithms: SSL::SignatureAndHashAlgorithm, certificate_authorities: string_vec) + { + print certificate_types; + print supported_signature_algorithms; + for ( i in certificate_authorities ) + { + print certificate_authorities[i]; + print parse_distinguished_name(certificate_authorities[i]); + } + print "========"; + } diff --git a/testing/btest/scripts/policy/protocols/ssl/certificate-request-info.zeek b/testing/btest/scripts/policy/protocols/ssl/certificate-request-info.zeek new file mode 100644 index 0000000000..6b6afec279 --- /dev/null +++ b/testing/btest/scripts/policy/protocols/ssl/certificate-request-info.zeek @@ -0,0 +1,4 @@ +# @TEST-EXEC: zeek -C -r $TRACES/tls/certificate-request-failed.pcap %INPUT +# @TEST-EXEC: btest-diff ssl.log + +@load protocols/ssl/certificate-request-info diff --git a/testing/external/commit-hash.zeek-testing b/testing/external/commit-hash.zeek-testing index 1aede870dd..c99b22a8fa 100644 --- a/testing/external/commit-hash.zeek-testing +++ b/testing/external/commit-hash.zeek-testing @@ -1 +1 @@ -ce420be749831180789003152320cadb6c8101e1 +0afa1572c003bceccb6fc10a4c7865e8777799c9 diff --git a/testing/external/commit-hash.zeek-testing-private b/testing/external/commit-hash.zeek-testing-private index 859f3f5aa0..f8fc754c6f 100644 --- a/testing/external/commit-hash.zeek-testing-private +++ b/testing/external/commit-hash.zeek-testing-private @@ -1 +1 @@ -b78a6881733079ef5e17c4dea95a8a2566f8b3b8 \ No newline at end of file +a35c14be50c65604d31d672166bd1fef2791e6e9 From b8d658ac77d5ec0fc22c6c97d6695785d999fda4 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 15 Mar 2023 09:19:26 +0100 Subject: [PATCH 2/2] SSL/TLS CertificateRequest message: Address review feedback Minor stylistic changes; see https://github.com/zeek/zeek/pull/2855 for details --- .../policy/protocols/ssl/certificate-request-info.zeek | 4 ++-- src/analyzer/protocol/ssl/functions.bif | 5 ++--- src/analyzer/protocol/ssl/tls-handshake-analyzer.pac | 9 ++++++--- .../scripts/base/protocols/ssl/certificate_request.zeek | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/policy/protocols/ssl/certificate-request-info.zeek b/scripts/policy/protocols/ssl/certificate-request-info.zeek index 6eaa664077..0b22e48563 100644 --- a/scripts/policy/protocols/ssl/certificate-request-info.zeek +++ b/scripts/policy/protocols/ssl/certificate-request-info.zeek @@ -16,8 +16,8 @@ event ssl_certificate_request(c: connection, is_client: bool, certificate_types: return; local out: vector of string = vector(); - for ( i in certificate_authorities ) - out[i] = parse_distinguished_name(certificate_authorities[i]); + for ( _, ca in certificate_authorities ) + out += parse_distinguished_name(ca); c$ssl$requested_client_certificate_authorities = out; } diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif index 44d70edf8c..2e91190b73 100644 --- a/src/analyzer/protocol/ssl/functions.bif +++ b/src/analyzer/protocol/ssl/functions.bif @@ -76,7 +76,6 @@ function set_keys%(c: connection, keys: string%): bool ## .. zeek:see:: ssl_certificate_request function parse_distinguished_name%(dn: string%): string %{ - std::string out = ""; const unsigned char* in = dn->Bytes(); X509_NAME* dn_x509 = d2i_X509_NAME(nullptr, &in, dn->Len()); @@ -92,8 +91,8 @@ function parse_distinguished_name%(dn: string%): string X509_NAME_print_ex(bio, dn_x509, 0, XN_FLAG_RFC2253); int len = BIO_gets(bio, buf, sizeof(buf)); - out.assign(buf, len); + auto out = zeek::make_intrusive(len, buf); BIO_free(bio); X509_NAME_free(dn_x509); - return zeek::make_intrusive(out); + return out; %} diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index aa642e18f7..ce19a4b2a9 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -631,7 +631,7 @@ refine connection Handshake_Conn += { if ( ! ssl_certificate_request ) return true; - auto ctlist = zeek::make_intrusive(zeek::id::find_type("index_vec")); + auto ctlist = zeek::make_intrusive(zeek::id::index_vec); auto ctypes = ${req.certificate_types}; if ( ctypes ) @@ -656,11 +656,14 @@ refine connection Handshake_Conn += { } - auto calist = zeek::make_intrusive(zeek::id::find_type("string_vec")); + auto calist = zeek::make_intrusive(zeek::id::string_vec); auto certificate_authorities = ${req.certificate_authorities.certificate_authorities}; if ( certificate_authorities ) for ( unsigned int i = 0; i < certificate_authorities->size(); ++i ) - calist->Assign(i, zeek::make_intrusive((*certificate_authorities)[i]->certificate_authority().length(), (const char*) (*certificate_authorities)[i]->certificate_authority().data())); + { + auto ca = (*certificate_authorities)[i]->certificate_authority(); + calist->Assign(i, zeek::make_intrusive(ca.length(), (const char*) ca.data())); + } zeek::BifEvent::enqueue_ssl_certificate_request(zeek_analyzer(), zeek_analyzer()->Conn(), ${rec.is_orig} ^ flipped_, ctlist, slist, calist); diff --git a/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek b/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek index c6e80fb518..259eca3ed8 100644 --- a/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek +++ b/testing/btest/scripts/base/protocols/ssl/certificate_request.zeek @@ -13,10 +13,10 @@ event ssl_certificate_request(c: connection, is_client: bool, certificate_types: { print certificate_types; print supported_signature_algorithms; - for ( i in certificate_authorities ) + for ( _, ca in certificate_authorities ) { - print certificate_authorities[i]; - print parse_distinguished_name(certificate_authorities[i]); + print ca; + print parse_distinguished_name(ca); } print "========"; }