Merge remote-tracking branch 'upstream/master'

This commit is contained in:
0x676e67 2025-06-17 20:16:49 +08:00
commit e04066ee46
3 changed files with 126 additions and 18 deletions

View File

@ -36,6 +36,7 @@ pub(crate) struct Env {
pub(crate) android_ndk_home: Option<PathBuf>,
pub(crate) cmake_toolchain_file: Option<PathBuf>,
pub(crate) cpp_runtime_lib: Option<OsString>,
pub(crate) docs_rs: bool,
}
impl Config {
@ -185,6 +186,7 @@ impl Env {
android_ndk_home: target_var("ANDROID_NDK_HOME").map(Into::into),
cmake_toolchain_file: target_var("CMAKE_TOOLCHAIN_FILE").map(Into::into),
cpp_runtime_lib: target_var("BORING_BSSL_RUST_CPPLIB"),
docs_rs: var("DOCS_RS").is_some(),
}
}
}

View File

@ -318,8 +318,8 @@ fn get_boringssl_cmake_config(config: &Config) -> cmake::Config {
);
}
_ => {
eprintln!(
"warning: no toolchain file configured by boring-sys for {}",
println!(
"cargo:warning=no toolchain file configured by boring-sys for {}",
config.target
);
}
@ -339,7 +339,7 @@ fn verify_fips_clang_version() -> (&'static str, &'static str) {
let output = match Command::new(tool).arg("--version").output() {
Ok(o) => o,
Err(e) => {
eprintln!("warning: missing {tool}, trying other compilers: {e}");
println!("cargo:warning=missing {tool}, trying other compilers: {e}");
// NOTE: hard-codes that the loop below checks the version
return None;
}
@ -372,8 +372,8 @@ fn verify_fips_clang_version() -> (&'static str, &'static str) {
"unsupported clang version \"{cc_version}\": FIPS requires clang {REQUIRED_CLANG_VERSION}"
);
} else if !cc_version.is_empty() {
eprintln!(
"warning: FIPS requires clang version {REQUIRED_CLANG_VERSION}, skipping incompatible version \"{cc_version}\""
println!(
"cargo:warning=FIPS requires clang version {REQUIRED_CLANG_VERSION}, skipping incompatible version \"{cc_version}\""
);
}
}
@ -423,9 +423,9 @@ fn get_extra_clang_args_for_bindgen(config: &Config) -> Vec<String> {
.unwrap();
if !output.status.success() {
if let Some(exit_code) = output.status.code() {
eprintln!("xcrun failed: exit code {exit_code}");
println!("cargo:warning=xcrun failed: exit code {exit_code}");
} else {
eprintln!("xcrun failed: killed");
println!("cargo:warning=xcrun failed: killed");
}
std::io::stderr().write_all(&output.stderr).unwrap();
// Uh... let's try anyway, I guess?
@ -449,8 +449,8 @@ fn get_extra_clang_args_for_bindgen(config: &Config) -> Vec<String> {
let toolchain = match pick_best_android_ndk_toolchain(&android_sysroot) {
Ok(toolchain) => toolchain,
Err(e) => {
eprintln!(
"warning: failed to find prebuilt Android NDK toolchain for bindgen: {e}"
println!(
"cargo:warning=failed to find prebuilt Android NDK toolchain for bindgen: {e}"
);
// Uh... let's try anyway, I guess?
return params;
@ -572,8 +572,13 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
let mut cfg = get_boringssl_cmake_config(config);
if let Ok(threads) = std::thread::available_parallelism() {
cfg.env("CMAKE_BUILD_PARALLEL_LEVEL", threads.to_string());
let num_jobs = std::env::var("NUM_JOBS").ok().or_else(|| {
std::thread::available_parallelism()
.ok()
.map(|t| t.to_string())
});
if let Some(num_jobs) = num_jobs {
cfg.env("CMAKE_BUILD_PARALLEL_LEVEL", num_jobs);
}
if config.features.fips {
@ -655,8 +660,15 @@ fn get_cpp_runtime_lib(config: &Config) -> Option<String> {
fn main() {
let config = Config::from_env();
let bssl_dir = built_boring_source_path(&config);
let build_path = get_boringssl_platform_output_path(&config);
if !config.env.docs_rs {
emit_link_directives(&config);
}
generate_bindings(&config);
}
fn emit_link_directives(config: &Config) {
let bssl_dir = built_boring_source_path(config);
let build_path = get_boringssl_platform_output_path(config);
if config.is_bazel || (config.features.is_fips_like() && config.env.path.is_some()) {
println!(
@ -688,10 +700,10 @@ fn main() {
}
if config.features.fips_link_precompiled {
link_in_precompiled_bcm_o(&config);
link_in_precompiled_bcm_o(config);
}
if let Some(cpp_lib) = get_cpp_runtime_lib(&config) {
if let Some(cpp_lib) = get_cpp_runtime_lib(config) {
println!("cargo:rustc-link-lib={cpp_lib}");
}
println!("cargo:rustc-link-lib=static=crypto");
@ -701,13 +713,15 @@ fn main() {
// Rust 1.87.0 compat - https://github.com/rust-lang/rust/pull/138233
println!("cargo:rustc-link-lib=advapi32");
}
}
fn generate_bindings(config: &Config) {
let include_path = config.env.include_path.clone().unwrap_or_else(|| {
if let Some(bssl_path) = &config.env.path {
return bssl_path.join("include");
}
let src_path = get_boringssl_source_path(&config);
let src_path = get_boringssl_source_path(config);
let candidate = src_path.join("include");
if candidate.exists() {
@ -741,7 +755,7 @@ fn main() {
.layout_tests(supports_layout_tests)
.prepend_enum_name(true)
.blocklist_type("max_align_t") // Not supported by bindgen on all targets, not used by BoringSSL
.clang_args(get_extra_clang_args_for_bindgen(&config))
.clang_args(get_extra_clang_args_for_bindgen(config))
.clang_arg("-I")
.clang_arg(include_path.display().to_string());

View File

@ -56,7 +56,7 @@ use crate::ec::EcKey;
use crate::error::ErrorStack;
use crate::rsa::Rsa;
use crate::util::{invoke_passwd_cb, CallbackState};
use crate::{cvt, cvt_p};
use crate::{cvt, cvt_0i, cvt_p};
/// A tag type indicating that a key only has parameters.
pub enum Params {}
@ -228,6 +228,36 @@ where
{
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
}
/// Returns the length of the "raw" form of the public key. Only supported for certain key types.
#[corresponds(EVP_PKEY_get_raw_public_key)]
pub fn raw_public_key_len(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut size = 0;
_ = cvt_0i(ffi::EVP_PKEY_get_raw_public_key(
self.as_ptr(),
std::ptr::null_mut(),
&mut size,
))?;
Ok(size)
}
}
/// Outputs a copy of the "raw" form of the public key. Only supported for certain key types.
///
/// Returns the used portion of `out`.
#[corresponds(EVP_PKEY_get_raw_public_key)]
pub fn raw_public_key<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], ErrorStack> {
unsafe {
let mut size = out.len();
_ = cvt_0i(ffi::EVP_PKEY_get_raw_public_key(
self.as_ptr(),
out.as_mut_ptr(),
&mut size,
))?;
Ok(&out[..size])
}
}
}
impl<T> PKeyRef<T>
@ -266,6 +296,36 @@ where
private_key_to_der_pkcs8_passphrase,
ffi::i2d_PKCS8PrivateKey_bio
}
/// Returns the length of the "raw" form of the private key. Only supported for certain key types.
#[corresponds(EVP_PKEY_get_raw_private_key)]
pub fn raw_private_key_len(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut size = 0;
_ = cvt_0i(ffi::EVP_PKEY_get_raw_private_key(
self.as_ptr(),
std::ptr::null_mut(),
&mut size,
))?;
Ok(size)
}
}
/// Outputs a copy of the "raw" form of the private key. Only supported for certain key types.
///
/// Returns the used portion of `out`.
#[corresponds(EVP_PKEY_get_raw_private_key)]
pub fn raw_private_key<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], ErrorStack> {
unsafe {
let mut size = out.len();
_ = cvt_0i(ffi::EVP_PKEY_get_raw_private_key(
self.as_ptr(),
out.as_mut_ptr(),
&mut size,
))?;
Ok(&out[..size])
}
}
}
impl<T> fmt::Debug for PKey<T> {
@ -451,6 +511,8 @@ use crate::ffi::EVP_PKEY_up_ref;
#[cfg(test)]
mod tests {
use hex::FromHex as _;
use crate::ec::EcKey;
use crate::nid::Nid;
use crate::rsa::Rsa;
@ -561,4 +623,34 @@ mod tests {
assert_eq!(pkey.id(), Id::EC);
assert!(pkey.rsa().is_err());
}
#[test]
fn test_raw_accessors() {
const ED25519_PRIVATE_KEY_DER: &str = concat!(
"302e020100300506032b6570042204207c8c6497f9960d5595d7815f550569e5",
"f77764ac97e63e339aaa68cc1512b683"
);
let pkey =
PKey::private_key_from_der(&Vec::from_hex(ED25519_PRIVATE_KEY_DER).unwrap()).unwrap();
assert_eq!(pkey.id(), Id::ED25519);
let priv_len = pkey.raw_private_key_len().unwrap();
assert_eq!(priv_len, 32);
let mut raw_private_key_buf = [0; 40];
let raw_private_key = pkey.raw_private_key(&mut raw_private_key_buf).unwrap();
assert_eq!(raw_private_key.len(), 32);
assert_ne!(raw_private_key, [0; 32]);
pkey.raw_private_key(&mut [0; 5])
.expect_err("buffer too small");
let pub_len = pkey.raw_public_key_len().unwrap();
assert_eq!(pub_len, 32);
let mut raw_public_key_buf = [0; 40];
let raw_public_key = pkey.raw_public_key(&mut raw_public_key_buf).unwrap();
assert_eq!(raw_public_key.len(), 32);
assert_ne!(raw_public_key, [0; 32]);
assert_ne!(raw_public_key, raw_private_key);
pkey.raw_public_key(&mut [0; 5])
.expect_err("buffer too small");
}
}