diff --git a/Cargo.toml b/Cargo.toml index 957b4209..cc4b96f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 0047a016..62dec155 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -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 diff --git a/boring-sys/Cargo.toml b/boring-sys/Cargo.toml index 7d49b267..67c66d85 100644 --- a/boring-sys/Cargo.toml +++ b/boring-sys/Cargo.toml @@ -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 = [] diff --git a/boring-sys/build/config.rs b/boring-sys/build/config.rs index 19a63f52..353f4d20 100644 --- a/boring-sys/build/config.rs +++ b/boring-sys/build/config.rs @@ -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))) diff --git a/boring-sys/build/main.rs b/boring-sys/build/main.rs index c6bb2f5e..2c67fdec 100644 --- a/boring-sys/build/main.rs +++ b/boring-sys/build/main.rs @@ -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", diff --git a/boring-sys/src/lib.rs b/boring-sys/src/lib.rs index 094221ff..404a9008 100644 --- a/boring-sys/src/lib.rs +++ b/boring-sys/src/lib.rs @@ -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 { diff --git a/boring/Cargo.toml b/boring/Cargo.toml index e77b6424..581bd5fc 100644 --- a/boring/Cargo.toml +++ b/boring/Cargo.toml @@ -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"] diff --git a/boring/src/fips.rs b/boring/src/fips.rs index 29dbfae0..23fbefdf 100644 --- a/boring/src/fips.rs +++ b/boring/src/fips.rs @@ -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()); diff --git a/boring/src/lib.rs b/boring/src/lib.rs index 25a1e506..e7b6adae 100644 --- a/boring/src/lib.rs +++ b/boring/src/lib.rs @@ -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; diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index e8af9bbe..37e941ed 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -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. diff --git a/boring/src/ssl/test/cert_verify.rs b/boring/src/ssl/test/cert_verify.rs index 929db48c..e8e54061 100644 --- a/boring/src/ssl/test/cert_verify.rs +++ b/boring/src/ssl/test/cert_verify.rs @@ -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 }); diff --git a/boring/src/ssl/test/mod.rs b/boring/src/ssl/test/mod.rs index fc82a3fb..98a6c7fa 100644 --- a/boring/src/ssl/test/mod.rs +++ b/boring/src/ssl/test/mod.rs @@ -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"); +} diff --git a/boring/src/ssl/test/server.rs b/boring/src/ssl/test/server.rs index e5c0497c..5436469d 100644 --- a/boring/src/ssl/test/server.rs +++ b/boring/src/ssl/test/server.rs @@ -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(), diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index 2f5706a0..746ca6c3 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -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`. diff --git a/tokio-boring/Cargo.toml b/tokio-boring/Cargo.toml index da79dcde..78d20b90 100644 --- a/tokio-boring/Cargo.toml +++ b/tokio-boring/Cargo.toml @@ -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"]