asn1: Update README-X681.md
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
Bringing the power of X.682 (ASN.1 Information Object System) to Heimdal
|
Bringing the Magical Power of X.681 (ASN.1 Information Object System) to Heimdal
|
||||||
========================================================================
|
================================================================================
|
||||||
|
|
||||||
The base of ASN.1 is specified by X.680, an ITU-T standard.
|
The base of ASN.1 is specified by X.680, an ITU-T standard.
|
||||||
|
|
||||||
@@ -11,21 +11,34 @@ Various extensions are specified in other X.680 series documents:
|
|||||||
|
|
||||||
While X.680 is essential for implementing many Internet (and other) protocols,
|
While X.680 is essential for implementing many Internet (and other) protocols,
|
||||||
implementing a subset of X.681, X.682, and X.683, can enable some magical
|
implementing a subset of X.681, X.682, and X.683, can enable some magical
|
||||||
features.
|
features. These magical features are generally not the focus of those ITU-T
|
||||||
|
specifications nor of many RFCs that make use of them.
|
||||||
|
|
||||||
This README will cover some ideas for implementation and why we should want
|
The intent of X.681, X.682, and X.683 is to add ways to formally express
|
||||||
this. This is also covered extensively in RFC 6025, in section 2.1.3.
|
constraints that would otherwise require natural language to express. But give
|
||||||
|
a compiler more formally-expressed constraints and it can do more labor-saving
|
||||||
|
than it could otherwise.
|
||||||
|
|
||||||
|
This README will cover some ideas for what this magic will be, and
|
||||||
|
implementation of it.
|
||||||
|
|
||||||
RFC 6025 does an excellent job of elucidating X.681, which otherwise most
|
RFC 6025 does an excellent job of elucidating X.681, which otherwise most
|
||||||
readers unfamiliar with it will no doubt find inscrutable.
|
readers unfamiliar with it will no doubt find inscrutable.
|
||||||
|
|
||||||
This README should explain the magic that we're after:
|
The magic that we're after is simply the *automatic and recursive handling of
|
||||||
|
open types by the Heimdal ASN.1 compiler*.
|
||||||
|
|
||||||
Automatic handling of open types by the Heimdal ASN.1 compiler, which,
|
Combined with adding support for the ASN.1 JSON Encoding Rules (JER) [X.697],
|
||||||
combined with an implementation of the ASN.1 JSON Encoding Rules (JER
|
the automatic handling of open types should allow us to trivially implement a
|
||||||
[X.697]), should allow one to build a trivial command-line tool and APIs to
|
command-line tool that can parse any DER or JER (JSON) encoding of any value
|
||||||
dump as JSON, or parse from JSON, the DER encoding of random PDU types from
|
whose type is known and compiled, and which could transcode to the other
|
||||||
random ASN.1 modules, with deep traversal of open types / typed holes.
|
encoding rules. I.e., dump DER to JSON, and parse JSON to output DER.
|
||||||
|
|
||||||
|
We especially want this for PKIX, and more than anything for Certificates.
|
||||||
|
|
||||||
|
Besides a magical ASN.1 DER/JER dumper/transcoder utility, we want to replace
|
||||||
|
DN attribute and subject alternative name (SAN) `otherName` tables and much
|
||||||
|
open-coded handling of certificate extensions in `lib/hx509/`.
|
||||||
|
|
||||||
https://www.itu.int/rec/T-REC-X.681-201508-I/en
|
https://www.itu.int/rec/T-REC-X.681-201508-I/en
|
||||||
|
|
||||||
@@ -54,7 +67,8 @@ needed is constraint specification and parameterization of types.
|
|||||||
Typed Holes / Open Types
|
Typed Holes / Open Types
|
||||||
========================
|
========================
|
||||||
|
|
||||||
A typed hole or open type is a data structure with a form like:
|
A typed hole or open type is a pattern of data structure that generally looks
|
||||||
|
like:
|
||||||
|
|
||||||
```
|
```
|
||||||
{ type_id, bytes_encoding_a_value_of_a_type_identified_by_type_id }
|
{ type_id, bytes_encoding_a_value_of_a_type_identified_by_type_id }
|
||||||
@@ -67,17 +81,24 @@ what all possible things are that can go in a typed hole, but many years ago
|
|||||||
didn't, say, or anyways, had a reason to use a typed hole.
|
didn't, say, or anyways, had a reason to use a typed hole.
|
||||||
|
|
||||||
These are used not only in protocols that use ASN.1, but in many protocols that
|
These are used not only in protocols that use ASN.1, but in many protocols that
|
||||||
use alternative syntaxes and encodings.
|
use syntaxes and encodings unrelated to ASN.1. I.e., these concepts are *not*
|
||||||
|
ASN.1-specific.
|
||||||
|
|
||||||
|
Many Internet protocols use typed holes, and many use ASN.1 and typed holes.
|
||||||
|
For example, PKIX, Kerberos, LDAP, and others, use ASN.1 and typed holes.
|
||||||
|
|
||||||
|
For an example of an Internet protocol that does not use ASN.1 but which still
|
||||||
|
has typed holes, see SSHv2.
|
||||||
|
|
||||||
In ASN.1 these generally look like:
|
In ASN.1 these generally look like:
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
TypedHole ::= SEQUENCE { typeId INTEGER, hole OCTET STRING }
|
TypedHole ::= SEQUENCE { typeId INTEGER, hole OCTET STRING }
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
TypedHole ::= SEQUENCE {
|
TypedHole ::= SEQUENCE {
|
||||||
typeId OBJECT IDENTIFIER,
|
typeId OBJECT IDENTIFIER,
|
||||||
opaque ANY DEFINED BY typeID
|
opaque ANY DEFINED BY typeID
|
||||||
@@ -86,7 +107,7 @@ or
|
|||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
TypedHole ::= SEQUENCE {
|
TypedHole ::= SEQUENCE {
|
||||||
typeId OBJECT IDENTIFIER,
|
typeId OBJECT IDENTIFIER,
|
||||||
opaque ANY -- DEFINED BY typeID
|
opaque ANY -- DEFINED BY typeID
|
||||||
@@ -107,7 +128,7 @@ require any particular type for the hole, nor for the type ID. Sometimes the
|
|||||||
|
|
||||||
An example from PKIX:
|
An example from PKIX:
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
Extension ::= SEQUENCE {
|
Extension ::= SEQUENCE {
|
||||||
extnID OBJECT IDENTIFIER, -- <- type ID
|
extnID OBJECT IDENTIFIER, -- <- type ID
|
||||||
critical BOOLEAN OPTIONAL,
|
critical BOOLEAN OPTIONAL,
|
||||||
@@ -121,7 +142,7 @@ identifier isn't always an integer.
|
|||||||
Now, Heimdal's ASN.1 compiler generates the obvious C data structure for PKIX's
|
Now, Heimdal's ASN.1 compiler generates the obvious C data structure for PKIX's
|
||||||
`Extension` type:
|
`Extension` type:
|
||||||
|
|
||||||
```
|
```C
|
||||||
typedef struct Extension {
|
typedef struct Extension {
|
||||||
heim_oid extnID;
|
heim_oid extnID;
|
||||||
int *critical;
|
int *critical;
|
||||||
@@ -138,7 +159,7 @@ This is very inconvenient.
|
|||||||
Compare this to the handling of discriminated unions (what ASN.1 calls a
|
Compare this to the handling of discriminated unions (what ASN.1 calls a
|
||||||
`CHOICE`):
|
`CHOICE`):
|
||||||
|
|
||||||
```
|
```C
|
||||||
/*
|
/*
|
||||||
* ASN.1 definition:
|
* ASN.1 definition:
|
||||||
*
|
*
|
||||||
@@ -175,7 +196,7 @@ In fact, extensible `CHOICE`s are handled by our compiler as a discriminated
|
|||||||
union one of whose alternatives is a typed hole when the `CHOICE` is
|
union one of whose alternatives is a typed hole when the `CHOICE` is
|
||||||
extensible:
|
extensible:
|
||||||
|
|
||||||
```
|
```C
|
||||||
typedef struct DigestRepInner {
|
typedef struct DigestRepInner {
|
||||||
enum DigestRepInner_enum {
|
enum DigestRepInner_enum {
|
||||||
choice_DigestRepInner_asn1_ellipsis = 0, /* <--- unknown CHOICE arm */
|
choice_DigestRepInner_asn1_ellipsis = 0, /* <--- unknown CHOICE arm */
|
||||||
@@ -231,7 +252,7 @@ lives much easier.
|
|||||||
RFC5912 has lots of examples, such as this `CLASS` corresponding to the
|
RFC5912 has lots of examples, such as this `CLASS` corresponding to the
|
||||||
`Extension` type from PKIX:
|
`Extension` type from PKIX:
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
-- A class that provides some of the details of the PKIX Extension typed
|
-- A class that provides some of the details of the PKIX Extension typed
|
||||||
-- hole:
|
-- hole:
|
||||||
EXTENSION ::= CLASS {
|
EXTENSION ::= CLASS {
|
||||||
@@ -283,7 +304,7 @@ RFC5912 has lots of examples, such as this `CLASS` corresponding to the
|
|||||||
|
|
||||||
and these uses of it in RFC5280 (PKIX base):
|
and these uses of it in RFC5280 (PKIX base):
|
||||||
|
|
||||||
```
|
```ASN.1
|
||||||
-- Here we have an individual "object" specifying that the OID
|
-- Here we have an individual "object" specifying that the OID
|
||||||
-- id-ce-authorityKeyIdentifier implies AuthorityKeyIdentifier as the hole
|
-- id-ce-authorityKeyIdentifier implies AuthorityKeyIdentifier as the hole
|
||||||
-- type:
|
-- type:
|
||||||
@@ -366,12 +387,17 @@ Implementation Thoughts
|
|||||||
|
|
||||||
- `ATTRIBUTE` (used for `DN` attributes in RFC5280)
|
- `ATTRIBUTE` (used for `DN` attributes in RFC5280)
|
||||||
- `EXTENSION` (used for certificate extensions in RFC5280)
|
- `EXTENSION` (used for certificate extensions in RFC5280)
|
||||||
- `TYPE-IDENTIFIER` (used for CMS)
|
- `TYPE-IDENTIFIER` (used for `OtherName` and for CMS' `Content-Type`)
|
||||||
|
|
||||||
The minimal subset of X.681, X.682, and X.683 needed to implement those
|
The minimal subset of X.681, X.682, and X.683 needed to implement those
|
||||||
three is all we need. Eventually we may want to increase that subset so as
|
three is all we need. Eventually we may want to increase that subset so as
|
||||||
to implement other IOS classes from PKIX, such as `DIGEST-ALGORITHM`
|
to implement other IOS classes from PKIX, such as `DIGEST-ALGORITHM`
|
||||||
|
|
||||||
|
Note that there's no object set specified for OTHER-NAME instances, but we
|
||||||
|
can create our own, and will. We want magic open type decoding to recurse
|
||||||
|
all the way down and handle DN attributes, extensions, SANs, policy
|
||||||
|
qualifiers, the works.
|
||||||
|
|
||||||
- We'll really want to do this mainly for the template compiler and begin
|
- We'll really want to do this mainly for the template compiler and begin
|
||||||
abandoning the original compiler -- hacking on two compilers is difficult,
|
abandoning the original compiler -- hacking on two compilers is difficult,
|
||||||
and the template compiler is superior just on account of emitted code size
|
and the template compiler is superior just on account of emitted code size
|
||||||
@@ -387,7 +413,7 @@ Implementation Thoughts
|
|||||||
|
|
||||||
Thus `Extension` should compile to:
|
Thus `Extension` should compile to:
|
||||||
|
|
||||||
```
|
```C
|
||||||
typedef struct Extension {
|
typedef struct Extension {
|
||||||
-- Existing fields:
|
-- Existing fields:
|
||||||
heim_oid extnID;
|
heim_oid extnID;
|
||||||
|
Reference in New Issue
Block a user