Various corrections to ANS1/DER doc - #2330
Conversation
| represent in DER is 256<sup>(2\*\*1008)</sup>-1. For a truly unbounded INTEGER you'd | ||
| have to encode in BER, which allows indefinitely-long fields. |
There was a problem hiding this comment.
Why delete the unbounded INTEGER comment?
| These tags all happen to be under 31 (0x1F), and that's for a good reason: Bits | ||
| 8, 7, and 6 (the high bits of the tag byte) are used to encode extra | ||
| information, so any universal tag numbers higher than 31 would need to | ||
| information, so any universal tag numbers of 31 or higher would need to |
There was a problem hiding this comment.
Is this right? It seems to me that universal tag number 31 would be encoded as 0b00011111, which doesn't interfere with the high bits mentioned above.
| (The IMPLICIT keyword is explained under [EXPLICIT vs IMPLICIT](#explicit-vs-implicit) | ||
| below. It matters here: without it the default is EXPLICIT, which produces a | ||
| different, longer encoding.) | ||
|
|
||
| So now, to encode a Point with just an x coordinate of 9, instead of | ||
| encoding x as a UNIVERSAL INTEGER, you'd set bits 8 and 7 of the encoded | ||
| tag to (1, 0) to indicate the context specific class, and set the low | ||
| bits to 0, giving this encoding: |
There was a problem hiding this comment.
This is a good catch but pedagogically, we first introduced INTEGER, then INTEGER OPTIONAL, and now [APPLICATION 0] INTEGER OPTIONAL. I'd rather not introduce [APPLICATION 0] and IMPLICIT at the same time in the examples, since it muddies the waters.
Instead, I suggest:
| So now, to encode a Point with just an x coordinate of 9, instead of | |
| encoding x as a UNIVERSAL INTEGER, you'd set bits 8 and 7 of the encoded | |
| tag to (1, 0) to indicate the context specific class, and set the low | |
| bits to 0, giving this encoding (assuming [IMPLICIT TAGS](#explicit-vs-implicit)): |
Along with reverting the above diffs to the ASN.1 notation.
| in ascending order by the tag of each element (first by class, then by tag | ||
| number). |
There was a problem hiding this comment.
Ooh this is a good catch, and subtle. SET and SET OF differ here. For SET, X.690 says:
10.3 Set components
The encodings of the component values of a set value shall appear in an order determined by their tags as specified in 8.6 of
Rec. ITU-T X.680 | ISO/IEC 8824-1.
X.680 says:
8.6 The canonical order for tags is based on the outermost tag of each type and is defined as follows:
a) those elements or alternatives with universal class tags shall appear first, followed by those with
application class tags, followed by those with context-specific tags, followed by those with private class
tags;
b) within each class of tags, the elements or alternatives shall appear in ascending order of their tag
numbers.
This reveals a misunderstanding I've had: I treat the first byte in an encoding as a "tag byte" but X.690 actually calls the first bytes "identifier octets." And a "tag" consists of a (class, tag number) pair (but not the constructed bit, which is an encoding instruction).
I think this deserves a little expansion here to clarify. How about:
In DER, the components of a SET must be encoded in ASN.1's canonical order by their tags. That means ordering first by class (universal, application, context-specific, private in that order), then by tag number. This differs from simply sorting encoded elements because it ignores the constructed bit, and also ignores the encoding nuances of high tag numbers.
Also we need some tweaks below since the definition of SET OF refers to this.
| A SET OF items is encoded the same way as a SET, including the tag byte | ||
| of 0x31. For DER encoding, there is a similar requirement that the SET OF | ||
| must be encoded in ascending order. Because all elements in the SET OF | ||
| have the same type, ordering by tag is not sufficient. So the elements | ||
| of a SET OF are sorted by their encoded values, with shorter values | ||
| treated as if they were padded to the right with zeroes. |
There was a problem hiding this comment.
| A SET OF items is encoded the same way as a SET, including the tag byte | |
| of 0x31. For DER encoding, there is a similar requirement that the SET OF | |
| must be encoded in ascending order. Because all elements in the SET OF | |
| have the same type, ordering by (class, tag number) is not sufficient. | |
| So the elements of a SET OF are sorted by their _encoded values_, with | |
| shorter values treated as if they were padded to the right with zeroes. |
|
Since you are much more of an expert on this than me, do you want to take over this PR/branch @jsha ? |
|
Will do, thanks for spotting these issues! |
No description provided.