From 9956b8f898fdb79d055219608d4e257c9ea30a70 Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Tue, 17 Dec 2024 12:06:16 +0100 Subject: [PATCH] fix: handle odd keys (#459) Ther are two issues with oddly formed keys that were not properly handled - avoid using `-` to avoid a subtraction with overflow for pkcs - always validate the key in `from_components` to avoid errors in the internal `precompute` --- src/algorithms/pkcs1v15.rs | 11 ++++++++++- src/key.rs | 14 +++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/algorithms/pkcs1v15.rs b/src/algorithms/pkcs1v15.rs index c1f0779a..e813de11 100644 --- a/src/algorithms/pkcs1v15.rs +++ b/src/algorithms/pkcs1v15.rs @@ -41,7 +41,7 @@ pub(crate) fn pkcs1v15_encrypt_pad( where R: CryptoRngCore + ?Sized, { - if msg.len() > k - 11 { + if msg.len() + 11 > k { return Err(Error::MessageTooLong); } @@ -195,4 +195,13 @@ mod tests { } } } + + #[test] + fn test_encrypt_tiny_no_crash() { + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let k = 8; + let message = vec![1u8; 4]; + let res = pkcs1v15_encrypt_pad(&mut rng, &message, k); + assert_eq!(res, Err(Error::MessageTooLong)); + } } diff --git a/src/key.rs b/src/key.rs index b7747d6f..68f34d6e 100644 --- a/src/key.rs +++ b/src/key.rs @@ -252,7 +252,6 @@ impl RsaPrivateKey { d: BigUint, mut primes: Vec, ) -> Result { - let mut should_validate = false; if primes.len() < 2 { if !primes.is_empty() { return Err(Error::NprimesTooSmall); @@ -262,7 +261,6 @@ impl RsaPrivateKey { let (p, q) = recover_primes(&n, &e, &d)?; primes.push(p); primes.push(q); - should_validate = true; } let mut k = RsaPrivateKey { @@ -272,10 +270,8 @@ impl RsaPrivateKey { precomputed: None, }; - // Validate the key if we had to recover the primes. - if should_validate { - k.validate()?; - } + // Alaways validate the key, to ensure precompute can't fail + k.validate()?; // precompute when possible, ignore error otherwise. let _ = k.precompute(); @@ -787,13 +783,13 @@ mod tests { .unwrap(), ]; - RsaPrivateKey::from_components( + let res = RsaPrivateKey::from_components( BigUint::from_bytes_be(&n), BigUint::from_bytes_be(&e), BigUint::from_bytes_be(&d), primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(), - ) - .unwrap(); + ); + assert_eq!(res, Err(Error::InvalidModulus)); } #[test]