summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-crypto/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/neqo-crypto/src/lib.rs')
-rw-r--r--third_party/rust/neqo-crypto/src/lib.rs132
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");
}
}