On this page:
asn1-type?
define-asn1-type
2.1 Base Types
BOOLEAN
INTEGER
ENUMERATED
BIT-STRING
OCTET-STRING
NULL
OBJECT-IDENTIFIER
RELATIVE-OID
Printable  String
IA5String
UTF8String
2.2 Structured Types
SEQUENCE
SET
SEQUENCE-OF
SET-OF
CHOICE
TAG
WRAP
DELAY
2.3 The ANY Type
ANY
ANY*
2.4 ASN.1 Type Utilities
bit-string
OID
build-OID
asn1-printable-string?
ascii-string?

2 ASN.1 Types

procedure

(asn1-type? v)  boolean?

  v : any/c
Returns #t if v is an ASN.1 type, #f otherwise.

syntax

(define-asn1-type name-id type-expr)

 
  type-expr : asn1-type?
Equivalent to

(define name-id (DELAY type-expr))

Useful for defining types with forward references. See also Translating ASN.1 Definition Order.

2.1 Base Types

Type of booleans. Corresponds to Racket’s boolean?.

Type of arbitrary-precision, signed integers. Corresponds to Racket’s exact-integer?.

Type of enumerations. Corresponds to Racket’s exact-integer?.

Type of bit strings, including those that end in a partial octet. Represented by the bit-string struct.

Type of octet strings. Corresponds to Racket’s bytes?.

value

NULL : asn1-type?

Indicates no information. Represented by the Racket value #f.

Type of references to “objects” in a hierarchical registry. Represented by Racket (listof exact-nonnegative-integer?) of length at least 2, where the first integer is between 0 and 2 (inclusive) and the second is between 0 and 39 (inclusive). There is no upper bound on subsequent integers.

