Pourquoi openssl s_client vérifie un certificat par rapport à un fichier CA incompatible?

10

J'essaye de produire une erreur de vérification de certificat avec openssl s_clientcomme ceci:

$ openssl s_client -crlf -verify 9 \
  -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
  -starttls smtp -host mx-ha03.web.de -port 25

Le certificat du serveur web.de est certifié par la Deutsche Telekom CA, pas TURKTRUST, donc la commande ci-dessus devrait échouer, non?

Mais il rapporte:

    Verify return code: 0 (ok)

Pourquoi?

Je veux dire qu'une commande analogique gnutls-cli échoue comme prévu:

$ { echo -e 'ehlo example.org\nstarttls' ; sleep 1 } | \
   gnutls-cli --starttls --crlf \
   --x509cafile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \
   --port 25 mx-ha03.web.de
[..]
*** Verifying server certificate failed...

Faire un recoupement, c'est à dire utiliser à la place --x509cafile /etc/ssl/certs/ca-certificates.crtavec gnutls-cli j'obtiens:

[..]
- The hostname in the certificate matches 'mx-ha03.web.de'.
- Peer's certificate is trusted

(ce qui est également prévu)

Openssl s_client imprime pour ca-certificats.crt:

    Verify return code: 0 (ok)

Le même résultat que pour TURKTRUST ...

J'ai d'abord suspecté openssl en utilisant un paramètre par défaut pour -CApath(ie / etc / ssl / certs) - mais quand je stracele processus, je vois juste le opensyscall pour l'argument de CAfile.

(tous les tests effectués sur un serveur Ubuntu 10.04)

Mise à jour: j'ai copié le certificat TURKTRUST sur un système Fedora 20 et exécuté la première instruction openssl - là, j'obtiens un résultat différent:

Verify return code: 19 (self signed certificate in certificate chain)
maxschlepzig
la source

Réponses:

10

Il s'avère que openssl s_clientsur Ubuntu 10.04 interroge toujours un emplacement par défaut pour les certificats installés par le système, même si -CApath et -CAfile sont spécifiés:

8466  open("/usr/lib/ssl/certs/4e18c148.0", O_RDONLY) = 4

(sortie strace)

Où:

$ ls -l /usr/lib/ssl/certs/4e18c148.0
lrwxrwxrwx 1 root root 30 2014-04-11 21:50 /usr/lib/ssl/certs/4e18c148.0 ->
    Deutsche_Telekom_Root_CA_2.pem

Le répertoire /usr/lib/ssl/certsest un lien symbolique vers /etc/ssl/certsUbuntu 10.04, donc la openligne du journal de strace n'est pas sélectionnée lors de la recherche de '/ etc / ssl' ...

La source

En regardant le OpenSSL-0.9.8k, la source de ce problème se trouve dans crypto/x509/by_dir.c, dir_ctrl():

dir=(char *)Getenv(X509_get_default_cert_dir_env());
if (dir)
    ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
else
    ret=add_cert_dir(ld,X509_get_default_cert_dir(),
                     X509_FILETYPE_PEM);

X509_get_default_cert_dirrevient /usr/lib/ssl/certset X509_get_default_cert_dir_envrevient SSL_CERT_DIR.

solution de contournement

Ainsi, on peut utiliser la solution de contournement suivante sous Ubuntu 10.04 / openssl 0.9.8k pour obtenir le comportement attendu:

$ SSL_CERT_DIR="" openssl s_client -crlf -verify 9 \
    -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.crt \
    -starttls smtp -host mx-ha03.web.de -port 25

Et avec la vérification échoue:

Verify return code: 19 (self signed certificate in certificate chain)

Situation actuelle

Il s'agit d'un problème Ubuntu. Par exemple, avec openssl 1.0.1e de Fedora 20 ou openssl 1.1.1 de Fedora 29, cette solution de contournement n'est pas nécessaire, car le problème ne peut pas être reproduit. Cela signifie que lorsque vous spécifiez une option comme -CAfileou -CApath, aucun répertoire système de certificats par défaut n'est ajouté à la liste de recherche de répertoires sur les systèmes Fedora.

Sur Ubuntu 16 avec openssl 1.0.2g, le problème est toujours présent.

Il est également présent sur CentOS 7 avec openssl-1.0.2k-16 - et malheureusement, la solution de contournement ci-dessus n'aide pas et le gnutls-3.3.29-8 échoue en raison de types de paquets TLS inconnus / inattendus.

maxschlepzig
la source
J'ai la version 1.0.2g et elle a toujours ce bug. Pour aggraver les choses, le drapeau -verify_return_error n'a aucun effet et la connexion TLS continue même si le certificat est incorrect.
takumar
@takumar, j'ai re-testé cela sous Ubuntu 16 avec openssl 1.0.2g-1ubuntu4.14 et je peux confirmer, sans la solution de contournement, ce test openssl échoue toujours. Mais au moins avec la solution de contournement, j'obtiens le message d'erreur attendu - et avec la solution de contournement et -verify_return_errorla commande se termine avec le statut de sortie 1. Avec Fedora 29 et openssl-1.1.1-3.fc29.x86_64 tout fonctionne toujours comme prévu, c'est-à-dire la solution de contournement n'est pas nécessaire.
maxschlepzig
En 2019, cela semble toujours être le cas sur macOS. En outre, certains systèmes peuvent prendre en charge -no-CAfile( Ne chargez pas les certificats d'autorité de certification approuvés à partir de l'emplacement du fichier par défaut ) et -no-CApath( Ne chargez pas les certificats d'autorité de certification approuvés à partir de l'emplacement du répertoire par défaut ), mais mon système ne le fait pas, donc je ne les ai pas testés.
Arjan