From 490edd424e76e564da82ad9a9671725b4f4179a2 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 25 Jul 2023 22:33:08 +0000 Subject: [PATCH] cms: pull builder changes Signed-off-by: Arthur Gautier --- cms/src/builder.rs | 55 +++++++++++++++++++++----------------------- cms/tests/builder.rs | 8 ++++--- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/cms/src/builder.rs b/cms/src/builder.rs index de484f5c5..ce19011fd 100644 --- a/cms/src/builder.rs +++ b/cms/src/builder.rs @@ -86,8 +86,7 @@ type Result = core::result::Result; /// - calculate the signature /// - set the signing time attribute /// - create a `SignerInfo` object -pub struct SignerInfoBuilder<'s, S> { - signer: &'s S, +pub struct SignerInfoBuilder<'s> { sid: SignerIdentifier, digest_algorithm: AlgorithmIdentifierOwned, signed_attributes: Option>, @@ -96,25 +95,19 @@ pub struct SignerInfoBuilder<'s, S> { external_message_digest: Option<&'s [u8]>, } -impl<'s, S> SignerInfoBuilder<'s, S> -where - S: Keypair + DynSignatureAlgorithmIdentifier, - S::VerifyingKey: EncodePublicKey, -{ +impl<'s> SignerInfoBuilder<'s> { /// Create a new `SignerInfoBuilder`. This is used for adding `SignerInfo`s to `SignedData` /// structures. /// The content to be signed can be stored externally. In this case `eContent` in /// `encapsulated_content_info` must be `None` and the message digest must be passed with /// `external_message_digest`. `digest_algorithm` must match the used digest algorithm. pub fn new( - signer: &'s S, sid: SignerIdentifier, digest_algorithm: AlgorithmIdentifierOwned, encapsulated_content_info: &'s EncapsulatedContentInfo, external_message_digest: Option<&'s [u8]>, ) -> Result { Ok(SignerInfoBuilder { - signer, sid, digest_algorithm, signed_attributes: None, @@ -158,41 +151,39 @@ where } } -impl<'s, S> Builder for SignerInfoBuilder<'s, S> -where - S: Keypair + DynSignatureAlgorithmIdentifier, - S::VerifyingKey: EncodePublicKey, -{ - type Signer = S; +impl<'s> Builder for SignerInfoBuilder<'s> { type Output = SignerInfo; - fn signer(&self) -> &Self::Signer { - self.signer - } - /// Calculate the data to be signed /// [RFC 5652 § 5.4](https://datatracker.ietf.org/doc/html/rfc5652#section-5.4) /// If an `external_message_digest` is passed in, it is assumed, that we are signing external /// content (see RFC 5652 § 5.2). In this case, the `eContent` in `EncapsulatedContentInfo` /// must be `None`. - fn finalize(&mut self) -> der::Result> { + fn finalize( + &mut self, + _signer: &S, + ) -> core::result::Result, x509_cert::builder::Error> + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S::VerifyingKey: EncodePublicKey, + { let message_digest = match self.external_message_digest { Some(external_content_digest) => { if self.encapsulated_content_info.econtent.is_some() { // Encapsulated content must be empty, if external digest is given. - return Err(der::Error::from(ErrorKind::Failed)); + return Err(der::Error::from(ErrorKind::Failed).into()); } external_content_digest.to_vec() } None => match &self.encapsulated_content_info.econtent { None => { // Content missing, cannot sign - return Err(der::Error::from(ErrorKind::Failed)); + return Err(der::Error::from(ErrorKind::Failed).into()); } Some(content) => { let mut hasher = get_hasher(&self.digest_algorithm).ok_or_else(|| { // Unsupported hash algorithm: {}, &self.digest_algorithm.oid.to_string() - der::Error::from(ErrorKind::Failed) + x509_cert::builder::Error::from(der::Error::from(ErrorKind::Failed)) })?; // Only the octets comprising the value of the eContent // OCTET STRING are input to the message digest algorithm, not the tag @@ -234,7 +225,7 @@ where // Check against `eContentType` if signed_attributes_content_type.oid != econtent_type { // Mismatch between content types: encapsulated content info <-> signed attributes. - return Err(der::Error::from(ErrorKind::Failed)); + return Err(der::Error::from(ErrorKind::Failed).into()); } } else { signed_attributes.push( @@ -252,10 +243,15 @@ where Ok(signed_attributes_der) } - fn assemble( + fn assemble( self, signature: BitString, - ) -> core::result::Result { + signer: &S, + ) -> core::result::Result + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S::VerifyingKey: EncodePublicKey, + { let signed_attrs = self.signed_attributes.as_ref().map(|signed_attributes| { SignedAttributes::try_from(signed_attributes.to_owned()).unwrap() }); @@ -269,7 +265,7 @@ where let signature_value = SignatureValue::new(signature.raw_bytes()).map_err(x509_cert::builder::Error::from)?; - let signature_algorithm = self.signer.signature_algorithm_identifier()?; + let signature_algorithm = signer.signature_algorithm_identifier()?; Ok(SignerInfo { version: self.version(), @@ -367,7 +363,8 @@ impl<'s> SignedDataBuilder<'s> { /// must not be changed after the first signer info was added. pub fn add_signer_info( &mut self, - signer_info_builder: SignerInfoBuilder<'_, S>, + signer_info_builder: SignerInfoBuilder<'_>, + signer: &S, ) -> Result<&mut Self> where S: Keypair + DynSignatureAlgorithmIdentifier, @@ -376,7 +373,7 @@ impl<'s> SignedDataBuilder<'s> { Signature: SignatureBitStringEncoding, { let signer_info = signer_info_builder - .build::() + .build::(signer) .map_err(|_| der::Error::from(ErrorKind::Failed))?; self.signer_infos.push(signer_info); diff --git a/cms/tests/builder.rs b/cms/tests/builder.rs index 3467e5dd4..e5fd2bfc9 100644 --- a/cms/tests/builder.rs +++ b/cms/tests/builder.rs @@ -67,7 +67,6 @@ fn test_build_signed_data() { }; let external_message_digest = None; let signer_info_builder_1 = SignerInfoBuilder::new( - &signer, signer_identifier(1), digest_algorithm.clone(), &content, @@ -82,7 +81,6 @@ fn test_build_signed_data() { }; let external_message_digest_2 = None; let signer_info_builder_2 = SignerInfoBuilder::new( - &signer_2, signer_identifier(1), digest_algorithm_2.clone(), &content, @@ -100,10 +98,14 @@ fn test_build_signed_data() { .expect("could not add a digest algorithm") .add_certificate(CertificateChoices::Certificate(certificate)) .expect("error adding certificate") - .add_signer_info::, rsa::pkcs1v15::Signature>(signer_info_builder_1) + .add_signer_info::, rsa::pkcs1v15::Signature>( + signer_info_builder_1, + &signer, + ) .expect("error adding RSA signer info") .add_signer_info::, p256::ecdsa::DerSignature>( signer_info_builder_2, + &signer_2, ) .expect("error adding RSA signer info") .build()