Bug #9889


CRL check for Intermediate CA CRLs fails

Added by Jim Pingle over 3 years ago. Updated over 3 years ago.

Very Low
Target version:
Start date:
Due date:
% Done:


Estimated time:
Plus Target Version:
Release Notes:
Affected Version:
Affected Architecture:


Adding this for tracking, but I don't think it's a bug in pfSense or FreeBSD, but OpenSSL itself. It could potentially be a flaw in the testing methods/setup, if someone sees a problem, definitely give suggestions for other things to try.

There have been a couple reports that CRLs fail to validate against intermediate certificates, primarily in OpenVPN. This appears to be a legitimate problem, but none of the workarounds I have tried seems to help. There are reports that using the ca and crlfile directives in OpenVPN will fail for this, but using capath with a proper setup helps. However, that also fails for me. Both in OpenVPN and directly with OpenSSL commands.

Walking through the process:

I setup a root CA, an intermediate CA signed by the root, and a user certificate issued by both. I made a CRL for the root and the intermediate, and revoked entries on both. I exported this structure to my workstation (Mint using OpenSSL 1.1.1) and I tried the same test with identical results on FreeBSD 12 and pfSense 2.5.0 snapshots.

First, check the issuers and subjects. It's all as expected:

$ openssl x509 -issuer -subject -noout -in CR.crt
issuer=CN = chain-root-ca
subject=CN = chain-root-ca
$ openssl x509 -issuer -subject -noout -in CI.crt
issuer=CN = chain-root-ca
subject=CN = chain-intermediate-ca
$ openssl x509 -issuer -subject -noout -in rootverifytest.crt
issuer=CN = chain-root-ca
subject=CN = rootverifytest
$ openssl x509 -issuer -subject -noout -in jimp.crt
issuer=CN = chain-intermediate-ca
subject=CN = jimp

Next check the CRLs. Note they have the correct issuer and validate OK on their own.

$ openssl crl -issuer -noout -in CR.crl
issuer=CN = chain-root-ca
$ openssl crl -issuer -noout -in CI.crl
issuer=CN = chain-intermediate-ca
$ openssl crl -CAfile CR.crt -noout -in CR.crl
verify OK
$ openssl crl -CAfile CI.crt -noout -in CI.crl
verify OK

Next, CApath requires files named after the hash of the CA. <cahash>.<n> for the CA and <cahash>.r<n> for CRLs. So let's check the hash and then setup some symlinks. I've also tried this using c_rehash on Linux and received the same results. Same as well with copied or renamed files.

$ openssl x509 -hash -noout -in CR.crt
$ openssl crl -hash -noout -in CR.crl
$ openssl x509 -hash -noout -in CI.crt
$ openssl crl -hash -noout -in CI.crl
$ ln -s CR.crt 485491b5.0
$ ln -s CR.crl 485491b5.r0
$ ln -s CI.crt 39ba1131.0
$ ln -s CI.crl 39ba1131.r0

Now let's test the CApath setup to validate the CRLs. They both validate OK.

$ openssl crl -CApath . -noout -in CR.crl
verify OK
$ openssl crl -CApath . -noout -in CI.crl
verify OK

Manually double check the certificate serials and confirm they are revoked in the CRL text:

$ openssl x509 -serial -noout -in rootverifytest.crt
$ openssl x509 -serial -noout -in jimp.crt
$ openssl crl -text -noout -in CR.crl | grep -A1 'Revoked'
Revoked Certificates:
    Serial Number: 02
$ openssl crl -text -noout -in CI.crl | grep -A1 'Revoked'
Revoked Certificates:
    Serial Number: 02

Now let's validate the user certificate signed by the root, and then check it with the root CA CRL. This works as expected (good!), first showing that the certificate is valid and then that it is revoked.

$ openssl verify -CApath . rootverifytest.crt
rootverifytest.crt: OK
$ openssl verify -CApath . -crl_check rootverifytest.crt
CN = rootverifytest
error 23 at 0 depth lookup: certificate revoked
error rootverifytest.crt: verification failed

Now let's try the same with the user certificate signed by the intermediate. It validates OK without the CRL, but checking the CRL, it produces an error:

$ openssl verify -CApath . jimp.crt
jimp.crt: OK
$ openssl verify -CApath . -crl_check jimp.crt
CN = jimp
error 3 at 0 depth lookup: unable to get certificate CRL
error jimp.crt: verification failed

I've tried with -crl_check_all, -extended_crl, and various related combinations, all failed the same way. I've also tried using -CAfile with the chain+CRLs included together and it also failed. Any reference I can find to "unable to get certificate CRL" is not relevant to this setup or involves an error in the setup not present here. Checking with truss/strace there is no obvious source of error either. I see it read the CRL, and also check to see if there is a newer copy, then it stops.

The CA/Cert structure contains nothing private, since it was created only for these tests. I have attached the relevant certificates and CRLs for others to test/confirm if needed.


crl-intermediate-problem.tgz (4.41 KB) crl-intermediate-problem.tgz CA, CRL, and Certificates used in testing Jim Pingle, 11/08/2019 11:00 AM
Actions #1

Updated by Jim Pingle over 3 years ago

  • Description updated (diff)

Also available in: Atom PDF