Examples:
> (define rsadsi '(1 2 840 113549))
> (define pkcs1 (append rsadsi '(1 1)))

See also OID and build-OID.

Type of relative object identifiers. Represented by Racket (listof exact-nonnegative-integer?).

Subset of ASCII strings containing only the “printable” characters, which consist of A to Z, a to z, 0 to 9, the space character, and the characters in '()+,-./:=?. (Note that some ASCII characters normally considered printable, such as @ and _, do not fit within ASN.1’s notion of printable.)

Represented by Racket strings satisfying the asn1-printable-string? predicate.

Type of ASCII string (IA5 is ASCII). Note that ASCII/IA5 consists of only 7-bit characters; it is not the same as Latin-1.

Represented by Racket strings satisfying the ascii-string? predicate.

Type of Unicode strings encoded using UTF-8. Corresponds to Racket’s string?.

2.2 Structured Types

syntax

(SEQUENCE component ... maybe-extensible)

 
component = [name-id maybe-tag component-type maybe-option]
  | [name-id maybe-tag #:dependent component-type maybe-option]
     
maybe-tag = 
  | maybe-tag-class #:implicit tag-number
  | maybe-tag-class #:explicit tag-number
     
maybe-tag-class = 
  | #:universal
  | #:application
  | #:private
     
maybe-option = 
  | #:optional
  | #:default default-expr
     
maybe-extensible = 
  | #:extensible extension-id
 
  component-type : asn1-type?
Corresponds to the ASN.1 SEQUENCE type form.

Represented by Racket hashes of the following form:

(hasheq 'name-id component-value ... ...)

That is, the hash maps component-name symbols to the corresponding component-type field values.

If a component-type is preceded with the #:dependent keyword, then that component-type is not constant, but is instead evaluated with the values of preceding fields in scope each time the type is used for encoding or decoding.

Examples:
> (define IntOrString
    (SEQUENCE [type-id INTEGER]
              [value #:dependent (get-type type-id)]))
; get-type : Integer -> Asn1-Type
> (define (get-type type-id)
    (case type-id
      [(1) INTEGER]
      [(2) IA5String]
      [else (error 'get-type "unknown type-id: ~e" type-id)]))
> (asn1->bytes/DER IntOrString (hasheq 'type-id 1 'value 729072))

#"0\b\2\1\1\2\3\v\37\360"

> (asn1->bytes/DER IntOrString (hasheq 'type-id 2 'value "hello"))

#"0\n\2\1\2\26\5hello"

If #:extensible extension-id is specified after the components, then the sequence type is extensible, and any extra final components found when parsing an instance of the type are included in the result hash under the key 'extension-idthat is, 'extension-id is mapped to a non-empty list of BER-frames. If extra components are found when parsing an instance of a non-extensible sequence type, an exception is raised.

See also Translating Information Classes, Objects, and Object Sets.

Changed in version 1.1 of package asn1-lib: Added the #:extensible option.

syntax

(SET component ... maybe-extensible)

 
component = [name-id maybe-tag component-type maybe-option]
     
maybe-extensible = 
  | #:extensible extension-id
 
  component-type : asn1-type?
Corresponds the ASN.1 SET type form.

Represented by Racket values of the following form:

(hash 'name-id component-value ... ...)

where each component-value is a component-type value.

The syntax for components and extensibility are similar to that of SEQUENCE, except that component types cannot depend on other component values.

Changed in version 1.1 of package asn1-lib: Added the #:extensible option.

procedure

(SEQUENCE-OF component-type)  asn1-type?

  component-type : asn1-type?
Corresponds to the ASN.1 SEQUENCE OF type form.

Represented by Racket values of the following form:

(list component-value ...)

where each component-value is a component-type value.

procedure

(SET-OF component-type)  asn1-type?

  component-type : asn1-type?
Corresponds the the ASN.1 SET OF type form.

Represented by Racket values of the following form:

(list component-value ...)

where each component-value is a component-type value.

syntax

(CHOICE variant ... maybe-extensible)

 
variant = [name-id maybe-tag variant-type maybe-option]
     
maybe-extensible = 
  | #:extensible extension-id
 
  variant-type : asn1-type?
Corresonds to the ASN.1 CHOICE type form.

Represented by Racket values of the following form:

(list variant-name-symbol variant-value)

where variant-value is a value of the variant-type in the variant named by variant-name-symbol.

If #:extensible extension-id is specified after the variants, then the choice type is extensible, and any unknown tag found when parsing an instance of the type is parsed as ANY and labeled with 'extension-id. If an unknown tag is found when parsing an instance of a non-extensible choice type, an exception is raised.

Changed in version 1.1 of package asn1-lib: Added the #:extensible option.

syntax

(TAG maybe-tag-class tag type)

 
tag = #:implicit tag-number
  | #:explicit tag-number
 
  type : asn1-type?
Corresponds to an ASN.1 alternatively tagged type.

The representation is the same as that of type.

procedure

(WRAP type [#:encode encode #:decode decode])  asn1-type?

  type : asn1-type?
  encode : (or/c (-> any/c any/c) #f) = #f
  decode : (or/c (-> any/c any/c) #f) = #f
Produces a type wrapped-type that acts like type, but whose encoding is affected by the additional parameters as follows:

If encode is a function, then when encoding v as wrapped-type, evaluate (encode v) and pass that to the built-in encoding rules (or the next encoder hook) instead of v.

If decode is a function, then when decoding a bytestring as wrapped-type, first call the built-in decoding rules (or the next decoder hook) to get a Racket value v, then evaluate (decode v) and return the result as the decoded value.

Encoding hooks can also be used to add in support for base types not otherwise supported by this library. See Handling Unsupported Types for details.

syntax

(DELAY type)

 
  type : asn1-type?
Produces a type that acts like type, but delays the evaluation of type until it is needed for encoding or decoding, or to check the well-formedness of another type.

Use DELAY to write recursive types or type definitions with forward references.

2.3 The ANY Type

value

ANY : asn1-type?

Unknown or context-dependent type. Represented as a BER-frame. Decoding an unknown ASN.1 encoding as ANY shows the frame structure and tags, and may be help you deduce what the encoding represents.

> (bytes->asn1 ANY
    (asn1->bytes (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")))

> (bytes->asn1 ANY
    (asn1->bytes (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")))

value

ANY* : asn1-type?

Like ANY, but additionally recognizes and translates standard universal tags.

Added in version 1.1 of package asn1-lib.

2.4 ASN.1 Type Utilities

struct

(struct bit-string (bytes unused))

  bytes : bytes?
  unused : (integer-in 0 7)
Represents a bit string. The first bit in the bit string is the high bit of the first octet of bytes. The lowest unused bits of the last octet of bytes are not considered part of the bit string; they should be set to 0.

syntax

(OID oid-component ...)

 
oid-component = arc-nat
  | (arc-name-id arc-nat)
Notation for object identifiers that allows named arcs. The resulting value consists only of the arc numbers, however.

Examples:
> (OID (iso 1) (member-body 2) (us 840) (rsadsi 113549))

'(1 2 840 113549)

> (OID (iso 1) (member-body 2) (us 840) (rsadsi 113549) (pkcs 1) 1)

'(1 2 840 113549 1 1)

syntax

(build-OID oid-expr oid-component ...)

 
oid-component = arc-nat
  | (arc-name-id arc-nat)
 
  oid-expr : (listof exact-nonnegative-integer?)
Notation for object identifiers that extend existing object identifiers.

Examples:
> (define rsadsi (OID (iso 1) (member-body 2) (us 840) (rsadsi 113549)))
> (define pkcs-1 (build-OID rsadsi (pkcs 1) 1))
> pkcs-1

'(1 2 840 113549 1 1)

procedure

(asn1-printable-string? v)  boolean?

  v : any/c
Returns #t if v is a string containing only the characters allowed by PrintableString, #f otherwise.

procedure

(ascii-string? v)  boolean?

  v : any/c
Returns #t if v is a string containing only the characters allowed by IA5String (that is, characters 0 through 127), #f otherwise.