mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
OCSP: generic extension parsing.
Raises ocsp_extension event if an extension is present in the reply or in one of the singlereplies.
This commit is contained in:
parent
8b50a1e09b
commit
cdcc21ea4b
4 changed files with 78 additions and 1 deletions
|
@ -3,8 +3,10 @@
|
|||
#include <string>
|
||||
|
||||
#include "OCSP.h"
|
||||
#include "X509.h"
|
||||
#include "Event.h"
|
||||
|
||||
#include "types.bif.h"
|
||||
#include "ocsp_events.bif.h"
|
||||
|
||||
#include "file_analysis/Manager.h"
|
||||
|
@ -185,7 +187,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
OCSP_RESPDATA *resp_data = nullptr;
|
||||
OCSP_RESPID *resp_id = nullptr;
|
||||
|
||||
int resp_count = 0;
|
||||
int resp_count, num_ext = 0;
|
||||
VectorVal *certs_vector = nullptr;
|
||||
int len = 0;
|
||||
|
||||
|
@ -285,6 +287,16 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
rvl->append(new Val(0, TYPE_TIME));
|
||||
|
||||
mgr.QueueEvent(ocsp_response_certificate, rvl);
|
||||
|
||||
num_ext = OCSP_SINGLERESP_get_ext_count(single_resp);
|
||||
for ( int k = 0; k < num_ext; ++k )
|
||||
{
|
||||
X509_EXTENSION* ex = OCSP_SINGLERESP_get_ext(single_resp, k);
|
||||
if ( ! ex )
|
||||
continue;
|
||||
|
||||
ParseExtension(ex, false);
|
||||
}
|
||||
}
|
||||
|
||||
i2a_ASN1_OBJECT(bio, basic_resp->signatureAlgorithm->algorithm);
|
||||
|
@ -314,12 +326,73 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
}
|
||||
mgr.QueueEvent(ocsp_response_bytes, vl);
|
||||
|
||||
// ok, now that we are done with the actual certificate - let's parse extensions :)
|
||||
num_ext = OCSP_BASICRESP_get_ext_count(basic_resp);
|
||||
for ( int k = 0; k < num_ext; ++k )
|
||||
{
|
||||
X509_EXTENSION* ex = OCSP_BASICRESP_get_ext(basic_resp, k);
|
||||
if ( ! ex )
|
||||
continue;
|
||||
|
||||
ParseExtension(ex, true);
|
||||
}
|
||||
|
||||
|
||||
clean_up:
|
||||
if (basic_resp)
|
||||
OCSP_BASICRESP_free(basic_resp);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
// This is a near copy from X509
|
||||
void file_analysis::OCSP::ParseExtension(X509_EXTENSION* ex, bool global)
|
||||
{
|
||||
char name[256];
|
||||
char oid[256];
|
||||
|
||||
ASN1_OBJECT* ext_asn = X509_EXTENSION_get_object(ex);
|
||||
const char* short_name = OBJ_nid2sn(OBJ_obj2nid(ext_asn));
|
||||
|
||||
OBJ_obj2txt(name, 255, ext_asn, 0);
|
||||
OBJ_obj2txt(oid, 255, ext_asn, 1);
|
||||
|
||||
int critical = 0;
|
||||
if ( X509_EXTENSION_get_critical(ex) != 0 )
|
||||
critical = 1;
|
||||
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
if( ! X509V3_EXT_print(bio, ex, 0, 0))
|
||||
M_ASN1_OCTET_STRING_print(bio,ex->value);
|
||||
|
||||
StringVal* ext_val = X509::GetExtensionFromBIO(bio);
|
||||
|
||||
if ( ! ext_val )
|
||||
ext_val = new StringVal(0, "");
|
||||
|
||||
RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension);
|
||||
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);
|
||||
|
||||
// send off generic extension event
|
||||
//
|
||||
// and then look if we have a specialized event for the extension we just
|
||||
// parsed. And if we have it, we send the specialized event on top of the
|
||||
// generic event that we just had. I know, that is... kind of not nice,
|
||||
// but I am not sure if there is a better way to do it...
|
||||
val_list* vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
vl->append(pX509Ext);
|
||||
vl->append(new Val(global ? 1 : 0, TYPE_BOOL));
|
||||
|
||||
mgr.QueueEvent(ocsp_extension, vl);
|
||||
}
|
||||
|
||||
OCSP_RESPVal::OCSP_RESPVal(OCSP_RESPONSE* arg_ocsp_resp) : OpaqueVal(ocsp_resp_opaque_type)
|
||||
{
|
||||
ocsp_resp = arg_ocsp_resp;
|
||||
|
|
|
@ -32,6 +32,7 @@ protected:
|
|||
private:
|
||||
void ParseResponse(OCSP_RESPVal *, const char* fid = 0);
|
||||
void ParseRequest(OCSP_REQUEST *, const char* fid = 0);
|
||||
void ParseExtension(X509_EXTENSION*, bool global);
|
||||
|
||||
std::string ocsp_data;
|
||||
bool request = false; // true if ocsp request, false if reply
|
||||
|
|
|
@ -248,6 +248,7 @@ StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio)
|
|||
return ext_val;
|
||||
}
|
||||
|
||||
// this is nearly replicated in the OCSP analyzer
|
||||
void file_analysis::X509::ParseExtension(X509_EXTENSION* ex)
|
||||
{
|
||||
char name[256];
|
||||
|
|
|
@ -26,3 +26,5 @@ event ocsp_response_status%(f: fa_file, status: string%);
|
|||
event ocsp_response_bytes%(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector%);
|
||||
|
||||
event ocsp_response_certificate%(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time%);
|
||||
|
||||
event ocsp_extension%(f: fa_file, ext: X509::Extension, global_resp: bool%);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue