mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge remote-tracking branch 'origin/topic/johanna/gh-859'
* origin/topic/johanna/gh-859: Add X509/SSL changes to NEWS X509: add check if function succeeds GH-1634: Address feedback Small indentation fixes in ssl-log-ext.zeek Fix memory leak in x509_check_cert_hostname bif Small bugfix and updates for external test hashes (SSL/X509) Baseline updates for recent SSL changes. Add ability to check if hostname is valid for a specific cert Add ssl_history field to ssl.log Add policy script suppressing certificate events Add new ssl-log-ext policy script Deprecate extract-certs-pem.zeek and add log-certs-base64.zeek Implement X509 certificate log caching Deprecate ICSI SSL notary script. Change SSL and X.509 logging format Enable OCSP logging by default. Split the code that handles X509 event hashing into its own file Closes GH-859
This commit is contained in:
commit
7ec50bf434
130 changed files with 2358 additions and 711 deletions
|
@ -107,7 +107,8 @@ event ssl_established(c: connection) &priority=5
|
|||
|
||||
function data_channel_initial_criteria(c: connection): bool
|
||||
{
|
||||
return ( c?$ssl && c$ssl?$client_subject && c$ssl?$subject &&
|
||||
return ( c?$ssl && c$ssl?$cert_chain && c$ssl?$client_cert_chain &&
|
||||
|c$ssl$cert_chain| > 0 && |c$ssl$client_cert_chain| > 0 &&
|
||||
c$ssl?$cipher && /WITH_NULL/ in c$ssl$cipher );
|
||||
}
|
||||
|
||||
|
|
|
@ -6,27 +6,37 @@
|
|||
module SSL;
|
||||
|
||||
export {
|
||||
## Set this to true to includd the server certificate subject and
|
||||
## issuer from the SSL log file. This information is still available
|
||||
## in x509.log.
|
||||
const log_include_server_certificate_subject_issuer = F &redef;
|
||||
|
||||
## Set this to true to include the client certificate subject
|
||||
## and issuer in the SSL logfile. This information is rarely present
|
||||
## and probably only interesting in very specific circumstances
|
||||
const log_include_client_certificate_subject_issuer = F &redef;
|
||||
|
||||
redef record Info += {
|
||||
## Chain of certificates offered by the server to validate its
|
||||
## complete signing chain.
|
||||
cert_chain: vector of Files::Info &optional;
|
||||
|
||||
## An ordered vector of all certificate file unique IDs for the
|
||||
## An ordered vector of all certificate fingerprints for the
|
||||
## certificates offered by the server.
|
||||
cert_chain_fuids: vector of string &optional &log;
|
||||
cert_chain_fps: vector of string &optional &log;
|
||||
|
||||
## Chain of certificates offered by the client to validate its
|
||||
## complete signing chain.
|
||||
client_cert_chain: vector of Files::Info &optional;
|
||||
|
||||
## An ordered vector of all certificate file unique IDs for the
|
||||
## An ordered vector of all certificate fingerprints for the
|
||||
## certificates offered by the client.
|
||||
client_cert_chain_fuids: vector of string &optional &log;
|
||||
client_cert_chain_fps: vector of string &optional &log;
|
||||
|
||||
## Subject of the X.509 certificate offered by the server.
|
||||
subject: string &log &optional;
|
||||
|
||||
## Subject of the signer of the X.509 certificate offered by the
|
||||
## Issuer of the signer of the X.509 certificate offered by the
|
||||
## server.
|
||||
issuer: string &log &optional;
|
||||
|
||||
|
@ -37,6 +47,11 @@ export {
|
|||
## client.
|
||||
client_issuer: string &log &optional;
|
||||
|
||||
## Set to true if the hostname sent in the SNI matches the certificate.
|
||||
## Set to false if they do not match. Unset if the client did not send
|
||||
## an SNI.
|
||||
sni_matches_cert: bool &log &optional;
|
||||
|
||||
## Current number of certificates seen from either side. Used
|
||||
## to create file handles.
|
||||
server_depth: count &default=0;
|
||||
|
@ -88,6 +103,25 @@ event zeek_init() &priority=5
|
|||
Files::register_protocol(Analyzer::ANALYZER_DTLS,
|
||||
[$get_file_handle = SSL::get_file_handle,
|
||||
$describe = SSL::describe_file]);
|
||||
|
||||
|
||||
local ssl_filter = Log::get_filter(SSL::LOG, "default");
|
||||
if ( ssl_filter$name != "<not found>" )
|
||||
{
|
||||
if ( ! ssl_filter?$exclude )
|
||||
ssl_filter$exclude = set();
|
||||
if ( ! log_include_server_certificate_subject_issuer )
|
||||
{
|
||||
add ssl_filter$exclude["subject"];
|
||||
add ssl_filter$exclude["issuer"];
|
||||
}
|
||||
if ( ! log_include_client_certificate_subject_issuer )
|
||||
{
|
||||
add ssl_filter$exclude["client_subject"];
|
||||
add ssl_filter$exclude["client_issuer"];
|
||||
}
|
||||
Log::add_filter(SSL::LOG, ssl_filter);
|
||||
}
|
||||
}
|
||||
|
||||
event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
|
||||
|
@ -114,28 +148,39 @@ event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
|
|||
{
|
||||
c$ssl$cert_chain = vector();
|
||||
c$ssl$client_cert_chain = vector();
|
||||
c$ssl$cert_chain_fuids = string_vec();
|
||||
c$ssl$client_cert_chain_fuids = string_vec();
|
||||
c$ssl$cert_chain_fps = string_vec();
|
||||
c$ssl$client_cert_chain_fps = string_vec();
|
||||
}
|
||||
|
||||
if ( f$is_orig )
|
||||
{
|
||||
c$ssl$client_cert_chain += f$info;
|
||||
c$ssl$client_cert_chain_fuids += f$id;
|
||||
}
|
||||
else
|
||||
{
|
||||
c$ssl$cert_chain += f$info;
|
||||
c$ssl$cert_chain_fuids += f$id;
|
||||
}
|
||||
}
|
||||
|
||||
event ssl_established(c: connection) &priority=6
|
||||
hook ssl_finishing(c: connection) &priority=20
|
||||
{
|
||||
# update subject and issuer information
|
||||
if ( c$ssl?$cert_chain)
|
||||
for ( i in c$ssl$cert_chain )
|
||||
if ( c$ssl$cert_chain[i]?$x509 && c$ssl$cert_chain[i]$x509?$fingerprint )
|
||||
c$ssl$cert_chain_fps += c$ssl$cert_chain[i]$x509$fingerprint;
|
||||
|
||||
if ( c$ssl?$client_cert_chain )
|
||||
for ( i in c$ssl$client_cert_chain )
|
||||
if ( c$ssl$client_cert_chain[i]?$x509 && c$ssl$client_cert_chain[i]$x509?$fingerprint )
|
||||
c$ssl$client_cert_chain_fps += c$ssl$client_cert_chain[i]$x509$fingerprint;
|
||||
|
||||
if ( c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 &&
|
||||
c$ssl$cert_chain[0]?$x509 )
|
||||
{
|
||||
if ( c$ssl?$server_name )
|
||||
{
|
||||
if ( x509_check_cert_hostname(c$ssl$cert_chain[0]$x509$handle, c$ssl$server_name) != "" )
|
||||
c$ssl$sni_matches_cert = T;
|
||||
else
|
||||
c$ssl$sni_matches_cert = F;
|
||||
}
|
||||
|
||||
c$ssl$subject = c$ssl$cert_chain[0]$x509$certificate$subject;
|
||||
c$ssl$issuer = c$ssl$cert_chain[0]$x509$certificate$issuer;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,36 @@ export {
|
|||
## Flag to indicate if this record already has been logged, to
|
||||
## prevent duplicates.
|
||||
logged: bool &default=F;
|
||||
|
||||
## SSL history showing which types of packets we received in which order.
|
||||
## Letters have the following meaning with client-sent letters being capitalized:
|
||||
## H hello_request
|
||||
## C client_hello
|
||||
## S server_hello
|
||||
## V hello_verify_request
|
||||
## T NewSessionTicket
|
||||
## X certificate
|
||||
## K server_key_exchange
|
||||
## R certificate_request
|
||||
## N server_hello_done
|
||||
## Y certificate_verify
|
||||
## G client_key_exchange
|
||||
## F finished
|
||||
## W certificate_url
|
||||
## U certificate_status
|
||||
## A supplemental_data
|
||||
## Z unassigned_handshake_type
|
||||
## I change_cipher_spec
|
||||
## B heartbeat
|
||||
## D application_data
|
||||
## E end_of_early_data
|
||||
## O encrypted_extensions
|
||||
## P key_update
|
||||
## M message_hash
|
||||
## J hello_retry_request
|
||||
## L alert
|
||||
## Q unknown_content_type
|
||||
ssl_history: string &log &default="";
|
||||
};
|
||||
|
||||
## The default root CA bundle. By default, the mozilla-ca-list.zeek
|
||||
|
@ -145,7 +175,8 @@ const dtls_ports = { 443/udp };
|
|||
|
||||
redef likely_server_ports += { ssl_ports, dtls_ports };
|
||||
|
||||
event zeek_init() &priority=5
|
||||
# Priority needs to be higher than priority of zeek_init in ssl/files.zeek
|
||||
event zeek_init() &priority=6
|
||||
{
|
||||
Log::create_stream(SSL::LOG, [$columns=Info, $ev=log_ssl, $path="ssl", $policy=log_policy]);
|
||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SSL, ssl_ports);
|
||||
|
@ -161,6 +192,14 @@ function set_session(c: connection)
|
|||
}
|
||||
}
|
||||
|
||||
function add_to_history(c: connection, is_orig: bool, char: string)
|
||||
{
|
||||
if ( is_orig )
|
||||
c$ssl$ssl_history = c$ssl$ssl_history+to_upper(char);
|
||||
else
|
||||
c$ssl$ssl_history = c$ssl$ssl_history+to_lower(char);
|
||||
}
|
||||
|
||||
function delay_log(info: Info, token: string)
|
||||
{
|
||||
if ( ! info?$delay_tokens )
|
||||
|
@ -295,6 +334,75 @@ event ssl_handshake_message(c: connection, is_orig: bool, msg_type: count, lengt
|
|||
|
||||
if ( is_orig && msg_type == SSL::CLIENT_KEY_EXCHANGE )
|
||||
c$ssl$client_key_exchange_seen = T;
|
||||
|
||||
switch ( msg_type )
|
||||
{
|
||||
case SSL::HELLO_REQUEST:
|
||||
add_to_history(c, is_orig, "h");
|
||||
break;
|
||||
case SSL::CLIENT_HELLO:
|
||||
add_to_history(c, is_orig, "c");
|
||||
break;
|
||||
case SSL::SERVER_HELLO:
|
||||
add_to_history(c, is_orig, "s");
|
||||
break;
|
||||
case SSL::HELLO_VERIFY_REQUEST:
|
||||
add_to_history(c, is_orig, "v");
|
||||
break;
|
||||
case SSL::SESSION_TICKET:
|
||||
add_to_history(c, is_orig, "t");
|
||||
break;
|
||||
# end of early data
|
||||
case 5:
|
||||
add_to_history(c, is_orig, "e");
|
||||
break;
|
||||
case SSL::HELLO_RETRY_REQUEST:
|
||||
add_to_history(c, is_orig, "j");
|
||||
break;
|
||||
case SSL::ENCRYPTED_EXTENSIONS:
|
||||
add_to_history(c, is_orig, "o");
|
||||
break;
|
||||
case SSL::CERTIFICATE:
|
||||
add_to_history(c, is_orig, "x");
|
||||
break;
|
||||
case SSL::SERVER_KEY_EXCHANGE:
|
||||
add_to_history(c, is_orig, "k");
|
||||
break;
|
||||
case SSL::CERTIFICATE_REQUEST:
|
||||
add_to_history(c, is_orig, "r");
|
||||
break;
|
||||
case SSL::SERVER_HELLO_DONE:
|
||||
add_to_history(c, is_orig, "n");
|
||||
break;
|
||||
case SSL::CERTIFICATE_VERIFY:
|
||||
add_to_history(c, is_orig, "y");
|
||||
break;
|
||||
case SSL::CLIENT_KEY_EXCHANGE:
|
||||
add_to_history(c, is_orig, "g");
|
||||
break;
|
||||
case SSL::FINISHED:
|
||||
add_to_history(c, is_orig, "f");
|
||||
break;
|
||||
case SSL::CERTIFICATE_URL:
|
||||
add_to_history(c, is_orig, "w");
|
||||
break;
|
||||
case SSL::CERTIFICATE_STATUS:
|
||||
add_to_history(c, is_orig, "u");
|
||||
break;
|
||||
case SSL::SUPPLEMENTAL_DATA:
|
||||
add_to_history(c, is_orig, "a");
|
||||
break;
|
||||
case SSL::KEY_UPDATE:
|
||||
add_to_history(c, is_orig, "p");
|
||||
break;
|
||||
# message hash
|
||||
case 254:
|
||||
add_to_history(c, is_orig, "m");
|
||||
break;
|
||||
default:
|
||||
add_to_history(c, is_orig, "z");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# Extension event is fired _before_ the respective client or server hello.
|
||||
|
@ -318,6 +426,7 @@ event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &pri
|
|||
event ssl_change_cipher_spec(c: connection, is_orig: bool) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
add_to_history(c, is_orig, "i");
|
||||
|
||||
if ( is_orig && c$ssl$client_ticket_empty_session_seen && ! c$ssl$client_key_exchange_seen )
|
||||
c$ssl$resumed = T;
|
||||
|
@ -326,10 +435,17 @@ event ssl_change_cipher_spec(c: connection, is_orig: bool) &priority=5
|
|||
event ssl_alert(c: connection, is_orig: bool, level: count, desc: count) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
add_to_history(c, is_orig, "l");
|
||||
|
||||
c$ssl$last_alert = alert_descriptions[desc];
|
||||
}
|
||||
|
||||
event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string)
|
||||
{
|
||||
set_session(c);
|
||||
add_to_history(c, is_orig, "b");
|
||||
}
|
||||
|
||||
event ssl_established(c: connection) &priority=7
|
||||
{
|
||||
c$ssl$established = T;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue