Merge remote-tracking branch 'upstream/master' into sync
This commit is contained in:
commit
6169bcd543
|
|
@ -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" }
|
boring = { package = "boring2", version = "4.15.13", path = "./boring" }
|
||||||
tokio-boring = { package = "tokio-boring2", version = "4.15.13", path = "./tokio-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"
|
bytes = "1"
|
||||||
cmake = "0.1.18"
|
cmake = "0.1.18"
|
||||||
fs_extra = "1.3.0"
|
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
|
4.15.0
|
||||||
- 2025-02-27 Expose API to enable certificate compression. (#241)
|
- 2025-02-27 Expose API to enable certificate compression. (#241)
|
||||||
- 2025-02-23 Fix lifetimes in ssl::select_next_proto
|
- 2025-02-23 Fix lifetimes in ssl::select_next_proto
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,19 @@ features = ["pq-experimental", "underscore-wildcards"]
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[features]
|
[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 = []
|
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.
|
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||||
fips-link-precompiled = []
|
fips-link-precompiled = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ pub(crate) struct Config {
|
||||||
|
|
||||||
pub(crate) struct Features {
|
pub(crate) struct Features {
|
||||||
pub(crate) fips: bool,
|
pub(crate) fips: bool,
|
||||||
|
pub(crate) fips_precompiled: bool,
|
||||||
pub(crate) fips_link_precompiled: bool,
|
pub(crate) fips_link_precompiled: bool,
|
||||||
pub(crate) pq_experimental: bool,
|
pub(crate) pq_experimental: bool,
|
||||||
pub(crate) rpk: bool,
|
pub(crate) rpk: bool,
|
||||||
|
|
@ -47,11 +48,7 @@ impl Config {
|
||||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||||
|
|
||||||
let features = Features::from_env();
|
let features = Features::from_env();
|
||||||
let env = Env::from_env(
|
let env = Env::from_env(&host, &target, features.is_fips_like());
|
||||||
&host,
|
|
||||||
&target,
|
|
||||||
features.fips || features.fips_link_precompiled,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut is_bazel = false;
|
let mut is_bazel = false;
|
||||||
if let Some(src_path) = &env.source_path {
|
if let Some(src_path) = &env.source_path {
|
||||||
|
|
@ -80,6 +77,10 @@ impl Config {
|
||||||
panic!("`fips` and `rpk` features are mutually exclusive");
|
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_precompiled_native_lib = self.env.path.is_some();
|
||||||
let is_external_native_lib_source =
|
let is_external_native_lib_source =
|
||||||
!is_precompiled_native_lib && self.env.source_path.is_none();
|
!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 {
|
if is_precompiled_native_lib && self.features.fips_link_precompiled {
|
||||||
panic!("precompiled BoringSSL was provided, so FIPS configuration can't be applied");
|
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 {
|
impl Features {
|
||||||
fn from_env() -> Self {
|
fn from_env() -> Self {
|
||||||
let fips = env::var_os("CARGO_FEATURE_FIPS").is_some();
|
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 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 pq_experimental = env::var_os("CARGO_FEATURE_PQ_EXPERIMENTAL").is_some();
|
||||||
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
|
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
|
||||||
|
|
@ -119,12 +127,17 @@ impl Features {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fips,
|
fips,
|
||||||
|
fips_precompiled,
|
||||||
fips_link_precompiled,
|
fips_link_precompiled,
|
||||||
pq_experimental,
|
pq_experimental,
|
||||||
rpk,
|
rpk,
|
||||||
underscore_wildcards,
|
underscore_wildcards,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_fips_like(&self) -> bool {
|
||||||
|
self.fips || self.fips_precompiled || self.fips_link_precompiled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env {
|
impl Env {
|
||||||
|
|
@ -138,6 +151,7 @@ impl Env {
|
||||||
let target_var = |name: &str| {
|
let target_var = |name: &str| {
|
||||||
let kind = if host == target { "HOST" } else { "TARGET" };
|
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))
|
var(&format!("{}_{}", name, target))
|
||||||
.or_else(|| var(&format!("{}_{}", name, target_with_underscores)))
|
.or_else(|| var(&format!("{}_{}", name, target_with_underscores)))
|
||||||
.or_else(|| var(&format!("{}_{}", kind, name)))
|
.or_else(|| var(&format!("{}_{}", kind, name)))
|
||||||
|
|
|
||||||
|
|
@ -661,13 +661,14 @@ fn main() {
|
||||||
let bssl_dir = built_boring_source_path(&config);
|
let bssl_dir = built_boring_source_path(&config);
|
||||||
let build_path = get_boringssl_platform_output_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!(
|
println!(
|
||||||
"cargo:rustc-link-search=native={}/lib/{}",
|
"cargo:rustc-link-search=native={}/lib/{}",
|
||||||
bssl_dir.display(),
|
bssl_dir.display(),
|
||||||
build_path
|
build_path
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// todo(rmehra): clean this up, I think these are pretty redundant
|
||||||
println!(
|
println!(
|
||||||
"cargo:rustc-link-search=native={}/build/crypto/{}",
|
"cargo:rustc-link-search=native={}/build/crypto/{}",
|
||||||
bssl_dir.display(),
|
bssl_dir.display(),
|
||||||
|
|
@ -699,6 +700,11 @@ fn main() {
|
||||||
println!("cargo:rustc-link-lib=static=crypto");
|
println!("cargo:rustc-link-lib=static=crypto");
|
||||||
println!("cargo:rustc-link-lib=static=ssl");
|
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(|| {
|
let include_path = config.env.include_path.clone().unwrap_or_else(|| {
|
||||||
if let Some(bssl_path) = &config.env.path {
|
if let Some(bssl_path) = &config.env.path {
|
||||||
return bssl_path.join("include");
|
return bssl_path.join("include");
|
||||||
|
|
@ -717,9 +723,12 @@ fn main() {
|
||||||
// bindgen 0.70 replaced the run-time layout tests with compile-time ones,
|
// 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.
|
// but they depend on std::mem::offset_of, stabilized in 1.77.
|
||||||
let supports_layout_tests = autocfg::new().probe_rustc_version(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()
|
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_copy(true)
|
||||||
.derive_debug(true)
|
.derive_debug(true)
|
||||||
.derive_default(true)
|
.derive_default(true)
|
||||||
|
|
@ -759,7 +768,7 @@ fn main() {
|
||||||
"des.h",
|
"des.h",
|
||||||
"dtls1.h",
|
"dtls1.h",
|
||||||
"hkdf.h",
|
"hkdf.h",
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
"hpke.h",
|
"hpke.h",
|
||||||
"hmac.h",
|
"hmac.h",
|
||||||
"hrss.h",
|
"hrss.h",
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ use std::os::raw::{c_char, c_int, c_uint, c_ulong};
|
||||||
#[allow(
|
#[allow(
|
||||||
clippy::useless_transmute,
|
clippy::useless_transmute,
|
||||||
clippy::derive_partial_eq_without_eq,
|
clippy::derive_partial_eq_without_eq,
|
||||||
|
clippy::ptr_offset_with_cast,
|
||||||
dead_code
|
dead_code
|
||||||
)]
|
)]
|
||||||
mod generated {
|
mod generated {
|
||||||
|
|
|
||||||
|
|
@ -19,24 +19,27 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||||
[features]
|
[features]
|
||||||
# Controlling the build
|
# 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"]
|
fips = ["fips-compat", "boring-sys/fips"]
|
||||||
|
|
||||||
# Use a FIPS build of BoringSSL, but don't set "fips-compat".
|
# Build with compatibility for the submoduled boringssl-fips, without enabling
|
||||||
#
|
# the `fips` feature itself (useful e.g. if `fips-link-precompiled` is used
|
||||||
# As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no longer
|
# with an older BoringSSL version).
|
||||||
# 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).
|
|
||||||
fips-compat = []
|
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.
|
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||||
fips-link-precompiled = ["boring-sys/fips-link-precompiled"]
|
fips-link-precompiled = ["boring-sys/fips-link-precompiled"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ pub fn enabled() -> bool {
|
||||||
fn is_enabled() {
|
fn is_enabled() {
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "fips",
|
feature = "fips",
|
||||||
feature = "fips-no-compat",
|
feature = "fips-precompiled",
|
||||||
feature = "fips-link-precompiled"
|
feature = "fips-link-precompiled"
|
||||||
))]
|
))]
|
||||||
assert!(enabled());
|
assert!(enabled());
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "fips",
|
feature = "fips",
|
||||||
feature = "fips-no-compat",
|
feature = "fips-precompiled",
|
||||||
feature = "fips-link-precompiled"
|
feature = "fips-link-precompiled"
|
||||||
)))]
|
)))]
|
||||||
assert!(!enabled());
|
assert!(!enabled());
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ pub mod error;
|
||||||
pub mod ex_data;
|
pub mod ex_data;
|
||||||
pub mod fips;
|
pub mod fips;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
pub mod hpke;
|
pub mod hpke;
|
||||||
pub mod memcmp;
|
pub mod memcmp;
|
||||||
pub mod nid;
|
pub mod nid;
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ mod callbacks;
|
||||||
#[cfg(feature = "cert-compression")]
|
#[cfg(feature = "cert-compression")]
|
||||||
mod cert_compression;
|
mod cert_compression;
|
||||||
mod connector;
|
mod connector;
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
mod ech;
|
mod ech;
|
||||||
mod error;
|
mod error;
|
||||||
mod mut_only;
|
mod mut_only;
|
||||||
|
|
@ -770,24 +770,36 @@ impl SslCurve {
|
||||||
pub const FFDHE3072: SslCurve = SslCurve(ffi::SSL_CURVE_DHE3072 as _);
|
pub const FFDHE3072: SslCurve = SslCurve(ffi::SSL_CURVE_DHE3072 as _);
|
||||||
|
|
||||||
#[cfg(feature = "pq-experimental")]
|
#[cfg(feature = "pq-experimental")]
|
||||||
pub const X25519_MLKEM768: SslCurve = SslCurve(ffi::SSL_CURVE_X25519_MLKEM768 as _);
|
#[cfg(not(any(feature = "fips", feature = "fips-precompiled")))]
|
||||||
|
|
||||||
#[cfg(feature = "pq-experimental")]
|
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
|
||||||
pub const X25519_KYBER768_DRAFT00: SslCurve =
|
pub const X25519_KYBER768_DRAFT00: SslCurve =
|
||||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 as _);
|
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 =
|
pub const X25519_KYBER768_DRAFT00_OLD: SslCurve =
|
||||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00_OLD as _);
|
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 =
|
pub const X25519_KYBER512_DRAFT00: SslCurve =
|
||||||
SslCurve(ffi::SSL_CURVE_X25519_KYBER512_DRAFT00 as _);
|
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 _);
|
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
|
/// Returns the curve name
|
||||||
#[corresponds(SSL_get_curve_name)]
|
#[corresponds(SSL_get_curve_name)]
|
||||||
pub fn name(&self) -> Option<&'static str> {
|
pub fn name(&self) -> Option<&'static str> {
|
||||||
|
|
@ -818,15 +830,27 @@ impl SslCurve {
|
||||||
ffi::SSL_CURVE_SECP384R1 => Some(ffi::NID_secp384r1),
|
ffi::SSL_CURVE_SECP384R1 => Some(ffi::NID_secp384r1),
|
||||||
ffi::SSL_CURVE_SECP521R1 => Some(ffi::NID_secp521r1),
|
ffi::SSL_CURVE_SECP521R1 => Some(ffi::NID_secp521r1),
|
||||||
ffi::SSL_CURVE_X25519 => Some(ffi::NID_X25519),
|
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),
|
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),
|
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),
|
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),
|
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_X25519_MLKEM768 => Some(ffi::NID_X25519MLKEM768),
|
||||||
ffi::SSL_CURVE_DHE2048 => Some(ffi::NID_ffdhe2048),
|
ffi::SSL_CURVE_DHE2048 => Some(ffi::NID_ffdhe2048),
|
||||||
ffi::SSL_CURVE_DHE3072 => Some(ffi::NID_ffdhe3072),
|
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())) }
|
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.
|
/// Sets the callback dealing with OCSP stapling.
|
||||||
///
|
///
|
||||||
/// On the client side, this callback is responsible for validating the OCSP status response
|
/// 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
|
/// 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
|
/// is safe to call even after the `SSL_CTX` has been associated with connections on various
|
||||||
/// threads.
|
/// threads.
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
#[corresponds(SSL_CTX_set1_ech_keys)]
|
#[corresponds(SSL_CTX_set1_ech_keys)]
|
||||||
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
|
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(|_| ()) }
|
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
|
/// 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
|
/// is safe to call even after the `SSL_CTX` has been associated with connections on various
|
||||||
/// threads.
|
/// threads.
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
#[corresponds(SSL_CTX_set1_ech_keys)]
|
#[corresponds(SSL_CTX_set1_ech_keys)]
|
||||||
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
|
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(|_| ()) }
|
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);
|
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.
|
/// An SSL stream midway through the handshake process.
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,29 @@ fn no_error_when_trusted_and_callback_returns_true() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn callback_receives_correct_certificate() {
|
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 mut client = server.client();
|
||||||
let expected = "59172d9313e84459bcff27f967e79e6e9217e584";
|
let leaf_sha1 = "59172d9313e84459bcff27f967e79e6e9217e584";
|
||||||
|
let root_sha1 = "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875";
|
||||||
client.ctx().set_verify(SslVerifyMode::PEER);
|
client.ctx().set_verify(SslVerifyMode::PEER);
|
||||||
client.ctx().set_cert_verify_callback(move |x509| {
|
client.ctx().set_cert_verify_callback(move |x509| {
|
||||||
assert!(!x509.verify_cert().unwrap());
|
assert!(!x509.verify_cert().unwrap());
|
||||||
|
// This is set to the root, since that's the problematic cert.
|
||||||
assert!(x509.current_cert().is_some());
|
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());
|
assert!(x509.verify_result().is_err());
|
||||||
let cert = x509.current_cert().unwrap();
|
|
||||||
let digest = cert.digest(MessageDigest::sha1()).unwrap();
|
let root = x509.current_cert().unwrap();
|
||||||
assert_eq!(hex::encode(digest), expected);
|
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
|
true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ use crate::ssl::{
|
||||||
use crate::x509::verify::X509CheckFlags;
|
use crate::x509::verify::X509CheckFlags;
|
||||||
use crate::x509::{X509Name, X509};
|
use crate::x509::{X509Name, X509};
|
||||||
|
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
use super::CompliancePolicy;
|
use super::CompliancePolicy;
|
||||||
|
|
||||||
mod cert_compressor;
|
mod cert_compressor;
|
||||||
mod cert_verify;
|
mod cert_verify;
|
||||||
mod custom_verify;
|
mod custom_verify;
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
mod ech;
|
mod ech;
|
||||||
mod extensions;
|
mod extensions;
|
||||||
mod private_key_method;
|
mod private_key_method;
|
||||||
|
|
@ -991,7 +991,7 @@ fn test_get_ciphers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
|
#[cfg(not(feature = "fips"))]
|
||||||
fn test_set_compliance() {
|
fn test_set_compliance() {
|
||||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||||
ctx.set_compliance_policy(CompliancePolicy::FIPS_202205)
|
ctx.set_compliance_policy(CompliancePolicy::FIPS_202205)
|
||||||
|
|
@ -1071,3 +1071,52 @@ fn test_info_callback() {
|
||||||
client.connect();
|
client.connect();
|
||||||
assert!(CALLED_BACK.load(Ordering::Relaxed));
|
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 {
|
pub fn client(&self) -> ClientBuilder {
|
||||||
ClientBuilder {
|
ClientBuilder {
|
||||||
ctx: SslContext::builder(SslMethod::tls()).unwrap(),
|
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())) }
|
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.
|
/// Verifies the stored certificate.
|
||||||
///
|
///
|
||||||
/// Returns `true` if verification succeeds. The `error` method will return the specific
|
/// 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`.
|
/// 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
|
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
|
||||||
# "fips-compat".
|
# "fips-compat".
|
||||||
fips-no-compat = ["boring/fips-no-compat"]
|
fips-precompiled = ["boring/fips-precompiled"]
|
||||||
|
|
||||||
# Link with precompiled FIPS-validated `bcm.o` module.
|
# Link with precompiled FIPS-validated `bcm.o` module.
|
||||||
fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"]
|
fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue