Skip to content

Commit

Permalink
try to expose less useless stuff in each unit, for #56
Browse files Browse the repository at this point in the history
As per the suggestion here #56 (review)
  • Loading branch information
mmguero committed May 18, 2021
1 parent 8cedba7 commit 51ec8fd
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 93 deletions.
104 changes: 48 additions & 56 deletions analyzer/protocol/ldap/asn1.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,23 @@ public type ASN1Class = enum {
#- ASN.1 tag definition (including length) ------------------------------------

type LengthType = unit {
var len: uint64;
var tag_len: uint8;

data : bitfield(8) {
num: 0..6;
islong: 7;
};

var len: uint64;

var tag_len: uint8;

switch ( self.data.islong ) {
0 -> : void {
self.len = self.data.num;
self.tag_len = 1;
}
1 -> length_parse: bytes &size=self.data.num
&convert=$$.to_uint(spicy::ByteOrder::Network) {
self.len = self.length_parse;
1 -> : bytes &size=self.data.num
&convert=$$.to_uint(spicy::ByteOrder::Network) {
self.len = $$;
self.tag_len = self.data.num + 1;
}
};
Expand All @@ -92,41 +92,37 @@ type ASN1Tag = unit {
var class: ASN1Class;
var constructed: bool;

data : bitfield(8) {
: bitfield(8) {
num: 0..4;
constructed: 5;
class: 6..7;
} {
self.type_ = ASN1Type(self.data.num);
self.class = ASN1Class(self.data.class);
self.constructed = cast<bool>(self.data.constructed);
self.type_ = ASN1Type($$.num);
self.class = ASN1Class($$.class);
self.constructed = cast<bool>($$.constructed);
}
};

#- ASN.1 bit string -----------------------------------------------------------
# https://www.obj-sys.com/asn1tutorial/node10.html

type ASN1BitString = unit(len: uint64, constructed: bool) {
unused_bits: uint8;
: uint8; # unused bits
value_bits: bytes &size=(len - 1);

# TODO - constructed form
# https://github.com/zeek/spicy/issues/921
# `bytes` needs << and >> support before we can implement complex bitstrings
#
};

#- ASN.1 octet string ---------------------------------------------------------
# https://www.obj-sys.com/asn1tutorial/node10.html

type ASN1OctetString = unit(len: uint64, constructed: bool) {
var len: uint64;
value: bytes &size = len;

# TODO - constructed form

on %done {
self.len = len;
}
};

#- ASN.1 various string types -------------------------------------------------
Expand All @@ -135,37 +131,36 @@ type ASN1OctetString = unit(len: uint64, constructed: bool) {
type ASN1String = unit(tag: ASN1Tag, len: uint64) {
var value: string = "";

octetstring: ASN1OctetString(len, tag.constructed);

switch ( tag.type_ ) {

# see "Restricted Character String Types" in
# "Generic String Encoding Rules (GSER) for ASN.1 Types"
# (https://datatracker.ietf.org/doc/html/rfc3641#section-3.2)

ASN1Type::PrintableString,
ASN1Type::GeneralizedTime,
ASN1Type::UTCTime -> : void {
self.value = self.octetstring.value.decode(hilti::Charset::ASCII);
}

ASN1Type::UTF8String,
ASN1Type::GeneralString,
ASN1Type::CharacterString,
ASN1Type::GraphicString,
ASN1Type::IA5String,
ASN1Type::NumericString,
ASN1Type::TeletextString,
ASN1Type::VideotextString,
ASN1Type::VisibleString,
# TODO: RFC3641 mentions special UTF-8 mapping rules for
# BMPString and UniversalString. This *may* not be correct.
ASN1Type::BMPString,
ASN1Type::UniversalString -> : void {
self.value = self.octetstring.value.decode(hilti::Charset::UTF8);
: ASN1OctetString(len, tag.constructed) {
switch ( tag.type_ ) {

# see "Restricted Character String Types" in
# "Generic String Encoding Rules (GSER) for ASN.1 Types"
# (https://datatracker.ietf.org/doc/html/rfc3641#section-3.2)

case ASN1Type::PrintableString,
ASN1Type::GeneralizedTime,
ASN1Type::UTCTime: {
self.value = $$.value.decode(hilti::Charset::ASCII);
}

case ASN1Type::UTF8String,
ASN1Type::GeneralString,
ASN1Type::CharacterString,
ASN1Type::GraphicString,
ASN1Type::IA5String,
ASN1Type::NumericString,
ASN1Type::TeletextString,
ASN1Type::VideotextString,
ASN1Type::VisibleString,
# TODO: RFC3641 mentions special UTF-8 mapping rules for
# BMPString and UniversalString. This *may* not be correct.
ASN1Type::BMPString,
ASN1Type::UniversalString: {
self.value = $$.value.decode(hilti::Charset::UTF8);
}
}

};
}
};

#- ASN.1 OID ------------------------------------------------------------------
Expand All @@ -176,32 +171,31 @@ type ASN1ObjectIdentifierNibble = unit {
num: 0..6;
more: 7;
};
};
} &convert=self.data;

type ASN1ObjectIdentifier = unit(len: uint64) {
var oid: vector<uint64>;
var temp: uint64;
var oidstring: string;

first: uint8 if ( len >= 1 ) {
self.temp = self.first / 40;
: uint8 if ( len >= 1 ) {
self.temp = $$ / 40;
self.oid.push_back( self.temp );
self.oidstring = "%d" % (self.temp);
self.temp = self.first % 40;
self.temp = $$ % 40;
self.oid.push_back( self.temp );
self.oidstring = self.oidstring + ".%d" % (self.temp);
self.temp = 0;
}

sublist: ASN1ObjectIdentifierNibble[len - 1] foreach {
self.temp = ( self.temp<<7 ) | $$.data.num;
if ( $$.data.more != 1 ) {
self.temp = ( self.temp<<7 ) | $$.num;
if ( $$.more != 1 ) {
self.oid.push_back(self.temp);
self.oidstring = self.oidstring + ".%d" % (self.temp);
self.temp = 0;
}
}

};


Expand Down Expand Up @@ -261,7 +255,6 @@ public type ASN1Body = unit(head: ASN1Header, recursive: bool) {
# unknown (to me) ASN.1 enumeration, skip over silently
* -> unimplemented_value: bytes &size=head.len.len;
};

};

#- ASN.1 array of ASN.1 sequence/set sub-messages (up to msgLen bytes) --------
Expand All @@ -286,9 +279,8 @@ public type ASN1Message = unit(recursive: bool) {
ASN1Class::Application,
ASN1Class::ContextSpecific,
ASN1Class::Private -> application_data: bytes &size=self.head.len.len {
self.application_id = self.head.tag.data.num;
self.application_id = cast<int32>(self.head.tag.type_);
}

};

};
60 changes: 23 additions & 37 deletions analyzer/protocol/ldap/ldap.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ public type Message = unit {
};
# TODO: add support for switch-level &parse-from/&parse-at
# https://github.com/zeek/spicy/issues/913

} &requires=((self?.messageID) && (self?.opcode) && (self.opcode != ProtocolOpcode::NOT_SET));

#-----------------------------------------------------------------------------
Expand All @@ -204,36 +203,36 @@ type SaslCredentials = unit() {
};

type BindRequest = unit(inout message: Message) {

version: asn1::ASN1Message(True) &convert=$$.body.num_value;
name: asn1::ASN1Message(True) &convert=$$.body.str_value {
message.obj = self.name;
}
var authType: BindAuthType = BindAuthType::NOT_SET;
var simpleCreds: string = "";
var saslData: bytes;

authentication: asn1::ASN1Message(True) {
if (self.authentication?.application_id) {
self.authType = cast<BindAuthType>(cast<uint8>(self.authentication.application_id));
: asn1::ASN1Message(True) {
if ($$?.application_id) {
self.authType = cast<BindAuthType>(cast<uint8>($$.application_id));
}
if ((self.authType == BindAuthType::BIND_AUTH_SIMPLE) &&
(|self.authentication.application_data| > 0)) {
self.simpleCreds = self.authentication.application_data.decode();
(|$$.application_data| > 0)) {
self.simpleCreds = $$.application_data.decode();
if (|self.simpleCreds| > 0) {
message.arg = self.simpleCreds;
}
} else {
self.saslData == $$.application_data;
}
}
saslCreds: SaslCredentials() &parse-from=self.authentication.application_data if (self.authType == BindAuthType::BIND_AUTH_SASL) {
saslCreds: SaslCredentials() &parse-from=self.saslData if (self?.saslData) {
message.arg = self.saslCreds.mechanism;
}

} &requires=((self?.authType) && (self.authType != BindAuthType::NOT_SET));

type BindResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}

# TODO: if we want to parse SASL credentials returned
Expand Down Expand Up @@ -318,7 +317,6 @@ type AttributeValueAssertion = unit() {
}
}
}

};

type SubstringFilter = unit() {
Expand All @@ -341,7 +339,6 @@ type SubstringFilter = unit() {
#
#}
}

};

type SearchFilter = unit() {
Expand Down Expand Up @@ -391,7 +388,6 @@ type SearchFilter = unit() {
};

type SearchRequest = unit(inout message: Message) {

baseObject: asn1::ASN1Message(True) &convert=$$.body.str_value {
message.obj = self.baseObject;
}
Expand All @@ -409,19 +405,16 @@ type SearchRequest = unit(inout message: Message) {
};

type SearchResultEntry = unit(inout message: Message) {

objectName: asn1::ASN1Message(True) &convert=$$.body.str_value {
message.obj = self.objectName;
}
# TODO: if we want to descend down into PartialAttributeList
attributes: asn1::ASN1Message(True);

};

type SearchResultDone = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand All @@ -435,7 +428,6 @@ type SearchResultDone = unit(inout message: Message) {
# https://tools.ietf.org/html/rfc4511#section-4.6

type ModifyRequest = unit(inout message: Message) {

objectName: asn1::ASN1Message(True) &convert=$$.body.str_value {
message.obj = self.objectName;
}
Expand All @@ -444,9 +436,8 @@ type ModifyRequest = unit(inout message: Message) {
};

type ModifyResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand All @@ -461,9 +452,8 @@ type ModifyResponse = unit(inout message: Message) {
# };

type AddResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand All @@ -472,16 +462,14 @@ type AddResponse = unit(inout message: Message) {
# https://tools.ietf.org/html/rfc4511#section-4.8

type DelRequest = unit(inout message: Message) {

objectName: asn1::ASN1Message(True) &convert=$$.body.str_value {
message.obj = self.objectName;
}
};

type DelResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand All @@ -495,9 +483,8 @@ type DelResponse = unit(inout message: Message) {
# };

type ModDNResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand All @@ -511,9 +498,8 @@ type ModDNResponse = unit(inout message: Message) {
# };

type CompareResponse = unit(inout message: Message) {

result: Result {
message.result = self.result;
: Result {
message.result = $$;
}
};

Expand Down

0 comments on commit 51ec8fd

Please sign in to comment.