diff --git a/cms/src/builder.rs b/cms/src/builder.rs index e37ae2105..69954ed35 100644 --- a/cms/src/builder.rs +++ b/cms/src/builder.rs @@ -25,6 +25,7 @@ use cipher::{ use const_oid::ObjectIdentifier; use core::cmp::Ordering; use core::fmt; +use core::future::ready; use core::marker::PhantomData; use der::asn1::{BitString, Null, OctetString, OctetStringRef, SetOfVec}; use der::oid::db::DB; @@ -410,9 +411,30 @@ impl<'s> SignedDataBuilder<'s> { S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, { - let signer_info = signer_info_builder + self.add_signer_info_cb::(signer_info_builder, signer, |_| Ok(())) + } + + /// Add a signer info. The signature will be calculated. Note that the encapsulated content + /// must not be changed after the first signer info was added. + pub fn add_signer_info_cb( + &mut self, + signer_info_builder: SignerInfoBuilder<'_>, + signer: &S, + callback: CB, + ) -> Result<&mut Self> + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S: Signer, + S::VerifyingKey: EncodePublicKey, + Signature: SignatureBitStringEncoding, + CB: FnOnce(&mut SignerInfo) -> Result<()>, + { + let mut signer_info = signer_info_builder .build::(signer) .map_err(|_| der::Error::from(ErrorKind::Failed))?; + + callback(&mut signer_info)?; + self.signer_infos.push(signer_info); Ok(self) @@ -433,9 +455,37 @@ impl<'s> SignedDataBuilder<'s> { Signature: SignatureBitStringEncoding, R: CryptoRng + ?Sized, { - let signer_info = signer_info_builder + self.add_signer_info_with_rng_cb::( + signer_info_builder, + signer, + |_| Ok(()), + rng, + ) + } + + /// Add a signer info. The signature will be calculated. Note that the encapsulated content + /// must not be changed after the first signer info was added. + pub fn add_signer_info_with_rng_cb( + &mut self, + signer_info_builder: SignerInfoBuilder<'_>, + signer: &S, + callback: CB, + rng: &mut R, + ) -> Result<&mut Self> + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S: RandomizedSigner, + S::VerifyingKey: EncodePublicKey, + Signature: SignatureBitStringEncoding, + CB: FnOnce(&mut SignerInfo) -> Result<()>, + R: CryptoRng + ?Sized, + { + let mut signer_info = signer_info_builder .build_with_rng::(signer, rng) .map_err(|_| der::Error::from(ErrorKind::Failed))?; + + callback(&mut signer_info)?; + self.signer_infos.push(signer_info); Ok(self) @@ -454,10 +504,33 @@ impl<'s> SignedDataBuilder<'s> { S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, { - let signer_info = signer_info_builder + self.add_signer_info_cb_async(signer_info_builder, signer, |_| ready(Ok(()))) + .await + } + + /// Add a signer info. The signature will be calculated. Note that the encapsulated content + /// must not be changed after the first signer info was added. + pub async fn add_signer_info_cb_async( + &mut self, + signer_info_builder: SignerInfoBuilder<'_>, + signer: &S, + callback: CB, + ) -> Result<&mut Self> + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S: AsyncSigner, + S::VerifyingKey: EncodePublicKey, + Signature: SignatureBitStringEncoding, + F: Future>, + CB: FnOnce(&mut SignerInfo) -> F, + { + let mut signer_info = signer_info_builder .build_async::(signer) .await .map_err(|_| der::Error::from(ErrorKind::Failed))?; + + callback(&mut signer_info).await?; + self.signer_infos.push(signer_info); Ok(self) @@ -478,10 +551,35 @@ impl<'s> SignedDataBuilder<'s> { Signature: SignatureBitStringEncoding, R: CryptoRng + ?Sized, { - let signer_info = signer_info_builder + self.add_signer_info_with_rng_cb_async(signer_info_builder, signer, rng, |_| ready(Ok(()))) + .await + } + + /// Add a signer info. The signature will be calculated. Note that the encapsulated content + /// must not be changed after the first signer info was added. + pub async fn add_signer_info_with_rng_cb_async( + &mut self, + signer_info_builder: SignerInfoBuilder<'_>, + signer: &S, + rng: &mut R, + callback: CB, + ) -> Result<&mut Self> + where + S: Keypair + DynSignatureAlgorithmIdentifier, + S: AsyncRandomizedSigner, + S::VerifyingKey: EncodePublicKey, + Signature: SignatureBitStringEncoding, + R: CryptoRng + ?Sized, + F: Future>, + CB: FnOnce(&mut SignerInfo) -> F, + { + let mut signer_info = signer_info_builder .build_with_rng_async::(signer, rng) .await .map_err(|_| der::Error::from(ErrorKind::Failed))?; + + callback(&mut signer_info).await?; + self.signer_infos.push(signer_info); Ok(self)