diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2024-07-12 16:23:38 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2024-07-12 16:57:29 +0200 |
commit | 640a51ed35f9c3f9c0fc3824536d87b17d7a05c1 (patch) | |
tree | 188b8e2c0312435d7574e6c92a239a447f35b8fe | |
parent | 2cf81515d30a00d6d87e5939991f0813b9bea5f0 (diff) |
openpgp: New Cert::revocation_keys2 that lazily verifies sigs.justus/be-more-lazy
-rw-r--r-- | openpgp/NEWS | 5 | ||||
-rw-r--r-- | openpgp/src/cert.rs | 38 | ||||
-rw-r--r-- | openpgp/src/cert/builder.rs | 2 |
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(()) } |