zeek/scripts/policy/protocols/ssl/known-certs.bro
Bernhard Amann 7eb6b5133e Fix circular reference problem and a few other small things.
SSL::Info now holds a reference to Files::Info instead of the
fa_files record.

Everything should work now, if everyone thinks that the interface is
ok I will update the test baselines in a bit.

addresses BIT-953, BIT-760
2014-03-04 05:30:32 -08:00

66 lines
2.2 KiB
Text

##! Log information about certificates while attempting to avoid duplicate
##! logging.
@load base/utils/directions-and-hosts
@load base/protocols/ssl
@load base/files/x509
module Known;
export {
redef enum Log::ID += { CERTS_LOG };
type CertsInfo: record {
## The timestamp when the certificate was detected.
ts: time &log;
## The address that offered the certificate.
host: addr &log;
## If the certificate was handed out by a server, this is the
## port that the server was listening on.
port_num: port &log &optional;
## Certificate subject.
subject: string &log &optional;
## Certificate issuer subject.
issuer_subject: string &log &optional;
## Serial number for the certificate.
serial: string &log &optional;
};
## The certificates whose existence should be logged and tracked.
## Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS.
const cert_tracking = LOCAL_HOSTS &redef;
## The set of all known certificates to store for preventing duplicate
## logging. It can also be used from other scripts to
## inspect if a certificate has been seen in use. The string value
## in the set is for storing the DER formatted certificate' SHA1 hash.
global certs: set[addr, string] &create_expire=1day &synchronized &redef;
## Event that can be handled to access the loggable record as it is sent
## on to the logging framework.
global log_known_certs: event(rec: CertsInfo);
}
event bro_init() &priority=5
{
Log::create_stream(Known::CERTS_LOG, [$columns=CertsInfo, $ev=log_known_certs]);
}
event ssl_established(c: connection) &priority=3
{
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| < 1 )
return;
local hash = c$ssl$cert_chain[0]$sha1;
local cert = c$ssl$cert_chain[0]$x509$certificate;
local host = c$id$resp_h;
if ( [host, hash] !in certs && addr_matches_host(host, cert_tracking) )
{
add certs[host, hash];
Log::write(Known::CERTS_LOG, [$ts=network_time(), $host=host,
$port_num=c$id$resp_p, $subject=cert$subject,
$issuer_subject=cert$issuer,
$serial=cert$serial]);
}
}