mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Add support for opaque hash values.
This commit is contained in:
parent
23ca1c90ef
commit
624003f036
6 changed files with 340 additions and 0 deletions
|
@ -358,6 +358,7 @@ set(bro_SRCS
|
|||
NetVar.cc
|
||||
NetbiosSSN.cc
|
||||
Obj.cc
|
||||
OpaqueVal.cc
|
||||
OSFinger.cc
|
||||
PacketFilter.cc
|
||||
PacketSort.cc
|
||||
|
|
200
src/OpaqueVal.cc
Normal file
200
src/OpaqueVal.cc
Normal file
|
@ -0,0 +1,200 @@
|
|||
#include "OpaqueVal.h"
|
||||
#include "Reporter.h"
|
||||
#include "Serializer.h"
|
||||
|
||||
bool HashVal::IsValid() const
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool HashVal::Init()
|
||||
{
|
||||
assert(! "missing implementation of Init()");
|
||||
return false;
|
||||
}
|
||||
|
||||
StringVal* HashVal::Get()
|
||||
{
|
||||
if ( ! valid )
|
||||
return new StringVal("");
|
||||
|
||||
StringVal* result = Finish();
|
||||
valid = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HashVal::Feed(const void* data, size_t size)
|
||||
{
|
||||
if ( valid )
|
||||
return Update(data, size);
|
||||
|
||||
reporter->InternalError("invalidated opaque handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HashVal::Update(const void*, size_t)
|
||||
{
|
||||
assert(! "missing implementation of Update()");
|
||||
return false;
|
||||
}
|
||||
|
||||
StringVal* HashVal::Finish()
|
||||
{
|
||||
assert(! "missing implementation of Finish()");
|
||||
return new StringVal("");
|
||||
}
|
||||
|
||||
HashVal::HashVal(OpaqueType* t) : OpaqueVal(t), valid(true) { }
|
||||
|
||||
IMPLEMENT_SERIAL(HashVal, SER_HASH_VAL);
|
||||
|
||||
bool HashVal::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
return SERIALIZE(valid);
|
||||
}
|
||||
|
||||
bool HashVal::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
return UNSERIALIZE(&valid);
|
||||
}
|
||||
|
||||
|
||||
void MD5Val::digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH])
|
||||
{
|
||||
MD5_CTX h;
|
||||
|
||||
md5_init(&h);
|
||||
loop_over_list(vlist, i)
|
||||
{
|
||||
Val* v = vlist[i];
|
||||
if ( v->Type()->Tag() == TYPE_STRING )
|
||||
{
|
||||
const BroString* str = v->AsString();
|
||||
md5_update(&h, str->Bytes(), str->Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
ODesc d(DESC_BINARY);
|
||||
v->Describe(&d);
|
||||
md5_update(&h, (const u_char *) d.Bytes(), d.Len());
|
||||
}
|
||||
}
|
||||
md5_final(&h, result);
|
||||
}
|
||||
|
||||
void MD5Val::hmac(val_list& vlist,
|
||||
u_char key[MD5_DIGEST_LENGTH],
|
||||
u_char result[MD5_DIGEST_LENGTH])
|
||||
{
|
||||
digest(vlist, result);
|
||||
for ( int i = 0; i < MD5_DIGEST_LENGTH; ++i )
|
||||
result[i] ^= key[i];
|
||||
MD5(result, MD5_DIGEST_LENGTH, result);
|
||||
}
|
||||
|
||||
bool MD5Val::Init()
|
||||
{
|
||||
md5_init(&ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MD5Val::Update(const void* data, size_t size)
|
||||
{
|
||||
assert(IsValid());
|
||||
md5_update(&ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
StringVal* MD5Val::Finish()
|
||||
{
|
||||
assert(IsValid());
|
||||
u_char digest[MD5_DIGEST_LENGTH];
|
||||
md5_final(&ctx, digest);
|
||||
return new StringVal(md5_digest_print(digest));
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(MD5Val, SER_MD5_VAL);
|
||||
|
||||
bool MD5Val::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
// TODO: Implement serialization of MD5 state.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MD5Val::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
// TODO: Implement deserialization of MD5 state.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SHA1Val::Init()
|
||||
{
|
||||
sha1_init(&ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHA1Val::Update(const void* data, size_t size)
|
||||
{
|
||||
assert(IsValid());
|
||||
sha1_update(&ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
StringVal* SHA1Val::Finish()
|
||||
{
|
||||
assert(IsValid());
|
||||
u_char digest[SHA_DIGEST_LENGTH];
|
||||
sha1_final(&ctx, digest);
|
||||
return new StringVal(sha1_digest_print(digest));
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(SHA1Val, SER_SHA1_VAL);
|
||||
|
||||
bool SHA1Val::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
// TODO: Implement serialization of SHA1 state.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHA1Val::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
// TODO: Implement deserialization of SHA1 state.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SHA256Val::Init()
|
||||
{
|
||||
sha256_init(&ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHA256Val::Update(const void* data, size_t size)
|
||||
{
|
||||
assert(IsValid());
|
||||
sha256_update(&ctx, data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
StringVal* SHA256Val::Finish()
|
||||
{
|
||||
assert(IsValid());
|
||||
u_char digest[SHA256_DIGEST_LENGTH];
|
||||
sha256_final(&ctx, digest);
|
||||
return new StringVal(sha256_digest_print(digest));
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(SHA256Val, SER_SHA256_VAL);
|
||||
|
||||
bool SHA256Val::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
// TODO: Implement serialization of SHA256 state.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHA256Val::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
// TODO: Implement deserialization of SHA256 state.
|
||||
return false;
|
||||
}
|
84
src/OpaqueVal.h
Normal file
84
src/OpaqueVal.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef OPAQUEVAL_H
|
||||
#define OPAQUEVAL_H
|
||||
|
||||
#include "Val.h"
|
||||
#include "digest.h"
|
||||
|
||||
class HashVal : public OpaqueVal {
|
||||
public:
|
||||
virtual bool IsValid() const;
|
||||
virtual bool Init();
|
||||
virtual bool Feed(const void* data, size_t size);
|
||||
virtual StringVal* Get();
|
||||
|
||||
protected:
|
||||
HashVal() { };
|
||||
HashVal(OpaqueType* t);
|
||||
virtual bool Update(const void* data, size_t size);
|
||||
virtual StringVal* Finish();
|
||||
|
||||
DECLARE_SERIAL(HashVal);
|
||||
|
||||
private:
|
||||
// This flag exists because Get() can only be called once.
|
||||
bool valid;
|
||||
};
|
||||
|
||||
class MD5Val : public HashVal {
|
||||
public:
|
||||
static void digest(val_list& vlist, u_char result[MD5_DIGEST_LENGTH]);
|
||||
|
||||
static void hmac(val_list& vlist,
|
||||
u_char key[MD5_DIGEST_LENGTH],
|
||||
u_char result[MD5_DIGEST_LENGTH]);
|
||||
|
||||
MD5Val() : HashVal(new OpaqueType("md5")) { }
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool Init() /* override */;
|
||||
virtual bool Update(const void* data, size_t size) /* override */;
|
||||
virtual StringVal* Finish() /* override */;
|
||||
|
||||
DECLARE_SERIAL(MD5Val);
|
||||
|
||||
private:
|
||||
MD5_CTX ctx;
|
||||
};
|
||||
|
||||
class SHA1Val : public HashVal {
|
||||
public:
|
||||
SHA1Val() : HashVal(new OpaqueType("sha1")) { }
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool Init() /* override */;
|
||||
virtual bool Update(const void* data, size_t size) /* override */;
|
||||
virtual StringVal* Finish() /* override */;
|
||||
|
||||
DECLARE_SERIAL(SHA1Val);
|
||||
|
||||
private:
|
||||
SHA_CTX ctx;
|
||||
};
|
||||
|
||||
class SHA256Val : public HashVal {
|
||||
public:
|
||||
SHA256Val() : HashVal(new OpaqueType("sha256")) { }
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool Init() /* override */;
|
||||
virtual bool Update(const void* data, size_t size) /* override */;
|
||||
virtual StringVal* Finish() /* override */;
|
||||
|
||||
DECLARE_SERIAL(SHA256Val);
|
||||
|
||||
private:
|
||||
SHA256_CTX ctx;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -98,6 +98,11 @@ SERIAL_VAL(RECORD_VAL, 10)
|
|||
SERIAL_VAL(ENUM_VAL, 11)
|
||||
SERIAL_VAL(VECTOR_VAL, 12)
|
||||
SERIAL_VAL(MUTABLE_VAL, 13)
|
||||
SERIAL_VAL(OPAQUE_VAL, 14)
|
||||
SERIAL_VAL(HASH_VAL, 15)
|
||||
SERIAL_VAL(MD5_VAL, 16)
|
||||
SERIAL_VAL(SHA1_VAL, 17)
|
||||
SERIAL_VAL(SHA256_VAL, 18)
|
||||
|
||||
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||
SERIAL_EXPR(EXPR, 1)
|
||||
|
|
32
src/Val.cc
32
src/Val.cc
|
@ -3114,6 +3114,38 @@ void VectorVal::ValDescribe(ODesc* d) const
|
|||
d->Add("]");
|
||||
}
|
||||
|
||||
OpaqueVal::OpaqueVal(OpaqueType* t) : opaque_type(t) { }
|
||||
|
||||
OpaqueVal::~OpaqueVal()
|
||||
{
|
||||
Unref(opaque_type);
|
||||
}
|
||||
|
||||
bool OpaqueVal::IsValid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(OpaqueVal, SER_OPAQUE_VAL);
|
||||
|
||||
bool OpaqueVal::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_OPAQUE_VAL, Val);
|
||||
assert(opaque_type);
|
||||
// TODO: how to serialize a serializable class?
|
||||
//return SERIALIZE(*opaque_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpaqueVal::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(Val);
|
||||
// TODO: how to deserialize a serializable class?
|
||||
//opaque_type = new OpaqueType();
|
||||
//return UNSERIALIZE(opaque_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
||||
{
|
||||
|
|
18
src/Val.h
18
src/Val.h
|
@ -1013,6 +1013,24 @@ protected:
|
|||
VectorType* vector_type;
|
||||
};
|
||||
|
||||
// See OpaqueVal.h for derived classes.
|
||||
class OpaqueVal : public Val {
|
||||
public:
|
||||
OpaqueVal(OpaqueType* t);
|
||||
virtual ~OpaqueVal();
|
||||
|
||||
// Determines whether the opaque value is in a valid state.
|
||||
virtual bool IsValid() const;
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
OpaqueVal() { }
|
||||
|
||||
DECLARE_SERIAL(OpaqueVal);
|
||||
|
||||
OpaqueType* opaque_type;
|
||||
};
|
||||
|
||||
|
||||
// Checks the given value for consistency with the given type. If an
|
||||
// exact match, returns it. If promotable, returns the promoted version,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue