Subject: [Spasm] Technical & Editorial Quality Control in this WG: some ASN.1 points

From: Sean Leonard <[email-masked]>
Date: Tue, 17 May 2016 16:18:07 -0700

I would like to propose a few ASN.1 points for this spasm WG to follow, 
to maintain a high level of Technical & Editorial Quality Control.

These proposed points should be effective for final publications from 
this WG:

Pick an ASN.1 standard to use as the normative reference. The current 
ITU-T standard in force is X.680: August 2015. We are no longer in the 
mid-90s, and there are at least a few widely-available, high-quality, 
open-source ASN.1 compiler tools that support the "new" syntax (new 
meaning, the syntax after 1988). If folks want or need 1988 syntax, then 
the 1988 syntax can be given in an informative (*not* normative) appendix.

Pick one of IMPLICIT, EXPLICIT, or AUTOMATIC for all WG output. (X.680 
recommends AUTOMATIC, but I am guessing there is an inherent bias 
towards IMPLICIT around these parts).

For character strings, UTF8String should always be used, unless 
backwards compatibility is a requirement (e.g., 
DirectoryString/distinguished names).

BOOLEAN is for an element with two alternatives.

If an element can take on one of a finite, enumerated set of values 
(more than two), ENUMERATED should be used. (I.e., not named INTEGERs.)

BITSTRING should be avoided, unless backwards compatibility is a 
requirement (e.g., SignatureValue) or the circumstances truly call for 
data in a non-integral number of octets.

Embedded ASN.1 (BER/DER) should not be stuffed into OCTET STRING.

For time, we have a lot of different time types to pick from. I really 
have no idea why time has to be so complicated...there are UTCTime, 
GeneralizedTime, BinaryTime [RFC6019], and the "new" TIME (X.680 Clause 
38). I am sure that people have stuffed time into other inappropriate 
types as well. It's time...for an overhaul! ha ha. X.680 recommends the 
"new" TIME. But, I suspect that this WG will settle upon 
GeneralizedTime, strictly limited to UTC (zero-offset) and no fractions 
of a second.

If the publication includes a text specification, the specification 
shall use ABNF normatively.

Each publication should have a normative ASN.1 module (if it uses ASN.1 
at all), which is submitted and maintained as a separate file with 
network (CRLF) line endings. The SHA-256 hash of the file should be 
included in the published RFC.

Before publication, each ASN.1 module (along with all of its 
dependencies) must be successfully compiled and verified by two 
independent ASN.1 compiler implementations.

Comments, etc. welcome.

Regards,

Sean

---

From: Sean Turner <[email-masked]>
Date: Tue, 17 May 2016 20:27:00 -0400

On May 17, 2016, at 19:18, Sean Leonard <[email-masked]> wrote:
> 
> Pick an ASN.1 standard to use as the normative reference. The current ITU-T standard in force is X.680: August 2015.

We’ve been down this road before :/

RFC 5280 is ’88 so we’re kinda stuck with that as the normative module.

We published ‘02 ASN.1 for PKIX in RFC 5912.  Some updates were also published in RFC 6268 and that used the ’08 syntax profiled back to the ’02 version.  I hope we can just do what we did for RFC 6268 for the alternate module.

spt

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 18 May 2016 12:37:59 +0000

Interesting thoughts.  Most seem reasonable -- but have we ever had an "official" source for *any* ASN.1?  And have we seen PKIX or SNMP interop errors because we didn't have one?

But I completely agree with Sean about the way forward on ASN.1

--  
Senior Architect, Akamai Technologies
IM: [email-masked] Twitter: RichSalz

---

From: Carl Wallace <[email-masked]>
Date: Wed, 18 May 2016 09:22:59 -0400

>to maintain a high level of Technical & Editorial Quality Control.

This seems like a good place to try something like this out. The utility
of it may not be great given the amount of legacy ASN.1 addressed here.

>the 1988 syntax can be given in an informative (*not* normative) appendix.

This makes sense to me. There is an RFC to help with back porting to '88
anyway even if not included in the spec.

>towards IMPLICIT around these parts).

This is the only item here I disagree with slightly. I'd favor EXPLICIT
where tagging objects that are usually handled independently, I.e., tagged
certificates, CMS messages, etc.

