X-Git-Url: http://www.git.cypherpunks.ru/?p=pyderasn.git;a=blobdiff_plain;f=pyderasn.py;h=391ff9ea1b456f68d5f761b5be60089220b9d83b;hp=50479c60a9d47b3266975178bbfb25ecdff9e841;hb=357b330105dcecde29121a6bc203d58c6a91eb78;hpb=62c83afbcea277bcaec2a70597e3cfdc0991410b diff --git a/pyderasn.py b/pyderasn.py index 50479c6..391ff9e 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -369,10 +369,6 @@ useful for SEQUENCE/SET OF-s. BER encoding ------------ -.. warning:: - - Currently BER support is not extensively tested. - By default PyDERASN accepts only DER encoded data. It always encodes to DER. But you can optionally enable BER decoding with setting ``bered`` :ref:`context ` argument to True. Indefinite lengths and @@ -2009,9 +2005,7 @@ class BitString(Obj): 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): + if isinstance(value, binary_type): return (len(value) * 8, value) else: raise InvalidValueType((self.__class__, string_types, binary_type)) @@ -2223,7 +2217,7 @@ class BitString(Obj): decode_path=decode_path, offset=offset, ) - if l > 0 and l > len(v): + if l > len(v): raise NotEnoughData( "encoded length is longer than data", klass=self.__class__, @@ -2251,7 +2245,7 @@ class BitString(Obj): raise DecodeError( "chunk out of bounds", klass=self.__class__, - decode_path=len(chunks) - 1, + decode_path=decode_path + (str(len(chunks) - 1),), offset=chunks[-1].offset, ) sub_decode_path = decode_path + (str(len(chunks)),) @@ -2286,7 +2280,7 @@ class BitString(Obj): for chunk_i, chunk in enumerate(chunks[:-1]): if chunk.bit_len % 8 != 0: raise DecodeError( - "BitString chunk is not multiple of 8 bit", + "BitString chunk is not multiple of 8 bits", klass=self.__class__, decode_path=decode_path + (str(chunk_i),), offset=chunk.offset, @@ -2591,20 +2585,13 @@ class OctetString(Obj): decode_path=decode_path, offset=offset, ) - if l > 0 and l > len(v): + if l > len(v): raise NotEnoughData( "encoded length is longer than data", klass=self.__class__, decode_path=decode_path, offset=offset, ) - if not lenindef and l == 0: - raise NotEnoughData( - "zero length", - klass=self.__class__, - decode_path=decode_path, - offset=offset, - ) chunks = [] sub_offset = offset + tlen + llen vlen = 0 @@ -2619,7 +2606,7 @@ class OctetString(Obj): raise DecodeError( "chunk out of bounds", klass=self.__class__, - decode_path=len(chunks) - 1, + decode_path=decode_path + (str(len(chunks) - 1),), offset=chunks[-1].offset, ) sub_decode_path = decode_path + (str(len(chunks)),) @@ -2642,13 +2629,6 @@ class OctetString(Obj): sub_offset += chunk.tlvlen vlen += chunk.tlvlen v = v_tail - if len(chunks) == 0: - raise DecodeError( - "no chunks", - klass=self.__class__, - decode_path=decode_path, - offset=offset, - ) try: obj = self.__class__( value=b"".join(bytes(chunk) for chunk in chunks), @@ -4036,29 +4016,27 @@ class Any(Obj): llen, vlen, v = 1, 0, lv[1:] sub_offset = offset + tlen + llen chunk_i = 0 - while True: - if v[:EOC_LEN].tobytes() == EOC: - tlvlen = tlen + llen + vlen + EOC_LEN - obj = self.__class__( - value=tlv[:tlvlen].tobytes(), - expl=self._expl, - optional=self.optional, - _decoded=(offset, 0, tlvlen), - ) - obj.lenindef = True - obj.tag = t - return obj, v[EOC_LEN:] - else: - chunk, v = Any().decode( - v, - offset=sub_offset, - decode_path=decode_path + (str(chunk_i),), - leavemm=True, - ctx=ctx, - ) - vlen += chunk.tlvlen - sub_offset += chunk.tlvlen - chunk_i += 1 + while v[:EOC_LEN].tobytes() != EOC: + chunk, v = Any().decode( + v, + offset=sub_offset, + decode_path=decode_path + (str(chunk_i),), + leavemm=True, + ctx=ctx, + ) + vlen += chunk.tlvlen + sub_offset += chunk.tlvlen + chunk_i += 1 + tlvlen = tlen + llen + vlen + EOC_LEN + obj = self.__class__( + value=tlv[:tlvlen].tobytes(), + expl=self._expl, + optional=self.optional, + _decoded=(offset, 0, tlvlen), + ) + obj.lenindef = True + obj.tag = t + return obj, v[EOC_LEN:] except DecodeError as err: raise err.__class__( msg=err.msg, @@ -4712,6 +4690,16 @@ class Set(Sequence): _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)), ) obj._value = values + if lenindef: + if v[:EOC_LEN].tobytes() != EOC: + raise DecodeError( + "no EOC", + klass=self.__class__, + decode_path=decode_path, + offset=offset, + ) + tail = v[EOC_LEN:] + obj.lenindef = True if not obj.ready: raise DecodeError( "not all values are ready", @@ -4719,8 +4707,7 @@ class Set(Sequence): decode_path=decode_path, offset=offset, ) - obj.lenindef = lenindef - return obj, (v[EOC_LEN:] if lenindef else tail) + return obj, tail class SequenceOf(Obj): @@ -4977,10 +4964,19 @@ class SequenceOf(Obj): expl=self._expl, default=self.default, optional=self.optional, - _decoded=(offset, llen, vlen), + _decoded=(offset, llen, vlen + (EOC_LEN if lenindef else 0)), ) - obj.lenindef = lenindef - return obj, (v[EOC_LEN:] if lenindef else tail) + if lenindef: + if v[:EOC_LEN].tobytes() != EOC: + raise DecodeError( + "no EOC", + klass=self.__class__, + decode_path=decode_path, + offset=offset, + ) + obj.lenindef = True + tail = v[EOC_LEN:] + return obj, tail def __repr__(self): return "%s[%s]" % (