¿Por qué openssl s_client verifica un certificado contra un archivo CA que no coincide?

10

Estoy tratando de generar un error de verificación de certificado openssl s_clientcomo este:

$ 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

El certificado del servidor web.de está certificado por Deutsche Telekom CA, no por TURKTRUST, por lo que el comando anterior debería fallar, ¿verdad?

Pero informa:

    Verify return code: 0 (ok)

¿Por qué?

Me refiero a que un comando analógico gnutls-cli falla como se esperaba:

$ { 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...

Haciendo una verificación cruzada, es decir, usando en su lugar --x509cafile /etc/ssl/certs/ca-certificates.crtcon gnutls-cli obtengo:

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

(que también se espera)

Openssl s_client imprime para ca-certificados.crt:

    Verify return code: 0 (ok)

El mismo resultado que para TURKTRUST ...

Primero sospeché de openssl usando una configuración predeterminada para -CApath(es decir, / etc / ssl / certs), pero cuando llego straceal proceso solo veo la openllamada al sistema para el argumento de CAfile.

(todas las pruebas realizadas en un servidor Ubuntu 10.04)

Actualización: Copié el certificado TURKTRUST en un sistema Fedora 20 y ejecuté la primera instrucción openssl; allí obtengo un resultado diferente:

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

Respuestas:

10

Resulta que el openssl s_clientde Ubuntu 10.04 todavía consultas una ubicación predeterminada para los certificados de sistema instalado, incluso si -CApath y -CAfile se especifican:

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

(salida de strace)

Dónde:

$ 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

El directorio /usr/lib/ssl/certses un enlace simbólico a /etc/ssl/certsUbuntu 10.04, por lo tanto, la openlínea del registro de strace no se selecciona cuando se selecciona '/ etc / ssl' ...

Fuente

En cuanto a la openssl-0.9.8k, el origen de este problema se encuentra en 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);

Donde X509_get_default_cert_dirvuelve /usr/lib/ssl/certsy X509_get_default_cert_dir_envvuelve SSL_CERT_DIR.

Solución alterna

Por lo tanto, se puede usar la siguiente solución en Ubuntu 10.04 / openssl 0.9.8k para obtener el comportamiento esperado:

$ 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

Y con la verificación falla:

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

Situación actual

Este es un problema de Ubuntu. Por ejemplo, con Fedora 20's openssl 1.0.1e o Fedora 29's openssl 1.1.1, esta solución no es necesaria porque el problema no se puede reproducir. Eso significa que al especificar una opción como -CAfileo -CApath, no se agrega un directorio predeterminado del sistema de certificados a la lista de búsqueda de directorios en los sistemas Fedora.

En Ubuntu 16 con openssl 1.0.2g, el problema aún está presente.

También está presente en CentOS 7 con openssl-1.0.2k-16, y desafortunadamente, la solución anterior no ayuda allí y el gnutls-3.3.29-8 falla debido a tipos de paquetes TLS desconocidos / inesperados.

maxschlepzig
fuente
Tengo la versión 1.0.2g y todavía tiene este error. Para empeorar las cosas, el indicador -verify_return_error no tiene ningún efecto y la conexión TLS continúa incluso si el certificado es incorrecto.
takumar
@takumar, volví a probar esto en Ubuntu 16 con openssl 1.0.2g-1ubuntu4.14 y puedo confirmar, sin la solución, esta prueba de openssl todavía falla. Pero al menos con la solución recibo el mensaje de error esperado, y con la solución y -verify_return_errorel comando termina con el estado de salida 1. Con Fedora 29 y openssl-1.1.1-3.fc29.x86_64, todo funciona como se esperaba, es decir, la solución no es necesario
maxschlepzig
En 2019, este parece ser el caso en macOS. Además, algunos sistemas pueden admitir -no-CAfile( No cargue los certificados de CA confiables desde la ubicación predeterminada del archivo ) y -no-CApath( No cargue los certificados de CA confiables desde la ubicación predeterminada del directorio ), pero mi sistema no lo hace, así que no los he probado.
Arjan