X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pyderasn.py;h=dbe706640e02878c438bafe8799efdb07d58bba3;hb=2d7da5e1403e4713085b08d109b932490f0b5d63;hp=c9d6a116044b5515b0f75b6b5271327345106f6d;hpb=659eb0e090ad8c9209c4e5b030806125509844f9;p=pyderasn.git diff --git a/pyderasn.py b/pyderasn.py index c9d6a11..dbe7066 100755 --- a/pyderasn.py +++ b/pyderasn.py @@ -665,6 +665,11 @@ parse the CRL above with fully assembled ``RevokedCertificate``:: ): print("serial number:", int(obj["userCertificate"])) +.. note:: + + SEQUENCE/SET values with DEFAULT specified are automatically decoded + without evgen mode. + .. _mmap: mmap-ed file @@ -763,6 +768,8 @@ forcefully encoded in DER during CER encoding, by specifying bounds = (1, 32) der_forced = True +.. _agg_octet_string: + agg_octet_string ________________ @@ -1178,7 +1185,7 @@ except ImportError: # pragma: no cover def colored(what, *args, **kwargs): return what -__version__ = "7.2" +__version__ = "7.3" __all__ = ( "agg_octet_string", @@ -1188,6 +1195,7 @@ __all__ = ( "Boolean", "BoundsError", "Choice", + "colonize_hex", "DecodeError", "DecodePathDefBy", "encode2pass", @@ -1759,13 +1767,13 @@ class Obj(object): @property def tlen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return len(self.tag) @property def tlvlen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.tlen + self.llen + self.vlen @@ -1921,7 +1929,8 @@ class Obj(object): That method is identical to :py:meth:`pyderasn.Obj.decode`, but it returns the generator producing ``(decode_path, obj, tail)`` - values. See :ref:`evgen mode `. + values. + .. seealso:: :ref:`evgen mode `. """ if ctx is None: ctx = {} @@ -2070,25 +2079,25 @@ class Obj(object): @property def expled(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self._expl is not None @property def expl_tag(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self._expl @property def expl_tlen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return len(self._expl) @property def expl_llen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ if self.expl_lenindef: return 1 @@ -2096,31 +2105,31 @@ class Obj(object): @property def expl_offset(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.offset - self.expl_tlen - self.expl_llen @property def expl_vlen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.tlvlen @property def expl_tlvlen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.expl_tlen + self.expl_llen + self.expl_vlen @property def fulloffset(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.expl_offset if self.expled else self.offset @property def fulllen(self): - """See :ref:`decoding` + """.. seealso:: :ref:`decoding` """ return self.expl_tlvlen if self.expled else self.tlvlen @@ -4074,6 +4083,8 @@ def agg_octet_string(evgens, decode_path, raw, writer): :param writer: buffer.write where string is going to be saved :param writer: where string is going to be saved. Must comply with ``io.RawIOBase.write`` behaviour + + .. seealso:: :ref:`agg_octet_string` """ decode_path_len = len(decode_path) for dp, obj, _ in evgens: @@ -4291,7 +4302,9 @@ class ObjectIdentifier(Obj): tuple element is ``{OID: pyderasn.Obj()}`` dictionary, mapping between current OID value and structure applied to defined field. - :ref:`Read about DEFINED BY ` + + .. seealso:: :ref:`definedby` + :param bytes impl: override default tag with ``IMPLICIT`` one :param bytes expl: override default tag with ``EXPLICIT`` one :param default: set default value. Type same as in ``value`` @@ -6188,11 +6201,10 @@ class Sequence(SequenceEncode1stMixing, Obj): defaulted values existence validation by setting ``"allow_default_values": True`` :ref:`context ` option. - .. warning:: - - Check for default value existence is not performed in - ``evgen_mode``, because previously decoded values are not stored - in memory, to be able to compare them. + All values with DEFAULT specified are decoded atomically in + :ref:`evgen mode `. If DEFAULT value is some kind of + SEQUENCE, then it will be yielded as a single element, not + disassembled. That is required for DEFAULT existence check. Two sequences are equal if they have equal specification (schema), implicit/explicit tagging and the same values. @@ -6418,9 +6430,10 @@ class Sequence(SequenceEncode1stMixing, Obj): len(v) == 0 ): continue + spec_defaulted = spec.default is not None sub_decode_path = decode_path + (name,) try: - if evgen_mode: + if evgen_mode and not spec_defaulted: for _decode_path, value, v_tail in spec.decode_evgen( v, sub_offset, @@ -6498,9 +6511,10 @@ class Sequence(SequenceEncode1stMixing, Obj): vlen += value_len sub_offset += value_len v = v_tail - if not evgen_mode: - if spec.default is not None and value == spec.default: - # This will not work in evgen_mode + if spec_defaulted: + if evgen_mode: + yield sub_decode_path, value, v_tail + if value == spec.default: if ctx_bered or ctx_allow_default_values: ber_encoded = True else: @@ -6510,6 +6524,7 @@ class Sequence(SequenceEncode1stMixing, Obj): decode_path=sub_decode_path, offset=sub_offset, ) + if not evgen_mode: values[name] = value spec_defines = getattr(spec, "defines", ()) if len(spec_defines) == 0: @@ -6709,7 +6724,8 @@ class Set(Sequence, SequenceEncode1stMixing): decode_path=decode_path, offset=offset, ) - if evgen_mode: + spec_defaulted = spec.default is not None + if evgen_mode and not spec_defaulted: for _decode_path, value, v_tail in spec.decode_evgen( v, sub_offset, @@ -6741,17 +6757,20 @@ class Set(Sequence, SequenceEncode1stMixing): decode_path=sub_decode_path, offset=sub_offset, ) - if spec.default is None or value != spec.default: - pass - elif ctx_bered or ctx_allow_default_values: - ber_encoded = True - else: - raise DecodeError( - "DEFAULT value met", - klass=self.__class__, - decode_path=sub_decode_path, - offset=sub_offset, - ) + if spec_defaulted: + if evgen_mode: + yield sub_decode_path, value, v_tail + if value != spec.default: + pass + elif ctx_bered or ctx_allow_default_values: + ber_encoded = True + else: + raise DecodeError( + "DEFAULT value met", + klass=self.__class__, + decode_path=sub_decode_path, + offset=sub_offset, + ) values[name] = value del _specs_items[name] tag_order_prev = value_tag_order