mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
First (sadly not completely working) approach at caching X509 certificates
This approach mostly relies on script-level changes. In scriptland, we track which certificates should be cached - and also perform the caching and the replaying of events there. This actually is probably nearly functional - the problem is the fact that now the event ordering is wrong - and file_state_remove is called before the x509 events are thrown. The fix probably is to move to a callback from the core - which can execute things in the right order again. (Or just write the whole event-raising inside the core - but that is both less flexible and a lot more cumbersome).
This commit is contained in:
parent
64855dfa0e
commit
0829164a3e
5 changed files with 153 additions and 6 deletions
|
@ -19,9 +19,7 @@
|
|||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
namespace file_analysis {
|
||||
std::map<Val*, X509_STORE*> X509::x509_stores;
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
using namespace file_analysis;
|
||||
|
||||
|
@ -45,10 +43,27 @@ bool file_analysis::X509::Undelivered(uint64_t offset, uint64_t len)
|
|||
|
||||
bool file_analysis::X509::EndOfFile()
|
||||
{
|
||||
const unsigned char* cert_char = reinterpret_cast<const unsigned char*>(cert_data.data());
|
||||
if ( certificate_cache )
|
||||
{
|
||||
// first step - let's see if the certificate has been cached.
|
||||
unsigned char buf[SHA256_DIGEST_LENGTH];
|
||||
auto ctx = hash_init(Hash_SHA256);
|
||||
hash_update(ctx, cert_char, cert_data.size());
|
||||
hash_final(ctx, buf);
|
||||
std::string cert_sha256 = sha256_digest_print(buf);
|
||||
auto index = make_intrusive<StringVal>(cert_sha256);
|
||||
if ( certificate_cache->Lookup(index.get(), false) )
|
||||
// in this case, the certificate is in the cache and we do not
|
||||
// do any further processing here
|
||||
{
|
||||
std::cerr << "Skipping " << cert_sha256 << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, now we can try to parse the certificate with openssl. Should
|
||||
// be rather straightforward...
|
||||
const unsigned char* cert_char = reinterpret_cast<const unsigned char*>(cert_data.data());
|
||||
|
||||
::X509* ssl_cert = d2i_X509(NULL, &cert_char, cert_data.size());
|
||||
if ( ! ssl_cert )
|
||||
{
|
||||
|
|
|
@ -112,6 +112,12 @@ public:
|
|||
*/
|
||||
static void FreeRootStore();
|
||||
|
||||
/**
|
||||
* Sets the table[string] that used as the certificate cache inside of Zeek.
|
||||
*/
|
||||
static void SetCertificateCache(IntrusivePtr<TableVal> cache)
|
||||
{ certificate_cache = cache; }
|
||||
|
||||
protected:
|
||||
X509(RecordVal* args, File* file);
|
||||
|
||||
|
@ -126,7 +132,8 @@ private:
|
|||
static StringVal* KeyCurve(EVP_PKEY *key);
|
||||
static unsigned int KeyLength(EVP_PKEY *key);
|
||||
/** X509 stores associated with global script-layer values */
|
||||
static std::map<Val*, X509_STORE*> x509_stores;
|
||||
inline static std::map<Val*, X509_STORE*> x509_stores = std::map<Val*, X509_STORE*>();
|
||||
inline static IntrusivePtr<TableVal> certificate_cache = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -881,3 +881,10 @@ function x509_spki_hash%(cert: opaque of x509, hash_alg: count%): string
|
|||
|
||||
return x509_entity_hash(cert_handle, hash_alg, 2);
|
||||
%}
|
||||
|
||||
function x509_set_certificate_cache%(tbl: string_any_table%) : bool
|
||||
%{
|
||||
file_analysis::X509::SetCertificateCache({NewRef{}, tbl->AsTableVal()});
|
||||
|
||||
return val_mgr->GetBool(1);
|
||||
%}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue