OCSP: What, why, how?

While debugging a problem with OCSP, I had to sit down and understand what it really does and why. So What is OCSP, and why do we use it?

What is OCSP

When we establish a secure connection using the standard SSL mechanism, we trust digital certificates. How can we trust them? Our vendor, for example Microsoft or Red Hat or Mozilla with the Firefox web browser, has a list of certificate authorities (CA) that it trusts, and provides a bundle of these certificates with the software. So when we surf to our online bank, and receive a certificate that is signed by a listed CA, the web browser can check that the signature matches. So far, so good.

From time to time, a certificate might be revoked. Reasons for this could span from security breaches to simply organizational changes. But a certificate that is already signed and delivered to us, is still valid until we are told about the revocation. And there is no automation here. So there is need for a mechanism where we can ask the CA if the certificate is still valid. This is what OCSP does. The CA provides a web service where a user (like a web browser) can look up given certificate, and check that it is not revoked. The response is signed by the CA, and is valid for a few days, to avoid hammering the service for each and every request.

Most web browsers do this automatically, so for your day to day online banking and webmail cruising, you may feel quite sure that you will be warned if a certificate is revoked.

Firefox Screenshot
In Firefox, switching OCSP checking off is an option under advanced settings.

OCSP Stapling

To offload the OCSP service on a CA, there is another mechanism, OCSP Stapling. A web server might download and cache the OCSP information from the CA, and serve this directly to the user at the same time as serving the certificate, thus both offloading the upstream CA OCSP service, and probably saving load time for the user. Modern web/TLS servers like Hitch, Apache, Nginx, and IIS, all have support for OCSP stapling.

You can test if a server has OCSP stapling switched on with the OpenSSL CLI tool:

openssl s_client -connect ialta.no:443 -status < /dev/null \
| grep 'OCSP Response'

The answer should be along the lines of

OCSP Response Data:
  OCSP Response Status: successful (0x0)
  Response Type: Basic OCSP Response

Checking for OCSP by hand

The more programmatically inclined of us might want to know how to check the OCSP information by hand, to make sure our scripts and programs trust certificates that are still valid.

OCSP, the Online Certificate Status Protocol is described in RFC 6960, but the approach is more or less like the following:

  1. Get the certificate that we want to check and its intermediate certificate chain up to the CA
  2. The certificate should include an URL to a web service that does OCSP checking
  3. Send a formatted request to that URL
  4. Check that the answer to the request is signed and valid

OpenSSL has tools to do all this, so let’s have a go.

We’ll use redpill-linpro.com as an example. First we download the certificate and the intermediate certificate chain in one go:

openssl s_client \
  -servername redpill-linpro.com \
  -host redpill-linpro.com \
  -port 443 \
  -showcerts < /dev/null > chain.pem

Next, we split the chain in its separate certificates

n=0
while read i; do
  if [ "$i" = "-----END CERTIFICATE-----" ]; then
    echo $i >> chain-$n.pem
    ((n++))
    continue
  else
    echo $i >> chain-$n.pem
  fi
done < chain.pem

The first certificate in the chain is for the server that we want to check. The second is the first in the intermediate chain, that is, the CA that issued the certificate that we want to check.

mv chain-0.pem cert.pem
mv chain-1.pem issuer.pem

We need to trust the issuer certificate, so we check that it is valid

$ openssl verify issuer.pem
issuer.pem: OK

We need the OCSP check URL, so we extract it from the server certificate.

openssl x509 -noout -ocsp_uri -in cert.pem
    http://ocsp.int-x3.letsencrypt.org/

Finally, we can request a signed OCSP response, and verify it.

$ openssl ocsp \
   -url http://ocsp.int-x3.letsencrypt.org/ \
   -header Host ocsp.int-x3.letsencrypt.org \
   -no_nonce \
   -VAfile issuer.pem \
   -issuer issuer.pem \
   -resp_text \
   -cert cert.pem

   Response verify OK
   cert.pem: good
     This Update: Dec 13 11:00:00 2016 GMT
     Next Update: Dec 20 11:00:00 2016 GMT

So we have checked the certificate. It is still valid, and it should not be necessary to check this again until next week.

For the option details, have a look at the man-page ocsp(1).

But wait, we did not check if the issuer intermediate certificate was still valid. While this should seldom be necessary, let’s check all the way back to the CA bundle, to make our exercise complete.

First find who issued the intermediate certificate:

openssl x509 -in issuer.pem -text -noout | grep 'Issuer:'
Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3

This looks like a root CA that should be in the trusted CA bundle that was provided by your OS vendor.

Note that if there are more than one certificate in the intermediate chain, you will have to loop over the algorithm below using the next certificate in the chain, before ending up at the trusted certificates in the ca bundle.

Extract all the trusted certificates from the CA bundle. On Fedora, you may find the bundle in /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (Homework: Do this more effectively in Perl).

$ n=0;
$ while read i; do
  if [ "$i" = "-----END CERTIFICATE-----" ]; then
    echo -n '#'
    echo $i >> trust-$n.pem
    ((n++)); continue
  else
    echo $i >> trust-$n.pem
  fi
done < /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
$ ls trust*.pem | wc -l
155

155 trusted certificates, what a bundle! Which of these provides the signature we are looking for?

$ for i in trust-*.pem; do
    echo -n '.'
    openssl x509 -in $i -text -noout |\
    grep -q 'Subject: O=Digital Signature Trust Co., CN=DST Root CA X3$' && \
    echo && echo $i && break
  done
  trust-47.pem

Finally, we can do the OCSP check also on the issuer certificate

$ openssl x509 -noout -ocsp_uri -in issuer.pem
http://isrg.trustid.ocsp.identrust.com

$ openssl ocsp
    -url http://isrg.trustid.ocsp.identrust.com \
    -header Host isrg.trustid.ocsp.identrust.com \
    -no_nonce \
    -VAfile trust-47.pem \
    -issuer trust-47.pem \
    -resp_text \
    -cert issuer.pem

  Response verify OK
  issuer.pem: good
    This Update: Dec 15 11:28:59 2016 GMT
    Next Update: Dec 16 11:28:59 2016 GMT

Conclusion: While a bit cumbersome, it is possible to verify that a certificate and its intermediate chain are both valid and not revoked, by issuing OCSP requests using the OpenSSL command line toolkit.

A script automating this, except checking the issuer certificate, may be found at https://ingvar.fedorapeople.org/varnish/check_ocsp.sh.txt.

Ingvar Hagelund

Team Lead, Application Management for Media at Redpill Linpro

Ingvar has been a system administrator at Redpill Linpro for more than 20 years. He is also a long time contributor to the Fedora and EPEL projects.

Containerized Development Environment

Do you spend days or weeks setting up your development environment just the way you like it when you get a new computer? Is your home directory a mess of dotfiles and metadata that you’re reluctant to clean up just in case they do something useful? Do you avoid trying new versions of software because of the effort to roll back software and settings if the new version doesn’t work?

Take control over your local development environment with containerization and Dev-Env-as-Code!

... [continue reading]

Ansible-runner

Published on February 27, 2024

Portable Java shell scripts with Java 21

Published on February 21, 2024