From ff290a96b46920e777e8adea489cf68a8f43bfbb Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Fri, 3 Jul 2026 12:26:00 +0200 Subject: [PATCH] deps: move the RustCrypto crates to their stable releases Most of the RustCrypto RC generation we moved to alongside the rand 0.10 upgrade has now had stable releases: - ecdsa 0.17.0-rc.20 -> 0.17.0 - elliptic-curve 0.14.0-rc.35 -> 0.14.1 - chacha20poly1305 0.11.0-rc.3 -> 0.11.0 - pem-rfc7468 0.7.0 -> 1.0.0 - k256/p256/p384 0.14.0-rc.12 -> 0.14.0-rc.15 (no stable release yet) - base64ct 1.8.0 -> 1.8.3 The pem-rfc7468 bump unifies our direct dependency with the 1.0 pulled in through der 0.8, removing a duplicate. elliptic-curve 0.14.1 deprecated SecretKey::random in favour of the Generate trait, and hybrid-array deprecated Array::from_slice in favour of TryFrom, hence the small code changes. Also reconcile deny.toml with the post-upgrade world: document the remaining rand 0.8/0.9 and digest-0.10 generation duplicates still pulled in by cookie, sqlx, opa-wasm, wasmtime and pest, and drop the RUSTSEC-2026-0097 ignore which no longer matches anything now that our own rand is on 0.10. --- Cargo.lock | 4 ++-- Cargo.toml | 16 ++++++------- crates/jose/src/jwk/public_parameters.rs | 7 +++--- crates/jose/src/jwt/signed.rs | 6 ++++- crates/keystore/src/lib.rs | 9 ++++---- deny.toml | 29 ++++++++++++++++++++---- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aea2cfb4b..a518ea331 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3539,7 +3539,7 @@ dependencies = [ "mas-iana", "mas-jose", "mas-keystore", - "pem-rfc7468 0.7.0", + "pem-rfc7468 1.0.0", "rand 0.10.2", "rand_chacha 0.10.0", "rustls-pki-types", @@ -3812,7 +3812,7 @@ dependencies = [ "mas-jose", "p256", "p384", - "pem-rfc7468 0.7.0", + "pem-rfc7468 1.0.0", "pkcs1 0.8.0-rc.4", "pkcs8 0.11.0", "rand 0.10.2", diff --git a/Cargo.toml b/Cargo.toml index fde13cd6e..7c9f6f8b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,7 +127,7 @@ features = ["alloc", "password-hash", "rand_core"] # Constant-time base64 [workspace.dependencies.base64ct] -version = "1.8.0" +version = "1.8.3" features = ["std"] # Bcrypt password hashing @@ -150,7 +150,7 @@ features = ["serde1"] # ChaCha20Poly1305 AEAD [workspace.dependencies.chacha20poly1305] -version = "0.11.0-rc.3" +version = "0.11.0" features = ["alloc", "getrandom"] # Memory optimisation for short strings @@ -220,12 +220,12 @@ version = "0.15.7" # ECDSA algorithms [workspace.dependencies.ecdsa] -version = "0.17.0-rc.20" +version = "0.17.0" features = ["alloc", "der", "pem", "pkcs8", "std"] # Elliptic curve cryptography [workspace.dependencies.elliptic-curve] -version = "0.14.0-rc.35" +version = "0.14.1" features = ["std", "pem", "pkcs8", "arithmetic"] # Configuration loading @@ -349,7 +349,7 @@ version = "0.15.0" # K256 elliptic curve [workspace.dependencies.k256] -version = "0.14.0-rc.12" +version = "0.14.0-rc.15" features = ["std", "ecdsa", "pem", "pkcs8"] # RFC 5646 language tags @@ -439,12 +439,12 @@ default-features = false # P256 elliptic curve [workspace.dependencies.p256] -version = "0.14.0-rc.12" +version = "0.14.0-rc.15" features = ["std", "ecdsa", "pem", "pkcs8"] # P384 elliptic curve [workspace.dependencies.p384] -version = "0.14.0-rc.12" +version = "0.14.0-rc.15" features = ["std", "ecdsa", "pem", "pkcs8"] # Text padding utilities @@ -458,7 +458,7 @@ features = ["phc", "sha2", "alloc"] # PEM encoding/decoding [workspace.dependencies.pem-rfc7468] -version = "0.7.0" +version = "1.0.0" features = ["std"] # Parser generator diff --git a/crates/jose/src/jwk/public_parameters.rs b/crates/jose/src/jwk/public_parameters.rs index 681cb2be8..7ca4f326d 100644 --- a/crates/jose/src/jwk/public_parameters.rs +++ b/crates/jose/src/jwk/public_parameters.rs @@ -1,3 +1,4 @@ +// Copyright 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2022-2024 The Matrix.org Foundation C.I.C. // @@ -255,9 +256,9 @@ mod ec_impls { .get(..C::FieldBytesSize::USIZE) .ok_or(elliptic_curve::Error)?; - let x = FieldBytes::::from_slice(x); - let y = FieldBytes::::from_slice(y); - let pubkey = Sec1Point::::from_affine_coordinates(x, y, false); + let x = FieldBytes::::try_from(x).map_err(|_| elliptic_curve::Error)?; + let y = FieldBytes::::try_from(y).map_err(|_| elliptic_curve::Error)?; + let pubkey = Sec1Point::::from_affine_coordinates(&x, &y, false); let pubkey: Option<_> = PublicKey::from_sec1_point(&pubkey).into(); pubkey.ok_or(elliptic_curve::Error) } diff --git a/crates/jose/src/jwt/signed.rs b/crates/jose/src/jwt/signed.rs index 0d843a320..e9008cb89 100644 --- a/crates/jose/src/jwt/signed.rs +++ b/crates/jose/src/jwt/signed.rs @@ -1,3 +1,4 @@ +// Copyright 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2022-2024 The Matrix.org Foundation C.I.C. // @@ -406,7 +407,10 @@ mod tests { let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::Es256); let payload = serde_json::json!({"hello": "world"}); - let key = ecdsa::SigningKey::::random(&mut rng()); + let key = + as elliptic_curve::Generate>::generate_from_rng( + &mut rng(), + ); let signed = Jwt::sign::<_, ecdsa::Signature<_>>(header, payload, &key).unwrap(); signed .verify::<_, ecdsa::Signature<_>>(key.verifying_key()) diff --git a/crates/keystore/src/lib.rs b/crates/keystore/src/lib.rs index 5ab1558fa..bab9c51a0 100644 --- a/crates/keystore/src/lib.rs +++ b/crates/keystore/src/lib.rs @@ -1,3 +1,4 @@ +// Copyright 2026 Element Creations Ltd. // Copyright 2024, 2025 New Vector Ltd. // Copyright 2022-2024 The Matrix.org Foundation C.I.C. // @@ -9,7 +10,7 @@ use std::{ops::Deref, sync::Arc}; use der::{Decode, Encode, EncodePem, pem::PemLabel, zeroize::Zeroizing}; -use elliptic_curve::{pkcs8::EncodePrivateKey, sec1::ToSec1Point}; +use elliptic_curve::{Generate, pkcs8::EncodePrivateKey, sec1::ToSec1Point}; use mas_iana::jose::{JsonWebKeyType, JsonWebSignatureAlg}; pub use mas_jose::jwk::{JsonWebKey, JsonWebKeySet}; use mas_jose::{ @@ -501,19 +502,19 @@ impl PrivateKey { /// Generate an Elliptic Curve key for the P-256 curve pub fn generate_ec_p256(mut rng: R) -> Self { - let key = elliptic_curve::SecretKey::random(&mut rng); + let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng); Self::EcP256(Box::new(key)) } /// Generate an Elliptic Curve key for the P-384 curve pub fn generate_ec_p384(mut rng: R) -> Self { - let key = elliptic_curve::SecretKey::random(&mut rng); + let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng); Self::EcP384(Box::new(key)) } /// Generate an Elliptic Curve key for the secp256k1 curve pub fn generate_ec_k256(mut rng: R) -> Self { - let key = elliptic_curve::SecretKey::random(&mut rng); + let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng); Self::EcK256(Box::new(key)) } } diff --git a/deny.toml b/deny.toml index 4df83c61f..a26118071 100644 --- a/deny.toml +++ b/deny.toml @@ -20,9 +20,6 @@ ignore = [ # RSA key extraction "Marvin Attack". This is only relevant when using # PKCS#1 v1.5 encryption, which we don't "RUSTSEC-2023-0071", - # Rand 0.8.5 unsoundness with custom logger + thread_rng reseeding. - # Only triggers when the `log` feature is enabled, which we don't use. - "RUSTSEC-2026-0097", ] [licenses] @@ -83,11 +80,35 @@ skip = [ { name = "darling_core", version = "0.20.11" }, { name = "darling_macro", version = "0.20.11" }, - # We are still mainly using rand 0.8 + # We moved to rand 0.10, but cookie and sqlx still pull the 0.8 generation { name = "rand", version = "0.8.5" }, { name = "rand_chacha", version = "0.3.1" }, { name = "rand_core", version = "0.6.4" }, { name = "getrandom", version = "0.2.16" }, + # ...and opentelemetry_sdk, sentry, ulid and opa-wasm pull the 0.9 generation + { name = "rand", version = "0.9.4" }, + { name = "rand_chacha", version = "0.9.0" }, + { name = "rand_core", version = "0.9.3" }, + { name = "getrandom", version = "0.3.3" }, + + # We moved to the new (digest 0.11-based) generation of the RustCrypto + # crates, but cookie (via axum-extra's private cookies), sqlx, opa-wasm, + # wasmtime and pest still pull the previous generation + { name = "aead", version = "0.5.2" }, # aes-gcm 0.10 <- cookie + { name = "aes", version = "0.8.4" }, # aes-gcm 0.10 <- cookie + { name = "aes-gcm", version = "0.10.3" }, # cookie + { name = "block-buffer", version = "0.10.4" }, # digest 0.10 + { name = "cipher", version = "0.4.4" }, # aes, aes-gcm, ctr + { name = "cpufeatures", version = "0.2.17" }, # aes, polyval, sha1, sha2 0.10 + { name = "crypto-common", version = "0.1.6" }, # aead, cipher, digest 0.10 + { name = "ctr", version = "0.9.2" }, # aes-gcm 0.10 <- cookie + { name = "digest", version = "0.10.7" }, # hmac, md-5, sha1, sha2 0.10 + { name = "ghash", version = "0.5.1" }, # aes-gcm 0.10 <- cookie + { name = "hmac", version = "0.12.1" }, # hkdf 0.12 <- cookie, sqlx, opa-wasm + { name = "inout", version = "0.1.4" }, # cipher 0.4 + { name = "polyval", version = "0.6.2" }, # ghash 0.5 + { name = "sha2", version = "0.10.9" }, # cookie, sqlx, opa-wasm, wasmtime, pest + { name = "universal-hash", version = "0.5.1" }, # ghash, polyval ] skip-tree = []