mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Second try on the event interface.
Now the x509 opaque is wrapped in the certificate structure. After pondering on it for a bit, this might not be the brightest idea.
This commit is contained in:
parent
1735e33691
commit
7ba6bcff2c
7 changed files with 40 additions and 62 deletions
|
@ -12,17 +12,17 @@ event x509_cert(f: fa_file, cert: X509::Certificate)
|
||||||
print cert;
|
print cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
event x509_extension(f: fa_file, ext: X509::Extension)
|
event x509_extension(f: fa_file, cert: X509::Certificate, ext: X509::Extension)
|
||||||
{
|
{
|
||||||
print ext;
|
print ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
event x509_ext_basic_constraints(f: fa_file, ext: X509::BasicConstraints)
|
event x509_ext_basic_constraints(f: fa_file, cert: X509::Certificate, ext: X509::BasicConstraints)
|
||||||
{
|
{
|
||||||
print ext;
|
print ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
event x509_ext_subject_alternative_name(f: fa_file, ext: X509::SubjectAlternativeName)
|
event x509_ext_subject_alternative_name(f: fa_file, cert: X509::Certificate, ext: X509::SubjectAlternativeName)
|
||||||
{
|
{
|
||||||
print ext;
|
print ext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2420,29 +2420,6 @@ global dns_skip_all_addl = T &redef;
|
||||||
## traffic and do not process it. Set to 0 to turn off this functionality.
|
## traffic and do not process it. Set to 0 to turn off this functionality.
|
||||||
global dns_max_queries = 5;
|
global dns_max_queries = 5;
|
||||||
|
|
||||||
## An X509 certificate.
|
|
||||||
##
|
|
||||||
## .. bro:see:: x509_certificate
|
|
||||||
type X509: record {
|
|
||||||
version: count; ##< Version number.
|
|
||||||
serial: string; ##< Serial number.
|
|
||||||
subject: string; ##< Subject.
|
|
||||||
issuer: string; ##< Issuer.
|
|
||||||
not_valid_before: time; ##< Timestamp before when certificate is not valid.
|
|
||||||
not_valid_after: time; ##< Timestamp after when certificate is not valid.
|
|
||||||
};
|
|
||||||
|
|
||||||
## An X509 extension.
|
|
||||||
##
|
|
||||||
## .. bro:see:: x509_extension
|
|
||||||
type X509_extension_info: record {
|
|
||||||
name: string; ##< Long name of extension; oid if name not known.
|
|
||||||
short_name: string &optional; ##< Short name of extension if known.
|
|
||||||
oid: string; ##< Oid of extension.
|
|
||||||
critical: bool; ##< True if extension is critical.
|
|
||||||
value: string; ##< Extension content parsed to string for known extensions. Raw data otherwise.
|
|
||||||
};
|
|
||||||
|
|
||||||
## HTTP session statistics.
|
## HTTP session statistics.
|
||||||
##
|
##
|
||||||
## .. bro:see:: http_stats
|
## .. bro:see:: http_stats
|
||||||
|
@ -2767,6 +2744,7 @@ export {
|
||||||
module X509;
|
module X509;
|
||||||
export {
|
export {
|
||||||
type X509::Certificate: record {
|
type X509::Certificate: record {
|
||||||
|
certificate: opaque of x509; ##< OpenSSL certificate reference
|
||||||
version: count; ##< Version number.
|
version: count; ##< Version number.
|
||||||
serial: string; ##< Serial number.
|
serial: string; ##< Serial number.
|
||||||
subject: string; ##< Subject.
|
subject: string; ##< Subject.
|
||||||
|
@ -2799,7 +2777,6 @@ export {
|
||||||
type X509::SubjectAlternativeName: record {
|
type X509::SubjectAlternativeName: record {
|
||||||
names: vector of string;
|
names: vector of string;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module SOCKS;
|
module SOCKS;
|
||||||
|
|
|
@ -47,9 +47,6 @@ int tcp_max_initial_window;
|
||||||
int tcp_max_above_hole_without_any_acks;
|
int tcp_max_above_hole_without_any_acks;
|
||||||
int tcp_excessive_data_without_further_acks;
|
int tcp_excessive_data_without_further_acks;
|
||||||
|
|
||||||
RecordType* x509_type;
|
|
||||||
RecordType* x509_extension_type;
|
|
||||||
|
|
||||||
RecordType* socks_address;
|
RecordType* socks_address;
|
||||||
|
|
||||||
double non_analyzed_lifetime;
|
double non_analyzed_lifetime;
|
||||||
|
@ -356,9 +353,6 @@ void init_net_var()
|
||||||
tcp_excessive_data_without_further_acks =
|
tcp_excessive_data_without_further_acks =
|
||||||
opt_internal_int("tcp_excessive_data_without_further_acks");
|
opt_internal_int("tcp_excessive_data_without_further_acks");
|
||||||
|
|
||||||
x509_type = internal_type("X509")->AsRecordType();
|
|
||||||
x509_extension_type = internal_type("X509_extension_info")->AsRecordType();
|
|
||||||
|
|
||||||
socks_address = internal_type("SOCKS::Address")->AsRecordType();
|
socks_address = internal_type("SOCKS::Address")->AsRecordType();
|
||||||
|
|
||||||
non_analyzed_lifetime = opt_internal_double("non_analyzed_lifetime");
|
non_analyzed_lifetime = opt_internal_double("non_analyzed_lifetime");
|
||||||
|
|
|
@ -50,9 +50,6 @@ extern int tcp_max_initial_window;
|
||||||
extern int tcp_max_above_hole_without_any_acks;
|
extern int tcp_max_above_hole_without_any_acks;
|
||||||
extern int tcp_excessive_data_without_further_acks;
|
extern int tcp_excessive_data_without_further_acks;
|
||||||
|
|
||||||
extern RecordType* x509_type;
|
|
||||||
extern RecordType* x509_extension_type;
|
|
||||||
|
|
||||||
extern RecordType* socks_address;
|
extern RecordType* socks_address;
|
||||||
|
|
||||||
extern double non_analyzed_lifetime;
|
extern double non_analyzed_lifetime;
|
||||||
|
|
|
@ -49,7 +49,7 @@ bool file_analysis::X509::EndOfFile()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseCertificate(ssl_cert);
|
RecordVal* cert_record = ParseCertificate(ssl_cert); // cert_record takes ownership of ssl_cert
|
||||||
|
|
||||||
// after parsing the certificate - parse the extensions...
|
// after parsing the certificate - parse the extensions...
|
||||||
|
|
||||||
|
@ -60,37 +60,43 @@ bool file_analysis::X509::EndOfFile()
|
||||||
if ( !ex )
|
if ( !ex )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ParseExtension(ex);
|
ParseExtension(ex, cert_record);
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_free(ssl_cert);
|
// X509_free(ssl_cert); We do _not_ free the certificate here. It is refcounted
|
||||||
|
// inside the X509Val that is sent on in the cert record to scriptland.
|
||||||
|
//
|
||||||
|
// The certificate will be freed when the last X509Val is Unref'd.
|
||||||
|
|
||||||
|
Unref(cert_record); // Unref the RecordVal that we kept around from ParseCertificate
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_analysis::X509::ParseCertificate(::X509* ssl_cert)
|
RecordVal* file_analysis::X509::ParseCertificate(::X509* ssl_cert)
|
||||||
{
|
{
|
||||||
char buf[256]; // we need a buffer for some of the openssl functions
|
char buf[256]; // we need a buffer for some of the openssl functions
|
||||||
memset(buf, 0, 256);
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
RecordVal* pX509Cert = new RecordVal(BifType::Record::X509::Certificate);
|
RecordVal* pX509Cert = new RecordVal(BifType::Record::X509::Certificate);
|
||||||
BIO *bio = BIO_new(BIO_s_mem());
|
BIO *bio = BIO_new(BIO_s_mem());
|
||||||
|
|
||||||
pX509Cert->Assign(0, new Val((uint64) X509_get_version(ssl_cert), TYPE_COUNT));
|
pX509Cert->Assign(0, new X509Val(ssl_cert)); // take ownership for cleanup
|
||||||
|
pX509Cert->Assign(1, new Val((uint64) X509_get_version(ssl_cert), TYPE_COUNT));
|
||||||
i2a_ASN1_INTEGER(bio, X509_get_serialNumber(ssl_cert));
|
i2a_ASN1_INTEGER(bio, X509_get_serialNumber(ssl_cert));
|
||||||
int len = BIO_read(bio, &(*buf), sizeof buf);
|
int len = BIO_read(bio, &(*buf), sizeof buf);
|
||||||
pX509Cert->Assign(1, new StringVal(len, buf));
|
pX509Cert->Assign(2, new StringVal(len, buf));
|
||||||
|
|
||||||
X509_NAME_print_ex(bio, X509_get_subject_name(ssl_cert), 0, XN_FLAG_RFC2253);
|
X509_NAME_print_ex(bio, X509_get_subject_name(ssl_cert), 0, XN_FLAG_RFC2253);
|
||||||
len = BIO_gets(bio, &(*buf), sizeof buf);
|
len = BIO_gets(bio, &(*buf), sizeof buf);
|
||||||
pX509Cert->Assign(2, new StringVal(len, buf));
|
pX509Cert->Assign(3, new StringVal(len, buf));
|
||||||
X509_NAME_print_ex(bio, X509_get_issuer_name(ssl_cert), 0, XN_FLAG_RFC2253);
|
X509_NAME_print_ex(bio, X509_get_issuer_name(ssl_cert), 0, XN_FLAG_RFC2253);
|
||||||
len = BIO_gets(bio, &(*buf), sizeof buf);
|
len = BIO_gets(bio, &(*buf), sizeof buf);
|
||||||
pX509Cert->Assign(3, new StringVal(len, buf));
|
pX509Cert->Assign(4, new StringVal(len, buf));
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
|
||||||
pX509Cert->Assign(4, new Val(get_time_from_asn1(X509_get_notBefore(ssl_cert)), TYPE_TIME));
|
pX509Cert->Assign(5, new Val(get_time_from_asn1(X509_get_notBefore(ssl_cert)), TYPE_TIME));
|
||||||
pX509Cert->Assign(5, new Val(get_time_from_asn1(X509_get_notAfter(ssl_cert)), TYPE_TIME));
|
pX509Cert->Assign(6, new Val(get_time_from_asn1(X509_get_notAfter(ssl_cert)), TYPE_TIME));
|
||||||
|
|
||||||
// we only read 255 bytes because byte 256 is always 0.
|
// we only read 255 bytes because byte 256 is always 0.
|
||||||
// if the string is longer than 255, that will be our null-termination,
|
// if the string is longer than 255, that will be our null-termination,
|
||||||
|
@ -137,12 +143,14 @@ void file_analysis::X509::ParseCertificate(::X509* ssl_cert)
|
||||||
|
|
||||||
val_list* vl = new val_list();
|
val_list* vl = new val_list();
|
||||||
vl->append(GetFile()->GetVal()->Ref());
|
vl->append(GetFile()->GetVal()->Ref());
|
||||||
vl->append(pX509Cert);
|
vl->append(pX509Cert->Ref()); // we Ref it here, because we want to keep a copy around for now...
|
||||||
|
|
||||||
mgr.QueueEvent(x509_cert, vl);
|
mgr.QueueEvent(x509_cert, vl);
|
||||||
|
|
||||||
|
return pX509Cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_analysis::X509::ParseExtension(X509_EXTENSION* ex)
|
void file_analysis::X509::ParseExtension(X509_EXTENSION* ex, RecordVal* r)
|
||||||
{
|
{
|
||||||
char name[256];
|
char name[256];
|
||||||
char oid[256];
|
char oid[256];
|
||||||
|
@ -188,18 +196,19 @@ void file_analysis::X509::ParseExtension(X509_EXTENSION* ex)
|
||||||
// but I am not sure if there is a better way to do it...
|
// but I am not sure if there is a better way to do it...
|
||||||
val_list* vl = new val_list();
|
val_list* vl = new val_list();
|
||||||
vl->append(GetFile()->GetVal()->Ref());
|
vl->append(GetFile()->GetVal()->Ref());
|
||||||
|
vl->append(r->Ref());
|
||||||
vl->append(pX509Ext);
|
vl->append(pX509Ext);
|
||||||
|
|
||||||
mgr.QueueEvent(x509_extension, vl);
|
mgr.QueueEvent(x509_extension, vl);
|
||||||
|
|
||||||
// look if we have a specialized handler for this event...
|
// look if we have a specialized handler for this event...
|
||||||
if ( OBJ_obj2nid(ext_asn) == NID_basic_constraints )
|
if ( OBJ_obj2nid(ext_asn) == NID_basic_constraints )
|
||||||
ParseBasicConstraints(ex);
|
ParseBasicConstraints(ex, r);
|
||||||
else if ( OBJ_obj2nid(ext_asn) == NID_subject_alt_name )
|
else if ( OBJ_obj2nid(ext_asn) == NID_subject_alt_name )
|
||||||
ParseSAN(ex);
|
ParseSAN(ex, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
|
void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex, RecordVal* r)
|
||||||
{
|
{
|
||||||
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints);
|
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints);
|
||||||
|
|
||||||
|
@ -217,6 +226,7 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
|
||||||
}
|
}
|
||||||
val_list* vl = new val_list();
|
val_list* vl = new val_list();
|
||||||
vl->append(GetFile()->GetVal()->Ref());
|
vl->append(GetFile()->GetVal()->Ref());
|
||||||
|
vl->append(r->Ref());
|
||||||
vl->append(pBasicConstraint);
|
vl->append(pBasicConstraint);
|
||||||
|
|
||||||
mgr.QueueEvent(x509_ext_basic_constraints, vl);
|
mgr.QueueEvent(x509_ext_basic_constraints, vl);
|
||||||
|
@ -224,7 +234,7 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
|
void file_analysis::X509::ParseSAN(X509_EXTENSION* ext, RecordVal* r)
|
||||||
{
|
{
|
||||||
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name);
|
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name);
|
||||||
|
|
||||||
|
@ -268,6 +278,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
|
||||||
|
|
||||||
val_list* vl = new val_list();
|
val_list* vl = new val_list();
|
||||||
vl->append(GetFile()->GetVal()->Ref());
|
vl->append(GetFile()->GetVal()->Ref());
|
||||||
|
vl->append(r->Ref());
|
||||||
vl->append(pSan);
|
vl->append(pSan);
|
||||||
|
|
||||||
mgr.QueueEvent(x509_ext_basic_constraints, vl);
|
mgr.QueueEvent(x509_ext_basic_constraints, vl);
|
||||||
|
|
|
@ -31,10 +31,10 @@ private:
|
||||||
static StringVal* key_curve(EVP_PKEY *key);
|
static StringVal* key_curve(EVP_PKEY *key);
|
||||||
static unsigned int key_length(EVP_PKEY *key);
|
static unsigned int key_length(EVP_PKEY *key);
|
||||||
|
|
||||||
void ParseCertificate(::X509* ssl_cert);
|
RecordVal* ParseCertificate(::X509* ssl_cert);
|
||||||
void ParseExtension(X509_EXTENSION* ex);
|
void ParseExtension(X509_EXTENSION* ex, RecordVal* r);
|
||||||
void ParseBasicConstraints(X509_EXTENSION* ex);
|
void ParseBasicConstraints(X509_EXTENSION* ex, RecordVal* r);
|
||||||
void ParseSAN(X509_EXTENSION* ex);
|
void ParseSAN(X509_EXTENSION* ex, RecordVal* r);
|
||||||
|
|
||||||
std::string cert_data;
|
std::string cert_data;
|
||||||
};
|
};
|
||||||
|
@ -55,7 +55,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return A newly initialized X509Val
|
* @return A newly initialized X509Val
|
||||||
*/
|
*/
|
||||||
X509Val(::X509* certificate);
|
explicit X509Val(::X509* certificate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor.
|
* Destructor.
|
||||||
|
@ -84,5 +84,4 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
event x509_cert%(f: fa_file, cert: X509::Certificate%);
|
event x509_cert%(f: fa_file, cert: X509::Certificate%);
|
||||||
event x509_extension%(f: fa_file, ext: X509::Extension%);
|
event x509_extension%(f: fa_file, cert: X509::Certificate, ext: X509::Extension%);
|
||||||
event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%);
|
event x509_ext_basic_constraints%(f: fa_file, cert: X509::Certificate, ext: X509::BasicConstraints%);
|
||||||
event x509_ext_subject_alternative_name%(f: fa_file, ext: X509::SubjectAlternativeName%);
|
event x509_ext_subject_alternative_name%(f: fa_file, cert: X509::Certificate, ext: X509::SubjectAlternativeName%);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue