Skip to content

Commit df6eabe

Browse files
authored
ASN.1: minor cleanup + LDAP/KRB bug fixes (#4306)
1 parent 77569af commit df6eabe

File tree

7 files changed

+190
-150
lines changed

7 files changed

+190
-150
lines changed

scapy/asn1/ber.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from scapy.compat import chb, orb, bytes_encode
1616
from scapy.utils import binrepr, inet_aton, inet_ntoa
1717
from scapy.asn1.asn1 import (
18+
ASN1Tag,
1819
ASN1_BADTAG,
1920
ASN1_BadTag_Decoding_Error,
2021
ASN1_Class,
@@ -216,14 +217,15 @@ def BER_id_enc(n):
216217

217218

218219
def BER_tagging_dec(s, # type: bytes
219-
hidden_tag=None, # type: Optional[Any]
220+
hidden_tag=None, # type: Optional[int | ASN1Tag]
220221
implicit_tag=None, # type: Optional[int]
221222
explicit_tag=None, # type: Optional[int]
222223
safe=False, # type: Optional[bool]
223224
_fname="", # type: str
224225
):
225226
# type: (...) -> Tuple[Optional[int], bytes]
226227
# We output the 'real_tag' if it is different from the (im|ex)plicit_tag.
228+
# 'hidden_tag' is the type tag that is implicited when 'implicit_tag' is used.
227229
real_tag = None
228230
if len(s) > 0:
229231
err_msg = (
@@ -233,13 +235,13 @@ def BER_tagging_dec(s, # type: bytes
233235
if implicit_tag is not None:
234236
ber_id, s = BER_id_dec(s)
235237
if ber_id != implicit_tag:
236-
if not safe and ber_id & 0x1f != implicit_tag & 0x1f:
238+
if not safe and ber_id != implicit_tag:
237239
raise BER_Decoding_Error(err_msg % (
238240
ber_id, implicit_tag, _fname),
239241
remaining=s)
240242
else:
241243
real_tag = ber_id
242-
s = chb(hash(hidden_tag)) + s
244+
s = chb(int(hidden_tag)) + s # type: ignore
243245
elif explicit_tag is not None:
244246
ber_id, s = BER_id_dec(s)
245247
if ber_id != explicit_tag:
@@ -253,11 +255,11 @@ def BER_tagging_dec(s, # type: bytes
253255
return real_tag, s
254256

255257

256-
def BER_tagging_enc(s, hidden_tag=None, implicit_tag=None, explicit_tag=None):
257-
# type: (bytes, Optional[Any], Optional[int], Optional[int]) -> bytes
258+
def BER_tagging_enc(s, implicit_tag=None, explicit_tag=None):
259+
# type: (bytes, Optional[int], Optional[int]) -> bytes
258260
if len(s) > 0:
259261
if implicit_tag is not None:
260-
s = BER_id_enc((hash(hidden_tag) & ~(0x1f)) | implicit_tag) + s[1:]
262+
s = BER_id_enc(implicit_tag) + s[1:]
261263
elif explicit_tag is not None:
262264
s = BER_id_enc(explicit_tag) + BER_len_enc(len(s)) + s
263265
return s
@@ -424,9 +426,9 @@ def enc(cls, i, size_len=0):
424426
i >>= 8
425427
if not i:
426428
break
427-
s = [chb(hash(c)) for c in ls]
429+
s = [chb(int(c)) for c in ls]
428430
s.append(BER_len_enc(len(s), size=size_len))
429-
s.append(chb(hash(cls.tag)))
431+
s.append(chb(int(cls.tag)))
430432
s.reverse()
431433
return b"".join(s)
432434

@@ -495,7 +497,7 @@ def enc(cls, _s, size_len=0):
495497
s = b"".join(chb(int(b"".join(chb(y) for y in x), 2))
496498
for x in zip(*[iter(s)] * 8))
497499
s = chb(unused_bits) + s
498-
return chb(hash(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
500+
return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
499501

500502

501503
class BERcodec_STRING(BERcodec_Object[str]):
@@ -506,7 +508,7 @@ def enc(cls, _s, size_len=0):
506508
# type: (Union[str, bytes], Optional[int]) -> bytes
507509
s = bytes_encode(_s)
508510
# Be sure we are encoding bytes
509-
return chb(hash(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
511+
return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
510512

511513
@classmethod
512514
def do_dec(cls,
@@ -526,7 +528,7 @@ class BERcodec_NULL(BERcodec_INTEGER):
526528
def enc(cls, i, size_len=0):
527529
# type: (int, Optional[int]) -> bytes
528530
if i == 0:
529-
return chb(hash(cls.tag)) + b"\0"
531+
return chb(int(cls.tag)) + b"\0"
530532
else:
531533
return super(cls, cls).enc(i, size_len=size_len)
532534

@@ -546,7 +548,7 @@ def enc(cls, _oid, size_len=0):
546548
lst[1] += 40 * lst[0]
547549
del lst[0]
548550
s = b"".join(BER_num_enc(k) for k in lst)
549-
return chb(hash(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
551+
return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
550552

551553
@classmethod
552554
def do_dec(cls,
@@ -631,7 +633,7 @@ def enc(cls, _ll, size_len=0):
631633
ll = _ll
632634
else:
633635
ll = b"".join(x.enc(cls.codec) for x in _ll)
634-
return chb(hash(cls.tag)) + BER_len_enc(len(ll), size=size_len) + ll
636+
return chb(int(cls.tag)) + BER_len_enc(len(ll), size=size_len) + ll
635637

636638
@classmethod
637639
def do_dec(cls,
@@ -678,7 +680,7 @@ def enc(cls, ipaddr_ascii, size_len=0): # type: ignore
678680
s = inet_aton(ipaddr_ascii)
679681
except Exception:
680682
raise BER_Encoding_Error("IPv4 address could not be encoded")
681-
return chb(hash(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
683+
return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
682684

683685
@classmethod
684686
def do_dec(cls, s, context=None, safe=False):

scapy/asn1fields.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ def __init__(self,
110110
if (implicit_tag is not None) and (explicit_tag is not None):
111111
err_msg = "field cannot be both implicitly and explicitly tagged"
112112
raise ASN1_Error(err_msg)
113-
self.implicit_tag = implicit_tag
114-
self.explicit_tag = explicit_tag
113+
self.implicit_tag = implicit_tag and int(implicit_tag)
114+
self.explicit_tag = explicit_tag and int(explicit_tag)
115115
# network_tag gets useful for ASN1F_CHOICE
116116
self.network_tag = int(implicit_tag or explicit_tag or self.ASN1_tag)
117117
self.owners = [] # type: List[Type[ASN1_Packet]]
@@ -173,7 +173,7 @@ def i2m(self, pkt, x):
173173
raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name)) # noqa: E501
174174
else:
175175
s = self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x, size_len=self.size_len)
176-
return BER_tagging_enc(s, hidden_tag=self.ASN1_tag,
176+
return BER_tagging_enc(s,
177177
implicit_tag=self.implicit_tag,
178178
explicit_tag=self.explicit_tag)
179179

@@ -709,8 +709,6 @@ def __init__(self, name, default, *args, **kwargs):
709709
else:
710710
# should be ASN1F_field instance
711711
self.choices[p.network_tag] = p
712-
if p.implicit_tag is not None:
713-
self.choices[p.implicit_tag & 0x1f] = p
714712
self.pktchoices[hash(p.cls)] = (p.implicit_tag, p.explicit_tag) # noqa: E501
715713
else:
716714
raise ASN1_Error("ASN1F_CHOICE: no tag found for one field")
@@ -729,9 +727,7 @@ def m2i(self, pkt, s):
729727
if tag in self.choices:
730728
choice = self.choices[tag]
731729
else:
732-
if tag & 0x1f in self.choices: # Try resolve only the tag number
733-
choice = self.choices[tag & 0x1f]
734-
elif self.flexible_tag:
730+
if self.flexible_tag:
735731
choice = ASN1F_field
736732
else:
737733
raise ASN1_Error(
@@ -757,7 +753,7 @@ def i2m(self, pkt, x):
757753
s = raw(x)
758754
if hash(type(x)) in self.pktchoices:
759755
imp, exp = self.pktchoices[hash(type(x))]
760-
s = BER_tagging_enc(s, hidden_tag=self.ASN1_tag,
756+
s = BER_tagging_enc(s,
761757
implicit_tag=imp,
762758
explicit_tag=exp)
763759
return BER_tagging_enc(s, explicit_tag=self.explicit_tag)
@@ -800,7 +796,7 @@ def __init__(self,
800796
)
801797
if implicit_tag is None and explicit_tag is None and cls is not None:
802798
if cls.ASN1_root.ASN1_tag == ASN1_Class_UNIVERSAL.SEQUENCE:
803-
self.network_tag = 16 | 0x20
799+
self.network_tag = 16 | 0x20 # 16 + CONSTRUCTED
804800
self.default = default
805801

806802
def m2i(self, pkt, s):
@@ -845,7 +841,7 @@ def i2m(self,
845841
if not hasattr(x, "ASN1_root"):
846842
# A normal Packet (!= ASN1)
847843
return s
848-
return BER_tagging_enc(s, hidden_tag=self.ASN1_tag,
844+
return BER_tagging_enc(s,
849845
implicit_tag=self.implicit_tag,
850846
explicit_tag=self.explicit_tag)
851847

0 commit comments

Comments
 (0)