Checking Your TLS Certificate Revocation Status

TLS certificates are used to secure communication between web browsers and websites. Under certain circumstances (most notably, but not exclusively, loss of control of the private signing key used to make the certificate) the certificate will be revoked. The only people who can revoke a certificate are the Certificate Authority who issued the cert - who will usually do this under order from the certificate owner.

If you search the web for information about certificate revocation, most of the top results will be about how broken the system is. I'm inclined to agree: if the idea is to revoke the certificate because you've lost control of it, that means that the certificate itself is no longer a reliable resource and you need another channel to find out if the certificate is (still) valid. A good discussion of that can be found at StackExchange.

Certificate expiry is passive and expected. When you purchase a certificate, the Certificate Authority (CA) tells you how long the certificate will last. If in doubt, you can at any time check the certificate expiry in a web browser (if the cert is on a website) or at the command line. I've included all the technical stuff below (you'll need a certificate and the issuing C.A.'s Intermediate certificate). The expiry exists for security reasons, but also allows reliable planning around renewal so that you never have an expired certificate on a server.

Certificate revocation on the other hand is active and unexpected. It's done when there are security problems found with the certificate, and it can only be done by the CA. I found this excellent short video (3 minutes) about the reasons and how-to of certificate revocation:

https://www.comodoca.com/en-us/support-videos/revoking-a-security-certificate/

That's Comodo, but I'm sure the process is quite similar at other C.A.s.

There are two ways to check to see if a certificate has expired: the CRL or Certificate Revocation List, and OCSP or Online Certificate Status Protocol. To be practical, the CRL has to be downloaded frequently (apparently it forcibly goes stale after 24 hours). OCSP appears to be more widely used at this point, as it's simpler and allows an immediate query-response for any certificate. The one potential advantage of the CRL is that it can list a reason for revocation ... although with the certificate I was investigating, no reason was given.


About openssl on OS X

Non-Mac users, skip this section. Mac users, go do this:

$ brew install openssl

Do it NOW. And then ALWAYS use the full path to the executable:

$ /usr/local/opt/openssl/bin/openssl

This is because OS X provides a five year old version of openssl. I very much doubt it's secure, but even if it is it's lacking dozens of features and will return incorrect answers for many queries.


At the Command Line

All the work that follows was with a legitimately revoked TLS certificate. However, it didn't belong to 'www.example.com'.

Checking the certificate expiry date:

$ openssl x509 -enddate -noout -in www.example.com
notAfter=Jan 11 12:00:00 2020 GMT

Checking the revocation via OCSP:

$ openssl x509 -in www.example.com -noout -ocsp_uri   # get the OCSP URL
http://ocsp.digicert.com
$ openssl ocsp -no_nonce -issuer IntermediateCA.crt -cert www.example.com -url http://ocsp.digicert.com -VAfile IntermediateCA.crt
Response verify OK
www.example.com: revoked
        This Update: Feb 28 07:20:56 2019 GMT
        Next Update: Mar  7 06:35:56 2019 GMT
        Revocation Time: Feb  3 01:04:29 2019 GMT

Checking the revocation via CRL:

$ openssl x509 -in www.example.com -noout -text | grep crl   # find the CRL URL
                  URI:http://crl3.digicert.com/sha2-ev-server-g2.crl
                  URI:http://crl4.digicert.com/sha2-ev-server-g2.crl
$ wget http://crl3.digicert.com/sha2-ev-server-g2.crl   # download the CRL
... # lots of output
$ openssl x509 -in www.example.com -noout -serial   # get the cert serial number
serial=016B009757D72FD6CB8FC8159CC58C0E
$ openssl crl -inform DER -text -in sha2-ev-server-g2.crl | grep -A 1 016B009757D72FD6CB8FC8159CC58C0E   # search the CRL for the serial
    Serial Number: 016B009757D72FD6CB8FC8159CC58C0E
        Revocation Date: Feb  3 01:04:29 2019 GMT

How to fetch certificates from an existing website:

$ openssl s_client -connect duckduckgo.com:443 -showcerts

The port number is required in this context (':443') as openssl doesn't assume it knows what port is being used - presumably because it's used for many types of encryption besides websites.