1# asn1crypto 2 3A fast, pure Python library for parsing and serializing ASN.1 structures. 4 5 - [Features](#features) 6 - [Why Another Python ASN.1 Library?](#why-another-python-asn1-library) 7 - [Related Crypto Libraries](#related-crypto-libraries) 8 - [Current Release](#current-release) 9 - [Dependencies](#dependencies) 10 - [Installation](#installation) 11 - [License](#license) 12 - [Security Policy](#security-policy) 13 - [Documentation](#documentation) 14 - [Continuous Integration](#continuous-integration) 15 - [Testing](#testing) 16 - [Development](#development) 17 - [CI Tasks](#ci-tasks) 18 19[](https://github.com/wbond/asn1crypto/actions?workflow=CI) 20[](https://circleci.com/gh/wbond/asn1crypto) 21[](https://pypi.org/project/asn1crypto/) 22 23## Features 24 25In addition to an ASN.1 BER/DER decoder and DER serializer, the project includes 26a bunch of ASN.1 structures for use with various common cryptography standards: 27 28| Standard | Module | Source | 29| ---------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | 30| X.509 | [`asn1crypto.x509`](asn1crypto/x509.py) | [RFC 5280](https://tools.ietf.org/html/rfc5280) | 31| CRL | [`asn1crypto.crl`](asn1crypto/crl.py) | [RFC 5280](https://tools.ietf.org/html/rfc5280) | 32| CSR | [`asn1crypto.csr`](asn1crypto/csr.py) | [RFC 2986](https://tools.ietf.org/html/rfc2986), [RFC 2985](https://tools.ietf.org/html/rfc2985) | 33| OCSP | [`asn1crypto.ocsp`](asn1crypto/ocsp.py) | [RFC 6960](https://tools.ietf.org/html/rfc6960) | 34| PKCS#12 | [`asn1crypto.pkcs12`](asn1crypto/pkcs12.py) | [RFC 7292](https://tools.ietf.org/html/rfc7292) | 35| PKCS#8 | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 5208](https://tools.ietf.org/html/rfc5208) | 36| PKCS#1 v2.1 (RSA keys) | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 3447](https://tools.ietf.org/html/rfc3447) | 37| DSA keys | [`asn1crypto.keys`](asn1crypto/keys.py) | [RFC 3279](https://tools.ietf.org/html/rfc3279) | 38| Elliptic curve keys | [`asn1crypto.keys`](asn1crypto/keys.py) | [SECG SEC1 V2](http://www.secg.org/sec1-v2.pdf) | 39| PKCS#3 v1.4 | [`asn1crypto.algos`](asn1crypto/algos.py) | [PKCS#3 v1.4](ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc) | 40| PKCS#5 v2.1 | [`asn1crypto.algos`](asn1crypto/algos.py) | [PKCS#5 v2.1](http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf) | 41| CMS (and PKCS#7) | [`asn1crypto.cms`](asn1crypto/cms.py) | [RFC 5652](https://tools.ietf.org/html/rfc5652), [RFC 2315](https://tools.ietf.org/html/rfc2315) | 42| TSP | [`asn1crypto.tsp`](asn1crypto/tsp.py) | [RFC 3161](https://tools.ietf.org/html/rfc3161) | 43| PDF signatures | [`asn1crypto.pdf`](asn1crypto/pdf.py) | [PDF 1.7](http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf) | 44 45## Why Another Python ASN.1 Library? 46 47Python has long had the [pyasn1](https://pypi.org/project/pyasn1/) and 48[pyasn1_modules](https://pypi.org/project/pyasn1-modules/) available for 49parsing and serializing ASN.1 structures. While the project does include a 50comprehensive set of tools for parsing and serializing, the performance of the 51library can be very poor, especially when dealing with bit fields and parsing 52large structures such as CRLs. 53 54After spending extensive time using *pyasn1*, the following issues were 55identified: 56 57 1. Poor performance 58 2. Verbose, non-pythonic API 59 3. Out-dated and incomplete definitions in *pyasn1-modules* 60 4. No simple way to map data to native Python data structures 61 5. No mechanism for overridden universal ASN.1 types 62 63The *pyasn1* API is largely method driven, and uses extensive configuration 64objects and lowerCamelCase names. There were no consistent options for 65converting types of native Python data structures. Since the project supports 66out-dated versions of Python, many newer language features are unavailable 67for use. 68 69Time was spent trying to profile issues with the performance, however the 70architecture made it hard to pin down the primary source of the poor 71performance. Attempts were made to improve performance by utilizing unreleased 72patches and delaying parsing using the `Any` type. Even with such changes, the 73performance was still unacceptably slow. 74 75Finally, a number of structures in the cryptographic space use universal data 76types such as `BitString` and `OctetString`, but interpret the data as other 77types. For instance, signatures are really byte strings, but are encoded as 78`BitString`. Elliptic curve keys use both `BitString` and `OctetString` to 79represent integers. Parsing these structures as the base universal types and 80then re-interpreting them wastes computation. 81 82*asn1crypto* uses the following techniques to improve performance, especially 83when extracting one or two fields from large, complex structures: 84 85 - Delayed parsing of byte string values 86 - Persistence of original ASN.1 encoded data until a value is changed 87 - Lazy loading of child fields 88 - Utilization of high-level Python stdlib modules 89 90While there is no extensive performance test suite, the 91`CRLTests.test_parse_crl` test case was used to parse a 21MB CRL file on a 92late 2013 rMBP. *asn1crypto* parsed the certificate serial numbers in just 93under 8 seconds. With *pyasn1*, using definitions from *pyasn1-modules*, the 94same parsing took over 4,100 seconds. 95 96For smaller structures the performance difference can range from a few times 97faster to an order of magnitude or more. 98 99## Related Crypto Libraries 100 101*asn1crypto* is part of the modularcrypto family of Python packages: 102 103 - [asn1crypto](https://github.com/wbond/asn1crypto) 104 - [oscrypto](https://github.com/wbond/oscrypto) 105 - [csrbuilder](https://github.com/wbond/csrbuilder) 106 - [certbuilder](https://github.com/wbond/certbuilder) 107 - [crlbuilder](https://github.com/wbond/crlbuilder) 108 - [ocspbuilder](https://github.com/wbond/ocspbuilder) 109 - [certvalidator](https://github.com/wbond/certvalidator) 110 111## Current Release 112 1131.5.0 - [changelog](changelog.md) 114 115## Dependencies 116 117Python 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10 or pypy. *No third-party 118packages required.* 119 120## Installation 121 122```bash 123pip install asn1crypto 124``` 125 126## License 127 128*asn1crypto* is licensed under the terms of the MIT license. See the 129[LICENSE](LICENSE) file for the exact license text. 130 131## Security Policy 132 133The security policies for this project are covered in 134[SECURITY.md](https://github.com/wbond/asn1crypto/blob/master/SECURITY.md). 135 136## Documentation 137 138The documentation for *asn1crypto* is composed of tutorials on basic usage and 139links to the source for the various pre-defined type classes. 140 141### Tutorials 142 143 - [Universal Types with BER/DER Decoder and DER Encoder](docs/universal_types.md) 144 - [PEM Encoder and Decoder](docs/pem.md) 145 146### Reference 147 148 - [Universal types](asn1crypto/core.py), `asn1crypto.core` 149 - [Digest, HMAC, signed digest and encryption algorithms](asn1crypto/algos.py), `asn1crypto.algos` 150 - [Private and public keys](asn1crypto/keys.py), `asn1crypto.keys` 151 - [X509 certificates](asn1crypto/x509.py), `asn1crypto.x509` 152 - [Certificate revocation lists (CRLs)](asn1crypto/crl.py), `asn1crypto.crl` 153 - [Online certificate status protocol (OCSP)](asn1crypto/ocsp.py), `asn1crypto.ocsp` 154 - [Certificate signing requests (CSRs)](asn1crypto/csr.py), `asn1crypto.csr` 155 - [Private key/certificate containers (PKCS#12)](asn1crypto/pkcs12.py), `asn1crypto.pkcs12` 156 - [Cryptographic message syntax (CMS, PKCS#7)](asn1crypto/cms.py), `asn1crypto.cms` 157 - [Time stamp protocol (TSP)](asn1crypto/tsp.py), `asn1crypto.tsp` 158 - [PDF signatures](asn1crypto/pdf.py), `asn1crypto.pdf` 159 160## Continuous Integration 161 162Various combinations of platforms and versions of Python are tested via: 163 164 - [macOS, Linux, Windows](https://github.com/wbond/asn1crypto/actions/workflows/ci.yml) via GitHub Actions 165 - [arm64](https://circleci.com/gh/wbond/asn1crypto) via CircleCI 166 167## Testing 168 169Tests are written using `unittest` and require no third-party packages. 170 171Depending on what type of source is available for the package, the following 172commands can be used to run the test suite. 173 174### Git Repository 175 176When working within a Git working copy, or an archive of the Git repository, 177the full test suite is run via: 178 179```bash 180python run.py tests 181``` 182 183To run only some tests, pass a regular expression as a parameter to `tests`. 184 185```bash 186python run.py tests ocsp 187``` 188 189### PyPi Source Distribution 190 191When working within an extracted source distribution (aka `.tar.gz`) from 192PyPi, the full test suite is run via: 193 194```bash 195python setup.py test 196``` 197 198### Package 199 200When the package has been installed via pip (or another method), the package 201`asn1crypto_tests` may be installed and invoked to run the full test suite: 202 203```bash 204pip install asn1crypto_tests 205python -m asn1crypto_tests 206``` 207 208## Development 209 210To install the package used for linting, execute: 211 212```bash 213pip install --user -r requires/lint 214``` 215 216The following command will run the linter: 217 218```bash 219python run.py lint 220``` 221 222Support for code coverage can be installed via: 223 224```bash 225pip install --user -r requires/coverage 226``` 227 228Coverage is measured by running: 229 230```bash 231python run.py coverage 232``` 233 234To change the version number of the package, run: 235 236```bash 237python run.py version {pep440_version} 238``` 239 240To install the necessary packages for releasing a new version on PyPI, run: 241 242```bash 243pip install --user -r requires/release 244``` 245 246Releases are created by: 247 248 - Making a git tag in [PEP 440](https://www.python.org/dev/peps/pep-0440/#examples-of-compliant-version-schemes) format 249 - Running the command: 250 251 ```bash 252 python run.py release 253 ``` 254 255Existing releases can be found at https://pypi.org/project/asn1crypto/. 256 257## CI Tasks 258 259A task named `deps` exists to download and stage all necessary testing 260dependencies. On posix platforms, `curl` is used for downloads and on Windows 261PowerShell with `Net.WebClient` is used. This configuration sidesteps issues 262related to getting pip to work properly and messing with `site-packages` for 263the version of Python being used. 264 265The `ci` task runs `lint` (if flake8 is available for the version of Python) and 266`coverage` (or `tests` if coverage is not available for the version of Python). 267If the current directory is a clean git working copy, the coverage data is 268submitted to codecov.io. 269 270```bash 271python run.py deps 272python run.py ci 273``` 274