X-Git-Url: http://www.git.cypherpunks.ru/?p=pyderasn.git;a=blobdiff_plain;f=pyderasn.py;h=3afaf60fde261bd6a985d06acd63ec4ca0e55fbd;hp=56eec8d7953e62d6b63295b80795d1dd148d8aed;hb=88244e6e055038f5d09f9cff63dd9507c837f123;hpb=7aed684a10179b2e57e81369e956ac6df4fb135e diff --git a/pyderasn.py b/pyderasn.py index 56eec8d..3afaf60 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -261,6 +261,8 @@ defined, ``value`` contains corresponding decoded value. For example above, ``content_info["content"].defined == (id_signedData, signed_data)``. +.. _defines_by_path_kwarg: + defines_by_path kwarg _____________________ @@ -4282,9 +4284,56 @@ def obj_by_path(pypath): # pragma: no cover return obj +def generic_decoder(): # pragma: no cover + # All of this below is a big hack with self references + choice = PrimitiveTypes() + choice.specs["SequenceOf"] = SequenceOf(schema=choice) + choice.specs["SetOf"] = SetOf(schema=choice) + for i in range(31): + choice.specs["SequenceOf%d" % i] = SequenceOf( + schema=choice, + expl=tag_ctxc(i), + ) + choice.specs["Any"] = Any() + + # Class name equals to type name, to omit it from output + class SEQUENCEOF(SequenceOf): + __slots__ = () + schema = choice + + def pprint_any(obj, oids=None): + def _pprint_pps(pps): + for pp in pps: + if hasattr(pp, "_fields"): + if pp.asn1_type_name == Choice.asn1_type_name: + continue + pp_kwargs = pp._asdict() + pp_kwargs["decode_path"] = pp.decode_path[:-1] + (">",) + pp = _pp(**pp_kwargs) + yield pp_console_row( + pp, + oids=oids, + with_offsets=True, + with_blob=False, + ) + for row in pp_console_blob(pp): + yield row + else: + for row in _pprint_pps(pp): + yield row + return "\n".join(_pprint_pps(obj.pps())) + return SEQUENCEOF(), pprint_any + + def main(): # pragma: no cover import argparse parser = argparse.ArgumentParser(description="PyDERASN ASN.1 DER decoder") + parser.add_argument( + "--skip", + type=int, + default=0, + help="Skip that number of bytes from the beginning", + ) parser.add_argument( "--oids", help="Python path to dictionary with OIDs", @@ -4293,12 +4342,17 @@ def main(): # pragma: no cover "--schema", help="Python path to schema definition to use", ) + parser.add_argument( + "--defines-by-path", + help="Python path to decoder's defines_by_path", + ) parser.add_argument( "DERFile", type=argparse.FileType("rb"), help="Path to DER file you want to decode", ) args = parser.parse_args() + args.DERFile.seek(args.skip) der = memoryview(args.DERFile.read()) args.DERFile.close() oids = obj_by_path(args.oids) if args.oids else {} @@ -4307,46 +4361,14 @@ def main(): # pragma: no cover from functools import partial pprinter = partial(pprint, big_blobs=True) else: - # All of this below is a big hack with self references - choice = PrimitiveTypes() - choice.specs["SequenceOf"] = SequenceOf(schema=choice) - choice.specs["SetOf"] = SetOf(schema=choice) - for i in range(31): - choice.specs["SequenceOf%d" % i] = SequenceOf( - schema=choice, - expl=tag_ctxc(i), - ) - choice.specs["Any"] = Any() - - # Class name equals to type name, to omit it from output - class SEQUENCEOF(SequenceOf): - __slots__ = () - schema = choice - schema = SEQUENCEOF() - - def pprint_any(obj, oids=None): - def _pprint_pps(pps): - for pp in pps: - if hasattr(pp, "_fields"): - if pp.asn1_type_name == Choice.asn1_type_name: - continue - pp_kwargs = pp._asdict() - pp_kwargs["decode_path"] = pp.decode_path[:-1] + (">",) - pp = _pp(**pp_kwargs) - yield pp_console_row( - pp, - oids=oids, - with_offsets=True, - with_blob=False, - ) - for row in pp_console_blob(pp): - yield row - else: - for row in _pprint_pps(pp): - yield row - return "\n".join(_pprint_pps(obj.pps())) - pprinter = pprint_any - obj, tail = schema().decode(der) + schema, pprinter = generic_decoder() + obj, tail = schema().decode( + der, + defines_by_path=( + None if args.defines_by_path is None + else obj_by_path(args.defines_by_path) + ), + ) print(pprinter(obj, oids=oids)) if tail != b"": print("\nTrailing data: %s" % hexenc(tail))