Skip to content

Commit a561c25

Browse files
committed
cms: pull builder changes
Signed-off-by: Arthur Gautier <[email protected]>
1 parent 23b8286 commit a561c25

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

cms/src/builder.rs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ use rsa::Pkcs1v15Encrypt;
3535
use sha2::digest;
3636
use signature::digest::DynDigest;
3737
use signature::{Keypair, Signer};
38-
use spki::{AlgorithmIdentifierOwned, DynSignatureAlgorithmIdentifier, SignatureBitStringEncoding};
38+
use spki::{
39+
AlgorithmIdentifierOwned, DynSignatureAlgorithmIdentifier, EncodePublicKey,
40+
SignatureBitStringEncoding,
41+
};
3942
use std::time::SystemTime;
4043
use std::vec;
4144
use x509_cert::attr::{Attribute, AttributeValue, Attributes};
@@ -96,8 +99,7 @@ type Result<T> = core::result::Result<T, Error>;
9699
/// - calculate the signature
97100
/// - set the signing time attribute
98101
/// - create a `SignerInfo` object
99-
pub struct SignerInfoBuilder<'s, S> {
100-
signer: &'s S,
102+
pub struct SignerInfoBuilder<'s> {
101103
sid: SignerIdentifier,
102104
digest_algorithm: AlgorithmIdentifierOwned,
103105
signed_attributes: Option<Vec<Attribute>>,
@@ -106,24 +108,19 @@ pub struct SignerInfoBuilder<'s, S> {
106108
external_message_digest: Option<&'s [u8]>,
107109
}
108110

109-
impl<'s, S> SignerInfoBuilder<'s, S>
110-
where
111-
S: Keypair + DynSignatureAlgorithmIdentifier,
112-
{
111+
impl<'s> SignerInfoBuilder<'s> {
113112
/// Create a new `SignerInfoBuilder`. This is used for adding `SignerInfo`s to `SignedData`
114113
/// structures.
115114
/// The content to be signed can be stored externally. In this case `eContent` in
116115
/// `encapsulated_content_info` must be `None` and the message digest must be passed with
117116
/// `external_message_digest`. `digest_algorithm` must match the used digest algorithm.
118117
pub fn new(
119-
signer: &'s S,
120118
sid: SignerIdentifier,
121119
digest_algorithm: AlgorithmIdentifierOwned,
122120
encapsulated_content_info: &'s EncapsulatedContentInfo,
123121
external_message_digest: Option<&'s [u8]>,
124122
) -> Result<Self> {
125123
Ok(SignerInfoBuilder {
126-
signer,
127124
sid,
128125
digest_algorithm,
129126
signed_attributes: None,
@@ -167,28 +164,27 @@ where
167164
}
168165
}
169166

170-
impl<'s, S> Builder for SignerInfoBuilder<'s, S>
171-
where
172-
S: Keypair + DynSignatureAlgorithmIdentifier,
173-
{
174-
type Signer = S;
167+
impl<'s> Builder for SignerInfoBuilder<'s> {
175168
type Output = SignerInfo;
176169

177-
fn signer(&self) -> &Self::Signer {
178-
self.signer
179-
}
180-
181170
/// Calculate the data to be signed
182171
/// [RFC 5652 § 5.4](https://datatracker.ietf.org/doc/html/rfc5652#section-5.4)
183172
/// If an `external_message_digest` is passed in, it is assumed, that we are signing external
184173
/// content (see RFC 5652 § 5.2). In this case, the `eContent` in `EncapsulatedContentInfo`
185174
/// must be `None`.
186-
fn finalize(&mut self) -> der::Result<Vec<u8>> {
175+
fn finalize<S>(
176+
&mut self,
177+
_signer: &S,
178+
) -> core::result::Result<Vec<u8>, x509_cert::builder::Error>
179+
where
180+
S: Keypair + DynSignatureAlgorithmIdentifier,
181+
S::VerifyingKey: EncodePublicKey,
182+
{
187183
let message_digest = match self.external_message_digest {
188184
Some(external_content_digest) => {
189185
if self.encapsulated_content_info.econtent.is_some() {
190186
// Encapsulated content must be empty, if external digest is given.
191-
return Err(der::Error::from(ErrorKind::Failed));
187+
return Err(der::Error::from(ErrorKind::Failed).into());
192188
}
193189
Some(external_content_digest.to_vec())
194190
}
@@ -201,7 +197,7 @@ where
201197
Some(content) => {
202198
let mut hasher = get_hasher(&self.digest_algorithm).ok_or_else(|| {
203199
// Unsupported hash algorithm: {}, &self.digest_algorithm.oid.to_string()
204-
der::Error::from(ErrorKind::Failed)
200+
x509_cert::builder::Error::from(der::Error::from(ErrorKind::Failed))
205201
})?;
206202
// Only the octets comprising the value of the eContent
207203
// OCTET STRING are input to the message digest algorithm, not the tag
@@ -245,7 +241,7 @@ where
245241
// Check against `eContentType`
246242
if signed_attributes_content_type.oid != econtent_type {
247243
// Mismatch between content types: encapsulated content info <-> signed attributes.
248-
return Err(der::Error::from(ErrorKind::Failed));
244+
return Err(der::Error::from(ErrorKind::Failed).into());
249245
}
250246
} else {
251247
signed_attributes.push(
@@ -264,10 +260,15 @@ where
264260
Ok(signed_attributes_der)
265261
}
266262

267-
fn assemble(
263+
fn assemble<S>(
268264
self,
269265
signature: BitString,
270-
) -> core::result::Result<Self::Output, x509_cert::builder::Error> {
266+
signer: &S,
267+
) -> core::result::Result<Self::Output, x509_cert::builder::Error>
268+
where
269+
S: Keypair + DynSignatureAlgorithmIdentifier,
270+
S::VerifyingKey: EncodePublicKey,
271+
{
271272
let signed_attrs = self.signed_attributes.as_ref().map(|signed_attributes| {
272273
SignedAttributes::try_from(signed_attributes.to_owned()).unwrap()
273274
});
@@ -281,7 +282,7 @@ where
281282
let signature_value =
282283
SignatureValue::new(signature.raw_bytes()).map_err(x509_cert::builder::Error::from)?;
283284

284-
let signature_algorithm = self.signer.signature_algorithm_identifier()?;
285+
let signature_algorithm = signer.signature_algorithm_identifier()?;
285286

286287
Ok(SignerInfo {
287288
version: self.version(),
@@ -379,15 +380,17 @@ impl<'s> SignedDataBuilder<'s> {
379380
/// must not be changed after the first signer info was added.
380381
pub fn add_signer_info<S, Signature>(
381382
&mut self,
382-
signer_info_builder: SignerInfoBuilder<'_, S>,
383+
signer_info_builder: SignerInfoBuilder<'_>,
384+
signer: &S,
383385
) -> Result<&mut Self>
384386
where
385387
S: Keypair + DynSignatureAlgorithmIdentifier,
386388
S: Signer<Signature>,
389+
S::VerifyingKey: EncodePublicKey,
387390
Signature: SignatureBitStringEncoding,
388391
{
389392
let signer_info = signer_info_builder
390-
.build::<Signature>()
393+
.build::<S, Signature>(signer)
391394
.map_err(|_| der::Error::from(ErrorKind::Failed))?;
392395
self.signer_infos.push(signer_info);
393396

cms/tests/builder.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ fn test_build_signed_data() {
104104
};
105105
let external_message_digest = None;
106106
let signer_info_builder_1 = SignerInfoBuilder::new(
107-
&signer,
108107
signer_identifier(1),
109108
digest_algorithm.clone(),
110109
&content,
@@ -119,7 +118,6 @@ fn test_build_signed_data() {
119118
};
120119
let external_message_digest_2 = None;
121120
let signer_info_builder_2 = SignerInfoBuilder::new(
122-
&signer_2,
123121
signer_identifier(1),
124122
digest_algorithm_2.clone(),
125123
&content,
@@ -137,10 +135,14 @@ fn test_build_signed_data() {
137135
.expect("could not add a digest algorithm")
138136
.add_certificate(CertificateChoices::Certificate(certificate))
139137
.expect("error adding certificate")
140-
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(signer_info_builder_1)
138+
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
139+
signer_info_builder_1,
140+
&signer,
141+
)
141142
.expect("error adding RSA signer info")
142143
.add_signer_info::<ecdsa::SigningKey<NistP256>, p256::ecdsa::DerSignature>(
143144
signer_info_builder_2,
145+
&signer_2,
144146
)
145147
.expect("error adding P256 signer info")
146148
.build()
@@ -324,7 +326,6 @@ fn test_build_pkcs7_scep_pkcsreq() {
324326
parameters: None,
325327
};
326328
let mut signer_info_builder = SignerInfoBuilder::new(
327-
&signer,
328329
signer_identifier(1),
329330
digest_algorithm.clone(),
330331
&content,
@@ -380,7 +381,10 @@ fn test_build_pkcs7_scep_pkcsreq() {
380381
.unwrap()
381382
.add_certificate(CertificateChoices::Certificate(certificate))
382383
.unwrap()
383-
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(signer_info_builder)
384+
.add_signer_info::<SigningKey<Sha256>, rsa::pkcs1v15::Signature>(
385+
signer_info_builder,
386+
&signer,
387+
)
384388
.unwrap()
385389
.build()
386390
.unwrap();

0 commit comments

Comments
 (0)