Features

  • BER/CER/DER decoding, DER encoding
  • Basic ASN.1 data types (X.208): BOOLEAN, INTEGER, BIT STRING, OCTET STRING, NULL, OBJECT IDENTIFIER, ENUMERATED, all strings, UTCTime, GeneralizedTime, CHOICE, ANY, SEQUENCE (OF), SET (OF)
  • Size constraints checking
  • Working with sequences as high level data objects with ability to (un)marshall them
  • Python 2.7/3.5/3.6 compatibility
  • Aimed to be complaint with X.690-201508

Why yet another library? pyasn1 had all of this a long time ago. PyDERASN resembles it in many ways. In practice it should be relatively easy to convert pyasn1’s code to pyderasn’s one. Also there is asn1crypto.

  • Small, simple and trying to be reviewable code. Just a single file with six dependency

  • Ability to know exact decoded objects offsets and lengths inside the binary

  • Automatic decoding of DEFINED BY fields

  • Ability to know exact decoded field presence, emptiness: for example SEQUENCE can lack OPTIONAL SEQUENCE OF field, but also can have it with no elements inside

  • Strict DER-encoding checks. If whole input binary is parsed, then it must be completely valid DER-encoded structure

  • Ability to allow BER-encoded data with knowing if any of specified field has either DER or BER encoding (or possibly indefinite-length encoding). For example CMS structures allow BER encoding for the whole message, except for SignedAttributes – you can easily verify your CMS satisfies that requirement

  • Extensive and comprehensive hypothesis driven tests coverage. It also has been fuzzed with python-afl.

  • Some kind of strong typing: SEQUENCEs require the exact type of settable values, even when they are inherited (assigning Integer to the field with the type CMSVersion(Integer) is not allowed)

  • However they do not require exact tags matching: IMPLICIT/EXPLICIT tags will be set automatically in the given sequence (assigning of CMSVersion() object to the field CMSVersion(expl=...) will automatically set required tags)

  • Descriptive errors, like pyderasn.DecodeError: UTCTime (tbsCertificate:validity:notAfter:utcTime) (at 328) invalid UTCTime format

  • __slots__ friendliness

  • Could be significantly faster and have lower memory usage. For example parsing of CACert.org’s CRL (8.48 MiB) on FreeBSD 12.0 amd64, Intel Core i5-6200U 2.3 GHz machine, Python 3.5.5/2.7.15:

    Library Command Time, sec (Py3/Py2) Memory used, MiB (Py3/Py2)
    pyasn1 0.4.5 der_decode(data, asn1Spec=rfc5280.CertificateList()) 1257 / 1302 1327 / 2093
    asn1crypto 0.24.0 asn1crypto.crl.CertificateList.load(data).native 29.3 / 43.8 983 / 1677
    pyderasn 4.9 CertificateList().decode(data) (CertificateList is converted pyasn1 scheme definition) 27.6 / 32.5 498 / 488
  • Pretty printer and command-line decoder, that could conveniently replace utilities like either dumpasn1 or openssl asn1parse

    Pretty printing example output

    An example of pretty printed X.509 certificate with automatically parsed DEFINED BY fields.

There are drawbacks: