web-dev-qa-db-fra.com

Comment lister les certificats, approuvés par OpenSSL?

Si je comprends bien, tout logiciel fonctionnant avec des certificats X.509 peut avoir sa propre base pour décider si un certificat est approuvé ou non.

AFAIK OpenSSL consulte simplement une liste (comme, par exemple,/etc/ssl/certs) et vérifie si le certificat y est présent.

Existe-t-il un moyen pour OpenSSL de répertorier tous les certificats auxquels il fait confiance? Je sais que je peux consulter ce fichier moi-même (sur mon installation particulière d'OpenSSL), mais existe-t-il un moyen (indépendant de l'installation) d'obtenir la liste de confiance d'OpenSSL lui-même?

15
Konstantin Shemyak

AFAIK OpenSSL consulte simplement une liste (comme, par exemple,/etc/ssl/certs) et vérifie si le certificat y est présent.

Non, OpenSSL ne fait confiance à rien par défaut. Vous devez lui dire à quoi faire confiance. Il y a même un FAQ sujet le couvrant: Pourquoi <SSL program> échec avec une erreur de vérification de certificat? :

Ce problème est généralement indiqué par des messages de journal indiquant quelque chose comme "impossible d'obtenir le certificat d'émetteur local" ou "certificat auto-signé". Lorsqu'un certificat est vérifié, son autorité de certification racine doit être "approuvée" par OpenSSL, cela signifie généralement que le certificat de l'autorité de certification doit être placé dans un répertoire ou un fichier et que le programme approprié doit être configuré pour le lire. Le programme OpenSSL 'verify' se comporte de manière similaire et émet des messages d'erreur similaires: consultez la page de manuel du programme verify (1) pour plus d'informations.

Vous pouvez également tester votre connexion à Google pour voir comment OpenSSL se comporte:

$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
...
Start Time: 1407377002
Timeout   : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)

Notez que ce qui précède échoue car OpenSSL ne fait pas confiance GeoTrust Global CA par défaut . En fait, il y a un autre point de confiance dans la chaîne et c'est Google Internet Authority G2 .

Vous pouvez remédier à la situation en disant à OpenSSL à quoi faire confiance. Ci-dessous, j'utilise -CAfile option avec Google Internet Authority G2 :

$ openssl s_client -connect google.com:443 -CAfile google-ca.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377196
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Ensuite, vous pouvez agir comme un navigateur en allant sur cURL et télécharger cacert.pem . cacert.pem contient beaucoup d'autorités de certification:

$ openssl s_client -connect google.com:443 -CAfile cacert.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377356
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Vous n'êtes pas aussi mauvais qu'un navigateur avec ses centaines de CA et CA subordonnés, mais vous vous en approchez:

$ cat cacert.pem | grep -o "\-\-\-\-\-BEGIN" | wc -l
     153

Le modèle de sécurité OpenSSL est en contraste avec le modèle de sécurité de l'application Web/navigateur, où le navigateur transporte une liste d'ancres de confiance ou de points de confiance connus sous le nom d'autorités de certification (CA). Remarque : dans ce modèle, la mauvaise autorité de certification pourrait prétendre certifier un site, et le navigateur ne serait pas plus sage.

Cela s'est produit dans le passé et cela se reproduira probablement à l'avenir. Pour une bonne histoire des activités drôles de PKIX, consultez Historique des risques de CAcert . Par exemple, vous savez Google Internet Authority G2 et GeoTrust Global CA certifie Sites de Google. Il n'y a aucune raison pour qu'une autorité de certification néerlandaise appelée Diginotar prétende les certifier, ou Agence française de cyberdéfense pour prétendre les certifier.

Liés aux modèles de sécurité: un autre problème avec le modèle d'application Web/navigateur est que vous ne pouvez pas empaqueter l'ancre de confiance ou l'autorité de certification requise pour votre application et l'utiliser ( en supposant que vous avez un canal de distribution de confiance). Vos certificats sont jetés dans la pile avec le zoo de CA. D'autres peuvent toujours prétendre certifier votre site et vous pouvez prétendre certifier d'autres sites.

Le modèle de sécurité est l'une des raisons pour lesquelles les applications Web sont reléguées aux données de faible valeur. Les applications Web ne doivent pas gérer des données de valeur moyenne ou élevée car nous ne pouvons pas placer les contrôles de sécurité nécessaires.


Existe-t-il un moyen pour OpenSSL de répertorier tous les certificats auxquels il fait confiance?

Pas besoin puisque la liste compte 0 membres :)


Voir aussi Comment trouver le chemin d'accès au certificat de confiance openssl? .

15
jww

J'ai récemment étudié la question et n'ai trouvé aucun moyen d'obtenir qu'OpenSSL répertorie les certificats dans son ensemble de confiance. Comme vous l'avez souligné, la meilleure façon que j'ai trouvée était de "consulter moi-même ce fichier [/ etc/ssl/certs] (sur mon installation particulière d'OpenSSL)".

Vous pouvez être plus indépendant de l'installation pour trouver le répertoire qu'OpenSSL consulte. openssl version -d affiche le chemin d'accès.

% openssl version -d
OPENSSLDIR: "/opt/local/etc/openssl"

OpenSSL recherche ici un fichier nommé cert.pem et un sous-répertoire certs/. Les certificats qu'il y trouve sont traités comme approuvés par openssl s_client et openssl verify (source: l'article, Quelles autorités de certification OpenSSL reconnaît-il?).

Vous pouvez donc faire quelque chose comme:

% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \ 
-type f -exec cat {} \+  

Ceci imprime l'intégralité du contenu des fichiers qu'OpenSSL s'attend à contenir des certificats. Si vous voulez moins que la totalité du fichier, remplacez cat par les commandes appropriées.

7
Jim DeLaHunt

Je me demande si cela a changé d'une manière ou d'une autre depuis la réponse de jww.

Si je soumets: $ openssl s_client -connect google.com:443

Il fonctionne correctement, récupère 4 certificats totaux et renvoie:

Start Time: 1484661709
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Je pense que c'est parce que les serveurs doivent être configurés pour envoyer, avec le certificat, tous les certificats intermédiaires et racine nécessaires pour vérifier la chaîne complète, non?

1
em_bo