Skip to content

Commit cabf437

Browse files
authored
cms: implement a SignedDataBuilder for PSS (#1531)
Fixes #1519
1 parent 49a9cb2 commit cabf437

2 files changed

Lines changed: 58 additions & 10 deletions

File tree

cms/src/builder.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use digest::Digest;
3535
use rsa::Pkcs1v15Encrypt;
3636
use sha2::digest;
3737
use signature::digest::DynDigest;
38-
use signature::{Keypair, Signer};
38+
use signature::{Keypair, RandomizedSigner, Signer};
3939
use spki::{
4040
AlgorithmIdentifierOwned, DynSignatureAlgorithmIdentifier, EncodePublicKey,
4141
SignatureBitStringEncoding,
@@ -404,6 +404,28 @@ impl<'s> SignedDataBuilder<'s> {
404404
Ok(self)
405405
}
406406

407+
/// Add a signer info. The signature will be calculated. Note that the encapsulated content
408+
/// must not be changed after the first signer info was added.
409+
pub fn add_signer_info_with_rng<S, Signature>(
410+
&mut self,
411+
signer_info_builder: SignerInfoBuilder<'_>,
412+
signer: &S,
413+
rng: &mut impl CryptoRngCore,
414+
) -> Result<&mut Self>
415+
where
416+
S: Keypair + DynSignatureAlgorithmIdentifier,
417+
S: RandomizedSigner<Signature>,
418+
S::VerifyingKey: EncodePublicKey,
419+
Signature: SignatureBitStringEncoding,
420+
{
421+
let signer_info = signer_info_builder
422+
.build_with_rng::<S, Signature>(signer, rng)
423+
.map_err(|_| der::Error::from(ErrorKind::Failed))?;
424+
self.signer_infos.push(signer_info);
425+
426+
Ok(self)
427+
}
428+
407429
/// This method returns a `ContentInfo` of type `signedData`.
408430
pub fn build(&mut self) -> Result<ContentInfo> {
409431
let digest_algorithms =

cms/tests/builder.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use p256::{pkcs8::DecodePrivateKey, NistP256};
1919
use pem_rfc7468::LineEnding;
2020
use rand::rngs::OsRng;
2121
use rsa::pkcs1::DecodeRsaPrivateKey;
22-
use rsa::pkcs1v15::{SigningKey, VerifyingKey};
22+
use rsa::pkcs1v15;
23+
use rsa::pss;
2324
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
2425
use sha2::Sha256;
2526
use signature::Verifier;
@@ -38,9 +39,14 @@ const RFC8894_ID_TRANSACTION_ID: ObjectIdentifier =
3839
const RSA_2048_PRIV_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-priv.der");
3940
const PKCS8_PRIVATE_KEY_DER: &[u8] = include_bytes!("examples/p256-priv.der");
4041

41-
fn rsa_signer() -> SigningKey<Sha256> {
42+
fn rsa_pss_signer() -> pss::SigningKey<Sha256> {
4243
let private_key = rsa::RsaPrivateKey::from_pkcs1_der(RSA_2048_PRIV_DER_EXAMPLE).unwrap();
43-
SigningKey::<Sha256>::new(private_key)
44+
pss::SigningKey::<Sha256>::new(private_key)
45+
}
46+
47+
fn rsa_pkcs1v15_signer() -> pkcs1v15::SigningKey<Sha256> {
48+
let private_key = rsa::RsaPrivateKey::from_pkcs1_der(RSA_2048_PRIV_DER_EXAMPLE).unwrap();
49+
pkcs1v15::SigningKey::<Sha256>::new(private_key)
4450
}
4551

4652
fn ecdsa_signer() -> ecdsa::SigningKey<NistP256> {
@@ -80,7 +86,7 @@ fn test_build_signed_data() {
8086
),
8187
};
8288
// Create multiple signer infos
83-
let signer = rsa_signer();
89+
let signer = rsa_pkcs1v15_signer();
8490
let digest_algorithm = AlgorithmIdentifierOwned {
8591
oid: const_oid::db::rfc5912::ID_SHA_256,
8692
parameters: None,
@@ -108,6 +114,20 @@ fn test_build_signed_data() {
108114
)
109115
.expect("Could not create ECDSA SignerInfoBuilder");
110116

117+
let signer_3 = rsa_pss_signer();
118+
let digest_algorithm = AlgorithmIdentifierOwned {
119+
oid: const_oid::db::rfc5912::ID_SHA_256,
120+
parameters: None,
121+
};
122+
let external_message_digest = None;
123+
let signer_info_builder_3 = SignerInfoBuilder::new(
124+
signer_identifier(3),
125+
digest_algorithm.clone(),
126+
&content,
127+
external_message_digest,
128+
)
129+
.expect("Could not create RSA SignerInfoBuilder");
130+
111131
let certificate_buf = include_bytes!("examples/ValidCertificatePathTest1EE.pem");
112132
let certificate = x509_cert::Certificate::from_pem(certificate_buf).unwrap();
113133

@@ -118,16 +138,22 @@ fn test_build_signed_data() {
118138
.expect("could not add a digest algorithm")
119139
.add_certificate(CertificateChoices::Certificate(certificate))
120140
.expect("error adding certificate")
121-
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
141+
.add_signer_info::<pkcs1v15::SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
122142
signer_info_builder_1,
123143
&signer,
124144
)
125-
.expect("error adding RSA signer info")
145+
.expect("error adding PKCS1v15 RSA signer info")
126146
.add_signer_info::<ecdsa::SigningKey<NistP256>, p256::ecdsa::DerSignature>(
127147
signer_info_builder_2,
128148
&signer_2,
129149
)
130150
.expect("error adding P256 signer info")
151+
.add_signer_info_with_rng::<pss::SigningKey<Sha256>, pss::Signature>(
152+
signer_info_builder_3,
153+
&signer_3,
154+
&mut OsRng,
155+
)
156+
.expect("error adding PKCS1v15 RSA signer info")
131157
.build()
132158
.expect("building signed data failed");
133159
let signed_data_pkcs7_der = signed_data_pkcs7
@@ -302,7 +328,7 @@ fn test_build_pkcs7_scep_pkcsreq() {
302328
let signer = {
303329
let sender_rsa_key_pem = include_str!("examples/sceptest_key.pem");
304330
let sender_rsa_key = RsaPrivateKey::from_pkcs8_pem(sender_rsa_key_pem).unwrap();
305-
SigningKey::<Sha256>::new(sender_rsa_key)
331+
pkcs1v15::SigningKey::<Sha256>::new(sender_rsa_key)
306332
};
307333
let digest_algorithm = AlgorithmIdentifierOwned {
308334
oid: const_oid::db::rfc5912::ID_SHA_256,
@@ -364,7 +390,7 @@ fn test_build_pkcs7_scep_pkcsreq() {
364390
.unwrap()
365391
.add_certificate(CertificateChoices::Certificate(certificate))
366392
.unwrap()
367-
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
393+
.add_signer_info::<pkcs1v15::SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
368394
signer_info_builder,
369395
&signer,
370396
)
@@ -399,7 +425,7 @@ fn test_build_pkcs7_scep_pkcsreq() {
399425
let verifier = {
400426
let verifier_rsa_key_pem = include_str!("examples/sceptest_key.pem");
401427
let verifier_rsa_key = RsaPrivateKey::from_pkcs8_pem(verifier_rsa_key_pem).unwrap();
402-
VerifyingKey::<Sha256>::new(RsaPublicKey::from(verifier_rsa_key))
428+
pkcs1v15::VerifyingKey::<Sha256>::new(RsaPublicKey::from(verifier_rsa_key))
403429
};
404430
assert!(verifier
405431
.verify(signed_attributes_der.as_slice(), &signature)

0 commit comments

Comments
 (0)