# pylint: disable=line-too-long,superfluous-parens,protected-access,too-many-lines
# pylint: disable=too-many-return-statements,too-many-branches,too-many-statements
# PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
-# Copyright (C) 2017-2020 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2017-2021 Sergey Matveev <stargrave@stargrave.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""Python ASN.1 DER/BER codec with abstract structures
+"""Python ASN.1 DER/CER/BER codec with abstract structures
-This library allows you to marshal various structures in ASN.1 DER
+This library allows you to marshal various structures in ASN.1 DER/CER
format, unmarshal BER/CER/DER ones.
>>> i = Integer(123)
(and its derivatives), ``SET``, ``SET OF``, ``UTCTime``, ``GeneralizedTime``
could be BERed.
+Also it could be helpful to add quick ASN.1 pprinting command in your
+pdb's configuration file::
+
+ alias pp1 import pyderasn ;; print(pyderasn.pprint(%1, oid_maps=(locals().get("OID_STR_TO_NAME", {}),)))
+
.. _definedby:
DEFINED BY
class SignedAttributes(SetOf):
schema = Attribute()
- bounds = (1, 32)
+ bounds = (1, float("+inf"))
der_forced = True
.. _agg_octet_string:
from datetime import timedelta
from io import BytesIO
from math import ceil
-from mmap import mmap
-from mmap import PROT_READ
from operator import attrgetter
from string import ascii_letters
from string import digits
def colored(what, *args, **kwargs):
return what
-__version__ = "7.6"
+__version__ = "8.4"
__all__ = (
"agg_octet_string",
:param fd: file object
:returns: memoryview over read-only mmap-ing of the whole file
+
+ .. warning::
+
+ It is known to work under neither Python 2.x nor Windows.
"""
- return memoryview(mmap(fd.fileno(), 0, prot=PROT_READ))
+ import mmap
+ return memoryview(mmap.mmap(fd.fileno(), length=0, prot=mmap.PROT_READ))
def pureint(value):
raise DecodeError("unfinished tag")
if indexbytes(data, i) & 0x80 == 0:
break
+ if i == 1 and indexbytes(data, 1) < 0x1F:
+ raise DecodeError("unexpected long form")
+ if i > 1 and indexbytes(data, 1) & 0x7F == 0:
+ raise DecodeError("leading zero byte in tag value")
i += 1
return data[:i], i, data[i:]
.. warning::
- Pay attention that UTCTime can not hold full year, so all years
- having < 50 years are treated as 20xx, 19xx otherwise, according
- to X.509 recommendation.
+ Only **naive** ``datetime`` objects are supported.
+ Library assumes that all work is done in UTC.
.. warning::
- No strict validation of UTC offsets are made, but very crude:
+ Pay attention that ``UTCTime`` can not hold full year, so all years
+ having < 50 years are treated as 20xx, 19xx otherwise, according to
+ X.509 recommendation. Use ``GeneralizedTime`` instead for
+ removing ambiguity.
+
+ .. warning::
+
+ No strict validation of UTC offsets are made (only applicable to
+ **BER**), but very crude:
* minutes are not exceeding 60
* offset value is not exceeding 14 hours
if isinstance(value, self.__class__):
return value._value, None
if value.__class__ == datetime:
+ if value.tzinfo is not None:
+ raise ValueError("only naive datetime supported")
return self._dt_sanitize(value), None
raise InvalidValueType((self.__class__, datetime))
.. warning::
- Only microsecond fractions are supported in DER encoding.
- :py:exc:`pyderasn.DecodeError` will be raised during decoding of
- higher precision values.
+ Only **naive** datetime objects are supported.
+ Library assumes that all work is done in UTC.
.. warning::
- BER encoded data can loss information (accuracy) during decoding
- because of float transformations.
+ Only **microsecond** fractions are supported in DER encoding.
+ :py:exc:`pyderasn.DecodeError` will be raised during decoding of
+ higher precision values.
.. warning::
- Local times (without explicit timezone specification) are treated
- as UTC one, no transformations are made.
+ **BER** encoded data can loss information (accuracy) during
+ decoding because of float transformations.
.. warning::
- Zero year is unsupported.
+ **Zero** year is unsupported.
"""
__slots__ = ()
tag_default = tag_encode(24)
def _value_sanitize(self, value):
if value.__class__ == binary_type:
if len(value) == 0:
- raise ValueError("Any value can not be empty")
+ raise ValueError("%s value can not be empty" % self.__class__.__name__)
return value
if isinstance(value, self.__class__):
return value._value
self._state_update()
return super(TW, self).selectable()
- def get_display_text(self):
+ def _get_display_text_without_offset(self):
pp, constructed = self._get_pp()
style = "constructed" if constructed else ""
if len(pp.decode_path) == 0:
))
return (style, ent)
+ def get_display_text(self):
+ pp, _ = self._get_pp()
+ style, ent = self._get_display_text_without_offset()
+ return [(style, ent), " [%d]" % pp.offset]
+
def _scroll(self, what, step):
self.state[what]._invalidate()
pos = self.state[what].focus_position
help="Path to BER/CER/DER file you want to decode",
)
args = parser.parse_args()
- if PY2:
+ try:
+ raw = file_mmaped(args.RAWFile)[args.skip:]
+ except:
args.RAWFile.seek(args.skip)
raw = memoryview(args.RAWFile.read())
args.RAWFile.close()
- else:
- raw = file_mmaped(args.RAWFile)[args.skip:]
oid_maps = (
[obj_by_path(_path) for _path in (args.oids or "").split(",")]
if args.oids else ()