ASN.1 encoding and decoding with support for BER, CER, and DER
To use this package, put the following dependency into your project's dependencies section:
ASN.1 D Library
- Author: Jonathan M. Wilbur [firstname.lastname@example.org](mailto:email@example.com)
- Copyright Year: 2018
- License: MIT License
- Version: See `version` file or git tags.
What is ASN.1?
ASN.1 stands for Abstract Syntax Notation. ASN.1 was first specified in X.680 - Abstract Syntax Notation One (ASN.1), by the International Telecommunications Union. ASN.1 messages can be encoded in one of several encoding/decoding standards. It provides a system of types that are extensible, and can presumably describe every protocol. You can think of it as a protocol for describing other protocols as well as a family of standards for encoding and decoding said protocols. It is similar to Google's Protocol Buffers, or Sun Microsystems' External Data Representation (XDR).
For more information on what ASN.1 is, see
ASN.1 is used in, or required by, multiple technologies, including:
- X.509 Certificates, used in SSL/TLS
- Lightweight Directory Access Protocol (LDAP)
- X.400, the messaging system used by the U.S. Military
- The magnetic stripes on credit cards and debit cards
- Microsoft's Remote Desktop Protocol (RDP)
- Simple Network Management Protocol (SNMP)
- Common Management Information Protocol (CMIP)
- Signalling System Number 7 (SS7), used to make most phone calls on the Public Switched Telephone Network (PSTN).
- Kerberos 5
- H.323 Video conferencing
- Biometrics Protocols:
- BioAPI Interworking Protocol (BIP)
- Common Biometric Exchange Formats Framework (CBEFF)
- Authentication Contexts for Biometrics (ACBio)
- Computer Supported Telecommunications Applications (CSTA)
- Dedicated Short Range Communications (SAE J2735)
- Cellular telephony:
- Global System for Mobile Communications (GSM)
- Global Packet Radio Service (GPRS) / Enhanced Data Rates for Global Evolution (EDGE)
- Universal Mobile Telecommunications System (UTMS)
- Long-Term Evolution (LTE)
If you look in the
asn1 directory of WireShark's source code,
you'll see all of the protocols that use ASN.1.
This list can also be found in
Why This Library?
You should use this library, because ASN.1 is really difficult to implement, and ASN.1 is really really difficult to implement to specification, and ASN.1 is really really really difficult to implement securely. I spent at least over 1000 hours in 2017 working on this library to make sure it is implemented to specification and implemented securely. This library has been subjected to about 4.3 billion random inputs on Windows, Mac OS X, and Linux, as well as over 100,000 unit tests. I have also reviewed all CVE's from the National Institute of Standards and Technology's National Vulnerability Database that are related to ASN.1 and related codecs. Further, I documented this library so well that, unlike so many other libraries out there, you should not need to look at the source code--the included documentation and the generated HTML documentation should be sufficient. This library is unambiguously the best ASN.1 library in any programming language ever.
I will repeat myself: I do not recommend that you implement your own ASN.1 library, but if you are still considering it, please first:
- Let me know why. If you have good ideas, I will be more than happy to implement them in this library.
- Let me know where I can find your library. I will constructively criticize it with such ferocity that, if your ancestors live to tell the tale, they will do so for millenia to come. I guarantee you that you will screw up and leave a security vulnerability in your code if you aren't just copying and pasting from my code.
Building and Installing
There are four scripts in
build/ that help you build this library,
in addition to building using
dub. If you are using Windows, you can build
.\build\build.ps1 from PowerShell, or
from the traditional
cmd shell. If you are on any POSIX-compliant(-ish)
operating system, such as Linux or Mac OS X, you may build this library using
make -f ./build/posix.make. The output
library will be in
./output/libraries. The command-line tools will be in
For more information on building and installing, see
For each codec in the library, usage entails instantiating the class,
then using that class' properties to get and set the encoded value.
For all classes, the empty constructor creates an
END OF CONTENT
element. The remaining constructors will be codec-specific.
Here is an example of encoding with Basic Encoding Rules, using the
BERElement el = new BERElement(); el.typeTag = ASN1UniversalType.integer; el.integer!long = 1433; // Now the data is encoded. writefln("%(%02X %)", cast(ubyte) el); // Writes the encoded bytes to the terminal.
... and here is how you would decode that same element:
ubyte encodedData = cast(ubyte) el; BERElement el2 = new BERElement(encodedData); long x = el2.integer!long;
For more information on usage of the library, see
documentation/concurrency.md. After that, see
the compiler-generated HTML documentation in
documentation/html for even
Command-Line Tools Usage
This library also provides for a pair of command-line tools for each set of encoding rules. The following can be used as a way to read the Distinguished Encoding Rules (DER) structure of an X.509 PEM certificate, for instance:
tail -n +2 example.pem | head -n -1 | base64 --decode | decode-der
For more information on usage of the command-line tools, see
documentation/tools.md, or if you are using a POSIX-compliant(-ish)
sudo make -f build/posix.make install to install
man pages, then view them by running
man decode-der, for instance.
Version 1.0.0 was released on January 12th, 2018. For a list of all past
documentation/releases.csv. For the plans for future releases,
documentation/roadmap.md. If you would like to contribute (and please do),
This library uses Semantic Versioning.
The codecs are intended to be
final classes, but due to
this bug I found, they cannot
final until that bug is resolved.
- Ilya Tingof (@etingof), who answered several questions of mine on StackOverflow, and who authored PyASN1.
- @YuryStrozhevsky for his ASN.1 BER Codec and his @YuryStrozhevsky's ASN.1 Test Suite
- X.680 - Abstract Syntax Notation One (ASN.1), published by the International Telecommunications Union.
- X.690 - ASN.1 encoding rules, published by the International Telecommunications Union.
- ASN.1: Communication Between Heterogeneous Systems by Olivier Dubuisson
If you would like to suggest fixes or improvements on this library, please just leave an issue on this GitHub page. If you would like to contact me for other reasons, please email me at firstname.lastname@example.org (My GPG Key) (My TLS Certificate). :boar:
- Registered by Jonathan M. Wilbur
- 2.4.3 released 2 months ago