``tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm``::
(
- (('parameters',), {
+ (("parameters",), {
id_ecPublicKey: ECParameters(),
id_GostR3410_2001: GostR34102001PublicKeyParameters(),
}),
- (('..', 'subjectPublicKey'), {
+ (("..", "subjectPublicKey"), {
id_rsaEncryption: RSAPublicKey(),
id_GostR3410_2001: OctetString(),
}),
def _encode(self): # pragma: no cover
raise NotImplementedError()
- def _decode(self, tlv, offset, decode_path, ctx): # pragma: no cover
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only): # pragma: no cover
raise NotImplementedError()
def encode(self):
return raw
return b"".join((self._expl, len_encode(len(raw)), raw))
- def decode(self, data, offset=0, leavemm=False, decode_path=(), ctx=None):
+ def decode(
+ self,
+ data,
+ offset=0,
+ leavemm=False,
+ decode_path=(),
+ ctx=None,
+ tag_only=False,
+ ):
"""Decode the data
:param data: either binary or memoryview
:param bool leavemm: do we need to leave memoryview of remaining
data as is, or convert it to bytes otherwise
:param ctx: optional :ref:`context <ctx>` governing decoding process.
+ :param tag_only: decode only the tag, without length and contents
+ (used only in Choice and Set structures, trying to
+ determine if tag satisfies the scheme)
:returns: (Obj, remaining data)
"""
if ctx is None:
ctx = {}
tlv = memoryview(data)
if self._expl is None:
- obj, tail = self._decode(
+ result = self._decode(
tlv,
offset,
decode_path=decode_path,
ctx=ctx,
+ tag_only=tag_only,
)
+ if tag_only:
+ return
+ obj, tail = result
else:
try:
t, tlen, lv = tag_strip(tlv)
decode_path=decode_path,
offset=offset,
)
- obj, tail = self._decode(
+ result = self._decode(
v,
offset=offset + tlen + llen,
decode_path=decode_path,
ctx=ctx,
+ tag_only=tag_only,
)
+ if tag_only:
+ return
+ obj, tail = result
return obj, (tail if leavemm else tail.tobytes())
@property
class DecodePathDefBy(object):
"""DEFINED BY representation inside decode path
"""
- __slots__ = ('defined_by',)
+ __slots__ = ("defined_by",)
def __init__(self, defined_by):
self.defined_by = defined_by
+ def __ne__(self, their):
+ return not(self == their)
+
def __eq__(self, their):
if not isinstance(their, self.__class__):
return False
(b"\xFF" if self._value else b"\x00"),
))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, _, v = len_decode(lv)
except DecodeError as err:
break
return b"".join((self.tag, len_encode(len(octets)), octets))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
class KeyUsage(BitString):
schema = (
- ('digitalSignature', 0),
- ('nonRepudiation', 1),
- ('keyEncipherment', 2),
+ ("digitalSignature", 0),
+ ("nonRepudiation", 1),
+ ("keyEncipherment", 2),
)
- >>> b = KeyUsage(('keyEncipherment', 'nonRepudiation'))
+ >>> b = KeyUsage(("keyEncipherment", "nonRepudiation"))
KeyUsage BIT STRING 3 bits nonRepudiation, keyEncipherment
>>> b.named
['nonRepudiation', 'keyEncipherment']
octets,
))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
self._value,
))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
def _encode(self):
return self.tag + len_encode(0)
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, _, v = len_decode(lv)
except DecodeError as err:
v = b"".join(octets)
return b"".join((self.tag, len_encode(len(v)), v))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, _, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
class GeneralName(Choice):
schema = (
- ('rfc822Name', IA5String(impl=tag_ctxp(1))),
- ('dNSName', IA5String(impl=tag_ctxp(2))),
+ ("rfc822Name", IA5String(impl=tag_ctxp(1))),
+ ("dNSName", IA5String(impl=tag_ctxp(2))),
)
>>> gn = GeneralName()
self._assert_ready()
return self._value[1].encode()
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
for choice, spec in self.specs.items():
+ sub_decode_path = decode_path + (choice,)
try:
- value, tail = spec.decode(
+ spec.decode(
tlv,
offset=offset,
leavemm=True,
- decode_path=decode_path + (choice,),
+ decode_path=sub_decode_path,
ctx=ctx,
+ tag_only=True,
)
except TagMismatch:
continue
- obj = self.__class__(
- schema=self.specs,
- expl=self._expl,
- default=self.default,
- optional=self.optional,
- _decoded=(offset, 0, value.tlvlen),
+ break
+ else:
+ raise TagMismatch(
+ klass=self.__class__,
+ decode_path=decode_path,
+ offset=offset,
)
- obj._value = (choice, value)
- return obj, tail
- raise TagMismatch(
- klass=self.__class__,
- decode_path=decode_path,
+ if tag_only:
+ return
+ value, tail = spec.decode(
+ tlv,
offset=offset,
+ leavemm=True,
+ decode_path=sub_decode_path,
+ ctx=ctx,
+ )
+ obj = self.__class__(
+ schema=self.specs,
+ expl=self._expl,
+ default=self.default,
+ optional=self.optional,
+ _decoded=(offset, 0, value.tlvlen),
)
+ obj._value = (choice, value)
+ return obj, tail
def __repr__(self):
value = pp_console_row(next(self.pps()))
self._assert_ready()
return self._value
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, tlen, lv = tag_strip(tlv)
l, llen, v = len_decode(lv)
pyderasn.InvalidValueType: invalid value type, expected: <class 'pyderasn.ObjectIdentifier'>
>>> ext["extnID"] = ObjectIdentifier("1.2.3")
- You can know if sequence is ready to be encoded:
+ You can determine if sequence is ready to be encoded:
>>> ext.ready
False
Assign ``None`` to remove value from sequence.
- You can know if value exists/set in the sequence and take its value:
+ You can set values in Sequence during its initialization:
+
+ >>> AlgorithmIdentifier((
+ ("algorithm", ObjectIdentifier("1.2.3")),
+ ("parameters", Any(Null()))
+ ))
+ AlgorithmIdentifier SEQUENCE[OBJECT IDENTIFIER 1.2.3, ANY 0500 OPTIONAL]
+
+ You can determine if value exists/set in the sequence and take its value:
>>> "extnID" in ext, "extnValue" in ext, "critical" in ext
(True, True, False)
)
self._value = {}
if value is not None:
- self._value = self._value_sanitize(value)
+ if issubclass(value.__class__, Sequence):
+ self._value = value._value
+ elif hasattr(value, "__iter__"):
+ for seq_key, seq_value in value:
+ self[seq_key] = seq_value
+ else:
+ raise InvalidValueType((Sequence,))
if default is not None:
- default_value = self._value_sanitize(default)
+ if not issubclass(default.__class__, Sequence):
+ raise InvalidValueType((Sequence,))
+ default_value = default._value
default_obj = self.__class__(impl=self.tag, expl=self._expl)
default_obj.specs = self.specs
default_obj._value = default_value
if value is None:
self._value = default_obj.copy()._value
- def _value_sanitize(self, value):
- if not issubclass(value.__class__, Sequence):
- raise InvalidValueType((Sequence,))
- return value._value
-
@property
def ready(self):
for name, spec in self.specs.items():
v = b"".join(self._encoded_values())
return b"".join((self.tag, len_encode(len(v)), v))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, tlen, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
v = b"".join(raws)
return b"".join((self.tag, len_encode(len(v)), v))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, tlen, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err:
specs_items = self.specs.items
while len(v) > 0:
for name, spec in specs_items():
+ sub_decode_path = decode_path + (name,)
try:
- value, v_tail = spec.decode(
+ spec.decode(
v,
sub_offset,
leavemm=True,
- decode_path=decode_path + (name,),
+ decode_path=sub_decode_path,
ctx=ctx,
+ tag_only=True,
)
except TagMismatch:
continue
- sub_offset += (
- value.expl_tlvlen if value.expled else value.tlvlen
- )
- v = v_tail
- if spec.default is None or value != spec.default: # pragma: no cover
- # SeqMixing.test_encoded_default_accepted covers that place
- values[name] = value
break
else:
raise TagMismatch(
decode_path=decode_path,
offset=offset,
)
+ value, v_tail = spec.decode(
+ v,
+ sub_offset,
+ leavemm=True,
+ decode_path=sub_decode_path,
+ ctx=ctx,
+ )
+ sub_offset += (
+ value.expl_tlvlen if value.expled else value.tlvlen
+ )
+ v = v_tail
+ if spec.default is None or value != spec.default: # pragma: no cover
+ # SeqMixing.test_encoded_default_accepted covers that place
+ values[name] = value
obj = self.__class__(
schema=self.specs,
impl=self.tag,
v = b"".join(self._encoded_values())
return b"".join((self.tag, len_encode(len(v)), v))
- def _decode(self, tlv, offset, decode_path, ctx):
+ def _decode(self, tlv, offset, decode_path, ctx, tag_only):
try:
t, tlen, lv = tag_strip(tlv)
except DecodeError as err:
decode_path=decode_path,
offset=offset,
)
+ if tag_only:
+ return
try:
l, llen, v = len_decode(lv)
except DecodeError as err: