From 30850a194fd07c0ad26605431638a343eb97a5d2 Mon Sep 17 00:00:00 2001 From: Kevin Lewi Date: Tue, 3 Nov 2026 11:45:11 -0800 Subject: [PATCH] Fix CI: rustfmt, clippy and cargo-deny - Apply the latest nightly rustfmt (comment wrapping under `wrap_comments = true`) - Fix clippy lints: explicit_counter_loop and a redundant format! reference in the test vector parser, and some_filter (new in clippy 1.99) in the SIGMA-I transcript builder (`cond.then_some(x)`, same behavior) - Allow clippy::multiple_crate_versions: a fresh resolve pulls in both syn 2 and syn 3 through proc-macro dependencies, which fails the clippy::cargo lint group - Upgrade the cryptoki dev-dependency to 0.12.1 to address RUSTSEC-2026-0286 (used only by the HSM integration test) - Temporarily ignore RUSTSEC-2026-0387 (crypto-bigint 0.5 via elliptic-curve 0.13) in deny.toml. There is no patched 0.5.x; the real fix is the elliptic-curve 0.14 migration, which should remove this ignore. --- Cargo.toml | 2 +- deny.toml | 4 ++++ examples/digital_locker.rs | 3 ++- examples/simple_login.rs | 14 ++++++++------ src/envelope.rs | 3 ++- src/key_exchange/group/elliptic_curve.rs | 6 +++--- src/key_exchange/sigma_i/ecdsa.rs | 8 ++++---- src/key_exchange/sigma_i/message.rs | 10 +++++----- src/keypair.rs | 5 +++-- src/lib.rs | 2 +- src/tests/parser.rs | 10 +++------- tests/remote_key.rs | 18 ++++++++++-------- 12 files changed, 46 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1348888..2d38b6bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ anyhow = "1" bincode = "1" chacha20poly1305 = "0.10" criterion = "0.8" -cryptoki = "0.9" +cryptoki = "0.12.1" elliptic-curve = { version = "0.13", features = ["alloc", "pkcs8"] } hex = "0.4" opaque-ke-3 = { package = "opaque-ke", version = "=3.0.0" } diff --git a/deny.toml b/deny.toml index dcfd0a50..d47d4271 100644 --- a/deny.toml +++ b/deny.toml @@ -46,6 +46,10 @@ ignore = [ "RUSTSEC-2024-0436", # bincode is unmaintained but only used as dev-dependency for tests "RUSTSEC-2025-0141", + # TODO: remove once opaque-ke and voprf move to elliptic-curve 0.14. + # crypto-bigint 0.5 (via elliptic-curve 0.13) has timing variability in + # operations intended to be constant-time; there is no patched 0.5.x + "RUSTSEC-2026-0387", ] # Threshold for security vulnerabilities, any vulnerability with a CVSS score # lower than the range specified will be ignored. Note that ignored advisories diff --git a/examples/digital_locker.rs b/examples/digital_locker.rs index 571856c8..d6a02bf8 100644 --- a/examples/digital_locker.rs +++ b/examples/digital_locker.rs @@ -201,7 +201,8 @@ fn open_locker( ) .unwrap(); - // Server sends locker contents, encrypted under the session key, to the client + // Server sends locker contents, encrypted under the session key, to the + // client let encrypted_locker_contents = encrypt(&server_login_finish_result.session_key, &locker.contents); diff --git a/examples/simple_login.rs b/examples/simple_login.rs index 7affe747..3b007f74 100644 --- a/examples/simple_login.rs +++ b/examples/simple_login.rs @@ -198,12 +198,14 @@ fn main() { { println!("\nLogin success!"); } else { - // Note that at this point, the client knows whether or not the - // login succeeded. In this example, we simply rely on - // client-reported result of login, but in a real client-server - // implementation, the server may not know the outcome of login yet, - // and extra care must be taken to ensure that the server can learn - // the outcome as well. + // Note that at this point, the client knows + // whether or not the login succeeded. In this + // example, we simply rely on client-reported + // result of login, but in a real client-server + // implementation, the server may not know the + // outcome of login yet, and extra care must be + // taken to ensure that the server can learn the + // outcome as well. println!("\nIncorrect password, please try again."); } } diff --git a/src/envelope.rs b/src/envelope.rs index 7d61b91e..c161e48c 100644 --- a/src/envelope.rs +++ b/src/envelope.rs @@ -245,7 +245,8 @@ impl Envelope { Ok(OpenedInnerEnvelope { export_key }) } - // Creates a dummy envelope object that serializes to the all-zeros byte string + // Creates a dummy envelope object that serializes to the all-zeros byte + // string pub(crate) fn dummy() -> Self { Self { mode: InnerEnvelopeMode::Zero, diff --git a/src/key_exchange/group/elliptic_curve.rs b/src/key_exchange/group/elliptic_curve.rs index 85a9ae9b..e7586ac9 100644 --- a/src/key_exchange/group/elliptic_curve.rs +++ b/src/key_exchange/group/elliptic_curve.rs @@ -34,9 +34,9 @@ where Repr = GenericArray as ModulusSize>::CompressedPointSize>, > + ToEncodedPoint, { - // We don't use `elliptic_curve::PublicKey` because it stores its internals in a - // format ideal for serialization and not computation. This is inconsistent with - // our other implementations. + // We don't use `elliptic_curve::PublicKey` because it stores its internals + // in a format ideal for serialization and not computation. This is + // inconsistent with our other implementations. type Pk = NonIdentity; type PkLen = as ModulusSize>::CompressedPointSize; diff --git a/src/key_exchange/sigma_i/ecdsa.rs b/src/key_exchange/sigma_i/ecdsa.rs index aedaddca..c31235d6 100644 --- a/src/key_exchange/sigma_i/ecdsa.rs +++ b/src/key_exchange/sigma_i/ecdsa.rs @@ -52,8 +52,8 @@ where type SignatureLen = SignatureSize; type VerifyState = PreHash; - // We use a manual implementation of `RandomizedPrehashSigner` to use the same - // hash for the message as for generating `k`. See + // We use a manual implementation of `RandomizedPrehashSigner` to use the + // same hash for the message as for generating `k`. See // https://github.com/RustCrypto/signatures/issues/949. fn sign<'a, R: CryptoRng + RngCore, CS: CipherSuite, KE: Group>( sk: &::Sk, @@ -100,8 +100,8 @@ where let z = hazmat::bits2field::(pre_hash).expect("hash output can not be shorter than a scalar"); - // This can only fail if the computed `r` or `s` are zero, in which case we just - // retry with a new `k`. See https://github.com/RustCrypto/signatures/pull/951. + // This can only fail if the computed `r` or `s` are zero, in which case we + // just retry with a new `k`. See https://github.com/RustCrypto/signatures/pull/951. loop { let mut ad = FieldBytes::::default(); rng.fill_bytes(&mut ad); diff --git a/src/key_exchange/sigma_i/message.rs b/src/key_exchange/sigma_i/message.rs index 01c0ac73..919292c1 100644 --- a/src/key_exchange/sigma_i/message.rs +++ b/src/key_exchange/sigma_i/message.rs @@ -169,21 +169,21 @@ impl CachedMessage { transcript: Role, identifier: &'a SerializedIdentifier<'_, KeGroup>, ) -> impl Clone + Iterator { - Some(identifier.iter()) - .filter(|_| matches!(transcript, Role::Client)) + matches!(transcript, Role::Client) + .then_some(identifier.iter()) .into_iter() .flatten() .chain(self.credential_request.iter()) .chain(self.ke1_message.iter()) .chain( - Some(identifier.iter()) - .filter(|_| matches!(transcript, Role::Server)) + matches!(transcript, Role::Server) + .then_some(identifier.iter()) .into_iter() .flatten(), ) .chain(self.credential_response.iter()) .chain([self.server_nonce.as_slice(), &self.server_e_pk]) - .chain(Some(self.server_mac.as_slice()).filter(|_| matches!(transcript, Role::Client))) + .chain(matches!(transcript, Role::Client).then_some(self.server_mac.as_slice())) } } diff --git a/src/keypair.rs b/src/keypair.rs index f653cc72..0ecbb5da 100644 --- a/src/keypair.rs +++ b/src/keypair.rs @@ -283,8 +283,9 @@ impl KeyPair { use rand::SeedableRng; use rand::rngs::StdRng; - // The no_shrink is because keypairs should be fixed -- shrinking would cause a - // different keypair to be generated, which appears to not be very useful. + // The no_shrink is because keypairs should be fixed -- shrinking would + // cause a different keypair to be generated, which appears to not be + // very useful. any::<[u8; 32]>() .prop_filter_map("valid random keypair", |seed| { let mut rng = StdRng::from_seed(seed); diff --git a/src/lib.rs b/src/lib.rs index f9cd29c5..409e1bc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1358,7 +1358,7 @@ #![cfg_attr(not(test), deny(unsafe_code))] #![warn(clippy::cargo, clippy::doc_markdown, missing_docs, rustdoc::all)] #![cfg_attr(not(test), warn(unused_crate_dependencies))] -#![allow(type_alias_bounds)] +#![allow(clippy::multiple_crate_versions, type_alias_bounds)] #[cfg(any(feature = "std", test))] extern crate std; diff --git a/src/tests/parser.rs b/src/tests/parser.rs index 920dd45c..89f42814 100644 --- a/src/tests/parser.rs +++ b/src/tests/parser.rs @@ -20,15 +20,13 @@ fn parse_vector_types(input: &str) -> String { let chunks: Vec<&str> = re.split(input).collect(); - let mut count = 1; - for caps in re.captures_iter(input) { + for (count, caps) in (1..).zip(re.captures_iter(input)) { let vector_type = format!( "\"{}\": [\n {} \n]", - &caps["type"].trim(), + caps["type"].trim(), parse_ciphersuites(chunks[count]) ); vector_types.push(vector_type); - count += 1; } vector_types.join(",\n") @@ -43,8 +41,7 @@ fn parse_ciphersuites(input: &str) -> String { let chunks: Vec<&str> = re.split(input).collect(); - let mut count = 1; - for caps in re.captures_iter(input) { + for (count, caps) in (1..).zip(re.captures_iter(input)) { let ciphersuite = format!( "{{ \"{}, {}\": {{ {} }} }}", &caps["oprf"], @@ -52,7 +49,6 @@ fn parse_ciphersuites(input: &str) -> String { parse_params(chunks[count]) ); ciphersuites.push(ciphersuite); - count += 1; } ciphersuites.join(",\n") diff --git a/tests/remote_key.rs b/tests/remote_key.rs index f64398b7..a804d193 100644 --- a/tests/remote_key.rs +++ b/tests/remote_key.rs @@ -15,7 +15,7 @@ use std::vec::Vec; #[cfg(feature = "ecdsa")] use ::ecdsa::SignatureSize; -use cryptoki::context::{CInitializeArgs, Pkcs11}; +use cryptoki::context::{CInitializeArgs, CInitializeFlags, Pkcs11}; use cryptoki::mechanism::Mechanism; use cryptoki::mechanism::elliptic_curve::{EcKdf, Ecdh1DeriveParams}; use cryptoki::object::{Attribute, AttributeType, KeyType, ObjectClass, ObjectHandle}; @@ -134,8 +134,8 @@ fn triple_dh_curve25519() { } test::( - // This should be [`Mechanism::EccMontgomeryKeyPairGen`], but SoftHSM has an incorrect - // implementation. See https://github.com/softhsm/SoftHSMv2/issues/647. + // This should be [`Mechanism::EccMontgomeryKeyPairGen`], but SoftHSM + // has an incorrect implementation. See https://github.com/softhsm/SoftHSMv2/issues/647. Mechanism::EccEdwardsKeyPairGen, ObjectIdentifier::new("1.3.101.110").unwrap(), Attribute::Derive(true), @@ -242,7 +242,7 @@ fn test( let key_material_info = server_setup.key_material_info(&[]); let key_material = pkcs11_hkdf::( key_material_info.ikm, - hmac_mechanism, + &hmac_mechanism, Vec::from_iter(key_material_info.info.into_iter().flatten().copied()), ); let message = ServerRegistration::start_with_key_material(&server_setup, key_material, message) @@ -266,7 +266,7 @@ fn test( let key_material_info = server_setup.key_material_info(&[]); let key_material = pkcs11_hkdf::( key_material_info.ikm, - hmac_mechanism, + &hmac_mechanism, Vec::from_iter(key_material_info.info.into_iter().flatten().copied()), ); let builder = ServerLogin::builder_with_key_material( @@ -310,7 +310,9 @@ fn test( static SESSION: LazyLock> = LazyLock::new(|| { let module = env::var("PKCS11_MODULE").expect("`PKCS11_MODULE` environment variable"); let pkcs11 = Pkcs11::new(module).unwrap(); - pkcs11.initialize(CInitializeArgs::OsThreads).unwrap(); + pkcs11 + .initialize(CInitializeArgs::new(CInitializeFlags::OS_LOCKING_OK)) + .unwrap(); let slot = pkcs11.get_slots_with_token().unwrap()[0]; @@ -380,7 +382,7 @@ fn pkcs11_generate_oprf_seed(length: u64) -> ObjectHandle { // by almost all HSMs and still protects the OPRF seed. fn pkcs11_hkdf( hmac: ObjectHandle, - mechanism: Mechanism, + mechanism: &Mechanism, info: Vec, ) -> GenericArray as voprf::Group>::ScalarLen> { let mut okm = GenericArray::default(); @@ -403,7 +405,7 @@ fn pkcs11_hkdf( data.extend(&info); data.extend(&[block_n + 1]); - let output = session.sign(&mechanism, hmac, &data).unwrap(); + let output = session.sign(mechanism, hmac, &data).unwrap(); block.copy_from_slice(&output[..block.len()]); prev = Some(output); }