From 44c92c84f7bbbe924942ccbd5866abf7c2349b9f Mon Sep 17 00:00:00 2001 From: Eugene Date: Mon, 24 Feb 2025 23:12:17 +0100 Subject: [PATCH 1/2] ssh-key: add a crate feature to allow insecure RSA keys - fixes #336 --- ssh-key/Cargo.toml | 1 + ssh-key/src/private/rsa.rs | 19 ++++++++++--------- ssh-key/src/public/rsa.rs | 11 ++++++----- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/ssh-key/Cargo.toml b/ssh-key/Cargo.toml index 389e2662..480038c4 100644 --- a/ssh-key/Cargo.toml +++ b/ssh-key/Cargo.toml @@ -76,6 +76,7 @@ encryption = [ "rand_core" ] getrandom = ["rand_core/getrandom"] +hazmat-allow-insecure-rsa-keys = [] p256 = ["dep:p256", "ecdsa"] p384 = ["dep:p384", "ecdsa"] p521 = ["dep:p521", "ecdsa"] diff --git a/ssh-key/src/private/rsa.rs b/ssh-key/src/private/rsa.rs index e628d9a1..d82998fb 100644 --- a/ssh-key/src/private/rsa.rs +++ b/ssh-key/src/private/rsa.rs @@ -138,17 +138,17 @@ pub struct RsaKeypair { impl RsaKeypair { /// Minimum allowed RSA key size. - #[cfg(feature = "rsa")] + #[cfg(all(feature = "rsa", not(feature = "hazmat-allow-insecure-rsa-keys")))] pub(crate) const MIN_KEY_SIZE: usize = 2048; /// Generate a random RSA keypair of the given size. #[cfg(feature = "rsa")] pub fn random(rng: &mut impl CryptoRngCore, bit_size: usize) -> Result { - if bit_size >= Self::MIN_KEY_SIZE { - rsa::RsaPrivateKey::new(rng, bit_size)?.try_into() - } else { - Err(Error::Crypto) + #[cfg(not(feature = "hazmat-allow-insecure-rsa-keys"))] + if bit_size < Self::MIN_KEY_SIZE { + return Err(Error::Crypto); } + rsa::RsaPrivateKey::new(rng, bit_size)?.try_into() } /// Create a new keypair from the given `public` and `private` key components. @@ -260,11 +260,12 @@ impl TryFrom<&RsaKeypair> for rsa::RsaPrivateKey { ], )?; - if ret.size().saturating_mul(8) >= RsaKeypair::MIN_KEY_SIZE { - Ok(ret) - } else { - Err(Error::Crypto) + #[cfg(not(feature = "hazmat-allow-insecure-rsa-keys"))] + if ret.size().saturating_mul(8) < RsaKeypair::MIN_KEY_SIZE { + return Err(Error::Crypto); } + + Ok(ret) } } diff --git a/ssh-key/src/public/rsa.rs b/ssh-key/src/public/rsa.rs index 35eda536..b30646a6 100644 --- a/ssh-key/src/public/rsa.rs +++ b/ssh-key/src/public/rsa.rs @@ -28,7 +28,7 @@ pub struct RsaPublicKey { impl RsaPublicKey { /// Minimum allowed RSA key size. - #[cfg(feature = "rsa")] + #[cfg(all(feature = "rsa", not(feature = "hazmat-allow-insecure-rsa-keys")))] pub(crate) const MIN_KEY_SIZE: usize = RsaKeypair::MIN_KEY_SIZE; /// Create a new [`RsaPublicKey`] with the given components: @@ -117,11 +117,12 @@ impl TryFrom<&RsaPublicKey> for rsa::RsaPublicKey { ) .map_err(|_| Error::Crypto)?; - if ret.size().saturating_mul(8) >= RsaPublicKey::MIN_KEY_SIZE { - Ok(ret) - } else { - Err(Error::Crypto) + #[cfg(not(feature = "hazmat-allow-insecure-rsa-keys"))] + if ret.size().saturating_mul(8) < RsaPublicKey::MIN_KEY_SIZE { + return Err(Error::Crypto); } + + Ok(ret) } } From 8dc1cce97fd13657bfb771f121fe8628f8a2dfb6 Mon Sep 17 00:00:00 2001 From: Eugene Date: Mon, 24 Feb 2025 23:15:14 +0100 Subject: [PATCH 2/2] lint --- ssh-key/src/private/rsa.rs | 8 ++++---- ssh-key/src/public/rsa.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ssh-key/src/private/rsa.rs b/ssh-key/src/private/rsa.rs index d82998fb..400feab1 100644 --- a/ssh-key/src/private/rsa.rs +++ b/ssh-key/src/private/rsa.rs @@ -9,13 +9,13 @@ use zeroize::Zeroize; #[cfg(feature = "rsa")] use { rand_core::CryptoRngCore, - rsa::{ - pkcs1v15, - traits::{PrivateKeyParts, PublicKeyParts}, - }, + rsa::{pkcs1v15, traits::PrivateKeyParts}, sha2::{digest::const_oid::AssociatedOid, Digest}, }; +#[cfg(all(feature = "rsa", not(feature = "hazmat-allow-insecure-rsa-keys")))] +use rsa::traits::PublicKeyParts; + /// RSA private key. #[derive(Clone)] pub struct RsaPrivateKey { diff --git a/ssh-key/src/public/rsa.rs b/ssh-key/src/public/rsa.rs index b30646a6..7bd26497 100644 --- a/ssh-key/src/public/rsa.rs +++ b/ssh-key/src/public/rsa.rs @@ -6,7 +6,6 @@ use encoding::{CheckedSum, Decode, Encode, Reader, Writer}; #[cfg(feature = "rsa")] use { - crate::private::RsaKeypair, rsa::{pkcs1v15, traits::PublicKeyParts}, sha2::{digest::const_oid::AssociatedOid, Digest}, }; @@ -29,7 +28,7 @@ pub struct RsaPublicKey { impl RsaPublicKey { /// Minimum allowed RSA key size. #[cfg(all(feature = "rsa", not(feature = "hazmat-allow-insecure-rsa-keys")))] - pub(crate) const MIN_KEY_SIZE: usize = RsaKeypair::MIN_KEY_SIZE; + pub(crate) const MIN_KEY_SIZE: usize = crate::private::RsaKeypair::MIN_KEY_SIZE; /// Create a new [`RsaPublicKey`] with the given components: ///