Fix x509_extension event.

The event now really returns the extension. If openssl supports printing
it, it is converted into the openssl ascii output.

The output does not always look pretty because it can contain newlines.

New event syntax:
event x509_extension(c: connection, is_orig: bool, cert:X509, extension: X509_extension_info)

Example output for extension:
  [name=X509v3 Extended Key Usage,
    short_name=extendedKeyUsage,
    oid=2.5.29.37,
    critical=F,
    value=TLS Web Server Authentication, TLS Web Client Authentication]
  [name=X509v3 Certificate Policies,
   short_name=certificatePolicies,
   oid=2.5.29.32,
   critical=F,
   value=Policy: 1.3.6.1.4.1.6449.1.2.1.3.4^J  CPS: https://secure.comodo.com/CPS^J]
This commit is contained in:
Bernhard Amann 2014-01-27 10:22:06 -08:00
parent 392d1cb759
commit 6d73b8c57e
7 changed files with 90 additions and 19 deletions

View file

@ -2432,6 +2432,18 @@ type X509: record {
not_valid_after: time; ##< Timestamp after 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

View file

@ -48,6 +48,7 @@ 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_type;
RecordType* x509_extension_type;
RecordType* socks_address; RecordType* socks_address;
@ -356,6 +357,7 @@ void init_net_var()
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_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();

View file

@ -51,6 +51,7 @@ 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_type;
extern RecordType* x509_extension_type;
extern RecordType* socks_address; extern RecordType* socks_address;

View file

@ -178,11 +178,13 @@ event x509_certificate%(c: connection, is_orig: bool, cert: X509, chain_idx: cou
## ##
## is_orig: True if event is raised for originator side of the connection. ## is_orig: True if event is raised for originator side of the connection.
## ##
## data: The raw data associated with the extension. ## cert: The parsed certificate.
##
## extension: The parsed extension.
## ##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
## ssl_server_hello x509_certificate x509_error x509_verify ## ssl_server_hello x509_certificate x509_error x509_verify
event x509_extension%(c: connection, is_orig: bool, data: string%); event x509_extension%(c: connection, is_orig: bool, cert: X509, extension: X509_extension_info%);
## Generated when errors occur during parsing an X509 certificate. ## Generated when errors occur during parsing an X509 certificate.
## ##

View file

@ -9,6 +9,7 @@
#include "util.h" #include "util.h"
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
%} %}
@ -298,25 +299,51 @@ refine connection SSL_Conn += {
int num_ext = X509_get_ext_count(pTemp); int num_ext = X509_get_ext_count(pTemp);
for ( int k = 0; k < num_ext; ++k ) for ( int k = 0; k < num_ext; ++k )
{ {
unsigned char *pBuffer = 0; char name[256];
int length = 0; char oid[256];
memset(name, 0, 256);
memset(oid, 0, 256);
X509_EXTENSION* ex = X509_get_ext(pTemp, k); X509_EXTENSION* ex = X509_get_ext(pTemp, k);
if (ex)
{ if ( !ex )
ASN1_STRING *pString = X509_EXTENSION_get_data(ex); continue;
length = ASN1_STRING_to_UTF8(&pBuffer, pString);
//i2t_ASN1_OBJECT(&pBuffer, length, obj) ASN1_OBJECT* ext_asn = X509_EXTENSION_get_object(ex);
// printf("extension length: %d\n", length); const char* short_name = OBJ_nid2sn(OBJ_obj2nid(ext_asn));
// -1 indicates an error.
if ( length >= 0 ) OBJ_obj2txt(name, 255, ext_asn, 0);
{ OBJ_obj2txt(oid, 255, ext_asn, 1);
StringVal* value = new StringVal(length, (char*)pBuffer);
BifEvent::generate_x509_extension(bro_analyzer(), int critical = 0;
bro_analyzer()->Conn(), ${rec.is_orig}, value); if ( X509_EXTENSION_get_critical(ex) != 0 )
} critical = 1;
OPENSSL_free(pBuffer);
} BIO *bio = BIO_new(BIO_s_mem());
if(!X509V3_EXT_print(bio, ex, 0, 0))
M_ASN1_OCTET_STRING_print(bio,ex->value);
BIO_flush(bio);
int length = BIO_pending(bio);
// use OPENSSL_malloc here. Using new or anything else can lead
// to interesting, hard to debug segfaults.
char *buffer = (char*) OPENSSL_malloc(length);
BIO_read(bio, buffer, length);
StringVal* ext_val = new StringVal(length, buffer);
BIO_free_all(bio);
OPENSSL_free(buffer);
RecordVal* pX509Ext = new RecordVal(x509_extension_type);
pX509Ext->Assign(0, new StringVal(name));
if ( short_name and strlen(short_name) > 0 )
pX509Ext->Assign(1, new StringVal(short_name));
pX509Ext->Assign(2, new StringVal(oid));
pX509Ext->Assign(3, new Val(critical, TYPE_BOOL));
pX509Ext->Assign(4, ext_val);
BifEvent::generate_x509_extension(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig}, pX509Cert->Ref(), pX509Ext);
} }
} }
X509_free(pTemp); X509_free(pTemp);

