summaryrefslogtreecommitdiffstats
path: root/openpgp/src/cert/keyiter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/cert/keyiter.rs')
-rw-r--r--openpgp/src/cert/keyiter.rs1075
1 files changed, 0 insertions, 1075 deletions
diff --git a/openpgp/src/cert/keyiter.rs b/openpgp/src/cert/keyiter.rs
deleted file mode 100644
index 3e5e2ba7..00000000
--- a/openpgp/src/cert/keyiter.rs
+++ /dev/null
@@ -1,1075 +0,0 @@
-use std::fmt;
-use std::convert::TryInto;
-use std::time::SystemTime;
-use std::borrow::Borrow;
-
-use crate::{
- KeyHandle,
- types::RevocationStatus,
- packet::key,
- packet::key::SecretKeyMaterial,
- types::KeyFlags,
- cert::prelude::*,
- policy::Policy,
-};
-
-/// An iterator over all `Key`s (both the primary key and the subkeys)
-/// in a certificate.
-///
-/// Returned by `Cert::keys()`.
-///
-/// `KeyIter` follows the builder pattern. There is no need to
-/// explicitly finalize it, however: it already implements the
-/// `Iterator` trait.
-///
-/// By default, `KeyIter` returns all keys. `KeyIter` provides some
-/// filters to control what it returns. For instance,
-/// `KeyIter::secret` causes the iterator to only returns keys that
-/// include secret key material. Of course, since `KeyIter`
-/// implements `Iterator`, it is possible to use `Iterator::filter` to
-/// implement custom filters.
-pub struct KeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- // This is an option to make it easier to create an empty KeyIter.
- cert: Option<&'a Cert>,
- primary: bool,
- subkey_iter: UnfilteredKeyBundleIter<'a,
- key::PublicParts,
- key::SubordinateRole>,
-
- // If not None, filters by whether a key has a secret.
- secret: Option<bool>,
-
- // If not None, filters by whether a key has an unencrypted
- // secret.
- unencrypted_secret: Option<bool>,
-
- // Only return keys in this set.
- key_handles: Vec<KeyHandle>,
-
- _p: std::marker::PhantomData<P>,
- _r: std::marker::PhantomData<R>,
-}
-
-impl<'a, P, R> fmt::Debug for KeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("KeyIter")
- .field("secret", &self.secret)
- .field("unencrypted_secret", &self.unencrypted_secret)
- .field("key_handles", &self.key_handles)
- .finish()
- }
-}
-
-macro_rules! impl_iterator {
- ($parts:path, $role:path, $item:ty) => {
- impl<'a> Iterator for KeyIter<'a, $parts, $role>
- {
- type Item = $item;
-
- fn next(&mut self) -> Option<Self::Item> {
- // We unwrap the result of the conversion. But, this
- // is safe by construction: next_common only returns
- // keys that can be correctly converted.
- self.next_common().map(|k| k.try_into().expect("filtered"))
- }
- }
- }
-}
-
-impl_iterator!(key::PublicParts, key::PrimaryRole,
- PrimaryKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::PrimaryRole,
- PrimaryKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::PrimaryRole,
- PrimaryKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl_iterator!(key::PublicParts, key::SubordinateRole,
- SubordinateKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::SubordinateRole,
- SubordinateKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::SubordinateRole,
- SubordinateKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl_iterator!(key::PublicParts, key::UnspecifiedRole,
- ErasedKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::UnspecifiedRole,
- ErasedKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::UnspecifiedRole,
- ErasedKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl<'a, P, R> KeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- fn next_common(&mut self) -> Option<ErasedKeyAmalgamation<'a, key::PublicParts>>
- {
- tracer!(false, "KeyIter::next", 0);
- t!("KeyIter: {:?}", self);
-
- if self.cert.is_none() {
- return None;
- }
- let cert = self.cert.unwrap();
-
- loop {
- let ka : ErasedKeyAmalgamation<key::PublicParts>
- = if ! self.primary {
- self.primary = true;
- PrimaryKeyAmalgamation::new(cert).into()
- } else {
- SubordinateKeyAmalgamation::new(
- cert, self.subkey_iter.next()?).into()
- };
-
- t!("Considering key: {:?}", ka.key());
-
- if self.key_handles.len() > 0 {
- if !self.key_handles
- .iter()
- .any(|h| h.aliases(ka.key().key_handle()))
- {
- t!("{} is not one of the keys that we are looking for ({:?})",
- ka.key().fingerprint(), self.key_handles);
- continue;
- }
- }
-
- if let Some(want_secret) = self.secret {
- if ka.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) = ka.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;
- }
- }
-
- return Some(ka);
- }
- }
-}
-
-impl<'a, P, R> KeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- /// Returns a new `KeyIter` instance.
- pub(crate) fn new(cert: &'a Cert) -> Self where Self: 'a {
- KeyIter {
- cert: Some(cert),
- primary: false,
- subkey_iter: cert.subkeys(),
-
- // The filters.
- secret: None,
- unencrypted_secret: None,
- key_handles: Vec::with_capacity(0),
-
- _p: std::marker::PhantomData,
- _r: std::marker::PhantomData,
- }
- }
-
- /// Changes the filter to only return keys with secret key material.
- pub fn secret(self) -> KeyIter<'a, key::SecretParts, R> {
- KeyIter {
- cert: self.cert,
- primary: self.primary,
- subkey_iter: self.subkey_iter,
-
- // The filters.
- secret: Some(true),
- unencrypted_secret: self.unencrypted_secret,
- key_handles: self.key_handles,
-
- _p: std::marker::PhantomData,
- _r: std::marker::PhantomData,
- }
- }
-
- /// Changes the filter to only return keys with unencrypted secret
- /// key material.
- pub fn unencrypted_secret(self) -> KeyIter<'a, key::SecretParts, R> {
- KeyIter {
- cert: self.cert,
- primary: self.primary,
- subkey_iter: self.subkey_iter,
-
- // The filters.
- secret: self.secret,
- unencrypted_secret: Some(true),
- key_handles: self.key_handles,
-
- _p: std::marker::PhantomData,
- _r: std::marker::PhantomData,
- }
- }
-
- /// Only returns a key if it matches the specified handle.
- ///
- /// Note: this function is cumulative. If you call this function
- /// (or `key_handles`) multiple times, then the iterator returns a
- /// key if it matches *any* of the specified handles.
- pub fn key_handle<H>(mut self, h: H) -> Self
- where H: Into<KeyHandle>
- {
- self.key_handles.push(h.into());
- self
- }
-
- /// Only returns a key if it matches any of the specified handles.
- ///
- /// Note: this function is cumulative. If you call this function
- /// (or `key_handle`) multiple times, then the iterator returns a
- /// key if it matches *any* of the specified handles.
- pub fn key_handles<'b>(mut self, h: impl Iterator<Item=&'b KeyHandle>)
- -> Self
- where 'a: 'b
- {
- self.key_handles.extend(h.map(|h| h.clone()));
- self
- }
-
- /// Changes the iterator to skip the primary key.
- pub fn subkeys(self) -> KeyIter<'a, P, key::SubordinateRole> {
- KeyIter {
- cert: self.cert,
- primary: true,
- subkey_iter: self.subkey_iter,
-
- // The filters.
- secret: self.secret,
- unencrypted_secret: self.unencrypted_secret,
- key_handles: self.key_handles,
-
- _p: std::marker::PhantomData,
- _r: std::marker::PhantomData,
- }
- }
-
- /// Changes the iterator to only return keys that are valid at
- /// time `time`.
- ///
- /// If `time` is None, then the current time is used.
- ///
- /// See `ValidKeyIter` for the definition of a valid key.
- ///
- /// This also makes a number of filters like `alive` and `revoked`
- /// available and causes the iterator to return a
- /// `KeyAmalgamation` instead of a bare `Key`.
- ///
- /// As a general rule of thumb, when encrypting or signing a
- /// message, you only want to use keys that are alive, not
- /// revoked, and have the appropriate capabilities keys right now.
- /// For example:
- ///
- /// ```rust
- /// # extern crate sequoia_openpgp as openpgp;
- /// # use openpgp::Result;
- /// # use openpgp::cert::prelude::*;
- /// use openpgp::types::RevocationStatus;
- /// use sequoia_openpgp::policy::StandardPolicy;
- ///
- /// # fn main() { f().unwrap(); }
- /// # fn f() -> Result<()> {
- /// # let (cert, _) =
- /// # CertBuilder::general_purpose(None, Some("alice@example.org"))
- /// # .generate()?;
- /// let p = &StandardPolicy::new();
- ///
- /// if let RevocationStatus::Revoked(_) = cert.revoked(p, None) {
- /// // The certificate is revoked, don't use any keys from it.
- /// } else if let Err(_) = cert.alive(p, None) {
- /// // The certificate is not alive, don't use any keys from it.
- /// } else {
- /// for key in cert.keys().with_policy(p, None).alive().revoked(false).for_signing() {
- /// // We can sign the message with this key.
- /// }
- /// }
- /// # Ok(())
- /// # }
- /// ```
- ///
- /// When verifying a message, you only want to use keys that were
- /// alive, not revoked, and signing capable when the message was
- /// signed. These are the only keys that the signer could have
- /// used; anything else suggests an attack, e.g., a forged time
- /// stamp.
- ///
- /// For version 4 Signature packets, the `Signature Creation Time`
- /// subpacket indicates when the signature was allegedly created.
- /// For the purpose of finding the key to verify the signature,
- /// this time stamp should be trusted.
- ///
- /// ```rust
- /// # extern crate sequoia_openpgp as openpgp;
- /// # use openpgp::Result;
- /// # use openpgp::cert::prelude::*;
- /// use openpgp::types::RevocationStatus;
- /// use sequoia_openpgp::policy::StandardPolicy;
- ///
- /// # fn main() { f().unwrap(); }
- /// # fn f() -> Result<()> {
- /// let p = &StandardPolicy::new();
- ///
- /// # let (cert, _) =
- /// # CertBuilder::general_purpose(None, Some("alice@example.org"))
- /// # .generate()?;
- /// # let timestamp = None;
- /// if let RevocationStatus::Revoked(_) = cert.revoked(p, None) {
- /// // The certificate is revoked, don't use any keys from it.
- /// } else if let Err(_) = cert.alive(p, None) {
- /// // The certificate is not alive, don't use any keys from it.
- /// } else {
- /// for key in cert.keys().with_policy(p, timestamp).alive().revoked(false).for_signing() {
- /// // Verify the message with this keys.
- /// }
- /// }
- /// # Ok(())
- /// # }
- /// ```
- ///
- /// Similarly, when decrypting a message, you should only consider
- /// keys that were alive, not revoked, and encryption-capable when
- /// the message was encrypted. Unfortunately, we don't know when
- /// a message was encrypted. This, of course, precludes checking
- /// the key's liveness, its revocation status, and its key
- /// capabilities at the time of encryption.
- ///
- /// Decrypting a message encrypt to an expired or revoked key is
- /// not a security problem. In fact, due to the slow propagation
- /// of revocation certificates, it is better to not ignore revoked
- /// keys in this case. However, checking whether a key is
- /// encryption capable is important. [This discussion] explains
- /// why using a signing key to decrypt a message can be dangerous.
- ///
- /// A possible workaround is to check whether the key is
- /// encryption capable now. Since a key's key flags don't
- /// typically change, this will correctly filter out keys that are
- /// not encryption capable. But, it will also skip keys whose
- /// self signature is now expired. Happily, no one appears to use
- /// [signature expirations] on self signatures. Since using the
- /// current time will almost never result in skipping the correct
- /// decryption key, but does protect the user from a dangerous
- /// attack, we recommend this approach when looking up a
- /// decryption key.
- ///
- /// ```rust
- /// # extern crate sequoia_openpgp as openpgp;
- /// # use openpgp::Result;
- /// # use openpgp::cert::prelude::*;
- /// use sequoia_openpgp::policy::StandardPolicy;
- ///
- /// # fn main() { f().unwrap(); }
- /// # fn f() -> Result<()> {
- /// let p = &StandardPolicy::new();
- ///
- /// # let (cert, _) =
- /// # CertBuilder::general_purpose(None, Some("alice@example.org"))
- /// # .generate()?;
- /// let decryption_keys = cert.keys().with_policy(p, None)
- /// .for_storage_encryption().for_transport_encryption()
- /// .collect::<Vec<_>>();
- /// # Ok(())
- /// # }
- /// ```
- ///
- /// [signature expirations]: https://tools.ietf.org/html/rfc4880#section-5.2.3.10
- /// [This discussion]: https://crypto.stackexchange.com/a/12138
- pub fn with_policy<T>(self, policy: &'a dyn Policy, time: T)
- -> ValidKeyIter<'a, P, R>
- where T: Into<Option<SystemTime>>
- {
- ValidKeyIter {
- cert: self.cert,
- primary: self.primary,
- subkey_iter: self.subkey_iter,
-
- policy: policy,
- time: time.into().unwrap_or_else(SystemTime::now),
-
- // The filters.
- secret: self.secret,
- unencrypted_secret: self.unencrypted_secret,
- key_handles: self.key_handles,
- flags: None,
- alive: None,
- revoked: None,
-
- _p: self._p,
- _r: self._r,
- }
- }
-}
-
-/// An iterator over all valid `Key`s in a certificate.
-///
-/// A key is valid at time `t` if it was not created after `t` and it
-/// has a live *self-signature* at time `t`. Note: this does not mean
-/// that the key or the certificate is also live at time `t`; the key
-/// or certificate may be expired, but the self-signature is still
-/// valid.
-///
-/// `ValidKeyIter` follows the builder pattern. There is no need to
-/// explicitly finalize it, however: it already implements the
-/// `Iterator` trait.
-pub struct ValidKeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- // This is an option to make it easier to create an empty ValidKeyIter.
- cert: Option<&'a Cert>,
- primary: bool,
- subkey_iter: UnfilteredKeyBundleIter<'a,
- key::PublicParts,
- key::SubordinateRole>,
-
- // The policy.
- policy: &'a dyn Policy,
-
- // 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 unencrypted
- // secret.
- unencrypted_secret: Option<bool>,
-
- // Only return keys in this set.
- key_handles: Vec<KeyHandle>,
-
- // If not None, only returns keys with the specified flags.
- flags: Option<KeyFlags>,
-
- // If not None, filters by whether a key is alive at time `t`.
- alive: Option<()>,
-
- // If not None, filters by whether the key is revoked or not at
- // time `t`.
- revoked: Option<bool>,
-
- _p: std::marker::PhantomData<P>,
- _r: std::marker::PhantomData<R>,
-}
-
-impl<'a, P, R> fmt::Debug for ValidKeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("ValidKeyIter")
- .field("policy", &self.policy)
- .field("time", &self.time)
- .field("secret", &self.secret)
- .field("unencrypted_secret", &self.unencrypted_secret)
- .field("key_handles", &self.key_handles)
- .field("flags", &self.flags)
- .field("alive", &self.alive)
- .field("revoked", &self.revoked)
- .finish()
- }
-}
-
-macro_rules! impl_iterator {
- ($parts:path, $role:path, $item:ty) => {
- impl<'a> Iterator for ValidKeyIter<'a, $parts, $role>
- {
- type Item = $item;
-
- fn next(&mut self) -> Option<Self::Item> {
- // We unwrap the result of the conversion. But, this
- // is safe by construction: next_common only returns
- // keys that can be correctly converted.
- self.next_common().map(|k| k.try_into().expect("filtered"))
- }
- }
- }
-}
-
-impl_iterator!(key::PublicParts, key::PrimaryRole,
- ValidPrimaryKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::PrimaryRole,
- ValidPrimaryKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::PrimaryRole,
- ValidPrimaryKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl_iterator!(key::PublicParts, key::SubordinateRole,
- ValidSubordinateKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::SubordinateRole,
- ValidSubordinateKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::SubordinateRole,
- ValidSubordinateKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl_iterator!(key::PublicParts, key::UnspecifiedRole,
- ValidErasedKeyAmalgamation<'a, key::PublicParts>);
-impl_iterator!(key::SecretParts, key::UnspecifiedRole,
- ValidErasedKeyAmalgamation<'a, key::SecretParts>);
-impl_iterator!(key::UnspecifiedParts, key::UnspecifiedRole,
- ValidErasedKeyAmalgamation<'a, key::UnspecifiedParts>);
-
-impl<'a, P, R> ValidKeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- fn next_common(&mut self)
- -> Option<ValidErasedKeyAmalgamation<'a, key::PublicParts>>
- {
- tracer!(false, "ValidKeyIter::next", 0);
- t!("ValidKeyIter: {:?}", self);
-
- if self.cert.is_none() {
- return None;
- }
- let cert = self.cert.unwrap();
-
- if let Some(flags) = self.flags.as_ref() {
- if flags.is_empty() {
- // Nothing to do.
- t!("short circuiting: flags is empty");
- return None;
- }
- }
-
- loop {
- let ka = if ! self.primary {
- self.primary = true;
- let ka : ErasedKeyAmalgamation<'a, key::PublicParts>
- = PrimaryKeyAmalgamation::new(cert).into();
- match ka.with_policy(self.policy, self.time) {
- Ok(ka) => ka,
- Err(err) => {
- // The primary key is bad. Abort.
- t!("Getting primary key: {:?}", err);
- return None;
- }
- }
- } else {
- let ka : ErasedKeyAmalgamation<'a, key::PublicParts>
- = SubordinateKeyAmalgamation::new(
- cert.into(), self.subkey_iter.next()?).into();
- match ka.with_policy(self.policy, self.time) {
- Ok(ka) => ka,
- Err(err) => {
- // The subkey is bad, abort.
- t!("Getting subkey: {:?}", err);
- continue;
- }
- }
- };
-
- let key = ka.key();
- t!("Considering key: {:?}", key);
-
- if self.key_handles.len() > 0 {
- if !self.key_handles
- .iter()
- .any(|h| h.aliases(key.key_handle()))
- {
- t!("{} is not one of the keys that we are looking for ({:?})",
- key.key_handle(), self.key_handles);
- continue;
- }
- }
-
- if let Some(flags) = self.flags.as_ref() {
- if !ka.has_any_key_flag(flags) {
- t!("Have flags: {:?}, want flags: {:?}... skipping.",
- flags, flags);
- continue;
- }
- }
-
- if let Some(()) = self.alive {
- if let Err(err) = ka.alive() {
- t!("Key not alive: {:?}", err);
- continue;
- }
- }
-
- if let Some(want_revoked) = self.revoked {
- if let RevocationStatus::Revoked(_) = ka.revoked() {
- // The key is definitely revoked.
- if ! want_revoked {
- t!("Key revoked... skipping.");
- continue;
- }
- } else {
- // The key is probably not revoked.
- if want_revoked {
- t!("Key not revoked... skipping.");
- continue;
- }
- }
- }
-
- 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;
- }
- }
-
- return Some(ka.into());
- }
- }
-}
-
-impl<'a, P, R> ValidKeyIter<'a, P, R>
- where P: key::KeyParts,
- R: key::KeyRole,
-{
- /// Returns keys that have the at least one of the flags specified
- /// in `flags`.
- ///
- /// If you call this function (or one of `for_certification` or
- /// `for_signing` functions) multiple times, the *union* of the
- /// values is used. Thus,
- /// `cert.flags().for_certification().for_signing()` will return
- /// keys that are certification capable *or* signing capable.
- ///
- /// If you need more complex filtering, e.g., you want a key that
- /// is both certification and signing capable, then use
- /// [`Iterator::filter`].
- ///
- /// [`Iterator::filter`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter
- pub fn key_flags<F>(mut self, flags: F) -> Self
- where F: Borrow<KeyFlags>
- {
- let flags = flags.borrow();
- if let Some(flags_old) = self.flags {
- self.flags = Some(flags | &flags_old);
- } else {
- self.flags = Some(flags.clone());
- }
- self
- }
-
- /// Returns keys that are certification capable.
- ///
- /// See `key_flags` for caveats.
- pub fn for_certification(self) -> Self {
- self.key_flags(KeyFlags::default().set_certification(true))
- }
-
- /// Returns keys that are signing capable.
- ///
- /// See `key_flags` for caveats.
- pub fn for_signing(self) -> Self {
- self.key_flags(KeyFlags::default().set_signing(true))
- }
-
- /// Returns keys that are authentication capable.
- ///
- /// See `key_flags` for caveats.
- pub fn for_authentication(self) -> Self {
- self.key_flags(KeyFlags::default().set_authentication(true))
- }
-
- /// Returns keys that are capable of encrypting data at rest.
- ///
- /// See `key_flags` for caveats.
- pub fn for_storage_encryption(self) -> Self {
- self.key_flags(KeyFlags::default().set_storage_encryption(true))
- }
-
- /// Returns keys that are capable of encrypting data for transport.
- ///
- /// See `key_flags` for caveats.
- pub fn for_transport_encryption(self) -> Self {
- self.key_flags(KeyFlags::default().set_transport_encryption(true))
- }
-
- /// Only returns keys that are alive.
- ///
- /// Note: this only checks if the key is alive; it does not check
- /// whether the certificate is alive.
- pub fn alive(mut self) -> Self
- {
- self.alive = Some(());
- self
- }
-
- /// Filters by whether a key is definitely revoked.
- ///
- /// A value of None disables this filter.
- ///
- /// Note: If you call this function multiple times on the same
- /// iterator, only the last value is used.
- ///
- /// Note: This only checks if the key is not revoked; it does not
- /// check whether the certificate not revoked.
- ///
- /// This filter checks whether a key's revocation status is
- /// `RevocationStatus::Revoked` or not. The latter (i.e.,
- /// `revoked(false)`) is equivalent to:
- ///
- /// ```rust
- /// extern crate sequoia_openpgp as openpgp;
- /// # use openpgp::Result;
- /// use openpgp::types::RevocationStatus;
- /// use openpgp::cert::prelude::*;
- /// use sequoia_openpgp::policy::StandardPolicy;
- ///
- /// # fn main() { f().unwrap(); }
- /// # fn f() -> Result<()> {
- /// # let (cert, _) =
- /// # CertBuilder::general_purpose(None, Some("alice@example.org"))
- /// # .generate()?;
- /// let p = &StandardPolicy::new();
- ///
- /// # let timestamp = None;
- /// let non_revoked_keys = cert
- /// .keys()
- /// .with_policy(p, timestamp)
- /// .filter(|ka| {
- /// match ka.revoked() {
- /// RevocationStatus::Revoked(_) =>
- /// // It's definitely revoked, skip it.
- /// false,
- /// RevocationStatus::CouldBe(_) =>
- /// // There is a designated revoker that we
- /// // should check, but don't (or can't). To
- /// // avoid a denial of service arising from fake
- /// // revocations, we assume that the key has not
- /// // been revoked and return it.
- /// true,
- /// RevocationStatus::NotAsFarAsWeKnow =>
- /// // We have no evidence to suggest that the key
- /// // is revoked.
- /// true,
- /// }
- /// })
- /// .map(|ka| ka.key())
- /// .collect::<Vec<_>>();
- /// # Ok(())
- /// # }
- /// ```