From 4ccdcf92a956d407c0266522ddc3116e30ddb851 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 25 Jul 2022 06:35:47 -0600 Subject: [PATCH] Make `RsaPrivateKey::from_components` fallible (#167) Adds an error case in the event the number of `primes` provides is fewer than 2, which prevents panics when invoking methods which expect primes to always be present at indices 0 and 1 (i.e. `p` and `q`) Fixes #163 --- Cargo.toml | 3 +++ src/algorithms.rs | 7 +------ src/encoding.rs | 2 +- src/key.rs | 18 +++++++++++++----- src/pkcs1v15.rs | 2 +- src/pss.rs | 2 +- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c395c2e1..d740dbe9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,3 +63,6 @@ getrandom = ["rand_core/getrandom"] [package.metadata.docs.rs] features = ["std", "pem", "serde", "expose-internals"] rustdoc-args = ["--cfg", "docsrs"] + +[profile.dev] +opt-level = 2 diff --git a/src/algorithms.rs b/src/algorithms.rs index 25f288bb..dd6fa086 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -131,12 +131,7 @@ pub fn generate_multi_prime_key_with_exp( } } - Ok(RsaPrivateKey::from_components( - n_final, - exp.clone(), - d_final, - primes, - )) + RsaPrivateKey::from_components(n_final, exp.clone(), d_final, primes) } /// Mask generation function. diff --git a/src/encoding.rs b/src/encoding.rs index bb41d4a9..6c59782b 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -41,7 +41,7 @@ impl TryFrom> for RsaPrivateKey { let prime1 = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes()); let prime2 = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes()); let primes = vec![prime1, prime2]; - Ok(RsaPrivateKey::from_components(n, e, d, primes)) + RsaPrivateKey::from_components(n, e, d, primes).map_err(|_| pkcs8::Error::KeyMalformed) } } diff --git a/src/key.rs b/src/key.rs index 7e725cec..3b323c0b 100644 --- a/src/key.rs +++ b/src/key.rs @@ -312,7 +312,13 @@ impl RsaPrivateKey { e: BigUint, d: BigUint, primes: Vec, - ) -> RsaPrivateKey { + ) -> Result { + // TODO(tarcieri): support recovering `p` and `q` from `d` if `primes` is empty + // See method in Appendix C: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br1.pdf + if primes.len() < 2 { + return Err(Error::NprimesTooSmall); + } + let mut k = RsaPrivateKey { pubkey_components: RsaPublicKey { n, e }, d, @@ -323,7 +329,7 @@ impl RsaPrivateKey { // precompute when possible, ignore error otherwise. let _ = k.precompute(); - k + Ok(k) } /// Get the public key from the private key, cloning `n` and `e`. @@ -692,7 +698,8 @@ mod tests { BigUint::from_bytes_le(&vec![105, 101, 60, 173, 19, 153, 3, 192]), BigUint::from_bytes_le(&vec![235, 65, 160, 134, 32, 136, 6, 241]), ], - ); + ) + .unwrap(); for _ in 0..1000 { test_key_basics(&private_key); @@ -785,7 +792,8 @@ mod tests { BigUint::from_bytes_be(&e), BigUint::from_bytes_be(&d), primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(), - ); + ) + .unwrap(); } fn get_private_key() -> RsaPrivateKey { @@ -825,7 +833,7 @@ mod tests { BigUint::parse_bytes(b"00f827bbf3a41877c7cc59aebf42ed4b29c32defcb8ed96863d5b090a05a8930dd624a21c9dcf9838568fdfa0df65b8462a5f2ac913d6c56f975532bd8e78fb07bd405ca99a484bcf59f019bbddcb3933f2bce706300b4f7b110120c5df9018159067c35da3061a56c8635a52b54273b31271b4311f0795df6021e6355e1a42e61",16).unwrap(), BigUint::parse_bytes(b"00da4817ce0089dd36f2ade6a3ff410c73ec34bf1b4f6bda38431bfede11cef1f7f6efa70e5f8063a3b1f6e17296ffb15feefa0912a0325b8d1fd65a559e717b5b961ec345072e0ec5203d03441d29af4d64054a04507410cf1da78e7b6119d909ec66e6ad625bf995b279a4b3c5be7d895cd7c5b9c4c497fde730916fcdb4e41b", 16).unwrap() ], - ) + ).unwrap() } #[test] diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index b46bbf68..232e739c 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -259,7 +259,7 @@ mod tests { BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(), BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap() ], - ) + ).unwrap() } #[test] diff --git a/src/pss.rs b/src/pss.rs index 16c7d9b9..41d2f144 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -265,7 +265,7 @@ mod test { BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(), BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap() ], - ) + ).unwrap() } #[test]