View file

@ -0,0 +1,20 @@
[name=X509v3 Authority Key Identifier, short_name=authorityKeyIdentifier, oid=2.5.29.35, critical=F, value=keyid:3F:D5:B5:D0:D6:44:79:50:4A:17:A3:9B:8C:4A:DC:B8:B0:22:64:6B^J]
[name=X509v3 Subject Key Identifier, short_name=subjectKeyIdentifier, oid=2.5.29.14, critical=F, value=A2:76:09:20:A8:40:FD:A1:AC:C8:E9:35:B9:11:A6:61:FF:8C:FF:A3]
[name=X509v3 Key Usage, short_name=keyUsage, oid=2.5.29.15, critical=T, value=Digital Signature, Key Encipherment]
[name=X509v3 Basic Constraints, short_name=basicConstraints, oid=2.5.29.19, critical=T, value=CA:FALSE]
[name=X509v3 Extended Key Usage, short_name=extendedKeyUsage, oid=2.5.29.37, critical=F, value=TLS Web Server Authentication, TLS Web Client Authentication]
[name=X509v3 Certificate Policies, short_name=certificatePolicies, oid=2.5.29.32, critical=F, value=Policy: 1.3.6.1.4.1.6449.1.2.1.3.4^J CPS: https://secure.comodo.com/CPS^J]
[name=X509v3 CRL Distribution Points, short_name=crlDistributionPoints, oid=2.5.29.31, critical=F, value=^JFull Name:^J URI:http://crl.comodoca.com/COMODOHigh-AssuranceSecureServerCA.crl^J]
[name=Authority Information Access, short_name=authorityInfoAccess, oid=1.3.6.1.5.5.7.1.1, critical=F, value=CA Issuers - URI:http://crt.comodoca.com/COMODOHigh-AssuranceSecureServerCA.crt^JOCSP - URI:http://ocsp.comodoca.com^J]
[name=X509v3 Subject Alternative Name, short_name=subjectAltName, oid=2.5.29.17, critical=F, value=DNS:*.taleo.net, DNS:taleo.net]
[name=X509v3 Authority Key Identifier, short_name=authorityKeyIdentifier, oid=2.5.29.35, critical=F, value=keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A^J]
[name=X509v3 Subject Key Identifier, short_name=subjectKeyIdentifier, oid=2.5.29.14, critical=F, value=3F:D5:B5:D0:D6:44:79:50:4A:17:A3:9B:8C:4A:DC:B8:B0:22:64:6B]
[name=X509v3 Key Usage, short_name=keyUsage, oid=2.5.29.15, critical=T, value=Certificate Sign, CRL Sign]
[name=X509v3 Basic Constraints, short_name=basicConstraints, oid=2.5.29.19, critical=T, value=CA:TRUE, pathlen:0]
[name=X509v3 Certificate Policies, short_name=certificatePolicies, oid=2.5.29.32, critical=F, value=Policy: X509v3 Any Policy^J]
[name=X509v3 CRL Distribution Points, short_name=crlDistributionPoints, oid=2.5.29.31, critical=F, value=^JFull Name:^J URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl^J]
[name=Authority Information Access, short_name=authorityInfoAccess, oid=1.3.6.1.5.5.7.1.1, critical=F, value=CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c^JCA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt^JOCSP - URI:http://ocsp.usertrust.com^J]
[name=X509v3 Subject Key Identifier, short_name=subjectKeyIdentifier, oid=2.5.29.14, critical=F, value=AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A]
[name=X509v3 Key Usage, short_name=keyUsage, oid=2.5.29.15, critical=F, value=Certificate Sign, CRL Sign]
[name=X509v3 Basic Constraints, short_name=basicConstraints, oid=2.5.29.19, critical=T, value=CA:TRUE]
[name=X509v3 Authority Key Identifier, short_name=authorityKeyIdentifier, oid=2.5.29.35, critical=F, value=keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A^JDirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root^Jserial:01^J]

View file

@ -0,0 +1,7 @@
# @TEST-EXEC: bro -r $TRACES/tls1.2.trace %INPUT
# @TEST-EXEC: btest-diff .stdout
event x509_extension(c: connection, is_orig: bool, cert:X509, extension: X509_extension_info)
{
print extension;
}