s4:heimdal: import lorikeet-heimdal-202201172009 (commit 5a0b45cd723628b3690ea848548b...
[samba.git] / source4 / heimdal / lib / asn1 / README.md
1 # Heimdal's ASN.1 Compiler
2
3 This is a new README, and it's not very rich in contents yet.  Be sure to check
4 out the [README on the template backend](/lib/asn1/README-template.md) and the [README
5 on automatic open type decoding via X.681/X.682/X.683
6 annotations](/lib/asn1/README-X681.md).
7
8 ## Table of Contents
9
10  1. [Introduction](#Introduction)
11  2. [ASN.1 Support in Heimdal](#asn1-support-in-heimdal)
12  3. [News](#News)
13  4. [Features](#Features)
14  5. [Limitations](#Limitations)
15  6. [Compiler Usage](#Compiler-usage)
16  7. [APIs Generated by the Compiler](#APIs-generated-by-the-compiler)
17  8. [asn1_print Usage](#asn1_print-usage)
18  9. [Implementation](#implementation)
19  10. [Moving From C](#moving-from-c)
20
21 ## Introduction
22
23 ASN.1 is a... some would say baroque, perhaps obsolete, archaic even, "syntax"
24 for expressing data type schemas, and also a set of "encoding rules" (ERs) that
25 specify many ways to encode values of those types for interchange.
26
27 Some ERs are binary, others are textual.  Some binary ERs are tag-length-value
28 (TLV), others have no need for tagging.  Some of the ERs are roundly and
29 rightly disliked, but then there are XER (XML Encoding Rules) and JER (JSON
30 Encoding Rules) that really illustrate how the syntax and the encoding rules
31 really are separate and distinct things.
32
33 ASN.1 is a wheel that everyone loves to reinvent, and often badly.  It's worth
34 knowing a bit about it before reinventing this wheel badly yet again.
35
36 It's also worth pondering that there appears to be ways to map most data
37 exchange metaschemas and schemas onto others, and therefore too, transliterate
38 most encodings onto others.
39
40 First, an example of the syntax:
41
42 ```ASN.1
43 -- This is what a certificate looks like (as in TLS server certificates, or
44 -- "SSL certs):
45 Certificate  ::=  SEQUENCE  {
46      tbsCertificate       TBSCertificate,
47      signatureAlgorithm   AlgorithmIdentifier,
48      signatureValue       BIT STRING
49 }
50
51 -- The main body of a certificate is here though:
52 TBSCertificate  ::=  SEQUENCE  {
53      version         [0]  Version DEFAULT 1,
54      serialNumber         CertificateSerialNumber,
55      signature            AlgorithmIdentifier,
56      issuer               Name,
57      validity             Validity,
58      subject              Name,
59      subjectPublicKeyInfo SubjectPublicKeyInfo,
60      issuerUniqueID  [1]  IMPLICIT BIT STRING OPTIONAL,
61      subjectUniqueID [2]  IMPLICIT BIT STRING OPTIONAL,
62      extensions      [3]  EXPLICIT Extensions OPTIONAL
63 }
64 ```
65
66 Here we see something akin to a "structure" or "record" with various named
67 fields of various types.  Some of these are optional, which means they can have
68 no value given in encodings.  One is defaulted, which means that if no values
69 is given in encodings then the default value is intended.
70
71 Those `[0]` things are called tags and are decidedly obsolete, along with all
72 "tag-length-value" (TLV) or "self-describing" encoding rules.  Tags appear as
73 lexical tokens in ASN.1 only because a) in the early 80s TLV encodings were
74 thought fantastic, and b) automatic tagging wasn't invented and implemented
75 until it was too late.  New ASN.1 modules should never need to have those tags
76 appear in the syntax.
77
78 ASN.1 has a lot of competition, and may even be obsolete.  Obsolete
79 technologies take decades to die out because of the need to interoperate with
80 the installed base.  So even if ASN.1 is obsolete, we find ourselves needing to
81 implement a large subset of it in order to implement certain important network
82 protocols.
83
84 Encoding rules?  There are many:
85
86  - JSON Encoding Rules (JER) ([X.697](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.697))
87
88    Use JSON instead of some binary scheme like DER (see below).
89
90  - XML Encoding Rules (XER) ([X.693](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.693))
91
92  - Generic String Encoding Rules (GSER) ([RFC3641](https://tools.ietf.org/html/rfc3641))
93
94  - Basic, Distinguished, and Canonical Encoding Rules (BER, DER, CER) ([X.690](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.690)
95
96    These are the dreaded tag-length-value encoding rules.  They are redundant,
97    wasteful, and inefficient in spite of being non-textual (i.e., binary)!
98
99    The descriptor "tag-length-value" is due to all values being encoded as some
100    bytes for a "tag", then some bytes for the length of the encoded value, then
101    the encoded value itself.  The body of a structured type (e.g.,
102    `Certificate`) is itself a concatenation of the TLV encodings of the fields
103    of that structured type, in order.
104
105    DER and CER are alternative canonical forms of BER.
106
107  - Packed Encoding Rules (PER) ([X.691](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.691)) and Octet Encoding Rules (OER) ([X.696](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.696))
108
109    These are a lot like eXternal Data Representation
110    ([XDR](https://tools.ietf.org/html/rfc4506.html)), but with 1-octet
111    alignment instead of 4-octet alignment.
112
113 There is also a meta encoding rule system, the Encoding Control Notation (ECN)
114 ([X.692](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.692))
115 intended to be able to express all sorts of kinds of encodings.
116
117 Heimdal currently only supports DER for encoding, and DER and BER for decoding,
118 but soon may support JER as well, and can print values as JSON, though not
119 compliant with JER.
120
121 The syntax itself is specified by
122 [X.680](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.680),
123 with extensions via
124 [X.681](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.681),
125 [X.682](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.682),
126 and
127 [X.683](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.683),.
128
129 ## ASN.1 Support in Heimdal
130
131 Heimdal contains an implementation of:
132
133  - ASN.1
134  - PKIX
135  - Kerberos
136  - misc. Heimdal-specific protocols related to PKIX and Kerberos, such as:
137
138     - Online certification authority protocols
139     - Kerberos KDC replication protocols
140     - Kerberos administration protocols
141
142 PKIX and Kerberos both require ASN.1 and DER support.
143
144 For historical reasons many ASN.1-using projects have used hand-rolled codecs
145 that have proven difficult to implement, maintain, and extend, and, of course,
146 buggy.  Heimdal has its own ASN.1 module compiler and library in order to avoid
147 the pitfalls of hand-rolled codecs, and to satisfy Heimdal's internal needs.
148
149 There are other ASN.1 compilers and libraries out there, of course, but it
150 would prove difficult to switch compilers as generally ASN.1 compilers lack
151 sufficient control over generated types and APIs for programming languages.
152
153 Heimdal's ASN.1 compiler supports a large subset of X.680, X.681, X.682, and
154 X.683, as well as a large subset of X.690, with an architecture that should
155 make it easy to add support for encoding rules other than X.690.
156
157 ## News
158
159 In recent times the following features have been added:
160
161  - Feature parity for the "template" backend, even superiority, as the codegen
162    backend does not yet support automatic open type decoding/encoding.
163
164  - IMPLICIT tagging support is finally complete.
165
166  - Automatic open type traversal, using a subset of X.681/X.682/X.683 for
167    expressing the requisite metadata.
168
169 ## Futures
170
171  - JER support?
172
173  - XDR/OER support?
174
175  - Generate comparators?  (lib/hx509 has a half-baked Certificate comparator)
176
177 ## Features
178
179  - Most of X.680 is supported.
180
181  - Most of X.690 is supported for decoding, with only DER supported for
182    encoding.
183
184  - We have an `asn1_print` program that can decode DER from any exported types
185    from any ASN.1 modules committed in Heimdal:
186
187    ```bash
188    $ ./asn1_print ek.crt Certificate |
189      jq '.tbsCertificate.extensions[3]._extnValue[]._values'
190    ```
191
192    ```JSON
193    [
194      {
195        "_type": "TPMSpecification",
196        "family": "2.0",
197        "level": 0,
198        "revision": 138
199      }
200    ]
201    [
202      {
203        "_type": "TPMSecurityAssertions",
204        "version": 0,
205        "fieldUpgradable": true,
206        "ekGenerationType": "ekgt-injected",
207        "ekGenerationLocation": "tpmManufacturer",
208        "ekCertificateGenerationLocation": "tpmManufacturer",
209        "ccInfo": {
210          "_type": "CommonCriteriaMeasures",
211          "version": "3.1",
212          "assurancelevel": "ealevel4",
213          "evaluationStatus": "evaluationCompleted",
214          "plus": true,
215          "strengthOfFunction": null,
216          "profileOid": null,
217          "profileUri": null,
218          "targetOid": null,
219          "targetUri": null
220        },
221        "fipsLevel": {
222          "_type": "FIPSLevel",
223          "version": "140-2",
224          "level": "sllevel2",
225          "plus": false
226        },
227        "iso9000Certified": false,
228        "iso9000Uri": null
229      }
230    ]
231    ```
232
233    A complete dump of such a certificate:
234
235    ```bash
236    $ ./asn1_print ek.crt Certificate | jq .
237    ```
238
239    ```JSON
240    {
241      "_type": "Certificate",
242      "tbsCertificate": {
243        "_type": "TBSCertificate",
244        "_save": "30820376A00302010202146A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A300D06092A864886F70D01010B05003055310B3009060355040613024348311E301C060355040A131553544D6963726F656C656374726F6E696373204E56312630240603550403131D53544D2054504D20454B20496E7465726D656469617465204341203035301E170D3138313231343030303030305A170D3238313231343030303030305A300030820122300D06092A864886F70D01010105000382010F003082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001A38201A9308201A5301F0603551D230418301680141ADB994AB58BE57A0CC9B900E7851E1A43C0866030420603551D20043B303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F30590603551D110101FF044F304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A303034393030303830670603551D090460305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100300E0603551D0F0101FF040403020520300C0603551D130101FF0402300030100603551D250409300706056781050801304A06082B06010505070101043E303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274",
245        "version": "rfc3280_version_3",
246        "serialNumber": "6A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A",
247        "signature": {
248          "_type": "AlgorithmIdentifier",
249          "algorithm": {
250            "_type": "OBJECT IDENTIFIER",
251            "oid": "1.2.840.113549.1.1.11",
252            "components": [
253              1,
254              2,
255              840,
256              113549,
257              1,
258              1,
259              11
260            ],
261            "name": "id-pkcs1-sha256WithRSAEncryption"
262          },
263          "parameters": "0500"
264        },
265        "issuer": {
266          "_choice": "rdnSequence",
267          "value": [
268            [
269              {
270                "_type": "AttributeTypeAndValue",
271                "type": {
272                  "_type": "OBJECT IDENTIFIER",
273                  "oid": "2.5.4.6",
274                  "components": [
275                    2,
276                    5,
277                    4,
278                    6
279                  ],
280                  "name": "id-at-countryName"
281                },
282                "value": {
283                  "_choice": "printableString",
284                  "value": "CH"
285                }
286              }
287            ],
288            [
289              {
290                "_type": "AttributeTypeAndValue",
291                "type": {
292                  "_type": "OBJECT IDENTIFIER",
293                  "oid": "2.5.4.10",
294                  "components": [
295                    2,
296                    5,
297                    4,
298                    10
299                  ],
300                  "name": "id-at-organizationName"
301                },
302                "value": {
303                  "_choice": "printableString",
304                  "value": "STMicroelectronics NV"
305                }
306              }
307            ],
308            [
309              {
310                "_type": "AttributeTypeAndValue",
311                "type": {
312                  "_type": "OBJECT IDENTIFIER",
313                  "oid": "2.5.4.3",
314                  "components": [
315                    2,
316                    5,
317                    4,
318                    3
319                  ],
320                  "name": "id-at-commonName"
321                },
322                "value": {
323                  "_choice": "printableString",
324                  "value": "STM TPM EK Intermediate CA 05"
325                }
326              }
327            ]
328          ]
329        },
330        "validity": {
331          "_type": "Validity",
332          "notBefore": {
333            "_choice": "utcTime",
334            "value": "2018-12-14T00:00:00Z"
335          },
336          "notAfter": {
337            "_choice": "utcTime",
338            "value": "2028-12-14T00:00:00Z"
339          }
340        },
341        "subject": {
342          "_choice": "rdnSequence",
343          "value": []
344        },
345        "subjectPublicKeyInfo": {
346          "_type": "SubjectPublicKeyInfo",
347          "algorithm": {
348            "_type": "AlgorithmIdentifier",
349            "algorithm": {
350              "_type": "OBJECT IDENTIFIER",
351              "oid": "1.2.840.113549.1.1.1",
352              "components": [
353                1,
354                2,
355                840,
356                113549,
357                1,
358                1,
359                1
360              ],
361              "name": "id-pkcs1-rsaEncryption"
362            },
363            "parameters": "0500"
364          },
365          "subjectPublicKey": "2160:3082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001"
366        },
367        "issuerUniqueID": null,
368        "subjectUniqueID": null,
369        "extensions": [
370          {
371            "_type": "Extension",
372            "extnID": {
373              "_type": "OBJECT IDENTIFIER",
374              "oid": "2.5.29.35",
375              "components": [
376                2,
377                5,
378                29,
379                35
380              ],
381              "name": "id-x509-ce-authorityKeyIdentifier"
382            },
383            "critical": false,
384            "extnValue": "301680141ADB994AB58BE57A0CC9B900E7851E1A43C08660",
385            "_extnValue_choice": "ext-AuthorityKeyIdentifier",
386            "_extnValue": {
387              "_type": "AuthorityKeyIdentifier",
388              "keyIdentifier": "1ADB994AB58BE57A0CC9B900E7851E1A43C08660",
389              "authorityCertIssuer": null,
390              "authorityCertSerialNumber": null
391            }
392          },
393          {
394            "_type": "Extension",
395            "extnID": {
396              "_type": "OBJECT IDENTIFIER",
397              "oid": "2.5.29.32",
398              "components": [
399                2,
400                5,
401                29,
402                32
403              ],
404              "name": "id-x509-ce-certificatePolicies"
405            },
406            "critical": false,
407            "extnValue": "303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F",
408            "_extnValue_choice": "ext-CertificatePolicies",
409            "_extnValue": [
410              {
411                "_type": "PolicyInformation",
412                "policyIdentifier": {
413                  "_type": "OBJECT IDENTIFIER",
414                  "oid": "2.5.29.32.0",
415                  "components": [
416                    2,
417                    5,
418                    29,
419                    32,
420                    0
421                  ],
422                  "name": "id-x509-ce-certificatePolicies-anyPolicy"
423                },
424                "policyQualifiers": [
425                  {
426                    "_type": "PolicyQualifierInfo",
427                    "policyQualifierId": {
428                      "_type": "OBJECT IDENTIFIER",
429                      "oid": "1.3.6.1.5.5.7.2.1",
430                      "components": [
431                        1,
432                        3,
433                        6,
434                        1,
435                        5,
436                        5,
437                        7,
438                        2,
439                        1
440                      ],
441                      "name": "id-pkix-qt-cps"
442                    },
443                    "qualifier": "1621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F"
444                  }
445                ]
446              }
447            ]
448          },
449          {
450            "_type": "Extension",
451            "extnID": {
452              "_type": "OBJECT IDENTIFIER",
453              "oid": "2.5.29.17",
454              "components": [
455                2,
456                5,
457                29,
458                17
459              ],
460              "name": "id-x509-ce-subjectAltName"
461            },
462            "critical": true,
463            "extnValue": "304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A3030343930303038",
464            "_extnValue_choice": "ext-SubjectAltName",
465            "_extnValue": [
466              {
467                "_choice": "directoryName",
468                "value": {
469                  "_choice": "rdnSequence",
470                  "value": [
471                    [
472                      {
473                        "_type": "AttributeTypeAndValue",
474                        "type": {
475                          "_type": "OBJECT IDENTIFIER",
476                          "oid": "2.23.133.2.1",
477                          "components": [
478                            2,
479                            23,
480                            133,
481                            2,
482                            1
483                          ],
484                          "name": "tcg-at-tpmManufacturer"
485                        },
486                        "value": {
487                          "_choice": "utf8String",
488                          "value": "id:53544D20"
489                        }
490                      }
491                    ],
492                    [
493                      {
494                        "_type": "AttributeTypeAndValue",
495                        "type": {
496                          "_type": "OBJECT IDENTIFIER",
497                          "oid": "2.23.133.2.2",
498                          "components": [
499                            2,
500                            23,
501                            133,
502                            2,
503                            2
504                          ],
505                          "name": "tcg-at-tpmModel"
506                        },
507                        "value": {
508                          "_choice": "utf8String",
509                          "value": "ST33HTPHAHC0"
510                        }
511                      }
512                    ],
513                    [
514                      {
515                        "_type": "AttributeTypeAndValue",
516                        "type": {
517                          "_type": "OBJECT IDENTIFIER",
518                          "oid": "2.23.133.2.3",
519                          "components": [
520                            2,
521                            23,
522                            133,
523                            2,
524                            3
525                          ],
526                          "name": "tcg-at-tpmVersion"
527                        },
528                        "value": {
529                          "_choice": "utf8String",
530                          "value": "id:00490008"
531                        }
532                      }
533                    ]
534                  ]
535                }
536              }
537            ]
538          },
539          {
540            "_type": "Extension",
541            "extnID": {
542              "_type": "OBJECT IDENTIFIER",
543              "oid": "2.5.29.9",
544              "components": [
545                2,
546                5,
547                29,
548                9
549              ],
550              "name": "id-x509-ce-subjectDirectoryAttributes"
551            },
552            "critical": false,
553            "extnValue": "305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100",
554            "_extnValue_choice": "ext-SubjectDirectoryAttributes",
555            "_extnValue": [
556              {
557                "_type": "AttributeSet",
558                "type": {
559                  "_type": "OBJECT IDENTIFIER",
560                  "oid": "2.23.133.2.16",
561                  "components": [
562                    2,
563                    23,
564                    133,
565                    2,
566                    16
567                  ],
568                  "name": "tcg-at-tpmSpecification"
569                },
570                "values": [
571                  "300C0C03322E300201000202008A"
572                ],
573                "_values_choice": "at-TPMSpecification",
574                "_values": [
575                  {
576                    "_type": "TPMSpecification",
577                    "family": "2.0",
578                    "level": 0,
579                    "revision": 138
580                  }
581                ]
582              },
583              {
584                "_type": "AttributeSet",
585                "type": {
586                  "_type": "OBJECT IDENTIFIER",
587                  "oid": "2.23.133.2.18",
588                  "components": [
589                    2,
590                    23,
591                    133,
592                    2,
593                    18
594                  ],
595                  "name": "tcg-at-tpmSecurityAssertions"
596                },
597                "values": [
598                  "30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100"
599                ],
600                "_values_choice": "at-TPMSecurityAssertions",
601                "_values": [
602                  {
603                    "_type": "TPMSecurityAssertions",
604                    "version": 0,
605                    "fieldUpgradable": true,
606                    "ekGenerationType": "ekgt-injected",
607                    "ekGenerationLocation": "tpmManufacturer",
608                    "ekCertificateGenerationLocation": "tpmManufacturer",
609                    "ccInfo": {
610                      "_type": "CommonCriteriaMeasures",
611                      "version": "3.1",
612                      "assurancelevel": "ealevel4",
613                      "evaluationStatus": "evaluationCompleted",
614                      "plus": true,
615                      "strengthOfFunction": null,
616                      "profileOid": null,
617                      "profileUri": null,
618                      "targetOid": null,
619                      "targetUri": null
620                    },
621                    "fipsLevel": {
622                      "_type": "FIPSLevel",
623                      "version": "140-2",
624                      "level": "sllevel2",
625                      "plus": false
626                    },
627                    "iso9000Certified": false,
628                    "iso9000Uri": null
629                  }
630                ]
631              }
632            ]
633          },
634          {
635            "_type": "Extension",
636            "extnID": {
637              "_type": "OBJECT IDENTIFIER",
638              "oid": "2.5.29.15",
639              "components": [
640                2,
641                5,
642                29,
643                15
644              ],
645              "name": "id-x509-ce-keyUsage"
646            },
647            "critical": true,
648            "extnValue": "03020520",
649            "_extnValue_choice": "ext-KeyUsage",
650            "_extnValue": [
651              "keyEncipherment"
652            ]
653          },
654          {
655            "_type": "Extension",
656            "extnID": {
657              "_type": "OBJECT IDENTIFIER",
658              "oid": "2.5.29.19",
659              "components": [
660                2,
661                5,
662                29,
663                19
664              ],
665              "name": "id-x509-ce-basicConstraints"
666            },
667            "critical": true,
668            "extnValue": "3000",
669            "_extnValue_choice": "ext-BasicConstraints",
670            "_extnValue": {
671              "_type": "BasicConstraints",
672              "cA": false,
673              "pathLenConstraint": null
674            }
675          },
676          {
677            "_type": "Extension",
678            "extnID": {
679              "_type": "OBJECT IDENTIFIER",
680              "oid": "2.5.29.37",
681              "components": [
682                2,
683                5,
684                29,
685                37
686              ],
687              "name": "id-x509-ce-extKeyUsage"
688            },
689            "critical": false,
690            "extnValue": "300706056781050801",
691            "_extnValue_choice": "ext-ExtKeyUsage",
692            "_extnValue": [
693              {
694                "_type": "OBJECT IDENTIFIER",
695                "oid": "2.23.133.8.1",
696                "components": [
697                  2,
698                  23,
699                  133,
700                  8,
701                  1
702                ],
703                "name": "tcg-kp-EKCertificate"
704              }
705            ]
706          },
707          {
708            "_type": "Extension",
709            "extnID": {
710              "_type": "OBJECT IDENTIFIER",
711              "oid": "1.3.6.1.5.5.7.1.1",
712              "components": [
713                1,
714                3,
715                6,
716                1,
717                5,
718                5,
719                7,
720                1,
721                1
722              ],
723              "name": "id-pkix-pe-authorityInfoAccess"
724            },
725            "critical": false,
726            "extnValue": "303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274",
727            "_extnValue_choice": "ext-AuthorityInfoAccess",
728            "_extnValue": [
729              {
730                "_type": "AccessDescription",
731                "accessMethod": {
732                  "_type": "OBJECT IDENTIFIER",
733                  "oid": "1.3.6.1.5.5.7.48.2",
734                  "components": [
735                    1,
736                    3,
737                    6,
738                    1,
739                    5,
740                    5,
741                    7,
742                    48,
743                    2
744                  ],
745                  "name": "id-pkix-ad-caIssuers"
746                },
747                "accessLocation": {
748                  "_choice": "uniformResourceIdentifier",
749                  "value": "http://secure.globalsign.com/stmtpmekint05.crt"
750                }
751              }
752            ]
753          }
754        ]
755      },
756      "signatureAlgorithm": {
757        "_type": "AlgorithmIdentifier",
758        "algorithm": {
759          "_type": "OBJECT IDENTIFIER",
760          "oid": "1.2.840.113549.1.1.11",
761          "components": [
762            1,
763            2,
764            840,
765            113549,
766            1,
767            1,
768            11
769          ],
770          "name": "id-pkcs1-sha256WithRSAEncryption"
771        },
772        "parameters": "0500"
773      },
774      "signatureValue": "2048:3D4C381E5B4F1BCBE09C63D52F1F04570CAEA142FD9CD942043B11F8E3BDCF50007AE16CF8869013041E92CDD3280BA4B51FBBD40582ED750219E261A695095674855AACEB520ADAFF9E7E908480A39CDCF900462D9171960FFE55D3AC49E8C981341BBD2EFBCC252A4C18A4F3B7C84CCE42CE70A208C84D2630A7ABFBE72D6271E75B9FF1C971D20EB3DBD763F1E04D834EAA692D2E4001BBF4730A3E3FDA9711AE386524D91C63BE0E516D00D5C6141FCCF6C539F3518E180049865BE16B69CAE1F8CB7FDC474B38F7EE56CBE7D8A89D9BA99B65D5265AEF32AA62426B10E6D75BB8677EC44F755BBC2806FD2B4E04BDF5D44259DBEAA42B6F563DF7AA7506"
775    }
776    ```
777
778    (Notice that OID names look a bit weird.  For reasons that may have been
779    lost to time and may no longer be relevant, these OIDs are defined with
780    slightly different names in the ASN.1 modules in Heimdal's source tree.
781    We'll fix this eventually.)
782
783  - Unconstrained integer types have a large integer representation in C that is
784    not terribly useful in common cases.  Range constraints on integer types
785    cause the compiler to use `int32_t`, `int64_t`, `uint32_t`, and/or
786    `uint64_t`.
787
788  - The Heimdal ASN.1 compiler currently handles a large subset of X.680, and
789    (in a branch) a small subset of X.681, X.682, and X.683, which manifests as
790    automatic handling of all open types contained in `SET`/`SEQUENCE` types
791    that are parameterized with information object sets.  This allows all open
792    types in PKIX certificates, for example, to get decoded automatically no
793    matter how deeply nested.  We use a TCG EK certificate that has eight
794    certificate extensions, including subject alternative names and subject
795    directory attributes where the attribute values are not string types, and
796    all of these things get decoded automatically.
797
798  - The template backend dedups templates to save space.  This is an O(N^2) kind
799    of feature that we need to make optional, but it works.  (When we implement
800    JER this will have the side-effect of printing the wrong type names in some
801    cases because two or more types have the same templates and get deduped.)
802
803  - There is an _experimental_ ASN.1 -> JSON feature in the compiler.  It
804    currently dumps type and value definitions, but not class, or object set
805    definitions.  Even for types, it is not complete, and the JSON schema used
806    is subject to change *WITHOUT NOTICE*.
807
808    Perhaps eventually we can re-write the compiler as a C-coded ASN.1 -> JSON
809    stage followed by a jq-coded code and template generator state, which would
810    make it much easier to extend the compiler.
811
812 ...
813
814 ## Limitations
815
816  - `asn1_print`'s JSON support is not X.697 (JER) compatible.
817
818  - Control over C types generated is very limited, mainly only for integer
819    types.
820
821  - When using the template backend, `SET { .. }` types are currently not sorted
822    by tag as they should be, but if the module author sorts them by hand then
823    DER will be produced.
824
825  - `REAL` is not supported.
826
827  - `EmbeddedPDV` is not supported.
828
829  - `BMPString` is not supported.
830
831  - IA5String is not properly supported -- it's essentially treated as a
832    `UTF8String` with a different tag.  This is true of all the string types.
833
834  - Only types can be imported at this time.  Without some rototilling we likely
835    will not be able to import anything other than types, values, and object
836    sets.
837
838  - Only simple value syntax is supported.  Constructed value syntax (i.e.,
839    values of `SET`, `SEQUENCE`, `SET OF`, and `SEQUENCE OF`), is not supported.
840    Values of `CHOICE` types are also not supported.
841
842  - ...
843
844 ## Compiler Usage
845
846 The various options for the Heimdal ASN.1 compiler are described in its manual
847 page, which is included below.
848
849 The `--option-file=FILE` option is particularly useful, as it allows additional
850 compiler options to be read from a file.
851
852 The `--preserve-binary=TYPE-NAME` option is critical for signature validation
853 as it causes the decoder to save the encoding of the given type so that
854 signature validation code can easily find the original encoding and thus avoid
855 having to re-encode or resort to other hacks.  E.g., we use this for preserving
856 the original encoding of the `tbsCertificate` field of `Certificate`.
857
858 The `--sequence=TYPE-NAME` causes the compiler to generate additional utility
859 functions for adding or removing items from the named type when it is a
860 `SEQUENCE OF` or `SET OF` type.
861
862 See the manual page `asn1_compile.1`:
863
864 ```
865 ASN1_COMPILE(1)       HEIMDAL General Commands Manual          ASN1_COMPILE(1)
866
867 NAME
868      asn1_compile — compile ASN.1 modules
869
870 SYNOPSIS
871      asn1_compile [--template] [--prefix-enum] [--enum-prefix=PREFIX]
872                   [--encode-rfc1510-bit-string] [--decode-dce-ber]
873                   [--support-ber] [--preserve-binary=TYPE-NAME]
874                   [--sequence=TYPE-NAME] [--one-code-file] [--gen-name=NAME]
875                   [--decorate=TYPE-NAME:FIELD-TYPE:field-name[?]]
876                   [--option-file=FILE] [--original-order] [--no-parse-units]
877                   [--type-file=C-HEADER-FILE] [--version] [--help]
878                   [FILE.asn1 [NAME]]
879
880 DESCRIPTION
881      asn1_compile Compiles an ASN.1 module into C source code and header
882      files.
883
884      Options supported:
885
886      --template
887              Use the “template” backend instead of the “codegen” backend
888              (which is the default backend).  The template backend generates
889              “templates” which are akin to bytecode, and which are interpreted
890              at run-time.  The codegen backend generates C code for all func-
891              tions directly, with no template interpretation.  The template
892              backend scales better than the codegen backend because as we add
893              support for more encoding rules the templates stay mostly the
894              same, thus scaling linearly with size of module.  Whereas the
895              codegen backend scales linear with the product of module size and
896              number of encoding rules supported.  More importantly, currently
897              only the template backend supports automatic decoding of open
898              types via X.681/X.682/X.683 annotations.
899
900      --prefix-enum
901              This option should be removed because ENUMERATED types should
902              always have their labels prefixed.
903
904      --enum-prefix=PREFIX
905              This option should be removed because ENUMERATED types should
906              always have their labels prefixed.
907
908      --encode-rfc1510-bit-string
909              Use RFC1510, non-standard handling of “BIT STRING” types.
910
911      --decode-dce-ber
912      --support-ber
913
914      --preserve-binary=TYPE-NAME
915              Generate ‘_save’ fields in structs to preserve the original
916              encoding of some sub-value.  This is useful for cryptographic
917              applications to avoid having to re-encode values to check signa-
918              tures, etc.
919
920      --sequence=TYPE-NAME
921              Generate add/remove functions for ‘SET OF’ and ‘SEQUENCE OF’
922              types.
923
924      --decorate=TYPE-NAME:FIELD-TYPE:field-name[?]
925              Add to the TYPE-NAME SET or SEQUENCE type a field of the given
926              FIELD-TYPE and field-name, but do not encode or decode this
927              field.  If the field-name ends in a question mark, then treat the
928              field as OPTIONAL for the purposes of copy/free function stubs.
929              This is useful for adding fields to existing types that can be
930              used for internal bookkeeping but which do not affect interoper-
931              ability because they are not encoded.
932
933      --one-code-file
934              Generate a single source code file.  Otherwise a separate code
935              file will be generated for every type.
936
937      --gen-name=NAME
938              Use NAME to form the names of the files generated.
939
940      --option-file=FILE
941              Take additional command-line options from FILE.
942
943      --original-order
944              Attempt to preserve the original order of type definition in the
945              ASN.1 module.  By default the compiler generates types in a topo-
946              logical sort order.
947
948      --no-parse-units
949              Do not generate to-int / from-int functions for enumeration
950              types.
951
952      --type-file=C-HEADER-FILE
953              Generate an include of the named header file that might be needed
954              for common type defintions.
955
956      --version
957
958      --help
959
960 HEIMDAL                        February 22, 2021                       HEIMDAL
961
962 ```
963
964 ## APIs Generated by the Compiler
965
966 Every named type in an ASN.1 module gets a corresponding type in C.
967 Em-dashes in symbols become underscores.
968
969 Every named type in an ASN.1 module also gets several functions generated
970 associated with it:
971
972  - `int decode_TypeName(const unsigned char *, size_t, TypeName *, size_t *);`
973
974    Decodes a value of `TypeName` in the given byte array of the given size,
975    into the given `TypeName` object, and outputs the number of bytes parsed.
976
977    Returns 0 on success, or an error that can be formatted as a string using
978    the `com_err` library.
979
980  - `int encode_TypeName(unsigned char *, size_t, const TypeName *, size_t *);`
981
982    Encodes the given object of `TypeName` type into the given byte array of the
983    given size, outputting the number of bytes used.
984
985    NOTE WELL: the `unsigned char *` pointer must point to the _last_ byte of
986    the buffer!
987
988    Returns 0 on success, or an error that can be formatted as a string using
989    the `com_err` library, including system errors such as `ENOMEM`.
990
991  - `int length_TypeName(const TypeName *);`
992
993    Returns the number of bytes needed to encode the given object.
994
995  - `void free_TypeName(TypeName *);`
996
997    Releases the memory associated with the content of the given object, but
998    note that the object itself is _not_ released.
999
1000  - `int copy_TypeName(const TypeName *, TypeName *);`
1001
1002    Copies the content of the given `const` object to the destination,
1003    non-`const` object.
1004
1005    Returns 0 on success, or an error that can be formatted as a string using
1006    the `com_err` library, including system errors such as `ENOMEM`.
1007
1008  - `char *print_TypeName(const TypeName *, int);`
1009
1010    Returns a string (JSON) representation of the given object.  The `int`
1011    argument is a bitset of flags:
1012
1013     - `ASN1_PRINT_INDENT`
1014
1015       Indent the JSON.  If not given the the JSON will have no interstitial
1016       whitespace, including newlines.
1017
1018 You will want to review the data structures generated.  They look like:
1019
1020 ```C
1021     typedef struct TBSCertificate TBSCertificate;
1022     typedef struct AlgorithmIdentifier AlgorithmIdentifier;
1023     typedef struct ... ...;
1024
1025     /*
1026     Certificate ::= SEQUENCE {
1027       tbsCertificate       TBSCertificate,
1028       signatureAlgorithm   AlgorithmIdentifier,
1029       signatureValue         BIT STRING {
1030       },
1031     }
1032     */
1033
1034     typedef struct Certificate {
1035       TBSCertificate tbsCertificate;
1036       AlgorithmIdentifier signatureAlgorithm;
1037       heim_bit_string signatureValue;
1038     } Certificate;
1039
1040     /*
1041     TBSCertificate ::= SEQUENCE {
1042       version                [0] Version OPTIONAL,
1043       serialNumber           CertificateSerialNumber,
1044       signature              AlgorithmIdentifier,
1045       issuer                 Name,
1046       validity               Validity,
1047       subject                Name,
1048       subjectPublicKeyInfo   SubjectPublicKeyInfo,
1049       issuerUniqueID         [1] IMPLICIT   BIT STRING {
1050       } OPTIONAL,
1051       subjectUniqueID        [2] IMPLICIT   BIT STRING {
1052       } OPTIONAL,
1053       extensions             [3] Extensions OPTIONAL,
1054     }
1055     */
1056
1057     typedef struct TBSCertificate {
1058       heim_octet_string _save;
1059       Version *version;
1060       CertificateSerialNumber serialNumber;
1061       AlgorithmIdentifier signature;
1062       Name issuer;
1063       Validity validity;
1064       Name subject;
1065       SubjectPublicKeyInfo subjectPublicKeyInfo;
1066       heim_bit_string *issuerUniqueID;
1067       heim_bit_string *subjectUniqueID;
1068       Extensions *extensions;
1069     } TBSCertificate;
1070 ```
1071
1072 Note how trivial the mapping onto C is.
1073
1074 `OPTIONAL` fields become pointer fields, with `NULL` indicating
1075 absence and non-NULL indicating presence.
1076
1077 And so on.
1078
1079 ## asn1_print Usage
1080
1081 ```
1082 ASN1_PRINT(1)             BSD General Commands Manual            ASN1_PRINT(1)
1083
1084 NAME
1085      asn1_print — dump ASN.1 DER encoded values
1086
1087 SYNOPSIS
1088      asn1_print [-i | --no-indent] [-I | --inner] [-l | --list-types]
1089                 [-A | --try-all-types] [-S | --raw-sequence] [-n | --no-print]
1090                 [-q | --quiet] [--test-encode] [--test-copy]
1091                 [-l -v | --version] [-l -h | --help] [FILE [TypeName...]]
1092
1093 DESCRIPTION
1094      asn1_print Dumps ASN.1 DER-encoded values.  If one or more TypeName argu-
1095      ments are given, then asn1_print will print the value in a JSON-like for-
1096      mat using its knowledge of the ASN.1 modules defining those types, stop-
1097      ping at the first type for which it can successfully decode the value.
1098      If TypeNames are given, they must be the names of ASN.1 types exported by
1099      an ASN.1 modules that are compiled into asn1_print.  Use the
1100      --try-all-types option to attempt decoding as all ASN.1 types known to
1101      asn1_print.  If neither any TypeName nor --try-all-types are given, then
1102      the value will be parsed and displayed using just the self-describing
1103      nature of DER.
1104
1105      Options supported:
1106
1107      -i, --no-indent
1108              Do not indent dump.
1109
1110      -I, --inner
1111              Try to parse inner structures of OCTET STRING and constructed
1112              values.
1113
1114      -l, --list-types
1115              List all types known to asn1_print.
1116
1117      -A, --try-all-types
1118              Attempt to decode the value as any of all types known to
1119              asn1_print.
1120
1121      -S, --raw-sequence
1122              If a value parses as a given TypeName but any bytes are left
1123              over, try to parse those separately as well until all bytes are
1124              consumed or an error occurs.
1125
1126      -n, --no-print
1127              For the case where -A or --try-all-types or where a TypeName is
1128              given, do not output a JSON representation of the value, just
1129              attempt to decode it.  This is useful for fuzzing.
1130
1131      -q, --quiet
1132              Similar to -n, --no-print but JSON output will be formatted, just
1133              not output.  As with -n, --no-print, this option requires -A -/
1134              --try-all-types or that a TypeName be given.  This is useful for
1135              fuzzing.
1136
1137      --test-encode
1138              Check that encoding produces the same value as decoding.  Useful
1139              for fuzzing.
1140
1141      --test-copy
1142              Test copy functions.  Useful for fuzzing.
1143
1144      -v, --version
1145
1146      -h, --help
1147
1148 HEIMDAL                        February 22, 2021                       HEIMDAL
1149 ```
1150
1151 ## Implementation
1152
1153 See:
1154
1155  - `lib/asn1/main.c` for the `main()` function of the compiler
1156  - `lib/asn1/asn1parse.y` for the grammar and most of the parsing into an AST
1157  - `lib/asn1/symbol.h` for the types making up the AST
1158  - `lib/asn1/{hash,symbol}.c` for compiler AST supporting functionality
1159  - `lib/asn1/gen.c` for the C header file generator
1160  - `lib/asn1/gen_template.c` for the template generator
1161  - `lib/asn1/gen_{decode,encode,length,copy,free}.c` for the C code generator
1162  - `lib/asn1/gen_{glue,seq}.c` for misc code generator
1163  - `lib/asn1/template.c` for the template interpreter
1164  - `lib/asn1/der*.c` for primitive type primitives
1165  - `lib/asn1/extra.c` for primitives related to `ANY`
1166
1167 ...
1168
1169 ## Futures
1170
1171  - Add JER support so we can convert between JER and DER?
1172
1173  - Add XDR support?
1174
1175  - Add OER support?
1176
1177  - Add NDR support?
1178
1179  - Perhaps third parties will contribute more control over generate types?
1180
1181 ## Moving From C
1182
1183  - Generate and output a JSON representation of the compiled ASN.1 module.
1184
1185  - Code codegen/templategen backends in jq or Haskell or whatever.
1186
1187  - Code template interpreters in some host language.
1188
1189  - Eventually rewrite the compiler itself in Rust or whatever.