22

To check if the certificate for google.com has been revoked, I tried the following command:

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

, but I got the dreaded "SSL certificate problem" error:

* 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

I guess this error is not correct, since Google should have a valid certificate.

Do you know how I could issue a curl command that does this correctly?

More details

If you're wondering why I used those specific files (GeoTrust_Global_CA.pem and gtglobal.pem) in the curl command, this is how I proceeded:

  • I first looked at what CA issued the certificate for https://www.google.com. Turns out it is GeoTrust Global CA;
  • I downloaded the GeoTrust Global CA root certificate from here (this is the GeoTrust_Global_CA.pem file);
  • I downloaded the corresponding CRL (certificate revocation list) from here (this is the gtglobal.pem file).
  • Seems to me like it already works? I'm not sure what your question is. – mtak Apr 16 '14 at 11:06
  • 1
    @mtak - Considering the verification failed it seems the author is asking the reason why the certificate failed to verify, the certificate should have been verified, considering the current Google certificate has not been revoked. – Ramhound Apr 16 '14 at 11:22
  • Sorry, I realize now that the question is a bit unclear. I will edit it. @Ramhound that is correct :) – Claudiu Apr 16 '14 at 12:16
  • I don't understand in principle why you would be connecting to google.com to confirm whether a certificate (which you already received during the TLS handshake) is present or not on a CRL (which you have already downloaded). Shouldn't you do that on your own computer? What if google.com was actually a MITM? – Craig Hicks Sep 17 '17 at 15:45
  • Here is an example of manually checking if a cert. is on a CRL once both the cert. and CRL are in local memory --- feistyduck.com/library/openssl%2dcookbook/online/… – Craig Hicks Sep 17 '17 at 15:47
10

Apparently, you cannot just verify a site with a single simple request. See https://stackoverflow.com/questions/16244084/how-to-programmatically-check-if-a-certificate-has-been-revoked?lq=1 and older related questions on stackoverflow.

curl did not work with Certificate Revocation Lists for me either, neither on Windows, nor on Linux. Why should you use curl? Openssl seems more appropriate:

openssl s_client -connect www.google.com:443

We get

---
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
---

Then we can inspect some certificate:

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

grep crl in the output of the above command. The interesting parts are:

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

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

Now we can manually inspect 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

Now we see a list of revoked certificates. IMHO, using curl is not enough, another program is required to check certificates. By doing a simple

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

we see that curl is not checking revocations (not even connecting to the relevant places). It just says

* 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.
  • 2
    Why do you say curl can't do this? The curl manpage specifies the '--crlfile' option which exists exactly for this purpose. Also, curl is compiled with openssl and uses it for its crypto-related operations (including certificates) - it's just not working for me, trying to find out why :) – Claudiu Apr 29 '14 at 7:52
9

That's my everyday script:

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
3

Apparently this is a pretty common problem on Windows, as this question on stackoverflow shows. I am specifically referring to the answer by user Артур Курицын, which I quote here for your convenience:

It's a pretty common problem in Windows. You need just to set cacert.pem to curl.cainfo.

Since PHP 5.3.7 you could do:

  1. download http://curl.haxx.se/ca/cacert.pem and save it somewhere.
  2. update php.ini -- add curl.cainfo = "PATH_TO/cacert.pem"

Otherwise you will need to do the following for every cURL resource:

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

Also, this article might also be useful.

  • From what I know, the command-line option '--cacert' (which I used) is the equivalent of setting the CURLOPT_CAINFO option in libcurl, so I don't think this is the problem in my case (also, I'm using Linux) – Claudiu Apr 25 '14 at 10:45
  • Not exactly the answer to the question, still very useful information! – amenthes Sep 13 '15 at 20:10
1

One way I found working is similar to others already exposed, only it sends the output to dev/null and it is relatively quick to use.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.