Subject ASN.1, BER, and Record Encoding
Author Jim Starkey
A question was raised awhile back about ASN.1 encoding for line
encoding, internal record encoding or both. Due to circumstances beyond
my control, I now know more about ASN.1 than I wish (and, not
incidentally, I take back everything nice I ever said about Crypto++).

ASN.1 is an abbreviation for Abstract Syntax Notation One, a language
used to describe data. BER (Basic Encoding Rules) is one of many
possible encodings for ASN.1. When most people talk about ASN.1,
they're usually talking about BER. BER is used, among many other
things, as the encoding for digital certificates.

BER defines a set of simple types like integer, octet-strings,
printable strings, NULL, etc., and structured types which are containers
holding other types. Each type consists of

<identifier-octets> <length-octets> <content-octets> [
<end-of-content-octets> ]

The identifier and length sequences are each one or more bytes long, so
the shortest possible item is two bytes -- a NULL. There are virtually
no restrictions on the lengths of item. An RSA private key, for
example, contains arbitrarily large integers. Integers are encoded as
2's complement sequence of octets.

There is a subset of BER called DER (Distinguished Encoding Rules) which
describes a canonical encoding.

Among the differences between BER and the scheme I proposed are:

1. BER supports structures, my scheme does not.
2. BER requires two passes for generation because the length of a
structure precedes the structure itself.
3. My scheme special cases zero and one, reducing each to a single
byte. The minimum length of an integer in BER is 3 bytes.
4. My scheme encodes both lengths and integers as flagged variable
length binary. BER uses flagged variable length binary for
lengths; integers have a declared length are containing in octets.
5. BER uses three bits of the identifier octet as flags, reducing the
number of primitives to 30 (0 and 31 and special). To be faithful
to BER, additional primitives would require uses of multi-byte
identifier sequences.
6. Repeating numeric values of zero and one in BER are not run length
encoding friendly.

ASN.1 and BER are intended for standardized protocols. For purposes of
data interchange, the costs are easily justified. For use within the
ODS or in a private line protocol, I think we can do better.

RSA keys generated by Crypto++ 4.2 are invalid in Crypto++ version 5.
It isn't fair to say that this is undocumented since nothing about the
product is documented. The Crypto++ list serve is a ghost town. After
a week of plowing through gory code (if you want pointers on advanced
C++ template abuse, study Crypto++), I finally figured out the Crypto++
4.2 uses the RSA standard encoding for private keys while Crypt++ 5.2.1
uses the X.509 encoding which is, in essence, a wrapper around the RSA
format encoded as an octet-string. This is vastly more than I wanted to
know about this crud.


Jim Starkey
Netfrastructure, Inc.
978 526-1376