summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-crypto
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/neqo-crypto/.cargo-checksum.json2
-rw-r--r--third_party/rust/neqo-crypto/Cargo.toml8
-rw-r--r--third_party/rust/neqo-crypto/bindings/bindings.toml5
-rw-r--r--third_party/rust/neqo-crypto/bindings/mozpkix.hpp1
-rw-r--r--third_party/rust/neqo-crypto/build.rs105
-rw-r--r--third_party/rust/neqo-crypto/min_version.txt1
-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
-rw-r--r--third_party/rust/neqo-crypto/tests/aead.rs3
-rw-r--r--third_party/rust/neqo-crypto/tests/init.rs51
-rw-r--r--third_party/rust/neqo-crypto/tests/selfencrypt.rs6
18 files changed, 271 insertions, 224 deletions
diff --git a/third_party/rust/neqo-crypto/.cargo-checksum.json b/third_party/rust/neqo-crypto/.cargo-checksum.json
index 5622e7f4ad..c3e603bd5a 100644
--- a/third_party/rust/neqo-crypto/.cargo-checksum.json
+++ b/third_party/rust/neqo-crypto/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"6f1917fbd4cbf53cb4883c30e8fcb9c20f8ebe15e19576c7d37cb6ba0ab9e42b","bindings/bindings.toml":"0660c1661318b8a5094834c2f1bb12266287ef467307f66947eff7762528f70a","bindings/mozpkix.hpp":"77072c8bb0f6eb6bfe8cbadc111dcd92e0c79936d13f2e501aae1e5d289a6675","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"21d9a0140b2afd708583f58f2af0a4ba93ab07ec088680b4cbf0e184aeb8785b","src/aead.rs":"8f50e4557b7829edb67f57c80c777c6ae23c868e2b2eeaaae0736af04dc0d298","src/aead_fuzzing.rs":"c3e590572314e0bb3fafa13dac3c831358b8a7b5570fe9cfe592752fce8cbdee","src/agent.rs":"e995e9cc5108470594bae1b0d4e4bc6b7a8ac2b66488f71ea99e2836c0edbd7e","src/agentio.rs":"c4cb1b3cd92ef53eb0b4fb0b34a597068d82d78ba470dae5821670a0f06c9cda","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"8942cb3ce25a61f92b6ffc30fb286052ed6f56eeda3be12fd46ea76ceba6c1cf","src/constants.rs":"f22bf16bd8cb539862cb1e47138dbba79e93fe738f4b907e465891326f98883c","src/ech.rs":"9d322fcc01c0886f1dfe9bb6273cb9f88a746452ac9a802761b1816a05930c1f","src/err.rs":"fca0222167883231a5e0a569a593f44214501819adf5aadf814be27891c87c24","src/exp.rs":"cec59d61fc95914f9703d2fb6490a8507af993c9db710dde894f2f8fd38123c7","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"ef32f20e30a9bd7f094199536d19c87c4231b7fbbe4a9c54c70e84ca9c6575be","src/hp.rs":"644f1bed67f1c6189a67c8d02ab3358aaa7f63af4b913dd7395becbc01a84291","src/lib.rs":"23732c7799be038c0e0835b54e7c40cf6c6536113e0adb6ae3b41b216a6e5220","src/p11.rs":"e8c366def0df470101f3d120dcc4391f74f921fe59e2f3db2a56832e2852b855","src/prio.rs":"e5e169296c0ac69919c59fb6c1f8bd6bf079452eaa13d75da0edd41d435d3f6f","src/replay.rs":"96b7af8eff9e14313e79303092018b12e8834f780c96b8e247c497fdc680c696","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"4ffaa66f25df47dadf042063bff5953effa7bf2f4920cafe827757d6a659cb58","src/selfencrypt.rs":"ac65b13f5bade9d03ab4709364f9ec937fa4ca009965c77ca73b481534a0a470","src/ssl.rs":"c83baa5518b81dd06f2e4072ea3c2d666ccdeb8b1ff6e3746eea9f1af47023a6","src/time.rs":"3b2829a98a1648eb052db19bb470808b6b015a1eca27ab7be64b5d196c0271c0","tests/aead.rs":"3ac4fe4ab79922b5d0191a9717058fc8d0710380ce9b25448095f870f511844f","tests/agent.rs":"824735f88e487a3748200844e9481e81a72163ad74d82faa9aa16594d9b9bb25","tests/ext.rs":"1b047d23d9b224ad06eb65d8f3a7b351e263774e404c79bbcbe8f43790e29c18","tests/handshake.rs":"e892a2839b31414be16e96cdf3b1a65978716094700c1a4989229f7edbf578a0","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"b24fec53771c169be788772532d2617a5349196cf87d6444dc74214f7c73e92c","tests/init.rs":"44fe7626b75ab8c57adfee361bb70a83d5958797e1eb6c4531bb74988ba3a990","tests/selfencrypt.rs":"25813b0c6f32fc8383bb7685745feb750eb3fdc0a6a172a50d961c68d39f2a46"},"package":null} \ No newline at end of file
+{"files":{"Cargo.toml":"e0ddb5aa433c742c87b94760fc995afb8091b8fa1360bf1ce66ed59d4e34a44d","bindings/bindings.toml":"29ec7a8ef3d5f1e4a632003e2d36c270e1caf12fd3fcf108a22d1893b90a41a6","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"cbf6a7d912314784c8c124cf7319c910a786d0e263f466843edd3f43826f036c","min_version.txt":"7e98f86c69cddb4f65cf96a6de1f4297e3ce224a4c4628609e29042b6c4dcfb9","src/aead.rs":"fc42bc20b84d2e5ccfd56271ae2d2db082e55586ea2926470c102da177f22296","src/aead_null.rs":"664f80bbb56d0abd3794b99cc927fd5f678ddb4ce95456001413ec18a6c6a6a9","src/agent.rs":"b12004faee4a136c10e8168848d397443b5927e9497edb62c72e6db3eb1c10a0","src/agentio.rs":"c4cb1b3cd92ef53eb0b4fb0b34a597068d82d78ba470dae5821670a0f06c9cda","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"8942cb3ce25a61f92b6ffc30fb286052ed6f56eeda3be12fd46ea76ceba6c1cf","src/constants.rs":"f22bf16bd8cb539862cb1e47138dbba79e93fe738f4b907e465891326f98883c","src/ech.rs":"9d322fcc01c0886f1dfe9bb6273cb9f88a746452ac9a802761b1816a05930c1f","src/err.rs":"ae979f334604aba89640c4491262641910033f0bd790d58671f649f5039b291c","src/exp.rs":"cec59d61fc95914f9703d2fb6490a8507af993c9db710dde894f2f8fd38123c7","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"ef32f20e30a9bd7f094199536d19c87c4231b7fbbe4a9c54c70e84ca9c6575be","src/hp.rs":"644f1bed67f1c6189a67c8d02ab3358aaa7f63af4b913dd7395becbc01a84291","src/lib.rs":"6b2d0eb2c55f6351d673d3a3e5fc5adac8d1030c67dae9af4c79552de0f57455","src/min_version.rs":"89b7ef6f9d2301db4f689f4d963b58375d577f705b92003a804048441e00cfd1","src/p11.rs":"e8c366def0df470101f3d120dcc4391f74f921fe59e2f3db2a56832e2852b855","src/prio.rs":"e5e169296c0ac69919c59fb6c1f8bd6bf079452eaa13d75da0edd41d435d3f6f","src/replay.rs":"96b7af8eff9e14313e79303092018b12e8834f780c96b8e247c497fdc680c696","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"4ffaa66f25df47dadf042063bff5953effa7bf2f4920cafe827757d6a659cb58","src/selfencrypt.rs":"b7cc1c896c7661c37461fc3a8bcbfdf2589433b907fa5f968ae4f6907704b441","src/ssl.rs":"c83baa5518b81dd06f2e4072ea3c2d666ccdeb8b1ff6e3746eea9f1af47023a6","src/time.rs":"c71a01ff8aa2c0e97fb16ad620df4ed6b7cc1819ff93f46634e2f1c9551627ec","tests/aead.rs":"e36ae77802df1ea6d17cfd1bd2178a3706089577d6fd1554ca86e748b8b235b9","tests/agent.rs":"824735f88e487a3748200844e9481e81a72163ad74d82faa9aa16594d9b9bb25","tests/ext.rs":"1b047d23d9b224ad06eb65d8f3a7b351e263774e404c79bbcbe8f43790e29c18","tests/handshake.rs":"e892a2839b31414be16e96cdf3b1a65978716094700c1a4989229f7edbf578a0","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"b24fec53771c169be788772532d2617a5349196cf87d6444dc74214f7c73e92c","tests/init.rs":"616313cb38eac44b8c71a1d23a52a7d7b4c7c07d4c20dc9ea6600c3317f92613","tests/selfencrypt.rs":"8d10840b41629bf449a6b3a551377315e8a05ca26c6b041548748196652c5909"},"package":null} \ No newline at end of file
diff --git a/third_party/rust/neqo-crypto/Cargo.toml b/third_party/rust/neqo-crypto/Cargo.toml
index 499921e531..9507a066df 100644
--- a/third_party/rust/neqo-crypto/Cargo.toml
+++ b/third_party/rust/neqo-crypto/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.74.0"
name = "neqo-crypto"
-version = "0.7.2"
+version = "0.7.5"
authors = ["The Neqo Authors <necko@mozilla.com>"]
build = "build.rs"
homepage = "https://github.com/mozilla/neqo/"
@@ -43,6 +43,10 @@ version = "0.1"
optional = true
default-features = false
+[build-dependencies.semver]
+version = "1.0"
+default-features = false
+
[build-dependencies.serde]
version = "1.0"
default-features = false
@@ -56,7 +60,7 @@ version = "0.5"
default-features = false
[features]
-fuzzing = []
+disable-encryption = []
gecko = ["mozbuild"]
[lints.clippy.pedantic]
diff --git a/third_party/rust/neqo-crypto/bindings/bindings.toml b/third_party/rust/neqo-crypto/bindings/bindings.toml
index 3e5c1fdf7d..72c6d524d5 100644
--- a/third_party/rust/neqo-crypto/bindings/bindings.toml
+++ b/third_party/rust/neqo-crypto/bindings/bindings.toml
@@ -265,8 +265,3 @@ enums = [
[nspr_time]
types = ["PRTime"]
functions = ["PR_Now"]
-
-[mozpkix]
-cplusplus = true
-types = ["mozilla::pkix::ErrorCode"]
-enums = ["mozilla::pkix::ErrorCode"]
diff --git a/third_party/rust/neqo-crypto/bindings/mozpkix.hpp b/third_party/rust/neqo-crypto/bindings/mozpkix.hpp
deleted file mode 100644
index d0a6cb5861..0000000000
--- a/third_party/rust/neqo-crypto/bindings/mozpkix.hpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "mozpkix/pkixnss.h" \ No newline at end of file
diff --git a/third_party/rust/neqo-crypto/build.rs b/third_party/rust/neqo-crypto/build.rs
index c4c2a73e75..2dd4543797 100644
--- a/third_party/rust/neqo-crypto/build.rs
+++ b/third_party/rust/neqo-crypto/build.rs
@@ -12,8 +12,13 @@ use std::{
};
use bindgen::Builder;
+use semver::{Version, VersionReq};
use serde_derive::Deserialize;
+#[path = "src/min_version.rs"]
+mod min_version;
+use min_version::MINIMUM_NSS_VERSION;
+
const BINDINGS_DIR: &str = "bindings";
const BINDINGS_CONFIG: &str = "bindings.toml";
@@ -90,46 +95,6 @@ fn setup_clang() {
}
}
-fn nss_dir() -> PathBuf {
- let dir = if let Ok(dir) = env::var("NSS_DIR") {
- let path = PathBuf::from(dir.trim());
- assert!(
- !path.is_relative(),
- "The NSS_DIR environment variable is expected to be an absolute path."
- );
- path
- } else {
- let out_dir = env::var("OUT_DIR").unwrap();
- let dir = Path::new(&out_dir).join("nss");
- if !dir.exists() {
- Command::new("hg")
- .args([
- "clone",
- "https://hg.mozilla.org/projects/nss",
- dir.to_str().unwrap(),
- ])
- .status()
- .expect("can't clone nss");
- }
- let nspr_dir = Path::new(&out_dir).join("nspr");
- if !nspr_dir.exists() {
- Command::new("hg")
- .args([
- "clone",
- "https://hg.mozilla.org/projects/nspr",
- nspr_dir.to_str().unwrap(),
- ])
- .status()
- .expect("can't clone nspr");
- }
- dir
- };
- assert!(dir.is_dir(), "NSS_DIR {dir:?} doesn't exist");
- // Note that this returns a relative path because UNC
- // paths on windows cause certain tools to explode.
- dir
-}
-
fn get_bash() -> PathBuf {
// If BASH is set, use that.
if let Ok(bash) = env::var("BASH") {
@@ -295,11 +260,63 @@ fn build_bindings(base: &str, bindings: &Bindings, flags: &[String], gecko: bool
.expect("couldn't write bindings");
}
-fn setup_standalone() -> Vec<String> {
+fn pkg_config() -> Vec<String> {
+ let modversion = Command::new("pkg-config")
+ .args(["--modversion", "nss"])
+ .output()
+ .expect("pkg-config reports NSS as absent")
+ .stdout;
+ let modversion = String::from_utf8(modversion).expect("non-UTF8 from pkg-config");
+ let modversion = modversion.trim();
+ // The NSS version number does not follow semver numbering, because it omits the patch version
+ // when that's 0. Deal with that.
+ let modversion_for_cmp = if modversion.chars().filter(|c| *c == '.').count() == 1 {
+ modversion.to_owned() + ".0"
+ } else {
+ modversion.to_owned()
+ };
+ let modversion_for_cmp =
+ Version::parse(&modversion_for_cmp).expect("NSS version not in semver format");
+ let version_req = VersionReq::parse(&format!(">={}", MINIMUM_NSS_VERSION.trim())).unwrap();
+ assert!(
+ version_req.matches(&modversion_for_cmp),
+ "neqo has NSS version requirement {version_req}, found {modversion}"
+ );
+
+ let cfg = Command::new("pkg-config")
+ .args(["--cflags", "--libs", "nss"])
+ .output()
+ .expect("NSS flags not returned by pkg-config")
+ .stdout;
+ let cfg_str = String::from_utf8(cfg).expect("non-UTF8 from pkg-config");
+
+ let mut flags: Vec<String> = Vec::new();
+ for f in cfg_str.split(' ') {
+ if let Some(include) = f.strip_prefix("-I") {
+ flags.push(String::from(f));
+ println!("cargo:include={include}");
+ } else if let Some(path) = f.strip_prefix("-L") {
+ println!("cargo:rustc-link-search=native={path}");
+ } else if let Some(lib) = f.strip_prefix("-l") {
+ println!("cargo:rustc-link-lib=dylib={lib}");
+ } else {
+ println!("Warning: Unknown flag from pkg-config: {f}");
+ }
+ }
+
+ flags
+}
+
+fn setup_standalone(nss: &str) -> Vec<String> {
setup_clang();
println!("cargo:rerun-if-env-changed=NSS_DIR");
- let nss = nss_dir();
+ let nss = PathBuf::from(nss);
+ assert!(
+ !nss.is_relative(),
+ "The NSS_DIR environment variable is expected to be an absolute path."
+ );
+
build_nss(nss.clone());
// $NSS_DIR/../dist/
@@ -406,8 +423,10 @@ fn setup_for_gecko() -> Vec<String> {
fn main() {
let flags = if cfg!(feature = "gecko") {
setup_for_gecko()
+ } else if let Ok(nss_dir) = env::var("NSS_DIR") {
+ setup_standalone(nss_dir.trim())
} else {
- setup_standalone()
+ pkg_config()
};
let config_file = PathBuf::from(BINDINGS_DIR).join(BINDINGS_CONFIG);
diff --git a/third_party/rust/neqo-crypto/min_version.txt b/third_party/rust/neqo-crypto/min_version.txt
new file mode 100644
index 0000000000..422c9c7093
--- /dev/null
+++ b/third_party/rust/neqo-crypto/min_version.txt
@@ -0,0 +1 @@
+3.98
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());
}
diff --git a/third_party/rust/neqo-crypto/tests/aead.rs b/third_party/rust/neqo-crypto/tests/aead.rs
index 5cf0034aec..f8416ed9a7 100644
--- a/third_party/rust/neqo-crypto/tests/aead.rs
+++ b/third_party/rust/neqo-crypto/tests/aead.rs
@@ -5,7 +5,7 @@
// except according to those terms.
#![warn(clippy::pedantic)]
-#![cfg(not(feature = "fuzzing"))]
+#![cfg(not(feature = "disable-encryption"))]
use neqo_crypto::{
constants::{Cipher, TLS_AES_128_GCM_SHA256, TLS_VERSION_1_3},
@@ -40,7 +40,6 @@ fn make_aead(cipher: Cipher) -> Aead {
)
.expect("make a secret");
Aead::new(
- false,
TLS_VERSION_1_3,
cipher,
&secret,
diff --git a/third_party/rust/neqo-crypto/tests/init.rs b/third_party/rust/neqo-crypto/tests/init.rs
index 13218cc340..ee7d808e29 100644
--- a/third_party/rust/neqo-crypto/tests/init.rs
+++ b/third_party/rust/neqo-crypto/tests/init.rs
@@ -15,13 +15,7 @@ use neqo_crypto::{assert_initialized, init_db};
// Pull in the NSS internals so that we can ask NSS if it thinks that
// it is properly initialized.
-#[allow(
- dead_code,
- non_upper_case_globals,
- clippy::redundant_static_lifetimes,
- clippy::unseparated_literal_suffix,
- clippy::upper_case_acronyms
-)]
+#[allow(dead_code, non_upper_case_globals)]
mod nss {
include!(concat!(env!("OUT_DIR"), "/nss_init.rs"));
}
@@ -29,19 +23,54 @@ mod nss {
#[cfg(nss_nodb)]
#[test]
fn init_nodb() {
- init();
+ neqo_crypto::init().unwrap();
assert_initialized();
unsafe {
- assert!(nss::NSS_IsInitialized() != 0);
+ assert_ne!(nss::NSS_IsInitialized(), 0);
}
}
+#[cfg(nss_nodb)]
+#[test]
+fn init_twice_nodb() {
+ unsafe {
+ nss::NSS_NoDB_Init(std::ptr::null());
+ assert_ne!(nss::NSS_IsInitialized(), 0);
+ }
+ // Now do it again
+ init_nodb();
+}
+
#[cfg(not(nss_nodb))]
#[test]
fn init_withdb() {
- init_db(::test_fixture::NSS_DB_PATH);
+ init_db(::test_fixture::NSS_DB_PATH).unwrap();
assert_initialized();
unsafe {
- assert!(nss::NSS_IsInitialized() != 0);
+ assert_ne!(nss::NSS_IsInitialized(), 0);
+ }
+}
+
+#[cfg(not(nss_nodb))]
+#[test]
+fn init_twice_withdb() {
+ use std::{ffi::CString, path::PathBuf};
+
+ let empty = CString::new("").unwrap();
+ let path: PathBuf = ::test_fixture::NSS_DB_PATH.into();
+ assert!(path.is_dir());
+ let pathstr = path.to_str().unwrap();
+ let dircstr = CString::new(pathstr).unwrap();
+ unsafe {
+ nss::NSS_Initialize(
+ dircstr.as_ptr(),
+ empty.as_ptr(),
+ empty.as_ptr(),
+ nss::SECMOD_DB.as_ptr().cast(),
+ nss::NSS_INIT_READONLY,
+ );
+ assert_ne!(nss::NSS_IsInitialized(), 0);
}
+ // Now do it again
+ init_withdb();
}
diff --git a/third_party/rust/neqo-crypto/tests/selfencrypt.rs b/third_party/rust/neqo-crypto/tests/selfencrypt.rs
index 4c574a3ae9..9fc2162fe2 100644
--- a/third_party/rust/neqo-crypto/tests/selfencrypt.rs
+++ b/third_party/rust/neqo-crypto/tests/selfencrypt.rs
@@ -4,7 +4,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![cfg(not(feature = "fuzzing"))]
+#![cfg(not(feature = "disable-encryption"))]
use neqo_crypto::{
constants::{TLS_AES_128_GCM_SHA256, TLS_VERSION_1_3},
@@ -15,7 +15,7 @@ use neqo_crypto::{
#[test]
fn se_create() {
- init();
+ init().unwrap();
SelfEncrypt::new(TLS_VERSION_1_3, TLS_AES_128_GCM_SHA256).expect("constructor works");
}
@@ -23,7 +23,7 @@ const PLAINTEXT: &[u8] = b"PLAINTEXT";
const AAD: &[u8] = b"AAD";
fn sealed() -> (SelfEncrypt, Vec<u8>) {
- init();
+ init().unwrap();
let se = SelfEncrypt::new(TLS_VERSION_1_3, TLS_AES_128_GCM_SHA256).unwrap();
let sealed = se.seal(AAD, PLAINTEXT).expect("sealing works");
(se, sealed)