summaryrefslogtreecommitdiffstats
path: root/openpgp/src/cert
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-06-23 15:32:22 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-06-23 15:35:12 +0200
commit4a2c51173f9dc48ebd8649982388750ab9dccec7 (patch)
tree539a2eb0bd1810b500d67325096b9d388174a5b8 /openpgp/src/cert
parenta027eae2820485b565209e0221a0671e6707036c (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.rs26
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(