2017-09-26 6 views
0

J'essaie d'implémenter un X509TrustManager personnalisé qui indique à l'utilisateur le certificat et lui donne la possibilité de continuer à utiliser le serveur malgré le problème.Comment puis-je obtenir la chaîne de certificats potentiellement seulement le certificat de feuille?

J'ai presque tout accroché ensemble et a commencé à tester contre divers certificats sur badssl.com.

Lorsque je visite expired.badssl.com dans Safari, je vois trois certificats:

* COMODO RSA Certification Authority 
    * COMODO RSA Domain Validation Secure Server CA 
     * *.badssl.com 

Et ma demande obtient la chaîne complète.

Lorsque je visite wrong.host.badssl.com, cependant, Safari montre encore trois certificats, mais ma demande ne voit que deux:

* DigiCert Global Root CA (Not in the array passed to the method!) 
    * DigiCert SHA2 Secure Server CA 
     * *.badssl.com 

Je suppose que je peux utiliser le nom « émetteur » de la « DigiCert SHA2 serveur sécurisé CA » certificat pour trouver le certificat racine en quelque sorte, mais puis-je le trouver?

Répondre

3

Le certificat racine utilisé pour valider la chaîne du serveur (ou en général toute chaîne reçue) doit être trouvé dans le magasin de clés de confiance local. C'est exactement ce que fait le TrustManager par défaut - il regarde dans le magasin de confiance local, ou plus exactement instancie un CertPathValidator qui (normalement) par défaut à PKIXValidator qui regarde dans un fichier de clés certifiées (un KeyStore contenant des entrées de cert) normalement initialisé à partir d'un fichier local par défaut JRE/lib/security/cacerts, puis exécute ce validateur qui effectue la validation en recherchant la racine à partir du fichier de clés certifiées en utilisant un HashMap par nom de sujet.

Ceci est indiqué, bien que brièvement, in RFC 5246 for TLS 1.2 (inchangé par rapport à 4346 pour 1.1 et 2346 pour 1.0).

Si vous regardez de plus près, vous constaterez que les cas ne sont pas aussi différents que vous le pensez.

wrong.host.badssl.com sert une chaîne de cert comprenant:
* https://crt.sh/?id=205900989 feuille * .badssl.com émis par DigiCert SHA2 SecServerCA
* https://crt.sh/?id=1262388 intermédiaire émis par DigiCert GlobalRootCA
qui utilise la racine https://crt.sh/?id=853428 avec SHA1 empreintes digitales A8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436 qui vous voulez trouver dans la plupart sinon tous les truststores communs, y compris Java (au moins Oracle/Sun Java, OpenJDK peut différer selon la façon dont il a été construit). Notez que ce CERT valide pour *.badssl.com échoue pour wrong.host.badssl.com parce que la correspondance de nom générique de certificat ne fait plus qu'un (plus à gauche) étiquette DNS (il en faudrait deux).

expired.badssl.com sert une chaîne cert consistant en:
* https://crt.sh/?id=7176112 feuille * .badssl.com délivré par COMODO RSADomainValCA
* https://crt.sh/?id=3509153 intermédiaire délivré par COMODO RSACertAuth
* https://crt.sh/?id=1044348 pont délivré 2000 (jusqu'en 2020) par AddTrust ExternalRoot
qui, comme envoyé, utilise la racine AddTrust https://crt.sh/?id=1 avec l'empreinte SHA1 02FAF3E291435468607857694DF5E45B68851868.Cependant, COMODO RSA a maintenant sa propre racine https://crt.sh/?id=1720081 datée 2010 (jusqu'en 2038) avec l'empreinte digitale SHA1 AFE5D244A8D1194230FF479FE2F897BBCD7A8CB4 assez largement acceptée - y compris par Oracle Java commençant 8u51. (AddTrust Externe remonte beaucoup plus loin, au moins 6u07 qui est le plus ancien que je peux facilement vérifier.) Je parie que vous trouverez Safari remplacé le certificat de pont pour COMODO RSA en haut de la chaîne reçue avec le (COMODO RSA) racine; tout relieur est autorisé à faire ce genre de raccourcis et mon (presque-courant) Firefox, IE et Chrome/Windows le font tous dans ce cas. (Les deux derniers partagent le truststore de Windows, Firefox utilise Mozilla.)

(PS pour les checklisters: j'utilise les empreintes digitales SHA1 car elles sont plus faciles à couper & coller et sont encore assez bon - des collisions SHA1 ont été trouvées pour certains données, mais pas de tous les certs qui sont beaucoup plus difficiles en raison de la corrélation de signature, et de toute façon que la deuxième preimage serait en fait un problème et autant que je sache, personne n'a fait aucun progrès sur cela.)


la question dans votre titre, 'donné seulement le cert de feuille', ne devrait jamais se produire dans TLS en raison des RFC référencés ci-dessus. Mais si c'est le cas, c'est presque un doublon de OpenSSL generate certificate chain et la même logique s'applique: suivez CAIssuers, ou (avec de la chance) chaîne sur le log CT (s) - comme je l'ai fait manuellement pour ce qui précède!

+1

Je ne suis pas sûr que ce serait une copie de cette question, même dans ce cas, parce que cette question est sur la façon de le faire dans openssl, et cette question est sur la façon de le faire en Java, qui n'a aucun accès pratique à openssl. – Trejkaz

+0

@Trejkaz: point équitable; qualifié –