mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
rip out x509 code from ssl analyzer. Note that since at the moment
the file analyzer does not yet re-populate the info record that means quite a lot of information is simply not available.
This commit is contained in:
parent
df552ca87d
commit
2b87499fd9
7 changed files with 12 additions and 298 deletions
|
@ -168,49 +168,6 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, session
|
|||
c$ssl$cipher = cipher_desc[cipher];
|
||||
}
|
||||
|
||||
event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
# We aren't doing anything with client certificates yet.
|
||||
if ( is_orig )
|
||||
{
|
||||
if ( chain_idx == 0 )
|
||||
{
|
||||
# Save the primary cert.
|
||||
c$ssl$client_cert = der_cert;
|
||||
|
||||
# Also save other certificate information about the primary cert.
|
||||
c$ssl$client_subject = cert$subject;
|
||||
c$ssl$client_issuer_subject = cert$issuer;
|
||||
}
|
||||
else
|
||||
{
|
||||
# Otherwise, add it to the cert validation chain.
|
||||
c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = der_cert;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( chain_idx == 0 )
|
||||
{
|
||||
# Save the primary cert.
|
||||
c$ssl$cert = der_cert;
|
||||
|
||||
# Also save other certificate information about the primary cert.
|
||||
c$ssl$subject = cert$subject;
|
||||
c$ssl$issuer_subject = cert$issuer;
|
||||
c$ssl$not_valid_before = cert$not_valid_before;
|
||||
c$ssl$not_valid_after = cert$not_valid_after;
|
||||
}
|
||||
else
|
||||
{
|
||||
# Otherwise, add it to the cert validation chain.
|
||||
c$ssl$cert_chain[|c$ssl$cert_chain|] = der_cert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
|
|
@ -6,6 +6,5 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI
|
|||
bro_plugin_begin(Bro SSL)
|
||||
bro_plugin_cc(SSL.cc Plugin.cc)
|
||||
bro_plugin_bif(events.bif)
|
||||
bro_plugin_bif(functions.bif)
|
||||
bro_plugin_pac(ssl.pac ssl-analyzer.pac ssl-protocol.pac ssl-defs.pac)
|
||||
bro_plugin_end()
|
||||
|
|
|
@ -7,5 +7,4 @@ BRO_PLUGIN_BEGIN(Bro, SSL)
|
|||
BRO_PLUGIN_DESCRIPTION("SSL analyzer");
|
||||
BRO_PLUGIN_ANALYZER("SSL", ssl::SSL_Analyzer);
|
||||
BRO_PLUGIN_BIF_FILE(events);
|
||||
BRO_PLUGIN_BIF_FILE(functions);
|
||||
BRO_PLUGIN_END
|
||||
|
|
|
@ -27,8 +27,7 @@ public:
|
|||
static bool Available()
|
||||
{
|
||||
return ( ssl_client_hello || ssl_server_hello ||
|
||||
ssl_established || ssl_extension || ssl_alert ||
|
||||
x509_certificate || x509_error );
|
||||
ssl_established || ssl_extension || ssl_alert );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
## :bro:id:`SSL::cipher_desc` table maps them to descriptive names.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
## ssl_session_ticket_handshake
|
||||
event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%);
|
||||
|
||||
## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions
|
||||
|
@ -52,7 +52,7 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, sessio
|
|||
## standardized as part of the SSL/TLS protocol.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
## ssl_session_ticket_handshake
|
||||
event ssl_server_hello%(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count%);
|
||||
|
||||
## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS
|
||||
|
@ -71,7 +71,7 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, sessio
|
|||
## val: The raw extension value that was sent in the message.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
## ssl_session_ticket_handshake
|
||||
event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%);
|
||||
|
||||
## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with
|
||||
|
@ -86,7 +86,7 @@ event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%);
|
|||
## c: The connection.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_extension ssl_server_hello
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
## ssl_session_ticket_handshake
|
||||
event ssl_established%(c: connection%);
|
||||
|
||||
## Generated for SSL/TLS alert records. SSL/TLS sessions start with an
|
||||
|
@ -109,7 +109,7 @@ event ssl_established%(c: connection%);
|
|||
## defined as part of the SSL/TLS protocol.
|
||||
##
|
||||
## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
## ssl_session_ticket_handshake
|
||||
event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%);
|
||||
|
||||
## Generated for SSL/TLS handshake messages that are a part of the
|
||||
|
@ -130,66 +130,5 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%);
|
|||
## ticket: The raw ticket data.
|
||||
##
|
||||
## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello
|
||||
## x509_certificate x509_error x509_extension ssl_alert
|
||||
## ssl_alert
|
||||
event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%);
|
||||
|
||||
## Generated for X509 certificates seen in SSL/TLS connections. During the
|
||||
## initial SSL/TLS handshake, certificates are exchanged in the clear. Bro
|
||||
## raises this event for each certificate seen (including both a site's primary
|
||||
## cert, and further certs sent as part of the validation chain).
|
||||
##
|
||||
## See `Wikipedia <http://en.wikipedia.org/wiki/X.509>`__ for more information
|
||||
## about the X.509 format.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## is_orig: True if event is raised for originator side of the connection.
|
||||
##
|
||||
## cert: The parsed certificate.
|
||||
##
|
||||
## chain_idx: The index in the validation chain that this cert has. Index zero
|
||||
## indicates an endpoint's primary cert, while higher indices
|
||||
## indicate the place in the validation chain (which has length
|
||||
## *chain_len*).
|
||||
##
|
||||
## chain_len: The total length of the validation chain that this cert is part
|
||||
## of.
|
||||
##
|
||||
## der_cert: The complete cert encoded in `DER
|
||||
## <http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules>`__
|
||||
## format.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
|
||||
## ssl_server_hello x509_error x509_extension x509_verify
|
||||
event x509_certificate%(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string%);
|
||||
|
||||
## Generated for X509 extensions seen in a certificate.
|
||||
##
|
||||
## See `Wikipedia <http://en.wikipedia.org/wiki/X.509>`__ for more information
|
||||
## about the X.509 format.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## is_orig: True if event is raised for originator side of the connection.
|
||||
##
|
||||
## data: The raw data associated with the extension.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
|
||||
## ssl_server_hello x509_certificate x509_error x509_verify
|
||||
#event x509_extension%(c: connection, is_orig: bool, data: string%);
|
||||
|
||||
## Generated when errors occur during parsing an X509 certificate.
|
||||
##
|
||||
## See `Wikipedia <http://en.wikipedia.org/wiki/X.509>`__ for more information
|
||||
## about the X.509 format.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## is_orig: True if event is raised for originator side of the connection.
|
||||
##
|
||||
## err: An error code describing what went wrong. :bro:id:`SSL::x509_errors`
|
||||
## maps error codes to a textual description.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
|
||||
## ssl_server_hello x509_certificate x509_extension x509_err2str x509_verify
|
||||
event x509_error%(c: connection, is_orig: bool, err: count%);
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
|
||||
%%{
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
// This is the indexed map of X509 certificate stores.
|
||||
static map<Val*, X509_STORE*> x509_stores;
|
||||
|
||||
// ### NOTE: while d2i_X509 does not take a const u_char** pointer,
|
||||
// here we assume d2i_X509 does not write to <data>, so it is safe to
|
||||
// convert data to a non-const pointer. Could some X509 guru verify
|
||||
// this?
|
||||
|
||||
X509* d2i_X509_(X509** px, const u_char** in, int len)
|
||||
{
|
||||
#ifdef OPENSSL_D2I_X509_USES_CONST_CHAR
|
||||
return d2i_X509(px, in, len);
|
||||
#else
|
||||
return d2i_X509(px, (u_char**)in, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
%%}
|
||||
|
||||
|
||||
## Verifies a certificate.
|
||||
##
|
||||
## der_cert: The X.509 certificate in DER format.
|
||||
##
|
||||
## cert_stack: Specifies a certificate chain to validate against, with index 0
|
||||
## typically being the root CA. Bro uses the Mozilla root CA list
|
||||
## by default.
|
||||
##
|
||||
## root_certs: A list of additional root certificates that extends
|
||||
## *cert_stack*.
|
||||
##
|
||||
## Returns: A status code of the verification which can be converted into an
|
||||
## ASCII string via :bro:id:`x509_err2str`.
|
||||
##
|
||||
## .. bro:see:: x509_err2str
|
||||
function x509_verify%(der_cert: string, cert_stack: string_vec, root_certs: table_string_of_string%): count
|
||||
%{
|
||||
X509_STORE* ctx = 0;
|
||||
int i = 0;
|
||||
|
||||
// If this certificate store was built previously, just reuse the old one.
|
||||
if ( x509_stores.count(root_certs) > 0 )
|
||||
ctx = x509_stores[root_certs];
|
||||
|
||||
if ( ! ctx ) // lookup to see if we have this one built already!
|
||||
{
|
||||
ctx = X509_STORE_new();
|
||||
TableVal* root_certs2 = root_certs->AsTableVal();
|
||||
ListVal* idxs = root_certs2->ConvertToPureList();
|
||||
|
||||
// Build the validation store
|
||||
for ( i = 0; i < idxs->Length(); ++i )
|
||||
{
|
||||
Val* key = idxs->Index(i);
|
||||
StringVal *sv = root_certs2->Lookup(key)->AsStringVal();
|
||||
const uint8* data = sv->Bytes();
|
||||
X509* x = d2i_X509_(NULL, &data, sv->Len());
|
||||
if ( ! x )
|
||||
{
|
||||
builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_peek_last_error(),NULL)));
|
||||
return new Val((uint64) ERR_get_error(), TYPE_COUNT);
|
||||
}
|
||||
X509_STORE_add_cert(ctx, x);
|
||||
}
|
||||
delete idxs;
|
||||
|
||||
// Save the newly constructed certificate store into the cacheing map.
|
||||
x509_stores[root_certs] = ctx;
|
||||
}
|
||||
|
||||
const uint8 *cert_data = der_cert->Bytes();
|
||||
X509* cert = d2i_X509_(NULL, &cert_data, der_cert->Len());
|
||||
if ( ! cert )
|
||||
{
|
||||
builtin_error(fmt("Certificate error: %s", ERR_error_string(ERR_peek_last_error(),NULL)));
|
||||
return new Val((uint64) ERR_get_error(), TYPE_COUNT);
|
||||
}
|
||||
|
||||
STACK_OF(X509)* untrusted_certs = sk_X509_new_null();
|
||||
if ( ! untrusted_certs )
|
||||
{
|
||||
builtin_error(fmt("Untrusted certificate stack initialization error: %s", ERR_error_string(ERR_peek_last_error(),NULL)));
|
||||
return new Val((uint64) ERR_get_error(), TYPE_COUNT);
|
||||
}
|
||||
|
||||
VectorVal *cert_stack_vec = cert_stack->AsVectorVal();
|
||||
for ( i = 0; i < (int) cert_stack_vec->Size(); ++i )
|
||||
{
|
||||
StringVal *sv = cert_stack_vec->Lookup(i)->AsStringVal();
|
||||
const uint8 *data = sv->Bytes();
|
||||
X509* x = d2i_X509_(NULL, &data, sv->Len());
|
||||
if ( ! x )
|
||||
{
|
||||
X509_free(cert);
|
||||
sk_X509_pop_free(untrusted_certs, X509_free);
|
||||
builtin_error(fmt("Untrusted certificate stack creation error: %s", ERR_error_string(ERR_peek_last_error(),NULL)));
|
||||
return new Val((uint64) ERR_get_error(), TYPE_COUNT);
|
||||
}
|
||||
sk_X509_push(untrusted_certs, x);
|
||||
}
|
||||
|
||||
X509_STORE_CTX csc;
|
||||
X509_STORE_CTX_init(&csc, ctx, cert, untrusted_certs);
|
||||
X509_STORE_CTX_set_time(&csc, 0, (time_t) network_time);
|
||||
|
||||
int result = X509_verify_cert(&csc);
|
||||
X509_STORE_CTX_cleanup(&csc);
|
||||
|
||||
if ( untrusted_certs )
|
||||
sk_X509_pop_free(untrusted_certs, X509_free);
|
||||
X509_free(cert);
|
||||
|
||||
return new Val((uint64) csc.error, TYPE_COUNT);
|
||||
%}
|
||||
|
||||
## Converts a certificate verification error code into an ASCII string.
|
||||
##
|
||||
## err_num: The error code.
|
||||
##
|
||||
## Returns: A string representation of *err_num*.
|
||||
##
|
||||
## .. bro:see:: x509_verify
|
||||
function x509_err2str%(err_num: count%): string
|
||||
%{
|
||||
return new StringVal(X509_verify_cert_error_string(err_num));
|
||||
%}
|
|
@ -8,9 +8,6 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include "file_analysis/Manager.h"
|
||||
%}
|
||||
|
||||
|
@ -247,57 +244,13 @@ refine connection SSL_Conn += {
|
|||
if ( certificates->size() == 0 )
|
||||
return true;
|
||||
|
||||
if ( x509_certificate )
|
||||
{
|
||||
STACK_OF(X509)* untrusted_certs = 0;
|
||||
|
||||
for ( unsigned int i = 0; i < certificates->size(); ++i )
|
||||
{
|
||||
const bytestring& cert = (*certificates)[i];
|
||||
const uint8* data = cert.data();
|
||||
|
||||
file_mgr->DataIn(reinterpret_cast<const u_char*>(data), cert.length(),
|
||||
bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), false);
|
||||
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), cert.length(),
|
||||
bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), ${rec.is_orig});
|
||||
file_mgr->EndOfFile(bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn());
|
||||
|
||||
X509* pTemp = d2i_X509_binpac(NULL, &data, cert.length());
|
||||
if ( ! pTemp )
|
||||
{
|
||||
BifEvent::generate_x509_error(bro_analyzer(), bro_analyzer()->Conn(),
|
||||
${rec.is_orig}, ERR_get_error());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
RecordVal* pX509Cert = new RecordVal(x509_type);
|
||||
char tmp[256];
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
|
||||
pX509Cert->Assign(0, new Val((uint64) X509_get_version(pTemp), TYPE_COUNT));
|
||||
i2a_ASN1_INTEGER(bio, X509_get_serialNumber(pTemp));
|
||||
int len = BIO_read(bio, &(*tmp), sizeof tmp);
|
||||
pX509Cert->Assign(1, new StringVal(len, tmp));
|
||||
|
||||
X509_NAME_print_ex(bio, X509_get_subject_name(pTemp), 0, XN_FLAG_RFC2253);
|
||||
len = BIO_gets(bio, &(*tmp), sizeof tmp);
|
||||
pX509Cert->Assign(2, new StringVal(len, tmp));
|
||||
X509_NAME_print_ex(bio, X509_get_issuer_name(pTemp), 0, XN_FLAG_RFC2253);
|
||||
len = BIO_gets(bio, &(*tmp), sizeof tmp);
|
||||
pX509Cert->Assign(3, new StringVal(len, tmp));
|
||||
BIO_free(bio);
|
||||
|
||||
pX509Cert->Assign(4, new Val(get_time_from_asn1(X509_get_notBefore(pTemp)), TYPE_TIME));
|
||||
pX509Cert->Assign(5, new Val(get_time_from_asn1(X509_get_notAfter(pTemp)), TYPE_TIME));
|
||||
StringVal* der_cert = new StringVal(cert.length(), (const char*) cert.data());
|
||||
|
||||
BifEvent::generate_x509_certificate(bro_analyzer(), bro_analyzer()->Conn(),
|
||||
${rec.is_orig},
|
||||
pX509Cert,
|
||||
i, certificates->size(),
|
||||
der_cert);
|
||||
|
||||
X509_free(pTemp);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
%}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue