Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Openssl telling certificate has expired when it has not

I'm having an issue with curl and openssl reporting a client certificate as expired, even though it's notAfter date is in the future:

# echo | openssl s_client -showcerts -connect example.com:443 2>&1 | grep Verify
    Verify return code: 10 (certificate has expired)

But

# echo | openssl s_client -showcerts -connect example.com:443 2>&1 | openssl x509 -noout -dates
notBefore=Oct 17 00:00:00 2011 GMT
notAfter=Oct 21 12:00:00 2014 GMT

System date is correct. Firefox is not showing any error for that site's cert either. Openssl versions I tried are OpenSSL 1.0.1e-fips 11 Feb 2013 and OpenSSL 1.0.1f 6 Jan 2014. I've found a similar-looking issue here where the author claims that the issue is missing in openssl 0.9.8, but present in 1.0.1.

Why is this happening?

like image 976
Fluffy Avatar asked Jul 28 '14 10:07

Fluffy


3 Answers

My problem was that the certificate did expire, but not this particular one, but one in the signing chain.

For example, for google this command openssl s_client -showcerts -connect google.com:443 </dev/null | openssl x509 -noout -dates shows:

notBefore=Oct  6 12:37:54 2016 GMT
notAfter=Dec 29 12:28:00 2016 GMT

However just openssl s_client -showcerts -connect google.com:443 </dev/null shows not 1, but 3 certificates (enclosed in ---BEGIN/END CERTIFICATE--- parts), the first one is of google and it is the one actually checked. To verify this, I've copied (there should probably be a less manual way) the first one to /tmp/google and the last one to /tmp/geotrust, now running openssl x509 -noout -dates < /tmp/google gives me:

notBefore=Oct  6 12:37:54 2016 GMT
notAfter=Dec 29 12:28:00 2016 GMT

Which matches the first command's output, and openssl x509 -noout -dates < /tmp/geotrust:

notBefore=May 21 04:00:00 2002 GMT
notAfter=Aug 21 04:00:00 2018 GMT

Which is different and was not shown before. So in the end my problem was that for one of the higher authority certificates was indeed outdated.

And BTW as the comment to the question suggests upgrading OS to fix this issue - I imagine the cause is the same. OS comes with a bunch of root certificates, so if you have crazy old OS, some of those might expire, you can either upgrade those root certs, or the whole OS to fix the issue.

Also handy to know that running without showcerts gives you a nice view of the cert chain - openssl s_client -connect google.com:443 </dev/null:

---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.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
---

All of these need not to be expired.

like image 186
Fluffy Avatar answered Oct 07 '22 17:10

Fluffy


I got the similar problem today and surfed here with the intention of finding the answer. Fortunately, I got the answer by myself. Here is how I got it:

  1. as I got "Verify return code: 10 (certificate has expired)" error on a box, I tried another box and didn't get the error against the same SSL site, which is actually "verify error:num=20:unable to get local issuer certificate" (acceptable to me)
  2. then I thought the root cause should be within the first box seeing that error. The most possible reason could be some different CA certificates in the trust store, although I still didn't know where it was for the first box
  3. to get the file impacting the cert validation verification, I prepended "strace" before "openssl s_client ...", and carefully read the files shown in the big output area, especially the ones near the "Verify return code: 10 (certificate has expired)" error. I got 2 suspect files
  4. I ran "openssl x509 -text -in {filename}" for validating the 2 files, and succeeded to confirm one of them was the root cause as it's expired. This is an intermediate certificate

With that being said, please check if there is any intermediate/root certificates that have expired in your local trust store (maybe /usr/lib/ssl/certs/ for openssl), which "poisons" the verification for openssl client command or curl command.

like image 26
VictorYang Avatar answered Oct 07 '22 18:10

VictorYang


If you just execute openssl s_client -connect <server>:<port>, it should show you at the end after the Verify... line something like:

---
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify error:num=10:certificate has expired
notAfter=May 30 10:48:38 2020 GMT
read:errno=10093

Basically this failure message mentions the certificate in the certificate chain that was not verified and why it happened.

like image 1
Wladimir Safonov Avatar answered Oct 07 '22 16:10

Wladimir Safonov