ssl_openssl: Fix some CRL mixups #844
Open
+34
−54
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi all! I tried to send this to openvpn-devel but it looks like it might not have gotten through? (I'm probably confused or just did something wrong.) It sounds like you all do look at GitHub though, so I figure I'll start here and we can figure out the mailing list step afterwards?
I've tested this by making sure things build and that the tests pass. However, it looks like some tests were skipped because they require manually configuring some things in ways I hadn't figured out. It's also unclear to me how well-tested CRL support is. There's no mention of CRLs in the tests directory. I'm not sure how you all test CRL-related changes.
There are two ways to load CRLs in OpenSSL. They can be loaded at the
X509_STORE
, shared across verifications, or loaded per verification at theX509_STORE_CTX
.OpenVPN currently does the former. However, it also supports CRL reloading, and tries to reload the CRL file before each connection. OpenSSL does not really have a good way to unload objects from an
X509_STORE
. OpenVPN currently does it by grabbing theSTACK_OF(X509_OBJECT)
out of theX509_STORE
and manually deleting all the CRLs from it.This mutates an OpenSSL internal object which bumps into problems if OpenSSL ever switches to a more efficient representation. See openssl/openssl#28599
(It's also not thread-safe, though it doesn't look like that impacts OpenVPN? Actually even reading that list doesn't work. See CVE-2024-0397. This OpenSSL API was simply broken.)
Additionally, this seems to cause two OpenVPN features to not work together. I gather
backend_tls_ctx_reload_crl
is trying to clear the CRLs loaded from last time it ran. Buttls_ctx_load_ca
with a ca_file can also load CRLs.tls_ctx_load_ca
with ca_path will also pick up CRLs andbackend_tls_ctx_reload_crl
actually ends up clobbering some stateX509_LOOKUP_hash_dir
internally maintains on theX509_STORE
. Likewise,tls_verify_crl_missing
can get confused betweenbackend_tls_ctx_reload_crl
's crl_file-based CRLs and CRLs fromtls_ctx_load_ca
.Avoid all this by tracking the two CRLs separately.
crl_file
-based CRLs now go onto aSTACK_OF(X509_CRL)
tracked on thetls_root_ctx
. Now this field can be freely reloaded by OpenVPN without reconfiguring OpenSSL. Instead, pass the current value into OpenSSL at verification time. To do so, we need to useSSL_CTX_set_cert_verify_callback
, which allows swapping out theX509_verify_cert
call, and also tweaking theX509_STORE_CTX
configuration before starting certificate verification.Context:
SSL_CTX_set_cert_verify_callback
and the existing verify_callback are not the same.SSL_CTX_set_cert_verify_callback
wraps the verification whileverify_callback
is called multiple times throughout verification. It's too late to reconfigureX509_STORE_CTX
inverify_callback
.verify_callback
is usually not what you want. Sometimescurrent_cert
anderror_depth
don't quite line up, andcert_hash_remember
may end up called multiple times for a single certificate.I suspect some of the other
verify_callback
logic would also be better done in the new callback, but I've left it alone to keep this change minimal.verify_callback
is really only usable for suppressing errors. Application bookkeeping is better done elsewhere.