diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-06-23 15:32:22 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-06-23 15:35:12 +0200 |
commit | 4a2c51173f9dc48ebd8649982388750ab9dccec7 (patch) | |
tree | 539a2eb0bd1810b500d67325096b9d388174a5b8 /openpgp/src/cert | |
parent | a027eae2820485b565209e0221a0671e6707036c (diff) |
openpgp: Improve certificate creation performance.
- Canonicalize the newly created certificate just once, not once for
every created component.
Diffstat (limited to 'openpgp/src/cert')
-rw-r--r-- | openpgp/src/cert/builder.rs | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/openpgp/src/cert/builder.rs b/openpgp/src/cert/builder.rs index 3060627c..43a27aab 100644 --- a/openpgp/src/cert/builder.rs +++ b/openpgp/src/cert/builder.rs @@ -1352,7 +1352,9 @@ impl CertBuilder<'_> { // Generate & self-sign primary key. let (primary, sig, mut signer) = self.primary_key(creation_time)?; - let mut cert = Cert::try_from(vec![ + // Construct a skeleton cert. We need this to bind the new + // components to. + let cert = Cert::try_from(vec![ Packet::SecretKey({ let mut primary = primary.clone(); if let Some(ref password) = self.password { @@ -1360,8 +1362,13 @@ impl CertBuilder<'_> { } primary }), - sig.into(), ])?; + // We will, however, collect any signatures and components in + // a separate vector, and only add them in the end, so that we + // canonicalize the new certificate just once. + let mut acc = vec![ + Packet::from(sig), + ]; // We want to mark exactly one User ID or Attribute as primary. // First, figure out whether one of the binding signature @@ -1402,8 +1409,8 @@ impl CertBuilder<'_> { } let signature = uid.bind(&mut signer, &cert, sig)?; - cert = cert.insert_packets( - vec![Packet::from(uid), signature.into()])?; + acc.push(uid.into()); + acc.push(signature.into()); } // Sign UserAttributes. @@ -1432,8 +1439,8 @@ impl CertBuilder<'_> { } let signature = ua.bind(&mut signer, &cert, sig)?; - cert = cert.insert_packets( - vec![Packet::from(ua), signature.into()])?; + acc.push(ua.into()); + acc.push(signature.into()); } // Sign subkeys. @@ -1469,10 +1476,13 @@ impl CertBuilder<'_> { if let Some(ref password) = self.password { subkey.secret_mut().encrypt_in_place(password)?; } - cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey), - signature.into()])?; + acc.push(subkey.into()); + acc.push(signature.into()); } + // Now add the new components and canonicalize once. + let cert = cert.insert_packets(acc)?; + let revocation = CertRevocationBuilder::new() .set_signature_creation_time(creation_time)? .set_reason_for_revocation( |