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..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 { @@ -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..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}, }; @@ -28,8 +27,8 @@ pub struct RsaPublicKey { impl RsaPublicKey { /// Minimum allowed RSA key size. - #[cfg(feature = "rsa")] - pub(crate) const MIN_KEY_SIZE: usize = RsaKeypair::MIN_KEY_SIZE; + #[cfg(all(feature = "rsa", not(feature = "hazmat-allow-insecure-rsa-keys")))] + pub(crate) const MIN_KEY_SIZE: usize = crate::private::RsaKeypair::MIN_KEY_SIZE; /// Create a new [`RsaPublicKey`] with the given components: /// @@ -117,11 +116,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) } }