X.509 e ASN.1
Formato canônico de certificado digital. RFC 5280 (Internet X.509 PKI Certificate and CRL Profile) é a referência. Tudo que envolve TLS, S/MIME, code signing, ICP-Brasil deriva daqui.
Estrutura de um cert X.509 v3
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate, -- "to be signed"
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity, -- notBefore + notAfter
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
extensions [3] EXPLICIT Extensions OPTIONAL
}Codificação: ASN.1 DER (Distinguished Encoding Rules) — binário canônico. PEM = base64 de DER com -----BEGIN CERTIFICATE----- envelope. Inspeção: openssl x509 -in cert.pem -text -noout.
Extensões críticas (v3)
| Extensão | OID | Pra que serve |
|---|---|---|
| BasicConstraints | 2.5.29.19 | CA:TRUE/FALSE + pathLenConstraint. Diferencia CA de end-entity. CA forjado por end-entity foi a base de diversos ataques históricos |
| SubjectAltName (SAN) | 2.5.29.17 | DNS names, IPs, emails. CN do subject está deprecated pra hostname matching desde 2017 (CA/B BR). Browsers só olham SAN |
| KeyUsage | 2.5.29.15 | digitalSignature, keyEncipherment, keyCertSign, … restringe operações |
| ExtKeyUsage (EKU) | 2.5.29.37 | serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, OCSPSigning |
| CRLDistributionPoints | 2.5.29.31 | Onde buscar CRL pra revogação |
| AuthorityInfoAccess (AIA) | 1.3.6.1.5.5.7.1.1 | URLs do OCSP responder + cert do issuer |
| CertificatePolicies | 2.5.29.32 | OIDs de política (ex: ICP-Brasil A1A3A4 têm OIDs específicos) |
| SCTList | 1.3.6.1.4.1.11129.2.4.2 | Embarcamento de Signed Certificate Timestamps (CT logs) |
| NameConstraints | 2.5.29.30 | Restringe domínios que um sub-CA pode emitir (CRÍTICO em sub-CAs delegados, ignorado em campo) |
Trust path validation
RFC 5280 §6 define o algoritmo. Resumo:
- Cadeia: end-entity → intermediate(s) → root. Root é trust anchor (já confiável por config).
- Cada par (cert, issuer) checa: assinatura válida (
issuer.publicKeyverificacert.signatureValue),notBefore ≤ now ≤ notAfter, BasicConstraintsKeyUsageEKU compatíveis, não revogado (OCSPCRLCRLite/embedded SCTs). - Pitfall comum: confundir "está na cadeia enviada pelo servidor" com "está no trust store". TLS server envia a cadeia até (e excluindo) o root; o client cola seu root local.
Pitfalls operacionais
- CN ≠ SAN: nunca dependa do CN. Cert moderno sem SAN é inválido pra hostname binding.
- Validade longa: máximo público em 2026 é 398 dias (CA/B BR §6.3.2). Roadmap em direção a 90 dias (Apple proposal 2024) e 47 dias (Google proposal).
- Algoritmo de assinatura: SHA-1 banido em CAs públicos desde 2017. Cert com
sha1WithRSAEncryptionem produção é red flag. - Cross-sign: um mesmo subject+key pode ter múltiplos certs emitidos por issuers diferentes — útil pra transição de root, ver
06-ssl-and-tls/05-creating-a-letsencrypt-style-ca.kmd§Cross-signing. - Path building: dado um pool de intermediários, achar a cadeia certa é NP-hard no pior caso; libs sérias têm heurísticas. Falhas reais quando intermediates estão faltando.
ASN.1 — o suficiente pra sobreviver
ASN.1 = linguagem de descrição de tipos abstratos. DER = encoding binário canônico (TLV: Tag + Length + Value).
SEQUENCE= struct ordenadoSET= struct não-ordenadoOCTET STRING= bytesBIT STRING= bits (com offset de padding)OBJECT IDENTIFIER(OID) = identificador hierárquico de tipo (1.2.840.113549.1.1.11= sha256WithRSAEncryption)UTCTime(YYMMDDHHMMSSZ, válido até 2049) vsGeneralizedTime(YYYYMMDDHHMMSSZ)
Tooling pra inspecionar: openssl asn1parse, dumpasn1, lapo.it/asn1js (browser).
Libs canônicas
- Go:
crypto/x509(stdlib) — completo e ergonômico - Rust:
rustls-webpki(path validation),x509-parser(parsing) - Dart:
package:basic_utils(parsing limitado; pra ops pesadas, ponte FFI) - Python:
cryptography.x509
Referências
- RFC 5280 — X.509 v3 Certificate Profile
- RFC 6818 — Updates to RFC 5280
- CA/Browser Forum Baseline Requirements
- Mozilla CA Cert Inclusion Policy
- Davis: How to read a X.509 Certificate — zlint codifica regras em verificadores