how to use curl to verify if a site's certificate has been revoked?

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

curl --cacert GeoTrust_Global_CA.pem --crlfile gtglobal.pem -v 

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

* About to connect() to 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: 

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 . 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).
6

5 Answers

That's my everyday script:

curl --insecure -vvI 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= * 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 left intact 

Apparently, you cannot just verify a site with a single simple request. See 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 

We get

--- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN= 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 | openssl x509 -inform der -text 

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

 X509v3 CRL Distribution Points: URI: Authority Information Access: OCSP - URI: 

Now we can manually inspect crl:

curl | openssl crl -inform der -text curl | 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 -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= * start date: 2014-04-09 11:40:11 GMT * expire date: 2014-07-08 00:00:00 GMT * subjectAltName: matched * issuer: C=US; O=Google Inc; CN=Google Internet Authority G2 * SSL certificate verify ok. 
1

curl since 7.41.0 has a --cert-status option, but it does not work for me:

$ curl --cert-status curl: (91) No OCSP response received 

It appears maybe it only works if the server is configured with OCSP stapling, and it does not cause curl to make its own OCSP request.

I had better success using openssl with the steps at

Fetch the cert:

$ openssl s_client -connect 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > /tmp/google.pem 

Output the cert's OCSP URI:

$ openssl x509 -noout -ocsp_uri -in /tmp/google.pem 

Build a /tmp/chain.pem from the certs 1-n output by:

openssl s_client -connect -showcerts 2>&1 < /dev/null 

Copy each cert into the chain.pem file, including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- and everything in between. Do not include the 0th cert since that's in the google.pem file.

Make the OCSP request:

openssl ocsp -issuer /tmp/chain.pem -cert /tmp/google.pem -text -url ... Response verify OK /tmp/google.pem: good This Update: Mar 24 12:40:59 2020 GMT Next Update: Mar 31 12:40:59 2020 GMT 

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

2

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 1>/dev/null

# curl -L -v -s 1>/dev/null * About to connect() to port 443 (#0) * Trying 216.58.208.35... * Connected to (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= 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: * issuer: CN=Google Internet Authority G3,O=Google Trust Services,C=US > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: > 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 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 left intact 
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like