diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /third_party/rust/neqo-crypto/src/lib.rs | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/neqo-crypto/src/lib.rs')
-rw-r--r-- | third_party/rust/neqo-crypto/src/lib.rs | 132 |
1 files changed, 70 insertions, 62 deletions
diff --git a/third_party/rust/neqo-crypto/src/lib.rs b/third_party/rust/neqo-crypto/src/lib.rs index 05424ee1f3..2ec1b4a3ea 100644 --- a/third_party/rust/neqo-crypto/src/lib.rs +++ b/third_party/rust/neqo-crypto/src/lib.rs @@ -4,13 +4,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![cfg_attr(feature = "deny-warnings", deny(warnings))] -#![warn(clippy::pedantic)] -// Bindgen auto generated code -// won't adhere to the clippy rules below -#![allow(clippy::module_name_repetitions)] -#![allow(clippy::unseparated_literal_suffix)] -#![allow(clippy::used_underscore_binding)] +#![allow(clippy::module_name_repetitions)] // This lint doesn't work here. +#![allow(clippy::unseparated_literal_suffix, clippy::used_underscore_binding)] // For bindgen code. mod aead; #[cfg(feature = "fuzzing")] @@ -27,7 +22,6 @@ mod exp; pub mod ext; pub mod hkdf; pub mod hp; -mod once; #[macro_use] mod p11; mod prio; @@ -37,11 +31,7 @@ pub mod selfencrypt; mod ssl; mod time; -use std::{ - ffi::CString, - path::{Path, PathBuf}, - ptr::null, -}; +use std::{ffi::CString, path::PathBuf, ptr::null, sync::OnceLock}; #[cfg(not(feature = "fuzzing"))] pub use self::aead::RealAead as Aead; @@ -49,7 +39,6 @@ pub use self::aead::RealAead as Aead; pub use self::aead::RealAead; #[cfg(feature = "fuzzing")] pub use self::aead_fuzzing::FuzzingAead as Aead; -use self::once::OnceResult; pub use self::{ agent::{ Agent, AllowZeroRtt, Client, HandshakeState, Record, RecordList, ResumptionToken, @@ -64,7 +53,7 @@ pub use self::{ }, err::{Error, PRErrorCode, Res}, ext::{ExtensionHandler, ExtensionHandlerResult, ExtensionWriterResult}, - p11::{random, PrivateKey, PublicKey, SymKey}, + p11::{random, randomize, PrivateKey, PublicKey, SymKey}, replay::AntiReplay, secrets::SecretDirection, ssl::Opt, @@ -87,7 +76,7 @@ fn secstatus_to_res(code: nss::SECStatus) -> Res<()> { enum NssLoaded { External, NoDb, - Db(Box<Path>), + Db, } impl Drop for NssLoaded { @@ -100,7 +89,7 @@ impl Drop for NssLoaded { } } -static mut INITIALIZED: OnceResult<NssLoaded> = OnceResult::new(); +static INITIALIZED: OnceLock<NssLoaded> = OnceLock::new(); fn already_initialized() -> bool { unsafe { nss::NSS_IsInitialized() != 0 } @@ -124,19 +113,18 @@ fn version_check() { pub fn init() { // Set time zero. time::init(); - unsafe { - INITIALIZED.call_once(|| { - version_check(); - if already_initialized() { - return NssLoaded::External; - } + _ = INITIALIZED.get_or_init(|| { + version_check(); + if already_initialized() { + return NssLoaded::External; + } - secstatus_to_res(nss::NSS_NoDB_Init(null())).expect("NSS_NoDB_Init failed"); - secstatus_to_res(nss::NSS_SetDomesticPolicy()).expect("NSS_SetDomesticPolicy failed"); + secstatus_to_res(unsafe { nss::NSS_NoDB_Init(null()) }).expect("NSS_NoDB_Init failed"); + secstatus_to_res(unsafe { nss::NSS_SetDomesticPolicy() }) + .expect("NSS_SetDomesticPolicy failed"); - NssLoaded::NoDb - }); - } + NssLoaded::NoDb + }); } /// This enables SSLTRACE by calling a simple, harmless function to trigger its @@ -158,51 +146,71 @@ fn enable_ssl_trace() { /// If NSS cannot be initialized. pub fn init_db<P: Into<PathBuf>>(dir: P) { time::init(); - unsafe { - INITIALIZED.call_once(|| { - version_check(); - if already_initialized() { - return NssLoaded::External; - } + _ = INITIALIZED.get_or_init(|| { + version_check(); + if already_initialized() { + return NssLoaded::External; + } - let path = dir.into(); - assert!(path.is_dir()); - let pathstr = path.to_str().expect("path converts to string").to_string(); - let dircstr = CString::new(pathstr).unwrap(); - let empty = CString::new("").unwrap(); - secstatus_to_res(nss::NSS_Initialize( + let path = dir.into(); + assert!(path.is_dir()); + let pathstr = path.to_str().expect("path converts to string").to_string(); + let dircstr = CString::new(pathstr).unwrap(); + let empty = CString::new("").unwrap(); + secstatus_to_res(unsafe { + nss::NSS_Initialize( dircstr.as_ptr(), empty.as_ptr(), empty.as_ptr(), nss::SECMOD_DB.as_ptr().cast(), nss::NSS_INIT_READONLY, - )) - .expect("NSS_Initialize failed"); - - secstatus_to_res(nss::NSS_SetDomesticPolicy()).expect("NSS_SetDomesticPolicy failed"); - secstatus_to_res(ssl::SSL_ConfigServerSessionIDCache( - 1024, - 0, - 0, - dircstr.as_ptr(), - )) - .expect("SSL_ConfigServerSessionIDCache failed"); - - #[cfg(debug_assertions)] - enable_ssl_trace(); - - NssLoaded::Db(path.into_boxed_path()) - }); - } + ) + }) + .expect("NSS_Initialize failed"); + + secstatus_to_res(unsafe { nss::NSS_SetDomesticPolicy() }) + .expect("NSS_SetDomesticPolicy failed"); + secstatus_to_res(unsafe { + ssl::SSL_ConfigServerSessionIDCache(1024, 0, 0, dircstr.as_ptr()) + }) + .expect("SSL_ConfigServerSessionIDCache failed"); + + #[cfg(debug_assertions)] + enable_ssl_trace(); + + NssLoaded::Db + }); } /// # Panics /// /// If NSS isn't initialized. pub fn assert_initialized() { - unsafe { - INITIALIZED.call_once(|| { - panic!("NSS not initialized with init or init_db"); - }); + INITIALIZED + .get() + .expect("NSS not initialized with init or init_db"); +} + +/// NSS tends to return empty "slices" with a null pointer, which will cause +/// `std::slice::from_raw_parts` to panic if passed directly. This wrapper avoids +/// that issue. It also performs conversion for lengths, as a convenience. +/// +/// # Panics +/// If the provided length doesn't fit into a `usize`. +/// +/// # Safety +/// The caller must adhere to the safety constraints of `std::slice::from_raw_parts`, +/// except that this will accept a null value for `data`. +unsafe fn null_safe_slice<'a, T>(data: *const u8, len: T) -> &'a [u8] +where + usize: TryFrom<T>, +{ + if data.is_null() { + &[] + } else if let Ok(len) = usize::try_from(len) { + #[allow(clippy::disallowed_methods)] + std::slice::from_raw_parts(data, len) + } else { + panic!("null_safe_slice: size overflow"); } } |