Module Asn.S

ASN.1 Abstract Syntax.

This module is the OCaml term-level analogue of ASN.1's surface notation.

It provides a ground type 'a t representing typed abstract syntax, a suite of primitives that correspond to ASN.1 primitives, and a suite of combinators that correspond to the combining structures of ASN.1.

ASN.1 naming and modules are not supported; these are provided by the host language instead.

ASN.1 Abstract Syntax

type nonrec 'a t = 'a t

'a t denotes a particular structure of data, irrespective of any encoding, that is represented by 'a in OCaml.

Basic combinators

val fix : ('a t -> 'a t) -> 'a t

fix fasn is the fixpoint, allowing fasn to construct a syntax that refers to itself.

val map : ?random:(unit -> 'b) -> ('a -> 'b) -> ('b -> 'a) -> 'a t -> 'b t

map ?random f g asn creates a derived syntax that encodes and decodes like asn, but uses f to project and g to inject.

~random is a function that generates random samples of 'b. Defaults to f a where a is a random 'a.

Tags

type cls = [
  1. | `Universal
  2. | `Application
  3. | `Private
]

ASN.1 tag CLASS.

val implicit : ?cls:cls -> int -> 'a t -> 'a t

implicit ?cls n asn is the ASN.1 IMPLICIT construct, changing the tag of asn to (cls, n).

n is the tag value.

~cls is the class. Defaults to CONTEXT SPECIFIC.

Note implicit implicitly becomes explicit when applied to nodes that cannot be made IMPLICIT, like CHOICE. This is consistent with X.608 (see 31.2.7) in case of a bare tag, and with the common practice in case of a tag marked as IMPLICIT.

val explicit : ?cls:cls -> int -> 'a t -> 'a t

explicit ?cls n asn is the ASN.1 EXPLICIT construct, changing the tag of asn to (cls, n).

n is the tag value.

~cls is the class. Defaults to CONTEXT SPECIFIC.

Combining constructs

These look like

sequence @@
   (required ~label:"l1" asn1)
 @ (optional ~label:"l2" asn2)
 @ (required ~label:"l3" asn3)
-@ (optional ~label:"l4" asn4)

or

choice3 asn1 asn2 asn3
type 'a element

An element is a single slot in a sequence.

val required : ?label:string -> 'a t -> 'a element

required ?label asn is a regular sequence element.

~label is the name of the element.

val optional : ?label:string -> 'a t -> 'a option element

optional ?label asn is a sequence element marked with the ASN.1 OPTIONAL keyword.

~label is the name of the element.

type 'a sequence

A sequence is the body of a multi-field ASN.1 construct, like SEQUENCE and SET.

val single : 'a element -> 'a sequence

single e is the singleton sequence containing just e.

val (@) : 'a element -> 'b sequence -> ('a * 'b) sequence

e @ seq extends seq by prepending e.

val (-@) : 'a element -> 'b element -> ('a * 'b) sequence

e -@ e1 is e @ single e1

val sequence : 'a sequence -> 'a t

sequence seq is the ASN.1 SEQUENCE construct, with the body seq.

val sequence_of : 'a t -> 'a list t

sequence_of is the ASN.1 SEQUENCE OF construct.

val sequence2 : 'a element -> 'b element -> ('a * 'b) t

sequence2 e1 e2 is sequence (e1 -@ e2). Other sequenceN functions are analogous.

val sequence3 : 'a element -> 'b element -> 'c element -> ('a * 'b * 'c) t
val sequence4 : 'a element -> 'b element -> 'c element -> 'd element -> ('a * 'b * 'c * 'd) t
val sequence5 : 'a element -> 'b element -> 'c element -> 'd element -> 'e element -> ('a * 'b * 'c * 'd * 'e) t
val sequence6 : 'a element -> 'b element -> 'c element -> 'd element -> 'e element -> 'f element -> ('a * 'b * 'c * 'd * 'e * 'f) t
val set : 'a sequence -> 'a t

seq seq is the ASN.1 SET construct, with the body seq.

val set_of : 'a t -> 'a list t

set_of asn is the ASN.1 SET OF construct.

val set2 : 'a element -> 'b element -> ('a * 'b) t

set2 e1 e2 is set (e1 -@ e2). Other setN functions are analogous.

val set3 : 'a element -> 'b element -> 'c element -> ('a * 'b * 'c) t
val set4 : 'a element -> 'b element -> 'c element -> 'd element -> ('a * 'b * 'c * 'd) t
val set5 : 'a element -> 'b element -> 'c element -> 'd element -> 'e element -> ('a * 'b * 'c * 'd * 'e) t
val set6 : 'a element -> 'b element -> 'c element -> 'd element -> 'e element -> 'f element -> ('a * 'b * 'c * 'd * 'e * 'f) t
val choice2 : 'a t -> 'b t -> [ `C1 of 'a | `C2 of 'b ] t

choice2 asn1 asn2 is the ASN.1 CHOICE construct, choosing between asn1 and asn2. Other choiceN functions are analogous.

Larger CHOICE can be obtained by nesting choice variants.

Note CHOICE containing elements with the same tag yields an illegal syntax. This will be detected by codec.

val choice3 : 'a t -> 'b t -> 'c t -> [ `C1 of 'a | `C2 of 'b | `C3 of 'c ] t
val choice4 : 'a t -> 'b t -> 'c t -> 'd t -> [ `C1 of 'a | `C2 of 'b | `C3 of 'c | `C4 of 'd ] t
val choice5 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> [ `C1 of 'a | `C2 of 'b | `C3 of 'c | `C4 of 'd | `C5 of 'e ] t
val choice6 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> [ `C1 of 'a | `C2 of 'b | `C3 of 'c | `C4 of 'd | `C5 of 'e | `C6 of 'f ] t

Primitives

val bool : bool t

bool is ASN.1 BOOLEAN.

val integer : string t

integer is ASN.1 INTEGER. The representation is a string. Be aware these are two's complement signed integers, in order to encode a positive number where the first bit is set (i.e. 128 = 0x80), you have to prepend a 0 byte: 0x00 0x80. Otherwise it (0x80) will be decoded as -128. See unsigned_integer for automated two's complement transformations.

val bit_string : bool array t

bit_string is ASN.1 BIT STRING.

val bit_string_octets : string t

bit_string_octets is ASN.1 BIT STRING, represented as string, and padded with 0-bits up to the next full octet.

val octet_string : string t

octet_string is ASN.1 OCTET STRING.

val null : unit t

null is ASN.1 NULL.

val oid : oid t

oid is ASN.1 OBJECT IDENTIFIER.

val enumerated : (int -> 'a) -> ('a -> int) -> 'a t

enumerated f g is ASN.1 ENUMERATED, with f projecting from, and g injecting into an int.

The full INTEGER range is not supported.

val generalized_time : Ptime.t t

generalized_time is ASN.1 GeneralizedTime.

val utc_time : Ptime.t t

utc_time is ASN.1 UTCTime.

Representable years are 1950–2049.

String primitives

Various ASN.1 stringy types.

Note Presently, no conversion or validation is performed on strings. They differ only in tags.

val utf8_string : string t
val numeric_string : string t
val printable_string : string t
val teletex_string : string t
val videotex_string : string t
val ia5_string : string t
val graphic_string : string t
val visible_string : string t
val general_string : string t
val universal_string : string t
val bmp_string : string t

Additional primitives

val int : int t

int is ASN.1 INTEGER, projected into an OCaml int.

val unsigned_integer : string t

unsigned_integer is ASN.1 INTEGER, where the necessary two's complement transformations are already applied. That is, it represents unsigned integers encoded as ASN.1 (signed) INTEGERs. Negative ASN.1 INTEGERs are rejected with a parse error.

val bit_string_flags : (int * 'a) list -> 'a list t

bit_string_flags xs is ASN.1 BIT STRING, represented as a collection of values.

xs is a list of (bit, x), where bit bit denotes the presence of x.

Errors

val error : [ `Parse of string ] -> 'a

error err aborts parsing with the error err.

Aborting the parse is useful, for example, in the f argument to map.

val parse_error : ('a, Stdlib.Format.formatter, unit, 'b) Stdlib.format4 -> 'a

parse_error fmt ... aborts parsing with the message produced by using fmt to format arguments ....