From 9eaffca0e06eddc94bfa06874838a13e557f9dbb Mon Sep 17 00:00:00 2001 From: Daniel Alley Date: Sun, 5 May 2024 17:15:04 -0400 Subject: [PATCH] Clean up some duplication build() and build_and_sign() don't need to contain duplicated implementations of the rpm building logic. --- src/rpm/builder.rs | 39 ++++++++++----------------------------- src/rpm/package.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/rpm/builder.rs b/src/rpm/builder.rs index bf94b0e..04e754a 100644 --- a/src/rpm/builder.rs +++ b/src/rpm/builder.rs @@ -593,8 +593,7 @@ impl PackageBuilder { header_idx_tag.write(&mut header)?; let digest_header = { - let header = header; - let header_digest_sha256 = hex::encode(sha2::Sha256::digest(header.as_slice())); + let header_digest_sha256 = hex::encode(sha2::Sha256::digest(&header)); Header::::builder() .add_digest(header_digest_sha256.as_str()) @@ -612,46 +611,28 @@ impl PackageBuilder { /// Build the package and sign it with the provided signer /// + /// If `source_date` was configured, that timestamp will be used during generation of the signature + /// rather than the current one - which makes "reproducible builds" easier. + /// /// See `signature::Signing` for more details. #[cfg(feature = "signature-meta")] pub fn build_and_sign(self, signer: S) -> Result where - S: signature::Signing, + S: signature::Signing>, { let source_date = self.source_date; - let (lead, header_idx_tag, content) = self.prepare_data()?; - - let mut header = Vec::with_capacity(128); - header_idx_tag.write(&mut header)?; - let header = header; - let now = Timestamp::now(); let signature_timestamp = match source_date { Some(source_date_epoch) if source_date_epoch < now => source_date_epoch, _ => now, }; - let header_digest_sha256 = hex::encode(sha2::Sha256::digest(header.as_slice())); - - let builder = - Header::::builder().add_digest(header_digest_sha256.as_str()); - - let sig_header_only = signer.sign(header.as_slice(), signature_timestamp)?; + // There's a little bit of duplicate work going on - the header is serialized twice, the header + // checksum is calculated twice - but the overhead is small enough that it's not worth making + // the codepath more complicated + let mut pkg = self.build()?; + pkg.sign_with_timestamp(signer, signature_timestamp)?; - let builder = match signer.algorithm() { - signature::AlgorithmType::RSA => builder.add_rsa_signature(sig_header_only.as_ref()), - signature::AlgorithmType::EdDSA => { - builder.add_eddsa_signature(sig_header_only.as_ref()) - } - }; - - let signature_header = builder.build(); - let metadata = PackageMetadata { - lead, - signature: signature_header, - header: header_idx_tag, - }; - let pkg = Package { metadata, content }; Ok(pkg) } diff --git a/src/rpm/package.rs b/src/rpm/package.rs index 05ea683..6149600 100644 --- a/src/rpm/package.rs +++ b/src/rpm/package.rs @@ -103,21 +103,21 @@ impl Package { self.metadata.header.write(&mut header_bytes)?; let header_digest_sha256 = hex::encode(sha2::Sha256::digest(header_bytes.as_slice())); - let header_signature = signer.sign(header_bytes.as_slice(), t)?; - let builder = Header::::builder().add_digest(&header_digest_sha256); + let sig_header_builder = + Header::::builder().add_digest(&header_digest_sha256); - let builder = match signer.algorithm() { + let sig_header_builder = match signer.algorithm() { crate::signature::AlgorithmType::RSA => { - builder.add_rsa_signature(header_signature.as_slice()) + sig_header_builder.add_rsa_signature(&header_signature) } crate::signature::AlgorithmType::EdDSA => { - builder.add_eddsa_signature(header_signature.as_slice()) + sig_header_builder.add_eddsa_signature(&header_signature) } }; - self.metadata.signature = builder.build(); + self.metadata.signature = sig_header_builder.build(); Ok(()) }