As X509_STORE_CTX_init requires its arguments to outlive
the store context, we take ownership of all of them
and put them in the store context's ex data, ensuring
the soundness of the operation without the mandatory
call to X509_STORE_CTX_cleanup after a closure
is run.
As X509_STORE_CTX_init may fail after setting some values
that should outlive the store context, we must ensure we
clean things up on its error path too.
We also know it's always ok to call X509_STORE_CTX_cleanupas X509_STORE_CTX_init starts with a call to it.
* Revert "feat(x509): Implement `Clone` for `X509Store` (#339)"
This reverts commit 49a8d0906a.
See <https://github.com/cloudflare/boring/pull/120>.
* Ensure Clone is not added to X509Store
* Add comment about why X509Store must not implement Clone
---------
Co-authored-by: Kornel <kornel@cloudflare.com>
This method reliably retrieves the certificate the `X509_STORE_CTX` is
verifying, unlike `X509_STORE_CTX_get_current_cert`, which may return
the "problematic" cert when verification fails.
Newer versions of FIPS don't need any special casing in our bindings,
unlike the submoduled boringssl-fips. In addition, many users currently
use FIPS by precompiling BoringSSL with the proper build tools and
passing that in to the bindings.
Until we adopt the Update Stream pattern for FIPS, there are two main
use cases:
1. Passing an unmodified, precompiled FIPS validated version of
boringssl (fips-precompiled)
2. Passing a custom source directory of boringssl meant to be linked
with a FIPS validated bcm.o. This is mainly useful if you carry
custom patches but still want to use a FIPS validated BoringCrypto.
(fips-link-precompiled)
This commit introduces the `fips-precompiled` feature and removes the
`fips-no-compat` feature.
The "fips" feature implies use of a prebuilt boringSSL. The boringSSL
API consumed by `SslCurve` in incompatible with older versions of
boringSSL.
In the `ffi` bindings, the following symbols don't exist in older
builds:
* NID_X25519MLKEM768
* SSL_CURVE_X25519_MLKEM768
* NID_X25519Kyber768Draft00Old
The following symbols have been renamed:
* SSL_CURVE_P256KYBER768DRAFT00 => SSL_CURVE_P256_KYBER768_DRAFT00
* SSL_CURVE_X25519KYBER512DRAFT00 => SSL_CURVE_X25519_KYBER512_DRAFT00
* SSL_CURVE_X25519KYBER768DRAFT00OLD => SSL_CURVE_X25519_KYBER768_DRAFT00_OLD
* SSL_CURVE_P256KYBER768DRAFT00 => SSL_CURVE_P256_KYBER768_DRAFT00
Meanwhile, the `ssl_set_curves_list()` API is stable across these
versions of boringSSL.
These codepoints are added to the `SslCurve` API whenever
"pq-experimental" is enabled. Since this feature is no longer mutually
exclusive with prebuilt boringSSL (`boring-sys` just ignores patches),
we also need to disable this API whenever "fips" is enabled.
Modify the "fips" feature so that it no longer implies "fips-compat".
The latter is no longer needed for recent builds of boringSSL; users who
need older builds will need to enable "fips-compat" explicitly.
Also, remove the "fipps-no-compat" feature, as it's now equivalent to
"fips".
As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no
longer need to make exceptions for the types of BufLen, ProtosLen, and
ValueLen, which means the "fips-compat" feature is no longer needed for
"fips" users.
Currently "fips" implies "fips-compat". To allow users to upgrade
without breaking API compatibility with boring version 4, add a new
feature, "fips-no-compat", that does not imply "fips-compat".
In boring 5, we should remove "fips-no-compat" and decouple
"fips-compat" from "fips".
This algorithm is advertised with "kx-client-pq-supported" but not with
"preferred". However the algorithm is wide spread enough that preferring
it is not a significant risk.
See https://github.com/sfackler/rust-openssl/pull/2360 and
https://nvd.nist.gov/vuln/detail/CVE-2025-24898. From the rust-openssl
PR:
`SSL_select_next_proto` can return a pointer into either the client or
server buffers, but the type signature of the function previously only
bound the output buffer to the client buffer. This can result in a UAF
in situations where the server slice does not point to a long-lived
allocation.
Thanks to Matt Mastracci for reporting this issue.
Previously, set_ech_keys would consume the SslEchKeys struct to enforce
the requirement that the struct is immutable after initializing it on a
SSL_CTX. The problem with this is that it requires applications to
needlessly reallocate the SslEchKeys struct if they want to initialize
keys on multiple SSL_CTXs, which is a pretty common pattern. To work
around this, we introduce a builder (SslEchKeysBuilder) that requires
mutable access to add keys to the underlying struct. set_ech_keys takes
in a reference to SslEchKeys, which can only be made via consuming the
builder.
We currently expose this method on `SslContextBuilder`, which is fine
for bootstrapping an `SSL_CTX`, but subsequent attempts to set ECH keys
(like during key rotation) can only happen via `SslContextRef`. Also
update the method on the builder to take an immutable reference to self
because the API is thread safe.
X25519MLKEM768 is the standardised successor of the preliminary
X25519Kyber768Draft00. Latest browsers have switched to X25519MLKEM768.
Cloudflare supports both on the edge.
We've had support for X25519MLKEM768 in this crate for a while, but
didn't enable by default. We're now enabling serverside support by
default. We also let clients advertise support when set
to kx-client-pq-supported.
We don't enable support by default yet for clients set to
kx-client-pq-preferred, as that would cause an extra round-trip due to
HelloRetryRequest if the server doesn't support X25519MLKEM768 yet.
BoringSSL against which we build must support X25519MLKEM768, otherwise
this will fail.
Mid-handshake errors that occur before certificate verification
currently look like this:
```
TLS handshake failed: cert verification failed - Invalid certificate verification context [WRONG_VERSION_NUMBER]
```
Despite no certificate even being received yet, the error complains
about a failed verification. The cause here is that `cert verification
failed` is only omitted if the verification result is `OK`. The default
in BoringSSL before verification runs is `INVALID_CALL`, however.
`INVALID_CALL` is set/returned in these places:
- 44b3df6f03/src/ssl/internal.h (L3904)
- 44b3df6f03/src/ssl/ssl_session.cc (L396)
- 44b3df6f03/src/ssl/ssl_x509.cc (L713)
It is not used anywhere else as a verification result code. To improve
the error message, this commit adds `INVALID_CALL` as a verification
result for which no additional error is dislayed.
As of https://boringssl-review.googlesource.com/c/boringssl/+/64141,
X509_STORE_CTX_cleanup will zero the memory allocated to the
X509_STORE_CTX. Because X509StoreContextRef::init invokes
X509_STORE_CTX_cleanup once the with_context closure has finished,
calling X509StoreContextRef::verify_result (or any API really) is going
to be invalid because memory has been zerod out. This is a pretty big
footgun, so maybe we should consider screaming a bit louder for this
case.
This adds a feature to build against a BoringSSL version compatible with
the current boringssl-fips, but _without_ actually enabling the `fips`
feature.
This can be useful to use with `fips-link-precompiled` while using a
custom BoringSSL version based on the older FIPS branch.
set_surves_list is similar to set_curves, but the curves are specified
by a string. This makes it convenient when the supported curves of
the underlying BoringSSL is not known at compile time.
Also fix a bug in checking return value of SSL_set1_curves_list.