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?
Thanks @grawity. Given a
b = 0x82
, then I wouldc = 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 both0x82
(1000 0010
) and0xC2
(1100 0010
) be in aSEQUENCE
? – jww – 2019-10-02T10:13:28.567The 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 anINTEGER
is tagged, and that would be invalid in the context of a GeneralName. – user1686 – 2019-10-02T10:15:47.493And 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. – user1686 – 2019-10-02T10:17:25.967
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]
. – user1686 – 2019-10-02T10:18:25.807As 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). – user1686 – 2019-10-02T10:22:36.307
And honestly use an existing X.509 library if you can... – user1686 – 2019-10-02T10:39:48.240