- Defined in:
Abstract Syntax Notation One (or ASN.1) is a notation syntax to describe data structures and is defined in ITU-T X.680. ASN.1 itself does not mandate any encoding or parsing rules, but usually ASN.1 data structures are encoded using the Distinguished Encoding Rules (DER) or less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER and BER encodings are binary Tag-Length-Value (TLV) encodings that are quite concise compared to other popular data description formats such as XML, JSON etc. ASN.1 data structures are very common in cryptographic applications, e.g. X.509 public key certificates or certificate revocation lists (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are the building blocks of applied cryptography. The ASN1 module provides the necessary classes that allow generation of ASN.1 data structures and the methods to encode them using a DER encoding. The decode method allows parsing arbitrary BER-/DER-encoded data to a Ruby object that can then be modified and re-encoded at will.
ASN.1 class hierarchy
The base class representing ASN.1 structures is ASN1Data. ASN1Data offers attributes to read and set the
tag_class and finally the
value of a particular ASN.1 item. Upon parsing, any tagged values (implicit or explicit) will be represented by ASN1Data instances because their “real type” can only be determined using out-of-band information from the ASN.1 type declaration. Since this information is normally known when encoding a type, all sub-classes of ASN1Data offer an additional attribute
tagging that allows to encode a value implicitly (
:IMPLICIT) or explicitly (
Constructive is, as its name implies, the base class for all constructed encodings, i.e. those that consist of several values, opposed to “primitive” encodings with just one single value. Primitive values that are encoded with “infinite length” are typically constructed (their values come in multiple chunks) and are therefore represented by instances of Constructive. The value of an Constructive is always an Array.
ASN1::Set and ASN1::Sequence
The most common constructive encodings are SETs and SEQUENCEs, which is why there are two sub-classes of Constructive representing each of them.
This is the super class of all primitive values. Primitive itself is not used when parsing ASN.1 data, all values are either instances of a corresponding sub-class of Primitive or they are instances of ASN1Data if the value was tagged implicitly or explicitly. Please cf. Primitive documentation for details on sub-classes and their respective mappings of ASN.1 data types to Ruby objects.
Possible values for
When constructing an ASN1Data object the ASN.1 type definition may require certain elements to be either implicitly or explicitly tagged. This can be achieved by setting the
tagging attribute manually for sub-classes of ASN1Data. Use the symbol
:IMPLICIT for implicit tagging and
:EXPLICIT if the element requires explicit tagging.
Possible values for
It is possible to create arbitrary ASN1Data objects that also support a PRIVATE or APPLICATION tag class. Possible values for the
tag_class attribute are:
:UNIVERSAL(the default for untagged values)
:CONTEXT_SPECIFIC(the default for tagged values)
There is a constant defined for each universal tag:
An Array that stores the name of a given tag number. These names are the same as the name of the tag constant that is additionally defined, e.g. UNIVERSAL_TAG_NAME = “INTEGER” and OpenSSL::ASN1::INTEGER = 2.
Decoding and viewing a DER-encoded file
require 'openssl' require 'pp' der = File.binread('data.der') asn1 = ::ASN1.decode(der) pp der
Creating an ASN.1 structure and DER-encoding it
require 'openssl' version = ::ASN1::Integer.new(1) # Explicitly 0-tagged implies context-specific tag class serial = ::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC) name = ::ASN1::PrintableString.new('Data 1') sequence = ::ASN1::Sequence.new( [ version, serial, name ] ) der = sequence.to_der
Defined Under Namespace
Classes:, , , ,