Skip to content

Commit e476a92

Browse files
pkcs1: reject an empty otherPrimeInfos (#2457)
RFC 8017 A.1.2: OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo otherPrimeInfos ... SHALL be omitted if version is 0 and SHALL contain at least one instance of OtherPrimeInfo if version is 1. The decoder checked that `otherPrimeInfos` is present exactly when the version is multi (#111, #115), but accepted an empty `SEQUENCE {}`, so a version-1 key with no additional primes decoded as `Version::Multi` with `Some(vec![])`. pyca/cryptography's rust-asn1 schema declares the same field as `SequenceOf<.., 1>` and rejects it. Reject an empty `otherPrimeInfos` on decode.
1 parent 2c0b0f9 commit e476a92

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

‎pkcs1/src/private_key.rs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub type RsaPrivateKeyOwned = RsaPrivateKey<Uint>;
4343
/// coefficient INTEGER, -- (inverse of q) mod p
4444
/// otherPrimeInfos OtherPrimeInfos OPTIONAL
4545
/// }
46+
///
47+
/// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
4648
/// ```
4749
///
4850
/// Note: the `version` field is selected automatically based on the absence or
@@ -133,6 +135,17 @@ where
133135
return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }));
134136
}
135137

138+
// `OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo`
139+
// (without `alloc`, `OtherPrimeInfos` never decodes, so there is nothing to check)
140+
#[cfg(feature = "alloc")]
141+
if result
142+
.other_prime_infos
143+
.as_ref()
144+
.is_some_and(|infos| infos.is_empty())
145+
{
146+
return Err(reader.error(der::ErrorKind::Value { tag: Tag::Sequence }));
147+
}
148+
136149
Ok(result)
137150
}
138151
}

‎pkcs1/tests/private_key.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ fn decode_rsa2048_multi_prime_der() {
202202
);
203203
}
204204

205+
/// RFC 8017 A.1.2: `OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo`, so a
206+
/// multi-prime key with an empty `otherPrimeInfos` is malformed.
207+
#[cfg(feature = "alloc")]
208+
#[test]
209+
fn reject_empty_other_prime_infos() {
210+
// version 1 (multi), eight one-byte INTEGERs, otherPrimeInfos = SEQUENCE {}
211+
let der = hex!("301d 020101 020107 020103 020105 02010b 02010d 020102 020104 020106 3000");
212+
assert!(RsaPrivateKeyRef::try_from(der.as_slice()).is_err());
213+
}
214+
205215
#[test]
206216
fn private_key_to_public_key() {
207217
let private_key = RsaPrivateKeyRef::try_from(RSA_2048_DER_EXAMPLE).unwrap();

0 commit comments

Comments
 (0)