Windows: link against LIBHEIMBASE for json functionality
[heimdal.git] / lib / asn1 / MANUAL.md
blob89c452a031c02404f1cd13376e2cee53dd625c54
1 # Introduction
3 Heimdal is an implementation of PKIX and Kerberos.  As such it must handle the
4 use of [Abstract Syntax Notation One (ASN.1)](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en)
5 by those protocols.  ASN.1 is a language for describing the schemata of network
6 protocol messages.  Associated with ASN.1 are the ASN.1 Encoding Rules (ERs)
7 that specify how to encode such messages.
9 In short:
11  - ASN.1 is just a _schema description language_
13  - ASN.1 Encoding Rules are specifications for encoding formats for values of
14    types described by ASN.1 schemas ("modules")
16 Similar languages include:
18  - [DCE RPC's Interface Description Language (IDL)](https://pubs.opengroup.org/onlinepubs/9629399/chap4.htm#tagcjh_08)
19  - [Microsoft Interface Description Language (IDL)](https://docs.microsoft.com/en-us/windows/win32/midl/midl-start-page)
20    (MIDL is derived from the DCE RPC IDL)
21  - ONC RPC's eXternal Data Representation (XDR) [RFC4506](https://datatracker.ietf.org/doc/html/rfc4506)
22  - [XML Schema](https://en.wikipedia.org/wiki/XML_schema)
23  - Various JSON schema languages
24  - [Protocol Buffers](https://developers.google.com/protocol-buffers)
25  - and [many, many others](https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats)!
26    Many are not even listed there.
28 Similar encoding rules include:
30  - DCE RPC's [NDR](https://pubs.opengroup.org/onlinepubs/9629399/chap14.htm)
31  - ONC RPC's [XDR](https://datatracker.ietf.org/doc/html/rfc4506)
32  - XML
33  - FastInfoSet
34  - JSON
35  - CBOR
36  - [Protocol Buffers](https://developers.google.com/protocol-buffers)
37  - [Flat Buffers](https://google.github.io/flatbuffers/)
38  - and [many, many others](https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats)!
39    Many are not even listed there.
41 Many such languages are quite old.  ASN.1 itself dates to the early 1980s, with
42 the first specification published in 1984.  XDR was first published in 1987.
43 IDL's lineage dates back to sometime during the 1980s, via the Apollo Domain
44 operating system.
46 ASN.1 is standardized by the International Telecommunications Union (ITU-T),
47 and has continued evolving over the years, with frequent updates.
49 The two most useful and transcending features of ASN.1 are:
51  - the ability to formally express what some know as "open types", "typed
52    holes", or "references";
54  - the ability to add encoding rules over type, which for ASN.1 includes:
56     - binary, tag-length-value (TLV) encoding rules
57     - binary, non-TLV encoding rules
58     - textual encoding rules using XML and JSON
59     - an ad-hoc generic text-based ER called GSER
61    In principle ASN.1 can add encoding rules that would allow it to
62    interoperate with many others, such as: CBOR, protocol buffers, flat
63    buffers, NDR, and others.
65    Readers may recognize that some alternatives to ASN.1 have followed a
66    similar arc.  For example, Protocol Buffers was originally a syntax and
67    encoding, and has become a syntax and set of various encodings (e.g., Flat
68    Buffers was added later).  And XML has FastInfoSet as a binary encoding
69    alternative to XML's textual encoding.
71 As well, ASN.1 has [high-quality, freely-available specifications](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en).
73 ## ASN.1 Example
75 For example, this is a `Certificate` as used in TLS and other protocols, taken
76 from [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280):
78    ```ASN.1
79    Certificate  ::=  SEQUENCE  {
80         tbsCertificate       TBSCertificate,
81         signatureAlgorithm   AlgorithmIdentifier,
82         signatureValue       BIT STRING
83    }
85    TBSCertificate  ::=  SEQUENCE  {
86         version         [0]  EXPLICIT Version DEFAULT v1,
87         serialNumber         CertificateSerialNumber,
88         signature            AlgorithmIdentifier,
89         issuer               Name,
90         validity             Validity,
91         subject              Name,
92         subjectPublicKeyInfo SubjectPublicKeyInfo,
93         issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
94         subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
95         extensions      [3]  EXPLICIT Extensions OPTIONAL
96    }
97    ```
99 and the same `Certificate` taken from a more modern version -from
100 [RFC5912](https://datatracker.ietf.org/doc/html/rfc5912)- using newer features
101 of ASN.1:
103    ```ASN.1
104    Certificate  ::=  SIGNED{TBSCertificate}
106    TBSCertificate  ::=  SEQUENCE  {
107        version         [0]  Version DEFAULT v1,
108        serialNumber         CertificateSerialNumber,
109        signature            AlgorithmIdentifier{SIGNATURE-ALGORITHM,
110                                  {SignatureAlgorithms}},
111        issuer               Name,
112        validity             Validity,
113        subject              Name,
114        subjectPublicKeyInfo SubjectPublicKeyInfo,
115        ... ,
116        [[2:
117        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
118        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL
119        ]],
120        [[3:
121        extensions      [3]  Extensions{{CertExtensions}} OPTIONAL
122        ]], ...
123    }
124    ```
126 As you can see, a `Certificate` is a structure containing a to-be-signed
127 sub-structure, and a signature of that sub-structure, and the sub-structure
128 has: a version number, a serial number, a signature algorithm, an issuer name,
129 a validity period, a subject name, a public key for the subject name, "unique
130 identifiers" for the issuer and subject entities, and "extensions".
132 To understand more we'd have to look at the types of those fields of
133 `TBSCertificate`, but for now we won't do that.  The point here is to show that
134 ASN.1 allows us to describe "types" of data in a way that resembles
135 "structures", "records", or "classes" in various programming languages.
137 To be sure, there are some "noisy" artifacts in the definition of
138 `TBSCertificate` which mostly have to do with the original encoding rules for
139 ASN.1.  The original encoding rules for ASN.1 were tag-length-value (TLV)
140 binary encodings, meaning that for every type, the encoding of a value of that
141 type consisted of a _tag_, a _length_ of the value's encoding, and the _actual
142 value's encoding_.  Over time other encoding rules were added that do not
143 require tags, such as the octet encoding rules (OER), but also JSON encoding
144 rules (JER), XML encoding rules (XER), and others.  There is almost no need for
145 tagging directives like `[1] IMPLICIT` when using OER.  But in existing
146 protocols like PKIX and Kerberos that date back to the days when DER was king,
147 tagging directives are unfortunately commonplace.
149 ## ASN.1 Crash Course
151 This is not a specification.  Readers should refer to the ITU-T's X.680 base
152 specification for ASN.1's syntax.
154 A schema is called a "module".
156 A module looks like:
158 ```ASN.1
159 -- This is a comment
161 -- Here's the name of the module, here given as an "object identifier" or
162 -- OID:
163 PKIXAlgs-2009 { iso(1) identified-organization(3) dod(6)
164   internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
165   id-mod-pkix1-algorithms2008-02(56) }
168 -- `DEFINITIONS` is a required keyword
169 -- `EXPLICIT TAGS` will be explained later
170 DEFINITIONS EXPLICIT TAGS ::=
171 BEGIN
172 -- list exported types, or `ALL`:
173 EXPORTS ALL;
174 -- import some types:
175 IMPORTS PUBLIC-KEY, SIGNATURE-ALGORITHM, ... FROM AlgorithmInformation-2009
176         mda-sha224, mda-sha256, ... FROM PKIX1-PSS-OAEP-Algorithms-2009;
178 -- type definitions follow:
184 Type names start with capital upper-case letters.  Value names start with
185 lower-case letters.
187 Type definitions are of the form `TypeName ::= TypeDefinition`.
189 Value (constant) definitions are of the form `valueName ::= TypeName <literal>`.
191 There are some "universal" primitive types (e.g., string types, numeric types),
192 and several "constructed" types (arrays, structures.
194 Some useful primitive types include `BOOLEAN`, `INTEGER` and `UTF8String`.
196 Structures are either `SEQUENCE { ... }` or `SET { ... }`.  The "fields" of
197 these are known as "members".
199 Arrays are either `SEQUENCE OF SomeType` or `SET OF SomeType`.
201 A `SEQUENCE`'s elements or members are ordered, while a `SET`'s are not.  In
202 practice this means that for _canonical_ encoding rules a `SET OF` type's
203 values must be sorted, while a `SET { ... }` type's members need not be sorted
204 at run-time, but are sorted by _tag_ at compile-time.
206 Anonymous types are supported, such as `SET OF SET { a A, b B }` (which is a
207 set of structures with an `a` field (member) of type `A` and a `b` member of
208 type `B`).
210 The members of structures can be `OPTIONAL` or have a `DEFAULT` value.
212 There are also discriminated union types known as `CHOICE`s: `U ::= CHOICE { a
213 A, b B, c C }` (in this case `U` is either an `A`, a `B`, or a `C`.
215 Extensibility is supported.  "Extensibility" means: the ability to add new
216 members to structures, new alternatives to discriminated unions, etc.  For
217 example, `A ::= SEQUENCE { a0 A0, a1 A1, ... }` means that type `A` is a
218 structure that has two fields and which may have more fields added in future
219 revisions, therefore decoders _must_ be able to receive and decode encodings of
220 extended versions of `A`, even encoders produced prior to the extensions being
221 specified!  (Normally a decoder "skips" extensions it doesn't know about, and
222 the encoding rules need only make it possible to do so.)
224 ## TLV Encoding Rules
226 The TLV encoding rules for ASN.1 are:
228  - Basic Encoding Rules (BER)
229  - Distinguished Encoding Rules (DER), a canonical subset of BER
230  - Canonical Encoding Rules (CER), another canonical subset of BER
232 "Canonical" encoding rules yield just one way to encode any value of any type,
233 while non-canonical rules possibly yield many ways to encode values of certain
234 types.  For example, JSON is not a canonical data encoding.  A canonical form
235 of JSON would have to specify what interstitial whitespace is allowed, a
236 canonical representation of strings (which Unicode codepoints must be escaped
237 and in what way, and which must not), and a canonical representation of decimal
238 numbers.
240 It is important to understand that originally ASN.1 came with TLV encoding
241 rules, and some considerations around TLV encoding rules leaked into the
242 language.  For example, `A ::= SET { a0 [0] A0, a1 [1] A1 }` is a structure
243 that has two members `a0` and `a1`, and when encoded those members will be
244 tagged with a "context-specific" tags `0` and `1`, respectively.
246 Tags only have to be specified when needed to disambiguate encodings.
247 Ambiguities arise only in `CHOICE` types and sometimes in `SEQUENCE`/`SET`
248 types that have `OPTIONAL`/`DEFAULT`ed members.
250 In modern ASN.1 it is possible to specify that a module uses `AUTOMATIC`
251 tagging so that one need never specify tags explicitly in order to fix
252 ambiguities.
254 Also, there are two types of tags: `IMPLICIT` and `EXPLICIT`.  Implicit tags
255 replace the tags that the tagged type would have otherwise.  Explicit tags
256 treat the encoding of a type's value (including its tag and length) as the
257 value of the tagged type, thus yielding a tag-length-tag-length-value encoding
258 -- a TLTLV encoding!
260 Thus explicit tagging is more redundant and wasteful than implicit tagging.
261 But implicit tagging loses metadata that is useful for tools that can decode
262 TLV encodings without reference to the schema (module) corresponding to the
263 types of values encoded.
265 TLV encodings were probably never justified except by lack of tooling and
266 belief that codecs for TLV ERs can be hand-coded.  But TLV RTs exist, and
267 because they are widely used, cannot be removed.
269 ## Other Encoding Rules
271 The Packed Encoding Rules (PER) and Octet Encoding Rules (OER) are rules that
272 resemble XDR, but with a 1-byte word size instead of 4-byte word size, and also
273 with a 1-byte alignment instead of 4-byte alignment, yielding space-efficient
274 encodings.
276 Hand-coding XDR codecs is quite common and fairly easy.  Hand-coding PER and
277 OER is widely considered difficult because PER and OER try to be quite
278 space-efficient.
280 Hand-coding TLV codecs used to be considered easy, but really, never was.
282 But no one should hand-code codecs for any encoding rules.
284 Instead, one should use a compiler.  This is true for ASN.1, and for all schema
285 languages.
287 ## Encoding Rule Specific Syntactic Forms
289 Some encoding rules require specific syntactic forms for some aspects of them.
291 For example, the JER (JSON Encoding Rules) provide for syntax to select the use
292 of JSON arrays vs. JSON objects for encoding structure types.
294 For example, the TLV encoding rules provide for syntax for specifying
295 alternative tags for disambiguation.
297 ## ASN.1 Syntax Specifications
299  - The base specification is ITU-T
300    [X.680](https://www.itu.int/rec/T-REC-X.680-202102-I/en).
302  - Additional syntax extensions include:
304     - [X.681 ASN.1 Information object specification](https://www.itu.int/rec/T-REC-X.681/en)
305     - [X.682 ASN.1 Constraint specification](https://www.itu.int/rec/T-REC-X.682/en)
306     - [X.682 ASN.1 Parameterization of ASN.1 specifications](https://www.itu.int/rec/T-REC-X.683/en)
308    Together these three specifications make the formal specification of open
309    types possible.
311 ## ASN.1 Encoding Rules Specifications
313  - The TLV Basic, Distinguished, and Canonical Encoding Rules (BER, DER, CER)
314    are described in ITU-T [X.690](https://www.itu.int/rec/T-REC-X.690/en).
316  - The more flat-buffers/XDR-like Packed Encoding Rules (PER) are described in
317    ITU-T [X.691](https://www.itu.int/rec/T-REC-X.691/en), and its successor,
318    the Octet Encoding Rules (OER) are described in
319    [X.696](https://www.itu.int/rec/T-REC-X.692/en).
321  - The XML Encoding Rules (XER) are described in ITU-T
322    [X.693](https://www.itu.int/rec/T-REC-X.693/en).
324    Related is the [X.694 Mapping W3C XML schema definitions into ASN.1](https://www.itu.int/rec/T-REC-X.694/en)
326  - The JSON Encoding Rules (JER) are described in ITU-T
327    [X.697](https://www.itu.int/rec/T-REC-X.697/en).
329  - The Generic String Encoding Rules are specified by IETF RFCs
330    [RFC3641](https://datatracker.ietf.org/doc/html/rfc3641),
331    [RFC3642](https://datatracker.ietf.org/doc/html/rfc3642),
332    [RFC4792](https://datatracker.ietf.org/doc/html/rfc4792).
334 Additional ERs can be added.
336 For example, XDR can clearly encode a very large subset of ASN.1, and with a
337 few additional conventions, all of ASN.1.
339 NDR too can clearly encode a very large subset of ASN.1, and with a few
340 additional conventions, all of ASN.  However, ASN.1 is not sufficiently rich a
341 _syntax_ to express all of what NDR can express (think of NDR conformant and/or
342 varying arrays), though with some extensions it could.
344 ## Commentary
346 The text in this section is the personal opinion of the author(s).
348  - ASN.1 gets a bad rap because BER/DER/CER are terrible encoding rules, as are
349    all TLV encoding rules.
351    The BER family of encoding rules is a disaster, yes, but ASN.1 itself is
352    not.  On the contrary, ASN.1 is quite rich in features and semantics -as
353    rich as any competitor- while also being very easy to write and understand
354    _as a syntax_.
356  - ASN.1 also gets a bad rap because its full syntax is not context-free, and
357    so parsing it can be tricky.
359    And yet the Heimdal ASN.1 compiler manages, using LALR(1) `yacc`/`bison`/`byacc`
360    parser-generators.  For the subset of ASN.1 that this compiler handles,
361    there are no ambiguities.  However, we understand that eventually we will
362    need run into ambiguities.
364    For example, `ValueSet` and `ObjectSet` are ambiguous.  X.680 says:
366    ```
367    ValueSet ::= "{" ElementSetSpecs "}"
368    ```
370    while X.681 says:
372    ```
373    ObjectSet ::= "{" ObjectSetSpec "}"
374    ```
376    and the set members can be just the symbolic names of members, in which case
377    there's no grammatical difference between those two productions.  These then
378    cause a conflict in the `FieldSetting` production, which is used in the
379    `ObjectDefn` production, which is used in defining an object (which is to be
380    referenced from some `ObjectSet` or `FieldSetting`).
382    This particular conflict can be resolved by one of:
384     - limiting the power of object sets by disallowing recursion (object sets
385       containing objects that have field settings that are object sets ...),
387     - or by introducing additional required and disambiguating syntactic
388       elements that preclude full compliance with ASN.1,
390     - or by simply using the same production and type internally to handle
391       both, the `ValueSet` and `ObjectSet` productions and then internally
392       resolving the actual type as late as possible by either inspecting the
393       types of the set members or by inspecting the expected kind of field that
394       the `ValueSet`-or-`ObjectSet` is setting.
396    Clearly, only the last of these is satisfying, but it is more work for the
397    compiler developer.
399  - TLV encodings are bad because they yield unnecessary redundance in
400    encodings.  This is space-inefficient, but also a source of bugs in
401    hand-coded codecs for TLV encodings.
403    EXPLICIT tagging makes this worse by making the encoding a TLTLV encoding
404    (tag length tag length value).  (The inner TLV is the V for the outer TL.)
406  - TLV encodings are often described as "self-describing" because one can
407    usually write a `dumpasn1` style of tool that attempts to decode a TLV
408    encoding of a value without reference to the value's type definition.
410    The use of `IMPLICIT` tagging with BER/DER/CER makes schema-less `dumpasn1`
411    style tools harder to use, as some type information is lost.  E.g., a
412    primitive type implicitly tagged with a context tag results in a TLV
413    encoding where -without reference to the schema- the tag denotes no
414    information about the type of the value encoded.  The user is left to figure
415    out what kind of data that is and to then decode it by hand.  For
416    constructed types (arrays and structures), implicit tagging does not really
417    lose any metadata about the type that wasn't already lost by BER/DER/CER, so
418    there is no great loss there.
420    However, Heimdal's ASN.1 compiler includes an `asn1_print(1)` utility that
421    can print DER-encoded values in much more detail than a schema-less
422    `dumpasn1` style of tool can.  This is because `asn1_print(1)` includes
423    a number of compiled ASN.1 modules, and it can be extended to include more.
425  - There is some merit to BER, however.  Specifically, an appropriate use of
426    indeterminate length encoding with BER can yield on-line encoding.  Think of
427    encoding streams of indeterminate size -- this cannot be done with DER or
428    Flat Buffers, or most encodings, though it can be done with some encodings,
429    such as BER and NDR (NDR has "pipes" for this).
431    Some clues are needed in order to produce an codec that can handle such
432    on-line behavior.  In IDL/NDR that clue comes from the "pipe" type.  In
433    ASN.1 there is no such clue and it would have to be provided separately to
434    the ASN.1 compiler (e.g., as a command-line option).
436  - Protocol Buffers is a TLV encoding.  There was no need to make it a TLV
437    encoding.
439    Public opinion seems to prefer Flat Buffers now, which is not a TLV encoding
440    and which is more comparable to XDR/NDR/PER/OER.
442 # Heimdal ASN.1 Compiler
444 The Heimdal ASN.1 compiler and library implement a very large subset of the
445 ASN.1 syntax, meanign large parts of X.680, X.681, X.682, and X.683.
447 The compiler currently emits:
449  - a JSON representation of ASN.1 modules
450  - C types corresponding to ASN.1 modules' types
451  - C functions for DER (and some BER) codecs for ASN.1 modules' types
453 We vaguely hope to eventually move to using the JSON representation of ASN.1
454 modules to do code generation in a programming language like `jq` rather than
455 in C.  The idea there is to make it much easier to target other programming
456 languages than C, especially Rust, so that we can start moving Heimdal to Rust
457 (first after this would be `lib/hx509`, then `lib/krb5`, then `lib/hdb`, then
458 `lib/gssapi`, then `kdc/`).
460 The compiler has two "backends":
462  - C code generation
463  - "template" (byte-code) generation and interpretation
465 ## Features and Limitations
467 Supported encoding rules:
469  - DER
470  - BER decoding (but not encoding)
472 As well, the Heimdal ASN.1 compiler can render values as JSON using an ad-hoc
473 metaschema that is not quite JER-compliant.  A sample rendering of a complex
474 PKIX `Certificate` with all typed holes automatically decoded is shown in
475 [README.md#features](README.md#features).
477 The Heimdal ASN.1 compiler supports open types via X.681/X.682/X.683 syntax.
478 Specifically: (when using the template backend) the generated codecs can
479 automatically and recursively decode and encode through "typed holes".
481 An "open type", also known as "typed holes" or "references", is a part of a
482 structure that can contain the encoding of a value of some arbitrary data type,
483 with a hint of that value's type expressed in some way such as: via an "object
484 identifier", or an integer, or even a string (e.g., like a URN).
486 Open types are widely used as a form of extensibility.
488 Historically, open types were never documented formally, but with natural
489 language (e.g., English) meant only for humans to understand.  Documenting open
490 types with formal syntax allows compilers to support them specially.
492 See the the [`asn1_compile(1)` manual page](#Manual-Page-for-asn1_compile)
493 below and [README.md#features](README.md#features), for more details on
494 limitations.  Excerpt from the manual page:
497 The Information Object System support includes automatic codec support
498 for encoding and decoding through “open types” which are also known as
499 “typed holes”.  See RFC5912 for examples of how to use the ASN.1 Infor-
500 mation Object System via X.681/X.682/X.683 annotations.  See the com-
501 piler's README files for more information on ASN.1 Information Object
502 System support.
504 Extensions specific to Heimdal are generally not syntactic in nature but
505 rather command-line options to this program.  For example, one can use
506 command-line options to:
507       •       enable decoding of BER-encoded values;
508       •       enable RFC1510-style handling of ‘BIT STRING’ types;
509       •       enable saving of as-received encodings of specific types
510               for the purpose of signature validation;
511       •       generate add/remove utility functions for array types;
512       •       decorate generated ‘struct’ types with fields that are nei-
513               ther encoded nor decoded;
514 etc.
516 ASN.1 x.680 features supported:
517       •       most primitive types (except BMPString and REAL);
518       •       all constructed types, including SET and SET OF;
519       •       explicit and implicit tagging.
521 Size and range constraints on the ‘INTEGER’ type cause the compiler to
522 generate appropriate C types such as ‘int’, ‘unsigned int’, ‘int64_t’,
523 ‘uint64_t’.  Unconstrained ‘INTEGER’ is treated as ‘heim_integer’, which
524 represents an integer of arbitrary size.
526 Caveats and ASN.1 x.680 features not supported:
527       •       JSON encoding support is not quite X.697 (JER) compatible.
528               Its JSON schema is subject to change without notice.
529       •       Control over C types generated is very limited, mainly only
530               for integer types.
531       •       When using the template backend, `SET { .. }` types are
532               currently not sorted by tag as they should be, but if the
533               module author sorts them by hand then correct DER will be
534               produced.
535       •       ‘AUTOMATIC TAGS’ is not supported.
536       •       The REAL type is not supported.
537       •       The EmbeddedPDV type is not supported.
538       •       The BMPString type is not supported.
539       •       The IA5String is not properly supported, as it's essen‐
540               tially treated as a UTF8String with a different tag.
541       •       All supported non-octet strings are treated as like the
542               UTF8String type.
543       •       Only types can be imported into ASN.1 modules at this time.
544       •       Only simple value syntax is supported.  Constructed value
545               syntax (i.e., values of SET, SEQUENCE, SET OF, and SEQUENCE
546               OF types), is not supported.  Values of `CHOICE` types are
547               also not supported.
550 ## Easy-to-Use C Types
552 The Heimdal ASN.1 compiler generates easy-to-use C types for ASN.1 types.
554 Unconstrained `INTEGER` becomes `heim_integer` -- a large integer type.
556 Constrained `INTEGER` types become `int`, `unsigned int`, `int64_t`, or
557 `uint64_t`.
559 String types generally become `char *` (C strings, i.e., NUL-terminated) or
560 `heim_octet_string` (a counted byte string type).
562 `SET` and `SEQUENCE` types become `struct` types.
564 `SET OF SomeType` and `SEQUENCE OF SomeType` types become `struct` types with a
565 `size_t len` field counting the number of elements of the array, and a pointer
566 to `len` consecutive elements of the `SomeType` type.
568 `CHOICE` types become a `struct` type with an `enum` discriminant and a
569 `union`.
571 Type names have hyphens turned to underscores.
573 Every ASN.1 gets a `typedef`.
575 `OPTIONAL` members of `SET`s and `SEQUENCE`s become pointer types (`NULL`
576 values mean "absent", while non-`NULL` values mean "present").
578 Tags are of no consequence to the C types generated.
580 Types definitions to be topographically sorted because of the need to have
581 forward declarations.
583 Forward `typedef` declarations are emmitted.
585 Circular type dependencies are allowed provided that `OPTIONAL` members are
586 used for enough circular references so as to avoid creating types whose values
587 have infinite size!  (Circular type dependencies can be used to build linked
588 lists, though that is a bit of a silly trick when one can use arrays instead,
589 though in principle this could be used to do on-line encoding and decoding of
590 arbitrarily large streams of objects.  See the [commentary](#Commentary)
591 section.)
593 Thus `Certificate` becomes:
595 ```C
596 typedef struct TBSCertificate {
597   heim_octet_string _save; /* see below! */
598   Version *version;
599   CertificateSerialNumber serialNumber;
600   AlgorithmIdentifier signature;
601   Name issuer;
602   Validity validity;
603   Name subject;
604   SubjectPublicKeyInfo subjectPublicKeyInfo;
605   heim_bit_string *issuerUniqueID;
606   heim_bit_string *subjectUniqueID;
607   Extensions *extensions;
608 } TBSCertificate;
610 typedef struct Certificate {
611   TBSCertificate tbsCertificate;
612   AlgorithmIdentifier signatureAlgorithm;
613   heim_bit_string signatureValue;
614 } Certificate;
617 The `_save` field in `TBSCertificate` is generated when the compiler is invoked
618 with `--preserve-binary=TBSCertificate`, and the decoder will place the
619 original encoding of the value of a `TBSCertificate` in the decoded
620 `TBSCertificate`'s `_save` field.  This is very useful for signature
621 validation: the application need not attempt to re-encode a `TBSCertificate` in
622 order to validate its signature from the containing `Certificate`!
624 Let's compare to the `Certificate` as defined in ASN.1:
626 ```ASN.1
627    Certificate  ::=  SEQUENCE  {
628         tbsCertificate       TBSCertificate,
629         signatureAlgorithm   AlgorithmIdentifier,
630         signatureValue       BIT STRING
631    }
633    TBSCertificate  ::=  SEQUENCE  {
634         version         [0]  EXPLICIT Version DEFAULT v1,
635         serialNumber         CertificateSerialNumber,
636         signature            AlgorithmIdentifier,
637         issuer               Name,
638         validity             Validity,
639         subject              Name,
640         subjectPublicKeyInfo SubjectPublicKeyInfo,
641         issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
642         subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
643         extensions      [3]  EXPLICIT Extensions OPTIONAL
644    }
647 The conversion from ASN.1 to C is quite mechanical and natural.  That's what
648 code-generators do, of course, so it's not surprising.  But you can see that
649 `Certificate` in ASN.1 and C differs only in:
651  - in C `SEQUENCE { }` becomes `struct { }`
652  - in C the type name comes first
653  - in C we drop the tagging directives (e.g., `[0]  EXPLICIT`)
654  - `DEFAULT` and `OPTIONAL` become pointers
655  - in C we use `typedef`s to make the type names usable without having to add
656    `struct`
658 ## Circular Type Dependencies
660 As noted above, circular type dependencies are supported.
662 Here's a toy example from [XDR](https://datatracker.ietf.org/doc/html/rfc4506)
663 -- a linked list:
665 ```XDR
666 struct stringentry {
667    string item<>;
668    stringentry *next;
671 typedef stringentry *stringlist;
674 Here is the same example in ASN.1:
676 ```ASN.1
677 Stringentry ::= SEQUENCE {
678     item UTF8String,
679     next Stringentry OPTIONAL
683 which compiles to:
685 ```C
686 typedef struct Stringentry Stringentry;
687 struct Stringentry {
688     char *item;
689     Stringentry *next;
693 This illustrates that `OPTIONAL` members in ASN.1 are like pointers in XDR.
695 Making the `next` member not `OPTIONAL` would cause `Stringentry` to be
696 infinitely large, and there is no way to declare the equivalent in C anyways
697 (`struct foo { int a; struct foo b; };` will not compile in C).
699 Mutual circular references are allowed too.  In the following example `A`
700 refers to `B` and `B` refers to `A`, but as long as one (or both) of those
701 references is `OPTIONAL`, then it will be allowed:
703 ```ASN1
704 A ::= SEQUENCE { name UTF8String, b B }
705 B ::= SEQUENCE { name UTF8String, a A OPTIONAL }
708 ```ASN1
709 A ::= SEQUENCE { name UTF8String, b B OPTIONAL }
710 B ::= SEQUENCE { name UTF8String, a A }
713 ```ASN1
714 A ::= SEQUENCE { name UTF8String, b B OPTIONAL }
715 B ::= SEQUENCE { name UTF8String, a A OPTIONAL }
718 In the above example values of types `A` and `B` together form a linked list.
720 Whereas this is broken and will not compile:
722 ```ASN1
723 A ::= SEQUENCE { name UTF8String, b B }
724 B ::= SEQUENCE { name UTF8String, a A } -- infinite size!
727 ## Generated APIs For Any Given Type T
729 The C functions generated for ASN.1 types are all of the same form, for any
730 type `T`:
732 ```C
733 int    decode_T(const unsigned char *, size_t, TBSCertificate *, size_t *);
734 int    encode_T(unsigned char *, size_t, const TBSCertificate *, size_t *);
735 size_t length_T(const TBSCertificate *);
736 int      copy_T(const TBSCertificate *, TBSCertificate *);
737 void     free_T(TBSCertificate *);
738 char *  print_T(const TBSCertificate *, int);
741 The `decode_T()` functions take a pointer to the encoded data, its length in
742 bytes, a pointer to a C object of type `T` to decode into, and a pointer into
743 which the number of bytes consumed will be written.
745 The `length_T()` functions take a pointer to a C object of type `T` and return
746 the number of bytes its encoding would need.
748 The `encode_T()` functions take a pointer to enough bytes to encode the value,
749 the number of bytes found there, a pointer to a C object of type `T` whose
750 value to encode, and a pointer into which the number of bytes output will be
751 written.
753 > NOTE WELL: The first argument to `encode_T()` functions must point to the
754 > last byte in the buffer into which the encoder will encode the value.  This
755 > is because the encoder encodes from the end towards the beginning.
757 The `print_T()` functions encode the value of a C object of type `T` in JSON
758 (though not in JER-compliant JSON).  A sample printing of a complex PKIX
759 `Certificate` can be seen in [README.md#features](README.md#features).
761 The `copy_T()` functions take a pointer to a source C object of type `T` whose
762 value they then copy to the destination C object of the same type.  The copy
763 constructor is equivalent to encoding the source value and decoding it onto the
764 destination.
766 The `free_T()` functions take a pointer to a C object of type `T` whose value's
767 memory resources will be released.  Note that the C object _itself_ is not
768 freed, only its _content_.
770 See [sample usage](#Using-the-Generated-APIs).
772 These functions are all recursive.
774 > NOTE WELL: These functions use the standard C memory allocator.
775 > When using the Windows statically-linked C run-time, you must link with
776 > `LIBASN1.LIB` to avoid possibly freeing memory allocated by a different
777 > allocator.
779 ## Error Handling
781 All codec functions that return errors return them as `int`.
783 Error values are:
785  - system error codes (use `strerror()` to display them)
789  - `ASN1_BAD_TIMEFORMAT`
790  - `ASN1_MISSING_FIELD`
791  - `ASN1_MISPLACED_FIELD`
792  - `ASN1_TYPE_MISMATCH`
793  - `ASN1_OVERFLOW`
794  - `ASN1_OVERRUN`
795  - `ASN1_BAD_ID`
796  - `ASN1_BAD_LENGTH`
797  - `ASN1_BAD_FORMAT`
798  - `ASN1_PARSE_ERROR`
799  - `ASN1_EXTRA_DATA`
800  - `ASN1_BAD_CHARACTER`
801  - `ASN1_MIN_CONSTRAINT`
802  - `ASN1_MAX_CONSTRAINT`
803  - `ASN1_EXACT_CONSTRAINT`
804  - `ASN1_INDEF_OVERRUN`
805  - `ASN1_INDEF_UNDERRUN`
806  - `ASN1_GOT_BER`
807  - `ASN1_INDEF_EXTRA_DATA`
809 You can use the `com_err` library to display these errors as strings:
811 ```C
812     struct et_list *etl = NULL;
813     initialize_asn1_error_table_r(&etl);
814     int ret;
816     ...
818     ret = decode_T(...);
819     if (ret) {
820         const char *error_message;
822         if ((error_message = com_right(etl, ret)) == NULL)
823             error_message = strerror(ret);
825         fprintf(stderr, "Failed to decode T: %s\n",
826                 error_message ? error_message : "<unknown error>");
827     }
830 ## Using the Generated APIs
832 Value construction is as usual in C.  Use the standard C allocator for
833 allocating values of `OPTIONAL` fields.
835 Value destruction is done with the `free_T()` destructors.
837 Decoding is just:
839 ```C
840     Certificate c;
841     size_t sz;
842     int ret;
844     ret = decode_Certificate(pointer_to_encoded_bytes,
845                              number_of_encoded_bytes,
846                              &c, &sz);
847     if (ret == 0) {
848         if (sz != number_of_encoded_bytes)
849             warnx("Extra bytes after Certificate!");
850     } else {
851         warnx("Failed to decode certificate!");
852         return ret;
853     }
855     /* Now do stuff with the Certificate */
856     ...
858     /* Now release the memory */
859     free_Certificate(&c);
862 Encoding involves calling the `length_T()` function to compute the number of
863 bytes needed for the encoding, then allocating that many bytes, then calling
864 `encode_T()` to encode into that memory.  A convenience macro,
865 `ASN1_MALLOC_ENCODE()`, does all three operations:
867 ```C
868     Certificate c;
869     size_t num_bytes, sz;
870     char *bytes = NULL;
871     int ret;
873     /* Build a `Certificate` in `c` */
874     ...
876     /* Encode `c` */
877     ASN1_MALLOC_ENCODE(Certificate, bytes, num_bytes, &c, sz, ret);
878     if (ret)
879         errx(1, "Out of memory encoding a Certificate");
881     /* This check isn't really needed -- it never fails */
882     if (num_bytes != sz)
883         errx(1, "ASN.1 encoder internal error");
885     /* Send the `num_bytes` in `bytes` */
886     ...
888     /* Free the memory allocated by `ASN1_MALLOC_ENCODE()` */
889     free(bytes);
892 or, the same code w/o the `ASN1_MALLOC_ENCODE()` macro:
894 ```C
895     Certificate c;
896     size_t num_bytes, sz;
897     char *bytes = NULL;
898     int ret;
900     /* Build a `Certificate` in `c` */
901     ...
903     /* Encode `c` */
904     num_bytes = length_Certificate(&c);
905     bytes = malloc(num_bytes);
906     if (bytes == NULL)
907         errx(1, "Out of memory");
909     /*
910      * Note that the memory to encode into, passed to encode_Certificate()
911      * must be a pointer to the _last_ byte of that memory, not the first!
912      */
913     ret = encode_Certificate(bytes + num_bytes - 1, num_bytes,
914                              &c, &sz);
915     if (ret)
916         errx(1, "Out of memory encoding a Certificate");
918     /* This check isn't really needed -- it never fails */
919     if (num_bytes != sz)
920         errx(1, "ASN.1 encoder internal error");
922     /* Send the `num_bytes` in `bytes` */
923     ...
925     /* Free the memory allocated by `ASN1_MALLOC_ENCODE()` */
926     free(bytes);
929 ## Open Types
931 The handling of X.681/X.682/X.683 syntax for open types is described at length
932 in [README-X681.md](README-X681.md).
934 ## Command-line Usage
936 The compiler takes an ASN.1 module file name and outputs a C header and C
937 source files, as well as various other metadata files:
939  - `<module>_asn1.h`
941    This file defines all the exported types from the given ASN.1 module as C
942    types.
944  - `<module>_asn1-priv.h`
946    This file defines all the non-exported types from the given ASN.1 module as
947    C types.
949  - `<module>_asn1_files`
951    This file is needed because the default is to place the code for each type
952    in a separate C source file, which can help improve the performance of
953    builds by making it easier to parallelize the building of the ASN.1 module.
955  - `asn1_<Type>.c` or `asn1_<module>_asn1.c`
957    If `--one-code-file` is used, then the implementation of the module will be
958    in a file named `asn1_<module>_asn1.c`, otherwise the implementation of each
959    type in the module will be in `asn1_<Type>.c`.
961  - `<module>_asn1.json`
963    This file contains a JSON description of the module (the schema for this
964    file is ad-hoc and subject to change w/o notice).
966  - `<module>_asn1_oids.c`
968    This file is meant to be `#include`d, and contains just calls to a
969    `DEFINE_OID_WITH_NAME(sym)` macro that the user must define, where `sym` is
970    the suffix of the name of a variable of type `heim_oid`.  The full name of
971    the variable is `asn1_oid_ ## sym`.
973  - `<module>_asn1_syms.c`
975    This file is meant to be `#include`d, and contains just calls to these
976    macros that the user must define:
978     - `ASN1_SYM_INTVAL(name, genname, sym, num)`
979     - `ASN1_SYM_OID(name, genname, sym)`
980     - `ASN1_SYM_TYPE(name, genname, sym)`
982    where `name` is the C string literal name of the value or type as it appears
983    in the ASN.1 module, `genname` is the C string literal name of the value or
984    type as generated (e.g., with hyphens replaced by underscores), `sym` is the
985    symbol or symbol suffix (see above0, and `num` is the numeric value of the
986    integer value.
988 Control over the C types used for ASN.1 `INTEGER` types is done by ASN.1 usage
989 convention:
991  - unconstrained `INTEGER` types, or `INTEGER` types where only the minimum, or
992    only the maximum value is specified generate `heim_integer`
994  - constrained `INTEGER` types whose minimum and maximum fit in `unsigned`'s
995    range generate `unsigned`
997  - constrained `INTEGER` types whose minimum and maximum fit in `int`'s
998    range generate `int`
1000  - constrained `INTEGER` types whose minimum and maximum fit in `uin64_t`'s
1001    range generate `uin64_t`
1003  - constrained `INTEGER` types whose minimum and maximum fit in `in64_t`'s
1004    range generate `in64_t`
1006  - `INTEGER` types with named members generate a C `struct` with `unsigned int`
1007    bit-field members
1009  - all other `INTEGER` types generate `heim_integer`
1011 Various code generation options are provided as command-line options or as
1012 ASN.1 usage conventions:
1014  - `--type-file=C-HEADER-FILE` -- generate an `#include` directive to include
1015    that header for some useful base types (within Heimdal we use `krb5-types.h`
1016    as that header)
1018  - `--template` -- use the "template" (byte-coded) backend
1020  - `--one-code-file` -- causes all the code generated to be placed in one C
1021    source file (mutually exclusive with `--template`)
1023  - `--support-ber` -- accept non-DER BER when decoding
1025  - `--preserve-binary=TYPE` -- add a `_save` field to the C struct type for the
1026    ASN.1 `TYPE` where the decoder will save the original encoding of the value
1027    of `TYPE` it decodes (useful for cryptographic signature verification!)
1029  - `--sequence=TYPE` -- generate `add_TYPE()` and `remove_TYPE()` utility
1030    functions (`TYPE` must be a `SET OF` or `SEQUENCE OF` type)
1032  - `--decorate=DECORATION` -- add fields to generated C struct types as
1033    described in the `DECORATION` (see the
1034    [manual page](#Manual-Page-for-asn1_compile) below)
1036    Decoration fields are never encoded or decoded.  They are meant to be used
1037    for, e.g., application state keeping.
1039  - `--no-parse-units` -- normally the compiler generates code to use the
1040    Heimdal `libroken` "units" utility for displaying bit fields; this option
1041    disables this
1043 See the [manual page for `asn1_compile(1)`](#Manual-Page-for-asn1_compile) for
1044 a full listing of command-line options.
1046 ### Manual Page for `asn1_compile(1)`
1049 ASN1_COMPILE(1)           BSD General Commands Manual          ASN1_COMPILE(1)
1051 NAME
1052      asn1_compile — compile ASN.1 modules
1054 SYNOPSIS
1055      asn1_compile [--template] [--prefix-enum] [--enum-prefix=PREFIX]
1056                   [--encode-rfc1510-bit-string] [--decode-dce-ber]
1057                   [--support-ber] [--preserve-binary=TYPE] [--sequence=TYPE]
1058                   [--decorate=DECORATION] [--one-code-file] [--gen-name=NAME]
1059                   [--option-file=FILE] [--original-order] [--no-parse-units]
1060                   [--type-file=C-HEADER-FILE] [--version] [--help]
1061                   [FILE.asn1 [NAME]]
1063 DESCRIPTION
1064      asn1_compile compiles an ASN.1 module into C source code and header
1065      files.
1067      A fairly large subset of ASN.1 as specified in X.680, and the ASN.1 In‐
1068      formation Object System as specified in X.681, X.682, and X.683 is sup‐
1069      ported, with support for the Distinguished Encoding Rules (DER), partial
1070      Basic Encoding Rules (BER) support, and experimental JSON support (encod‐
1071      ing only at this time).
1073      See the compiler's README files for details about the C code and inter‐
1074      faces it generates.
1076      The Information Object System support includes automatic codec support
1077      for encoding and decoding through “open types” which are also known as
1078      “typed holes”.  See RFC 5912 for examples of how to use the ASN.1 Infor‐
1079      mation Object System via X.681/X.682/X.683 annotations.  See the com‐
1080      piler's README files for more information on ASN.1 Information Object
1081      System support.
1083      Extensions specific to Heimdal are generally not syntactic in nature but
1084      rather command-line options to this program.  For example, one can use
1085      command-line options to:
1086            •       enable decoding of BER-encoded values;
1087            •       enable RFC1510-style handling of ‘BIT STRING’ types;
1088            •       enable saving of as-received encodings of specific types
1089                    for the purpose of signature validation;
1090            •       generate add/remove utility functions for array types;
1091            •       decorate generated ‘struct’ types with fields that are nei‐
1092                    ther encoded nor decoded;
1093      etc.
1095      ASN.1 x.680 features supported:
1096            •       most primitive types (except BMPString and REAL);
1097            •       all constructed types, including SET and SET OF;
1098            •       explicit and implicit tagging.
1100      Size and range constraints on the ‘INTEGER’ type cause the compiler to
1101      generate appropriate C types such as ‘int’, ‘unsigned int’, ‘int64_t’,
1102      ‘uint64_t’.  Unconstrained ‘INTEGER’ is treated as ‘heim_integer’, which
1103      represents an integer of arbitrary size.
1105      Caveats and ASN.1 x.680 features not supported:
1106            •       JSON encoding support is not quite X.697 (JER) compatible.
1107                    Its JSON schema is subject to change without notice.
1108            •       Control over C types generated is very limited, mainly only
1109                    for integer types.
1110            •       When using the template backend, `SET { .. }` types are
1111                    currently not sorted by tag as they should be, but if the
1112                    module author sorts them by hand then correct DER will be
1113                    produced.
1114            •       ‘AUTOMATIC TAGS’ is not supported.
1115            •       The REAL type is not supported.
1116            •       The EmbeddedPDV type is not supported.
1117            •       The BMPString type is not supported.
1118            •       The IA5String is not properly supported, as it's essen‐
1119                    tially treated as a UTF8String with a different tag.
1120            •       All supported non-octet strings are treated as like the
1121                    UTF8String type.
1122            •       Only types can be imported into ASN.1 modules at this time.
1123            •       Only simple value syntax is supported.  Constructed value
1124                    syntax (i.e., values of SET, SEQUENCE, SET OF, and SEQUENCE
1125                    OF types), is not supported.  Values of `CHOICE` types are
1126                    also not supported.
1128      Options supported:
1130      --template
1131              Use the “template” backend instead of the “codegen” backend
1132              (which is the default backend).
1134              The template backend generates “templates” which are akin to
1135              bytecode, and which are interpreted at run-time.
1137              The codegen backend generates C code for all functions directly,
1138              with no template interpretation.
1140              The template backend scales better than the codegen backend be‐
1141              cause as we add support for more encoding rules and more opera‐
1142              tions (we may add value comparators) the templates stay mostly
1143              the same, thus scaling linearly with size of module.  Whereas the
1144              codegen backend scales linear with the product of module size and
1145              number of encoding rules supported.
1147      --prefix-enum
1148              This option should be removed because ENUMERATED types should al‐
1149              ways have their labels prefixed.
1151      --enum-prefix=PREFIX
1152              This option should be removed because ENUMERATED types should al‐
1153              ways have their labels prefixed.
1155      --encode-rfc1510-bit-string
1156              Use RFC1510, non-standard handling of “BIT STRING” types.
1158      --decode-dce-ber
1160      --support-ber
1162      --preserve-binary=TYPE
1163              Generate a field named ‘_save’ in the C struct generated for the
1164              named TYPE.  This field is used to preserve the original encoding
1165              of the value of the TYPE.
1167              This is useful for cryptographic applications so that they can
1168              check signatures of encoded values as-received without having to
1169              re-encode those values.
1171              For example, the TBSCertificate type should have values preserved
1172              so that Certificate validation can check the signatureValue over
1173              the tbsCertificate's value as-received.
1175              The alternative of encoding a value to check a signature of it is
1176              brittle.  For types where non-canonical encodings (such as BER)
1177              are allowed, this alternative is bound to fail.  Thus the point
1178              of this option.
1180      --sequence=TYPE
1181              Generate add/remove functions for the named ASN.1 TYPE which must
1182              be a ‘SET OF’ or ‘SEQUENCE OF’ type.
1184      --decorate=ASN1-TYPE:FIELD-ASN1-TYPE:fname[?]
1185              Add to the C struct generated for the given ASN.1 SET, SEQUENCE,
1186              or CHOICE type named ASN1-TYPE a “hidden” field named fname of
1187              the given ASN.1 type FIELD-ASN1-TYPE, but do not encode or decode
1188              it.  If the fname ends in a question mark, then treat the field
1189              as OPTIONAL.
1191              This is useful for adding fields to existing types that can be
1192              used for internal bookkeeping but which do not affect interoper‐
1193              ability because they are neither encoded nor decoded.  For exam‐
1194              ple, one might decorate a request type with state needed during
1195              processing of the request.
1197      --decorate=ASN1-TYPE:void*:fname
1198              Add to the C struct generated for the given ASN.1 SET, SEQUENCE,
1199              or CHOICE type named ASN1-TYPE a “hidden” field named fname of
1200              type ‘void *’ (but do not encode or decode it.
1202              The destructor and copy constructor functions generated by this
1203              compiler for ASN1-TYPE will set this field to the ‘NULL’ pointer.
1205      --decorate=ASN1-TYPE:FIELD-C-TYPE:fname[?]:[copyfn]:[freefn]:header
1206              Add to the C struct generated for the given ASN.1 SET, SEQUENCE,
1207              or CHOICE type named ASN1-TYPE a “hidden” field named fname of
1208              the given external C type FIELD-C-TYPE, declared in the given
1209              header but do not encode or decode this field.  If the fname ends
1210              in a question mark, then treat the field as OPTIONAL.
1212              The header must include double quotes or angle brackets.  The
1213              copyfn must be the name of a copy constructor function that takes
1214              a pointer to a source value of the type, and a pointer to a des‐
1215              tination value of the type, in that order, and which returns zero
1216              on success or else a system error code on failure.  The freefn
1217              must be the name of a destructor function that takes a pointer to
1218              a value of the type and which releases resources referenced by
1219              that value, but does not free the value itself (the run-time al‐
1220              locates this value as needed from the C heap).  The freefn should
1221              also reset the value to a pristine state (such as all zeros).
1223              If the copyfn and freefn are empty strings, then the decoration
1224              field will neither be copied nor freed by the functions generated
1225              for the TYPE.
1227      --one-code-file
1228              Generate a single source code file.  Otherwise a separate code
1229              file will be generated for every type.
1231      --gen-name=NAME
1232              Use NAME to form the names of the files generated.
1234      --option-file=FILE
1235              Take additional command-line options from FILE.
1237      --original-order
1238              Attempt to preserve the original order of type definition in the
1239              ASN.1 module.  By default the compiler generates types in a topo‐
1240              logical sort order.
1242      --no-parse-units
1243              Do not generate to-int / from-int functions for enumeration
1244              types.
1246      --type-file=C-HEADER-FILE
1247              Generate an include of the named header file that might be needed
1248              for common type defintions.
1250      --version
1252      --help
1254 NOTES
1255      Currently only the template backend supports automatic encoding and de‐
1256      coding of open types via the ASN.1 Information Object System and
1257      X.681/X.682/X.683 annotations.
1259 HEIMDAL                        February 22, 2021                       HEIMDAL
1262 # Future Directions
1264 The Heimdal ASN.1 compiler is focused on PKIX and Kerberos, and is almost
1265 feature-complete for dealing with those.  It could use additional support for
1266 X.681/X.682/X.683 elements that would allow the compiler to understand
1267 `Certificate ::= SIGNED{TBSCertificate}`, particularly the ability to
1268 automatically validate cryptographic algorithm parameters.  However, this is
1269 not that important.
1271 Another feature that might be nice is the ability of callers to specify smaller
1272 information object sets when decoding values of types like `Certificate`,
1273 mainly to avoid spending CPU cycles and memory allocations on decoding types in
1274 typed holes that are not of interest to the application.
1276 For testing purposes, a JSON reader to go with the JSON printer might be nice,
1277 and anyways, would make for a generally useful tool.
1279 Another feature that would be nice would to automatically generate SQL and LDAP
1280 code for HDB based on `lib/hdb/hdb.asn1` (with certain usage conventions and/or
1281 compiler command-line options to make it possible to map schemas usefully).
1283 For the `hxtool` command, it would be nice if the user could input arbitrary
1284 certificate extensions and `subjectAlternativeName` (SAN) values in JSON + an
1285 ASN.1 module and type reference that `hxtool` could then parse and encode using
1286 the ASN.1 compiler and library.  Currently the `hx509` library and its `hxtool`
1287 command must be taught about every SAN type.