2 ASN.1 Types
procedure
(asn1-type? v) → boolean?
v : any/c
syntax
(define-asn1-type name-id type-expr)
type-expr : asn1-type?
2.1 Base Types
value
value
value
value
value
value
value
value
value
Represented by Racket strings satisfying the asn1-printable-string? predicate.
value
Represented by Racket strings satisfying the ascii-string? predicate.
value
value
Added in version 1.2 of package asn1-lib.
value
Added in version 1.2 of package asn1-lib.
value
Added in version 1.2 of package asn1-lib.
value
Added in version 1.2 of package asn1-lib.
value
Added in version 1.2 of package asn1-lib.
value
Added in version 1.2 of package asn1-lib.
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?
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.
> (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-id—
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?
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?
procedure
(SET-OF component-type) → asn1-type?
component-type : asn1-type?
syntax
(CHOICE variant ... maybe-extensible)
variant = [name-id maybe-tag variant-type maybe-option] maybe-extensible =
| #:extensible extension-id
variant-type : asn1-type?
(list variant-name-symbol variant-value)
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?
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
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?
Use DELAY to write recursive types or type definitions with forward references.
2.3 The ANY Type
value
> (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
> (bytes->asn1 ANY* (asn1->bytes (SEQUENCE-OF INTEGER) '(1 2 3 -1000))) '(sequence ((integer 1) (integer 2) (integer 3) (integer -1000)))
> (bytes->asn1 ANY* (asn1->bytes (SEQUENCE [a IA5String] [b INTEGER]) (hasheq 'a "Jean" 'b 24601))) '(sequence ((ia5string "Jean") (integer 24601)))
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)
syntax
(OID oid-component ...)
oid-component = arc-nat | (arc-name-id arc-nat)
> (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?)
> (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
v : any/c
Corresponds to #rx"^[-a-zA-Z0-9 '()+,./:=?]*$".
procedure
(asn1-numeric-string? v) → boolean?
v : any/c
Corresponds to #rx"^[ 0-9]*$".
Added in version 1.3 of package asn1-lib.
procedure
(asn1-visible-string? v) → boolean?
v : any/c
Corresponds to #rx"^[ -~]*$", or equivalently #rx"^[\x20-\x7E]*$".
Added in version 1.3 of package asn1-lib.
procedure
(ascii-string? v) → boolean?
v : any/c
Corresponds to #px"^[[:ascii:]]*$".
procedure
v : any/c
<GeneralizedTime> = YYYYMMDDhh[mm[ss[<sep>f[f[f[f]]]]]][<offset>] |
<sep> = "." | "," |
<offset> = "Z" | "+"hhmm | "-"hhmm |
> (asn1-generalized-time? "1985110621") #t
> (asn1-generalized-time? "19851106210627Z") #t
> (asn1-generalized-time? "19851106210627.3") #t
> (asn1-generalized-time? "19851106210627.3Z") #t
> (asn1-generalized-time? "19851106210627.3-0500") #t
Added in version 1.2 of package asn1-lib.
procedure
(asn1-utc-time? v) → boolean?
v : any/c
<UTCTime> = YYMMDDhh[mm[ss]]<offset> |
<sep> = "." | "," |
<offset> = "Z" | "+"hhmm | "-"hhmm |
> (asn1-utc-time? "851106210627Z") #t
> (asn1-utc-time? "851106210627-0500") #t
Added in version 1.2 of package asn1-lib.
> (asn1-oid? '(1 2 840 113549 1 1)) #t
Added in version 1.3 of package asn1-lib.