summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-crypto/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/neqo-crypto/src/aead.rs8
-rw-r--r--third_party/rust/neqo-crypto/src/aead_fuzzing.rs103
-rw-r--r--third_party/rust/neqo-crypto/src/aead_null.rs78
-rw-r--r--third_party/rust/neqo-crypto/src/agent.rs11
-rw-r--r--third_party/rust/neqo-crypto/src/err.rs30
-rw-r--r--third_party/rust/neqo-crypto/src/lib.rs68
-rw-r--r--third_party/rust/neqo-crypto/src/min_version.rs9
-rw-r--r--third_party/rust/neqo-crypto/src/selfencrypt.rs2
-rw-r--r--third_party/rust/neqo-crypto/src/time.rs4
9 files changed, 157 insertions, 156 deletions
diff --git a/third_party/rust/neqo-crypto/src/aead.rs b/third_party/rust/neqo-crypto/src/aead.rs
index bf7d7fe9d7..21027d55b2 100644
--- a/third_party/rust/neqo-crypto/src/aead.rs
+++ b/third_party/rust/neqo-crypto/src/aead.rs
@@ -63,13 +63,7 @@ impl RealAead {
/// # Errors
///
/// Returns `Error` when the supporting NSS functions fail.
- pub fn new(
- _fuzzing: bool,
- version: Version,
- cipher: Cipher,
- secret: &SymKey,
- prefix: &str,
- ) -> Res<Self> {
+ pub fn new(version: Version, cipher: Cipher, secret: &SymKey, prefix: &str) -> Res<Self> {
let s: *mut PK11SymKey = **secret;
unsafe { Self::from_raw(version, cipher, s, prefix) }
}
diff --git a/third_party/rust/neqo-crypto/src/aead_fuzzing.rs b/third_party/rust/neqo-crypto/src/aead_fuzzing.rs
deleted file mode 100644
index 4e5a6de07f..0000000000
--- a/third_party/rust/neqo-crypto/src/aead_fuzzing.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt;
-
-use crate::{
- constants::{Cipher, Version},
- err::{sec::SEC_ERROR_BAD_DATA, Error, Res},
- p11::SymKey,
- RealAead,
-};
-
-pub const FIXED_TAG_FUZZING: &[u8] = &[0x0a; 16];
-
-pub struct FuzzingAead {
- real: Option<RealAead>,
-}
-
-impl FuzzingAead {
- pub fn new(
- fuzzing: bool,
- version: Version,
- cipher: Cipher,
- secret: &SymKey,
- prefix: &str,
- ) -> Res<Self> {
- let real = if fuzzing {
- None
- } else {
- Some(RealAead::new(false, version, cipher, secret, prefix)?)
- };
- Ok(Self { real })
- }
-
- #[must_use]
- pub fn expansion(&self) -> usize {
- if let Some(aead) = &self.real {
- aead.expansion()
- } else {
- FIXED_TAG_FUZZING.len()
- }
- }
-
- pub fn encrypt<'a>(
- &self,
- count: u64,
- aad: &[u8],
- input: &[u8],
- output: &'a mut [u8],
- ) -> Res<&'a [u8]> {
- if let Some(aead) = &self.real {
- return aead.encrypt(count, aad, input, output);
- }
-
- let l = input.len();
- output[..l].copy_from_slice(input);
- output[l..l + 16].copy_from_slice(FIXED_TAG_FUZZING);
- Ok(&output[..l + 16])
- }
-
- pub fn decrypt<'a>(
- &self,
- count: u64,
- aad: &[u8],
- input: &[u8],
- output: &'a mut [u8],
- ) -> Res<&'a [u8]> {
- if let Some(aead) = &self.real {
- return aead.decrypt(count, aad, input, output);
- }
-
- if input.len() < FIXED_TAG_FUZZING.len() {
- return Err(Error::from(SEC_ERROR_BAD_DATA));
- }
-
- let len_encrypted = input.len() - FIXED_TAG_FUZZING.len();
- // Check that:
- // 1) expansion is all zeros and
- // 2) if the encrypted data is also supplied that at least some values are no zero
- // (otherwise padding will be interpreted as a valid packet)
- if &input[len_encrypted..] == FIXED_TAG_FUZZING
- && (len_encrypted == 0 || input[..len_encrypted].iter().any(|x| *x != 0x0))
- {
- output[..len_encrypted].copy_from_slice(&input[..len_encrypted]);
- Ok(&output[..len_encrypted])
- } else {
- Err(Error::from(SEC_ERROR_BAD_DATA))
- }
- }
-}
-
-impl fmt::Debug for FuzzingAead {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if let Some(a) = &self.real {
- a.fmt(f)
- } else {
- write!(f, "[FUZZING AEAD]")
- }
- }
-}
diff --git a/third_party/rust/neqo-crypto/src/aead_null.rs b/third_party/rust/neqo-crypto/src/aead_null.rs
new file mode 100644
index 0000000000..2d5656de73
--- /dev/null
+++ b/third_party/rust/neqo-crypto/src/aead_null.rs
@@ -0,0 +1,78 @@
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg(feature = "disable-encryption")]
+
+use std::fmt;
+
+use crate::{
+ constants::{Cipher, Version},
+ err::{sec::SEC_ERROR_BAD_DATA, Error, Res},
+ p11::SymKey,
+};
+
+pub const AEAD_NULL_TAG: &[u8] = &[0x0a; 16];
+
+pub struct AeadNull {}
+
+impl AeadNull {
+ #[allow(clippy::missing_errors_doc)]
+ pub fn new(_version: Version, _cipher: Cipher, _secret: &SymKey, _prefix: &str) -> Res<Self> {
+ Ok(Self {})
+ }
+
+ #[must_use]
+ pub fn expansion(&self) -> usize {
+ AEAD_NULL_TAG.len()
+ }
+
+ #[allow(clippy::missing_errors_doc)]
+ pub fn encrypt<'a>(
+ &self,
+ _count: u64,
+ _aad: &[u8],
+ input: &[u8],
+ output: &'a mut [u8],
+ ) -> Res<&'a [u8]> {
+ let l = input.len();
+ output[..l].copy_from_slice(input);
+ output[l..l + 16].copy_from_slice(AEAD_NULL_TAG);
+ Ok(&output[..l + 16])
+ }
+
+ #[allow(clippy::missing_errors_doc)]
+ pub fn decrypt<'a>(
+ &self,
+ _count: u64,
+ _aad: &[u8],
+ input: &[u8],
+ output: &'a mut [u8],
+ ) -> Res<&'a [u8]> {
+ if input.len() < AEAD_NULL_TAG.len() {
+ return Err(Error::from(SEC_ERROR_BAD_DATA));
+ }
+
+ let len_encrypted = input.len() - AEAD_NULL_TAG.len();
+ // Check that:
+ // 1) expansion is all zeros and
+ // 2) if the encrypted data is also supplied that at least some values are no zero
+ // (otherwise padding will be interpreted as a valid packet)
+ if &input[len_encrypted..] == AEAD_NULL_TAG
+ && (len_encrypted == 0 || input[..len_encrypted].iter().any(|x| *x != 0x0))
+ {
+ output[..len_encrypted].copy_from_slice(&input[..len_encrypted]);
+ Ok(&output[..len_encrypted])
+ } else {
+ Err(Error::from(SEC_ERROR_BAD_DATA))
+ }
+ }
+}
+
+impl fmt::Debug for AeadNull {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "[NULL AEAD]")
+ }
+}
diff --git a/third_party/rust/neqo-crypto/src/agent.rs b/third_party/rust/neqo-crypto/src/agent.rs
index 82a6dacd48..3d5a8b9f35 100644
--- a/third_party/rust/neqo-crypto/src/agent.rs
+++ b/third_party/rust/neqo-crypto/src/agent.rs
@@ -16,7 +16,7 @@ use std::{
time::Instant,
};
-use neqo_common::{hex_snip_middle, hex_with_len, qdebug, qinfo, qtrace, qwarn};
+use neqo_common::{hex_snip_middle, hex_with_len, qdebug, qtrace, qwarn};
pub use crate::{
agentio::{as_c_void, Record, RecordList},
@@ -406,10 +406,7 @@ impl SecretAgent {
self.set_option(ssl::Opt::Locking, false)?;
self.set_option(ssl::Opt::Tickets, false)?;
self.set_option(ssl::Opt::OcspStapling, true)?;
- if let Err(e) = self.set_option(ssl::Opt::Grease, grease) {
- // Until NSS supports greasing, it's OK to fail here.
- qinfo!([self], "Failed to enable greasing {:?}", e);
- }
+ self.set_option(ssl::Opt::Grease, grease)?;
Ok(())
}
@@ -670,7 +667,7 @@ impl SecretAgent {
let info = self.capture_error(SecretAgentInfo::new(self.fd))?;
HandshakeState::Complete(info)
};
- qinfo!([self], "state -> {:?}", self.state);
+ qdebug!([self], "state -> {:?}", self.state);
Ok(())
}
@@ -898,7 +895,7 @@ impl Client {
let len = usize::try_from(len).unwrap();
let mut v = Vec::with_capacity(len);
v.extend_from_slice(null_safe_slice(token, len));
- qinfo!(
+ qdebug!(
[format!("{fd:p}")],
"Got resumption token {}",
hex_snip_middle(&v)
diff --git a/third_party/rust/neqo-crypto/src/err.rs b/third_party/rust/neqo-crypto/src/err.rs
index 187303d2a9..8d4f239a0b 100644
--- a/third_party/rust/neqo-crypto/src/err.rs
+++ b/third_party/rust/neqo-crypto/src/err.rs
@@ -16,13 +16,39 @@ mod codes {
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/nss_secerr.rs"));
include!(concat!(env!("OUT_DIR"), "/nss_sslerr.rs"));
- include!(concat!(env!("OUT_DIR"), "/mozpkix.rs"));
}
-pub use codes::{mozilla_pkix_ErrorCode as mozpkix, SECErrorCodes as sec, SSLErrorCodes as ssl};
+pub use codes::{SECErrorCodes as sec, SSLErrorCodes as ssl};
pub mod nspr {
include!(concat!(env!("OUT_DIR"), "/nspr_err.rs"));
}
+pub mod mozpkix {
+ // These are manually extracted from the many bindings generated
+ // by bindgen when provided with the simple header:
+ // #include "mozpkix/pkixnss.h"
+
+ #[allow(non_camel_case_types)]
+ pub type mozilla_pkix_ErrorCode = ::std::os::raw::c_int;
+ pub const MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE: mozilla_pkix_ErrorCode = -16384;
+ pub const MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY: mozilla_pkix_ErrorCode = -16383;
+ pub const MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE: mozilla_pkix_ErrorCode = -16382;
+ pub const MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA: mozilla_pkix_ErrorCode = -16381;
+ pub const MOZILLA_PKIX_ERROR_NO_RFC822NAME_MATCH: mozilla_pkix_ErrorCode = -16380;
+ pub const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: mozilla_pkix_ErrorCode = -16379;
+ pub const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE: mozilla_pkix_ErrorCode = -16378;
+ pub const MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH: mozilla_pkix_ErrorCode = -16377;
+ pub const MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING: mozilla_pkix_ErrorCode = -16376;
+ pub const MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG: mozilla_pkix_ErrorCode = -16375;
+ pub const MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING: mozilla_pkix_ErrorCode = -16374;
+ pub const MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING: mozilla_pkix_ErrorCode = -16373;
+ pub const MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: mozilla_pkix_ErrorCode = -16372;
+ pub const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED: mozilla_pkix_ErrorCode =
+ -16371;
+ pub const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT: mozilla_pkix_ErrorCode = -16370;
+ pub const MOZILLA_PKIX_ERROR_MITM_DETECTED: mozilla_pkix_ErrorCode = -16369;
+ pub const END_OF_LIST: mozilla_pkix_ErrorCode = -16368;
+}
+
pub type Res<T> = Result<T, Error>;
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
diff --git a/third_party/rust/neqo-crypto/src/lib.rs b/third_party/rust/neqo-crypto/src/lib.rs
index 2ec1b4a3ea..2db985e8ee 100644
--- a/third_party/rust/neqo-crypto/src/lib.rs
+++ b/third_party/rust/neqo-crypto/src/lib.rs
@@ -8,8 +8,8 @@
#![allow(clippy::unseparated_literal_suffix, clippy::used_underscore_binding)] // For bindgen code.
mod aead;
-#[cfg(feature = "fuzzing")]
-mod aead_fuzzing;
+#[cfg(feature = "disable-encryption")]
+pub mod aead_null;
pub mod agent;
mod agentio;
mod auth;
@@ -33,12 +33,12 @@ mod time;
use std::{ffi::CString, path::PathBuf, ptr::null, sync::OnceLock};
-#[cfg(not(feature = "fuzzing"))]
+#[cfg(not(feature = "disable-encryption"))]
pub use self::aead::RealAead as Aead;
-#[cfg(feature = "fuzzing")]
+#[cfg(feature = "disable-encryption")]
pub use self::aead::RealAead;
-#[cfg(feature = "fuzzing")]
-pub use self::aead_fuzzing::FuzzingAead as Aead;
+#[cfg(feature = "disable-encryption")]
+pub use self::aead_null::AeadNull as Aead;
pub use self::{
agent::{
Agent, AllowZeroRtt, Client, HandshakeState, Record, RecordList, ResumptionToken,
@@ -59,7 +59,8 @@ pub use self::{
ssl::Opt,
};
-const MINIMUM_NSS_VERSION: &str = "3.97";
+mod min_version;
+use min_version::MINIMUM_NSS_VERSION;
#[allow(non_upper_case_globals, clippy::redundant_static_lifetimes)]
#[allow(clippy::upper_case_acronyms)]
@@ -89,7 +90,7 @@ impl Drop for NssLoaded {
}
}
-static INITIALIZED: OnceLock<NssLoaded> = OnceLock::new();
+static INITIALIZED: OnceLock<Res<NssLoaded>> = OnceLock::new();
fn already_initialized() -> bool {
unsafe { nss::NSS_IsInitialized() != 0 }
@@ -107,24 +108,24 @@ fn version_check() {
/// Initialize NSS. This only executes the initialization routines once, so if there is any chance
/// that
///
-/// # Panics
+/// # Errors
///
/// When NSS initialization fails.
-pub fn init() {
+pub fn init() -> Res<()> {
// Set time zero.
time::init();
- _ = INITIALIZED.get_or_init(|| {
+ let res = INITIALIZED.get_or_init(|| {
version_check();
if already_initialized() {
- return NssLoaded::External;
+ return Ok(NssLoaded::External);
}
- 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");
+ secstatus_to_res(unsafe { nss::NSS_NoDB_Init(null()) })?;
+ secstatus_to_res(unsafe { nss::NSS_SetDomesticPolicy() })?;
- NssLoaded::NoDb
+ Ok(NssLoaded::NoDb)
});
+ res.as_ref().map(|_| ()).map_err(Clone::clone)
}
/// This enables SSLTRACE by calling a simple, harmless function to trigger its
@@ -132,31 +133,32 @@ pub fn init() {
/// global options are accessed. Reading an option is the least impact approach.
/// This allows us to use SSLTRACE in all of our unit tests and programs.
#[cfg(debug_assertions)]
-fn enable_ssl_trace() {
+fn enable_ssl_trace() -> Res<()> {
let opt = ssl::Opt::Locking.as_int();
let mut v: ::std::os::raw::c_int = 0;
secstatus_to_res(unsafe { ssl::SSL_OptionGetDefault(opt, &mut v) })
- .expect("SSL_OptionGetDefault failed");
}
/// Initialize with a database.
///
-/// # Panics
+/// # Errors
///
/// If NSS cannot be initialized.
-pub fn init_db<P: Into<PathBuf>>(dir: P) {
+pub fn init_db<P: Into<PathBuf>>(dir: P) -> Res<()> {
time::init();
- _ = INITIALIZED.get_or_init(|| {
+ let res = INITIALIZED.get_or_init(|| {
version_check();
if already_initialized() {
- return NssLoaded::External;
+ return Ok(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();
+ if !path.is_dir() {
+ return Err(Error::InternalError);
+ }
+ let pathstr = path.to_str().ok_or(Error::InternalError)?;
+ let dircstr = CString::new(pathstr)?;
+ let empty = CString::new("")?;
secstatus_to_res(unsafe {
nss::NSS_Initialize(
dircstr.as_ptr(),
@@ -165,21 +167,19 @@ pub fn init_db<P: Into<PathBuf>>(dir: P) {
nss::SECMOD_DB.as_ptr().cast(),
nss::NSS_INIT_READONLY,
)
- })
- .expect("NSS_Initialize failed");
+ })?;
- secstatus_to_res(unsafe { nss::NSS_SetDomesticPolicy() })
- .expect("NSS_SetDomesticPolicy failed");
+ secstatus_to_res(unsafe { nss::NSS_SetDomesticPolicy() })?;
secstatus_to_res(unsafe {
ssl::SSL_ConfigServerSessionIDCache(1024, 0, 0, dircstr.as_ptr())
- })
- .expect("SSL_ConfigServerSessionIDCache failed");
+ })?;
#[cfg(debug_assertions)]
- enable_ssl_trace();
+ enable_ssl_trace()?;
- NssLoaded::Db
+ Ok(NssLoaded::Db)
});
+ res.as_ref().map(|_| ()).map_err(Clone::clone)
}
/// # Panics
diff --git a/third_party/rust/neqo-crypto/src/min_version.rs b/third_party/rust/neqo-crypto/src/min_version.rs
new file mode 100644
index 0000000000..4386371b1b
--- /dev/null
+++ b/third_party/rust/neqo-crypto/src/min_version.rs
@@ -0,0 +1,9 @@
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// The minimum version of NSS that is required by this version of neqo.
+/// Note that the string may contain whitespace at the beginning and/or end.
+pub(crate) const MINIMUM_NSS_VERSION: &str = include_str!("../min_version.txt");
diff --git a/third_party/rust/neqo-crypto/src/selfencrypt.rs b/third_party/rust/neqo-crypto/src/selfencrypt.rs
index 1130c35250..d0a85830b0 100644
--- a/third_party/rust/neqo-crypto/src/selfencrypt.rs
+++ b/third_party/rust/neqo-crypto/src/selfencrypt.rs
@@ -47,7 +47,7 @@ impl SelfEncrypt {
debug_assert_eq!(salt.len(), Self::SALT_LENGTH);
let salt = hkdf::import_key(self.version, salt)?;
let secret = hkdf::extract(self.version, self.cipher, Some(&salt), k)?;
- Aead::new(false, self.version, self.cipher, &secret, "neqo self")
+ Aead::new(self.version, self.cipher, &secret, "neqo self")
}
/// Rotate keys. This causes any previous key that is being held to be replaced by the current
diff --git a/third_party/rust/neqo-crypto/src/time.rs b/third_party/rust/neqo-crypto/src/time.rs
index 0e59c4f5e2..359436a854 100644
--- a/third_party/rust/neqo-crypto/src/time.rs
+++ b/third_party/rust/neqo-crypto/src/time.rs
@@ -258,11 +258,11 @@ mod test {
#[test]
// We allow replace_consts here because
- // std::u64::max_value() isn't available
+ // std::u64::MAX isn't available
// in all of our targets
fn overflow_interval() {
init();
- let interval = Interval::from(Duration::from_micros(u64::max_value()));
+ let interval = Interval::from(Duration::from_micros(u64::MAX));
let res: Res<PRTime> = interval.try_into();
assert!(res.is_err());
}