Ceci est lié à une autre question, Comment vérifier une signature d'une entité par une autre en utilisant OpenSSL CLI?
J'ai utilisé openssl s_client -showcerts -connect www.google.com:443
pour collecter trois certificats auprès de google. Appelle les g0
, g1
, g2
, où:
g0
est un certificat feuille signé par l'AC intermédiaire de Googleg1
détient la clé publique CA intermédiaire et est signé par GeoTrust CAg2
détient la clé publique GeoTrust et est signé par EquiFax CAMon objectif est de démontrer qu'il s'agit d'une chaîne de signature valide, étape par étape, à l'aide de l'OpenSSL CLI. L'essai intuitif est le suivant:
$ openssl verify -CAfile g1 g0
Mais il s'avère qu'OpenSSL utilise des certificats de son magasin de confiance (voir Comment vérifier une signature d'une entité par une autre en utilisant OpenSSL CLI? ). Au lieu de cela, je tue le magasin de confiance comme @ dave_thompson_085 l'a suggéré dans un commentaire à la question référencée ci-dessus. Mais cela ne semble pas fonctionner:
$ openssl verify -CApath /dev/null -CAfile g1 g0
g1.crt: C = US, O = Google Inc, CN = Google Internet Authority G2
error 2 at 1 depth lookup:unable to get issuer certificate
Alors, comment puis-je émettre correctement cette commande verify
de manière à pouvoir vérifier spécifiquement si g1
a signé g0
?
$ openssl version
OpenSSL 1.0.1f 6 Jan 2014
J'ai plus ou moins résolu mon problème comme suit:
Il existe une option pour verify
appelée -partial_chain
qui permet de vérifier la sortie OK
sans trouver de chaîne qui atterrit sur le certificat racine de confiance auto-signé. Cependant, -partial_chain
n'existe pas sur la version d'OpenSSL que j'ai, ni dans aucune version ultérieure de 1.0.1. Voici le délabré:
-partial_chain
Donc avec 1.0.2g
ou plus tard, on peut faire ce qui suit:
$ openssl verify -CApath /dev/null -partial_chain -trusted g1 g0
g0: OK
$ openssl verify -CApath /dev/null -partial_chain -trusted g2 g1
g1: OK
$ openssl verify -CApath /dev/null -trusted /etc/ssl/certs/EquiFax_Secure_CA.pem g2
g2: OK
(Notez que -partial_chain
n'était pas nécessaire dans la dernière commande car le certificat racine Equifax est auto-signé.)
Cela répond à ma question, mais nécessite une version d'OpenSSL qui n'est pas encore disponible sur certaines distributions, sauf si vous l'installez à la main. Si vous êtes coincé avec une version antérieure à 1.0.2, vous devrez probablement utiliser la méthode de @Anthony Geoghegan.
Remarque: Il existe une option répertoriée dans les documents verify
appelés -no-CApath
qui supprime prétendument le besoin de -CApath /dev/null
, mais il n'est pas disponible sur 1.0.2g ou une version antérieure, d'après mes tests. Je suppose qu'il est disponible en 1.1.
La commande OpenSSL verify
crée une chaîne de certificats complète (jusqu'à ce qu'elle atteigne un certificat CA auto-signé) afin de vérifier un certificat. Depuis sa page de manuel:
Tout d'abord, une chaîne de certificats est créée à partir du certificat fourni et se terminant par l'autorité de certification racine. C'est une erreur si toute la chaîne ne peut pas être constituée.
Il ne renvoie un résultat positif que s'il peut vérifier la chaîne complète.
Si une opération échoue, le certificat n'est pas valide.
Cependant, les résultats de commande suivants fournissent suffisamment d'informations pour montrer que le certificat g0 est signé par le certificat g1 .
$ openssl verify -CApath /dev/null -CAfile g1 g0
g1.crt: C = US, O = Google Inc, CN = Google Internet Authority G2
error 2 at 1 depth lookup:unable to get issuer certificate
Erreur 2 indique que l'un des certificats de la chaîne est introuvable.
2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: impossible d'obtenir le certificat d'émetteur
le certificat d'émetteur d'un certificat recherché est introuvable. Cela signifie normalement que la liste des certificats approuvés n'est pas complète.
L'important ici est que la profondeur est 1. Cela indique que le certificat en cours de vérification a été vérifié au premier niveau, profondeur 0 (par le certificat g1 ).
Si le certificat g1 était pas utilisé pour signer le g0 certificat, l'erreur serait à la première étape, profondeur 0 et vous recevriez à la place erreur 2:
error 20 at 0 depth lookup:unable to get local issuer certificate
20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: impossible d'obtenir le certificat d'émetteur local
le certificat d'émetteur est introuvable: cela se produit si le certificat d'émetteur d'un certificat non approuvé est introuvable.
Pour vérifier que l'émetteur de cert1.crt
est cert1Issuer.crt
:
openssl verify -no-CAfile -no-CApath -partial_chain -trusted cert1Issuer.crt cert1.crt
# cert1.crt : OK