0

I'm having trouble working out the syntax when decoding a SubjectAltName in a TLS self-signed certificate. I believe the certificate is well formed. The trouble is, I don't understand how to decode CHOICE.

First, the SAN has four names:

DNS.1  = example.com
DNS.2  = www.example.com
DNS.3  = mail.example.com
DNS.4  = ftp.example.com

Next, RFC 5280, p. 127 says:

SubjectAltName ::= GeneralNames

GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

GeneralName ::= CHOICE {
     otherName                 [0]  AnotherName,
     rfc822Name                [1]  IA5String,
     dNSName                   [2]  IA5String,
     x400Address               [3]  ORAddress,
     directoryName             [4]  Name,
     ediPartyName              [5]  EDIPartyName,
     uniformResourceIdentifier [6]  IA5String,
     iPAddress                 [7]  OCTET STRING,
     registeredID              [8]  OBJECT IDENTIFIER }

And finally, a hex encoded string starting at the SEQUENCE:

3041820B6578616D706C652E636F6D820F7777772E6578616D706C652E636F6D82106D61696C2E6578616D706C652E636F6D820F6674702E6578616D706C652E636F6D

I understand 30 is the tag and 41 is the length. When I break out the values I see:

820B6578616D706C652E636F6D
820F7777772E6578616D706C652E636F6D
82106D61696C2E6578616D706C652E636F6D
820F6674702E6578616D706C652E636F6D

So it looks like 82 is CHOICE, followed by the length of the value, and then the value. And all the values are concatenated together.

My question is, how did 82 become CHOICE? I don't recall encountering it in ASN.1 before. How do I handle the decoding?

1 Answer 1

2

There is no actual tag for CHOICE itself (it is a "transparent" type) – instead each possible inner type is directly determined by its own tag. For example, when you are decoding a GeneralName, an iPAddress is indicated by having the context-specific tag 7.

The highest two bits of a tag byte indicate its class (universal, app, context, private – you can find a table in A Layman's Guide section 3.1). So byte 82 corresponds to tag [CONTEXT 2], or [2] for short, which means you have a dNSName.

The same tag also means it's an IA5String – since it's an implicit tag by default, it overwrites the usual [universal 22] tag that an IA5String would have. (This is why openssl asn1parse just shows "cont [ 2 ]" – it doesn't have the actual spec and doesn't know what it's decoding.)

Sometimes the type can already be unambiguously determined from the built-in tags, e.g. the same RFC has DisplayText which is a CHOICE between four types each already having a different 'universal' tag, so there is no need to add custom tags.

6
  • Thanks @grawity. Given a b = 0x82, then I would c = b & 0x3f to find the choice. What happens to the upper two bits? Are they discarded? Can they be mixed and matched? For example, can both 0x82 (1000 0010) and 0xC2 (1100 0010) be in a SEQUENCE?
    – jww
    Commented Oct 2, 2019 at 10:13
  • The upper two bits indicate the tag class – you need to compare both the tag number and its class together. For example, 0x82 is [CONTEXT 2] would mean dNSName in this situation, but 0x02 is [UNIVERSAL 2] which is how an INTEGER is tagged, and that would be invalid in the context of a GeneralName. Commented Oct 2, 2019 at 10:15
  • And yeah, they can be mixed and matched as long as the ASN.1 schema allows it. For example I've noticed that some CHOICEs specify a custom context tag for all options except the first one, relying on its existing type tag instead. Commented Oct 2, 2019 at 10:17
  • For example, CHOICE { foo IA5String, bar [1] IA5String, baz [2] IA5String } appears to be a common pattern, if I've remembered it correctly. In this case foo would retain its 0x16 [UNIVERSAL 22] tag from IA5String, while bar would get 0x81 [CONTEXT 1]. Commented Oct 2, 2019 at 10:18
  • As for mixing different types in a SEQUENCE, well, yes you can do that as long as it's a sequence of a CHOICE type (just like you have here with GeneralNames). Commented Oct 2, 2019 at 10:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .