sync upstream (#74)
* Add fips-precompiled feature to support newer versions of FIPS (#338)
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.
* Release 4.16.0 (#341)
* feat(x509): Implement `Clone` for `X509Store` (#339)
* boring(x509): impl Clone of X509Store
* expose SSL_set_compliance_policy
* fix clippy error
* Use ubuntu-latest for all ci jobs
ubuntu 20.04 is now deprecated:
https://github.com/actions/runner-images/issues/11101
* add SslCurve::X25519_MLKEM768 constant
* Clippy
* Fix linking SystemFunction036 from advapi32 in Rust 1.87
* rustfmt ;(
* build: Fix the build for 32-bit Linux platform
* Update Cargo.toml
* boring(ssl): use `corresponds` macro in `add_certificate_compression_algorithm`
* Add `X509_STORE_CTX_get0_cert` interface
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.
* Update bindgen from 0.70.1 -> 0.71.1.
* Revert "feat(x509): Implement `Clone` for `X509Store` (#339)" (#353)
* 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>
* Release 4.17.0 (#354)
* Add set_verify_param
* clippy fix
---------
Co-authored-by: Rushil Mehra <84047965+rushilmehra@users.noreply.github.com>
Co-authored-by: Shih-Chiang Chien <shih-chiang@cloudflare.com>
Co-authored-by: Rushil Mehra <rmehra@cloudflare.com>
Co-authored-by: Eric Rosenberg <eric_rosenberg@apple.com>
Co-authored-by: Kornel <kornel@cloudflare.com>
Co-authored-by: James Larisch <jlarisch@cloudflare.com>
Co-authored-by: Yury Yarashevich <yura.yaroshevich@gmail.com>
Co-authored-by: Anthony Ramine <123095+nox@users.noreply.github.com>
This commit is contained in:
commit
0f2461ad00
|
|
@ -22,7 +22,7 @@ boring-sys = { package = "boring-sys2", version = "4.15.13", path = "./boring-sy
|
|||
boring = { package = "boring2", version = "4.15.13", path = "./boring" }
|
||||
tokio-boring = { package = "tokio-boring2", version = "4.15.13", path = "./tokio-boring" }
|
||||
|
||||
bindgen = { version = "0.70.1", default-features = false, features = ["runtime"] }
|
||||
bindgen = { version = "0.71.1", default-features = false, features = ["runtime"] }
|
||||
bytes = "1"
|
||||
cmake = "0.1.18"
|
||||
fs_extra = "1.3.0"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,32 @@
|
|||
|
||||
4.17.0
|
||||
- 2025-05-27 Revert "feat(x509): Implement `Clone` for `X509Store` (#339)" (#353)
|
||||
- 2025-05-14 Update bindgen from 0.70.1 -> 0.71.1.
|
||||
- 2025-05-19 Add `X509_STORE_CTX_get0_cert` interface
|
||||
- 2025-05-18 boring(ssl): use `corresponds` macro in `add_certificate_compression_algorithm`
|
||||
- 2025-02-14 Update Cargo.toml
|
||||
- 2025-02-13 build: Fix the build for 32-bit Linux platform
|
||||
- 2025-05-20 rustfmt ;(
|
||||
- 2025-05-20 Fix linking SystemFunction036 from advapi32 in Rust 1.87
|
||||
- 2025-05-20 Clippy
|
||||
- 2025-05-01 add SslCurve::X25519_MLKEM768 constant
|
||||
- 2025-04-17 Use ubuntu-latest for all ci jobs
|
||||
- 2025-04-16 fix clippy error
|
||||
- 2025-04-15 expose SSL_set_compliance_policy
|
||||
- 2025-04-07 feat(x509): Implement `Clone` for `X509Store` (#339)
|
||||
|
||||
4.16.0
|
||||
- 2025-03-31 Add fips-precompiled feature to support newer versions of FIPS (#338)
|
||||
- 2025-03-18 Document linking to C++ standard library (#335)
|
||||
- 2025-03-18 Revert "Remove "fips-no-compat", decouple "fips-compat" from "fips"" (#334)
|
||||
- 2025-03-11 boring: Disable `SslCurve` API with "fips" feature
|
||||
- 2025-03-11 boring-sys: Ignore patches when boringSSL is precompiled
|
||||
- 2025-03-13 Remove "fips-no-compat", decouple "fips-compat" from "fips"
|
||||
- 2025-03-14 Add feature "fips-no-compat"
|
||||
- 2025-03-10 Advertise X25519MLKEM768 with "kx-client-pq-preferred" (#329)
|
||||
- 2025-03-10 Update to actions/cache@v4 (#328)
|
||||
- 2025-02-28 Add missing release notes entry (#324)
|
||||
|
||||
4.15.0
|
||||
- 2025-02-27 Expose API to enable certificate compression. (#241)
|
||||
- 2025-02-23 Fix lifetimes in ssl::select_next_proto
|
||||
|
|
|
|||
|
|
@ -58,9 +58,19 @@ features = ["pq-experimental", "underscore-wildcards"]
|
|||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
# Use a FIPS-validated version of boringssl.
|
||||
# Compile boringssl using the FIPS build flag if building boringssl from
|
||||
# scratch.
|
||||
#
|
||||
# See
|
||||
# https://boringssl.googlesource.com/boringssl/+/master/crypto/fipsmodule/FIPS.md
|
||||
# for instructions and more details on the boringssl FIPS flag.
|
||||
fips = []
|
||||
|
||||
# Use a precompiled FIPS-validated version of BoringSSL. Meant to be used with
|
||||
# FIPS-20230428 or newer. Users must set `BORING_BSSL_FIPS_PATH` to use this
|
||||
# feature, or else the build will fail.
|
||||
fips-precompiled = []
|
||||
|
||||
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||
fips-link-precompiled = []
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ pub(crate) struct Config {
|
|||
|
||||
pub(crate) struct Features {
|
||||
pub(crate) fips: bool,
|
||||
pub(crate) fips_precompiled: bool,
|
||||
pub(crate) fips_link_precompiled: bool,
|
||||
pub(crate) pq_experimental: bool,
|
||||
pub(crate) rpk: bool,
|
||||
|
|
@ -47,11 +48,7 @@ impl Config {
|
|||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
|
||||
let features = Features::from_env();
|
||||
let env = Env::from_env(
|
||||
&host,
|
||||
&target,
|
||||
features.fips || features.fips_link_precompiled,
|
||||
);
|
||||
let env = Env::from_env(&host, &target, features.is_fips_like());
|
||||
|
||||
let mut is_bazel = false;
|
||||
if let Some(src_path) = &env.source_path {
|
||||
|
|
@ -80,6 +77,10 @@ impl Config {
|
|||
panic!("`fips` and `rpk` features are mutually exclusive");
|
||||
}
|
||||
|
||||
if self.features.fips_precompiled && self.features.rpk {
|
||||
panic!("`fips-precompiled` and `rpk` features are mutually exclusive");
|
||||
}
|
||||
|
||||
let is_precompiled_native_lib = self.env.path.is_some();
|
||||
let is_external_native_lib_source =
|
||||
!is_precompiled_native_lib && self.env.source_path.is_none();
|
||||
|
|
@ -103,15 +104,22 @@ impl Config {
|
|||
);
|
||||
}
|
||||
|
||||
// todo(rmehra): should this even be a restriction? why not let people link a custom bcm.o?
|
||||
// precompiled boringssl will include libcrypto.a
|
||||
if is_precompiled_native_lib && self.features.fips_link_precompiled {
|
||||
panic!("precompiled BoringSSL was provided, so FIPS configuration can't be applied");
|
||||
}
|
||||
|
||||
if !is_precompiled_native_lib && self.features.fips_precompiled {
|
||||
panic!("`fips-precompiled` feature requires `BORING_BSSL_FIPS_PATH` to be set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Features {
|
||||
fn from_env() -> Self {
|
||||
let fips = env::var_os("CARGO_FEATURE_FIPS").is_some();
|
||||
let fips_precompiled = env::var_os("CARGO_FEATURE_FIPS_PRECOMPILED").is_some();
|
||||
let fips_link_precompiled = env::var_os("CARGO_FEATURE_FIPS_LINK_PRECOMPILED").is_some();
|
||||
let pq_experimental = env::var_os("CARGO_FEATURE_PQ_EXPERIMENTAL").is_some();
|
||||
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
|
||||
|
|
@ -119,12 +127,17 @@ impl Features {
|
|||
|
||||
Self {
|
||||
fips,
|
||||
fips_precompiled,
|
||||
fips_link_precompiled,
|
||||
pq_experimental,
|
||||
rpk,
|
||||
underscore_wildcards,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_fips_like(&self) -> bool {
|
||||
self.fips || self.fips_precompiled || self.fips_link_precompiled
|
||||
}
|
||||
}
|
||||
|
||||
impl Env {
|
||||
|
|
@ -138,6 +151,7 @@ impl Env {
|
|||
let target_var = |name: &str| {
|
||||
let kind = if host == target { "HOST" } else { "TARGET" };
|
||||
|
||||
// TODO(rmehra): look for just `name` first, as most people just set that
|
||||
var(&format!("{}_{}", name, target))
|
||||
.or_else(|| var(&format!("{}_{}", name, target_with_underscores)))
|
||||
.or_else(|| var(&format!("{}_{}", kind, name)))
|
||||
|
|
|
|||
|
|
@ -661,13 +661,14 @@ fn main() {
|
|||
let bssl_dir = built_boring_source_path(&config);
|
||||
let build_path = get_boringssl_platform_output_path(&config);
|
||||
|
||||
if config.is_bazel || (config.features.fips && config.env.path.is_some()) {
|
||||
if config.is_bazel || (config.features.is_fips_like() && config.env.path.is_some()) {
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}/lib/{}",
|
||||
bssl_dir.display(),
|
||||
build_path
|
||||
);
|
||||
} else {
|
||||
// todo(rmehra): clean this up, I think these are pretty redundant
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}/build/crypto/{}",
|
||||
bssl_dir.display(),
|
||||
|
|
@ -699,6 +700,11 @@ fn main() {
|
|||
println!("cargo:rustc-link-lib=static=crypto");
|
||||
println!("cargo:rustc-link-lib=static=ssl");
|
||||
|
||||
if config.target_os == "windows" {
|
||||
// Rust 1.87.0 compat - https://github.com/rust-lang/rust/pull/138233
|
||||
println!("cargo:rustc-link-lib=advapi32");
|
||||
}
|
||||
|
||||
let include_path = config.env.include_path.clone().unwrap_or_else(|| {
|
||||
if let Some(bssl_path) = &config.env.path {
|
||||
return bssl_path.join("include");
|
||||
|
|
@ -717,9 +723,12 @@ fn main() {
|
|||
// bindgen 0.70 replaced the run-time layout tests with compile-time ones,
|
||||
// but they depend on std::mem::offset_of, stabilized in 1.77.
|
||||
let supports_layout_tests = autocfg::new().probe_rustc_version(1, 77);
|
||||
let Ok(target_rust_version) = bindgen::RustTarget::stable(68, 0) else {
|
||||
panic!("bindgen does not recognize target rust version");
|
||||
};
|
||||
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.rust_target(bindgen::RustTarget::Stable_1_68) // bindgen MSRV is 1.70, so this is enough
|
||||
.rust_target(target_rust_version) // bindgen MSRV is 1.70, so this is enough
|
||||
.derive_copy(true)
|
||||
.derive_debug(true)
|
||||
.derive_default(true)
|
||||
|
|
@ -759,7 +768,7 @@ fn main() {
|
|||
"des.h",
|
||||
"dtls1.h",
|
||||
"hkdf.h",
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
"hpke.h",
|
||||
"hmac.h",
|
||||
"hrss.h",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use std::os::raw::{c_char, c_int, c_uint, c_ulong};
|
|||
#[allow(
|
||||
clippy::useless_transmute,
|
||||
clippy::derive_partial_eq_without_eq,
|
||||
clippy::ptr_offset_with_cast,
|
||||
dead_code
|
||||
)]
|
||||
mod generated {
|
||||
|
|
|
|||
|
|
@ -19,24 +19,27 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||
[features]
|
||||
# Controlling the build
|
||||
|
||||
# Use a FIPS-validated version of BoringSSL. This feature sets "fips-compat".
|
||||
# NOTE: This feature is deprecated. It is needed for the submoduled
|
||||
# boringssl-fips, which is extremely old and requires modifications to the
|
||||
# bindings, as some newer APIs don't exist and some function signatures have
|
||||
# changed. It is highly recommended to use `fips-precompiled` instead.
|
||||
#
|
||||
# This feature sets `fips-compat` on behalf of the user to guarantee bindings
|
||||
# compatibility with the submoduled boringssl-fips.
|
||||
#
|
||||
# Use a FIPS-validated version of BoringSSL.
|
||||
fips = ["fips-compat", "boring-sys/fips"]
|
||||
|
||||
# Use a FIPS build of BoringSSL, but don't set "fips-compat".
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
|
||||
# "fips-compat".
|
||||
fips-no-compat = ["boring-sys/fips"]
|
||||
|
||||
# Build with compatibility for the BoringSSL FIPS version, without enabling the
|
||||
# `fips` feature itself (useful e.g. if `fips-link-precompiled` is used with an
|
||||
# older BoringSSL version).
|
||||
# Build with compatibility for the submoduled boringssl-fips, without enabling
|
||||
# the `fips` feature itself (useful e.g. if `fips-link-precompiled` is used
|
||||
# with an older BoringSSL version).
|
||||
fips-compat = []
|
||||
|
||||
# Use a precompiled FIPS-validated version of BoringSSL. Meant to be used with
|
||||
# FIPS-20230428 or newer. Users must set `BORING_BSSL_FIPS_PATH` to use this
|
||||
# feature, or else the build will fail.
|
||||
fips-precompiled = ["boring-sys/fips-precompiled"]
|
||||
|
||||
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||
fips-link-precompiled = ["boring-sys/fips-link-precompiled"]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ pub fn enabled() -> bool {
|
|||
fn is_enabled() {
|
||||
#[cfg(any(
|
||||
feature = "fips",
|
||||
feature = "fips-no-compat",
|
||||
feature = "fips-precompiled",
|
||||
feature = "fips-link-precompiled"
|
||||
))]
|
||||
assert!(enabled());
|
||||
#[cfg(not(any(
|
||||
feature = "fips",
|
||||
feature = "fips-no-compat",
|
||||
feature = "fips-precompiled",
|
||||
feature = "fips-link-precompiled"
|
||||
)))]
|
||||
assert!(!enabled());
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ pub mod error;
|
|||
pub mod ex_data;
|
||||
pub mod fips;
|
||||
pub mod hash;
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
pub mod hpke;
|
||||
pub mod memcmp;
|
||||
pub mod nid;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ pub use self::cert_compression::CertCompressionAlgorithm;
|
|||
pub use self::connector::{
|
||||
ConnectConfiguration, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder,
|
||||
};
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
pub use self::ech::SslEchKeysRef;
|
||||
pub use self::error::{Error, ErrorCode, HandshakeError};
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ mod callbacks;
|
|||
#[cfg(feature = "cert-compression")]
|
||||
mod cert_compression;
|
||||
mod connector;
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
mod ech;
|
||||
mod error;
|
||||
mod mut_only;
|
||||
|
|
@ -770,24 +770,36 @@ impl SslCurve {
|
|||
pub const FFDHE3072: SslCurve = SslCurve(ffi::SSL_CURVE_DHE3072 as _);
|
||||
|
||||
#[cfg(feature = "pq-experimental")]
|
||||
pub const X25519_MLKEM768: SslCurve = SslCurve(ffi::SSL_CURVE_X25519_MLKEM768 as _);
|
||||
|
||||
#[cfg(feature = "pq-experimental")]
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-precompiled")))]
|
||||
pub const X25519_KYBER768_DRAFT00: SslCurve =
|
||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 as _);
|
||||
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
pub const X25519_KYBER768_DRAFT00_OLD: SslCurve =
|
||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00_OLD as _);
|
||||
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
pub const X25519_KYBER512_DRAFT00: SslCurve =
|
||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER512_DRAFT00 as _);
|
||||
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
pub const P256_KYBER768_DRAFT00: SslCurve = SslCurve(ffi::SSL_CURVE_P256_KYBER768_DRAFT00 as _);
|
||||
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
pub const X25519_MLKEM768: SslCurve = SslCurve(ffi::SSL_CURVE_X25519_MLKEM768 as _);
|
||||
|
||||
/// Returns the curve name
|
||||
#[corresponds(SSL_get_curve_name)]
|
||||
pub fn name(&self) -> Option<&'static str> {
|
||||
|
|
@ -818,15 +830,27 @@ impl SslCurve {
|
|||
ffi::SSL_CURVE_SECP384R1 => Some(ffi::NID_secp384r1),
|
||||
ffi::SSL_CURVE_SECP521R1 => Some(ffi::NID_secp521r1),
|
||||
ffi::SSL_CURVE_X25519 => Some(ffi::NID_X25519),
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-precompiled")))]
|
||||
ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 => Some(ffi::NID_X25519Kyber768Draft00),
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
ffi::SSL_CURVE_X25519_KYBER768_DRAFT00_OLD => Some(ffi::NID_X25519Kyber768Draft00Old),
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
ffi::SSL_CURVE_X25519_KYBER512_DRAFT00 => Some(ffi::NID_X25519Kyber512Draft00),
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
ffi::SSL_CURVE_P256_KYBER768_DRAFT00 => Some(ffi::NID_P256Kyber768Draft00),
|
||||
#[cfg(all(not(feature = "fips"), feature = "pq-experimental"))]
|
||||
#[cfg(all(
|
||||
not(any(feature = "fips", feature = "fips-precompiled")),
|
||||
feature = "pq-experimental"
|
||||
))]
|
||||
ffi::SSL_CURVE_X25519_MLKEM768 => Some(ffi::NID_X25519MLKEM768),
|
||||
ffi::SSL_CURVE_DHE2048 => Some(ffi::NID_ffdhe2048),
|
||||
ffi::SSL_CURVE_DHE3072 => Some(ffi::NID_ffdhe3072),
|
||||
|
|
@ -1663,12 +1687,6 @@ impl SslContextBuilder {
|
|||
unsafe { X509StoreBuilderRef::from_ptr(ffi::SSL_CTX_get_cert_store(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the context's certificate store.
|
||||
#[corresponds(SSL_CTX_get_cert_store)]
|
||||
pub fn cert_store_mut(&mut self) -> &mut X509StoreBuilderRef {
|
||||
unsafe { X509StoreBuilderRef::from_ptr_mut(ffi::SSL_CTX_get_cert_store(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Sets the callback dealing with OCSP stapling.
|
||||
///
|
||||
/// On the client side, this callback is responsible for validating the OCSP status response
|
||||
|
|
@ -2070,7 +2088,7 @@ impl SslContextBuilder {
|
|||
/// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function
|
||||
/// is safe to call even after the `SSL_CTX` has been associated with connections on various
|
||||
/// threads.
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
#[corresponds(SSL_CTX_set1_ech_keys)]
|
||||
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) }
|
||||
|
|
@ -2312,7 +2330,7 @@ impl SslContextRef {
|
|||
/// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function
|
||||
/// is safe to call even after the `SSL_CTX` has been associated with connections on various
|
||||
/// threads.
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
#[corresponds(SSL_CTX_set1_ech_keys)]
|
||||
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) }
|
||||
|
|
@ -3715,6 +3733,13 @@ impl SslRef {
|
|||
ffi::SSL_set_enable_ech_grease(self.as_ptr(), enable);
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the compliance policy on `SSL`.
|
||||
#[cfg(not(feature = "fips-compat"))]
|
||||
#[corresponds(SSL_set_compliance_policy)]
|
||||
pub fn set_compliance_policy(&mut self, policy: CompliancePolicy) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt_0i(ffi::SSL_set_compliance_policy(self.as_ptr(), policy.0)).map(|_| ()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// An SSL stream midway through the handshake process.
|
||||
|
|
|
|||
|
|
@ -56,17 +56,29 @@ fn no_error_when_trusted_and_callback_returns_true() {
|
|||
|
||||
#[test]
|
||||
fn callback_receives_correct_certificate() {
|
||||
let server = Server::builder().build();
|
||||
// Server sends the full chain (leaf + root)...
|
||||
let server = Server::builder_full_chain().build();
|
||||
// but client doesn't load the root as trusted.
|
||||
// So we expect an error.
|
||||
let mut client = server.client();
|
||||
let expected = "59172d9313e84459bcff27f967e79e6e9217e584";
|
||||
let leaf_sha1 = "59172d9313e84459bcff27f967e79e6e9217e584";
|
||||
let root_sha1 = "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875";
|
||||
client.ctx().set_verify(SslVerifyMode::PEER);
|
||||
client.ctx().set_cert_verify_callback(move |x509| {
|
||||
assert!(!x509.verify_cert().unwrap());
|
||||
// This is set to the root, since that's the problematic cert.
|
||||
assert!(x509.current_cert().is_some());
|
||||
// This is set to the leaf, since that's the cert we're verifying.
|
||||
assert!(x509.cert().is_some());
|
||||
assert!(x509.verify_result().is_err());
|
||||
let cert = x509.current_cert().unwrap();
|
||||
let digest = cert.digest(MessageDigest::sha1()).unwrap();
|
||||
assert_eq!(hex::encode(digest), expected);
|
||||
|
||||
let root = x509.current_cert().unwrap();
|
||||
let digest = root.digest(MessageDigest::sha1()).unwrap();
|
||||
assert_eq!(hex::encode(digest), root_sha1);
|
||||
|
||||
let leaf = x509.cert().unwrap();
|
||||
let digest = leaf.digest(MessageDigest::sha1()).unwrap();
|
||||
assert_eq!(hex::encode(digest), leaf_sha1);
|
||||
true
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ use crate::ssl::{
|
|||
use crate::x509::verify::X509CheckFlags;
|
||||
use crate::x509::{X509Name, X509};
|
||||
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
use super::CompliancePolicy;
|
||||
|
||||
mod cert_compressor;
|
||||
mod cert_verify;
|
||||
mod custom_verify;
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
mod ech;
|
||||
mod extensions;
|
||||
mod private_key_method;
|
||||
|
|
@ -991,7 +991,7 @@ fn test_get_ciphers() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
||||
#[cfg(not(feature = "fips"))]
|
||||
fn test_set_compliance() {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
ctx.set_compliance_policy(CompliancePolicy::FIPS_202205)
|
||||
|
|
@ -1071,3 +1071,52 @@ fn test_info_callback() {
|
|||
client.connect();
|
||||
assert!(CALLED_BACK.load(Ordering::Relaxed));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "fips-compat"))]
|
||||
#[test]
|
||||
fn test_ssl_set_compliance() {
|
||||
let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
|
||||
let mut ssl = Ssl::new(&ctx).unwrap();
|
||||
ssl.set_compliance_policy(CompliancePolicy::FIPS_202205)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(ssl.max_proto_version().unwrap(), SslVersion::TLS1_3);
|
||||
assert_eq!(ssl.min_proto_version().unwrap(), SslVersion::TLS1_2);
|
||||
|
||||
const FIPS_CIPHERS: [&str; 4] = [
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
"ECDHE-RSA-AES128-GCM-SHA256",
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
];
|
||||
|
||||
let ciphers = ssl.ciphers();
|
||||
assert_eq!(ciphers.len(), FIPS_CIPHERS.len());
|
||||
|
||||
for cipher in ciphers.into_iter().zip(FIPS_CIPHERS) {
|
||||
assert_eq!(cipher.0.name(), cipher.1)
|
||||
}
|
||||
|
||||
let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
|
||||
let mut ssl = Ssl::new(&ctx).unwrap();
|
||||
ssl.set_compliance_policy(CompliancePolicy::WPA3_192_202304)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(ssl.max_proto_version().unwrap(), SslVersion::TLS1_3);
|
||||
assert_eq!(ssl.min_proto_version().unwrap(), SslVersion::TLS1_2);
|
||||
|
||||
const WPA3_192_CIPHERS: [&str; 2] = [
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
];
|
||||
|
||||
let ciphers = ssl.ciphers();
|
||||
assert_eq!(ciphers.len(), WPA3_192_CIPHERS.len());
|
||||
|
||||
for cipher in ciphers.into_iter().zip(WPA3_192_CIPHERS) {
|
||||
assert_eq!(cipher.0.name(), cipher.1)
|
||||
}
|
||||
|
||||
ssl.set_compliance_policy(CompliancePolicy::NONE)
|
||||
.expect_err("Testing expect err if set compliance policy to NONE");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,24 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
/// Serves the leaf and the root together.
|
||||
pub fn builder_full_chain() -> Builder {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
// Uses certs.pem instead of cert.pem.
|
||||
ctx.set_certificate_chain_file("test/certs.pem").unwrap();
|
||||
ctx.set_private_key_file("test/key.pem", SslFiletype::PEM)
|
||||
.unwrap();
|
||||
|
||||
Builder {
|
||||
ctx,
|
||||
ssl_cb: Box::new(|_| {}),
|
||||
io_cb: Box::new(|_| {}),
|
||||
err_cb: Box::new(|_| {}),
|
||||
should_error: false,
|
||||
expected_connections_count: 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client(&self) -> ClientBuilder {
|
||||
ClientBuilder {
|
||||
ctx: SslContext::builder(SslMethod::tls()).unwrap(),
|
||||
|
|
|
|||
|
|
@ -148,6 +148,12 @@ impl X509StoreContextRef {
|
|||
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_CTX_get0_param(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Sets the X509 verifification configuration on the X509_STORE_CTX.
|
||||
#[corresponds(X509_STORE_CTX_set0_param)]
|
||||
pub fn set_verify_param(&mut self, param: &mut X509VerifyParamRef) {
|
||||
unsafe { ffi::X509_STORE_CTX_set0_param(self.as_ptr(), param.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Verifies the stored certificate.
|
||||
///
|
||||
/// Returns `true` if verification succeeds. The `error` method will return the specific
|
||||
|
|
@ -209,6 +215,20 @@ impl X509StoreContextRef {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the certificate being verified.
|
||||
/// May return None if a raw public key is being verified.
|
||||
#[corresponds(X509_STORE_CTX_get0_cert)]
|
||||
pub fn cert(&self) -> Option<&X509Ref> {
|
||||
unsafe {
|
||||
let ptr = ffi::X509_STORE_CTX_get0_cert(self.as_ptr());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(X509Ref::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder used to construct an `X509`.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ fips = ["boring/fips", "boring-sys/fips"]
|
|||
#
|
||||
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
|
||||
# "fips-compat".
|
||||
fips-no-compat = ["boring/fips-no-compat"]
|
||||
fips-precompiled = ["boring/fips-precompiled"]
|
||||
|
||||
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||
fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"]
|
||||
|
|
|
|||
Loading…
Reference in New Issue