█████ ███████ ███ ██ ██
██ ██ ██ ████ ██ ███
███████ ███████ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██
██ ██ ███████ ██ ████ ██ ██
BER encoder/decoder
Encoding and decoding of ASN.1 (Abstract Syntax Notation One) (X.208) abstract objects using BER (Basic Encoding Rules) (X.209).
A BER encoding consists of 3 components:
- Identifier octets
- Length octets
- Contents octets
The identifier octets encode the ASN.1 tag (class and number) of the type of the data value.
Single octet
- Bits 8 + 7: class of the tag
- Bit 6:
0
if primitive,1
if constructed - Bit 5 - 1: tag number, encoded as a binary integer
2+ octets
- Bit 8 + 7: class of the tag
- Bit 6:
0
if primitive,1
if constructed - Bits 5 - 1:
11111
- 2nd octet: tag number base-128 encoded
Can be in definite and indefinite form. We don't use indefinite.
- 1 or more octets
- Represents the number of octets in the contetns octets
- Can be in short or long form
Contents octets <= 127
- Single octet
- Bit 8:
0
- Bits 7 - 1: Number of content octets (may be zero), as an unsigned bianry integer
Example:
Number of content octets = 38
Short from length encoding: b00100110
Contents octets > 127
- Initial octet + one or more subsequent octets
- Initial octet
- Bit 8:
1
- Bit 7 - 1: Number of subsequent octets in length octets, as an unsigned binary integer
- Value
b11111111
cannot be used
- Bit 8:
- Subsequent octets
- Encoding of unsigned binary integer equal to the number of content octets
Example:
Number of content octets = 201
Long from length encoding: 0b10000001 0b11001001
Class | Bit 8 | Bit 7 | Definition |
---|---|---|---|
Universal | 0 |
0 |
Meaning is the same in all applications |
Application | 0 |
1 |
Meaning is specific to an application (i.e. LDAP) |
Context-specific | 1 |
0 |
Meaning is specific to a particular usage within a given application. |
Private | 1 |
1 |
Meaning is specific to a given enterprise |
For each octet:
- Bit 8:
1
, except last octet - Bit 7 - 1: encoding of the unsigned binary integer
Bits 7 - 1 of the first subsequent octet cannot be all zero.
BIT STRING
: an arbitrary string of bits.IA5String
: an arbitrary string of IA5 (ASCII) characters.INTEGER
: an arbitrary integer.NULL
: a null value.OBJECT IDENTIFIER
: an object identifierOCTET STRING
: an arbitrary string of octets.PrintableString
: an arbitrary string of printable characters.T61String
: an arbitrary string of T.61 characters.UTCTime
: a UTC timestamp
SEQUENCE
: ordered collection of items of one or more typesSEQUENCE OF
: ordered collection of zero or more items of the same typeSET
: unordered collection of items of one or more typesSET OF
unordered collection of zero or more items of the same type
Implicitly tagged types are derived from other types by changing the tag of the underlying type.
Explicitly tagged types are derived from other types by adding an outer tag to the underlying type. Effectively a structured type consisting of one component: the underlying type.
These can be translated as:
IMPLICIT
: instead of
EXPLICIT
: in addition to
EXPLICIT is the default.
Primitive or constructed.
Constructed not supported.
BIT STRING
is an arbitrary string of bits. Can have any length, including zero.
The first contents octets give the number of unused bits. The second and following contents octets give the value of the bit string, converted to an octet string.
The bit string is padded after the last bit with zero to seven bits to make the length of the bit string a multiple of eight (so no padding if the length already is a multiple of eight).
Example: 011011100101110111
-> 01101110 01011101 11000000
(6e 5d c0
) (6 unused bits)
Then in Go:
bitString, _ := NewBitString([]byte{0x6e, 0x5d, 0xc0}, 6)
Primitive or constructed.
Constructed not supported.
IA5String
is an arbitrary string of IA5 characters (ASCII).
Primitive
INTEGER
is an arbitrary integer. Contents octets are the value of the integer, base-256, two's complement form, big-endian, with minimum number of octets.
Encoding is exactly the same as an INTEGER
.
Primitive
NULL
denotes a null value. Contents octets are empty.
Primitive
OBJECT IDENTIFIER
denotes an object identifier.
The first octet has the value 40 * oid[0] + oid[1]
. oid[0]
is limited to 0, 1 and 2. oid[1]
is limited to 0 to 39 when oid[0]
is 0 or 1.
The following octets are each value encoded, base-128, big-endian, with minimum number of octets. The most significant bit of each octet, except the last, must be 1.
Primitive or constructed.
Constructed not supported.
OCTET STRING
denotes an arbitrary string of octets.
The encoding is the value of the octet string.
Primitive or constructed.
Constructed not supported.
PrintableString
is an arbitrary string of printable characters from the following set:
A, B, ..., Z
a, b, ..., z
0, 1, ..., 9
(space) ' ( ) + , - . / : = ?
Constructed
SEQUENCE
denotes an ordered collection of one or more types.
Contents octets are the concatenation of the BER encodings of the values of the components of the sequence, in order of definition.
If a compnent has an OPTIONAL
or DEFAULT
qualifier, and is absent from the sequence during encoding, that component is not included in the contents octets. If the compnent with a DEFAULT
qualifier is the default value during the encoding, it may or may not be included in the contents octets.
Constructed
SEQUENCE OF
denotes an ordered collection of zero or more occurrences of a given type.
Contents octets are the concatenation of the BER encodings of the values of the components of the sequence, in order of definition.
Constructed
SET
denotes an unordered collection of one or more types.
Contents octets are the concatenation of the BER encodings of the values of the components of the set, in any order.
If a compnent has an OPTIONAL
or DEFAULT
qualifier, and is absent from the sequence during encoding, that component is not included in the contents octets. If the compnent with a DEFAULT
qualifier is the default value during the encoding, it may or may not be included in the contents octets.
Constructed
SET OF
denotes an unordered collection of zero or more occurrences of a given type.
Contents octets are the concatenation of the BER encodings of the values of the components of the set, in any order.
Primitive or constructed.
Constructed not supported.
T61String
is an arbitrary string of T.61 characters.
Primitive or constructed.
Constructed not supported.
UTCTime
denotes a UTC timestamp. Can be in the following formats:
YYMMDDhhmmZ
YYMMDDhhmm+hh'mm'
YYMMDDhhmm-hh'mm'
YYMMDDhhmmssZ
YYMMDDhhmmss+hh'mm'
YYMMDDhhmmss-hh'mm'
It is encoded as an ASCII string.
Example:
May 6, 1991 4:45:40 PM PDT
Can be formatted as:
910506164540-0700
910506234540Z
A Layman's Guide to a Subset of ASN.1, BER, and DER
Basic Encoding Rules - Sun OpenDS Standard Edition 2.2 Glossary of LDAP and Directory Terminology
LDAPv3 Wire Protocol Reference: The ASN.1 Basic Encoding Rules
A Warm Welcome to ASN.1 and DER
ASN.1 by simple words - Yury Strozhevsky
ASN.1 Communication Between Heterogeneous Systems - Olivier Dubuisson