summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Runge <dave@sleepmap.de>2023-09-29 17:26:23 +0200
committerDavid Runge <dave@sleepmap.de>2023-10-06 17:59:02 +0200
commita83799b778e8645c5ba58b3ecbf8b295c41af96f (patch)
tree12b6e82a12333d3d460aea76f6ab2931ede396e7
parent5795f1f065a65aa27e54cc176df9b406fd01ddce (diff)
openpgp: Add encrypted_secret filter for ValidKeyAmalgamationIter.
Add the new filter `encrypted_secret` to filter on whether secret key material is present and encrypted. Remove the `secret` field of `ValidKeyAmalgamationIter` and alter `ValidKeyAmalgamationIter::secret()` to set both `encrypted_secret` and `unencrypted_secret` to `Some(true)`. Closes https://gitlab.com/sequoia-pgp/sequoia/-/issues/1040 Signed-off-by: David Runge <dave@sleepmap.de>
-rw-r--r--openpgp/NEWS1
-rw-r--r--openpgp/src/cert/amalgamation/key/iter.rs107
2 files changed, 64 insertions, 44 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index 56cd3e8f..926380eb 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -39,6 +39,7 @@
** New functionality
- The RustCrypto backend now supports DSA.
- cert::amalgamation::key::KeyAmalgamationIter::encrypted_secret
+ - cert::amalgamation::key::ValidKeyAmalgamationIter::encrypted_secret
- crypto::SessionKey::as_protected
- crypto::ecdh::decrypt_unwrap2
- packet::Key::generate_dsa
diff --git a/openpgp/src/cert/amalgamation/key/iter.rs b/openpgp/src/cert/amalgamation/key/iter.rs
index f2ce3470..dcc13000 100644
--- a/openpgp/src/cert/amalgamation/key/iter.rs
+++ b/openpgp/src/cert/amalgamation/key/iter.rs
@@ -8,7 +8,6 @@ use crate::{
KeyHandle,
types::RevocationStatus,
packet::key,
- packet::key::SecretKeyMaterial,
types::KeyFlags,
cert::prelude::*,
policy::Policy,
@@ -579,14 +578,7 @@ impl<'a, P, R> KeyAmalgamationIter<'a, P, R>
time: time.into().unwrap_or_else(crate::now),
// The filters.
- secret: match (self.encrypted_secret, self.unencrypted_secret) {
- (Some(encrypted_secret), Some(unencrypted_secret)) => {
- Some(encrypted_secret && unencrypted_secret)
- }
- (Some(encrypted_secret), None) => Some(encrypted_secret),
- (None, Some(unencrypted_secret)) => Some(unencrypted_secret),
- (None, None) => None,
- },
+ encrypted_secret: self.encrypted_secret,
unencrypted_secret: self.unencrypted_secret,
key_handles: self.key_handles,
supported: self.supported,
@@ -694,8 +686,8 @@ pub struct ValidKeyAmalgamationIter<'a, P, R>
// The time.
time: SystemTime,
- // If not None, filters by whether a key has a secret.
- secret: Option<bool>,
+ // If not None, filters by whether a key has an encrypted secret.
+ encrypted_secret: Option<bool>,
// If not None, filters by whether a key has an unencrypted
// secret.
@@ -734,7 +726,7 @@ impl<'a, P, R> fmt::Debug for ValidKeyAmalgamationIter<'a, P, R>
f.debug_struct("ValidKeyAmalgamationIter")
.field("policy", &self.policy)
.field("time", &self.time)
- .field("secret", &self.secret)
+ .field("encrypted_secret", &self.encrypted_secret)
.field("unencrypted_secret", &self.unencrypted_secret)
.field("key_handles", &self.key_handles)
.field("supported", &self.supported)
@@ -887,35 +879,13 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
}
}
- if let Some(want_secret) = self.secret {
- if key.has_secret() {
- // We have a secret.
- if ! want_secret {
- t!("Have a secret... skipping.");
- continue;
- }
- } else if want_secret {
- t!("No secret... skipping.");
- continue;
- }
- }
-
- if let Some(want_unencrypted_secret) = self.unencrypted_secret {
- if let Some(secret) = key.optional_secret() {
- if let SecretKeyMaterial::Unencrypted { .. } = secret {
- if ! want_unencrypted_secret {
- t!("Unencrypted secret... skipping.");
- continue;
- }
- } else if want_unencrypted_secret {
- t!("Encrypted secret... skipping.");
- continue;
- }
- } else {
- // No secret.
- t!("No secret... skipping.");
- continue;
- }
+ if let Some(msg) = skip_secret(
+ ka.key().optional_secret().map(|x| x.is_encrypted()),
+ self.encrypted_secret,
+ self.unencrypted_secret,
+ ) {
+ t!(msg);
+ continue;
}
return Some(ka);
@@ -1405,7 +1375,56 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
policy: self.policy,
// The filters.
- secret: Some(true),
+ encrypted_secret: Some(true),
+ unencrypted_secret: Some(true),
+ key_handles: self.key_handles,
+ supported: self.supported,
+ flags: self.flags,
+ alive: self.alive,
+ revoked: self.revoked,
+
+ _p: std::marker::PhantomData,
+ _r: std::marker::PhantomData,
+ }
+ }
+
+ /// Changes the iterator to only return keys with encrypted secret key
+ /// material.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use sequoia_openpgp as openpgp;
+ /// # use openpgp::Result;
+ /// # use openpgp::cert::prelude::*;
+ /// use openpgp::policy::StandardPolicy;
+ ///
+ /// # fn main() -> Result<()> {
+ /// let p = &StandardPolicy::new();
+ ///
+ /// # let (cert, _) =
+ /// # CertBuilder::new().set_password(Some("password".into()))
+ /// # .generate()?;
+ /// for ka in cert.keys().with_policy(p, None).encrypted_secret() {
+ /// // Use it.
+ /// }
+ /// # assert!(cert.keys().with_policy(p, None).encrypted_secret().count() == 1);
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn encrypted_secret(
+ self,
+ ) -> ValidKeyAmalgamationIter<'a, key::SecretParts, R> {
+ ValidKeyAmalgamationIter {
+ cert: self.cert,
+ primary: self.primary,
+ subkey_iter: self.subkey_iter,
+
+ time: self.time,
+ policy: self.policy,
+
+ // The filters.
+ encrypted_secret: Some(true),
unencrypted_secret: self.unencrypted_secret,
key_handles: self.key_handles,
supported: self.supported,
@@ -1451,7 +1470,7 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
policy: self.policy,
// The filters.
- secret: self.secret,
+ encrypted_secret: self.encrypted_secret,
unencrypted_secret: Some(true),
key_handles: self.key_handles,
supported: self.supported,
@@ -1637,7 +1656,7 @@ impl<'a, P, R> ValidKeyAmalgamationIter<'a, P, R>
policy: self.policy,
// The filters.
- secret: self.secret,
+ encrypted_secret: self.encrypted_secret,
unencrypted_secret: self.unencrypted_secret,
key_handles: self.key_handles,
supported: self.supported,