Skip to content

Commit d8649d3

Browse files
committed
Support RSA PKCS#1 signatures with absent parameters
RFC4055 says on sha256WithRSAEncryption and company: > When any of these four object identifiers appears within an > AlgorithmIdentifier, the parameters MUST be NULL. Implementations > MUST accept the parameters being absent as well as present. The latter clause is implemented in this commit. The algorithm identifiers live here rather than pki-types, as they _must not_ be used to originate new certificates. Putting them in pki-types would mean they appear in a public API, whereas here they are kept private and restricted to verifying existing signatures.
1 parent 0ac75b1 commit d8649d3

File tree

11 files changed

+117
-2
lines changed

11 files changed

+117
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ include = [
3434
"src/cert.rs",
3535
"src/crl/mod.rs",
3636
"src/crl/types.rs",
37+
"src/data/",
3738
"src/der.rs",
3839
"src/end_entity.rs",
3940
"src/error.rs",

src/aws_lc_rs_algs.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,39 @@ pub static RSA_PKCS1_2048_8192_SHA512: &dyn SignatureVerificationAlgorithm = &Aw
124124
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
125125
};
126126

127+
/// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits,
128+
/// with illegally absent AlgorithmIdentifier parameters.
129+
pub static RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
130+
&AwsLcRsAlgorithm {
131+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
132+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
133+
"data/alg-rsa-pkcs1-sha256-absent-params.der"
134+
)),
135+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
136+
};
137+
138+
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits,
139+
/// with illegally absent AlgorithmIdentifier parameters.
140+
pub static RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
141+
&AwsLcRsAlgorithm {
142+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
143+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
144+
"data/alg-rsa-pkcs1-sha384-absent-params.der"
145+
)),
146+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
147+
};
148+
149+
/// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits,
150+
/// with illegally absent AlgorithmIdentifier parameters.
151+
pub static RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
152+
&AwsLcRsAlgorithm {
153+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
154+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
155+
"data/alg-rsa-pkcs1-sha512-absent-params.der"
156+
)),
157+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
158+
};
159+
127160
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 3072-8192 bits.
128161
pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm {
129162
public_key_alg_id: alg_id::RSA_ENCRYPTION,

src/data/alg-rsa-pkcs1-sha256-absent-params.der

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
 *�H��

src/data/alg-rsa-pkcs1-sha384-absent-params.der

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
 *�H��

src/data/alg-rsa-pkcs1-sha512-absent-params.der

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
 *�H��

src/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ pub mod ring {
9797

9898
#[cfg(feature = "alloc")]
9999
pub use super::ring_algs::{
100-
RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512,
100+
RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
101+
RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
102+
RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
101103
RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
102104
RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
103105
};
@@ -109,7 +111,9 @@ pub mod aws_lc_rs {
109111
pub use super::aws_lc_rs_algs::{
110112
ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384,
111113
ECDSA_P521_SHA256, ECDSA_P521_SHA384, ECDSA_P521_SHA512, ED25519,
112-
RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512,
114+
RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
115+
RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
116+
RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
113117
RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
114118
RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
115119
};
@@ -136,6 +140,12 @@ pub static ALL_VERIFICATION_ALGS: &[&dyn pki_types::SignatureVerificationAlgorit
136140
#[cfg(all(feature = "ring", feature = "alloc"))]
137141
ring::RSA_PKCS1_2048_8192_SHA512,
138142
#[cfg(all(feature = "ring", feature = "alloc"))]
143+
ring::RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
144+
#[cfg(all(feature = "ring", feature = "alloc"))]
145+
ring::RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
146+
#[cfg(all(feature = "ring", feature = "alloc"))]
147+
ring::RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
148+
#[cfg(all(feature = "ring", feature = "alloc"))]
139149
ring::RSA_PKCS1_3072_8192_SHA384,
140150
#[cfg(all(feature = "ring", feature = "alloc"))]
141151
ring::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
@@ -166,6 +176,12 @@ pub static ALL_VERIFICATION_ALGS: &[&dyn pki_types::SignatureVerificationAlgorit
166176
#[cfg(feature = "aws-lc-rs")]
167177
aws_lc_rs::RSA_PKCS1_2048_8192_SHA512,
168178
#[cfg(feature = "aws-lc-rs")]
179+
aws_lc_rs::RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
180+
#[cfg(feature = "aws-lc-rs")]
181+
aws_lc_rs::RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
182+
#[cfg(feature = "aws-lc-rs")]
183+
aws_lc_rs::RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
184+
#[cfg(feature = "aws-lc-rs")]
169185
aws_lc_rs::RSA_PKCS1_3072_8192_SHA384,
170186
#[cfg(feature = "aws-lc-rs")]
171187
aws_lc_rs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,

src/ring_algs.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,42 @@ pub static RSA_PKCS1_2048_8192_SHA512: &dyn SignatureVerificationAlgorithm = &Ri
9696
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
9797
};
9898

99+
/// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits,
100+
/// with illegally absent AlgorithmIdentifier parameters.
101+
#[cfg(feature = "alloc")]
102+
pub static RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
103+
&RingAlgorithm {
104+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
105+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
106+
"data/alg-rsa-pkcs1-sha256-absent-params.der"
107+
)),
108+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
109+
};
110+
111+
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits,
112+
/// with illegally absent AlgorithmIdentifier parameters.
113+
#[cfg(feature = "alloc")]
114+
pub static RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
115+
&RingAlgorithm {
116+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
117+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
118+
"data/alg-rsa-pkcs1-sha384-absent-params.der"
119+
)),
120+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
121+
};
122+
123+
/// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits,
124+
/// with illegally absent AlgorithmIdentifier parameters.
125+
#[cfg(feature = "alloc")]
126+
pub static RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
127+
&RingAlgorithm {
128+
public_key_alg_id: alg_id::RSA_ENCRYPTION,
129+
signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
130+
"data/alg-rsa-pkcs1-sha512-absent-params.der"
131+
)),
132+
verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
133+
};
134+
99135
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 3072-8192 bits.
100136
#[cfg(feature = "alloc")]
101137
pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {

tests/integration.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,32 @@ fn netflix() {
4848
);
4949
}
5050

51+
#[test]
52+
fn sanofi() {
53+
let ee: &[u8] = include_bytes!("sanofi/ee.der");
54+
let inter = CertificateDer::from(&include_bytes!("sanofi/inter.der")[..]);
55+
let ca = CertificateDer::from(&include_bytes!("sanofi/ca.der")[..]);
56+
57+
let anchors = [anchor_from_trusted_cert(&ca).unwrap()];
58+
59+
let time = UnixTime::since_unix_epoch(Duration::from_secs(1_746_549_566)); // 2025-05-06T17:39:26Z
60+
61+
let ee = CertificateDer::from(ee);
62+
let cert = webpki::EndEntityCert::try_from(&ee).unwrap();
63+
assert!(
64+
cert.verify_for_usage(
65+
webpki::ALL_VERIFICATION_ALGS,
66+
&anchors,
67+
&[inter],
68+
time,
69+
KeyUsage::server_auth(),
70+
None,
71+
None,
72+
)
73+
.is_ok()
74+
);
75+
}
76+
5177
/* This is notable because it is a popular use of IP address subjectAltNames. */
5278
#[cfg(feature = "alloc")]
5379
#[test]

tests/sanofi/ca.der

1.33 KB
Binary file not shown.

tests/sanofi/ee.der

1.44 KB
Binary file not shown.

0 commit comments

Comments
 (0)