From 2b87499fd96ea28cf66f999ffd97b94f5596a7b2 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 1 Oct 2013 16:20:55 -0700 Subject: [PATCH] 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. --- scripts/base/protocols/ssl/main.bro | 43 ------- src/analyzer/protocol/ssl/CMakeLists.txt | 1 - src/analyzer/protocol/ssl/Plugin.cc | 1 - src/analyzer/protocol/ssl/SSL.h | 3 +- src/analyzer/protocol/ssl/events.bif | 73 +----------- src/analyzer/protocol/ssl/functions.bif | 132 --------------------- src/analyzer/protocol/ssl/ssl-analyzer.pac | 57 +-------- 7 files changed, 12 insertions(+), 298 deletions(-) delete mode 100644 src/analyzer/protocol/ssl/functions.bif diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index 2381b356e4..1b487ef4bf 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -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); diff --git a/src/analyzer/protocol/ssl/CMakeLists.txt b/src/analyzer/protocol/ssl/CMakeLists.txt index f1838e5f3b..2591c5dfec 100644 --- a/src/analyzer/protocol/ssl/CMakeLists.txt +++ b/src/analyzer/protocol/ssl/CMakeLists.txt @@ -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() diff --git a/src/analyzer/protocol/ssl/Plugin.cc b/src/analyzer/protocol/ssl/Plugin.cc index c63be864f8..c1783b357d 100644 --- a/src/analyzer/protocol/ssl/Plugin.cc +++ b/src/analyzer/protocol/ssl/Plugin.cc @@ -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 diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 5749066780..f674d64fed 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -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: diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index b7586561fc..aff5f4798c 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -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 `__ 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 -## `__ -## 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 `__ 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 `__ 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%); diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif deleted file mode 100644 index f2d4861007..0000000000 --- a/src/analyzer/protocol/ssl/functions.bif +++ /dev/null @@ -1,132 +0,0 @@ - -%%{ -#include -#include -#include - -// This is the indexed map of X509 certificate stores. -static map x509_stores; - -// ### NOTE: while d2i_X509 does not take a const u_char** pointer, -// here we assume d2i_X509 does not write to , 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)); - %} diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 43e2ac5c73..4bf1e27d64 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -8,9 +8,6 @@ #include "util.h" -#include -#include - #include "file_analysis/Manager.h" %} @@ -247,57 +244,13 @@ refine connection SSL_Conn += { if ( certificates->size() == 0 ) return true; - if ( x509_certificate ) + for ( unsigned int i = 0; i < certificates->size(); ++i ) { - STACK_OF(X509)* untrusted_certs = 0; + const bytestring& cert = (*certificates)[i]; - for ( unsigned int i = 0; i < certificates->size(); ++i ) - { - const bytestring& cert = (*certificates)[i]; - const uint8* data = cert.data(); - - file_mgr->DataIn(reinterpret_cast(data), cert.length(), - bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), false); - 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); - } + file_mgr->DataIn(reinterpret_cast(cert.data()), cert.length(), + bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), ${rec.is_orig}); + file_mgr->EndOfFile(bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn()); } return true; %}