Merge branch 'topic/johanna/signed_certificate_timestamp' into topic/johanna/ocsp-new

This commit is contained in:
Johanna Amann 2017-02-10 17:04:50 -08:00
commit b061a5db1a
17 changed files with 223 additions and 7 deletions

View file

@ -7,4 +7,5 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}
bro_plugin_begin(Bro X509)
bro_plugin_cc(X509.cc OCSP.cc Plugin.cc)
bro_plugin_bif(events.bif types.bif functions.bif ocsp_events.bif)
bro_plugin_pac(x509-extension.pac x509-signed_certificate_timestamp.pac)
bro_plugin_end()

View file

@ -4,6 +4,7 @@
#include "X509.h"
#include "Event.h"
#include "x509-extension_pac.h"
#include "events.bif.h"
#include "types.bif.h"
@ -301,6 +302,56 @@ void file_analysis::X509::ParseExtension(X509_EXTENSION* ex)
else if ( OBJ_obj2nid(ext_asn) == NID_subject_alt_name )
ParseSAN(ex);
#ifdef NID_ct_cert_scts
else if ( OBJ_obj2nid(ext_asn) == NID_ct_cert_scts || OBJ_obj2nid(ext_asn) == NID_ct_precert_scts )
#else
else if ( strcmp(oid, "1.3.6.1.4.1.11129.2.4.2") == 0 || strcmp(oid, "1.3.6.1.4.1.11129.2.4.4") == 0 )
#endif
ParseSignedCertificateTimestamps(ex);
}
void file_analysis::X509::ParseSignedCertificateTimestamps(X509_EXTENSION* ext)
{
// Ok, signed certificate timestamps are a bit of an odd case out; we don't
// want to use the (basically nonexistant) OpenSSL functionality to parse them.
// Instead we have our own, self-written binpac parser to parse just them,
// which we will initialize here and tear down immediately again.
ASN1_OCTET_STRING* ext_val = X509_EXTENSION_get_data(ext);
// the octet string of the extension contains the octet string which in turn
// contains the SCT. Obviously.
unsigned char* ext_val_copy = (unsigned char*) OPENSSL_malloc(ext_val->length);
unsigned char* ext_val_second_pointer = ext_val_copy;
memcpy(ext_val_copy, ext_val->data, ext_val->length);
ASN1_OCTET_STRING* inner = d2i_ASN1_OCTET_STRING(NULL, (const unsigned char**) &ext_val_copy, ext_val->length);
if ( !inner )
{
reporter->Error("X509::ParseSignedCertificateTimestamps could not parse inner octet string");
return;
}
binpac::X509Extension::MockConnection* conn = new binpac::X509Extension::MockConnection(this);
binpac::X509Extension::SignedCertTimestampExt* interp = new binpac::X509Extension::SignedCertTimestampExt(conn);
try
{
interp->NewData(inner->data, inner->data + inner->length);
}
catch( const binpac::Exception& e )
{
// throw a warning or sth
reporter->Error("X509::ParseSignedCertificateTimestamps could not parse SCT");
}
OPENSSL_free(ext_val_second_pointer);
interp->FlowEOF();
delete interp;
delete conn;
}
void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)

View file

@ -58,6 +58,7 @@ private:
void ParseExtension(X509_EXTENSION* ex);
void ParseBasicConstraints(X509_EXTENSION* ex);
void ParseSAN(X509_EXTENSION* ex);
void ParseSignedCertificateTimestamps(X509_EXTENSION* ext);
std::string cert_data;

View file

@ -55,3 +55,22 @@ event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%);
## x509_parse x509_verify
## x509_get_certificate_string
event x509_ext_subject_alternative_name%(f: fa_file, ext: X509::SubjectAlternativeName%);
## Generated for the signed_certificate_timestamp X509 extension as defined in
## :rfc:`6962`. The extension is used to transmit signed proofs that are
## used for Certificate Transparency.
##
## f: The file.
##
## version: the version of the protocol to which the SCT conforms. Always
## should be 0 (representing version 1)
##
## logid: 32 bit key id
##
## timestamp: the timestamp of the sct
##
## signature_and_hashalgorithm: signature and hash algorithm used for the
## digitally_signed struct
##
## signature: signature part of the digitally_signed struct
event x509_ext_signed_certificate_timestamp%(f: fa_file, version: count, logid: string, timestamp: time, hash_algorithm: count, signature_algorithm: count, signature: string%);

View file

@ -0,0 +1,54 @@
# Binpac analyzer for X.509 extensions
# we just use it for the SignedCertificateTimestamp at the moment
%include binpac.pac
%include bro.pac
%extern{
#include "types.bif.h"
#include "file_analysis/File.h"
#include "events.bif.h"
%}
analyzer X509Extension withcontext {
connection: MockConnection;
flow: SignedCertTimestampExt;
};
connection MockConnection(bro_analyzer: BroFileAnalyzer) {
upflow = SignedCertTimestampExt;
downflow = SignedCertTimestampExt;
};
%include x509-signed_certificate_timestamp.pac
# The base record
type HandshakeRecord() = record {
signed_certificate_timestamp_list: SignedCertificateTimestampList(this)[] &transient;
} &byteorder = bigendian;
flow SignedCertTimestampExt {
flowunit = HandshakeRecord withcontext(connection, this);
};
refine connection MockConnection += {
function proc_signedcertificatetimestamp(rec: HandshakeRecord, version: uint8, logid: const_bytestring, timestamp: uint64, digitally_signed_algorithms: SignatureAndHashAlgorithm, digitally_signed_signature: const_bytestring) : bool
%{
BifEvent::generate_x509_ext_signed_certificate_timestamp((analyzer::Analyzer *) bro_analyzer(),
bro_analyzer()->GetFile()->GetVal()->Ref(),
version,
new StringVal(logid.length(), reinterpret_cast<const char*>(logid.begin())),
((double)timestamp)/1000,
digitally_signed_algorithms->HashAlgorithm(),
digitally_signed_algorithms->SignatureAlgorithm(),
new StringVal(digitally_signed_signature.length(), reinterpret_cast<const char*>(digitally_signed_signature.begin()))
);
return true;
%}
};
refine typeattr SignedCertificateTimestamp += &let {
proc : bool = $context.connection.proc_signedcertificatetimestamp(rec, version, logid, timestamp, digitally_signed_algorithms, digitally_signed_signature);
};

View file

@ -0,0 +1 @@
../../../analyzer/protocol/ssl/tls-handshake-signed_certificate_timestamp.pac