Bug #9889
closedCannot validate Certificates against Certificate Revocation Lists for Intermediate Certificate Authorities
100%
Description
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 485491b5 $ openssl crl -hash -noout -in CR.crl 485491b5 $ openssl x509 -hash -noout -in CI.crt 39ba1131 $ openssl crl -hash -noout -in CI.crl 39ba1131 $ 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 serial=02 $ openssl x509 -serial -noout -in jimp.crt serial=02 $ 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.
Files
Updated by Jim Pingle about 1 year ago
- Status changed from New to Feedback
- Target version set to 2.8.0
- % Done changed from 0 to 100
- Plus Target Version set to 23.09
We received a submission privately from MalteHillmann with a fix for this. It's a problem in the security/php-openssl_x509_crl
we use to generate CRLs:
--- a/a/usr/local/share/openssl_x509_crl/X509_CERT.php
+++ b/b/usr/local/share/openssl_x509_crl/X509_CERT.php
@@ -90,7 +90,7 @@ class X509_CERT
$ret->content['keyIdentifier']->setType(0, false, ASN1_CLASSTYPE_CONTEXT);
//Copy subject
- $subject = $cert_root->content[0]->content[$is_v1 ? 4 : 5];
+ $subject = $cert_root->content[0]->content[$is_v1 ? 2 : 3];
//Write into authorityCertIssuer ([4] EXPLICIT Name)
$ret->content['authorityCertIssuer'] = new ASN1_SEQUENCE; //it's GeneralNames
I have added a patch file for this in the security/php-openssl_x509_crl
port so we will have the fix on future versions:
https://github.com/pfsense/FreeBSD-ports/commit/e573756c98d1181583fee0f7d818c6be0ea3da0e
I will also be adding an entry for this to the system patches package recommended patches for Plus 23.05.1 / CE 2.7.0 shortly.
Updated by Jim Pingle about 1 year ago
Added to System Patches: https://github.com/pfsense/FreeBSD-ports/commit/ade361d4fbbaf4c40b55fdd0838e6b1594b5f801
Updated by Jim Pingle about 1 year ago
- Subject changed from CRL check for Intermediate CA CRLs fails to Cannot validate Certificates against Certificate Revocation Lists for Intermediate Certificate Authorities
Updating subject for release notes.
Updated by Jim Pingle about 1 year ago
- Status changed from Feedback to Resolved
Working as expected in current dev snapshots.
Updated by Chris Merchant about 1 year ago
This patch appears to break two items in 2.7.0-RELEASE (at least from what I have discovered so far)
1. Version information section no longer confirms installed version status
2. In Package Manager, 'Please wait while the list of packages is retrieved and formatted' is as far as that function will proceed. It will not show installed packages status.
Once the 9889 patch is reverted, the two items above function properly again.
Updated by Jim Pingle about 1 year ago
Chris Merchant wrote in #note-6:
This patch appears to break two items in 2.7.0-RELEASE (at least from what I have discovered so far)
1. Version information section no longer confirms installed version status
2. In Package Manager, 'Please wait while the list of packages is retrieved and formatted' is as far as that function will proceed. It will not show installed packages status.Once the 9889 patch is reverted, the two items above function properly again.
1. Version information where? Dashboard? Upgrade check? Somewhere else?
2. Do you get errors with pkg-static update -f
from the CLI?
I can't replicate either of those problems here. The patch would not affect any certificate operations done by pkg
which is what would be involved in upgrade and package operations.
The patch here only affects CRL operations for GUI certificates/chains and those have no involvement in any outbound connections from the firewall itself.
Updated by Chris Merchant about 1 year ago
1. Version information on dashboard. I've just applied the patch again, and the readout is now 'Unable to check for updates'.
2. The shell command eventually times out with the browser (Brave) throwing a 504 Gateway Time-out.
No biggie from your description, just thought you'd like to be aware. cheers
Updated by Jim Pingle about 1 year ago
- Target version changed from 2.8.0 to 2.7.1