><snip>

This could be handy for dependencies as well.

>independent ASN.1 compiler implementations.

What does verified mean here? Successful interop via compilation is one
thing, successful interop via exchanging encoded values is another (and
more work to confirm).

>Comments, etc. welcome.

One addition might be requiring the inclusion of base64 encoded samples of
structures defined in the module. This might help avoid some boundary
issues where constraints or tagging are used.

>
>Regards,
>
>Sean
>
>_______________________________________________
>Spasm mailing list
>[email-masked]
>https://www.ietf.org/mailman/listinfo/spasm

---

From: Russ Housley <[email-masked]>
Date: Wed, 18 May 2016 13:24:39 -0400

I included an ASN.1 module in the -01 version.  It uses the newer syntax.

Russ

---

From: Sean Leonard <[email-masked]>
Date: Wed, 18 May 2016 14:29:02 -0700

Just a few points; mostly in agreement:

> anyway even if not included in the spec.

What's that RFC that you're referring to?

> certificates, CMS messages, etc.

My take is that AUTOMATIC--though recommended--makes it "non-obvious" 
what actually the tags are going to be on-the-wire unless you really 
know the ASN.1 rules in your head.

As for EXPLICIT vs. IMPLICIT: it's kind of a stylistic choice between 
being verbose and being concise, by a few bytes per instance (an extra 
tag, which is usually one byte, and an extra length specifier, which is 
probably going to be the same number of bytes as the length tag for the 
inner item--depends on the encased structure).

The thing however is that PKIX/CMS uses IMPLICIT quite a bit--for PKIX 
it's literally like half/half, and for CMS, the whole thing is in an 
IMPLICIT module (with a few EXPLICIT items as exceptions). Therefore, 
the coders "have to support" IMPLICIT, and for developing and debugging, 
it's basically the same amount of cognitive overhead for engineers.

My take is that since IMPLICIT is necessary, we may as well stick with 
it as the default. The better solution, however, would be to create 
structures where the IMPLICIT/EXPLICIT distinction does not result in 
significant divergence on the wire (this specifically applies to 
primitive types, i.e., things that are not SET or SEQUENCE). What I mean 
is that, if confronted with a CHOICE of two strings and an integer, it 
would be better to say: CHOICE { PrintableString, UTF8String, INTEGER } 
than: CHOICE { [0] UTF8String, [1] UTF8String, [2] UTF8String }. (I.e., 
the types are naturally disambiguated with their "natural" tags.) 
Alternatively, the underlying data could be expressed as SEQUENCE { 
ENUMERATED, UTF8String } where the ENUMERATED says what kind of data is 
in the UTF8String. It depends on the underlying data. In contrast, 
CHOICE { [0] SEQUENCE {...}, [1] SEQUENCE {...}, [2] SEQUENCE OF INTEGER 
} is "all right" because SEQUENCE is always a constructed type.

> thing, successful interop via exchanging encoded values is another (and

When I wrote that, I was referring to successful compilation. I suppose 
that exchanging encoded values would be nice/a "level 2" of 
verification, but it was not my intent to go there when I wrote that. 
Others are free to disagree.

> issues where constraints or tagging are used.

I agree with this. Since you wrote "samples" as plural, I suggest at 
least one sample that is in the normal & expected range, and one sample 
that is pathological but still technically in range. For example, if it 
were a date-time, "normal" would be 2016-05-18; pathological would be 
9999-12-31 (assuming that the spec, or the spec on which the spec 
relies, says that 4-digit years up to 9999 are acceptable). If the spec 
says nothing and the underlying spec says nothing, an appropriate 
pathological case would be one that tests the boundaries further, such 
as 3999999-12-31.

By the way: extreme examples of valid OIDs are in the 2.25. arc because 
those represent 128-bit UUIDs. (See Kaminsky et. al., PKI Layer Cake, 
2009 <http://www.ioactive.com/pdfs/PKILayerCake.pdf>.)

Sean

---

From: Carl Wallace <[email-masked]>
Date: Wed, 18 May 2016 19:14:20 -0400

>What's that RFC that you're referring to?

6025