mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
Make x509 certificates an opaque type
This commit is contained in:
parent
2b87499fd9
commit
2c7e7f962e
9 changed files with 114 additions and 117 deletions
|
@ -111,6 +111,7 @@ SERIAL_VAL(ENTROPY_VAL, 19)
|
|||
SERIAL_VAL(TOPK_VAL, 20)
|
||||
SERIAL_VAL(BLOOMFILTER_VAL, 21)
|
||||
SERIAL_VAL(CARDINALITY_VAL, 22)
|
||||
SERIAL_VAL(X509_VAL, 23)
|
||||
|
||||
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||
SERIAL_EXPR(EXPR, 1)
|
||||
|
|
|
@ -616,6 +616,7 @@ extern OpaqueType* entropy_type;
|
|||
extern OpaqueType* cardinality_type;
|
||||
extern OpaqueType* topk_type;
|
||||
extern OpaqueType* bloomfilter_type;
|
||||
extern OpaqueType* x509_opaque_type;
|
||||
|
||||
// Returns the BRO basic (non-parameterized) type with the given type.
|
||||
extern BroType* base_type(TypeTag tag);
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
};
|
||||
|
||||
string orig_label(bool is_orig);
|
||||
void free_X509(void *);
|
||||
X509* d2i_X509_binpac(X509** px, const uint8** in, int len);
|
||||
string handshake_type_label(int type);
|
||||
%}
|
||||
|
||||
|
@ -33,20 +31,6 @@ string orig_label(bool is_orig)
|
|||
return string(is_orig ? "originator" :"responder");
|
||||
}
|
||||
|
||||
void free_X509(void* cert)
|
||||
{
|
||||
X509_free((X509*) cert);
|
||||
}
|
||||
|
||||
X509* d2i_X509_binpac(X509** px, const uint8** 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
|
||||
}
|
||||
|
||||
string handshake_type_label(int type)
|
||||
{
|
||||
switch ( type ) {
|
||||
|
|
|
@ -22,7 +22,6 @@ type uint24 = record {
|
|||
};
|
||||
|
||||
string state_label(int state_nr);
|
||||
double get_time_from_asn1(const ASN1_TIME * atime);
|
||||
%}
|
||||
|
||||
extern type to_int;
|
||||
|
@ -146,105 +145,6 @@ enum AnalyzerState {
|
|||
return string(fmt("UNKNOWN (%d)", state_nr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double get_time_from_asn1(const ASN1_TIME * atime)
|
||||
{
|
||||
time_t lResult = 0;
|
||||
|
||||
char lBuffer[24];
|
||||
char * pBuffer = lBuffer;
|
||||
|
||||
size_t lTimeLength = atime->length;
|
||||
char * pString = (char *) atime->data;
|
||||
|
||||
if ( atime->type == V_ASN1_UTCTIME )
|
||||
{
|
||||
if ( lTimeLength < 11 || lTimeLength > 17 )
|
||||
return 0;
|
||||
|
||||
memcpy(pBuffer, pString, 10);
|
||||
pBuffer += 10;
|
||||
pString += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lTimeLength < 13 )
|
||||
return 0;
|
||||
|
||||
memcpy(pBuffer, pString, 12);
|
||||
pBuffer += 12;
|
||||
pString += 12;
|
||||
}
|
||||
|
||||
if ((*pString == 'Z') || (*pString == '-') || (*pString == '+'))
|
||||
{
|
||||
*(pBuffer++) = '0';
|
||||
*(pBuffer++) = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
*(pBuffer++) = *(pString++);
|
||||
*(pBuffer++) = *(pString++);
|
||||
|
||||
// Skip any fractional seconds...
|
||||
if (*pString == '.')
|
||||
{
|
||||
pString++;
|
||||
while ((*pString >= '0') && (*pString <= '9'))
|
||||
pString++;
|
||||
}
|
||||
}
|
||||
|
||||
*(pBuffer++) = 'Z';
|
||||
*(pBuffer++) = '\0';
|
||||
|
||||
time_t lSecondsFromUTC;
|
||||
|
||||
if ( *pString == 'Z' )
|
||||
lSecondsFromUTC = 0;
|
||||
|
||||
else
|
||||
{
|
||||
if ((*pString != '+') && (pString[5] != '-'))
|
||||
return 0;
|
||||
|
||||
lSecondsFromUTC = ((pString[1]-'0') * 10 + (pString[2]-'0')) * 60;
|
||||
lSecondsFromUTC += (pString[3]-'0') * 10 + (pString[4]-'0');
|
||||
|
||||
if (*pString == '-')
|
||||
lSecondsFromUTC = -lSecondsFromUTC;
|
||||
}
|
||||
|
||||
tm lTime;
|
||||
lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
|
||||
lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
|
||||
lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
|
||||
lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
|
||||
lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
|
||||
lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
|
||||
|
||||
if ( lTime.tm_year < 50 )
|
||||
lTime.tm_year += 100; // RFC 2459
|
||||
|
||||
lTime.tm_wday = 0;
|
||||
lTime.tm_yday = 0;
|
||||
lTime.tm_isdst = 0; // No DST adjustment requested
|
||||
|
||||
lResult = mktime(&lTime);
|
||||
|
||||
if ( lResult )
|
||||
{
|
||||
if ( 0 != lTime.tm_isdst )
|
||||
lResult -= 3600; // mktime may adjust for DST (OS dependent)
|
||||
|
||||
lResult += lSecondsFromUTC;
|
||||
}
|
||||
else
|
||||
lResult = 0;
|
||||
|
||||
return lResult;
|
||||
}
|
||||
%}
|
||||
|
||||
######################################################################
|
||||
|
|
|
@ -6,5 +6,5 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}
|
|||
|
||||
bro_plugin_begin(Bro X509)
|
||||
bro_plugin_cc(X509.cc Plugin.cc ../../Analyzer.cc)
|
||||
bro_plugin_bif(events.bif types.bif)
|
||||
bro_plugin_bif(events.bif types.bif functions.bif)
|
||||
bro_plugin_end()
|
||||
|
|
|
@ -7,4 +7,5 @@ BRO_PLUGIN_BEGIN(Bro, X509)
|
|||
BRO_PLUGIN_FILE_ANALYZER("X509", X509);
|
||||
BRO_PLUGIN_BIF_FILE(events);
|
||||
BRO_PLUGIN_BIF_FILE(types);
|
||||
BRO_PLUGIN_BIF_FILE(functions);
|
||||
BRO_PLUGIN_END
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
using namespace file_analysis;
|
||||
|
||||
IMPLEMENT_SERIAL(X509Val, SER_X509_VAL);
|
||||
|
||||
file_analysis::X509::X509(RecordVal* args, file_analysis::File* file)
|
||||
: file_analysis::Analyzer(file_mgr->GetComponentTag("X509"), args, file)
|
||||
{
|
||||
|
@ -444,3 +446,65 @@ double file_analysis::X509::get_time_from_asn1(const ASN1_TIME * atime)
|
|||
return lResult;
|
||||
}
|
||||
|
||||
X509Val::X509Val(::X509* arg_certificate) : OpaqueVal(x509_opaque_type)
|
||||
{
|
||||
certificate = arg_certificate;
|
||||
}
|
||||
|
||||
X509Val::X509Val() : OpaqueVal(x509_opaque_type)
|
||||
{
|
||||
certificate = 0;
|
||||
}
|
||||
|
||||
X509Val::~X509Val()
|
||||
{
|
||||
if ( certificate )
|
||||
X509_free(certificate);
|
||||
}
|
||||
|
||||
::X509* X509Val::GetCertificate() const
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
|
||||
bool X509Val::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_X509_VAL, X509Val);
|
||||
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
int length = i2d_X509(certificate, &buf);
|
||||
|
||||
if ( length < 0 )
|
||||
return false;
|
||||
|
||||
bool res = SERIALIZE_STR(reinterpret_cast<const char*>(buf), length);
|
||||
|
||||
OPENSSL_free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool X509Val::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(OpaqueVal)
|
||||
|
||||
int length;
|
||||
unsigned char *certbuf, *opensslbuf;
|
||||
|
||||
if ( ! UNSERIALIZE_STR(reinterpret_cast<char **>(&certbuf), &length) )
|
||||
return false;
|
||||
|
||||
opensslbuf = certbuf; // OpenSSL likes to shift pointers around. really.
|
||||
certificate = d2i_X509(NULL, const_cast<const unsigned char**>(&opensslbuf), length);
|
||||
delete[] certbuf;
|
||||
|
||||
if ( !certificate )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,50 @@ private:
|
|||
std::string cert_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class wraps an OpenSSL X509 data structure.
|
||||
*
|
||||
* We need these to be able to pass OpenSSL pointers around in Bro
|
||||
* script-land. Otherwise, we cannot verify certificates from Bro
|
||||
* scriptland
|
||||
*/
|
||||
class X509Val : public OpaqueVal {
|
||||
public:
|
||||
/**
|
||||
* Construct an X509Val.
|
||||
*
|
||||
* @param certificate specifies the wrapped OpenSSL certificate
|
||||
*
|
||||
* @return A newly initialized X509Val
|
||||
*/
|
||||
X509Val(::X509* certificate);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~X509Val();
|
||||
|
||||
/**
|
||||
* Get the wrapped X509 certificate. Please take care, that the
|
||||
* internal OpenSSL reference counting stays the same.
|
||||
*
|
||||
* @return The wrapped OpenSSL X509 certificate
|
||||
*/
|
||||
::X509* GetCertificate() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Construct an empty X509Val. Only used for deserialization
|
||||
*/
|
||||
X509Val();
|
||||
|
||||
private:
|
||||
::X509* certificate; // the wrapped certificate
|
||||
|
||||
DECLARE_SERIAL(X509Val);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -131,6 +131,7 @@ OpaqueType* entropy_type = 0;
|
|||
OpaqueType* cardinality_type = 0;
|
||||
OpaqueType* topk_type = 0;
|
||||
OpaqueType* bloomfilter_type = 0;
|
||||
OpaqueType* x509_opaque_type = 0;
|
||||
|
||||
extern std::list<BroDoc*> docs_generated;
|
||||
|
||||
|
@ -860,6 +861,7 @@ int main(int argc, char** argv)
|
|||
cardinality_type = new OpaqueType("cardinality");
|
||||
topk_type = new OpaqueType("topk");
|
||||
bloomfilter_type = new OpaqueType("bloomfilter");
|
||||
x509_opaque_type = new OpaqueType("x509");
|
||||
|
||||
// The leak-checker tends to produce some false
|
||||
// positives (memory which had already been
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue