sequoia_openpgp/cert/amalgamation/
key.rs

1//! Keys, their associated signatures, and some useful methods.
2//!
3//! A [`KeyAmalgamation`] is similar to a [`ComponentAmalgamation`],
4//! but a `KeyAmalgamation` includes some additional functionality
5//! that is needed to correctly implement a [`Key`] component's
6//! semantics.  In particular, unlike other components where the
7//! binding signature stores the component's meta-data, a Primary Key
8//! doesn't have a binding signature (it is the thing that other
9//! components are bound to!), and, as a consequence, the associated
10//! meta-data is stored elsewhere.
11//!
12//! Unfortunately, a primary Key's meta-data is usually not stored on
13//! a direct key signature, which would be convenient as it is located
14//! at the same place as a binding signature would be, but on the
15//! primary User ID's binding signature.  This requires some
16//! acrobatics on the implementation side to realize the correct
17//! semantics.  In particular, a `Key` needs to memorize its role
18//! (i.e., whether it is a primary key or a subkey) in order to know
19//! whether to consider its own self signatures or the primary User
20//! ID's self signatures when looking for its meta-data.
21//!
22//! Ideally, a `KeyAmalgamation`'s role would be encoded in its type.
23//! This increases safety, and reduces the run-time overhead.
24//! However, we want [`Cert::keys`] to return an iterator over all
25//! keys; we don't want the user to have to specially handle the
26//! primary key when that fact is not relevant.  This means that
27//! `Cert::keys` has to erase the returned `Key`s' roles: all items in
28//! an iterator must have the same type.  To support this, we have to
29//! keep track of a `KeyAmalgamation`'s role at run-time.
30//!
31//! But, just because we need to erase a `KeyAmalgamation`'s role to
32//! implement `Cert::keys` doesn't mean that we have to always erase
33//! it.  To achieve this, we use three data types:
34//! [`PrimaryKeyAmalgamation`], [`SubordinateKeyAmalgamation`], and
35//! [`ErasedKeyAmalgamation`].  The first two encode the role
36//! information in their type, and the last one stores it at run time.
37//! We provide conversion functions to convert the static type
38//! information into dynamic type information, and vice versa.
39//!
40//! Note: `KeyBundle`s and `KeyAmalgamation`s have a notable
41//! difference: whereas a `KeyBundle`'s role is a marker, a
42//! `KeyAmalgamation`'s role determines its semantics.  A consequence
43//! of this is that it is not possible to convert a
44//! `PrimaryKeyAmalgamation` into a `SubordinateAmalgamation`s, or
45//! vice versa even though we support changing a `KeyBundle`'s role:
46//!
47//! ```
48//! # fn main() -> sequoia_openpgp::Result<()> {
49//! # use std::convert::TryInto;
50//! # use sequoia_openpgp as openpgp;
51//! # use openpgp::cert::prelude::*;
52//! # use openpgp::packet::prelude::*;
53//! # let (cert, _) = CertBuilder::new()
54//! #     .add_userid("Alice")
55//! #     .add_signing_subkey()
56//! #     .add_transport_encryption_subkey()
57//! #     .generate()?;
58//! // This works:
59//! cert.primary_key().bundle().role_as_subordinate();
60//!
61//! // But this doesn't:
62//! let ka: ErasedKeyAmalgamation<_> = cert.keys().nth(0).expect("primary key");
63//! let ka: openpgp::Result<SubordinateKeyAmalgamation<key::PublicParts>> = ka.try_into();
64//! assert!(ka.is_err());
65//! # Ok(()) }
66//! ```
67//!
68//! The use of the prefix `Erased` instead of `Unspecified`
69//! (cf. [`KeyRole::UnspecifiedRole`]) emphasizes this.
70//!
71//! # Selecting Keys
72//!
73//! It is essential to choose the right keys, and to make sure that
74//! they are appropriate.  Below, we present some guidelines for the most
75//! common situations.
76//!
77//! ## Encrypting and Signing Messages
78//!
79//! As a general rule of thumb, when encrypting or signing a message,
80//! you want to use keys that are alive, not revoked, and have the
81//! appropriate capabilities right now.  For example, the following
82//! code shows how to find a key, which is appropriate for signing a
83//! message:
84//!
85//! ```rust
86//! # use sequoia_openpgp as openpgp;
87//! # use openpgp::Result;
88//! # use openpgp::cert::prelude::*;
89//! use openpgp::types::RevocationStatus;
90//! use sequoia_openpgp::policy::StandardPolicy;
91//!
92//! # fn main() -> Result<()> {
93//! #     let (cert, _) =
94//! #         CertBuilder::general_purpose(Some("alice@example.org"))
95//! #         .generate()?;
96//! #     let mut i = 0;
97//! let p = &StandardPolicy::new();
98//!
99//! let cert = cert.with_policy(p, None)?;
100//!
101//! if let RevocationStatus::Revoked(_) = cert.revocation_status() {
102//!     // The certificate is revoked, don't use any keys from it.
103//! #   unreachable!();
104//! } else if let Err(_) = cert.alive() {
105//!     // The certificate is not alive, don't use any keys from it.
106//! #   unreachable!();
107//! } else {
108//!     for ka in cert.keys() {
109//!         if let RevocationStatus::Revoked(_) = ka.revocation_status() {
110//!             // The key is revoked.
111//! #           unreachable!();
112//!         } else if let Err(_) = ka.alive() {
113//!             // The key is not alive.
114//! #           unreachable!();
115//!         } else if ! ka.for_signing() {
116//!             // The key is not signing capable.
117//!         } else {
118//!             // Use it!
119//! #           i += 1;
120//!         }
121//!     }
122//! }
123//! # assert_eq!(i, 1);
124//! #     Ok(())
125//! # }
126//! ```
127//!
128//! ## Verifying a Message
129//!
130//! When verifying a message, you only want to use keys that were
131//! alive, not revoked, and signing capable *when the message was
132//! signed*.  These are the keys that the signer would have used, and
133//! they reflect the signer's policy when they made the signature.
134//! (See the [`Policy` discussion] for an explanation.)
135//!
136//! For version 4 Signature packets, the `Signature Creation Time`
137//! subpacket indicates when the signature was allegedly created.  For
138//! the purpose of finding the key to verify the signature, this time
139//! stamp should be trusted: if the key is authenticated and the
140//! signature is valid, then the time stamp is valid; if the signature
141//! is not valid, then forging the time stamp won't help an attacker.
142//!
143//! ```rust
144//! # use sequoia_openpgp as openpgp;
145//! # use openpgp::Result;
146//! # use openpgp::cert::prelude::*;
147//! use openpgp::types::RevocationStatus;
148//! use sequoia_openpgp::policy::StandardPolicy;
149//!
150//! # fn main() -> Result<()> {
151//! let p = &StandardPolicy::new();
152//!
153//! #     let (cert, _) =
154//! #         CertBuilder::general_purpose(Some("alice@example.org"))
155//! #         .generate()?;
156//! #     let timestamp = None;
157//! #     let issuer = cert.with_policy(p, None)?.keys()
158//! #         .for_signing().nth(0).unwrap().key().fingerprint();
159//! #     let mut i = 0;
160//! let cert = cert.with_policy(p, timestamp)?;
161//! if let RevocationStatus::Revoked(_) = cert.revocation_status() {
162//!     // The certificate is revoked, don't use any keys from it.
163//! #   unreachable!();
164//! } else if let Err(_) = cert.alive() {
165//!     // The certificate is not alive, don't use any keys from it.
166//! #   unreachable!();
167//! } else {
168//!     for ka in cert.keys().key_handle(issuer) {
169//!         if let RevocationStatus::Revoked(_) = ka.revocation_status() {
170//!             // The key is revoked, don't use it!
171//! #           unreachable!();
172//!         } else if let Err(_) = ka.alive() {
173//!             // The key was not alive when the signature was made!
174//!             // Something fishy is going on.
175//! #           unreachable!();
176//!         } else if ! ka.for_signing() {
177//!             // The key was not signing capable!  Better be safe
178//!             // than sorry.
179//! #           unreachable!();
180//!         } else {
181//!             // Try verifying the message with this key.
182//! #           i += 1;
183//!         }
184//!     }
185//! }
186//! #     assert_eq!(i, 1);
187//! #     Ok(())
188//! # }
189//! ```
190//!
191//! ## Decrypting a Message
192//!
193//! When decrypting a message, it seems like one ought to only use keys
194//! that were alive, not revoked, and encryption-capable when the
195//! message was encrypted.  Unfortunately, we don't know when a
196//! message was encrypted.  But anyway, due to the slow propagation of
197//! revocation certificates, we can't assume that senders won't
198//! mistakenly use a revoked key.
199//!
200//! However, wanting to decrypt a message encrypted using an expired
201//! or revoked key is reasonable.  If someone is trying to decrypt a
202//! message using an expired key, then they are the certificate
203//! holder, and probably attempting to access archived data using a
204//! key that they themselves revoked!  We don't want to prevent that.
205//!
206//! We do, however, want to check whether a key is really encryption
207//! capable.  [This discussion] explains why using a signing key to
208//! decrypt a message can be dangerous.  Since we need a binding
209//! signature to determine this, but we don't have the time that the
210//! message was encrypted, we need a workaround.  One approach would
211//! be to check whether the key is encryption capable now.  Since a
212//! key's key flags don't typically change, this will correctly filter
213//! out keys that are not encryption capable.  But, it will skip keys
214//! whose self signature has expired.  But that is not a problem
215//! either: no one sets self signatures to expire; if anything, they
216//! set keys to expire.  Thus, this will not result in incorrectly
217//! failing to decrypt messages in practice, and is a reasonable
218//! approach.
219//!
220//! ```rust
221//! # use sequoia_openpgp as openpgp;
222//! # use openpgp::Result;
223//! # use openpgp::cert::prelude::*;
224//! use sequoia_openpgp::policy::StandardPolicy;
225//!
226//! # fn main() -> Result<()> {
227//! let p = &StandardPolicy::new();
228//!
229//! #     let (cert, _) =
230//! #         CertBuilder::general_purpose(Some("alice@example.org"))
231//! #         .generate()?;
232//! let decryption_keys = cert.keys().with_policy(p, None)
233//!     .for_storage_encryption().for_transport_encryption()
234//!     .collect::<Vec<_>>();
235//! #     Ok(())
236//! # }
237//! ```
238//!
239//! [`ComponentAmalgamation`]: super::ComponentAmalgamation
240//! [`Key`]: crate::packet::key
241//! [`Cert::keys`]: super::super::Cert::keys()
242//! [`PrimaryKeyAmalgamation`]: super::PrimaryKeyAmalgamation
243//! [`SubordinateKeyAmalgamation`]: super::SubordinateKeyAmalgamation
244//! [`ErasedKeyAmalgamation`]: super::ErasedKeyAmalgamation
245//! [`KeyRole::UnspecifiedRole`]: crate::packet::key::KeyRole
246//! [`Policy` discussion]: super
247//! [This discussion]: https://crypto.stackexchange.com/a/12138
248use std::time;
249use std::time::SystemTime;
250use std::borrow::Borrow;
251use std::convert::TryFrom;
252use std::convert::TryInto;
253
254use anyhow::Context;
255
256use crate::{
257    Cert,
258    cert::bundle::KeyBundle,
259    cert::amalgamation::{
260        ComponentAmalgamation,
261        key::signature::subpacket::SubpacketValue,
262        ValidAmalgamation,
263        ValidBindingSignature,
264        ValidateAmalgamation,
265    },
266    cert::ValidCert,
267    crypto::Signer,
268    Error,
269    packet::Key,
270    packet::key,
271    packet::Signature,
272    packet::signature,
273    packet::signature::subpacket::SubpacketTag,
274    policy::Policy,
275    Result,
276    seal,
277    types::{
278        KeyFlags,
279        RevocationKey,
280        RevocationStatus,
281        SignatureType,
282    },
283};
284
285mod iter;
286pub use iter::{
287    KeyAmalgamationIter,
288    ValidKeyAmalgamationIter,
289};
290
291/// Whether the key is a primary key.
292///
293/// This trait is an implementation detail.  It exists so that we can
294/// have a blanket implementation of [`ValidAmalgamation`] for
295/// [`ValidKeyAmalgamation`], for instance, even though we only have
296/// specialized implementations of `PrimaryKey`.
297///
298/// [`ValidAmalgamation`]: super::ValidAmalgamation
299///
300/// # Sealed trait
301///
302/// This trait is [sealed] and cannot be implemented for types outside this crate.
303/// Therefore it can be extended in a non-breaking way.
304/// If you want to implement the trait inside the crate
305/// you also need to implement the `seal::Sealed` marker trait.
306///
307/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
308pub trait PrimaryKey<'a, P, R>: seal::Sealed
309    where P: 'a + key::KeyParts,
310          R: 'a + key::KeyRole,
311{
312    /// Returns whether the key amalgamation is a primary key
313    /// amalgamation.
314    ///
315    /// # Examples
316    ///
317    /// ```
318    /// # use sequoia_openpgp as openpgp;
319    /// # use openpgp::cert::prelude::*;
320    /// # use openpgp::policy::StandardPolicy;
321    /// #
322    /// # fn main() -> openpgp::Result<()> {
323    /// #     let p = &StandardPolicy::new();
324    /// #     let (cert, _) =
325    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
326    /// #         .generate()?;
327    /// #     let fpr = cert.fingerprint();
328    /// // This works if the type is concrete:
329    /// let ka: PrimaryKeyAmalgamation<_> = cert.primary_key();
330    /// assert!(ka.primary());
331    ///
332    /// // Or if it has been erased:
333    /// for (i, ka) in cert.keys().enumerate() {
334    ///     let ka: ErasedKeyAmalgamation<_> = ka;
335    ///     if i == 0 {
336    ///         // The primary key is always the first key returned by
337    ///         // `Cert::keys`.
338    ///         assert!(ka.primary());
339    ///     } else {
340    ///         // The rest are subkeys.
341    ///         assert!(! ka.primary());
342    ///     }
343    /// }
344    /// # Ok(()) }
345    /// ```
346    fn primary(&self) -> bool;
347}
348
349/// A key, and its associated data, and useful methods.
350///
351/// A `KeyAmalgamation` is like a [`ComponentAmalgamation`], but
352/// specialized for keys.  Due to the requirement to keep track of the
353/// key's role when it is erased ([see the module's documentation] for
354/// more details), this is a different data structure rather than a
355/// specialized type alias.
356///
357/// Generally, you won't use this type directly, but instead use
358/// [`PrimaryKeyAmalgamation`], [`SubordinateKeyAmalgamation`], or
359/// [`ErasedKeyAmalgamation`].
360///
361/// A `KeyAmalgamation` is returned by [`Cert::primary_key`], and
362/// [`Cert::keys`].
363///
364/// `KeyAmalgamation` implements [`ValidateAmalgamation`], which
365/// allows you to turn a `KeyAmalgamation` into a
366/// [`ValidKeyAmalgamation`] using [`KeyAmalgamation::with_policy`].
367///
368/// # Examples
369///
370/// Iterating over all keys:
371///
372/// ```
373/// # use sequoia_openpgp as openpgp;
374/// # use openpgp::cert::prelude::*;
375/// # use openpgp::policy::StandardPolicy;
376/// #
377/// # fn main() -> openpgp::Result<()> {
378/// #     let p = &StandardPolicy::new();
379/// #     let (cert, _) =
380/// #         CertBuilder::general_purpose(Some("alice@example.org"))
381/// #         .generate()?;
382/// #     let fpr = cert.fingerprint();
383/// for ka in cert.keys() {
384///     let ka: ErasedKeyAmalgamation<_> = ka;
385/// }
386/// #     Ok(())
387/// # }
388/// ```
389///
390/// Getting the primary key:
391///
392/// ```
393/// # use sequoia_openpgp as openpgp;
394/// # use openpgp::cert::prelude::*;
395/// # use openpgp::policy::StandardPolicy;
396/// #
397/// # fn main() -> openpgp::Result<()> {
398/// #     let p = &StandardPolicy::new();
399/// #     let (cert, _) =
400/// #         CertBuilder::general_purpose(Some("alice@example.org"))
401/// #         .generate()?;
402/// #     let fpr = cert.fingerprint();
403/// let ka: PrimaryKeyAmalgamation<_> = cert.primary_key();
404/// #     Ok(())
405/// # }
406/// ```
407///
408/// Iterating over just the subkeys:
409///
410/// ```
411/// # use sequoia_openpgp as openpgp;
412/// # use openpgp::cert::prelude::*;
413/// # use openpgp::policy::StandardPolicy;
414/// #
415/// # fn main() -> openpgp::Result<()> {
416/// #     let p = &StandardPolicy::new();
417/// #     let (cert, _) =
418/// #         CertBuilder::general_purpose(Some("alice@example.org"))
419/// #         .generate()?;
420/// #     let fpr = cert.fingerprint();
421/// // We can skip the primary key (it's always first):
422/// for ka in cert.keys().skip(1) {
423///     let ka: ErasedKeyAmalgamation<_> = ka;
424/// }
425///
426/// // Or use `subkeys`, which returns a more accurate type:
427/// for ka in cert.keys().subkeys() {
428///     let ka: SubordinateKeyAmalgamation<_> = ka;
429/// }
430/// #     Ok(())
431/// # }
432/// ```
433///
434/// [`ComponentAmalgamation`]: super::ComponentAmalgamation
435/// [see the module's documentation]: self
436/// [`Cert::primary_key`]: crate::cert::Cert::primary_key()
437/// [`Cert::keys`]: crate::cert::Cert::keys()
438/// [`ValidateAmalgamation`]: super::ValidateAmalgamation
439/// [`KeyAmalgamation::with_policy`]: super::ValidateAmalgamation::with_policy()
440#[derive(Debug, PartialEq)]
441pub struct KeyAmalgamation<'a, P, R, R2>
442    where P: 'a + key::KeyParts,
443          R: 'a + key::KeyRole,
444{
445    ca: ComponentAmalgamation<'a, Key<P, R>>,
446    primary: R2,
447}
448assert_send_and_sync!(KeyAmalgamation<'_, P, R, R2>
449    where P: key::KeyParts,
450          R: key::KeyRole,
451          R2,
452);
453
454impl<'a, P, R> ComponentAmalgamation<'a, Key<P, R>>
455where
456    P: key::KeyParts,
457    R: key::KeyRole,
458{
459    /// Returns a reference to the key.
460    ///
461    /// This is just a type-specific alias for
462    /// [`ComponentAmalgamation::component`].
463    ///
464    /// [`ComponentAmalgamation::component`]: ComponentAmalgamation::component()
465    ///
466    /// # Examples
467    ///
468    /// ```
469    /// # use sequoia_openpgp as openpgp;
470    /// # use openpgp::cert::prelude::*;
471    /// #
472    /// # fn main() -> openpgp::Result<()> {
473    /// # let (cert, _) =
474    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
475    /// #     .generate()?;
476    /// // Display some information about the keys.
477    /// for ka in cert.keys() {
478    ///     eprintln!(" - {:?}", ka.key());
479    /// }
480    /// # Ok(()) }
481    /// ```
482    pub fn key(&self) -> &Key<P, R> {
483        self.component()
484    }
485
486    pub(crate) fn set_role(&mut self, _: key::KeyRoleRT) {
487        // The amalgamation only has an immutable reference, we cannot
488        // change the role.
489    }
490
491    /// Forwarder for the conversion macros.
492    pub(crate) fn has_secret(&self) -> bool {
493        self.key().has_secret()
494    }
495}
496
497// derive(Clone) doesn't work with generic parameters that don't
498// implement clone.  But, we don't need to require that C implements
499// Clone, because we're not cloning C, just the reference.
500//
501// See: https://github.com/rust-lang/rust/issues/26925
502impl<'a, P, R, R2> Clone for KeyAmalgamation<'a, P, R, R2>
503    where P: 'a + key::KeyParts,
504          R: 'a + key::KeyRole,
505          R2: Copy,
506{
507    fn clone(&self) -> Self {
508        Self {
509            ca: self.ca.clone(),
510            primary: self.primary,
511        }
512    }
513}
514
515
516/// A primary key amalgamation.
517///
518/// A specialized version of [`KeyAmalgamation`].
519///
520pub type PrimaryKeyAmalgamation<'a, P>
521    = KeyAmalgamation<'a, P, key::PrimaryRole, ()>;
522
523/// A subordinate key amalgamation.
524///
525/// A specialized version of [`KeyAmalgamation`].
526///
527pub type SubordinateKeyAmalgamation<'a, P>
528    = KeyAmalgamation<'a, P, key::SubordinateRole, ()>;
529
530
531impl<'a, P> SubordinateKeyAmalgamation<'a, P>
532where
533    P: key::KeyParts,
534{
535    /// Returns the subkey's revocation status at time `t`.
536    ///
537    /// A subkey is revoked at time `t` if:
538    ///
539    ///   - There is a live revocation at time `t` that is newer than
540    ///     all live self signatures at time `t`, or
541    ///
542    ///   - There is a hard revocation (even if it is not live at
543    ///     time `t`, and even if there is a newer self-signature).
544    ///
545    /// Note: Certs and subkeys have different criteria from User IDs
546    /// and User Attributes.
547    ///
548    /// Note: this only returns whether this subkey is revoked; it
549    /// does not imply anything about the Cert or other components.
550    ///
551    /// # Examples
552    ///
553    /// ```
554    /// # use sequoia_openpgp as openpgp;
555    /// # use openpgp::cert::prelude::*;
556    /// use openpgp::policy::StandardPolicy;
557    /// #
558    /// # fn main() -> openpgp::Result<()> {
559    /// let p = &StandardPolicy::new();
560    ///
561    /// # let (cert, _) =
562    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
563    /// #     .generate()?;
564    /// // Display the subkeys' revocation status.
565    /// for ka in cert.keys().subkeys() {
566    ///     eprintln!(" Revocation status of {}: {:?}",
567    ///               ka.key().fingerprint(), ka.revocation_status(p, None));
568    /// }
569    /// # Ok(()) }
570    /// ```
571    pub fn revocation_status<T>(&self, policy: &dyn Policy, t: T)
572                                -> RevocationStatus
573    where
574        T: Into<Option<time::SystemTime>>,
575    {
576        let t = t.into();
577        self.bundle().revocation_status(policy, t)
578    }
579}
580
581/// An amalgamation whose role is not known at compile time.
582///
583/// A specialized version of [`KeyAmalgamation`].
584///
585/// Unlike a [`Key`] or a [`KeyBundle`] with an unspecified role, an
586/// `ErasedKeyAmalgamation` remembers its role; it is just not exposed
587/// to the type system.  For details, see the [module-level
588/// documentation].
589///
590/// [`Key`]: crate::packet::key
591/// [`KeyBundle`]: super::super::bundle
592/// [module-level documentation]: self
593pub type ErasedKeyAmalgamation<'a, P>
594    = KeyAmalgamation<'a, P, key::UnspecifiedRole, bool>;
595
596impl<'a, P> seal::Sealed
597    for PrimaryKeyAmalgamation<'a, P>
598    where P: 'a + key::KeyParts
599{}
600impl<'a, P> ValidateAmalgamation<'a, Key<P, key::PrimaryRole>>
601    for PrimaryKeyAmalgamation<'a, P>
602    where P: 'a + key::KeyParts
603{
604    type V = ValidPrimaryKeyAmalgamation<'a, P>;
605
606    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T)
607        -> Result<Self::V>
608        where T: Into<Option<time::SystemTime>>
609    {
610        let ka : ErasedKeyAmalgamation<P> = self.clone().into();
611        Ok(ka.with_policy(policy, time)?
612               .try_into().expect("conversion is symmetric"))
613    }
614}
615
616impl<'a, P> seal::Sealed
617    for SubordinateKeyAmalgamation<'a, P>
618    where P: 'a + key::KeyParts
619{}
620impl<'a, P> ValidateAmalgamation<'a, Key<P, key::SubordinateRole>>
621    for SubordinateKeyAmalgamation<'a, P>
622    where P: 'a + key::KeyParts
623{
624    type V = ValidSubordinateKeyAmalgamation<'a, P>;
625
626    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T)
627        -> Result<Self::V>
628        where T: Into<Option<time::SystemTime>>
629    {
630        let ka : ErasedKeyAmalgamation<P> = self.clone().into();
631        Ok(ka.with_policy(policy, time)?
632               .try_into().expect("conversion is symmetric"))
633    }
634}
635
636impl<'a, P> seal::Sealed
637    for ErasedKeyAmalgamation<'a, P>
638    where P: 'a + key::KeyParts
639{}
640impl<'a, P> ValidateAmalgamation<'a, Key<P, key::UnspecifiedRole>>
641    for ErasedKeyAmalgamation<'a, P>
642    where P: 'a + key::KeyParts
643{
644    type V = ValidErasedKeyAmalgamation<'a, P>;
645
646    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T)
647        -> Result<Self::V>
648        where T: Into<Option<time::SystemTime>>
649    {
650        let time = time.into().unwrap_or_else(crate::now);
651
652        // We need to make sure the certificate is okay.  This means
653        // checking the primary key.  But, be careful: we don't need
654        // to double-check.
655        if ! self.primary() {
656            let pka = PrimaryKeyAmalgamation::new(self.cert());
657            pka.with_policy(policy, time).context("primary key")?;
658        }
659
660        let binding_signature = self.binding_signature(policy, time)?;
661        let cert = self.ca.cert();
662        let vka = ValidErasedKeyAmalgamation {
663            ka: KeyAmalgamation {
664                ca: self.ca.clone().parts_into_public(),
665                primary: self.primary,
666            },
667            // We need some black magic to avoid infinite
668            // recursion: a ValidCert must be valid for the
669            // specified policy and reference time.  A ValidCert
670            // is considered valid if the primary key is valid.
671            // ValidCert::with_policy checks that by calling this
672            // function.  So, if we call ValidCert::with_policy
673            // here we'll recurse infinitely.
674            //
675            // But, hope is not lost!  We know that if we get
676            // here, we've already checked that the primary key is
677            // valid (see above), or that we're in the process of
678            // evaluating the primary key's validity and we just
679            // need to check the user's policy.  So, it is safe to
680            // create a ValidCert from scratch.
681            cert: ValidCert {
682                cert,
683                policy,
684                time,
685            },
686            binding_signature
687        };
688        policy.key(&vka)?;
689        Ok(ValidErasedKeyAmalgamation {
690            ka: KeyAmalgamation {
691                ca: P::convert_key_amalgamation(
692                    vka.ka.ca.parts_into_unspecified()).expect("roundtrip"),
693                primary: vka.ka.primary,
694            },
695            cert: vka.cert,
696            binding_signature,
697        })
698    }
699}
700
701impl<'a, P> PrimaryKey<'a, P, key::PrimaryRole>
702    for PrimaryKeyAmalgamation<'a, P>
703    where P: 'a + key::KeyParts
704{
705    fn primary(&self) -> bool {
706        true
707    }
708}
709
710impl<'a, P> PrimaryKey<'a, P, key::SubordinateRole>
711    for SubordinateKeyAmalgamation<'a, P>
712    where P: 'a + key::KeyParts
713{
714    fn primary(&self) -> bool {
715        false
716    }
717}
718
719impl<'a, P> PrimaryKey<'a, P, key::UnspecifiedRole>
720    for ErasedKeyAmalgamation<'a, P>
721    where P: 'a + key::KeyParts
722{
723    fn primary(&self) -> bool {
724        self.primary
725    }
726}
727
728
729impl<'a, P: 'a + key::KeyParts> From<PrimaryKeyAmalgamation<'a, P>>
730    for ErasedKeyAmalgamation<'a, P>
731{
732    fn from(ka: PrimaryKeyAmalgamation<'a, P>) -> Self {
733        ErasedKeyAmalgamation {
734            ca: ka.ca.role_into_unspecified(),
735            primary: true,
736        }
737    }
738}
739
740impl<'a, P: 'a + key::KeyParts> From<SubordinateKeyAmalgamation<'a, P>>
741    for ErasedKeyAmalgamation<'a, P>
742{
743    fn from(ka: SubordinateKeyAmalgamation<'a, P>) -> Self {
744        ErasedKeyAmalgamation {
745            ca: ka.ca.role_into_unspecified(),
746            primary: false,
747        }
748    }
749}
750
751
752// We can infallibly convert part X to part Y for everything but
753// Public -> Secret and Unspecified -> Secret.
754macro_rules! impl_conversion {
755    ($s:ident, $primary:expr, $p1:path, $p2:path) => {
756        impl<'a> From<$s<'a, $p1>>
757            for ErasedKeyAmalgamation<'a, $p2>
758        {
759            fn from(ka: $s<'a, $p1>) -> Self {
760                ErasedKeyAmalgamation {
761                    ca: ka.ca.into(),
762                    primary: $primary,
763                }
764            }
765        }
766    }
767}
768
769impl_conversion!(PrimaryKeyAmalgamation, true,
770                 key::SecretParts, key::PublicParts);
771impl_conversion!(PrimaryKeyAmalgamation, true,
772                 key::SecretParts, key::UnspecifiedParts);
773impl_conversion!(PrimaryKeyAmalgamation, true,
774                 key::PublicParts, key::UnspecifiedParts);
775impl_conversion!(PrimaryKeyAmalgamation, true,
776                 key::UnspecifiedParts, key::PublicParts);
777
778impl_conversion!(SubordinateKeyAmalgamation, false,
779                 key::SecretParts, key::PublicParts);
780impl_conversion!(SubordinateKeyAmalgamation, false,
781                 key::SecretParts, key::UnspecifiedParts);
782impl_conversion!(SubordinateKeyAmalgamation, false,
783                 key::PublicParts, key::UnspecifiedParts);
784impl_conversion!(SubordinateKeyAmalgamation, false,
785                 key::UnspecifiedParts, key::PublicParts);
786
787
788impl<'a, P, P2> TryFrom<ErasedKeyAmalgamation<'a, P>>
789    for PrimaryKeyAmalgamation<'a, P2>
790    where P: 'a + key::KeyParts,
791          P2: 'a + key::KeyParts,
792{
793    type Error = anyhow::Error;
794
795    fn try_from(ka: ErasedKeyAmalgamation<'a, P>) -> Result<Self> {
796        if ka.primary {
797            Ok(Self {
798                ca: P2::convert_key_amalgamation(
799                    ka.ca.role_into_primary().parts_into_unspecified())?,
800                primary: (),
801            })
802        } else {
803            Err(Error::InvalidArgument(
804                "can't convert a SubordinateKeyAmalgamation \
805                 to a PrimaryKeyAmalgamation".into()).into())
806        }
807    }
808}
809
810impl<'a, P, P2> TryFrom<ErasedKeyAmalgamation<'a, P>>
811    for SubordinateKeyAmalgamation<'a, P2>
812    where P: 'a + key::KeyParts,
813          P2: 'a + key::KeyParts,
814{
815    type Error = anyhow::Error;
816
817    fn try_from(ka: ErasedKeyAmalgamation<'a, P>) -> Result<Self> {
818        if ka.primary {
819            Err(Error::InvalidArgument(
820                "can't convert a PrimaryKeyAmalgamation \
821                 to a SubordinateKeyAmalgamation".into()).into())
822        } else {
823            Ok(Self {
824                ca: P2::convert_key_amalgamation(
825                    ka.ca.role_into_subordinate().parts_into_unspecified())?,
826                primary: (),
827            })
828        }
829    }
830}
831
832impl<'a> PrimaryKeyAmalgamation<'a, key::PublicParts> {
833    pub(crate) fn new(cert: &'a Cert) -> Self {
834        PrimaryKeyAmalgamation {
835            ca: ComponentAmalgamation::new(cert, &cert.primary),
836            primary: (),
837        }
838    }
839}
840
841impl<'a, P> PrimaryKeyAmalgamation<'a, P>
842where
843    P: key::KeyParts,
844{
845    /// Returns the active binding signature at time `t`.
846    ///
847    /// The active binding signature is the most recent, non-revoked
848    /// self-signature that is valid according to the `policy` and
849    /// alive at time `t` (`creation time <= t`, `t < expiry`).  If
850    /// there are multiple such signatures then the signatures are
851    /// ordered by their MPIs interpreted as byte strings.
852    ///
853    /// # Examples
854    ///
855    /// ```
856    /// # use sequoia_openpgp as openpgp;
857    /// # use openpgp::cert::prelude::*;
858    /// use openpgp::policy::StandardPolicy;
859    /// #
860    /// # fn main() -> openpgp::Result<()> {
861    /// let p = &StandardPolicy::new();
862    ///
863    /// # let (cert, _) =
864    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
865    /// #     .generate()?;
866    /// // Display information about the primary key's current active
867    /// // binding signature (the `time` parameter is `None`), if any.
868    /// eprintln!("{:?}", cert.primary_key().binding_signature(p, None));
869    /// # Ok(()) }
870    /// ```
871    pub fn binding_signature<T>(&self, policy: &dyn Policy, time: T)
872                                -> Result<&'a Signature>
873        where T: Into<Option<time::SystemTime>>
874    {
875        let time = time.into().unwrap_or_else(crate::now);
876        self.bundle().binding_signature(policy, time)
877    }
878}
879
880impl<'a, P: 'a + key::KeyParts> SubordinateKeyAmalgamation<'a, P> {
881    pub(crate) fn new(
882        cert: &'a Cert, bundle: &'a KeyBundle<P, key::SubordinateRole>)
883        -> Self
884    {
885        SubordinateKeyAmalgamation {
886            ca: ComponentAmalgamation::new(cert, bundle),
887            primary: (),
888        }
889    }
890
891    /// Returns the active binding signature at time `t`.
892    ///
893    /// The active binding signature is the most recent, non-revoked
894    /// self-signature that is valid according to the `policy` and
895    /// alive at time `t` (`creation time <= t`, `t < expiry`).  If
896    /// there are multiple such signatures then the signatures are
897    /// ordered by their MPIs interpreted as byte strings.
898    ///
899    /// # Examples
900    ///
901    /// ```
902    /// # use sequoia_openpgp as openpgp;
903    /// # use openpgp::cert::prelude::*;
904    /// use openpgp::policy::StandardPolicy;
905    /// #
906    /// # fn main() -> openpgp::Result<()> {
907    /// let p = &StandardPolicy::new();
908    ///
909    /// # let (cert, _) =
910    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
911    /// #     .generate()?;
912    /// // Display information about each keys' current active
913    /// // binding signature (the `time` parameter is `None`), if any.
914    /// for k in cert.keys().subkeys() {
915    ///     eprintln!("{:?}", k.binding_signature(p, None));
916    /// }
917    /// # Ok(()) }
918    /// ```
919    pub fn binding_signature<T>(&self, policy: &dyn Policy, time: T)
920                                -> Result<&'a Signature>
921        where T: Into<Option<time::SystemTime>>
922    {
923        let time = time.into().unwrap_or_else(crate::now);
924        self.bundle().binding_signature(policy, time)
925    }
926}
927
928impl<'a, P: 'a + key::KeyParts> ErasedKeyAmalgamation<'a, P> {
929    /// Returns the key's binding signature as of the reference time,
930    /// if any.
931    ///
932    /// Note: this function is not exported.  Users of this interface
933    /// should instead do: `ka.with_policy(policy,
934    /// time)?.binding_signature()`.
935    fn binding_signature<T>(&self, policy: &'a dyn Policy, time: T)
936        -> Result<&'a Signature>
937        where T: Into<Option<time::SystemTime>>
938    {
939        let time = time.into().unwrap_or_else(crate::now);
940        if self.primary {
941            self.cert().primary_userid_relaxed(policy, time, false)
942                .map(|u| u.binding_signature())
943                .or_else(|e0| {
944                    // Lookup of the primary user id binding failed.
945                    // Look for direct key signatures.
946                    self.cert().primary_key().bundle()
947                        .binding_signature(policy, time)
948                        .map_err(|e1| {
949                            // Both lookups failed.  Keep the more
950                            // meaningful error.
951                            if let Some(Error::NoBindingSignature(_))
952                                = e1.downcast_ref()
953                            {
954                                e0 // Return the original error.
955                            } else {
956                                e1
957                            }
958                        })
959                })
960        } else {
961            self.bundle().binding_signature(policy, time)
962        }
963    }
964}
965
966
967impl<'a, P, R, R2> KeyAmalgamation<'a, P, R, R2>
968    where P: 'a + key::KeyParts,
969          R: 'a + key::KeyRole,
970
971{
972    /// Returns the component's associated certificate.
973    ///
974    /// ```
975    /// # use sequoia_openpgp as openpgp;
976    /// # use openpgp::cert::prelude::*;
977    /// #
978    /// # fn main() -> openpgp::Result<()> {
979    /// # let (cert, _) =
980    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
981    /// #     .generate()?;
982    /// for k in cert.keys() {
983    ///     // It's not only an identical `Cert`, it's the same one.
984    ///     assert!(std::ptr::eq(k.cert(), &cert));
985    /// }
986    /// # Ok(()) }
987    /// ```
988    pub fn cert(&self) -> &'a Cert {
989        self.ca.cert()
990    }
991
992    /// Returns this amalgamation's bundle.
993    pub fn bundle(&self) -> &'a crate::cert::ComponentBundle<Key<P, R>> {
994        self.ca.bundle()
995    }
996
997    /// Returns this amalgamation's component.
998    ///
999    /// # Examples
1000    ///
1001    /// ```
1002    /// # use sequoia_openpgp as openpgp;
1003    /// # use openpgp::cert::prelude::*;
1004    /// #
1005    /// # fn main() -> openpgp::Result<()> {
1006    /// # let (cert, _) =
1007    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1008    /// #     .generate()?;
1009    /// // Display some information about any unknown components.
1010    /// for k in cert.keys() {
1011    ///     eprintln!(" - {:?}", k.component());
1012    /// }
1013    /// # Ok(()) }
1014    /// ```
1015    pub fn component(&self) -> &'a Key<P, R> {
1016        self.bundle().component()
1017    }
1018
1019    /// Returns the `KeyAmalgamation`'s key.
1020    pub fn key(&self) -> &'a Key<P, R> {
1021        self.component()
1022    }
1023
1024    /// Returns the component's self-signatures.
1025    ///
1026    /// The signatures are validated, and they are sorted by their
1027    /// creation time, most recent first.
1028    ///
1029    /// # Examples
1030    ///
1031    /// ```
1032    /// # use sequoia_openpgp as openpgp;
1033    /// # use openpgp::cert::prelude::*;
1034    /// #
1035    /// # fn main() -> openpgp::Result<()> {
1036    /// # let (cert, _) =
1037    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1038    /// #     .generate()?;
1039    /// for (i, ka) in cert.keys().enumerate() {
1040    ///     eprintln!("Key #{} ({}) has {:?} self signatures",
1041    ///               i, ka.key().fingerprint(),
1042    ///               ka.self_signatures().count());
1043    /// }
1044    /// # Ok(()) }
1045    /// ```
1046    pub fn self_signatures(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1047        self.ca.self_signatures()
1048    }
1049
1050    /// Returns the component's third-party certifications.
1051    ///
1052    /// The signatures are *not* validated.  They are sorted by their
1053    /// creation time, most recent first.
1054    ///
1055    /// # Examples
1056    ///
1057    /// ```
1058    /// # use sequoia_openpgp as openpgp;
1059    /// # use openpgp::cert::prelude::*;
1060    /// #
1061    /// # fn main() -> openpgp::Result<()> {
1062    /// # let (cert, _) =
1063    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1064    /// #     .generate()?;
1065    /// for k in cert.keys() {
1066    ///     eprintln!("Key {} has {:?} unverified, third-party certifications",
1067    ///               k.key().fingerprint(),
1068    ///               k.certifications().count());
1069    /// }
1070    /// # Ok(()) }
1071    /// ```
1072    pub fn certifications(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1073        self.ca.certifications()
1074    }
1075
1076    /// Returns the component's revocations that were issued by the
1077    /// certificate holder.
1078    ///
1079    /// The revocations are validated, and they are sorted by their
1080    /// creation time, most recent first.
1081    ///
1082    /// # Examples
1083    ///
1084    /// ```
1085    /// # use sequoia_openpgp as openpgp;
1086    /// # use openpgp::cert::prelude::*;
1087    /// use openpgp::policy::StandardPolicy;
1088    /// #
1089    /// # fn main() -> openpgp::Result<()> {
1090    /// let p = &StandardPolicy::new();
1091    ///
1092    /// # let (cert, _) =
1093    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1094    /// #     .generate()?;
1095    /// for k in cert.keys() {
1096    ///     eprintln!("Key {} has {:?} revocation certificates.",
1097    ///               k.key().fingerprint(),
1098    ///               k.self_revocations().count());
1099    /// }
1100    /// # Ok(()) }
1101    /// ```
1102    pub fn self_revocations(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1103        self.ca.self_revocations()
1104    }
1105
1106    /// Returns the component's revocations that were issued by other
1107    /// certificates.
1108    ///
1109    /// The revocations are *not* validated.  They are sorted by their
1110    /// creation time, most recent first.
1111    ///
1112    /// # Examples
1113    ///
1114    /// ```
1115    /// # use sequoia_openpgp as openpgp;
1116    /// # use openpgp::cert::prelude::*;
1117    /// use openpgp::policy::StandardPolicy;
1118    /// #
1119    /// # fn main() -> openpgp::Result<()> {
1120    /// let p = &StandardPolicy::new();
1121    ///
1122    /// # let (cert, _) =
1123    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1124    /// #     .generate()?;
1125    /// for k in cert.keys() {
1126    ///     eprintln!("Key {} has {:?} unverified, third-party revocation certificates.",
1127    ///               k.key().fingerprint(),
1128    ///               k.other_revocations().count());
1129    /// }
1130    /// # Ok(()) }
1131    /// ```
1132    pub fn other_revocations(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1133        self.ca.other_revocations()
1134    }
1135
1136    /// Returns all of the component's signatures.
1137    ///
1138    /// Only the self-signatures are validated.  The signatures are
1139    /// sorted first by type, then by creation time.  The self
1140    /// revocations come first, then the self signatures,
1141    /// then any certification approval key signatures,
1142    /// certifications, and third-party revocations coming last.  This
1143    /// function may return additional types of signatures that could
1144    /// be associated to this component.
1145    ///
1146    /// # Examples
1147    ///
1148    /// ```
1149    /// # use sequoia_openpgp as openpgp;
1150    /// # use openpgp::cert::prelude::*;
1151    /// use openpgp::policy::StandardPolicy;
1152    /// #
1153    /// # fn main() -> openpgp::Result<()> {
1154    /// let p = &StandardPolicy::new();
1155    ///
1156    /// # let (cert, _) =
1157    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1158    /// #     .generate()?;
1159    /// for (i, ka) in cert.keys().enumerate() {
1160    ///     eprintln!("Key #{} ({}) has {:?} signatures",
1161    ///               i, ka.key().fingerprint(),
1162    ///               ka.signatures().count());
1163    /// }
1164    /// # Ok(()) }
1165    /// ```
1166    pub fn signatures(&self)
1167                      -> impl Iterator<Item = &'a Signature> + Send + Sync {
1168        self.ca.signatures()
1169    }
1170
1171    /// Forwarder for the conversion macros.
1172    pub(crate) fn has_secret(&self) -> bool {
1173        self.key().has_secret()
1174    }
1175}
1176
1177impl<'a, P, R, R2> KeyAmalgamation<'a, P, R, R2>
1178    where Self: PrimaryKey<'a, P, R>,
1179          P: 'a + key::KeyParts,
1180          R: 'a + key::KeyRole,
1181{
1182    /// Returns the third-party certifications issued by the specified
1183    /// key, and valid at the specified time.
1184    ///
1185    /// This function returns the certifications issued by the
1186    /// specified key.  Specifically, it returns a certification if:
1187    ///
1188    ///   - it is well-formed,
1189    ///   - it is live with respect to the reference time,
1190    ///   - it conforms to the policy, and
1191    ///   - the signature is cryptographically valid.
1192    ///
1193    /// This method is implemented on a [`KeyAmalgamation`] and not
1194    /// a [`ValidKeyAmalgamation`], because a third-party
1195    /// certification does not require the key to be self-signed.
1196    ///
1197    /// # Examples
1198    ///
1199    /// Alice has certified that a certificate belongs to Bob on two
1200    /// occasions.  Whereas
1201    /// [`KeyAmalgamation::valid_certifications_by_key`] returns
1202    /// both certifications,
1203    /// [`KeyAmalgamation::active_certifications_by_key`] only
1204    /// returns the most recent certification.
1205    ///
1206    /// ```rust
1207    /// use sequoia_openpgp as openpgp;
1208    /// use openpgp::cert::prelude::*;
1209    /// # use openpgp::packet::signature::SignatureBuilder;
1210    /// # use openpgp::packet::UserID;
1211    /// use openpgp::policy::StandardPolicy;
1212    /// # use openpgp::types::SignatureType;
1213    ///
1214    /// const P: &StandardPolicy = &StandardPolicy::new();
1215    ///
1216    /// # fn main() -> openpgp::Result<()> {
1217    /// # let epoch = std::time::SystemTime::now()
1218    /// #     - std::time::Duration::new(100, 0);
1219    /// # let t0 = epoch;
1220    /// #
1221    /// # let (alice, _) = CertBuilder::new()
1222    /// #     .set_creation_time(t0)
1223    /// #     .add_userid("<alice@example.org>")
1224    /// #     .generate()
1225    /// #     .unwrap();
1226    /// let alice: Cert = // ...
1227    /// # alice;
1228    /// #
1229    /// # let bob_userid = "<bob@example.org>";
1230    /// # let (bob, _) = CertBuilder::new()
1231    /// #     .set_creation_time(t0)
1232    /// #     .add_userid(bob_userid)
1233    /// #     .generate()
1234    /// #     .unwrap();
1235    /// let bob: Cert = // ...
1236    /// # bob;
1237    ///
1238    /// # // Alice has not certified Bob's User ID.
1239    /// # let ka = bob.primary_key();
1240    /// # assert_eq!(
1241    /// #     ka.active_certifications_by_key(
1242    /// #         P, t0, alice.primary_key().key()).count(),
1243    /// #     0);
1244    /// #
1245    /// # // Have Alice certify Bob's certificate.
1246    /// # let mut alice_signer = alice
1247    /// #     .keys()
1248    /// #     .with_policy(P, None)
1249    /// #     .for_certification()
1250    /// #     .next().expect("have a certification-capable key")
1251    /// #     .key()
1252    /// #     .clone()
1253    /// #     .parts_into_secret().expect("have unencrypted key material")
1254    /// #     .into_keypair().expect("have unencrypted key material");
1255    /// #
1256    /// # let mut bob = bob;
1257    /// # for i in 1..=2usize {
1258    /// #     let ti = t0 + std::time::Duration::new(i as u64, 0);
1259    /// #
1260    /// #     let certification = SignatureBuilder::new(SignatureType::DirectKey)
1261    /// #         .set_signature_creation_time(ti)?
1262    /// #         .sign_direct_key(
1263    /// #             &mut alice_signer,
1264    /// #             bob.primary_key().key())?;
1265    /// #     bob = bob.insert_packets(certification)?.0;
1266    /// #
1267    /// #     let ka = bob.primary_key();
1268    /// #     assert_eq!(
1269    /// #         ka.valid_certifications_by_key(
1270    /// #             P, ti, alice.primary_key().key()).count(),
1271    /// #         i);
1272    /// #
1273    /// #     assert_eq!(
1274    /// #         ka.active_certifications_by_key(
1275    /// #             P, ti, alice.primary_key().key()).count(),
1276    /// #         1);
1277    /// # }
1278    /// let bob_pk = bob.primary_key();
1279    ///
1280    /// let valid_certifications = bob_pk.valid_certifications_by_key(
1281    ///     P, None, alice.primary_key().key());
1282    /// // Alice certified Bob's certificate twice.
1283    /// assert_eq!(valid_certifications.count(), 2);
1284    ///
1285    /// let active_certifications = bob_pk.active_certifications_by_key(
1286    ///     P, None, alice.primary_key().key());
1287    /// // But only the most recent one is active.
1288    /// assert_eq!(active_certifications.count(), 1);
1289    /// # Ok(()) }
1290    /// ```
1291    pub fn valid_certifications_by_key<T, PK>(&self,
1292                                              policy: &'a dyn Policy,
1293                                              reference_time: T,
1294                                              issuer: PK)
1295        -> impl Iterator<Item=&Signature> + Send + Sync
1296    where
1297        T: Into<Option<time::SystemTime>>,
1298        PK: Into<&'a Key<key::PublicParts,
1299                         key::UnspecifiedRole>>,
1300    {
1301        let reference_time = reference_time.into();
1302        let issuer = issuer.into();
1303
1304        let primary = self.primary();
1305
1306        self.ca.valid_certifications_by_key_(
1307            policy, reference_time, issuer, false,
1308            self.certifications(),
1309            move |sig| {
1310                if primary {
1311                    sig.clone().verify_direct_key(
1312                        issuer,
1313                        self.component().role_as_primary())
1314                } else {
1315                    sig.clone().verify_subkey_binding(
1316                        issuer,
1317                        self.cert().primary_key().key(),
1318                        self.component().role_as_subordinate())
1319                }
1320            })
1321    }
1322
1323    /// Returns any active third-party certifications issued by the
1324    /// specified key.
1325    ///
1326    /// This function is like
1327    /// [`KeyAmalgamation::valid_certifications_by_key`], but it
1328    /// only returns active certifications.  Active certifications are
1329    /// the most recent valid certifications with respect to the
1330    /// reference time.
1331    ///
1332    /// Although there is normally only a single active certification,
1333    /// there can be multiple certifications with the same timestamp.
1334    /// In this case, all of them are returned.
1335    ///
1336    /// Unlike self-signatures, multiple third-party certifications
1337    /// issued by the same key at the same time can be sensible.  For
1338    /// instance, Alice may fully trust a CA for user IDs in a
1339    /// particular domain, and partially trust it for everything else.
1340    /// This can only be expressed using multiple certifications.
1341    ///
1342    /// This method is implemented on a [`KeyAmalgamation`] and not
1343    /// a [`ValidKeyAmalgamation`], because a third-party
1344    /// certification does not require the user ID to be self-signed.
1345    ///
1346    /// # Examples
1347    ///
1348    /// See the examples for
1349    /// [`KeyAmalgamation::valid_certifications_by_key`].
1350    pub fn active_certifications_by_key<T, PK>(&self,
1351                                               policy: &'a dyn Policy,
1352                                               reference_time: T,
1353                                               issuer: PK)
1354        -> impl Iterator<Item=&Signature> + Send + Sync
1355    where
1356        T: Into<Option<time::SystemTime>>,
1357        PK: Into<&'a Key<key::PublicParts,
1358                         key::UnspecifiedRole>>,
1359    {
1360        let reference_time = reference_time.into();
1361        let issuer = issuer.into();
1362
1363        let primary = self.primary();
1364
1365        self.ca.valid_certifications_by_key_(
1366            policy, reference_time, issuer, true,
1367            self.certifications(),
1368            move |sig| {
1369                if primary {
1370                    sig.clone().verify_direct_key(
1371                        issuer,
1372                        self.component().role_as_primary())
1373                } else {
1374                    sig.clone().verify_subkey_binding(
1375                        issuer,
1376                        self.cert().primary_key().key(),
1377                        &self.component().role_as_subordinate())
1378                }
1379            })
1380    }
1381
1382    /// Returns the third-party revocations issued by the specified
1383    /// key, and valid at the specified time.
1384    ///
1385    /// This function returns the revocations issued by the specified
1386    /// key.  Specifically, it returns a revocation if:
1387    ///
1388    ///   - it is well-formed,
1389    ///   - it is a [hard revocation](crate::types::RevocationType),
1390    ///     or it is live with respect to the reference time,
1391    ///   - it conforms to the policy, and
1392    ///   - the signature is cryptographically valid.
1393    ///
1394    /// This method is implemented on a [`KeyAmalgamation`] and not
1395    /// a [`ValidKeyAmalgamation`], because a third-party
1396    /// revocation does not require the key to be self-signed.
1397    ///
1398    /// # Examples
1399    ///
1400    /// Alice revoked Bob's certificate.
1401    ///
1402    /// ```rust
1403    /// use sequoia_openpgp as openpgp;
1404    /// use openpgp::cert::prelude::*;
1405    /// # use openpgp::Packet;
1406    /// # use openpgp::packet::signature::SignatureBuilder;
1407    /// # use openpgp::packet::UserID;
1408    /// use openpgp::policy::StandardPolicy;
1409    /// # use openpgp::types::ReasonForRevocation;
1410    /// # use openpgp::types::SignatureType;
1411    ///
1412    /// const P: &StandardPolicy = &StandardPolicy::new();
1413    ///
1414    /// # fn main() -> openpgp::Result<()> {
1415    /// # let epoch = std::time::SystemTime::now()
1416    /// #     - std::time::Duration::new(100, 0);
1417    /// # let t0 = epoch;
1418    /// # let t1 = epoch + std::time::Duration::new(1, 0);
1419    /// #
1420    /// # let (alice, _) = CertBuilder::new()
1421    /// #     .set_creation_time(t0)
1422    /// #     .add_userid("<alice@example.org>")
1423    /// #     .generate()
1424    /// #     .unwrap();
1425    /// let alice: Cert = // ...
1426    /// # alice;
1427    /// #
1428    /// # let bob_userid = "<bob@example.org>";
1429    /// # let (bob, _) = CertBuilder::new()
1430    /// #     .set_creation_time(t0)
1431    /// #     .add_userid(bob_userid)
1432    /// #     .generate()
1433    /// #     .unwrap();
1434    /// let bob: Cert = // ...
1435    /// # bob;
1436    ///
1437    /// # // Have Alice certify Bob's certificate.
1438    /// # let mut alice_signer = alice
1439    /// #     .keys()
1440    /// #     .with_policy(P, None)
1441    /// #     .for_certification()
1442    /// #     .next().expect("have a certification-capable key")
1443    /// #     .key()
1444    /// #     .clone()
1445    /// #     .parts_into_secret().expect("have unencrypted key material")
1446    /// #     .into_keypair().expect("have unencrypted key material");
1447    /// #
1448    /// # let certification = SignatureBuilder::new(SignatureType::KeyRevocation)
1449    /// #     .set_signature_creation_time(t1)?
1450    /// #     .set_reason_for_revocation(
1451    /// #         ReasonForRevocation::KeyRetired, b"")?
1452    /// #     .sign_direct_key(
1453    /// #         &mut alice_signer,
1454    /// #         bob.primary_key().key())?;
1455    /// # let bob = bob.insert_packets(certification)?.0;
1456    /// let ka = bob.primary_key();
1457    ///
1458    /// let revs = ka.valid_third_party_revocations_by_key(
1459    ///     P, None, alice.primary_key().key());
1460    /// // Alice revoked Bob's certificate.
1461    /// assert_eq!(revs.count(), 1);
1462    /// # Ok(()) }
1463    /// ```
1464    pub fn valid_third_party_revocations_by_key<T, PK>(&self,
1465                                                       policy: &'a dyn Policy,
1466                                                       reference_time: T,
1467                                                       issuer: PK)
1468        -> impl Iterator<Item=&Signature> + Send + Sync
1469    where
1470        T: Into<Option<time::SystemTime>>,
1471        PK: Into<&'a Key<key::PublicParts,
1472                         key::UnspecifiedRole>>,
1473    {
1474        let issuer = issuer.into();
1475        let reference_time = reference_time.into();
1476
1477        let primary = self.primary();
1478
1479        self.ca.valid_certifications_by_key_(
1480            policy, reference_time, issuer, false,
1481            self.other_revocations(),
1482            move |sig| {
1483                if primary {
1484                    sig.clone().verify_primary_key_revocation(
1485                        issuer,
1486                        self.component().role_as_primary())
1487                } else {
1488                    sig.clone().verify_subkey_revocation(
1489                        issuer,
1490                        self.cert().primary_key().key(),
1491                        &self.component().role_as_subordinate())
1492                }
1493            })
1494    }
1495}
1496
1497/// A `KeyAmalgamation` plus a `Policy` and a reference time.
1498///
1499/// In the same way that a [`ValidComponentAmalgamation`] extends a
1500/// [`ComponentAmalgamation`], a `ValidKeyAmalgamation` extends a
1501/// [`KeyAmalgamation`]: a `ValidKeyAmalgamation` combines a
1502/// `KeyAmalgamation`, a [`Policy`], and a reference time.  This
1503/// allows it to implement the [`ValidAmalgamation`] trait, which
1504/// provides methods like [`ValidAmalgamation::binding_signature`] that require a
1505/// `Policy` and a reference time.  Although `KeyAmalgamation` could
1506/// implement these methods by requiring that the caller explicitly
1507/// pass them in, embedding them in the `ValidKeyAmalgamation` helps
1508/// ensure that multipart operations, even those that span multiple
1509/// functions, use the same `Policy` and reference time.
1510///
1511/// A `ValidKeyAmalgamation` can be obtained by transforming a
1512/// `KeyAmalgamation` using [`ValidateAmalgamation::with_policy`].  A
1513/// [`KeyAmalgamationIter`] can also be changed to yield
1514/// `ValidKeyAmalgamation`s.
1515///
1516/// A `ValidKeyAmalgamation` is guaranteed to come from a valid
1517/// certificate, and have a valid and live *binding* signature at the
1518/// specified reference time.  Note: this only means that the binding
1519/// signatures are live; it says nothing about whether the
1520/// *certificate* or the *`Key`* is live and non-revoked.  If you care
1521/// about those things, you need to check them separately.
1522///
1523/// # Examples:
1524///
1525/// Find all non-revoked, live, signing-capable keys:
1526///
1527/// ```
1528/// # use sequoia_openpgp as openpgp;
1529/// # use openpgp::cert::prelude::*;
1530/// use openpgp::policy::StandardPolicy;
1531/// use openpgp::types::RevocationStatus;
1532///
1533/// # fn main() -> openpgp::Result<()> {
1534/// let p = &StandardPolicy::new();
1535///
1536/// # let (cert, _) = CertBuilder::new()
1537/// #     .add_userid("Alice")
1538/// #     .add_signing_subkey()
1539/// #     .add_transport_encryption_subkey()
1540/// #     .generate().unwrap();
1541/// // `with_policy` ensures that the certificate and any components
1542/// // that it returns have valid *binding signatures*.  But, we still
1543/// // need to check that the certificate and `Key` are not revoked,
1544/// // and live.
1545/// //
1546/// // Note: `ValidKeyAmalgamation::revocation_status`, etc. use the
1547/// // embedded policy and timestamp.  Even though we used `None` for
1548/// // the timestamp (i.e., now), they are guaranteed to use the same
1549/// // timestamp, because `with_policy` eagerly transforms it into
1550/// // the current time.
1551/// let cert = cert.with_policy(p, None)?;
1552/// if let RevocationStatus::Revoked(_revs) = cert.revocation_status() {
1553///     // Revoked by the certificate holder.  (If we care about
1554///     // designated revokers, then we need to check those
1555///     // ourselves.)
1556/// #   unreachable!();
1557/// } else if let Err(_err) = cert.alive() {
1558///     // Certificate was created in the future or is expired.
1559/// #   unreachable!();
1560/// } else {
1561///     // `ValidCert::keys` returns `ValidKeyAmalgamation`s.
1562///     for ka in cert.keys() {
1563///         if let RevocationStatus::Revoked(_revs) = ka.revocation_status() {
1564///             // Revoked by the key owner.  (If we care about
1565///             // designated revokers, then we need to check those
1566///             // ourselves.)
1567/// #           unreachable!();
1568///         } else if let Err(_err) = ka.alive() {
1569///             // Key was created in the future or is expired.
1570/// #           unreachable!();
1571///         } else if ! ka.for_signing() {
1572///             // We're looking for a signing-capable key, skip this one.
1573///         } else {
1574///             // Use it!
1575///         }
1576///     }
1577/// }
1578/// # Ok(()) }
1579/// ```
1580///
1581/// [`ValidComponentAmalgamation`]: super::ValidComponentAmalgamation
1582/// [`ComponentAmalgamation`]: super::ComponentAmalgamation
1583/// [`Policy`]: crate::policy::Policy
1584/// [`ValidAmalgamation`]: super::ValidAmalgamation
1585/// [`ValidAmalgamation::binding_signature`]: super::ValidAmalgamation::binding_signature()
1586/// [`ValidateAmalgamation::with_policy`]: super::ValidateAmalgamation::with_policy
1587#[derive(Debug, Clone)]
1588pub struct ValidKeyAmalgamation<'a, P, R, R2>
1589    where P: 'a + key::KeyParts,
1590          R: 'a + key::KeyRole,
1591          R2: Copy,
1592{
1593    // Ouch, ouch, ouch!  ka is a `KeyAmalgamation`, which contains a
1594    // reference to a `Cert`.  `cert` is a `ValidCert` and contains a
1595    // reference to the same `Cert`!  We do this so that
1596    // `ValidKeyAmalgamation` can deref to a `KeyAmalgamation` and
1597    // `ValidKeyAmalgamation::cert` can return a `&ValidCert`.
1598
1599    ka: KeyAmalgamation<'a, P, R, R2>,
1600    cert: ValidCert<'a>,
1601
1602    // The binding signature at time `time`.  (This is just a cache.)
1603    binding_signature: &'a Signature,
1604}
1605assert_send_and_sync!(ValidKeyAmalgamation<'_, P, R, R2>
1606    where P: key::KeyParts,
1607          R: key::KeyRole,
1608          R2: Copy,
1609);
1610
1611
1612impl<'a, P, R, R2> ValidKeyAmalgamation<'a, P, R, R2>
1613where
1614    P: 'a + key::KeyParts,
1615    R: 'a + key::KeyRole,
1616    R2: Copy,
1617{
1618    /// Returns the component's associated certificate.
1619    ///
1620    /// ```
1621    /// # use sequoia_openpgp as openpgp;
1622    /// # use openpgp::cert::prelude::*;
1623    /// use openpgp::policy::StandardPolicy;
1624    /// #
1625    /// # fn main() -> openpgp::Result<()> {
1626    /// let p = &StandardPolicy::new();
1627    ///
1628    /// # let (cert, _) =
1629    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1630    /// #     .generate()?;
1631    /// for k in cert.with_policy(p, None)?.keys() {
1632    ///     // It's not only an identical `Cert`, it's the same one.
1633    ///     assert!(std::ptr::eq(k.cert(), &cert));
1634    /// }
1635    /// # Ok(()) }
1636    /// ```
1637    pub fn cert(&self) -> &'a Cert {
1638        self.ka.cert()
1639    }
1640
1641    /// Returns the valid amalgamation's active binding signature.
1642    ///
1643    /// The active binding signature is the most recent, non-revoked
1644    /// self-signature that is valid according to the `policy` and
1645    /// alive at time `t` (`creation time <= t`, `t < expiry`).  If
1646    /// there are multiple such signatures then the signatures are
1647    /// ordered by their MPIs interpreted as byte strings.
1648    ///
1649    /// # Examples
1650    ///
1651    /// ```
1652    /// # use sequoia_openpgp as openpgp;
1653    /// # use openpgp::cert::prelude::*;
1654    /// use openpgp::policy::StandardPolicy;
1655    /// #
1656    /// # fn main() -> openpgp::Result<()> {
1657    /// let p = &StandardPolicy::new();
1658    ///
1659    /// # let (cert, _) =
1660    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1661    /// #     .generate()?;
1662    /// // Display information about each User ID's current active
1663    /// // binding signature (the `time` parameter is `None`), if any.
1664    /// for ua in cert.with_policy(p, None)?.userids() {
1665    ///     eprintln!("{:?}", ua.binding_signature());
1666    /// }
1667    /// # Ok(()) }
1668    /// ```
1669    pub fn binding_signature(&self) -> &'a Signature {
1670        self.binding_signature
1671    }
1672
1673    /// Returns the valid amalgamation's amalgamation.
1674    ///
1675    /// # Examples
1676    ///
1677    /// ```
1678    /// # use sequoia_openpgp as openpgp;
1679    /// # use openpgp::cert::prelude::*;
1680    /// use openpgp::policy::StandardPolicy;
1681    ///
1682    /// # fn main() -> openpgp::Result<()> {
1683    /// let p = &StandardPolicy::new();
1684    ///
1685    /// # let (cert, _) = CertBuilder::new()
1686    /// #     .add_userid("Alice")
1687    /// #     .add_signing_subkey()
1688    /// #     .add_transport_encryption_subkey()
1689    /// #     .generate()?;
1690    /// // Get a key amalgamation.
1691    /// let ka = cert.primary_key();
1692    ///
1693    /// // Validate it, yielding a valid key amalgamation.
1694    /// let vka = ka.with_policy(p, None)?;
1695    ///
1696    /// // And here we get the amalgamation back.
1697    /// let ka2 = vka.amalgamation();
1698    /// assert_eq!(&ka, ka2);
1699    /// # Ok(()) }
1700    /// ```
1701    pub fn amalgamation(&self) -> &KeyAmalgamation<'a, P, R, R2> {
1702        &self.ka
1703    }
1704
1705    /// Returns this amalgamation's bundle.
1706    pub fn bundle(&self) -> &'a crate::cert::ComponentBundle<Key<P, R>> {
1707        self.ka.bundle()
1708    }
1709
1710    /// Returns this amalgamation's component.
1711    ///
1712    /// # Examples
1713    ///
1714    /// ```
1715    /// # use sequoia_openpgp as openpgp;
1716    /// # use openpgp::cert::prelude::*;
1717    /// use openpgp::policy::StandardPolicy;
1718    /// #
1719    /// # fn main() -> openpgp::Result<()> {
1720    /// let p = &StandardPolicy::new();
1721    ///
1722    /// # let (cert, _) =
1723    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1724    /// #     .generate()?;
1725    /// // Display some information about any unknown components.
1726    /// for k in cert.with_policy(p, None)?.keys() {
1727    ///     eprintln!(" - {:?}", k.component());
1728    /// }
1729    /// # Ok(()) }
1730    /// ```
1731    pub fn component(&self) -> &'a Key<P, R> {
1732        self.bundle().component()
1733    }
1734
1735    /// Returns the `KeyAmalgamation`'s key.
1736    pub fn key(&self) -> &'a Key<P, R> {
1737        self.component()
1738    }
1739
1740    /// Returns the component's self-signatures.
1741    ///
1742    /// The signatures are validated, and they are sorted by their
1743    /// creation time, most recent first.
1744    ///
1745    /// # Examples
1746    ///
1747    /// ```
1748    /// # use sequoia_openpgp as openpgp;
1749    /// # use openpgp::cert::prelude::*;
1750    /// use openpgp::policy::StandardPolicy;
1751    /// #
1752    /// # fn main() -> openpgp::Result<()> {
1753    /// let p = &StandardPolicy::new();
1754    ///
1755    /// # let (cert, _) =
1756    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1757    /// #     .generate()?;
1758    /// for (i, ka) in cert.with_policy(p, None)?.keys().enumerate() {
1759    ///     eprintln!("Key #{} ({}) has {:?} self signatures",
1760    ///               i, ka.key().fingerprint(),
1761    ///               ka.self_signatures().count());
1762    /// }
1763    /// # Ok(()) }
1764    /// ```
1765    pub fn self_signatures(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1766        self.ka.self_signatures()
1767    }
1768
1769    /// Returns the component's third-party certifications.
1770    ///
1771    /// The signatures are *not* validated.  They are sorted by their
1772    /// creation time, most recent first.
1773    ///
1774    /// # Examples
1775    ///
1776    /// ```
1777    /// # use sequoia_openpgp as openpgp;
1778    /// # use openpgp::cert::prelude::*;
1779    /// use openpgp::policy::StandardPolicy;
1780    /// #
1781    /// # fn main() -> openpgp::Result<()> {
1782    /// let p = &StandardPolicy::new();
1783    ///
1784    /// # let (cert, _) =
1785    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1786    /// #     .generate()?;
1787    /// for k in cert.with_policy(p, None)?.keys() {
1788    ///     eprintln!("Key {} has {:?} unverified, third-party certifications",
1789    ///               k.key().fingerprint(),
1790    ///               k.certifications().count());
1791    /// }
1792    /// # Ok(()) }
1793    /// ```
1794    pub fn certifications(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1795        self.ka.certifications()
1796    }
1797
1798    /// Returns the component's revocations that were issued by the
1799    /// certificate holder.
1800    ///
1801    /// The revocations are validated, and they are sorted by their
1802    /// creation time, most recent first.
1803    ///
1804    /// # Examples
1805    ///
1806    /// ```
1807    /// # use sequoia_openpgp as openpgp;
1808    /// # use openpgp::cert::prelude::*;
1809    /// use openpgp::policy::StandardPolicy;
1810    /// #
1811    /// # fn main() -> openpgp::Result<()> {
1812    /// let p = &StandardPolicy::new();
1813    ///
1814    /// # let (cert, _) =
1815    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1816    /// #     .generate()?;
1817    /// for k in cert.with_policy(p, None)?.keys() {
1818    ///     eprintln!("Key {} has {:?} revocation certificates.",
1819    ///               k.key().fingerprint(),
1820    ///               k.self_revocations().count());
1821    /// }
1822    /// # Ok(()) }
1823    /// ```
1824    pub fn self_revocations(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1825        self.ka.self_revocations()
1826    }
1827
1828    /// Returns the component's revocations that were issued by other
1829    /// certificates.
1830    ///
1831    /// The revocations are *not* validated.  They are sorted by their
1832    /// creation time, most recent first.
1833    ///
1834    /// # Examples
1835    ///
1836    /// ```
1837    /// # use sequoia_openpgp as openpgp;
1838    /// # use openpgp::cert::prelude::*;
1839    /// use openpgp::policy::StandardPolicy;
1840    /// #
1841    /// # fn main() -> openpgp::Result<()> {
1842    /// let p = &StandardPolicy::new();
1843    ///
1844    /// # let (cert, _) =
1845    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1846    /// #     .generate()?;
1847    /// for k in cert.with_policy(p, None)?.keys() {
1848    ///     eprintln!("Key {} has {:?} unverified, third-party revocation certificates.",
1849    ///               k.key().fingerprint(),
1850    ///               k.other_revocations().count());
1851    /// }
1852    /// # Ok(()) }
1853    /// ```
1854    pub fn other_revocations(&self) -> impl Iterator<Item=&'a Signature> + Send + Sync {
1855        self.ka.other_revocations()
1856    }
1857
1858    /// Returns all of the component's signatures.
1859    ///
1860    /// Only the self-signatures are validated.  The signatures are
1861    /// sorted first by type, then by creation time.  The self
1862    /// revocations come first, then the self signatures,
1863    /// then any certification approval key signatures,
1864    /// certifications, and third-party revocations coming last.  This
1865    /// function may return additional types of signatures that could
1866    /// be associated to this component.
1867    ///
1868    /// # Examples
1869    ///
1870    /// ```
1871    /// # use sequoia_openpgp as openpgp;
1872    /// # use openpgp::cert::prelude::*;
1873    /// use openpgp::policy::StandardPolicy;
1874    /// #
1875    /// # fn main() -> openpgp::Result<()> {
1876    /// let p = &StandardPolicy::new();
1877    ///
1878    /// # let (cert, _) =
1879    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1880    /// #     .generate()?;
1881    /// for (i, ka) in cert.with_policy(p, None)?.keys().enumerate() {
1882    ///     eprintln!("Key #{} ({}) has {:?} signatures",
1883    ///               i, ka.key().fingerprint(),
1884    ///               ka.signatures().count());
1885    /// }
1886    /// # Ok(()) }
1887    /// ```
1888    pub fn signatures(&self)
1889                      -> impl Iterator<Item = &'a Signature> + Send + Sync {
1890        self.ka.signatures()
1891    }
1892
1893    /// Forwarder for the conversion macros.
1894    pub(crate) fn has_secret(&self) -> bool {
1895        self.key().has_secret()
1896    }
1897}
1898
1899/// A Valid primary Key, and its associated data.
1900///
1901/// A specialized version of [`ValidKeyAmalgamation`].
1902///
1903pub type ValidPrimaryKeyAmalgamation<'a, P>
1904    = ValidKeyAmalgamation<'a, P, key::PrimaryRole, ()>;
1905
1906/// A Valid subkey, and its associated data.
1907///
1908/// A specialized version of [`ValidKeyAmalgamation`].
1909///
1910pub type ValidSubordinateKeyAmalgamation<'a, P>
1911    = ValidKeyAmalgamation<'a, P, key::SubordinateRole, ()>;
1912
1913/// A valid key whose role is not known at compile time.
1914///
1915/// A specialized version of [`ValidKeyAmalgamation`].
1916///
1917pub type ValidErasedKeyAmalgamation<'a, P>
1918    = ValidKeyAmalgamation<'a, P, key::UnspecifiedRole, bool>;
1919
1920
1921impl<'a, P, R, R2> From<ValidKeyAmalgamation<'a, P, R, R2>>
1922    for KeyAmalgamation<'a, P, R, R2>
1923    where P: 'a + key::KeyParts,
1924          R: 'a + key::KeyRole,
1925          R2: Copy,
1926{
1927    fn from(vka: ValidKeyAmalgamation<'a, P, R, R2>) -> Self {
1928        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1929        vka.ka
1930    }
1931}
1932
1933impl<'a, P: 'a + key::KeyParts> From<ValidPrimaryKeyAmalgamation<'a, P>>
1934    for ValidErasedKeyAmalgamation<'a, P>
1935{
1936    fn from(vka: ValidPrimaryKeyAmalgamation<'a, P>) -> Self {
1937        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1938        ValidErasedKeyAmalgamation {
1939            ka: vka.ka.into(),
1940            cert: vka.cert,
1941            binding_signature: vka.binding_signature,
1942        }
1943    }
1944}
1945
1946impl<'a, P: 'a + key::KeyParts> From<&ValidPrimaryKeyAmalgamation<'a, P>>
1947    for ValidErasedKeyAmalgamation<'a, P>
1948{
1949    fn from(vka: &ValidPrimaryKeyAmalgamation<'a, P>) -> Self {
1950        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1951        ValidErasedKeyAmalgamation {
1952            ka: vka.ka.clone().into(),
1953            cert: vka.cert.clone(),
1954            binding_signature: vka.binding_signature,
1955        }
1956    }
1957}
1958
1959impl<'a, P: 'a + key::KeyParts> From<ValidSubordinateKeyAmalgamation<'a, P>>
1960    for ValidErasedKeyAmalgamation<'a, P>
1961{
1962    fn from(vka: ValidSubordinateKeyAmalgamation<'a, P>) -> Self {
1963        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1964        ValidErasedKeyAmalgamation {
1965            ka: vka.ka.into(),
1966            cert: vka.cert,
1967            binding_signature: vka.binding_signature,
1968        }
1969    }
1970}
1971
1972impl<'a, P: 'a + key::KeyParts> From<&ValidSubordinateKeyAmalgamation<'a, P>>
1973    for ValidErasedKeyAmalgamation<'a, P>
1974{
1975    fn from(vka: &ValidSubordinateKeyAmalgamation<'a, P>) -> Self {
1976        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1977        ValidErasedKeyAmalgamation {
1978            ka: vka.ka.clone().into(),
1979            cert: vka.cert.clone(),
1980            binding_signature: vka.binding_signature,
1981        }
1982    }
1983}
1984
1985// We can infallibly convert part X to part Y for everything but
1986// Public -> Secret and Unspecified -> Secret.
1987macro_rules! impl_conversion {
1988    ($s:ident, $p1:path, $p2:path) => {
1989        impl<'a> From<$s<'a, $p1>>
1990            for ValidErasedKeyAmalgamation<'a, $p2>
1991        {
1992            fn from(vka: $s<'a, $p1>) -> Self {
1993                assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
1994                ValidErasedKeyAmalgamation {
1995                    ka: vka.ka.into(),
1996                    cert: vka.cert,
1997                    binding_signature: vka.binding_signature,
1998                }
1999            }
2000        }
2001
2002        impl<'a> From<&$s<'a, $p1>>
2003            for ValidErasedKeyAmalgamation<'a, $p2>
2004        {
2005            fn from(vka: &$s<'a, $p1>) -> Self {
2006                assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
2007                ValidErasedKeyAmalgamation {
2008                    ka: vka.ka.clone().into(),
2009                    cert: vka.cert.clone(),
2010                    binding_signature: vka.binding_signature,
2011                }
2012            }
2013        }
2014    }
2015}
2016
2017impl_conversion!(ValidPrimaryKeyAmalgamation,
2018                 key::SecretParts, key::PublicParts);
2019impl_conversion!(ValidPrimaryKeyAmalgamation,
2020                 key::SecretParts, key::UnspecifiedParts);
2021impl_conversion!(ValidPrimaryKeyAmalgamation,
2022                 key::PublicParts, key::UnspecifiedParts);
2023impl_conversion!(ValidPrimaryKeyAmalgamation,
2024                 key::UnspecifiedParts, key::PublicParts);
2025
2026impl_conversion!(ValidSubordinateKeyAmalgamation,
2027                 key::SecretParts, key::PublicParts);
2028impl_conversion!(ValidSubordinateKeyAmalgamation,
2029                 key::SecretParts, key::UnspecifiedParts);
2030impl_conversion!(ValidSubordinateKeyAmalgamation,
2031                 key::PublicParts, key::UnspecifiedParts);
2032impl_conversion!(ValidSubordinateKeyAmalgamation,
2033                 key::UnspecifiedParts, key::PublicParts);
2034
2035
2036impl<'a, P, P2> TryFrom<ValidErasedKeyAmalgamation<'a, P>>
2037    for ValidPrimaryKeyAmalgamation<'a, P2>
2038    where P: 'a + key::KeyParts,
2039          P2: 'a + key::KeyParts,
2040{
2041    type Error = anyhow::Error;
2042
2043    fn try_from(vka: ValidErasedKeyAmalgamation<'a, P>) -> Result<Self> {
2044        assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
2045        Ok(ValidPrimaryKeyAmalgamation {
2046            ka: vka.ka.try_into()?,
2047            cert: vka.cert,
2048            binding_signature: vka.binding_signature,
2049        })
2050    }
2051}
2052
2053impl<'a, P, P2> TryFrom<ValidErasedKeyAmalgamation<'a, P>>
2054    for ValidSubordinateKeyAmalgamation<'a, P2>
2055    where P: 'a + key::KeyParts,
2056          P2: 'a + key::KeyParts,
2057{
2058    type Error = anyhow::Error;
2059
2060    fn try_from(vka: ValidErasedKeyAmalgamation<'a, P>) -> Result<Self> {
2061        Ok(ValidSubordinateKeyAmalgamation {
2062            ka: vka.ka.try_into()?,
2063            cert: vka.cert,
2064            binding_signature: vka.binding_signature,
2065        })
2066    }
2067}
2068
2069
2070impl<'a, P> ValidateAmalgamation<'a, Key<P, key::PrimaryRole>>
2071    for ValidPrimaryKeyAmalgamation<'a, P>
2072    where P: 'a + key::KeyParts
2073{
2074    type V = Self;
2075
2076    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T) -> Result<Self::V>
2077        where T: Into<Option<time::SystemTime>>,
2078              Self: Sized
2079    {
2080        assert!(std::ptr::eq(self.ka.cert(), self.cert.cert()));
2081        self.ka.with_policy(policy, time)
2082            .map(|vka| {
2083                assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
2084                vka
2085            })
2086    }
2087}
2088
2089impl<'a, P> ValidateAmalgamation<'a, Key<P, key::SubordinateRole>>
2090    for ValidSubordinateKeyAmalgamation<'a, P>
2091    where P: 'a + key::KeyParts
2092{
2093    type V = Self;
2094
2095    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T) -> Result<Self::V>
2096        where T: Into<Option<time::SystemTime>>,
2097              Self: Sized
2098    {
2099        assert!(std::ptr::eq(self.ka.cert(), self.cert.cert()));
2100        self.ka.with_policy(policy, time)
2101            .map(|vka| {
2102                assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
2103                vka
2104            })
2105    }
2106}
2107
2108
2109impl<'a, P> ValidateAmalgamation<'a, Key<P, key::UnspecifiedRole>>
2110    for ValidErasedKeyAmalgamation<'a, P>
2111    where P: 'a + key::KeyParts
2112{
2113    type V = Self;
2114
2115    fn with_policy<T>(&self, policy: &'a dyn Policy, time: T) -> Result<Self::V>
2116        where T: Into<Option<time::SystemTime>>,
2117              Self: Sized
2118    {
2119        assert!(std::ptr::eq(self.ka.cert(), self.cert.cert()));
2120        self.ka.with_policy(policy, time)
2121            .map(|vka| {
2122                assert!(std::ptr::eq(vka.ka.cert(), vka.cert.cert()));
2123                vka
2124            })
2125    }
2126}
2127
2128impl<'a, P, R, R2> seal::Sealed for ValidKeyAmalgamation<'a, P, R, R2>
2129    where P: 'a + key::KeyParts,
2130          R: 'a + key::KeyRole,
2131          R2: Copy,
2132          Self: PrimaryKey<'a, P, R>,
2133{}
2134
2135impl<'a, P, R, R2> ValidAmalgamation<'a, Key<P, R>>
2136    for ValidKeyAmalgamation<'a, P, R, R2>
2137    where P: 'a + key::KeyParts,
2138          R: 'a + key::KeyRole,
2139          R2: Copy,
2140          Self: PrimaryKey<'a, P, R>,
2141{
2142    fn valid_cert(&self) -> &ValidCert<'a> {
2143        assert!(std::ptr::eq(self.ka.cert(), self.cert.cert()));
2144        &self.cert
2145    }
2146
2147    fn time(&self) -> SystemTime {
2148        self.cert.time()
2149    }
2150
2151    fn policy(&self) -> &'a dyn Policy {
2152        assert!(std::ptr::eq(self.ka.cert(), self.cert.cert()));
2153        self.cert.policy()
2154    }
2155
2156    fn binding_signature(&self) -> &'a Signature {
2157        self.binding_signature
2158    }
2159
2160    fn revocation_status(&self) -> RevocationStatus<'a> {
2161        if self.primary() {
2162            self.cert.revocation_status()
2163        } else {
2164            self.bundle().revocation_status_intern(
2165                self.policy(), Some(self.time()), true,
2166                Some(self.binding_signature))
2167        }
2168    }
2169
2170    fn revocation_keys(&self)
2171                       -> Box<dyn Iterator<Item = &'a RevocationKey> + 'a>
2172    {
2173        let mut keys = std::collections::HashSet::new();
2174
2175        let policy = self.policy();
2176        let pk_sec = self.cert().primary_key().key().hash_algo_security();
2177
2178        // All valid self-signatures.
2179        let sec = self.bundle().hash_algo_security;
2180        self.self_signatures()
2181            .filter(move |sig| {
2182                policy.signature(sig, sec).is_ok()
2183            })
2184        // All direct-key signatures.
2185            .chain(self.cert().primary_key()
2186                   .self_signatures()
2187                   .filter(|sig| {
2188                       policy.signature(sig, pk_sec).is_ok()
2189                   }))
2190            .flat_map(|sig| sig.revocation_keys())
2191            .for_each(|rk| { keys.insert(rk); });
2192
2193        Box::new(keys.into_iter())
2194    }
2195}
2196
2197impl<'a, P, R, R2> ValidBindingSignature<'a, Key<P, R>>
2198    for ValidKeyAmalgamation<'a, P, R, R2>
2199where P: 'a + key::KeyParts,
2200      R: 'a + key::KeyRole,
2201      R2: Copy,
2202      Self: PrimaryKey<'a, P, R>,
2203{}
2204
2205impl<'a, P> PrimaryKey<'a, P, key::PrimaryRole>
2206    for ValidPrimaryKeyAmalgamation<'a, P>
2207    where P: 'a + key::KeyParts
2208{
2209    fn primary(&self) -> bool {
2210        true
2211    }
2212}
2213
2214impl<'a, P> PrimaryKey<'a, P, key::SubordinateRole>
2215    for ValidSubordinateKeyAmalgamation<'a, P>
2216    where P: 'a + key::KeyParts
2217{
2218    fn primary(&self) -> bool {
2219        false
2220    }
2221}
2222
2223impl<'a, P> PrimaryKey<'a, P, key::UnspecifiedRole>
2224    for ValidErasedKeyAmalgamation<'a, P>
2225    where P: 'a + key::KeyParts
2226{
2227    fn primary(&self) -> bool {
2228        self.ka.primary
2229    }
2230}
2231
2232
2233impl<'a, P, R, R2> ValidKeyAmalgamation<'a, P, R, R2>
2234    where P: 'a + key::KeyParts,
2235          R: 'a + key::KeyRole,
2236          R2: Copy,
2237          Self: ValidAmalgamation<'a, Key<P, R>>,
2238          Self: PrimaryKey<'a, P, R>,
2239{
2240    /// Returns whether the key is alive as of the amalgamation's
2241    /// reference time.
2242    ///
2243    /// A `ValidKeyAmalgamation` is guaranteed to have a live binding
2244    /// signature.  This is independent of whether the component is
2245    /// live.
2246    ///
2247    /// If the certificate is not alive as of the reference time, no
2248    /// subkey can be alive.
2249    ///
2250    /// This function considers both the binding signature and the
2251    /// direct key signature.  Information in the binding signature
2252    /// takes precedence over the direct key signature.  See [Section
2253    /// 5.2.3.10 of RFC 9580].
2254    ///
2255    ///   [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
2256    ///
2257    /// For a definition of liveness, see the [`key_alive`] method.
2258    ///
2259    /// [`key_alive`]: crate::packet::signature::subpacket::SubpacketAreas::key_alive()
2260    ///
2261    /// # Examples
2262    ///
2263    /// ```
2264    /// # use sequoia_openpgp as openpgp;
2265    /// # use openpgp::cert::prelude::*;
2266    /// use openpgp::policy::StandardPolicy;
2267    ///
2268    /// # fn main() -> openpgp::Result<()> {
2269    /// let p = &StandardPolicy::new();
2270    ///
2271    /// # let (cert, _) = CertBuilder::new()
2272    /// #     .add_userid("Alice")
2273    /// #     .add_signing_subkey()
2274    /// #     .add_transport_encryption_subkey()
2275    /// #     .generate()?;
2276    /// let ka = cert.primary_key().with_policy(p, None)?;
2277    /// if let Err(_err) = ka.alive() {
2278    ///     // Not alive.
2279    /// #   unreachable!();
2280    /// }
2281    /// # Ok(()) }
2282    /// ```
2283    pub fn alive(&self) -> Result<()>
2284    {
2285        if ! self.primary() {
2286            // First, check the certificate.
2287            self.valid_cert().alive()
2288                .context("The certificate is not live")?;
2289        }
2290
2291        let sig = {
2292            let binding : &Signature = self.binding_signature();
2293            if binding.key_validity_period().is_some() {
2294                Some(binding)
2295            } else {
2296                self.direct_key_signature().ok()
2297            }
2298        };
2299        if let Some(sig) = sig {
2300            sig.key_alive(self.key(), self.time())
2301                .with_context(|| if self.primary() {
2302                    "The primary key is not live"
2303                } else {
2304                    "The subkey is not live"
2305                })
2306        } else {
2307            // There is no key expiration time on the binding
2308            // signature.  This key does not expire.
2309            Ok(())
2310        }
2311    }
2312}
2313
2314impl<'a, P, R, R2> ValidKeyAmalgamation<'a, P, R, R2>
2315    where P: key::KeyParts,
2316          R: key::KeyRole,
2317          R2: Copy,
2318          Self: PrimaryKey<'a, P, R>,
2319{
2320    /// Returns the key's primary key binding signature, if any.
2321    ///
2322    /// The [primary key binding signature] is embedded inside a
2323    /// subkey binding signature.  It is made by the subkey to
2324    /// indicate that it should be associated with the primary key.
2325    /// This prevents an attack in which an attacker creates a
2326    /// certificate, and associates the victim's subkey with it
2327    /// thereby creating confusion about the certificate that issued a
2328    /// signature.
2329    ///
2330    ///   [primary key binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
2331    ///
2332    /// Not all keys have primary key binding signatures.  First,
2333    /// primary keys don't have them, because they don't need them.
2334    /// Second, encrypt-capable subkeys don't have them because they
2335    /// are not (usually) able to issue signatures.
2336    ///
2337    /// # Examples
2338    ///
2339    /// ```
2340    /// # use sequoia_openpgp as openpgp;
2341    /// # use openpgp::cert::prelude::*;
2342    /// # use openpgp::policy::StandardPolicy;
2343    /// #
2344    /// # const P: &StandardPolicy = &StandardPolicy::new();
2345    /// #
2346    /// # fn main() -> openpgp::Result<()> {
2347    /// #     let (cert, _) =
2348    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
2349    /// #         .generate()?;
2350    /// #     let fpr = cert.fingerprint();
2351    /// let vc = cert.with_policy(P, None)?;
2352    ///
2353    /// assert!(vc.primary_key().primary_key_binding_signature().is_none());
2354    ///
2355    /// // A signing key has to have a primary key binding signature.
2356    /// for ka in vc.keys().for_signing() {
2357    ///     assert!(ka.primary_key_binding_signature().is_some());
2358    /// }
2359    ///
2360    /// // Encryption keys normally can't have a primary key binding
2361    /// // signature, because they can't issue signatures.
2362    /// for ka in vc.keys().for_transport_encryption() {
2363    ///     assert!(ka.primary_key_binding_signature().is_none());
2364    /// }
2365    /// #     Ok(())
2366    /// # }
2367    /// ```
2368    pub fn primary_key_binding_signature(&self) -> Option<&Signature> {
2369        let subkey = if self.primary() {
2370            // A primary key has no backsig.
2371            return None;
2372        } else {
2373            self.key().role_as_subordinate()
2374        };
2375
2376        let pk = self.cert().primary_key().key();
2377
2378        for backsig in
2379            self.binding_signature.subpackets(SubpacketTag::EmbeddedSignature)
2380        {
2381            if let SubpacketValue::EmbeddedSignature(sig) =
2382                backsig.value()
2383            {
2384                if sig.verify_primary_key_binding(pk, subkey).is_ok() {
2385                    // Mark the subpacket as authenticated by the
2386                    // embedded signature.
2387                    backsig.set_authenticated(true);
2388
2389                    return Some(sig);
2390                }
2391            } else {
2392                unreachable!("subpackets(EmbeddedSignature) returns \
2393                              EmbeddedSignatures");
2394            }
2395        }
2396
2397        None
2398    }
2399}
2400
2401impl<'a, P> ValidPrimaryKeyAmalgamation<'a, P>
2402    where P: 'a + key::KeyParts
2403{
2404    /// Sets the key to expire in delta seconds.
2405    ///
2406    /// Note: the time is relative to the key's creation time, not the
2407    /// current time!
2408    ///
2409    /// This function exists to facilitate testing, which is why it is
2410    /// not exported.
2411    #[cfg(test)]
2412    pub(crate) fn set_validity_period_as_of(&self,
2413                                            primary_signer: &mut dyn Signer,
2414                                            expiration: Option<time::Duration>,
2415                                            now: time::SystemTime)
2416        -> Result<Vec<Signature>>
2417    {
2418        ValidErasedKeyAmalgamation::<P>::from(self)
2419            .set_validity_period_as_of(primary_signer, None, expiration, now)
2420    }
2421
2422    /// Creates signatures that cause the key to expire at the specified time.
2423    ///
2424    /// This function creates new binding signatures that cause the
2425    /// key to expire at the specified time when integrated into the
2426    /// certificate.  For the primary key, it is necessary to
2427    /// create a new self-signature for each non-revoked User ID, and
2428    /// to create a direct key signature.  This is needed, because the
2429    /// primary User ID is first consulted when determining the
2430    /// primary key's expiration time, and certificates can be
2431    /// distributed with a possibly empty subset of User IDs.
2432    ///
2433    /// Setting a key's expiry time means updating an existing binding
2434    /// signature---when looking up information, only one binding
2435    /// signature is normally considered, and we don't want to drop
2436    /// the other information stored in the current binding signature.
2437    /// This function uses the binding signature determined by
2438    /// `ValidKeyAmalgamation`'s policy and reference time for this.
2439    ///
2440    /// # Examples
2441    ///
2442    /// ```
2443    /// use std::time;
2444    /// # use sequoia_openpgp as openpgp;
2445    /// # use openpgp::cert::prelude::*;
2446    /// use openpgp::policy::StandardPolicy;
2447    ///
2448    /// # fn main() -> openpgp::Result<()> {
2449    /// let p = &StandardPolicy::new();
2450    ///
2451    /// # let t = time::SystemTime::now() - time::Duration::from_secs(10);
2452    /// # let (cert, _) = CertBuilder::new()
2453    /// #     .set_creation_time(t)
2454    /// #     .add_userid("Alice")
2455    /// #     .add_signing_subkey()
2456    /// #     .add_transport_encryption_subkey()
2457    /// #     .generate()?;
2458    /// let vc = cert.with_policy(p, None)?;
2459    ///
2460    /// // Assert that the primary key is not expired.
2461    /// assert!(vc.primary_key().alive().is_ok());
2462    ///
2463    /// // Make the primary key expire in a week.
2464    /// let t = time::SystemTime::now()
2465    ///     + time::Duration::from_secs(7 * 24 * 60 * 60);
2466    ///
2467    /// // We assume that the secret key material is available, and not
2468    /// // password protected.
2469    /// let mut signer = vc.primary_key()
2470    ///     .key().clone().parts_into_secret()?.into_keypair()?;
2471    ///
2472    /// let sigs = vc.primary_key().set_expiration_time(&mut signer, Some(t))?;
2473    /// let cert = cert.insert_packets(sigs)?.0;
2474    ///
2475    /// // The primary key isn't expired yet.
2476    /// let vc = cert.with_policy(p, None)?;
2477    /// assert!(vc.primary_key().alive().is_ok());
2478    ///
2479    /// // But in two weeks, it will be...
2480    /// let t = time::SystemTime::now()
2481    ///     + time::Duration::from_secs(2 * 7 * 24 * 60 * 60);
2482    /// let vc = cert.with_policy(p, t)?;
2483    /// assert!(vc.primary_key().alive().is_err());
2484    /// # Ok(()) }
2485    pub fn set_expiration_time(&self,
2486                               primary_signer: &mut dyn Signer,
2487                               expiration: Option<time::SystemTime>)
2488        -> Result<Vec<Signature>>
2489    {
2490        ValidErasedKeyAmalgamation::<P>::from(self)
2491            .set_expiration_time(primary_signer, None, expiration)
2492    }
2493}
2494
2495impl<'a, P> ValidSubordinateKeyAmalgamation<'a, P>
2496    where P: 'a + key::KeyParts
2497{
2498    /// Creates signatures that cause the key to expire at the specified time.
2499    ///
2500    /// This function creates new binding signatures that cause the
2501    /// key to expire at the specified time when integrated into the
2502    /// certificate.  For subkeys, a single `Signature` is returned.
2503    ///
2504    /// Setting a key's expiry time means updating an existing binding
2505    /// signature---when looking up information, only one binding
2506    /// signature is normally considered, and we don't want to drop
2507    /// the other information stored in the current binding signature.
2508    /// This function uses the binding signature determined by
2509    /// `ValidKeyAmalgamation`'s policy and reference time for this.
2510    ///
2511    /// When updating the expiration time of signing-capable subkeys,
2512    /// we need to create a new [primary key binding signature].
2513    /// Therefore, we need a signer for the subkey.  If
2514    /// `subkey_signer` is `None`, and this is a signing-capable
2515    /// subkey, this function fails with [`Error::InvalidArgument`].
2516    /// Likewise, this function fails if `subkey_signer` is not `None`
2517    /// when updating the expiration of a non signing-capable subkey.
2518    ///
2519    ///   [primary key binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
2520    ///   [`Error::InvalidArgument`]: super::super::super::Error::InvalidArgument
2521    ///
2522    /// # Examples
2523    ///
2524    /// ```
2525    /// use std::time;
2526    /// # use sequoia_openpgp as openpgp;
2527    /// # use openpgp::cert::prelude::*;
2528    /// use openpgp::policy::StandardPolicy;
2529    ///
2530    /// # fn main() -> openpgp::Result<()> {
2531    /// let p = &StandardPolicy::new();
2532    ///
2533    /// # let t = time::SystemTime::now() - time::Duration::from_secs(10);
2534    /// # let (cert, _) = CertBuilder::new()
2535    /// #     .set_creation_time(t)
2536    /// #     .add_userid("Alice")
2537    /// #     .add_signing_subkey()
2538    /// #     .add_transport_encryption_subkey()
2539    /// #     .generate()?;
2540    /// let vc = cert.with_policy(p, None)?;
2541    ///
2542    /// // Assert that the keys are not expired.
2543    /// for ka in vc.keys() {
2544    ///     assert!(ka.alive().is_ok());
2545    /// }
2546    ///
2547    /// // Make the keys expire in a week.
2548    /// let t = time::SystemTime::now()
2549    ///     + time::Duration::from_secs(7 * 24 * 60 * 60);
2550    ///
2551    /// // We assume that the secret key material is available, and not
2552    /// // password protected.
2553    /// let mut primary_signer = vc.primary_key()
2554    ///     .key().clone().parts_into_secret()?.into_keypair()?;
2555    /// let mut signing_subkey_signer = vc.keys().for_signing().nth(0).unwrap()
2556    ///     .key().clone().parts_into_secret()?.into_keypair()?;
2557    ///
2558    /// let mut sigs = Vec::new();
2559    /// for ka in vc.keys() {
2560    ///     if ! ka.for_signing() {
2561    ///         // Non-signing-capable subkeys are easy to update.
2562    ///         sigs.append(&mut ka.set_expiration_time(&mut primary_signer,
2563    ///                                                 None, Some(t))?);
2564    ///     } else {
2565    ///         // Signing-capable subkeys need to create a primary
2566    ///         // key binding signature with the subkey:
2567    ///         assert!(ka.set_expiration_time(&mut primary_signer,
2568    ///                                        None, Some(t)).is_err());
2569    ///
2570    ///         // Here, we need the subkey's signer:
2571    ///         sigs.append(&mut ka.set_expiration_time(&mut primary_signer,
2572    ///                                                 Some(&mut signing_subkey_signer),
2573    ///                                                 Some(t))?);
2574    ///     }
2575    /// }
2576    /// let cert = cert.insert_packets(sigs)?.0;
2577    ///
2578    /// // They aren't expired yet.
2579    /// let vc = cert.with_policy(p, None)?;
2580    /// for ka in vc.keys() {
2581    ///     assert!(ka.alive().is_ok());
2582    /// }
2583    ///
2584    /// // But in two weeks, they will be...
2585    /// let t = time::SystemTime::now()
2586    ///     + time::Duration::from_secs(2 * 7 * 24 * 60 * 60);
2587    /// let vc = cert.with_policy(p, t)?;
2588    /// for ka in vc.keys() {
2589    ///     assert!(ka.alive().is_err());
2590    /// }
2591    /// # Ok(()) }
2592    pub fn set_expiration_time(&self,
2593                               primary_signer: &mut dyn Signer,
2594                               subkey_signer: Option<&mut dyn Signer>,
2595                               expiration: Option<time::SystemTime>)
2596        -> Result<Vec<Signature>>
2597    {
2598        ValidErasedKeyAmalgamation::<P>::from(self)
2599            .set_expiration_time(primary_signer, subkey_signer, expiration)
2600    }
2601}
2602
2603impl<'a, P> ValidErasedKeyAmalgamation<'a, P>
2604    where P: 'a + key::KeyParts
2605{
2606    /// Sets the key to expire in delta seconds.
2607    ///
2608    /// Note: the time is relative to the key's creation time, not the
2609    /// current time!
2610    ///
2611    /// This function exists to facilitate testing, which is why it is
2612    /// not exported.
2613    pub(crate) fn set_validity_period_as_of(&self,
2614                                            primary_signer: &mut dyn Signer,
2615                                            subkey_signer:
2616                                                Option<&mut dyn Signer>,
2617                                            expiration: Option<time::Duration>,
2618                                            now: time::SystemTime)
2619        -> Result<Vec<Signature>>
2620    {
2621        let mut sigs = Vec::new();
2622
2623        // There are two cases to consider.  If we are extending the
2624        // validity of the primary key, we also need to create new
2625        // binding signatures for all userids.
2626        if self.primary() {
2627            // First, update or create a direct key signature.
2628            let template = self.direct_key_signature()
2629                .map(|sig| {
2630                    signature::SignatureBuilder::from(sig.clone())
2631                })
2632                .unwrap_or_else(|_| {
2633                    let mut template = signature::SignatureBuilder::from(
2634                        self.binding_signature().clone())
2635                        .set_type(SignatureType::DirectKey);
2636
2637                    // We're creating a direct signature from a User
2638                    // ID self signature.  Remove irrelevant packets.
2639                    use SubpacketTag::*;
2640                    let ha = template.hashed_area_mut();
2641                    ha.remove_all(ExportableCertification);
2642                    ha.remove_all(Revocable);
2643                    ha.remove_all(TrustSignature);
2644                    ha.remove_all(RegularExpression);
2645                    ha.remove_all(PrimaryUserID);
2646                    ha.remove_all(SignersUserID);
2647                    ha.remove_all(ReasonForRevocation);
2648                    ha.remove_all(SignatureTarget);
2649                    ha.remove_all(EmbeddedSignature);
2650
2651                    template
2652                });
2653            let mut builder = template
2654                .set_signature_creation_time(now)?
2655                .set_key_validity_period(expiration)?;
2656            builder.hashed_area_mut().remove_all(
2657                signature::subpacket::SubpacketTag::PrimaryUserID);
2658
2659            // Generate the signature.
2660            sigs.push(builder.sign_direct_key(primary_signer, None)?);
2661
2662            // Second, generate a new binding signature for every
2663            // userid.  We need to be careful not to change the
2664            // primary userid, so we make it explicit using the
2665            // primary userid subpacket.
2666            for userid in self.valid_cert().userids().revoked(false) {
2667                // To extend the validity of the subkey, create a new
2668                // binding signature with updated key validity period.
2669                let binding_signature = userid.binding_signature();
2670
2671                let builder = signature::SignatureBuilder::from(binding_signature.clone())
2672                    .set_signature_creation_time(now)?
2673                    .set_key_validity_period(expiration)?
2674                    .set_primary_userid(
2675                        self.valid_cert().primary_userid().map(|primary| {
2676                            userid.userid() == primary.userid()
2677                        }).unwrap_or(false))?;
2678
2679                sigs.push(builder.sign_userid_binding(primary_signer,
2680                                                      self.cert().primary_key().component(),
2681                                                      userid.userid())?);
2682            }
2683        } else {
2684            // To extend the validity of the subkey, create a new
2685            // binding signature with updated key validity period.
2686            let backsig = if self.for_certification() || self.for_signing()
2687                || self.for_authentication()
2688            {
2689                if let Some(subkey_signer) = subkey_signer {
2690                    Some(signature::SignatureBuilder::new(
2691                        SignatureType::PrimaryKeyBinding)
2692                         .set_signature_creation_time(now)?
2693                         .set_hash_algo(self.binding_signature.hash_algo())
2694                         .sign_primary_key_binding(
2695                             subkey_signer,
2696                             self.cert().primary_key().key(),
2697                             self.key().role_as_subordinate())?)
2698                } else {
2699                    return Err(Error::InvalidArgument(
2700                        "Changing expiration of signing-capable subkeys \
2701                         requires subkey signer".into()).into());
2702                }
2703            } else {
2704                if subkey_signer.is_some() {
2705                    return Err(Error::InvalidArgument(
2706                        "Subkey signer given but subkey is not signing-capable"
2707                            .into()).into());
2708                }
2709                None
2710            };
2711
2712            let mut sig =
2713                signature::SignatureBuilder::from(
2714                        self.binding_signature().clone())
2715                    .set_signature_creation_time(now)?
2716                    .set_key_validity_period(expiration)?;
2717
2718            if let Some(bs) = backsig {
2719                sig = sig.set_embedded_signature(bs)?;
2720            }
2721
2722            sigs.push(sig.sign_subkey_binding(
2723                primary_signer,
2724                self.cert().primary_key().component(),
2725                self.key().role_as_subordinate())?);
2726        }
2727
2728        Ok(sigs)
2729    }
2730
2731    /// Creates signatures that cause the key to expire at the specified time.
2732    ///
2733    /// This function creates new binding signatures that cause the
2734    /// key to expire at the specified time when integrated into the
2735    /// certificate.  For subkeys, only a single `Signature` is
2736    /// returned.  For the primary key, however, it is necessary to
2737    /// create a new self-signature for each non-revoked User ID, and
2738    /// to create a direct key signature.  This is needed, because the
2739    /// primary User ID is first consulted when determining the
2740    /// primary key's expiration time, and certificates can be
2741    /// distributed with a possibly empty subset of User IDs.
2742    ///
2743    /// Setting a key's expiry time means updating an existing binding
2744    /// signature---when looking up information, only one binding
2745    /// signature is normally considered, and we don't want to drop
2746    /// the other information stored in the current binding signature.
2747    /// This function uses the binding signature determined by
2748    /// `ValidKeyAmalgamation`'s policy and reference time for this.
2749    ///
2750    /// When updating the expiration time of signing-capable subkeys,
2751    /// we need to create a new [primary key binding signature].
2752    /// Therefore, we need a signer for the subkey.  If
2753    /// `subkey_signer` is `None`, and this is a signing-capable
2754    /// subkey, this function fails with [`Error::InvalidArgument`].
2755    /// Likewise, this function fails if `subkey_signer` is not `None`
2756    /// when updating the expiration of the primary key, or a non
2757    /// signing-capable subkey.
2758    ///
2759    ///   [primary key binding signature]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.1
2760    ///   [`Error::InvalidArgument`]: super::super::super::Error::InvalidArgument
2761    ///
2762    /// # Examples
2763    ///
2764    /// ```
2765    /// use std::time;
2766    /// # use sequoia_openpgp as openpgp;
2767    /// # use openpgp::cert::prelude::*;
2768    /// use openpgp::policy::StandardPolicy;
2769    ///
2770    /// # fn main() -> openpgp::Result<()> {
2771    /// let p = &StandardPolicy::new();
2772    ///
2773    /// # let t = time::SystemTime::now() - time::Duration::from_secs(10);
2774    /// # let (cert, _) = CertBuilder::new()
2775    /// #     .set_creation_time(t)
2776    /// #     .add_userid("Alice")
2777    /// #     .add_signing_subkey()
2778    /// #     .add_transport_encryption_subkey()
2779    /// #     .generate()?;
2780    /// let vc = cert.with_policy(p, None)?;
2781    ///
2782    /// // Assert that the keys are not expired.
2783    /// for ka in vc.keys() {
2784    ///     assert!(ka.alive().is_ok());
2785    /// }
2786    ///
2787    /// // Make the keys expire in a week.
2788    /// let t = time::SystemTime::now()
2789    ///     + time::Duration::from_secs(7 * 24 * 60 * 60);
2790    ///
2791    /// // We assume that the secret key material is available, and not
2792    /// // password protected.
2793    /// let mut primary_signer = vc.primary_key()
2794    ///     .key().clone().parts_into_secret()?.into_keypair()?;
2795    /// let mut signing_subkey_signer = vc.keys().for_signing().nth(0).unwrap()
2796    ///     .key().clone().parts_into_secret()?.into_keypair()?;
2797    ///
2798    /// let mut sigs = Vec::new();
2799    /// for ka in vc.keys() {
2800    ///     if ! ka.for_signing() {
2801    ///         // Non-signing-capable subkeys are easy to update.
2802    ///         sigs.append(&mut ka.set_expiration_time(&mut primary_signer,
2803    ///                                                 None, Some(t))?);
2804    ///     } else {
2805    ///         // Signing-capable subkeys need to create a primary
2806    ///         // key binding signature with the subkey:
2807    ///         assert!(ka.set_expiration_time(&mut primary_signer,
2808    ///                                        None, Some(t)).is_err());
2809    ///
2810    ///         // Here, we need the subkey's signer:
2811    ///         sigs.append(&mut ka.set_expiration_time(&mut primary_signer,
2812    ///                                                 Some(&mut signing_subkey_signer),
2813    ///                                                 Some(t))?);
2814    ///     }
2815    /// }
2816    /// let cert = cert.insert_packets(sigs)?.0;
2817    ///
2818    /// // They aren't expired yet.
2819    /// let vc = cert.with_policy(p, None)?;
2820    /// for ka in vc.keys() {
2821    ///     assert!(ka.alive().is_ok());
2822    /// }
2823    ///
2824    /// // But in two weeks, they will be...
2825    /// let t = time::SystemTime::now()
2826    ///     + time::Duration::from_secs(2 * 7 * 24 * 60 * 60);
2827    /// let vc = cert.with_policy(p, t)?;
2828    /// for ka in vc.keys() {
2829    ///     assert!(ka.alive().is_err());
2830    /// }
2831    /// # Ok(()) }
2832    pub fn set_expiration_time(&self,
2833                               primary_signer: &mut dyn Signer,
2834                               subkey_signer: Option<&mut dyn Signer>,
2835                               expiration: Option<time::SystemTime>)
2836        -> Result<Vec<Signature>>
2837    {
2838        let expiration =
2839            if let Some(e) = expiration.map(crate::types::normalize_systemtime)
2840        {
2841            let ct = self.key().creation_time();
2842            match e.duration_since(ct) {
2843                Ok(v) => Some(v),
2844                Err(_) => return Err(Error::InvalidArgument(
2845                    format!("Expiration time {:?} predates creation time \
2846                             {:?}", e, ct)).into()),
2847            }
2848        } else {
2849            None
2850        };
2851
2852        self.set_validity_period_as_of(primary_signer, subkey_signer,
2853                                       expiration, crate::now())
2854    }
2855}
2856
2857impl<'a, P, R, R2> ValidKeyAmalgamation<'a, P, R, R2>
2858    where P: 'a + key::KeyParts,
2859          R: 'a + key::KeyRole,
2860          R2: Copy,
2861          Self: ValidAmalgamation<'a, Key<P, R>>,
2862          Self: ValidBindingSignature<'a, Key<P, R>>,
2863{
2864    /// Returns the key's `Key Flags`.
2865    ///
2866    /// A Key's [`Key Flags`] holds information about the key.  As of
2867    /// RFC 9580, this information is primarily concerned with the
2868    /// key's capabilities (e.g., whether it may be used for signing).
2869    /// The other information that has been defined is: whether the
2870    /// key has been split using something like [SSS], and whether the
2871    /// primary key material is held by multiple parties.  In
2872    /// practice, the latter two flags are ignored.
2873    ///
2874    /// As per [Section 5.2.3.10 of RFC 9580], when looking for the
2875    /// `Key Flags`, the key's binding signature is first consulted
2876    /// (in the case of the primary Key, this is the binding signature
2877    /// of the primary User ID).  If the `Key Flags` subpacket is not
2878    /// present, then the direct key signature is consulted.
2879    ///
2880    /// Since the key flags are taken from the active self signature,
2881    /// a key's flags may change depending on the policy and the
2882    /// reference time.
2883    ///
2884    /// To increase compatibility with early v4 certificates, if there
2885    /// is no key flags subpacket on the considered signatures, we
2886    /// infer the key flags from the key's role and public key
2887    /// algorithm.
2888    ///
2889    ///   [`Key Flags`]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
2890    ///   [SSS]: https://de.wikipedia.org/wiki/Shamir%E2%80%99s_Secret_Sharing
2891    ///   [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
2892    ///
2893    /// # Examples
2894    ///
2895    /// ```
2896    /// # use sequoia_openpgp as openpgp;
2897    /// # use openpgp::cert::prelude::*;
2898    /// # use openpgp::policy::{Policy, StandardPolicy};
2899    /// #
2900    /// # fn main() -> openpgp::Result<()> {
2901    /// #     let p: &dyn Policy = &StandardPolicy::new();
2902    /// #     let (cert, _) =
2903    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
2904    /// #         .generate()?;
2905    /// #     let cert = cert.with_policy(p, None)?;
2906    /// let ka = cert.primary_key();
2907    /// println!("Primary Key's Key Flags: {:?}", ka.key_flags());
2908    /// # assert!(ka.key_flags().unwrap().for_certification());
2909    /// # Ok(()) }
2910    /// ```
2911    pub fn key_flags(&self) -> Option<KeyFlags> {
2912        self.map(|s| s.key_flags())
2913            .or_else(|| {
2914                // There is no key flags subpacket.  Match on the key
2915                // role and algorithm and synthesize one.  We do this
2916                // to better support very early v4 certificates, where
2917                // either the binding signature is a v3 signature and
2918                // cannot contain subpackets, or it is a v4 signature,
2919                // but the key's capabilities were implied by the
2920                // public key algorithm.
2921                use crate::types::PublicKeyAlgorithm;
2922
2923                // XXX: We cannot know whether this is a primary key
2924                // or not because of
2925                // https://gitlab.com/sequoia-pgp/sequoia/-/issues/1036
2926                let is_primary = false;
2927
2928                // We only match on public key algorithms used at the
2929                // time.
2930                #[allow(deprecated)]
2931                match (is_primary, self.key().pk_algo()) {
2932                    (true, PublicKeyAlgorithm::RSAEncryptSign) =>
2933                        Some(KeyFlags::empty()
2934                             .set_certification()
2935                             .set_transport_encryption()
2936                             .set_storage_encryption()
2937                             .set_signing()),
2938
2939                    (true, _) =>
2940                        Some(KeyFlags::empty()
2941                             .set_certification()
2942                             .set_signing()),
2943
2944                    (false, PublicKeyAlgorithm::RSAEncryptSign) =>
2945                        Some(KeyFlags::empty()
2946                             .set_transport_encryption()
2947                             .set_storage_encryption()
2948                             .set_signing()),
2949
2950                    (false,
2951                     | PublicKeyAlgorithm::RSASign
2952                     | PublicKeyAlgorithm::DSA) =>
2953                        Some(KeyFlags::empty().set_signing()),
2954
2955                    (false,
2956                     | PublicKeyAlgorithm::RSAEncrypt
2957                     | PublicKeyAlgorithm::ElGamalEncrypt
2958                     | PublicKeyAlgorithm::ElGamalEncryptSign) =>
2959                        Some(KeyFlags::empty()
2960                             .set_transport_encryption()
2961                             .set_storage_encryption()),
2962
2963                    // Be conservative: newer algorithms don't get to
2964                    // benefit from implicit key flags.
2965                    (false, _) => None,
2966                }
2967            })
2968    }
2969
2970    /// Returns whether the key has at least one of the specified key
2971    /// flags.
2972    ///
2973    /// The key flags are looked up as described in
2974    /// [`ValidKeyAmalgamation::key_flags`].
2975    ///
2976    /// # Examples
2977    ///
2978    /// Finds keys that may be used for transport encryption (data in
2979    /// motion) *or* storage encryption (data at rest):
2980    ///
2981    /// ```
2982    /// # use sequoia_openpgp as openpgp;
2983    /// # use openpgp::cert::prelude::*;
2984    /// use openpgp::policy::StandardPolicy;
2985    /// use openpgp::types::KeyFlags;
2986    ///
2987    /// # fn main() -> openpgp::Result<()> {
2988    /// let p = &StandardPolicy::new();
2989    ///
2990    /// #     let (cert, _) =
2991    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
2992    /// #         .generate()?;
2993    /// for ka in cert.keys().with_policy(p, None) {
2994    ///     if ka.has_any_key_flag(KeyFlags::empty()
2995    ///        .set_storage_encryption()
2996    ///        .set_transport_encryption())
2997    ///     {
2998    ///         // `ka` is encryption capable.
2999    ///     }
3000    /// }
3001    /// # Ok(()) }
3002    /// ```
3003    ///
3004    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3005    pub fn has_any_key_flag<F>(&self, flags: F) -> bool
3006        where F: Borrow<KeyFlags>
3007    {
3008        let our_flags = self.key_flags().unwrap_or_else(KeyFlags::empty);
3009        !(&our_flags & flags.borrow()).is_empty()
3010    }
3011
3012    /// Returns whether the key is certification capable.
3013    ///
3014    /// Note: [Section 10.1 of RFC 9580] says that the primary key is
3015    /// certification capable independent of the `Key Flags`
3016    /// subpacket:
3017    ///
3018    /// > In a V4 key, the primary key MUST be a key capable of
3019    /// > certification.
3020    ///
3021    /// This function only reflects what is stored in the `Key Flags`
3022    /// packet; it does not implicitly set this flag.  In practice,
3023    /// there are keys whose primary key's `Key Flags` do not have the
3024    /// certification capable flag set.  Some versions of netpgp, for
3025    /// instance, create keys like this.  Sequoia's higher-level
3026    /// functionality correctly handles these keys by always
3027    /// considering the primary key to be certification capable.
3028    /// Users of this interface should too.
3029    ///
3030    /// The key flags are looked up as described in
3031    /// [`ValidKeyAmalgamation::key_flags`].
3032    ///
3033    /// # Examples
3034    ///
3035    /// Finds keys that are certification capable:
3036    ///
3037    /// ```
3038    /// # use sequoia_openpgp as openpgp;
3039    /// # use openpgp::cert::prelude::*;
3040    /// use openpgp::policy::StandardPolicy;
3041    ///
3042    /// # fn main() -> openpgp::Result<()> {
3043    /// let p = &StandardPolicy::new();
3044    ///
3045    /// #     let (cert, _) =
3046    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3047    /// #         .generate()?;
3048    /// for ka in cert.keys().with_policy(p, None) {
3049    ///     if ka.primary() || ka.for_certification() {
3050    ///         // `ka` is certification capable.
3051    ///     }
3052    /// }
3053    /// # Ok(()) }
3054    /// ```
3055    ///
3056    /// [Section 10.1 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.29
3057    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3058    pub fn for_certification(&self) -> bool {
3059        self.has_any_key_flag(KeyFlags::empty().set_certification())
3060    }
3061
3062    /// Returns whether the key is signing capable.
3063    ///
3064    /// The key flags are looked up as described in
3065    /// [`ValidKeyAmalgamation::key_flags`].
3066    ///
3067    /// # Examples
3068    ///
3069    /// Finds keys that are signing capable:
3070    ///
3071    /// ```
3072    /// # use sequoia_openpgp as openpgp;
3073    /// # use openpgp::cert::prelude::*;
3074    /// use openpgp::policy::StandardPolicy;
3075    ///
3076    /// # fn main() -> openpgp::Result<()> {
3077    /// let p = &StandardPolicy::new();
3078    ///
3079    /// #     let (cert, _) =
3080    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3081    /// #         .generate()?;
3082    /// for ka in cert.keys().with_policy(p, None) {
3083    ///     if ka.for_signing() {
3084    ///         // `ka` is signing capable.
3085    ///     }
3086    /// }
3087    /// # Ok(()) }
3088    /// ```
3089    ///
3090    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3091    pub fn for_signing(&self) -> bool {
3092        self.has_any_key_flag(KeyFlags::empty().set_signing())
3093    }
3094
3095    /// Returns whether the key is authentication capable.
3096    ///
3097    /// The key flags are looked up as described in
3098    /// [`ValidKeyAmalgamation::key_flags`].
3099    ///
3100    /// # Examples
3101    ///
3102    /// Finds keys that are authentication capable:
3103    ///
3104    /// ```
3105    /// # use sequoia_openpgp as openpgp;
3106    /// # use openpgp::cert::prelude::*;
3107    /// use openpgp::policy::StandardPolicy;
3108    ///
3109    /// # fn main() -> openpgp::Result<()> {
3110    /// let p = &StandardPolicy::new();
3111    ///
3112    /// #     let (cert, _) =
3113    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3114    /// #         .generate()?;
3115    /// for ka in cert.keys().with_policy(p, None) {
3116    ///     if ka.for_authentication() {
3117    ///         // `ka` is authentication capable.
3118    ///     }
3119    /// }
3120    /// # Ok(()) }
3121    /// ```
3122    ///
3123    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3124    pub fn for_authentication(&self) -> bool
3125    {
3126        self.has_any_key_flag(KeyFlags::empty().set_authentication())
3127    }
3128
3129    /// Returns whether the key is storage-encryption capable.
3130    ///
3131    /// OpenPGP distinguishes two types of encryption keys: those for
3132    /// storage ([data at rest]) and those for transport ([data in
3133    /// transit]).  Most OpenPGP implementations, however, don't
3134    /// distinguish between them in practice.  Instead, when they
3135    /// create a new encryption key, they just set both flags.
3136    /// Likewise, when encrypting a message, it is not typically
3137    /// possible to indicate the type of protection that is needed.
3138    /// Sequoia supports creating keys with only one of these flags
3139    /// set, and makes it easy to select the right type of key when
3140    /// encrypting messages.
3141    ///
3142    /// The key flags are looked up as described in
3143    /// [`ValidKeyAmalgamation::key_flags`].
3144    ///
3145    /// # Examples
3146    ///
3147    /// Finds keys that are storage-encryption capable:
3148    ///
3149    /// ```
3150    /// # use sequoia_openpgp as openpgp;
3151    /// # use openpgp::cert::prelude::*;
3152    /// use openpgp::policy::StandardPolicy;
3153    ///
3154    /// # fn main() -> openpgp::Result<()> {
3155    /// let p = &StandardPolicy::new();
3156    ///
3157    /// #     let (cert, _) =
3158    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3159    /// #         .generate()?;
3160    /// for ka in cert.keys().with_policy(p, None) {
3161    ///     if ka.for_storage_encryption() {
3162    ///         // `ka` is storage-encryption capable.
3163    ///     }
3164    /// }
3165    /// # Ok(()) }
3166    /// ```
3167    ///
3168    /// [data at rest]: https://en.wikipedia.org/wiki/Data_at_rest
3169    /// [data in transit]: https://en.wikipedia.org/wiki/Data_in_transit
3170    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3171    pub fn for_storage_encryption(&self) -> bool
3172    {
3173        self.has_any_key_flag(KeyFlags::empty().set_storage_encryption())
3174    }
3175
3176    /// Returns whether the key is transport-encryption capable.
3177    ///
3178    /// OpenPGP distinguishes two types of encryption keys: those for
3179    /// storage ([data at rest]) and those for transport ([data in
3180    /// transit]).  Most OpenPGP implementations, however, don't
3181    /// distinguish between them in practice.  Instead, when they
3182    /// create a new encryption key, they just set both flags.
3183    /// Likewise, when encrypting a message, it is not typically
3184    /// possible to indicate the type of protection that is needed.
3185    /// Sequoia supports creating keys with only one of these flags
3186    /// set, and makes it easy to select the right type of key when
3187    /// encrypting messages.
3188    ///
3189    /// The key flags are looked up as described in
3190    /// [`ValidKeyAmalgamation::key_flags`].
3191    ///
3192    /// # Examples
3193    ///
3194    /// Finds keys that are transport-encryption capable:
3195    ///
3196    /// ```
3197    /// # use sequoia_openpgp as openpgp;
3198    /// # use openpgp::cert::prelude::*;
3199    /// use openpgp::policy::StandardPolicy;
3200    ///
3201    /// # fn main() -> openpgp::Result<()> {
3202    /// let p = &StandardPolicy::new();
3203    ///
3204    /// #     let (cert, _) =
3205    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3206    /// #         .generate()?;
3207    /// for ka in cert.keys().with_policy(p, None) {
3208    ///     if ka.for_transport_encryption() {
3209    ///         // `ka` is transport-encryption capable.
3210    ///     }
3211    /// }
3212    /// # Ok(()) }
3213    /// ```
3214    ///
3215    /// [data at rest]: https://en.wikipedia.org/wiki/Data_at_rest
3216    /// [data in transit]: https://en.wikipedia.org/wiki/Data_in_transit
3217    /// [`ValidKeyAmalgamation::key_flags`]: ValidKeyAmalgamation::key_flags()
3218    pub fn for_transport_encryption(&self) -> bool
3219    {
3220        self.has_any_key_flag(KeyFlags::empty().set_transport_encryption())
3221    }
3222
3223    /// Returns how long the key is live.
3224    ///
3225    /// This returns how long the key is live relative to its creation
3226    /// time.  Use [`ValidKeyAmalgamation::key_expiration_time`] to
3227    /// get the key's absolute expiry time.
3228    ///
3229    /// This function considers both the binding signature and the
3230    /// direct key signature.  Information in the binding signature
3231    /// takes precedence over the direct key signature.  See [Section
3232    /// 5.2.3.10 of RFC 9580].
3233    ///
3234    /// # Examples
3235    ///
3236    /// ```
3237    /// use std::time;
3238    /// use std::convert::TryInto;
3239    /// # use sequoia_openpgp as openpgp;
3240    /// # use openpgp::cert::prelude::*;
3241    /// use openpgp::policy::StandardPolicy;
3242    /// use openpgp::types::Timestamp;
3243    ///
3244    /// # fn main() -> openpgp::Result<()> {
3245    /// let p = &StandardPolicy::new();
3246    ///
3247    /// // OpenPGP Timestamps have a one-second resolution.  Since we
3248    /// // want to round trip the time, round it down.
3249    /// let now: Timestamp = time::SystemTime::now().try_into()?;
3250    /// let now: time::SystemTime = now.try_into()?;
3251    ///
3252    /// let a_week = time::Duration::from_secs(7 * 24 * 60 * 60);
3253    ///
3254    /// let (cert, _) =
3255    ///     CertBuilder::general_purpose(Some("alice@example.org"))
3256    ///     .set_creation_time(now)
3257    ///     .set_validity_period(a_week)
3258    ///     .generate()?;
3259    ///
3260    /// assert_eq!(cert.primary_key().with_policy(p, None)?.key_validity_period(),
3261    ///            Some(a_week));
3262    /// # Ok(()) }
3263    /// ```
3264    ///
3265    ///   [`ValidKeyAmalgamation::key_expiration_time`]: ValidKeyAmalgamation::key_expiration_time()
3266    ///   [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
3267    pub fn key_validity_period(&self) -> Option<std::time::Duration> {
3268        self.map(|s| s.key_validity_period())
3269    }
3270
3271    /// Returns the key's expiration time.
3272    ///
3273    /// If this function returns `None`, the key does not expire.
3274    ///
3275    /// This returns the key's expiration time.  Use
3276    /// [`ValidKeyAmalgamation::key_validity_period`] to get the
3277    /// duration of the key's lifetime.
3278    ///
3279    /// This function considers both the binding signature and the
3280    /// direct key signature.  Information in the binding signature
3281    /// takes precedence over the direct key signature.  See [Section
3282    /// 5.2.3.10 of RFC 9580].
3283    ///
3284    /// # Examples
3285    ///
3286    /// ```
3287    /// use std::time;
3288    /// use std::convert::TryInto;
3289    /// # use sequoia_openpgp as openpgp;
3290    /// # use openpgp::cert::prelude::*;
3291    /// use openpgp::policy::StandardPolicy;
3292    /// use openpgp::types::Timestamp;
3293    ///
3294    /// # fn main() -> openpgp::Result<()> {
3295    /// let p = &StandardPolicy::new();
3296    ///
3297    /// // OpenPGP Timestamps have a one-second resolution.  Since we
3298    /// // want to round trip the time, round it down.
3299    /// let now: Timestamp = time::SystemTime::now().try_into()?;
3300    /// let now: time::SystemTime = now.try_into()?;
3301    //
3302    /// let a_week = time::Duration::from_secs(7 * 24 * 60 * 60);
3303    /// let a_week_later = now + a_week;
3304    ///
3305    /// let (cert, _) =
3306    ///     CertBuilder::general_purpose(Some("alice@example.org"))
3307    ///     .set_creation_time(now)
3308    ///     .set_validity_period(a_week)
3309    ///     .generate()?;
3310    ///
3311    /// assert_eq!(cert.primary_key().with_policy(p, None)?.key_expiration_time(),
3312    ///            Some(a_week_later));
3313    /// # Ok(()) }
3314    /// ```
3315    ///
3316    ///   [`ValidKeyAmalgamation::key_validity_period`]: ValidKeyAmalgamation::key_validity_period()
3317    ///   [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
3318    pub fn key_expiration_time(&self) -> Option<time::SystemTime> {
3319        match self.key_validity_period() {
3320            Some(vp) if vp.as_secs() > 0 => Some(self.key().creation_time() + vp),
3321            _ => None,
3322        }
3323    }
3324
3325    // NOTE: If you add a method to ValidKeyAmalgamation that takes
3326    // ownership of self, then don't forget to write a forwarder for
3327    // it for ValidPrimaryKeyAmalgamation.
3328}
3329
3330
3331#[cfg(test)]
3332mod test {
3333    use std::time::Duration;
3334    use std::time::UNIX_EPOCH;
3335
3336    use crate::policy::StandardPolicy as P;
3337    use crate::cert::prelude::*;
3338    use crate::packet::Packet;
3339    use crate::packet::signature::SignatureBuilder;
3340    use crate::types::ReasonForRevocation;
3341    use crate::types::RevocationType;
3342
3343    use super::*;
3344
3345    #[test]
3346    fn expire_subkeys() {
3347        let p = &P::new();
3348
3349        // Timeline:
3350        //
3351        // -1: Key created with no key expiration.
3352        // 0: Setkeys set to expire in 1 year
3353        // 1: Subkeys expire
3354
3355        let now = crate::now();
3356        let a_year = time::Duration::from_secs(365 * 24 * 60 * 60);
3357        let in_a_year = now + a_year;
3358        let in_two_years = now + 2 * a_year;
3359
3360        let (cert, _) = CertBuilder::new()
3361            .set_creation_time(now - a_year)
3362            .add_signing_subkey()
3363            .add_transport_encryption_subkey()
3364            .generate().unwrap();
3365
3366        for ka in cert.keys().with_policy(p, None) {
3367            assert!(ka.alive().is_ok());
3368        }
3369
3370        let mut primary_signer = cert.primary_key().key().clone()
3371            .parts_into_secret().unwrap().into_keypair().unwrap();
3372        let mut signing_subkey_signer = cert.with_policy(p, None).unwrap()
3373            .keys().for_signing().next().unwrap()
3374            .key().clone().parts_into_secret().unwrap()
3375            .into_keypair().unwrap();
3376
3377        // Only expire the subkeys.
3378        let sigs = cert.keys().subkeys().with_policy(p, None)
3379            .flat_map(|ka| {
3380                if ! ka.for_signing() {
3381                    ka.set_expiration_time(&mut primary_signer,
3382                                           None,
3383                                           Some(in_a_year)).unwrap()
3384                } else {
3385                    ka.set_expiration_time(&mut primary_signer,
3386                                           Some(&mut signing_subkey_signer),
3387                                           Some(in_a_year)).unwrap()
3388                }
3389                    .into_iter()
3390                    .map(Into::into)
3391            })
3392            .collect::<Vec<Packet>>();
3393        let cert = cert.insert_packets(sigs).unwrap().0;
3394
3395        for ka in cert.keys().with_policy(p, None) {
3396            assert!(ka.alive().is_ok());
3397        }
3398
3399        // Primary should not be expired two years from now.
3400        assert!(cert.primary_key().with_policy(p, in_two_years).unwrap()
3401                .alive().is_ok());
3402        // But the subkeys should be.
3403        for ka in cert.keys().subkeys().with_policy(p, in_two_years) {
3404            assert!(ka.alive().is_err());
3405        }
3406    }
3407
3408    /// Test that subkeys of expired certificates are also considered
3409    /// expired.
3410    #[test]
3411    fn issue_564() -> Result<()> {
3412        use crate::parse::Parse;
3413        use crate::packet::signature::subpacket::SubpacketTag;
3414        let p = &P::new();
3415        let cert = Cert::from_bytes(crate::tests::key("testy.pgp"))?;
3416        assert!(cert.with_policy(p, None)?.alive().is_err());
3417        let subkey = cert.with_policy(p, None)?.keys().nth(1).unwrap();
3418        assert!(subkey.binding_signature().hashed_area()
3419                .subpacket(SubpacketTag::KeyExpirationTime).is_none());
3420        assert!(subkey.alive().is_err());
3421        Ok(())
3422    }
3423
3424    /// When setting the primary key's validity period, we create a
3425    /// direct key signature.  Check that this works even when the
3426    /// original certificate doesn't have a direct key signature.
3427    #[test]
3428    fn set_expiry_on_certificate_without_direct_signature() -> Result<()> {
3429        use crate::policy::StandardPolicy;
3430
3431        let p = &StandardPolicy::new();
3432
3433        let (cert, _) =
3434            CertBuilder::general_purpose(Some("alice@example.org"))
3435            .set_validity_period(None)
3436            .generate()?;
3437
3438        // Remove the direct key signatures.
3439        let cert = Cert::from_packets(
3440            cert.as_tsk().into_packets()
3441            .filter(|p| ! matches!(
3442                        p,
3443                        Packet::Signature(s) if s.typ() == SignatureType::DirectKey
3444            )))?;
3445
3446        let vc = cert.with_policy(p, None)?;
3447
3448        // Assert that the keys are not expired.
3449        for ka in vc.keys() {
3450            assert!(ka.alive().is_ok());
3451        }
3452
3453        // Make the primary key expire in a week.
3454        let t = crate::now()
3455            + time::Duration::from_secs(7 * 24 * 60 * 60);
3456
3457        let mut signer = vc
3458            .primary_key().key().clone().parts_into_secret()?
3459            .into_keypair()?;
3460        let sigs = vc.primary_key()
3461            .set_expiration_time(&mut signer, Some(t))?;
3462
3463        assert!(sigs.iter().any(|s| {
3464            s.typ() == SignatureType::DirectKey
3465        }));
3466
3467        let cert = cert.insert_packets(sigs)?.0;
3468
3469        // Make sure the primary key *and* all subkeys expire in a
3470        // week: the subkeys inherit the KeyExpirationTime subpacket
3471        // from the direct key signature.
3472        for ka in cert.keys() {
3473            let ka = ka.with_policy(p, None)?;
3474            assert!(ka.alive().is_ok());
3475
3476            let ka = ka.with_policy(p, t + std::time::Duration::new(1, 0))?;
3477            assert!(ka.alive().is_err());
3478        }
3479
3480        Ok(())
3481    }
3482
3483    #[test]
3484    fn key_amalgamation_certifications_by_key() -> Result<()> {
3485        // Alice and Bob certify Carol's certificate.  We then check
3486        // that valid_certifications_by_key and
3487        // active_certifications_by_key return them.
3488        let p = &crate::policy::StandardPolicy::new();
3489
3490        // $ date -u -d '2024-01-02 13:00' +%s
3491        let t0 = UNIX_EPOCH + Duration::new(1704200400, 0);
3492        // $ date -u -d '2024-01-02 14:00' +%s
3493        let t1 = UNIX_EPOCH + Duration::new(1704204000, 0);
3494        // $ date -u -d '2024-01-02 15:00' +%s
3495        let t2 = UNIX_EPOCH + Duration::new(1704207600, 0);
3496
3497        let (alice, _) = CertBuilder::new()
3498            .set_creation_time(t0)
3499            .add_userid("<alice@example.example>")
3500            .generate()
3501            .unwrap();
3502        let alice_primary = alice.primary_key().key();
3503
3504        let (bob, _) = CertBuilder::new()
3505            .set_creation_time(t0)
3506            .add_userid("<bob@example.example>")
3507            .generate()
3508            .unwrap();
3509        let bob_primary = bob.primary_key().key();
3510
3511        let carol_userid = "<carol@example.example>";
3512        let (carol, _) = CertBuilder::new()
3513            .set_creation_time(t0)
3514            .add_userid(carol_userid)
3515            .generate()
3516            .unwrap();
3517
3518        let ka = alice.primary_key();
3519        assert_eq!(
3520            ka.valid_certifications_by_key(p, None, alice_primary).count(),
3521            0);
3522        assert_eq!(
3523            ka.active_certifications_by_key(p, None, alice_primary).count(),
3524            0);
3525
3526        // Alice has not certified Bob's User ID.
3527        let ka = bob.primary_key();
3528        assert_eq!(
3529            ka.valid_certifications_by_key(p, None, alice_primary).count(),
3530            0);
3531        assert_eq!(
3532            ka.active_certifications_by_key(p, None, alice_primary).count(),
3533            0);
3534
3535        // Alice has not certified Carol's User ID.
3536        let ka = carol.primary_key();
3537        assert_eq!(
3538            ka.valid_certifications_by_key(p, None, alice_primary).count(),
3539            0);
3540        assert_eq!(
3541            ka.active_certifications_by_key(p, None, alice_primary).count(),
3542            0);
3543
3544
3545        // Have Alice certify Carol's certificate at t1.
3546        let mut alice_signer = alice_primary
3547            .clone()
3548            .parts_into_secret().expect("have unencrypted key material")
3549            .into_keypair().expect("have unencrypted key material");
3550        let certification = SignatureBuilder::new(SignatureType::DirectKey)
3551            .set_signature_creation_time(t1)?
3552            .sign_direct_key(
3553                &mut alice_signer,
3554                carol.primary_key().key())?;
3555        let carol = carol.insert_packets(certification.clone())?.0;
3556
3557        // Check that it is returned.
3558        let ka = carol.primary_key();
3559        assert_eq!(ka.certifications().count(), 1);
3560
3561        assert_eq!(
3562            ka.valid_certifications_by_key(p, t0, alice_primary).count(),
3563            0);
3564        assert_eq!(
3565            ka.active_certifications_by_key(p, t0, alice_primary).count(),
3566            0);
3567
3568        assert_eq!(
3569            ka.valid_certifications_by_key(p, t1, alice_primary).count(),
3570            1);
3571        assert_eq!(
3572            ka.active_certifications_by_key(p, t1, alice_primary).count(),
3573            1);
3574
3575        assert_eq!(
3576            ka.valid_certifications_by_key(p, t1, bob_primary).count(),
3577            0);
3578        assert_eq!(
3579            ka.active_certifications_by_key(p, t1, bob_primary).count(),
3580            0);
3581
3582
3583        // Have Alice certify Carol's certificate at t1 (again).
3584        // Since both certifications were created at t1, they should
3585        // both be returned.
3586        let mut alice_signer = alice_primary
3587            .clone()
3588            .parts_into_secret().expect("have unencrypted key material")
3589            .into_keypair().expect("have unencrypted key material");
3590        let certification = SignatureBuilder::new(SignatureType::DirectKey)
3591            .set_signature_creation_time(t1)?
3592            .sign_direct_key(
3593                &mut alice_signer,
3594                carol.primary_key().key())?;
3595        let carol = carol.insert_packets(certification.clone())?.0;
3596
3597        // Check that it is returned.
3598        let ka = carol.primary_key();
3599        assert_eq!(ka.certifications().count(), 2);
3600        assert_eq!(
3601            ka.valid_certifications_by_key(p, t0, alice_primary).count(),
3602            0);
3603        assert_eq!(
3604            ka.active_certifications_by_key(p, t0, alice_primary).count(),
3605            0);
3606
3607        assert_eq!(
3608            ka.valid_certifications_by_key(p, t1, alice_primary).count(),
3609            2);
3610        assert_eq!(
3611            ka.active_certifications_by_key(p, t1, alice_primary).count(),
3612            2);
3613
3614        assert_eq!(
3615            ka.valid_certifications_by_key(p, t2, alice_primary).count(),
3616            2);
3617        assert_eq!(
3618            ka.active_certifications_by_key(p, t2, alice_primary).count(),
3619            2);
3620
3621        assert_eq!(
3622            ka.valid_certifications_by_key(p, t0, bob_primary).count(),
3623            0);
3624        assert_eq!(
3625            ka.active_certifications_by_key(p, t0, bob_primary).count(),
3626            0);
3627
3628
3629        // Have Alice certify Carol's certificate at t2.  Now we only
3630        // have one active certification.
3631        let mut alice_signer = alice_primary
3632            .clone()
3633            .parts_into_secret().expect("have unencrypted key material")
3634            .into_keypair().expect("have unencrypted key material");
3635        let certification = SignatureBuilder::new(SignatureType::DirectKey)
3636            .set_signature_creation_time(t2)?
3637            .sign_direct_key(
3638                &mut alice_signer,
3639                carol.primary_key().key())?;
3640        let carol = carol.insert_packets(certification.clone())?.0;
3641
3642        // Check that it is returned.
3643        let ka = carol.primary_key();
3644        assert_eq!(ka.certifications().count(), 3);
3645        assert_eq!(
3646            ka.valid_certifications_by_key(p, t0, alice_primary).count(),
3647            0);
3648        assert_eq!(
3649            ka.active_certifications_by_key(p, t0, alice_primary).count(),
3650            0);
3651
3652        assert_eq!(
3653            ka.valid_certifications_by_key(p, t1, alice_primary).count(),
3654            2);
3655        assert_eq!(
3656            ka.active_certifications_by_key(p, t1, alice_primary).count(),
3657            2);
3658
3659        assert_eq!(
3660            ka.valid_certifications_by_key(p, t2, alice_primary).count(),
3661            3);
3662        assert_eq!(
3663            ka.active_certifications_by_key(p, t2, alice_primary).count(),
3664            1);
3665
3666        assert_eq!(
3667            ka.valid_certifications_by_key(p, t0, bob_primary).count(),
3668            0);
3669        assert_eq!(
3670            ka.active_certifications_by_key(p, t0, bob_primary).count(),
3671            0);
3672
3673
3674        // Have Bob certify Carol's certificate at t1 and have it expire at t2.
3675        let mut bob_signer = bob.primary_key()
3676            .key()
3677            .clone()
3678            .parts_into_secret().expect("have unencrypted key material")
3679            .into_keypair().expect("have unencrypted key material");
3680        let certification = SignatureBuilder::new(SignatureType::DirectKey)
3681            .set_signature_creation_time(t1)?
3682            .set_signature_validity_period(t2.duration_since(t1)?)?
3683            .sign_direct_key(
3684                &mut bob_signer,
3685                carol.primary_key().key())?;
3686        let carol = carol.insert_packets(certification.clone())?.0;
3687
3688        // Check that it is returned.
3689        let ka = carol.primary_key();
3690        assert_eq!(ka.certifications().count(), 4);
3691
3692        assert_eq!(
3693            ka.valid_certifications_by_key(p, t0, alice_primary).count(),
3694            0);
3695        assert_eq!(
3696            ka.active_certifications_by_key(p, t0, alice_primary).count(),
3697            0);
3698
3699        assert_eq!(
3700            ka.valid_certifications_by_key(p, t1, alice_primary).count(),
3701            2);
3702        assert_eq!(
3703            ka.active_certifications_by_key(p, t1, alice_primary).count(),
3704            2);
3705
3706        assert_eq!(
3707            ka.valid_certifications_by_key(p, t2, alice_primary).count(),
3708            3);
3709        assert_eq!(
3710            ka.active_certifications_by_key(p, t2, alice_primary).count(),
3711            1);
3712
3713        assert_eq!(
3714            ka.valid_certifications_by_key(p, t0, bob_primary).count(),
3715            0);
3716        assert_eq!(
3717            ka.active_certifications_by_key(p, t0, bob_primary).count(),
3718            0);
3719
3720        assert_eq!(
3721            ka.valid_certifications_by_key(p, t1, bob_primary).count(),
3722            1);
3723        assert_eq!(
3724            ka.active_certifications_by_key(p, t1, bob_primary).count(),
3725            1);
3726
3727        // It expired.
3728        assert_eq!(
3729            ka.valid_certifications_by_key(p, t2, bob_primary).count(),
3730            0);
3731        assert_eq!(
3732            ka.active_certifications_by_key(p, t2, bob_primary).count(),
3733            0);
3734
3735
3736        // Have Bob certify Carol's certificate at t1 again.  This
3737        // time don't have it expire.
3738        let mut bob_signer = bob.primary_key()
3739            .key()
3740            .clone()
3741            .parts_into_secret().expect("have unencrypted key material")
3742            .into_keypair().expect("have unencrypted key material");
3743        let certification = SignatureBuilder::new(SignatureType::DirectKey)
3744            .set_signature_creation_time(t1)?
3745            .sign_direct_key(
3746                &mut bob_signer,
3747                carol.primary_key().key())?;
3748        let carol = carol.insert_packets(certification.clone())?.0;
3749
3750        // Check that it is returned.
3751        let ka = carol.primary_key();
3752        assert_eq!(ka.certifications().count(), 5);
3753        assert_eq!(
3754            ka.valid_certifications_by_key(p, t0, alice_primary).count(),
3755            0);
3756        assert_eq!(
3757            ka.active_certifications_by_key(p, t0, alice_primary).count(),
3758            0);
3759
3760        assert_eq!(
3761            ka.valid_certifications_by_key(p, t1, alice_primary).count(),
3762            2);
3763        assert_eq!(
3764            ka.active_certifications_by_key(p, t1, alice_primary).count(),
3765            2);
3766
3767        assert_eq!(
3768            ka.valid_certifications_by_key(p, t2, alice_primary).count(),
3769            3);
3770        assert_eq!(
3771            ka.active_certifications_by_key(p, t2, alice_primary).count(),
3772            1);
3773
3774        assert_eq!(
3775            ka.valid_certifications_by_key(p, t0, bob_primary).count(),
3776            0);
3777        assert_eq!(
3778            ka.active_certifications_by_key(p, t0, bob_primary).count(),
3779            0);
3780
3781        assert_eq!(
3782            ka.valid_certifications_by_key(p, t1, bob_primary).count(),
3783            2);
3784        assert_eq!(
3785            ka.active_certifications_by_key(p, t1, bob_primary).count(),
3786            2);
3787
3788        // One of the certifications expired.
3789        assert_eq!(
3790            ka.valid_certifications_by_key(p, t2, bob_primary).count(),
3791            1);
3792        assert_eq!(
3793            ka.active_certifications_by_key(p, t2, bob_primary).count(),
3794            1);
3795
3796        Ok(())
3797    }
3798
3799    fn key_amalgamation_valid_third_party_revocations_by_key(
3800        reason: ReasonForRevocation)
3801        -> Result<()>
3802    {
3803        // Hard revocations are returned independent of the reference
3804        // time and independent of their expiration.  They are always
3805        // live.
3806        let soft = reason.revocation_type() == RevocationType::Soft;
3807
3808        // Alice and Bob revoke Carol's certificate.  We then check
3809        // that valid_third_party_revocations_by_key returns them.
3810        let p = &crate::policy::StandardPolicy::new();
3811
3812        // $ date -u -d '2024-01-02 13:00' +%s
3813        let t0 = UNIX_EPOCH + Duration::new(1704200400, 0);
3814        // $ date -u -d '2024-01-02 14:00' +%s
3815        let t1 = UNIX_EPOCH + Duration::new(1704204000, 0);
3816        // $ date -u -d '2024-01-02 15:00' +%s
3817        let t2 = UNIX_EPOCH + Duration::new(1704207600, 0);
3818
3819        let (alice, _) = CertBuilder::new()
3820            .set_creation_time(t0)
3821            .add_userid("<alice@example.example>")
3822            .generate()
3823            .unwrap();
3824        let alice_primary = alice.primary_key().key();
3825
3826        let (bob, _) = CertBuilder::new()
3827            .set_creation_time(t0)
3828            .add_userid("<bob@example.example>")
3829            .generate()
3830            .unwrap();
3831        let bob_primary = bob.primary_key().key();
3832
3833        let carol_userid = "<carol@example.example>";
3834        let (carol, _) = CertBuilder::new()
3835            .set_creation_time(t0)
3836            .add_userid(carol_userid)
3837            .generate()
3838            .unwrap();
3839
3840        let ka = alice.primary_key();
3841        assert_eq!(
3842            ka.valid_third_party_revocations_by_key(p, None, alice_primary).count(),
3843            0);
3844
3845        // Alice has not revoked Bob's certificate.
3846        let ka = bob.primary_key();
3847        assert_eq!(
3848            ka.valid_third_party_revocations_by_key(p, None, alice_primary).count(),
3849            0);
3850
3851        // Alice has not revoked Carol's certificate.
3852        let ka = carol.primary_key();
3853        assert_eq!(
3854            ka.valid_third_party_revocations_by_key(p, None, alice_primary).count(),
3855            0);
3856
3857
3858        // Have Alice revoke Carol's revoke at t1.
3859        let mut alice_signer = alice_primary
3860            .clone()
3861            .parts_into_secret().expect("have unencrypted key material")
3862            .into_keypair().expect("have unencrypted key material");
3863        let rev = SignatureBuilder::new(SignatureType::KeyRevocation)
3864            .set_signature_creation_time(t1)?
3865            .set_reason_for_revocation(
3866                reason, b"")?
3867            .sign_direct_key(
3868                &mut alice_signer,
3869                carol.primary_key().key())?;
3870        let carol = carol.insert_packets(rev)?.0;
3871
3872        // Check that it is returned.
3873        let ka = carol.primary_key();
3874        assert_eq!(ka.other_revocations().count(), 1);
3875
3876        assert_eq!(
3877            ka.valid_third_party_revocations_by_key(p, t0, alice_primary).count(),
3878            if soft { 0 } else { 1 });
3879        assert_eq!(
3880            ka.valid_third_party_revocations_by_key(p, t1, alice_primary).count(),
3881            1);
3882        assert_eq!(
3883            ka.valid_third_party_revocations_by_key(p, t1, bob_primary).count(),
3884            0);
3885
3886
3887        // Have Alice revoke Carol's certificate at t1 (again).
3888        let mut alice_signer = alice_primary
3889            .clone()
3890            .parts_into_secret().expect("have unencrypted key material")
3891            .into_keypair().expect("have unencrypted key material");
3892        let rev = SignatureBuilder::new(SignatureType::KeyRevocation)
3893            .set_signature_creation_time(t1)?
3894            .set_reason_for_revocation(reason, b"")?
3895            .sign_direct_key(
3896                &mut alice_signer,
3897                carol.primary_key().key())?;
3898        let carol = carol.insert_packets(rev)?.0;
3899
3900        // Check that it is returned.
3901        let ka = carol.primary_key();
3902        assert_eq!(ka.other_revocations().count(), 2);
3903        assert_eq!(
3904            ka.valid_third_party_revocations_by_key(p, t0, alice_primary).count(),
3905            if soft { 0 } else { 2 });
3906        assert_eq!(
3907            ka.valid_third_party_revocations_by_key(p, t1, alice_primary).count(),
3908            2);
3909        assert_eq!(
3910            ka.valid_third_party_revocations_by_key(p, t2, alice_primary).count(),
3911            2);
3912        assert_eq!(
3913            ka.valid_third_party_revocations_by_key(p, t0, bob_primary).count(),
3914            0);
3915
3916
3917        // Have Alice revoke Carol's certificate at t2.
3918        let mut alice_signer = alice_primary
3919            .clone()
3920            .parts_into_secret().expect("have unencrypted key material")
3921            .into_keypair().expect("have unencrypted key material");
3922        let rev = SignatureBuilder::new(SignatureType::KeyRevocation)
3923            .set_signature_creation_time(t2)?
3924            .set_reason_for_revocation(reason, b"")?
3925            .sign_direct_key(
3926                &mut alice_signer,
3927                carol.primary_key().key())?;
3928        let carol = carol.insert_packets(rev)?.0;
3929
3930        // Check that it is returned.
3931        let ka = carol.primary_key();
3932        assert_eq!(ka.other_revocations().count(), 3);
3933        assert_eq!(
3934            ka.valid_third_party_revocations_by_key(p, t0, alice_primary).count(),
3935            if soft { 0 } else { 3 });
3936        assert_eq!(
3937            ka.valid_third_party_revocations_by_key(p, t1, alice_primary).count(),
3938            if soft { 2 } else { 3 });
3939        assert_eq!(
3940            ka.valid_third_party_revocations_by_key(p, t2, alice_primary).count(),
3941            3);
3942        assert_eq!(
3943            ka.valid_third_party_revocations_by_key(p, t0, bob_primary).count(),
3944            0);
3945
3946
3947        // Have Bob revoke Carol's certificate at t1 and have it expire at t2.
3948        let mut bob_signer = bob.primary_key()
3949            .key()
3950            .clone()
3951            .parts_into_secret().expect("have unencrypted key material")
3952            .into_keypair().expect("have unencrypted key material");
3953        let rev = SignatureBuilder::new(SignatureType::KeyRevocation)
3954            .set_signature_creation_time(t1)?
3955            .set_signature_validity_period(t2.duration_since(t1)?)?
3956            .set_reason_for_revocation(reason, b"")?
3957            .sign_direct_key(
3958                &mut bob_signer,
3959                carol.primary_key().key())?;
3960        let carol = carol.insert_packets(rev)?.0;
3961
3962        // Check that it is returned.
3963        let ka = carol.primary_key();
3964        assert_eq!(ka.other_revocations().count(), 4);
3965
3966        assert_eq!(
3967            ka.valid_third_party_revocations_by_key(p, t0, alice_primary).count(),
3968            if soft { 0 } else { 3 });
3969        assert_eq!(
3970            ka.valid_third_party_revocations_by_key(p, t1, alice_primary).count(),
3971            if soft { 2 } else { 3 });
3972        assert_eq!(
3973            ka.valid_third_party_revocations_by_key(p, t2, alice_primary).count(),
3974            3);
3975        assert_eq!(
3976            ka.valid_third_party_revocations_by_key(p, t0, bob_primary).count(),
3977            if soft { 0 } else { 1 });
3978        assert_eq!(
3979            ka.valid_third_party_revocations_by_key(p, t1, bob_primary).count(),
3980            1);
3981        // It expired.
3982        assert_eq!(
3983            ka.valid_third_party_revocations_by_key(p, t2, bob_primary).count(),
3984            if soft { 0 } else { 1 });
3985
3986
3987        // Have Bob revoke Carol's certificate at t1 again.  This
3988        // time don't have it expire.
3989        let mut bob_signer = bob.primary_key()
3990            .key()
3991            .clone()
3992            .parts_into_secret().expect("have unencrypted key material")
3993            .into_keypair().expect("have unencrypted key material");
3994        let rev = SignatureBuilder::new(SignatureType::KeyRevocation)
3995            .set_signature_creation_time(t1)?
3996            .set_reason_for_revocation(reason, b"")?
3997            .sign_direct_key(
3998                &mut bob_signer,
3999                carol.primary_key().key())?;
4000        let carol = carol.insert_packets(rev)?.0;
4001
4002        // Check that it is returned.
4003        let ka = carol.primary_key();
4004        assert_eq!(
4005            ka.other_revocations().count(), 5);
4006        assert_eq!(
4007            ka.valid_third_party_revocations_by_key(p, t0, alice_primary).count(),
4008            if soft { 0 } else { 3 });
4009        assert_eq!(
4010            ka.valid_third_party_revocations_by_key(p, t1, alice_primary).count(),
4011            if soft { 2 } else { 3 });
4012        assert_eq!(
4013            ka.valid_third_party_revocations_by_key(p, t2, alice_primary).count(),
4014            3);
4015        assert_eq!(
4016            ka.valid_third_party_revocations_by_key(p, t0, bob_primary).count(),
4017            if soft { 0 } else { 2 });
4018        assert_eq!(
4019            ka.valid_third_party_revocations_by_key(p, t1, bob_primary).count(),
4020            2);
4021        // One of the revocations expired.
4022        assert_eq!(
4023            ka.valid_third_party_revocations_by_key(p, t2, bob_primary).count(),
4024            if soft { 1 } else { 2 });
4025
4026        Ok(())
4027    }
4028
4029    #[test]
4030    fn key_amalgamation_valid_third_party_revocations_by_key_soft()
4031        -> Result<()>
4032    {
4033        key_amalgamation_valid_third_party_revocations_by_key(
4034            ReasonForRevocation::KeyRetired)
4035    }
4036
4037    #[test]
4038    fn key_amalgamation_valid_third_party_revocations_by_key_hard()
4039        -> Result<()>
4040    {
4041        key_amalgamation_valid_third_party_revocations_by_key(
4042            ReasonForRevocation::KeyCompromised)
4043    }
4044}