On this page:
write-asn1
read-asn1
asn1->bytes
bytes->asn1
write-asn1/  DER
read-asn1/  DER
asn1->bytes/  DER
bytes->asn1/  DER
3.1 BER Utilities
BER-frame
BER-encode
BER-decode
write-BER-frame
read-BER-frame
3.2 ASN.1 Exceptions
exn:  fail:  asn1
exn:  fail:  asn1:  encoding
exn:  fail:  asn1:  type

3 ASN.1 Encoding and Decoding🔗ℹ

This library supports the Basic Encoding Rules (BER) for ASN.1 as well as its restricted form, the Distinguished Encoding Rules (DER).

A BER encoding is logically a tag, length, value (TLV) triple. The tag indicates to what type the value belongs (or at least disambiguates; the tag is often context-specific). The tag also indicates whether the encoding is primitive or constructedthat is, consisting of a sequence of TLV triples. The length indicates the length of the value encoding, so even unknown types can be decomposed into TLV triples. The value component contains a type-specific encoding of the value. For example, integers are encoded in big-endian, base-256, two’s-complement form using a minimal number of octets.

procedure

(write-asn1 type value [out #:rules rules])  void?

  type : asn1-type?
  value : any/c
  out : output-port? = (current-output-port)
  rules : (or/c 'BER 'DER) = 'BER
Writes to out the encoding of value as an instance of the given ASN.1 type, using the specified encoding rules.

procedure

(read-asn1 type [in #:rules rules])  any/c

  type : asn1-type?
  in : input-port? = (current-input-port)
  rules : (or/c 'BER 'DER) = 'BER
Reads a value of the given ASN.1 type from in, using the specified encoding rules.

Changed in version 1.2 of package asn1-lib: Strings and bytes in the result are immutable.

procedure

(asn1->bytes type value [#:rules rules])  bytes?

  type : asn1-type?
  value : any/c
  rules : (or/c 'BER 'DER) = 'BER
Encodes value as an instance of the given ASN.1 type, using the specified encoding rules.

procedure

(bytes->asn1 type bstr [#:rules rules])  any/c

  type : asn1-type?
  bstr : bytes?
  rules : (or/c 'BER 'DER) = 'BER
Decodes bstr as an instance of the given ASN.1 type, using the specified encoding rules.

Changed in version 1.2 of package asn1-lib: Strings and bytes in the result are immutable.

procedure

(write-asn1/DER type value [out])  void?

  type : asn1-type?
  value : any/c
  out : output-port? = (current-output-port)

procedure

(read-asn1/DER type [in])  any/c

  type : asn1-type?
  in : input-port? = (current-input-port)

procedure

(asn1->bytes/DER type value)  bytes?

  type : asn1-type?
  value : any/c

procedure

(bytes->asn1/DER type bstr)  any/c

  type : asn1-type?
  bstr : bytes?
Like write-asn1, read-asn1, asn1->bytes, and bytes->asn1, respectively, but use the DER encoding rules.

Equivalent to calling the corresponding procedure with #:rules 'DER.

> (define Integers (SEQUENCE-OF INTEGER))
> (asn1->bytes Integers '(1 2 3 -1000))

#"0\200\2\1\1\2\1\2\2\1\3\2\2\374\30\0\0"

> (asn1->bytes Integers '(1 2 3 -1000) #:rules 'DER)

#"0\r\2\1\1\2\1\2\2\1\3\2\2\374\30"

> (asn1->bytes/DER Integers '(1 2 3 -1000))

#"0\r\2\1\1\2\1\2\2\1\3\2\2\374\30"

Changed in version 1.2 of package asn1-lib: Strings and bytes in the result are immutable.

3.1 BER Utilities🔗ℹ

 (require asn1/ber) package: asn1-lib

struct

(struct BER-frame (tag-class tag-number value))

  tag-class : (or/c 'universal 'private 'application 'context-sensitive)
  tag-number : exact-nonnegative-integer?
  value : (or/c bytes? (listof (or/c bytes? BER-frame?)))
Represents a decomposed TLV triple. The tag is broken down into the tagclass and tagn fields. The length is not represented; it is implicit in the value field. The value is a list for “constructed” types and a bytestring for “primitive” types.

procedure

(BER-encode type v [#:der? der?])  BER-frame?

  type : asn1-type?
  v : any/c
  der? : boolean? = #f

procedure

(BER-decode type b [#:der? der?])  any/c

  type : asn1-type?
  b : BER-frame?
  der? : boolean? = #f
Encode or decode a value of the given ASN.1 type to a BER TLV frame.

> (BER-encode INTEGER 5)

(BER-frame 'universal 2 #"\5")

> (BER-decode INTEGER (BER-frame 'universal 2 #"\5"))

5

> (BER-encode (SEQUENCE-OF INTEGER) '(1 2 3 -1000))

(BER-frame

 'universal 16

 (list

  (BER-frame 'universal 2 #"\1")

  (BER-frame 'universal 2 #"\2")

  (BER-frame 'universal 2 #"\3")

  (BER-frame 'universal 2 #"\374\30")))

> (BER-encode (SEQUENCE [a IA5String] [b INTEGER])
              (hasheq 'a "Jean" 'b 24601))

(BER-frame

 'universal 16

 (list (BER-frame 'universal 22 #"Jean") (BER-frame 'universal 2 #"`\31")))

procedure

(write-BER-frame frame [out #:rules rules])  void?

  frame : BER-frame?
  out : output-port? = (current-output-port)
  rules : (or/c 'BER 'DER) = 'BER

procedure

(read-BER-frame [in #:rules rules])  BER-frame?

  in : input-port? = (current-input-port)
  rules : (or/c 'BER 'DER) = 'BER
Write or read a BER TLV frame, respectively.

3.2 ASN.1 Exceptions🔗ℹ

Super struct type for exceptions related to ASN.1 encoding and decoding.

Added in version 1.2 of package asn1-lib.

Raised for errors in decoding, specifically when the encoded input violates the encoding rules (eg, BER or DER). Examples of BER violations include invalid frame structure, such as truncated input. Examples of DER violations include unsorted SET elements and use of the indefinite length encoding.

Added in version 1.2 of package asn1-lib.

Raised for errors in either encoding or decoding involving a specific ASN.1 type and either the input being decoded or the Racket value being encoded. Examples include missing required fields, unexpected fields in non-extensible SET or SEQUENCE types, unexpected CHOICE variants, invalid characters in a IA5String, and so on.

Added in version 1.2 of package asn1-lib.