Skip to content

Commit 4ccdcf9

Browse files
authored
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
1 parent b626d48 commit 4ccdcf9

File tree

6 files changed

+20
-14
lines changed

6 files changed

+20
-14
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,6 @@ getrandom = ["rand_core/getrandom"]
6363
[package.metadata.docs.rs]
6464
features = ["std", "pem", "serde", "expose-internals"]
6565
rustdoc-args = ["--cfg", "docsrs"]
66+
67+
[profile.dev]
68+
opt-level = 2

src/algorithms.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,7 @@ pub fn generate_multi_prime_key_with_exp<R: RngCore + CryptoRng>(
131131
}
132132
}
133133

134-
Ok(RsaPrivateKey::from_components(
135-
n_final,
136-
exp.clone(),
137-
d_final,
138-
primes,
139-
))
134+
RsaPrivateKey::from_components(n_final, exp.clone(), d_final, primes)
140135
}
141136

142137
/// Mask generation function.

src/encoding.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl TryFrom<pkcs8::PrivateKeyInfo<'_>> for RsaPrivateKey {
4141
let prime1 = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes());
4242
let prime2 = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes());
4343
let primes = vec![prime1, prime2];
44-
Ok(RsaPrivateKey::from_components(n, e, d, primes))
44+
RsaPrivateKey::from_components(n, e, d, primes).map_err(|_| pkcs8::Error::KeyMalformed)
4545
}
4646
}
4747

src/key.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,13 @@ impl RsaPrivateKey {
312312
e: BigUint,
313313
d: BigUint,
314314
primes: Vec<BigUint>,
315-
) -> RsaPrivateKey {
315+
) -> Result<RsaPrivateKey> {
316+
// TODO(tarcieri): support recovering `p` and `q` from `d` if `primes` is empty
317+
// See method in Appendix C: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br1.pdf
318+
if primes.len() < 2 {
319+
return Err(Error::NprimesTooSmall);
320+
}
321+
316322
let mut k = RsaPrivateKey {
317323
pubkey_components: RsaPublicKey { n, e },
318324
d,
@@ -323,7 +329,7 @@ impl RsaPrivateKey {
323329
// precompute when possible, ignore error otherwise.
324330
let _ = k.precompute();
325331

326-
k
332+
Ok(k)
327333
}
328334

329335
/// Get the public key from the private key, cloning `n` and `e`.
@@ -692,7 +698,8 @@ mod tests {
692698
BigUint::from_bytes_le(&vec![105, 101, 60, 173, 19, 153, 3, 192]),
693699
BigUint::from_bytes_le(&vec![235, 65, 160, 134, 32, 136, 6, 241]),
694700
],
695-
);
701+
)
702+
.unwrap();
696703

697704
for _ in 0..1000 {
698705
test_key_basics(&private_key);
@@ -785,7 +792,8 @@ mod tests {
785792
BigUint::from_bytes_be(&e),
786793
BigUint::from_bytes_be(&d),
787794
primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(),
788-
);
795+
)
796+
.unwrap();
789797
}
790798

791799
fn get_private_key() -> RsaPrivateKey {
@@ -825,7 +833,7 @@ mod tests {
825833
BigUint::parse_bytes(b"00f827bbf3a41877c7cc59aebf42ed4b29c32defcb8ed96863d5b090a05a8930dd624a21c9dcf9838568fdfa0df65b8462a5f2ac913d6c56f975532bd8e78fb07bd405ca99a484bcf59f019bbddcb3933f2bce706300b4f7b110120c5df9018159067c35da3061a56c8635a52b54273b31271b4311f0795df6021e6355e1a42e61",16).unwrap(),
826834
BigUint::parse_bytes(b"00da4817ce0089dd36f2ade6a3ff410c73ec34bf1b4f6bda38431bfede11cef1f7f6efa70e5f8063a3b1f6e17296ffb15feefa0912a0325b8d1fd65a559e717b5b961ec345072e0ec5203d03441d29af4d64054a04507410cf1da78e7b6119d909ec66e6ad625bf995b279a4b3c5be7d895cd7c5b9c4c497fde730916fcdb4e41b", 16).unwrap()
827835
],
828-
)
836+
).unwrap()
829837
}
830838

831839
#[test]

src/pkcs1v15.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ mod tests {
259259
BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
260260
BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
261261
],
262-
)
262+
).unwrap()
263263
}
264264

265265
#[test]

src/pss.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ mod test {
265265
BigUint::from_str_radix("98920366548084643601728869055592650835572950932266967461790948584315647051443",10).unwrap(),
266266
BigUint::from_str_radix("94560208308847015747498523884063394671606671904944666360068158221458669711639", 10).unwrap()
267267
],
268-
)
268+
).unwrap()
269269
}
270270

271271
#[test]

0 commit comments

Comments
 (0)