mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
OCSP: rewrite events and data structures.
Instead of having a big event, that tries to parse all the data into a huge datastructure, we do the more common thing and use a series of smaller events to parse requests and responses. The new events are: ocsp_request -> raised for an ocsp request, giving version and requestor ocsp_request_certificate -> raised n times per request, once per cert ocsp_response_status -> raised for each ocsp response, giving status ocsp_response_bytes -> raised for each ocsp response with information ocsp_response_certificate -> raised for each cert in an ocsp response
This commit is contained in:
parent
9c6cebf324
commit
e1bcc4509f
12 changed files with 90 additions and 277 deletions
|
@ -1,2 +1,2 @@
|
|||
@load ./main
|
||||
@load ./ocsp
|
||||
#@load ./ocsp
|
||||
|
|
|
@ -3643,60 +3643,6 @@ export {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
module OCSP;
|
||||
export {
|
||||
type OneReq: record {
|
||||
hashAlgorithm: string &log;
|
||||
issuerNameHash: string &log;
|
||||
issuerKeyHash: string &log;
|
||||
serialNumber: string &log;
|
||||
};
|
||||
|
||||
type Request: record {
|
||||
version: count &log &optional;
|
||||
requestorName: string &log &optional;
|
||||
requestList: vector of OneReq;
|
||||
};
|
||||
|
||||
type SingleResp: record {
|
||||
hashAlgorithm: string &log;
|
||||
issuerNameHash: string &log;
|
||||
issuerKeyHash: string &log;
|
||||
serialNumber: string &log;
|
||||
certStatus: string &log;
|
||||
revoketime: time &log &optional;
|
||||
revokereason: string &log &optional;
|
||||
thisUpdate: time &log;
|
||||
nextUpdate: time &log &optional;
|
||||
};
|
||||
|
||||
type Response: record {
|
||||
responseStatus: string &log;
|
||||
responseType: string &log &optional;
|
||||
version: count &log &optional;
|
||||
responderID: string &log &optional;
|
||||
producedAt: time &log &optional;
|
||||
responses: vector of SingleResp;
|
||||
signatureAlgorithm: string &log &optional;
|
||||
#signature: string &optional; #&log;
|
||||
certs: vector of opaque of x509 &optional;
|
||||
};
|
||||
|
||||
type CertId: record {
|
||||
hashAlgorithm: string &log &optional;
|
||||
issuerNameHash: string &log &optional;
|
||||
issuerKeyHash: string &log &optional;
|
||||
serialNumber: string &log &optional;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module GLOBAL;
|
||||
type ocsp_req_vec: vector of OCSP::OneReq;
|
||||
type ocsp_resp_vec: vector of OCSP::SingleResp;
|
||||
|
||||
|
||||
module SOCKS;
|
||||
export {
|
||||
## This record is for a SOCKS client or server to provide either a
|
||||
|
|
|
@ -115,8 +115,7 @@ SERIAL_VAL(CARDINALITY_VAL, 22)
|
|||
SERIAL_VAL(X509_VAL, 23)
|
||||
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
|
||||
SERIAL_VAL(COMM_DATA_VAL, 25)
|
||||
SERIAL_VAL(OCSP_REQ_VAL, 26)
|
||||
SERIAL_VAL(OCSP_RESP_VAL, 27)
|
||||
SERIAL_VAL(OCSP_RESP_VAL, 26)
|
||||
|
||||
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||
SERIAL_EXPR(EXPR, 1)
|
||||
|
|
|
@ -628,7 +628,6 @@ extern OpaqueType* cardinality_type;
|
|||
extern OpaqueType* topk_type;
|
||||
extern OpaqueType* bloomfilter_type;
|
||||
extern OpaqueType* x509_opaque_type;
|
||||
extern OpaqueType* ocsp_req_opaque_type;
|
||||
extern OpaqueType* ocsp_resp_opaque_type;
|
||||
|
||||
// Returns the Bro basic (non-parameterized) type with the given type.
|
||||
|
|
|
@ -6,5 +6,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 ocsp_types.bif ocsp_functions.bif)
|
||||
bro_plugin_bif(events.bif types.bif functions.bif ocsp_events.bif)
|
||||
bro_plugin_end()
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "Event.h"
|
||||
|
||||
#include "ocsp_events.bif.h"
|
||||
#include "ocsp_types.bif.h"
|
||||
|
||||
#include "file_analysis/Manager.h"
|
||||
|
||||
|
@ -28,7 +27,6 @@ X509 *helper_sk_X509_value(STACK_OF(X509) *certs, int i)
|
|||
|
||||
using namespace file_analysis;
|
||||
|
||||
IMPLEMENT_SERIAL(OCSP_REQVal, SER_OCSP_REQ_VAL);
|
||||
IMPLEMENT_SERIAL(OCSP_RESPVal, SER_OCSP_RESP_VAL);
|
||||
|
||||
#define OCSP_STRING_BUF_SIZE 2048
|
||||
|
@ -51,32 +49,29 @@ static void OCSP_RESPID_bio(OCSP_RESPID *resp_id, BIO* bio)
|
|||
i2a_ASN1_STRING(bio, resp_id->value.byKey, V_ASN1_OCTET_STRING);
|
||||
}
|
||||
|
||||
static RecordVal* ocsp_fill_cert_id(OCSP_CERTID *cert_id, RecordType* type, BIO* bio)
|
||||
void ocsp_add_cert_id(OCSP_CERTID *cert_id, val_list* vl, BIO* bio)
|
||||
{
|
||||
RecordVal *d = new RecordVal(type);
|
||||
char buf[OCSP_STRING_BUF_SIZE];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
i2a_ASN1_OBJECT(bio, cert_id->hashAlgorithm->algorithm);
|
||||
int len = BIO_read(bio, buf, sizeof(buf));
|
||||
d->Assign(0, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
i2a_ASN1_STRING(bio, cert_id->issuerNameHash, V_ASN1_OCTET_STRING);
|
||||
len = BIO_read(bio, buf, sizeof(buf));
|
||||
d->Assign(1, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
i2a_ASN1_STRING(bio, cert_id->issuerKeyHash, V_ASN1_OCTET_STRING);
|
||||
len = BIO_read(bio, buf, sizeof(buf));
|
||||
d->Assign(2, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
i2a_ASN1_INTEGER(bio, cert_id->serialNumber);
|
||||
d->Assign(3, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
file_analysis::Analyzer* OCSP::Instantiate(RecordVal* args, File* file)
|
||||
|
@ -123,16 +118,8 @@ bool file_analysis::OCSP::EndOfFile()
|
|||
return false;
|
||||
}
|
||||
|
||||
OCSP_REQVal* req_val = new OCSP_REQVal(req); // req_val takes ownership
|
||||
|
||||
RecordVal* req_record = ParseRequest(req_val, GetFile()->GetID().c_str());
|
||||
|
||||
// and send the record on to scriptland
|
||||
val_list* vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
vl->append(req_val);
|
||||
vl->append(req_record);
|
||||
mgr.QueueEvent(ocsp_request, vl);
|
||||
ParseRequest(req, GetFile()->GetID().c_str());
|
||||
OCSP_REQUEST_free(req);
|
||||
}
|
||||
else if (ocsp_type == "response")
|
||||
{
|
||||
|
@ -144,14 +131,8 @@ bool file_analysis::OCSP::EndOfFile()
|
|||
}
|
||||
|
||||
OCSP_RESPVal* resp_val = new OCSP_RESPVal(resp); // resp_val takes ownership
|
||||
RecordVal* resp_record = ParseResponse(resp_val, GetFile()->GetID().c_str());
|
||||
|
||||
// and send the record on to scriptland
|
||||
val_list* vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
vl->append(resp_val);
|
||||
vl->append(resp_record);
|
||||
mgr.QueueEvent(ocsp_response, vl);
|
||||
ParseResponse(resp_val, GetFile()->GetID().c_str());
|
||||
Unref(resp_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -162,46 +143,48 @@ bool file_analysis::OCSP::EndOfFile()
|
|||
return true;
|
||||
}
|
||||
|
||||
RecordVal *file_analysis::OCSP::ParseRequest(OCSP_REQVal *req_val, const char* fid)
|
||||
void file_analysis::OCSP::ParseRequest(OCSP_REQUEST *req, const char* fid)
|
||||
{
|
||||
OCSP_REQUEST *req = req_val->GetReq();
|
||||
OCSP_REQINFO *inf = req->tbsRequest;
|
||||
|
||||
char buf[OCSP_STRING_BUF_SIZE]; // we need a buffer for some of the openssl functions
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
RecordVal* ocsp_req_record = new RecordVal(BifType::Record::OCSP::Request);
|
||||
|
||||
ocsp_req_record->Assign(0, new Val((uint64)ASN1_INTEGER_get(inf->version), TYPE_COUNT));
|
||||
// build up our response as we go along...
|
||||
val_list* vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
vl->append(new Val((uint64)ASN1_INTEGER_get(inf->version), TYPE_COUNT));
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
|
||||
if (inf->requestorName != NULL)
|
||||
{
|
||||
GENERAL_NAME_print(bio, inf->requestorName);
|
||||
int len = BIO_read(bio, buf, sizeof(buf));
|
||||
ocsp_req_record->Assign(1, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
}
|
||||
else
|
||||
vl->append(new StringVal(0, ""));
|
||||
|
||||
VectorVal* all_req_bro = new VectorVal(internal_type("ocsp_req_vec")->AsVectorType());
|
||||
ocsp_req_record->Assign(2, all_req_bro);
|
||||
mgr.QueueEvent(ocsp_request, vl);
|
||||
|
||||
int req_count = OCSP_request_onereq_count(req);
|
||||
for ( int i=0; i<req_count; i++ )
|
||||
{
|
||||
val_list* rvl = new val_list();
|
||||
rvl->append(GetFile()->GetVal()->Ref());
|
||||
|
||||
OCSP_ONEREQ *one_req = OCSP_request_onereq_get0(req, i);
|
||||
OCSP_CERTID *cert_id = OCSP_onereq_get0_id(one_req);
|
||||
|
||||
RecordVal* one_req_bro = ocsp_fill_cert_id(cert_id, BifType::Record::OCSP::OneReq, bio);
|
||||
all_req_bro->Assign(i, one_req_bro);
|
||||
ocsp_add_cert_id(cert_id, rvl, bio);
|
||||
mgr.QueueEvent(ocsp_request_certificate, rvl);
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
return ocsp_req_record;
|
||||
}
|
||||
|
||||
RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
||||
void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
||||
{
|
||||
OCSP_RESPONSE *resp = resp_val->GetResp();
|
||||
OCSP_RESPBYTES *resp_bytes = resp->responseBytes;
|
||||
|
@ -210,24 +193,31 @@ RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char
|
|||
OCSP_RESPID *resp_id = nullptr;
|
||||
|
||||
int resp_count = 0;
|
||||
VectorVal *all_resp_bro = nullptr;
|
||||
VectorVal *certs_vector = nullptr;
|
||||
int len = 0;
|
||||
|
||||
char buf[OCSP_STRING_BUF_SIZE];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
RecordVal *ocsp_resp_record = new RecordVal(BifType::Record::OCSP::Response);
|
||||
val_list* vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
|
||||
const char *status_str = OCSP_response_status_str(OCSP_response_status(resp));
|
||||
ocsp_resp_record->Assign(0, new StringVal(strlen(status_str), status_str));
|
||||
StringVal* status_val = new StringVal(strlen(status_str), status_str);
|
||||
vl->append(status_val->Ref());
|
||||
mgr.QueueEvent(ocsp_response_status, vl);
|
||||
vl = nullptr;
|
||||
|
||||
if (!resp_bytes)
|
||||
return ocsp_resp_record;
|
||||
{
|
||||
Unref(status_val);
|
||||
return;
|
||||
}
|
||||
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
i2a_ASN1_OBJECT(bio, resp_bytes->responseType);
|
||||
int len = BIO_read(bio, buf, sizeof(buf));
|
||||
ocsp_resp_record->Assign(1, new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
//i2a_ASN1_OBJECT(bio, resp_bytes->responseType);
|
||||
//int len = BIO_read(bio, buf, sizeof(buf));
|
||||
//BIO_reset(bio);
|
||||
|
||||
// get the basic response
|
||||
basic_resp = OCSP_response_get1_basic(resp);
|
||||
|
@ -238,19 +228,21 @@ RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char
|
|||
if ( !resp_data )
|
||||
goto clean_up;
|
||||
|
||||
ocsp_resp_record->Assign(2, new Val((uint64)ASN1_INTEGER_get(resp_data->version), TYPE_COUNT));
|
||||
vl = new val_list();
|
||||
vl->append(GetFile()->GetVal()->Ref());
|
||||
vl->append(resp_val->Ref());
|
||||
vl->append(status_val);
|
||||
vl->append(new Val((uint64)ASN1_INTEGER_get(resp_data->version), TYPE_COUNT));
|
||||
|
||||
// responderID
|
||||
resp_id = resp_data->responderId;
|
||||
OCSP_RESPID_bio(resp_id, bio);
|
||||
len = BIO_read(bio, buf, sizeof(buf));
|
||||
ocsp_resp_record->Assign(3, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
// producedAt
|
||||
ocsp_resp_record->Assign(4, new Val(GetTimeFromAsn1(resp_data->producedAt, fid, reporter), TYPE_TIME));
|
||||
|
||||
all_resp_bro = new VectorVal(internal_type("ocsp_resp_vec")->AsVectorType());
|
||||
ocsp_resp_record->Assign(5, all_resp_bro);
|
||||
vl->append(new Val(GetTimeFromAsn1(resp_data->producedAt, fid, reporter), TYPE_TIME));
|
||||
|
||||
// responses
|
||||
resp_count = sk_OCSP_SINGLERESP_num(resp_data->responses);
|
||||
|
@ -260,39 +252,51 @@ RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char
|
|||
if ( !single_resp )
|
||||
continue;
|
||||
|
||||
val_list* rvl = new val_list();
|
||||
rvl->append(GetFile()->GetVal()->Ref());
|
||||
|
||||
// cert id
|
||||
OCSP_CERTID *cert_id = single_resp->certId;
|
||||
RecordVal *single_resp_bro = ocsp_fill_cert_id(cert_id, BifType::Record::OCSP::SingleResp, bio);
|
||||
ocsp_add_cert_id(cert_id, rvl, bio);
|
||||
BIO_reset(bio);
|
||||
|
||||
// certStatus
|
||||
OCSP_CERTSTATUS *cert_status = single_resp->certStatus;
|
||||
const char* cert_status_str = OCSP_cert_status_str(cert_status->type);
|
||||
single_resp_bro->Assign(4, new StringVal(strlen(cert_status_str), cert_status_str));
|
||||
rvl->append(new StringVal(strlen(cert_status_str), cert_status_str));
|
||||
|
||||
// revocation time and reason if revoked
|
||||
if ( cert_status->type == V_OCSP_CERTSTATUS_REVOKED )
|
||||
{
|
||||
OCSP_REVOKEDINFO *revoked_info = cert_status->value.revoked;
|
||||
single_resp_bro->Assign(5, new Val(GetTimeFromAsn1(revoked_info->revocationTime, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(revoked_info->revocationTime, fid, reporter), TYPE_TIME));
|
||||
|
||||
if ( revoked_info->revocationReason )
|
||||
{
|
||||
const char* revoke_reason = OCSP_crl_reason_str(ASN1_ENUMERATED_get(revoked_info->revocationReason));
|
||||
single_resp_bro->Assign(6, new StringVal(strlen(revoke_reason), revoke_reason));
|
||||
rvl->append(new StringVal(strlen(revoke_reason), revoke_reason));
|
||||
}
|
||||
else
|
||||
rvl->append(new StringVal(0, ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
rvl->append(new Val(0, TYPE_TIME));
|
||||
rvl->append(new StringVal(0, ""));
|
||||
}
|
||||
|
||||
single_resp_bro->Assign(7, new Val(GetTimeFromAsn1(single_resp->thisUpdate, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(single_resp->thisUpdate, fid, reporter), TYPE_TIME));
|
||||
if ( single_resp->nextUpdate )
|
||||
single_resp_bro->Assign(8, new Val(GetTimeFromAsn1(single_resp->nextUpdate, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(single_resp->nextUpdate, fid, reporter), TYPE_TIME));
|
||||
else
|
||||
rvl->append(new Val(0, TYPE_TIME));
|
||||
|
||||
all_resp_bro->Assign(i, single_resp_bro);
|
||||
mgr.QueueEvent(ocsp_response_certificate, rvl);
|
||||
}
|
||||
|
||||
i2a_ASN1_OBJECT(bio, basic_resp->signatureAlgorithm->algorithm);
|
||||
len = BIO_read(bio, buf, sizeof(buf));
|
||||
ocsp_resp_record->Assign(6, new StringVal(len, buf));
|
||||
vl->append(new StringVal(len, buf));
|
||||
BIO_reset(bio);
|
||||
|
||||
//i2a_ASN1_OBJECT(bio, basic_resp->signature);
|
||||
|
@ -300,10 +304,10 @@ RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char
|
|||
//ocsp_resp_record->Assign(7, new StringVal(len, buf));
|
||||
//BIO_reset(bio);
|
||||
|
||||
//certs
|
||||
certs_vector = new VectorVal(internal_type("x509_opaque_vector")->AsVectorType());
|
||||
vl->append(certs_vector);
|
||||
if ( basic_resp->certs )
|
||||
{
|
||||
VectorVal *certs_vector = new VectorVal(internal_type("x509_opaque_vector")->AsVectorType());
|
||||
int num_certs = sk_X509_num(basic_resp->certs);
|
||||
for ( int i=0; i<num_certs; i++ )
|
||||
{
|
||||
|
@ -314,68 +318,15 @@ RecordVal *file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char
|
|||
else
|
||||
reporter->Weird("OpenSSL returned null certificate");
|
||||
}
|
||||
ocsp_resp_record->Assign(7, certs_vector);
|
||||
}
|
||||
mgr.QueueEvent(ocsp_response_bytes, vl);
|
||||
|
||||
clean_up:
|
||||
if (basic_resp)
|
||||
OCSP_BASICRESP_free(basic_resp);
|
||||
BIO_free(bio);
|
||||
return ocsp_resp_record;
|
||||
}
|
||||
|
||||
OCSP_REQVal::OCSP_REQVal(OCSP_REQUEST* arg_ocsp_req) : OpaqueVal(ocsp_req_opaque_type)
|
||||
{
|
||||
ocsp_req = arg_ocsp_req;
|
||||
}
|
||||
|
||||
OCSP_REQVal::OCSP_REQVal() : OpaqueVal(ocsp_req_opaque_type)
|
||||
{
|
||||
ocsp_req = nullptr;
|
||||
}
|
||||
|
||||
OCSP_REQVal::~OCSP_REQVal()
|
||||
{
|
||||
if (ocsp_req)
|
||||
OCSP_REQUEST_free(ocsp_req);
|
||||
}
|
||||
|
||||
OCSP_REQUEST* OCSP_REQVal::GetReq() const
|
||||
{
|
||||
return ocsp_req;
|
||||
}
|
||||
|
||||
bool OCSP_REQVal::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_OCSP_REQ_VAL, OpaqueVal);
|
||||
unsigned char *buf = nullptr;
|
||||
int length = i2d_OCSP_REQUEST(ocsp_req, &buf);
|
||||
if ( length < 0 )
|
||||
return false;
|
||||
bool res = SERIALIZE_STR(reinterpret_cast<const char*>(buf), length);
|
||||
OPENSSL_free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool OCSP_REQVal::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(OpaqueVal)
|
||||
|
||||
int length;
|
||||
unsigned char *ocsp_req_buf, *opensslbuf;
|
||||
|
||||
if ( ! UNSERIALIZE_STR(reinterpret_cast<char **>(&ocsp_req_buf), &length) )
|
||||
return false;
|
||||
opensslbuf = ocsp_req_buf; // OpenSSL likes to shift pointers around. really.
|
||||
ocsp_req = d2i_OCSP_REQUEST(nullptr, const_cast<const unsigned char**>(&opensslbuf), length);
|
||||
delete[] ocsp_req_buf;
|
||||
if ( !ocsp_req )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//OCSP_RESPVal
|
||||
OCSP_RESPVal::OCSP_RESPVal(OCSP_RESPONSE* arg_ocsp_resp) : OpaqueVal(ocsp_resp_opaque_type)
|
||||
{
|
||||
ocsp_resp = arg_ocsp_resp;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
namespace file_analysis {
|
||||
|
||||
class OCSP_REQVal;
|
||||
class OCSP_RESPVal;
|
||||
|
||||
class OCSP : public file_analysis::Analyzer {
|
||||
|
@ -24,8 +23,6 @@ public:
|
|||
virtual bool Undelivered(uint64 offset, uint64 len);
|
||||
virtual bool EndOfFile();
|
||||
|
||||
static RecordVal *ParseResponse(OCSP_RESPVal *, const char* fid = 0);
|
||||
static RecordVal *ParseRequest(OCSP_REQVal *, const char* fid = 0);
|
||||
|
||||
static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file);
|
||||
|
||||
|
@ -33,22 +30,13 @@ protected:
|
|||
OCSP(RecordVal* args, File* file, const string& ocsp_type);
|
||||
|
||||
private:
|
||||
void ParseResponse(OCSP_RESPVal *, const char* fid = 0);
|
||||
void ParseRequest(OCSP_REQUEST *, const char* fid = 0);
|
||||
|
||||
std::string ocsp_data;
|
||||
std::string ocsp_type;
|
||||
};
|
||||
|
||||
class OCSP_REQVal: public OpaqueVal {
|
||||
public:
|
||||
explicit OCSP_REQVal(OCSP_REQUEST *);
|
||||
~OCSP_REQVal();
|
||||
OCSP_REQUEST *GetReq() const;
|
||||
protected:
|
||||
OCSP_REQVal();
|
||||
private:
|
||||
OCSP_REQUEST *ocsp_req;
|
||||
DECLARE_SERIAL(OCSP_REQVal);
|
||||
};
|
||||
|
||||
class OCSP_RESPVal: public OpaqueVal {
|
||||
public:
|
||||
explicit OCSP_RESPVal(OCSP_RESPONSE *);
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
## Generated for encountered OCSP request
|
||||
##
|
||||
## Event that is raised when encountering an OCSP request, e.g. in an HTTP
|
||||
## connection. See :rfc:`6960` for more details.
|
||||
##
|
||||
## f: The file.
|
||||
##
|
||||
## req_ref: An opaque pointer to the underlying OpenSSL data structure of the
|
||||
## OCSP request
|
||||
## req: version: the version of the OCSP request. Typically 0 (Version 1).
|
||||
##
|
||||
## req: The parsed OCSP request information.
|
||||
## requestorName: name of the OCSP requestor. This attribute is optional; if
|
||||
## it is not set, an empty string is returned here.
|
||||
##
|
||||
event ocsp_request%(f: fa_file, req_ref: opaque of ocsp_req, req: OCSP::Request%);
|
||||
event ocsp_request%(f: fa_file, version: count, requestorName: string%);
|
||||
|
||||
event ocsp_request_certificate%(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string%);
|
||||
|
||||
## Generated for encountered OCSP response
|
||||
##
|
||||
##
|
||||
## f: The file.
|
||||
##
|
||||
## req_ref: An opaque pointer to the underlying OpenSSL data structure of the
|
||||
|
@ -20,4 +21,8 @@ event ocsp_request%(f: fa_file, req_ref: opaque of ocsp_req, req: OCSP::Request%
|
|||
##
|
||||
## req: The parsed OCSP response information.
|
||||
##
|
||||
event ocsp_response%(f: fa_file, resp_ref: opaque of ocsp_resp, resp: OCSP::Response%);
|
||||
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%);
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
%%{
|
||||
#include "file_analysis/analyzer/x509/OCSP.h"
|
||||
#include "ocsp_types.bif.h"
|
||||
%%}
|
||||
|
||||
## Parses a OCSP response into an OCSP::Response structure.
|
||||
##
|
||||
## ocsp_reply: OCSP data.
|
||||
##
|
||||
## Returns: A OCSP::Response structure.
|
||||
##
|
||||
## .. bro:see:: ssl_stapled_ocsp ocsp_parse_request
|
||||
function ocsp_parse_response%(ocsp_reply: string%): OCSP::Response
|
||||
%{
|
||||
const unsigned char* start = ocsp_reply->Bytes();
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
file_analysis::OCSP_RESPVal* resp_val = NULL;
|
||||
RecordVal* resp_record = NULL;
|
||||
resp = d2i_OCSP_RESPONSE(NULL, &start, ocsp_reply->Len());
|
||||
if ( ! resp )
|
||||
{
|
||||
reporter->Weird("OPENSSL Could not parse OCSP response");
|
||||
return NULL;
|
||||
}
|
||||
resp_val = new file_analysis::OCSP_RESPVal(resp);
|
||||
resp_record = file_analysis::OCSP::ParseResponse(resp_val);
|
||||
if (!resp_record)
|
||||
{
|
||||
reporter->Weird("Internal fail to parse OCSP response");
|
||||
Unref(resp_val);
|
||||
return NULL;
|
||||
}
|
||||
Unref(resp_val);
|
||||
//Unref(resp_record);
|
||||
return resp_record;
|
||||
%}
|
||||
|
||||
## Parses a OCSP request into an OCSP::Request structure.
|
||||
##
|
||||
## ocsp_req: OCSP data.
|
||||
##
|
||||
## Returns: A OCSP::Request structure.
|
||||
##
|
||||
## .. bro:see:: ssl_stapled_ocsp ocsp_parse_response
|
||||
function ocsp_parse_request%(ocsp_req: string%): OCSP::Request
|
||||
%{
|
||||
const unsigned char* start = ocsp_req->Bytes();
|
||||
OCSP_REQUEST *req = NULL;
|
||||
file_analysis::OCSP_REQVal* req_val = NULL;
|
||||
RecordVal* req_record = NULL;
|
||||
req = d2i_OCSP_REQUEST(NULL, &start, ocsp_req->Len());
|
||||
if ( ! req )
|
||||
{
|
||||
reporter->Weird("OPENSSL Could not parse OCSP request");
|
||||
return NULL;
|
||||
}
|
||||
req_val = new file_analysis::OCSP_REQVal(req);
|
||||
req_record = file_analysis::OCSP::ParseRequest(req_val);
|
||||
if (!req_record)
|
||||
{
|
||||
reporter->Weird("Internal fail to parse OCSP request");
|
||||
Unref(req_val);
|
||||
return NULL;
|
||||
}
|
||||
Unref(req_val);
|
||||
//Unref(req_record);
|
||||
return req_record;
|
||||
%}
|
|
@ -1,5 +0,0 @@
|
|||
type OCSP::Request: record;
|
||||
type OCSP::Response: record;
|
||||
type OCSP::OneReq: record;
|
||||
type OCSP::SingleResp: record;
|
||||
type OCSP::CertId: record;
|
|
@ -129,7 +129,6 @@ OpaqueType* cardinality_type = 0;
|
|||
OpaqueType* topk_type = 0;
|
||||
OpaqueType* bloomfilter_type = 0;
|
||||
OpaqueType* x509_opaque_type = 0;
|
||||
OpaqueType* ocsp_req_opaque_type = 0;
|
||||
OpaqueType* ocsp_resp_opaque_type = 0;
|
||||
|
||||
// Keep copy of command line
|
||||
|
@ -841,7 +840,6 @@ int main(int argc, char** argv)
|
|||
topk_type = new OpaqueType("topk");
|
||||
bloomfilter_type = new OpaqueType("bloomfilter");
|
||||
x509_opaque_type = new OpaqueType("x509");
|
||||
ocsp_req_opaque_type = new OpaqueType("ocsp_req");
|
||||
ocsp_resp_opaque_type = new OpaqueType("ocsp_resp");
|
||||
|
||||
// The leak-checker tends to produce some false
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue