¿Cómo usar curl para verificar si el certificado de un sitio ha sido revocado?

26

Para verificar si el certificado de google.com ha sido revocado, probé el siguiente comando:

curl https://www.google.com --cacert GeoTrust_Global_CA.pem --crlfile gtglobal.pem -v

, pero recibí el temido error "problema de certificado SSL":

* About to connect() to www.google.com port 443 (#0)
*   Trying 81.24.29.91... connected
* successfully set certificate verify locations:
*   CAfile: GeoTrust_Global_CA.pem
  CApath: /etc/ssl/certs
* successfully load CRL file:
*   CRLfile: gtglobal.pem
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html

Supongo que este error no es correcto, ya que Google debería tener un certificado válido.

¿Sabes cómo podría emitir un comando curl que haga esto correctamente?

Más detalles

Si se pregunta por qué usé esos archivos específicos (GeoTrust_Global_CA.pem y gtglobal.pem) en el comando curl, así es como procedí:

  • Primero miré qué CA emitió el certificado para https://www.google.com . Resulta que es GeoTrust Global CA;
  • Descargué el certificado raíz de GeoTrust Global CA desde aquí (este es el archivo GeoTrust_Global_CA.pem);
  • Descargué la CRL (lista de revocación de certificados) correspondiente desde aquí (este es el archivo gtglobal.pem).
Claudiu
fuente
¿Me parece que ya funciona? No estoy seguro de cuál es tu pregunta.
mtak
1
@mtak: considerando que la verificación falló, parece que el autor pregunta por qué el certificado no pudo verificar, el certificado debería haberse verificado, dado que el certificado actual de Google no ha sido revocado.
Ramhound
Lo siento, ahora me doy cuenta de que la pregunta no está clara. Lo editaré @Ramhound eso es correcto :)
Claudiu
En principio, no entiendo por qué se conectaría a google.com para confirmar si un certificado (que ya recibió durante el protocolo de enlace TLS) está presente o no en una CRL (que ya ha descargado). ¿No deberías hacer eso en tu propia computadora? ¿Qué pasaría si google.com fuera realmente un MITM?
Craig Hicks
Aquí hay un ejemplo de comprobación manual de un certificado. está en una CRL una vez que ambos cert. y CRL están en la memoria local --- feistyduck.com/library/openssl%2dcookbook/online/…
Craig Hicks

Respuestas:

12

Ese es mi guión cotidiano:

curl --insecure -v https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* Server certificate:/ { cert=1 } /^\*/ { if (cert) print }'

Ouput:

* Server certificate:
*    subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*    start date: 2016-01-07 11:34:33 GMT
*    expire date: 2016-04-06 00:00:00 GMT
*    issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*    SSL certificate verify ok.
* Server GFE/2.0 is not blacklisted
* Connection #0 to host www.google.com left intact
Antonio Feitosa
fuente
10

Aparentemente, no puede simplemente verificar un sitio con una sola solicitud simple. Consulte /programming/16244084/how-to-programmatic-check-if-a-certificate-has-been-revoked?lq=1 y preguntas relacionadas anteriores sobre stackoverflow.

curl tampoco funcionó para mí con las listas de revocación de certificados , ni en Windows ni en Linux. ¿Por qué deberías usar curl ? Openssl parece más apropiado:

openssl s_client -connect www.google.com:443

Obtenemos

---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---

Entonces podemos inspeccionar algunos certificados:

curl http://pki.google.com/GIAG2.crt | openssl x509 -inform der -text

grep crlen la salida del comando anterior. Las partes interesantes son:

        X509v3 CRL Distribution Points:
            URI:http://crl.geotrust.com/crls/gtglobal.crl

        Authority Information Access:
            OCSP - URI:http://gtglobal-ocsp.geotrust.com

Ahora podemos inspeccionar manualmente crl:

curl http://crl.geotrust.com/crls/gtglobal.crl | openssl crl -inform der -text
curl http://pki.google.com/GIAG2.crl | openssl crl -inform der -text

Ahora vemos una lista de certificados revocados. En mi humilde opinión, el uso de curl no es suficiente, se requiere otro programa para verificar los certificados. Al hacer un simple

strace curl https://www.google.com   -v

vemos que curl no verifica las revocaciones (ni siquiera se conecta a los lugares relevantes). Solo dice

* Server certificate:
*        subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*        start date: 2014-04-09 11:40:11 GMT
*        expire date: 2014-07-08 00:00:00 GMT
*        subjectAltName: www.google.com matched
*        issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*        SSL certificate verify ok.
Makama
fuente
2
¿Por qué dices que curl no puede hacer esto? La página de manual de curl especifica la opción '--crlfile' que existe exactamente para este propósito. Además, curl se compila con openssl y lo usa para sus operaciones relacionadas con la criptografía (incluidos los certificados), simplemente no funciona para mí, tratando de averiguar por qué :)
Claudiu
3

Aparentemente, este es un problema bastante común en Windows, como muestra esta pregunta en stackoverflow . Me refiero específicamente a la respuesta del usuario Артур Курицын, que cito aquí para su conveniencia:

Es un problema bastante común en Windows. Es necesario sólo para conjunto cacert.pema curl.cainfo.

Desde PHP 5.3.7 podrías hacer:

  1. descargue http://curl.haxx.se/ca/cacert.pem y guárdelo en algún lugar.
  2. actualización php.ini: agregue curl.cainfo = "PATH_TO / cacert.pem"

De lo contrario, deberá hacer lo siguiente para cada recurso cURL:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");

Además, este artículo también podría ser útil.

usuario1301428
fuente
Por lo que sé, la opción de línea de comandos '--cacert' (que usé) es el equivalente a configurar la opción CURLOPT_CAINFO en libcurl, por lo que no creo que este sea el problema en mi caso (también, estoy usando Linux)
Claudiu
¡No es exactamente la respuesta a la pregunta, sigue siendo información muy útil!
Amenthes
1

Una forma en que encontré que funciona es similar a otras ya expuestas, solo que envía el resultado dev/nully es relativamente rápido de usar.

curl -L -v -s https://www.google.de 1>/dev/null

# curl -L -v -s https://www.google.de 1>/dev/null
* About to connect() to www.google.de port 443 (#0)
*   Trying 216.58.208.35...
* Connected to www.google.de (216.58.208.35) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: CN=www.google.de,O=Google LLC,L=Mountain View,ST=California,C=US
*   start date: Okt 23 16:53:00 2018 GMT
*   expire date: Jan 15 16:53:00 2019 GMT
*   common name: www.google.de
*   issuer: CN=Google Internet Authority G3,O=Google Trust Services,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.google.de
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 12 Nov 2018 15:36:17 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< Server: gws
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: 1P_JAR=2018-11-12-15; expires=Wed, 12-Dec-2018 15:36:17 GMT; path=/; domain=.google.de
< Set-Cookie: NID=146=4SDchvTa39-4IskdXfZpgjtm2ym5zzvHVx8g0v39Q1fiOzk26NQl1TGkFMllh_pg8bFWr6x4jG3ODYDWrkn6TXmd0Ewp4DC_N3p1NPlWqdBUfwFR_PTHIXRi8RuTxdA54w9Zr0uNyhN__5xjUdrCLZTLujNEQ2MV9EVwnmxux6o; expires=Tue, 14-May-2019 15:36:17 GMT; path=/; domain=.google.de; HttpOnly
< Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
{ [data not shown]
* Connection #0 to host www.google.de left intact
Pierfrancesco PierQR Aiello
fuente
Esto no parece decirnos nada sobre si el certificado del sitio ha sido revocado. De hecho, según la documentación, curlen Unix no se verifica (a menos que lo compile específicamente con una biblioteca SSL que lo haga automáticamente por usted).
Tripleee