Multi-CA Capable OCSP Responder in OpenSSL

Greg McLearn Common Criteria, Tools

At Lightship, we use a lot of open-source tools to perform our testing. Because of the nature of the tests we perform, we often find that these tools can be a bit too rigid. One specific example is that of the ocsp sub-tool provided in the apps directory of OpenSSL. In this blog post, we will describe the changes we made to the OCSP responder subtool and point to our implementation on github for your use and consideration.

In our testing environment, tool selection is important in providing assurance in the test results. We gravitate toward open-source, highly flexible and industry-standard tools. In addition, we will choose lightweight tools over heavier-weight tools where possible. This is because we will often dynamically spin up multiple instances of tools with highly ephemeral characteristics. When testing OCSP responders, the OpenSSL ocsp sub-tool is our tool of choice as it meets all of the above properties…with one small exception: it can’t serve multiple CAs from a single port.

The OCSP responder sub-tool first added to OpenSSL 0.9.7 is an example of a great little test tool that helps verify basic behaviour of OCSP requests. It never claims to be a fully-functional OCSP responder and is expressly noted as being a test tool only — not to be used for production purposes. For example, it only covers the POST portion of RFC 6960 and it was never designed to handle multiple CAs. Most of the time, this is fine. However, every once in a while, we get test targets which implement a single URI to communicate with the responder.

To this end, we have published our variant of the ocsp sub-tool on our github (along with the original->custom patch diff). This is published as-is, without any warranty and is designed and offered as a test tool only. It is a modification of the OpenSSL ocsp sub-tool which effectively permits multiple CAs, signing keys and index files to be used.

One of the goals was to offer multi-CA support without having to force users to extensively describe additional configuration in a configuration file. This means an expanded command-line, but in a logical, reasonably sane fashion.

The original OpenSSL ocsp subtool, when operating as a responder for a fictitious ‘root’ CA, would be used similar to this:

apps/openssl ocsp \
  -index root-db.ocsp.txt \
  -CA root.cert.pem \
  -rsigner root-ocsp-signer.cert.pem \
  -rkey root-ocsp-signer.key.pem \
  -port 8888 -text

(There is also -rother to provide a certificate chain for the response signer certificate and the originally undocumented flag -rmd to set the message digest algorithm, if necessary.)

The above command-line will work with our variant as well, without any modification. However, to use multiple CAs, we can add as many of the above flags as necessary with an index number to designate their position:

apps/openssl ocsp \
  -index root-db.ocsp.txt \
  -CA root.cert.pem \
  -rsigner root-ocsp-signer.cert.pem \
  -rkey root-ocsp-signer.key.pem \
  \
  -index1 int1-db.ocsp.txt \
  -CA1 int1.cert.pem \
  -rsigner1 int1-ocsp-signer.cert.pem \
  -rkey1 int1-ocsp-signer.key.pem \
  -rmd1 sha512 \
  -rother1 int1-ocsp-cert-chain.cert.pem \
... \
  -index31 int31-db.ocsp.txt \ 
  -CA31 int31.cert.pem \ 
  -rsigner31 int31-ocsp-signer.cert.pem \
  -rkey31 int31-ocsp-signer.key.pem \
  -port 8888 -text

The unnumbered flags are index 0; up to 31 additional indexes can be provided (for a total of 32 CAs being handled). Not all options need to be provided for all indexes (as you can see we provide the message digest algorithm for index 1, but not index 0 as well as a cert chain for the int1 CA and not the root CA). Additional notes are provided in the standard usage screen.

When the multi-CA OCSP responder receives a request, it will iterate through each of the 32-defined responder indices. For each index that has a database, a CA and a signing key, the OCSP responder will determine if the certificate in the request has been issued by the corresponding CA. If it has, then the state of the certificate will be determined in the associated database. The entire response will be signed using the designated signing key using the defined message digest (sha256 by default); the certificate and optional certificate chain being returned as part of the response. It is up to the requester to ensure that the response meets their needs.

The multi-CA OCSP responder does not attempt to protect the user from themselves: if the same certificate is loaded in multiple databases, or if the same CA is loaded multiple times, the application will only use the first instance as discovered in numerical order. If the database is not formatted correctly, this generally results in a parse error or a response error — behaviour similar to the original (the CA DB format is not officially documented, but is easy to understand and tailor). The intention was to perform no more and no less checks than are performed in the original OpenSSL ocsp subtool regarding parameter usage or loaded certificate status.

Finally, if a certificate request cannot be fulfilled by the OCSP responder across any of the defined CAs, then the response will be unknown and the response will be signed by the first located signing key. (A statement is issued to stderr to this effect.) This is an awkward semantic and is a byproduct of hosting multiple CAs on a single responder.

There you have it. A simple, relatively naive, multi-CA OCSP responder based on the original OpenSSL ocsp subtool. It is useful for testing products when a lightweight, easy to configure multi-CA OCSP responder is needed, and that’s about it. It is not meant as an RFC 6960 request verification tool and the onus remains with the requester to ensure the response is valid within their trust context.

 

For more information on how Lightship can help your organization with all your Common Criteria and FIPS 140-2/3 requirements, please contact us!