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
|
NetVar.cc
|
||||||
NetbiosSSN.cc
|
NetbiosSSN.cc
|
||||||
Obj.cc
|
Obj.cc
|
||||||
|
OpaqueVal.cc
|
||||||
OSFinger.cc
|
OSFinger.cc
|
||||||
PacketFilter.cc
|
PacketFilter.cc
|
||||||
PacketSort.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(ENUM_VAL, 11)
|
||||||
SERIAL_VAL(VECTOR_VAL, 12)
|
SERIAL_VAL(VECTOR_VAL, 12)
|
||||||
SERIAL_VAL(MUTABLE_VAL, 13)
|
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)
|
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||||
SERIAL_EXPR(EXPR, 1)
|
SERIAL_EXPR(EXPR, 1)
|
||||||
|
|
32
src/Val.cc
32
src/Val.cc
|
@ -3114,6 +3114,38 @@ void VectorVal::ValDescribe(ODesc* d) const
|
||||||
d->Add("]");
|
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)
|
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;
|
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
|
// Checks the given value for consistency with the given type. If an
|
||||||
// exact match, returns it. If promotable, returns the promoted version,
|
// exact match, returns it. If promotable, returns the promoted version,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue