Estou tendo problemas para entender a sintaxe ao decodificar um SubjectAltName em um certificado TLS autoassinado. Eu acredito que o certificado está bem formado. O problema é que não entendo como decodificar arquivos CHOICE
.
Primeiro, o SAN tem quatro nomes:
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
Em seguida, RFC 5280, p. 127 diz:
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 }
E, finalmente, uma string codificada em hexadecimal começando em SEQUENCE
:
3041820B6578616D706C652E636F6D820F7777772E6578616D706C652E636F6D82106D61696C2E6578616D706C652E636F6D820F6674702E6578616D706C652E636F6D
Eu entendo 30
é a etiqueta e 41
é o comprimento. Quando separo os valores, vejo:
820B6578616D706C652E636F6D
820F7777772E6578616D706C652E636F6D
82106D61696C2E6578616D706C652E636F6D
820F6674702E6578616D706C652E636F6D
Parece que 82
é CHOICE
, seguido pelo comprimento do valor e, em seguida, pelo valor. E todos os valores são concatenados juntos.
Minha pergunta é, como se 82
tornou CHOICE
? Não me lembro de tê-lo encontrado antes em ASN.1. Como faço para lidar com a decodificação?
Não há marca real para CHOICE em si (é um tipo "transparente") - em vez disso, cada tipo interno possível é determinado diretamente por sua própria marca. Por exemplo, quando você está decodificando um GeneralName, um iPAddress é indicado por ter a tag específica do contexto 7.
Os dois bits mais altos de um byte de tag indicam sua classe (universal, app, context, private – você pode encontrar uma tabela na seção 3.1 do A Layman's Guide ). Portanto, byte
82
corresponde a tag[CONTEXT 2]
, ou[2]
abreviado, o que significa que você tem um dNSName .A mesma tag também significa que é uma IA5String – já que é uma tag implícita por padrão, ela sobrescreve a
[universal 22]
tag usual que uma IA5String teria. (É por isso queopenssl asn1parse
mostra apenas "cont [ 2 ]" - não tem a especificação real e não sabe o que está decodificando.)Às vezes, o tipo já pode ser determinado de forma inequívoca a partir das tags internas, por exemplo, o mesmo RFC tem DisplayText , que é uma ESCOLHA entre quatro tipos, cada um já tendo uma tag 'universal' diferente, portanto, não há necessidade de adicionar tags personalizadas.