summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-11-14 17:57:10 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-11-14 17:57:10 +0100
commit9bb3f10773a13fb51076cc538fc0ad6fae7cdc71 (patch)
treeb890fbe4a5892a46ac887fdc691eeb8c4dae2dfb
parent2560383bf9c71cdaf025dd583ba8e28b25bbfb52 (diff)
openpgp: When creating certs, derive the encryption key once.justus/fix-1015
- Fixes #1015.
-rw-r--r--openpgp/src/cert/builder.rs19
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());