X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pyderasn.py;h=b3ee318ae7f03cecbe120f8173e4de1a580e8eb6;hb=3906f3ed9567496401ada4ba71a342215b8785f1;hp=c8e29e3d767249c9de62be911540c9c3cf9e7992;hpb=05f030d41edef47ea94f68b9e770590d96e743af;p=pyderasn.git diff --git a/pyderasn.py b/pyderasn.py index c8e29e3..b3ee318 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -608,7 +608,7 @@ class NotEnoughData(DecodeError): pass -class LenIndefiniteForm(DecodeError): +class LenIndefForm(DecodeError): pass @@ -803,6 +803,11 @@ def len_encode(l): def len_decode(data): + """Decode length + + :returns: (decoded length, length's length, remaining data) + :raises LenIndefForm: if indefinite form encoding is met + """ if len(data) == 0: raise NotEnoughData("no data at all") first_octet = byte2int(data) @@ -812,7 +817,7 @@ def len_decode(data): if octets_num + 1 > len(data): raise NotEnoughData("encoded length is longer than data") if octets_num == 0: - raise LenIndefiniteForm() + raise LenIndefForm() if byte2int(data[1:]) == 0: raise DecodeError("leading zeros") l = 0 @@ -986,7 +991,7 @@ class Obj(object): ) try: l, llen, v = len_decode(lv) - except LenIndefiniteForm as err: + except LenIndefForm as err: if not ctx.get("bered", False): raise err.__class__( msg=err.msg, @@ -1826,6 +1831,8 @@ class BitString(Obj): >>> b.bit_len 88 + >>> BitString("'0A3B5F291CD'H") + BIT STRING 44 bits 0a3b5f291cd0 >>> b = BitString("'010110000000'B") BIT STRING 12 bits 5800 >>> b.bit_len @@ -1914,21 +1921,25 @@ class BitString(Obj): if isinstance(value, (string_types, binary_type)): if ( isinstance(value, string_types) and - value.startswith("'") and - value.endswith("'B") + value.startswith("'") ): - value = value[1:-2] - if not set(value) <= set(("0", "1")): - raise ValueError("B's coding contains unacceptable chars") - return self._bits2octets(value) + if value.endswith("'B"): + value = value[1:-2] + if not set(value) <= set(("0", "1")): + raise ValueError("B's coding contains unacceptable chars") + return self._bits2octets(value) + elif value.endswith("'H"): + value = value[1:-2] + return ( + len(value) * 4, + hexdec(value + ("" if len(value) % 2 == 0 else "0")), + ) + else: + raise InvalidValueType((self.__class__, string_types, binary_type)) elif isinstance(value, binary_type): return (len(value) * 8, value) else: - raise InvalidValueType(( - self.__class__, - string_types, - binary_type, - )) + raise InvalidValueType((self.__class__, string_types, binary_type)) if isinstance(value, tuple): if ( len(value) == 2 and @@ -2126,7 +2137,7 @@ class BitString(Obj): lenindef = False try: l, llen, v = len_decode(lv) - except LenIndefiniteForm: + except LenIndefForm: llen, l, v = 1, 0, lv[1:] lenindef = True except DecodeError as err: @@ -2478,7 +2489,7 @@ class OctetString(Obj): lenindef = False try: l, llen, v = len_decode(lv) - except LenIndefiniteForm: + except LenIndefForm: llen, l, v = 1, 0, lv[1:] lenindef = True except DecodeError as err: @@ -3240,6 +3251,10 @@ class CommonString(OctetString): tlen=self.tlen, llen=self.llen, vlen=self.vlen, + expl_offset=self.expl_offset if self.expled else None, + expl_tlen=self.expl_tlen if self.expled else None, + expl_llen=self.expl_llen if self.expled else None, + expl_vlen=self.expl_vlen if self.expled else None, ) @@ -3428,6 +3443,10 @@ class UTCTime(CommonString): tlen=self.tlen, llen=self.llen, vlen=self.vlen, + expl_offset=self.expl_offset if self.expled else None, + expl_tlen=self.expl_tlen if self.expled else None, + expl_llen=self.expl_llen if self.expled else None, + expl_vlen=self.expl_vlen if self.expled else None, ) @@ -3899,7 +3918,7 @@ class Any(Obj): ) try: l, llen, v = len_decode(lv) - except LenIndefiniteForm as err: + except LenIndefForm as err: if not ctx.get("bered", False): raise err.__class__( msg=err.msg, @@ -4282,7 +4301,7 @@ class Sequence(Obj): lenindef = False try: l, llen, v = len_decode(lv) - except LenIndefiniteForm as err: + except LenIndefForm as err: if not ctx.get("bered", False): raise err.__class__( msg=err.msg, @@ -4313,8 +4332,8 @@ class Sequence(Obj): values = {} for name, spec in self.specs.items(): if spec.optional and ( - (lenindef and v[:EOC_LEN].tobytes() == EOC) or - len(v) == 0 + (lenindef and v[:EOC_LEN].tobytes() == EOC) or + len(v) == 0 ): continue sub_decode_path = decode_path + (name,) @@ -4507,7 +4526,7 @@ class Set(Sequence): lenindef = False try: l, llen, v = len_decode(lv) - except LenIndefiniteForm as err: + except LenIndefForm as err: if not ctx.get("bered", False): raise err.__class__( msg=err.msg, @@ -4794,7 +4813,7 @@ class SequenceOf(Obj): lenindef = False try: l, llen, v = len_decode(lv) - except LenIndefiniteForm as err: + except LenIndefForm as err: if not ctx.get("bered", False): raise err.__class__( msg=err.msg,