Skip to content

Commit 4da5150

Browse files
uytyvulgraph
andauthored
Add regression test for CVE-2026-21895 (per @tarcieri's note in #690) (#692)
Per @tarcieri's reply on #690: > The fix for the logic is there, however it looks like the regression test wasn't carried over and probably should be. > As it were, the entire implementation diverged as we moved from `num-bigint` to `crypto-bigint`. The production fix lives on master already (`validate_private_key_parts` rejects any `prime <= one` with `Error::InvalidPrime`, src/key.rs:760-763). What was missing was the regression test added alongside it in upstream commit `2926c91bef` (PR #624). This PR ports just that test. ## Adaptations vs the original test - **Type swap**: original used `num-bigint::BigUint` constructors (`BigUint::from_u64`, `BigUint::zero()`); ported to `crypto-bigint::BoxedUint::from(u64)` since that's what current master's `from_components` API takes. - **API path**: the original numeric inputs (`n=239, e=185, d=0, primes=[1, 239]`) include an `e` below master's `MIN_PUB_EXPONENT` bound, so the test calls `from_components_with_large_exponent` (gated `#[cfg(feature = "hazmat")]`, matching the existing `test_from_components_with_small_exponent` / `test_from_components_with_large_exponent` neighbors) rather than `from_components`. Ordering inside `validate_skip_exponent_size` -> `validate_private_key_parts` still hits the `prime <= one` check first, so we exercise exactly the path the original test did. - **Assertion**: `Err(Error::InvalidPrime)` (not a panic) — same intent as the original. No production-code changes. Single-file diff in `src/key.rs`. Refs: GHSA-9c48-w39g-hm26, #690, #624, upstream `2926c91bef`. Co-authored-by: vulgraph <vulgraph@users.noreply.github.com>
1 parent e31a020 commit 4da5150

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/key.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,4 +1302,28 @@ mod tests {
13021302
// Verify that the key is cryptographically valid
13031303
assert!(validate_skip_exponent_size(&key_with_small_exp).is_ok());
13041304
}
1305+
1306+
/// Regression test for CVE-2026-21895 / GHSA-9c48-w39g-hm26.
1307+
///
1308+
/// Loading a secret key whose prime factor is `1` must be rejected with
1309+
/// `Error::InvalidPrime` rather than panicking via a divide-by-zero in
1310+
/// the validation/precompute path.
1311+
///
1312+
/// Adapted from the test added in upstream commit 2926c91bef (PR #624);
1313+
/// the original used `num-bigint` `BigUint` types, this version uses
1314+
/// `crypto-bigint` `BoxedUint` and goes through
1315+
/// `from_components_with_large_exponent` so the small (out-of-range) `e`
1316+
/// can be supplied verbatim from the original test.
1317+
#[test]
1318+
#[cfg(feature = "hazmat")]
1319+
fn test_key_invalid_primes() {
1320+
let e = RsaPrivateKey::from_components_with_large_exponent(
1321+
BoxedUint::from(239u64),
1322+
BoxedUint::from(185u64),
1323+
BoxedUint::from(0u64),
1324+
vec![BoxedUint::from(1u64), BoxedUint::from(239u64)],
1325+
)
1326+
.unwrap_err();
1327+
assert_eq!(e, Error::InvalidPrime);
1328+
}
13051329
}

0 commit comments

Comments
 (0)