diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-11-14 17:57:10 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-11-14 17:57:10 +0100 |
commit | 9bb3f10773a13fb51076cc538fc0ad6fae7cdc71 (patch) | |
tree | b890fbe4a5892a46ac887fdc691eeb8c4dae2dfb | |
parent | 2560383bf9c71cdaf025dd583ba8e28b25bbfb52 (diff) |
openpgp: When creating certs, derive the encryption key once.justus/fix-1015
- Fixes #1015.
-rw-r--r-- | openpgp/src/cert/builder.rs | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/openpgp/src/cert/builder.rs b/openpgp/src/cert/builder.rs index 82045295..766d9edb 100644 --- a/openpgp/src/cert/builder.rs +++ b/openpgp/src/cert/builder.rs @@ -18,7 +18,7 @@ use crate::packet::signature::{ }; use crate::cert::prelude::*; use crate::Error; -use crate::crypto::{Password, Signer}; +use crate::crypto::{Password, S2K, Signer}; use crate::types::{ Features, HashAlgorithm, @@ -1349,6 +1349,15 @@ impl CertBuilder<'_> { time::Duration::new(SIG_BACKDATE_BY, 0) }); + // Fix encryption parameters so that we encrypt all subkeys + // using the same session key. This is an optimization that + // speeds up certificate creation as well as using them, as + // the key derivation function only has to be done once. + let encryption_params = + self.password.as_ref().map(|p| { + S2K::default().make_encryption_parameters(p, None) + }).transpose()?; + // Generate & self-sign primary key. let (primary, sig, mut signer) = self.primary_key(creation_time)?; @@ -1357,8 +1366,8 @@ impl CertBuilder<'_> { let cert = Cert::try_from(vec![ Packet::SecretKey({ let mut primary = primary.clone(); - if let Some(ref password) = self.password { - primary.secret_mut().encrypt_in_place(password)?; + if let Some(params) = &encryption_params { + primary.secret_mut().encrypt_in_place_with(params)?; } primary }), @@ -1475,8 +1484,8 @@ impl CertBuilder<'_> { let signature = subkey.bind(&mut signer, &cert, builder)?; - if let Some(ref password) = self.password { - subkey.secret_mut().encrypt_in_place(password)?; + if let Some(params) = &encryption_params { + subkey.secret_mut().encrypt_in_place_with(params)?; } acc.push(subkey.into()); acc.push(signature.into()); |