Merge remote-tracking branch 'upstream/master' into sync

This commit is contained in:
0x676e67 2025-05-30 10:55:52 +08:00
commit 6169bcd543
15 changed files with 246 additions and 57 deletions

View File

@ -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"

View File

@ -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

View File

@ -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 = []

View File

@ -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)))

View File

@ -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",

View File

@ -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 {

View File

@ -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"]

View File

@ -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());

View File

@ -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;

View File

@ -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.

View File

@ -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
});

View File

@ -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");
}

View File

@ -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(),

View File

@ -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`.

View File

@ -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"]