summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2024-07-12 16:23:38 +0200
committerJustus Winter <justus@sequoia-pgp.org>2024-07-12 16:57:29 +0200
commit640a51ed35f9c3f9c0fc3824536d87b17d7a05c1 (patch)
tree188b8e2c0312435d7574e6c92a239a447f35b8fe
parent2cf81515d30a00d6d87e5939991f0813b9bea5f0 (diff)
openpgp: New Cert::revocation_keys2 that lazily verifies sigs.justus/be-more-lazy
-rw-r--r--openpgp/NEWS5
-rw-r--r--openpgp/src/cert.rs38
-rw-r--r--openpgp/src/cert/builder.rs2
3 files changed, 42 insertions, 3 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index 11c720f9..7d0c9c7b 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -4,6 +4,11 @@
#+STARTUP: content hidestars
+* Changes in 1.22.0
+** New functionality
+ - Cert::revocation_keys2
+** Deprecated functionality
+ - Cert::revocation_keys
* Changes in 1.21.2
** Notable fixes
- A set of constructors for KeyFlags added in 1.21.0 mistakenly
diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs
index 95430c24..77d2cefa 100644
--- a/openpgp/src/cert.rs
+++ b/openpgp/src/cert.rs
@@ -1213,10 +1213,44 @@ impl Cert {
/// .generate()?;
///
/// // Make sure Alice is listed as a designated revoker for Bob.
- /// assert_eq!(bob.revocation_keys(p).collect::<Vec<&RevocationKey>>(),
+ /// assert_eq!(bob.revocation_keys2(p).collect::<Vec<&RevocationKey>>(),
/// vec![&(&alice).into()]);
/// # Ok(()) }
/// ```
+ pub fn revocation_keys2<'a, 'p: 'a>(&'a self, policy: &'p dyn Policy)
+ -> Box<dyn Iterator<Item = &'a RevocationKey> + 'a>
+ {
+ let mut keys = std::collections::HashSet::new();
+
+ let pk_sec = self.primary_key().hash_algo_security();
+
+ // All user ids.
+ self.userids()
+ .flat_map(|ua| {
+ // All valid self-signatures.
+ let sec = ua.hash_algo_security;
+ ua.bundle().self_signatures
+ .filter_verified(move |sig| {
+ policy.signature(sig, sec).is_ok()
+ && sig.revocation_keys().next().is_some()
+ }, None)
+ })
+ // All direct-key signatures.
+ .chain(self.primary_key().bundle()
+ .self_signatures
+ .filter_verified(move |sig| {
+ policy.signature(sig, pk_sec).is_ok()
+ && sig.revocation_keys().next().is_some()
+ }, None))
+ .flat_map(|sig| sig.revocation_keys())
+ .for_each(|rk| { keys.insert(rk); });
+
+ Box::new(keys.into_iter())
+ }
+
+ /// Returns a list of any designated revokers for this certificate.
+ // XXXv2: Remove this function.
+ #[deprecated(note = "Use Cert::revocation_keys2")]
pub fn revocation_keys<'a>(&'a self, policy: &dyn Policy)
-> Box<dyn Iterator<Item = &'a RevocationKey> + 'a>
{
@@ -4422,7 +4456,7 @@ impl<'a> ValidCert<'a> {
where
P: Into<Option<&'a dyn Policy>>,
{
- self.cert.revocation_keys(
+ self.cert.revocation_keys2(
policy.into().unwrap_or_else(|| self.policy()))
}
}
diff --git a/openpgp/src/cert/builder.rs b/openpgp/src/cert/builder.rs
index a22de58b..7471245e 100644
--- a/openpgp/src/cert/builder.rs
+++ b/openpgp/src/cert/builder.rs
@@ -1918,7 +1918,7 @@ mod tests {
let cert = cert.insert_packets(sig)?;
assert!(cert.with_policy(p, then)?.primary_userid().is_err());
- assert_eq!(cert.revocation_keys(p).collect::<HashSet<_>>(),
+ assert_eq!(cert.revocation_keys2(p).collect::<HashSet<_>>(),
revokers.iter().collect::<HashSet<_>>());
Ok(())
}