Skip to main content

sequoia_openpgp/
cert.rs

1//! Certificates and related data structures.
2//!
3//! An OpenPGP certificate, often called a `PGP key` or just a `key,`
4//! is a collection of keys, identity information, and certifications
5//! about those keys and identities.
6//!
7//! The foundation of an OpenPGP certificate is the so-called primary
8//! key.  A primary key has three essential functions.  First, the
9//! primary key is used to derive a universally unique identifier
10//! (UUID) for the certificate, the certificate's so-called
11//! fingerprint.  Second, the primary key is used to certify
12//! assertions that the certificate holder makes about their
13//! certificate.  For instance, to associate a subkey or a User ID
14//! with a certificate, the certificate holder uses the primary key to
15//! create a self signature called a binding signature.  This binding
16//! signature is distributed with the certificate.  It allows anyone
17//! who has the certificate to verify that the certificate holder
18//! (identified by the primary key) really intended for the subkey to
19//! be associated with the certificate.  Finally, the primary key can
20//! be used to make assertions about other certificates.  For
21//! instance, Alice can make a so-called third-party certification
22//! that attests that she is convinced that `Bob` (as described by
23//! some User ID) controls a particular certificate.  These
24//! third-party certifications are typically distributed alongside the
25//! signee's certificate, and are used by trust models like the Web of
26//! Trust to authenticate certificates.
27//!
28//! # Common Operations
29//!
30//!  - *Generating a certificate*: See the [`CertBuilder`] module.
31//!  - *Parsing a certificate*: See the [`Parser` implementation] for `Cert`.
32//!  - *Parsing a keyring*: See the [`CertParser`] module.
33//!  - *Serializing a certificate*: See the [`Serialize`
34//!    implementation] for `Cert`, and the [`Cert::as_tsk`] method to
35//!    also include any secret key material.
36//!  - *Using a certificate*: See the [`Cert`] and [`ValidCert`] data structures.
37//!  - *Revoking a certificate*: See the [`CertRevocationBuilder`] data structure.
38//!  - *Decrypt or encrypt secret keys*: See [`packet::Key::encrypt_secret`]'s example.
39//!  - *Merging packets*: See the [`Cert::insert_packets`] method.
40//!  - *Merging certificates*: See the [`Cert::merge_public`] method.
41//!  - *Creating third-party certifications*: See the [`UserID::certify`]
42//!     and [`UserAttribute::certify`] methods.
43//!  - *Using User IDs and User Attributes*: See the [`ComponentAmalgamation`] module.
44//!  - *Using keys*: See the [`KeyAmalgamation`] module.
45//!  - *Updating a binding signature*: See the [`UserID::bind`],
46//!    [`UserAttribute::bind`], and [`Key::bind`] methods.
47//!  - *Checking third-party signatures*: See the
48//!    [`Signature::verify_direct_key`],
49//!    [`Signature::verify_userid_binding`], and
50//!    [`Signature::verify_user_attribute_binding`] methods.
51//!  - *Checking third-party revocations*: See the
52//!    [`ValidCert::revocation_keys`],
53//!    [`ValidAmalgamation::revocation_keys`],
54//!    [`Signature::verify_primary_key_revocation`],
55//!    [`Signature::verify_userid_revocation`],
56//!    [`Signature::verify_user_attribute_revocation`] methods.
57//!
58//! # Data Structures
59//!
60//! ## `Cert`
61//!
62//! The [`Cert`] data structure closely mirrors the transferable
63//! public key (`TPK`) data structure described in [Section 10.1 of
64//! RFC 9580]: it contains the certificate's `Component`s and their
65//! associated signatures.
66//!
67//! ## `Component`s
68//!
69//! In Sequoia, we refer to `User ID`s, `User Attribute`s, and `Key`s
70//! as `Component`s.  To accommodate unsupported components (e.g.,
71//! deprecated v3 keys) and unknown components (e.g., the
72//! yet-to-be-defined `Xyzzy Property`), we also define an `Unknown`
73//! component.
74//!
75//! ## `ComponentBundle`s
76//!
77//! We call a Component and any associated signatures a
78//! [`ComponentBundle`].  There are four types of associated
79//! signatures: self signatures, third-party signatures, self
80//! revocations, and third-party revocations.
81//!
82//! Although some information about a given `Component` is stored in
83//! the `Component` itself, most of the information is stored on the
84//! associated signatures.  For instance, a key's creation time is
85//! stored in the key packet, but the key's capabilities (e.g.,
86//! whether it can be used for encryption or signing), and its expiry
87//! are stored in the associated self signatures.  Thus, to use a
88//! component, we usually need its corresponding self signature.
89//!
90//! When a certificate is parsed, Sequoia ensures that all components
91//! (except the primary key) have at least one valid self signature.
92//! However, when using a component, it is still necessary to find the
93//! right self signature.  And, unfortunately, finding the
94//! self signature for the primary `Key` is non-trivial: that's the
95//! primary User ID's self signature.  Another complication is that if
96//! the self signature doesn't contain the required information, then
97//! the implementation should look for the information on a direct key
98//! signature.  Thus, a `ComponentBundle` doesn't contain all of the
99//! information that is needed to use a component.
100//!
101//! ## `ComponentAmalgamation`s
102//!
103//! To workaround this lack of context, we introduce another data
104//! structure called a [`ComponentAmalgamation`].  A
105//! `ComponentAmalgamation` references a `ComponentBundle` and its
106//! associated `Cert`.  Unfortunately, we can't include a reference to
107//! the `Cert` in the `ComponentBundle`, because the `Cert` owns the
108//! `ComponentBundle`, and that would create a self-referential data
109//! structure, which is currently not supported in Rust.
110//!
111//! [Section 10.1 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1
112//! [`ComponentBundle`]: bundle::ComponentBundle
113//! [`ComponentAmalgamation`]: amalgamation::ComponentAmalgamation
114//! [`Parser` implementation]: struct.Cert.html#impl-Parse%3C%27a%2C%20Cert%3E
115//! [`Serialize` implementation]: struct.Cert.html#impl-Serialize
116//! [`UserID::certify`]: crate::packet::UserID::certify()
117//! [`UserAttribute::certify`]: crate::packet::user_attribute::UserAttribute::certify()
118//! [`KeyAmalgamation`]: amalgamation::key
119//! [`UserID::bind`]: crate::packet::UserID::bind()
120//! [`UserAttribute::bind`]: crate::packet::user_attribute::UserAttribute::bind()
121//! [`Key::bind`]: crate::packet::Key::bind()
122//! [`Signature::verify_direct_key`]: crate::packet::Signature::verify_direct_key()
123//! [`Signature::verify_userid_binding`]: crate::packet::Signature::verify_userid_binding()
124//! [`Signature::verify_user_attribute_binding`]: crate::packet::Signature::verify_user_attribute_binding()
125//! [`ValidAmalgamation::revocation_keys`]: amalgamation::ValidAmalgamation::revocation_keys
126//! [`Signature::verify_primary_key_revocation`]: crate::packet::Signature::verify_primary_key_revocation()
127//! [`Signature::verify_userid_revocation`]: crate::packet::Signature::verify_userid_revocation()
128//! [`Signature::verify_user_attribute_revocation`]: crate::packet::Signature::verify_user_attribute_revocation()
129
130use std::collections::btree_map::BTreeMap;
131use std::collections::btree_map::Entry;
132use std::collections::hash_map::DefaultHasher;
133use std::cmp::Ordering;
134use std::convert::TryFrom;
135use std::hash::Hasher;
136use std::mem;
137use std::fmt;
138use std::time;
139
140use buffered_reader::BufferedReader;
141
142use crate::{
143    crypto::{
144        Signer,
145    },
146    Error,
147    Result,
148    SignatureType,
149    packet,
150    packet::Signature,
151    packet::Key,
152    packet::key,
153    packet::Tag,
154    packet::UserID,
155    packet::UserAttribute,
156    packet::Unknown,
157    Packet,
158    PacketPile,
159    seal,
160    KeyID,
161    Fingerprint,
162    KeyHandle,
163    policy::Policy,
164};
165use crate::parse::{Cookie, Parse, PacketParserResult, PacketParser};
166use crate::types::{
167    AEADAlgorithm,
168    CompressionAlgorithm,
169    Features,
170    HashAlgorithm,
171    KeyServerPreferences,
172    ReasonForRevocation,
173    RevocationKey,
174    RevocationStatus,
175    SymmetricAlgorithm,
176};
177
178pub mod amalgamation;
179mod builder;
180mod bindings;
181pub mod bundle;
182use bundle::{
183    ComponentBundles,
184    UserIDBundles,
185    UserAttributeBundles,
186    SubkeyBundles,
187    UnknownBundles,
188};
189mod lazysigs;
190mod parser;
191pub mod raw;
192mod revoke;
193
194pub use self::builder::{CertBuilder, CipherSuite, KeyBuilder, SubkeyBuilder};
195
196pub use parser::{
197    CertParser,
198};
199
200pub(crate) use parser::{
201    CertValidator,
202    CertValidity,
203    KeyringValidator,
204    KeyringValidity,
205};
206
207pub use revoke::{
208    SubkeyRevocationBuilder,
209    CertRevocationBuilder,
210    UserAttributeRevocationBuilder,
211    UserIDRevocationBuilder,
212};
213
214pub mod prelude;
215use prelude::*;
216
217const TRACE : bool = false;
218
219// Helper functions.
220
221/// Compare the creation time of two signatures.  Order them so that
222/// the more recent signature is first.
223fn canonical_signature_order(a: Option<time::SystemTime>, b: Option<time::SystemTime>)
224                             -> Ordering {
225    // Note: None < Some, so the normal ordering is:
226    //
227    //   None, Some(old), Some(new)
228    //
229    // Reversing the ordering puts the signatures without a creation
230    // time at the end, which is where they belong.
231    a.cmp(&b).reverse()
232}
233
234/// Compares two signatures by creation time using the MPIs as tie-breaker.
235///
236/// Useful to sort signatures so that the most recent ones are at the
237/// front.
238fn sig_cmp(a: &Signature, b: &Signature) -> Ordering {
239    match canonical_signature_order(a.signature_creation_time(),
240                                    b.signature_creation_time()) {
241        Ordering::Equal => a.mpis().cmp(b.mpis()),
242        r => r
243    }
244}
245
246impl fmt::Display for Cert {
247    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248        write!(f, "{}", self.fingerprint())
249    }
250}
251
252/// Returns the certificate holder's preferences.
253///
254/// OpenPGP provides a mechanism for a certificate holder to transmit
255/// information about communication preferences, and key management to
256/// communication partners in an asynchronous manner.  This
257/// information is attached to the certificate itself.  Specifically,
258/// the different types of information are stored as signature
259/// subpackets in the User IDs' self signatures, and in the
260/// certificate's direct key signature.
261///
262/// OpenPGP allows the certificate holder to specify different
263/// information depending on the way the certificate is addressed.
264/// When addressed by User ID, that User ID's self signature is first
265/// checked for the subpacket in question.  If the subpacket is not
266/// present or the certificate is addressed is some other way, for
267/// instance, by its fingerprint, then the primary User ID's
268/// self signature is checked.  If the subpacket is also not there,
269/// then the direct key signature is checked.  This policy and its
270/// justification are described in [Section 5.2.3.10 of RFC 9580].
271///
272/// Note: User IDs may be stripped.  For instance, the [WKD] standard
273/// requires User IDs that are unrelated to the WKD's domain be
274/// stripped from the certificate prior to publication.  As such, any
275/// User ID may be considered the primary User ID.  Consequently, if
276/// any User ID includes a particular subpacket, then all User IDs
277/// should include it.  Furthermore, [Section 10.1.1 of RFC 9580]
278/// allows certificates without any User ID packets.  To handle this
279/// case, certificates should also create a direct key signature with
280/// this information.
281///
282/// [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
283/// [Section 10.1.1 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10.1.1
284/// [WKD]: https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-09#section-5
285///
286/// # Algorithm Preferences
287///
288/// Algorithms are ordered with the most preferred algorithm first.
289/// If an algorithm is not listed, then the
290/// implementation should assume that it is not supported by the
291/// certificate holder's software (see e.g. [Section 5.2.3.15 of RFC
292/// 9580]).
293///
294/// [Section 5.2.3.15 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.15
295///
296/// # Examples
297///
298/// ```
299/// use sequoia_openpgp as openpgp;
300/// # use openpgp::Result;
301/// use openpgp::cert::prelude::*;
302/// use sequoia_openpgp::policy::StandardPolicy;
303///
304/// # fn main() -> Result<()> {
305/// let p = &StandardPolicy::new();
306///
307/// # let (cert, _) =
308/// #     CertBuilder::general_purpose(Some("alice@example.org"))
309/// #     .generate()?;
310/// match cert.with_policy(p, None)?.primary_userid()?.preferred_symmetric_algorithms() {
311///     Some(algos) => {
312///         println!("Certificate Holder's preferred symmetric algorithms:");
313///         for (i, algo) in algos.iter().enumerate() {
314///             println!("{}. {}", i, algo);
315///         }
316///     }
317///     None => {
318///         println!("Certificate Holder did not specify any preferred \
319///                   symmetric algorithms, or the subpacket is missing.");
320///     }
321/// }
322/// # Ok(()) }
323/// ```
324///
325/// # Sealed trait
326///
327/// This trait is [sealed] and cannot be implemented for types outside this crate.
328/// Therefore it can be extended in a non-breaking way.
329/// If you want to implement the trait inside the crate
330/// you also need to implement the `seal::Sealed` marker trait.
331///
332/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
333pub trait Preferences<'a>: seal::Sealed {
334    /// Returns the supported symmetric algorithms ordered by
335    /// preference.
336    ///
337    /// The algorithms are ordered according to the certificate
338    /// holder's preference.
339    fn preferred_symmetric_algorithms(&self)
340        -> Option<&'a [SymmetricAlgorithm]>;
341
342    /// Returns the supported hash algorithms ordered by preference.
343    ///
344    /// The algorithms are ordered according to the certificate
345    /// holder's preference.
346    fn preferred_hash_algorithms(&self) -> Option<&'a [HashAlgorithm]>;
347
348    /// Returns the supported compression algorithms ordered by
349    /// preference.
350    ///
351    /// The algorithms are ordered according to the certificate
352    /// holder's preference.
353    fn preferred_compression_algorithms(&self)
354        -> Option<&'a [CompressionAlgorithm]>;
355
356    /// Returns the supported AEAD ciphersuites ordered by preference.
357    ///
358    /// The algorithms are ordered according to the certificate holder's
359    /// preference.
360    fn preferred_aead_ciphersuites(
361        &self)
362        -> Option<&'a [(SymmetricAlgorithm, AEADAlgorithm)]>;
363
364    /// Returns the certificate holder's keyserver preferences.
365    fn key_server_preferences(&self) -> Option<KeyServerPreferences>;
366
367    /// Returns the certificate holder's preferred keyserver for
368    /// updates.
369    fn preferred_key_server(&self) -> Option<&'a [u8]>;
370
371    /// Returns the certificate holder's feature set.
372    fn features(&self) -> Option<Features>;
373
374    /// Returns the URI of a document describing the policy
375    /// the certificate was issued under.
376    fn policy_uri(&self) -> Option<&'a [u8]>;
377}
378
379/// A collection of components and their associated signatures.
380///
381/// The `Cert` data structure mirrors the [TPK and TSK data
382/// structures] defined in RFC 9580.  Specifically, it contains
383/// components ([`Key`]s, [`UserID`]s, and [`UserAttribute`]s), their
384/// associated self signatures, self revocations, third-party
385/// signatures, and third-party revocations, as well as useful methods.
386///
387/// [TPK and TSK data structures]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10
388/// [`Key`]: crate::packet::Key
389/// [`UserID`]: crate::packet::UserID
390/// [`UserAttribute`]: crate::packet::user_attribute::UserAttribute
391///
392/// `Cert`s are canonicalized in the sense that their `Component`s are
393/// deduplicated, and their signatures and revocations are
394/// deduplicated and checked for validity.  The canonicalization
395/// routine does *not* throw away components that have no self
396/// signatures.  These are returned as usual by, e.g.,
397/// [`Cert::userids`].
398///
399/// [`Cert::userids`]: Cert::userids()
400///
401/// Keys are deduplicated by comparing their public bits using
402/// [`Key::public_cmp`].  If two keys are considered equal, and only
403/// one of them has secret key material, the key with the secret key
404/// material is preferred.  If both keys have secret material, then
405/// one of them is chosen in a deterministic, but undefined manner,
406/// which is subject to change.  ***Note***: the secret key material
407/// is not integrity checked.  Hence when updating a certificate with
408/// secret key material, it is essential to first strip the secret key
409/// material from copies that came from an untrusted source.
410///
411/// [`Key::public_cmp`]: crate::packet::Key::public_cmp()
412///
413/// Signatures are deduplicated using [their `Eq` implementation],
414/// which compares the data that is hashed and the MPIs.  That is, it
415/// does not compare [the unhashed data], the digest prefix and the
416/// unhashed subpacket area.  If two signatures are considered equal,
417/// but have different unhashed data, the unhashed data are merged in
418/// a deterministic, but undefined manner, which is subject to change.
419/// This policy prevents an attacker from flooding a certificate with
420/// valid signatures that only differ in their unhashed data.
421///
422/// [their `Eq` implementation]: crate::packet::Signature#a-note-on-equality
423/// [the unhashed data]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3
424///
425/// Self signatures and self revocations are checked for validity by
426/// making sure that the signature is *mathematically* correct.  At
427/// this point, the signature is *not* checked against a [`Policy`].
428///
429/// Third-party signatures and revocations are checked for validity by
430/// making sure the computed digest matches the [digest prefix] stored
431/// in the signature packet.  This is *not* an integrity check and is
432/// easily spoofed.  Unfortunately, at the time of canonicalization,
433/// the actual signatures cannot be checked, because the public keys
434/// are not available.  If you rely on these signatures, it is up to
435/// you to check their validity by using an appropriate signature
436/// verification method, e.g., [`Signature::verify_userid_binding`]
437/// or [`Signature::verify_userid_revocation`].
438///
439/// [`Policy`]: crate::policy::Policy
440/// [digest prefix]: crate::packet::signature::Signature4::digest_prefix()
441/// [`Signature::verify_userid_binding`]: crate::packet::Signature::verify_userid_binding()
442/// [`Signature::verify_userid_revocation`]: crate::packet::Signature::verify_userid_revocation()
443///
444/// If a signature or a revocation is not valid,
445/// we check to see whether it is simply out of place (i.e., belongs
446/// to a different component) and, if so, we reorder it.  If not, it
447/// is added to a list of bad signatures.  These can be retrieved
448/// using [`Cert::bad_signatures`].
449///
450/// [`Cert::bad_signatures`]: Cert::bad_signatures()
451///
452/// Signatures and revocations are sorted so that the newest signature
453/// comes first.  Components are sorted, but in an undefined manner
454/// (i.e., when parsing the same certificate multiple times, the
455/// components will be in the same order, but we reserve the right to
456/// change the sort function between versions).
457///
458/// # Secret Keys
459///
460/// Any key in a certificate may include secret key material.  To
461/// protect secret key material from being leaked, secret keys are not
462/// written out when a `Cert` is serialized.  To also serialize secret
463/// key material, you need to serialize the object returned by
464/// [`Cert::as_tsk()`].
465///
466///
467/// Secret key material may be protected with a password.  In such
468/// cases, it needs to be decrypted before it can be used to decrypt
469/// data or generate a signature.  Refer to [`Key::decrypt_secret`]
470/// for details.
471///
472/// [`Key::decrypt_secret`]: crate::packet::Key::decrypt_secret()
473///
474/// # Filtering Certificates
475///
476/// Component-wise filtering of userids, user attributes, and subkeys
477/// can be done with [`Cert::retain_userids`],
478/// [`Cert::retain_user_attributes`], and [`Cert::retain_subkeys`].
479///
480/// [`Cert::retain_userids`]: Cert::retain_userids()
481/// [`Cert::retain_user_attributes`]: Cert::retain_user_attributes()
482/// [`Cert::retain_subkeys`]: Cert::retain_subkeys()
483///
484/// If you need even more control, iterate over all components, clone
485/// what you want to keep, and then reassemble the certificate.  The
486/// following example simply copies all the packets, and can be
487/// adapted to suit your policy:
488///
489/// ```rust
490/// # use sequoia_openpgp as openpgp;
491/// # use openpgp::Result;
492/// # use openpgp::parse::{Parse, PacketParserResult, PacketParser};
493/// use std::convert::TryFrom;
494/// use openpgp::cert::prelude::*;
495///
496/// # fn main() -> Result<()> {
497/// fn identity_filter(cert: &Cert) -> Result<Cert> {
498///     // Iterate over all the Cert components, pushing packets we
499///     // want to keep into the accumulator.
500///     let mut acc = Vec::new();
501///
502///     // Primary key and related signatures.
503///     let c = cert.primary_key();
504///     acc.push(c.key().clone().into());
505///     for s in c.self_signatures()   { acc.push(s.clone().into()) }
506///     for s in c.certifications()    { acc.push(s.clone().into()) }
507///     for s in c.self_revocations()  { acc.push(s.clone().into()) }
508///     for s in c.other_revocations() { acc.push(s.clone().into()) }
509///
510///     // UserIDs and related signatures.
511///     for c in cert.userids() {
512///         acc.push(c.userid().clone().into());
513///         for s in c.self_signatures()   { acc.push(s.clone().into()) }
514///         for s in c.approvals()         { acc.push(s.clone().into()) }
515///         for s in c.certifications()    { acc.push(s.clone().into()) }
516///         for s in c.self_revocations()  { acc.push(s.clone().into()) }
517///         for s in c.other_revocations() { acc.push(s.clone().into()) }
518///     }
519///
520///     // UserAttributes and related signatures.
521///     for c in cert.user_attributes() {
522///         acc.push(c.user_attribute().clone().into());
523///         for s in c.self_signatures()   { acc.push(s.clone().into()) }
524///         for s in c.approvals()         { acc.push(s.clone().into()) }
525///         for s in c.certifications()    { acc.push(s.clone().into()) }
526///         for s in c.self_revocations()  { acc.push(s.clone().into()) }
527///         for s in c.other_revocations() { acc.push(s.clone().into()) }
528///     }
529///
530///     // Subkeys and related signatures.
531///     for c in cert.keys().subkeys() {
532///         acc.push(c.key().clone().into());
533///         for s in c.self_signatures()   { acc.push(s.clone().into()) }
534///         for s in c.certifications()    { acc.push(s.clone().into()) }
535///         for s in c.self_revocations()  { acc.push(s.clone().into()) }
536///         for s in c.other_revocations() { acc.push(s.clone().into()) }
537///     }
538///
539///     // Unknown components and related signatures.
540///     for c in cert.unknowns() {
541///         acc.push(c.unknown().clone().into());
542///         for s in c.self_signatures()   { acc.push(s.clone().into()) }
543///         for s in c.certifications()    { acc.push(s.clone().into()) }
544///         for s in c.self_revocations()  { acc.push(s.clone().into()) }
545///         for s in c.other_revocations() { acc.push(s.clone().into()) }
546///     }
547///
548///     // Any signatures that we could not associate with a component.
549///     for s in cert.bad_signatures()     { acc.push(s.clone().into()) }
550///
551///     // Finally, parse into Cert.
552///     Cert::try_from(acc)
553/// }
554///
555/// let (cert, _) =
556///     CertBuilder::general_purpose(Some("alice@example.org"))
557///     .generate()?;
558/// assert_eq!(cert, identity_filter(&cert)?);
559/// #     Ok(())
560/// # }
561/// ```
562///
563/// # A note on equality
564///
565/// We define equality on `Cert` as the equality of the serialized
566/// form as defined by RFC 9580.  That is, two certs are considered
567/// equal if and only if their serialized forms are equal, modulo the
568/// OpenPGP packet framing (see [`Packet`#a-note-on-equality]).
569///
570/// Because secret key material is not emitted when a `Cert` is
571/// serialized, two certs are considered equal even if only one of
572/// them has secret key material.  To take secret key material into
573/// account, compare the [`TSK`s](crate::serialize::TSK) instead:
574///
575/// ```rust
576/// # fn main() -> sequoia_openpgp::Result<()> {
577/// # use sequoia_openpgp as openpgp;
578/// use openpgp::cert::prelude::*;
579///
580/// // Generate a cert with secrets.
581/// let (cert_with_secrets, _) =
582///     CertBuilder::general_purpose(Some("alice@example.org"))
583///     .generate()?;
584///
585/// // Derive a cert without secrets.
586/// let cert_without_secrets =
587///     cert_with_secrets.clone().strip_secret_key_material();
588///
589/// // Both are considered equal.
590/// assert!(cert_with_secrets == cert_without_secrets);
591///
592/// // But not if we compare their TSKs:
593/// assert!(cert_with_secrets.as_tsk() != cert_without_secrets.as_tsk());
594/// # Ok(()) }
595/// ```
596///
597/// # Examples
598///
599/// Parse a certificate:
600///
601/// ```rust
602/// use std::convert::TryFrom;
603/// use sequoia_openpgp as openpgp;
604/// # use openpgp::Result;
605/// # use openpgp::parse::{Parse, PacketParserResult, PacketParser};
606/// use openpgp::Cert;
607///
608/// # fn main() -> Result<()> {
609/// #     let ppr = PacketParser::from_bytes(&b""[..])?;
610/// match Cert::try_from(ppr) {
611///     Ok(cert) => {
612///         println!("Key: {}", cert.fingerprint());
613///         for uid in cert.userids() {
614///             println!("User ID: {}", uid.userid());
615///         }
616///     }
617///     Err(err) => {
618///         eprintln!("Error parsing Cert: {}", err);
619///     }
620/// }
621///
622/// #     Ok(())
623/// # }
624/// ```
625#[derive(Debug, Clone, PartialEq)]
626pub struct Cert {
627    primary: PrimaryKeyBundle<key::PublicParts>,
628
629    userids: UserIDBundles,
630    user_attributes: UserAttributeBundles,
631    subkeys: SubkeyBundles<key::PublicParts>,
632
633    // Unknown components, e.g., some UserAttribute++ packet from the
634    // future.
635    unknowns: UnknownBundles,
636    // Signatures that we couldn't find a place for.
637    bad: Vec<packet::Signature>,
638}
639assert_send_and_sync!(Cert);
640
641impl std::str::FromStr for Cert {
642    type Err = anyhow::Error;
643
644    /// Parses and returns a certificate.
645    ///
646    /// `s` must return an OpenPGP-encoded certificate.
647    ///
648    /// If `s` contains multiple certificates, this returns an error.
649    /// Use [`CertParser`] if you want to parse a keyring.
650    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
651        Self::from_bytes(s.as_bytes())
652    }
653}
654
655impl<'a> Parse<'a, Cert> for Cert {
656    /// Parses and returns a certificate.
657    ///
658    /// The reader must return an OpenPGP-encoded certificate.
659    ///
660    /// If `reader` contains multiple certificates, this returns an
661    /// error.  Use [`CertParser`] if you want to parse a keyring.
662    fn from_buffered_reader<R>(reader: R) -> Result<Cert>
663    where
664        R: BufferedReader<Cookie> + 'a,
665    {
666        Cert::try_from(PacketParser::from_buffered_reader(reader.into_boxed())?)
667    }
668}
669
670impl Cert {
671    /// Returns the primary key.
672    ///
673    /// Unlike getting the certificate's primary key using the
674    /// [`Cert::keys`] method, this method does not erase the key's
675    /// role.
676    ///
677    /// A key's secret key material may be protected with a password.
678    /// In such cases, it needs to be decrypted before it can be used
679    /// to decrypt data or generate a signature.  Refer to
680    /// [`Key::decrypt_secret`] for details.
681    ///
682    /// [`Cert::keys`]: Cert::keys()
683    /// [`Key::decrypt_secret`]: crate::packet::Key::decrypt_secret()
684    ///
685    /// # Examples
686    ///
687    /// The first key returned by [`Cert::keys`] is the primary key,
688    /// but its role has been erased:
689    ///
690    /// ```
691    /// # use sequoia_openpgp as openpgp;
692    /// # use openpgp::cert::prelude::*;
693    /// # fn main() -> openpgp::Result<()> {
694    /// # let (cert, _) = CertBuilder::new()
695    /// #     .add_userid("Alice")
696    /// #     .add_signing_subkey()
697    /// #     .add_transport_encryption_subkey()
698    /// #     .generate()?;
699    /// assert_eq!(cert.primary_key().key().role_as_unspecified(),
700    ///            cert.keys().nth(0).unwrap().key());
701    /// #     Ok(())
702    /// # }
703    /// ```
704    pub fn primary_key(&self) -> PrimaryKeyAmalgamation<'_, key::PublicParts>
705    {
706        PrimaryKeyAmalgamation::new(self)
707    }
708
709    /// Returns the certificate's revocation status.
710    ///
711    /// Normally, methods that take a policy and a reference time are
712    /// only provided by [`ValidCert`].  This method is provided here
713    /// because there are two revocation criteria, and one of them is
714    /// independent of the reference time.  That is, even if it is not
715    /// possible to turn a `Cert` into a `ValidCert` at time `t`, it
716    /// may still be considered revoked at time `t`.
717    ///
718    ///
719    /// A certificate is considered revoked at time `t` if:
720    ///
721    ///   - There is a valid and live revocation at time `t` that is
722    ///     newer than all valid and live self signatures at time `t`,
723    ///     or
724    ///
725    ///   - There is a valid [hard revocation] (even if it is not live
726    ///     at time `t`, and even if there is a newer self signature).
727    ///
728    /// [hard revocation]: crate::types::RevocationType::Hard
729    ///
730    /// Note: certificates and subkeys have different revocation
731    /// criteria from [User IDs] and [User Attributes].
732    ///
733    //  Pending https://github.com/rust-lang/rust/issues/85960, should be
734    //  [User IDs]: bundle::ComponentBundle<UserID>::revocation_status
735    //  [User Attributes]: bundle::ComponentBundle<UserAttribute>::revocation_status
736    /// [User IDs]: bundle::ComponentBundle#method.revocation_status-1
737    /// [User Attributes]: bundle::ComponentBundle#method.revocation_status-2
738    ///
739    /// # Examples
740    ///
741    /// ```
742    /// use sequoia_openpgp as openpgp;
743    /// use openpgp::cert::prelude::*;
744    /// use openpgp::types::RevocationStatus;
745    /// use openpgp::policy::StandardPolicy;
746    ///
747    /// # fn main() -> openpgp::Result<()> {
748    /// let p = &StandardPolicy::new();
749    ///
750    /// let (cert, rev) =
751    ///     CertBuilder::general_purpose(Some("alice@example.org"))
752    ///     .generate()?;
753    ///
754    /// assert_eq!(cert.revocation_status(p, None), RevocationStatus::NotAsFarAsWeKnow);
755    ///
756    /// // Merge the revocation certificate.  `cert` is now considered
757    /// // to be revoked.
758    /// let cert = cert.insert_packets(rev.clone())?.0;
759    /// assert_eq!(cert.revocation_status(p, None),
760    ///            RevocationStatus::Revoked(vec![&rev.into()]));
761    /// #     Ok(())
762    /// # }
763    /// ```
764    pub fn revocation_status<T>(&self, policy: &dyn Policy, t: T) -> RevocationStatus<'_>
765        where T: Into<Option<time::SystemTime>>
766    {
767        let t = t.into();
768        // Both a primary key signature and the primary userid's
769        // binding signature can override a soft revocation.  Compute
770        // the most recent one.
771        let vkao = self.primary_key().with_policy(policy, t).ok();
772        let mut sig = vkao.as_ref().map(|vka| vka.binding_signature());
773        if let Some(direct) = vkao.as_ref()
774            .and_then(|vka| vka.direct_key_signature().ok())
775        {
776            match (direct.signature_creation_time(),
777                   sig.and_then(|s| s.signature_creation_time())) {
778                (Some(ds), Some(bs)) if ds > bs =>
779                    sig = Some(direct),
780                _ => ()
781            }
782        }
783        self.primary_key().bundle().revocation_status_intern(
784            policy, t, true, sig)
785    }
786
787    /// Generates a revocation certificate.
788    ///
789    /// This is a convenience function around
790    /// [`CertRevocationBuilder`] to generate a revocation
791    /// certificate.  To use the revocation certificate, merge it into
792    /// the certificate using [`Cert::insert_packets`].
793    ///
794    ///
795    /// If you want to revoke an individual component, use
796    /// [`SubkeyRevocationBuilder`], [`UserIDRevocationBuilder`], or
797    /// [`UserAttributeRevocationBuilder`], as appropriate.
798    ///
799    ///
800    /// # Examples
801    ///
802    /// ```rust
803    /// use sequoia_openpgp as openpgp;
804    /// # use openpgp::Result;
805    /// use openpgp::types::{ReasonForRevocation, RevocationStatus, SignatureType};
806    /// use openpgp::cert::prelude::*;
807    /// use openpgp::crypto::KeyPair;
808    /// use openpgp::parse::Parse;
809    /// use openpgp::policy::StandardPolicy;
810    ///
811    /// # fn main() -> Result<()> {
812    /// let p = &StandardPolicy::new();
813    ///
814    /// let (cert, rev) = CertBuilder::new()
815    ///     .set_cipher_suite(CipherSuite::Cv25519)
816    ///     .generate()?;
817    ///
818    /// // A new certificate is not revoked.
819    /// assert_eq!(cert.revocation_status(p, None),
820    ///            RevocationStatus::NotAsFarAsWeKnow);
821    ///
822    /// // The default revocation certificate is a generic
823    /// // revocation.
824    /// assert_eq!(rev.reason_for_revocation().unwrap().0,
825    ///            ReasonForRevocation::Unspecified);
826    ///
827    /// // Create a revocation to explain what *really* happened.
828    /// let mut keypair = cert.primary_key()
829    ///     .key().clone().parts_into_secret()?.into_keypair()?;
830    /// let rev = cert.revoke(&mut keypair,
831    ///                       ReasonForRevocation::KeyCompromised,
832    ///                       b"It was the maid :/")?;
833    /// let cert = cert.insert_packets(rev)?.0;
834    /// if let RevocationStatus::Revoked(revs) = cert.revocation_status(p, None) {
835    ///     assert_eq!(revs.len(), 1);
836    ///     let rev = revs[0];
837    ///
838    ///     assert_eq!(rev.typ(), SignatureType::KeyRevocation);
839    ///     assert_eq!(rev.reason_for_revocation(),
840    ///                Some((ReasonForRevocation::KeyCompromised,
841    ///                      "It was the maid :/".as_bytes())));
842    /// } else {
843    ///     unreachable!()
844    /// }
845    /// # Ok(())
846    /// # }
847    /// ```
848    pub fn revoke(&self, primary_signer: &mut dyn Signer,
849                  code: ReasonForRevocation, reason: &[u8])
850        -> Result<Signature>
851    {
852        CertRevocationBuilder::new()
853            .set_reason_for_revocation(code, reason)?
854            .build(primary_signer, self, None)
855    }
856
857    /// Sets the key to expire in delta seconds.
858    ///
859    /// Note: the time is relative to the key's creation time, not the
860    /// current time!
861    ///
862    /// This function exists to facilitate testing, which is why it is
863    /// not exported.
864    #[cfg(test)]
865    fn set_validity_period_as_of(self, policy: &dyn Policy,
866                                 primary_signer: &mut dyn Signer,
867                                 expiration: Option<time::Duration>,
868                                 now: time::SystemTime)
869        -> Result<Cert>
870    {
871        let primary = self.primary_key().with_policy(policy, now)?;
872        let sigs = primary.set_validity_period_as_of(primary_signer,
873                                                     expiration,
874                                                     now)?;
875        Ok(self.insert_packets(sigs)?.0)
876    }
877
878    /// Sets the certificate to expire at the specified time.
879    ///
880    /// If no time (`None`) is specified, then the certificate is set
881    /// to not expire.
882    ///
883    /// This function creates new binding signatures that cause the
884    /// certificate to expire at the specified time.  Specifically, it
885    /// updates the current binding signature on each of the valid,
886    /// non-revoked User IDs, and the direct key signature, if any.
887    /// This is necessary, because the primary User ID is first
888    /// consulted when determining the certificate's expiration time,
889    /// and certificates can be distributed with a possibly empty
890    /// subset of User IDs.
891    ///
892    /// A policy is needed, because the expiration is updated by
893    /// updating the current binding signatures.
894    ///
895    /// # Examples
896    ///
897    /// ```rust
898    /// use std::time;
899    /// use sequoia_openpgp as openpgp;
900    /// # use openpgp::Result;
901    /// use openpgp::cert::prelude::*;
902    /// use openpgp::crypto::KeyPair;
903    /// use openpgp::policy::StandardPolicy;
904    ///
905    /// # fn main() -> Result<()> {
906    /// let p = &StandardPolicy::new();
907    ///
908    /// # let t0 = time::SystemTime::now() - time::Duration::from_secs(1);
909    /// # let (cert, _) = CertBuilder::new()
910    /// #     .set_cipher_suite(CipherSuite::Cv25519)
911    /// #     .set_creation_time(t0)
912    /// #     .generate()?;
913    /// // The certificate is alive (not expired).
914    /// assert!(cert.with_policy(p, None)?.alive().is_ok());
915    ///
916    /// // Make cert expire now.
917    /// let mut keypair = cert.primary_key()
918    ///     .key().clone().parts_into_secret()?.into_keypair()?;
919    /// let sigs = cert.set_expiration_time(p, None, &mut keypair,
920    ///                                     Some(time::SystemTime::now()))?;
921    ///
922    /// let cert = cert.insert_packets(sigs)?.0;
923    /// assert!(cert.with_policy(p, None)?.alive().is_err());
924    /// # Ok(())
925    /// # }
926    /// ```
927    pub fn set_expiration_time<T>(&self, policy: &dyn Policy, t: T,
928                                  primary_signer: &mut dyn Signer,
929                                  expiration: Option<time::SystemTime>)
930        -> Result<Vec<Signature>>
931        where T: Into<Option<time::SystemTime>>,
932    {
933        let primary = self.primary_key().with_policy(policy, t.into())?;
934        primary.set_expiration_time(primary_signer, expiration)
935    }
936
937    /// Returns the primary User ID at the reference time, if any.
938    fn primary_userid_relaxed<'a, T>(&'a self, policy: &'a dyn Policy, t: T,
939                                     valid_cert: bool)
940        -> Result<ValidUserIDAmalgamation<'a>>
941        where T: Into<Option<std::time::SystemTime>>
942    {
943        let t = t.into().unwrap_or_else(crate::now);
944        ValidComponentAmalgamation::primary(self, self.userids.iter(),
945                                            policy, t, valid_cert)
946    }
947
948    /// Returns an iterator over the certificate's User IDs.
949    ///
950    /// **Note:** This returns all User IDs, even those without a
951    /// binding signature.  This is not what you want, unless you are
952    /// doing a low-level inspection of the certificate.  Use
953    /// [`ValidCert::userids`] instead.  (You turn a `Cert` into a
954    /// [`ValidCert`] by using [`Cert::with_policy`].)
955    ///
956    /// # Examples
957    ///
958    /// ```
959    /// # use sequoia_openpgp as openpgp;
960    /// # use openpgp::cert::prelude::*;
961    /// # use openpgp::packet::prelude::*;
962    /// #
963    /// # fn main() -> openpgp::Result<()> {
964    /// # let (cert, rev) =
965    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
966    /// #     .generate()?;
967    /// println!("{}'s User IDs:", cert.fingerprint());
968    /// for ua in cert.userids() {
969    ///     println!("  {}", String::from_utf8_lossy(ua.userid().value()));
970    /// }
971    /// # // Add a User ID without a binding signature and make sure
972    /// # // it is still returned.
973    /// # let userid = UserID::from("alice@example.net");
974    /// # let cert = cert.insert_packets(userid)?.0;
975    /// # assert_eq!(cert.userids().count(), 2);
976    /// #     Ok(())
977    /// # }
978    /// ```
979    pub fn userids(&self) -> UserIDAmalgamationIter<'_> {
980        ComponentAmalgamationIter::new(self, self.userids.iter())
981    }
982
983    /// Returns an iterator over the certificate's User Attributes.
984    ///
985    /// **Note:** This returns all User Attributes, even those without
986    /// a binding signature.  This is not what you want, unless you
987    /// are doing a low-level inspection of the certificate.  Use
988    /// [`ValidCert::user_attributes`] instead.  (You turn a `Cert`
989    /// into a [`ValidCert`] by using [`Cert::with_policy`].)
990    ///
991    /// # Examples
992    ///
993    /// ```
994    /// # use sequoia_openpgp as openpgp;
995    /// # use openpgp::cert::prelude::*;
996    /// #
997    /// # fn main() -> openpgp::Result<()> {
998    /// # let (cert, rev) =
999    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1000    /// #     .generate()?;
1001    /// println!("{}'s has {} User Attributes.",
1002    ///          cert.fingerprint(),
1003    ///          cert.user_attributes().count());
1004    /// # assert_eq!(cert.user_attributes().count(), 0);
1005    /// #     Ok(())
1006    /// # }
1007    /// ```
1008    pub fn user_attributes(&self) -> UserAttributeAmalgamationIter<'_> {
1009        ComponentAmalgamationIter::new(self, self.user_attributes.iter())
1010    }
1011
1012    /// Returns an iterator over the certificate's keys.
1013    ///
1014    /// That is, this returns an iterator over the primary key and any
1015    /// subkeys.
1016    ///
1017    /// **Note:** This returns all keys, even those without a binding
1018    /// signature.  This is not what you want, unless you are doing a
1019    /// low-level inspection of the certificate.  Use
1020    /// [`ValidCert::keys`] instead.  (You turn a `Cert` into a
1021    /// [`ValidCert`] by using [`Cert::with_policy`].)
1022    ///
1023    /// By necessity, this function erases the returned keys' roles.
1024    /// If you are only interested in the primary key, use
1025    /// [`Cert::primary_key`].  If you are only interested in the
1026    /// subkeys, use [`KeyAmalgamationIter::subkeys`].  These
1027    /// functions preserve the keys' role in the type system.
1028    ///
1029    /// A key's secret key material may be protected with a
1030    /// password.  In such cases, it needs to be decrypted before it
1031    /// can be used to decrypt data or generate a signature.  Refer to
1032    /// [`Key::decrypt_secret`] for details.
1033    ///
1034    /// [`Cert::primary_key`]: Cert::primary_key()
1035    /// [`KeyAmalgamationIter::subkeys`]: amalgamation::key::KeyAmalgamationIter::subkeys()
1036    /// [`Key::decrypt_secret`]: crate::packet::Key::decrypt_secret()
1037    ///
1038    /// # Examples
1039    ///
1040    /// ```
1041    /// # use sequoia_openpgp as openpgp;
1042    /// # use openpgp::cert::prelude::*;
1043    /// # use openpgp::packet::Tag;
1044    /// # use std::convert::TryInto;
1045    /// #
1046    /// # fn main() -> openpgp::Result<()> {
1047    /// # let (cert, _) = CertBuilder::new()
1048    /// #     .add_userid("Alice")
1049    /// #     .add_signing_subkey()
1050    /// #     .add_transport_encryption_subkey()
1051    /// #     .generate()?;
1052    /// println!("{}'s has {} keys.",
1053    ///          cert.fingerprint(),
1054    ///          cert.keys().count());
1055    /// # assert_eq!(cert.keys().count(), 1 + 2);
1056    /// #
1057    /// # // Make sure that we keep all keys even if they don't have
1058    /// # // any self signatures.
1059    /// # let packets = cert.into_packets()
1060    /// #     .filter(|p| p.tag() != Tag::Signature)
1061    /// #     .collect::<Vec<_>>();
1062    /// # let cert : Cert = packets.try_into()?;
1063    /// # assert_eq!(cert.keys().count(), 1 + 2);
1064    /// #
1065    /// #     Ok(())
1066    /// # }
1067    /// ```
1068    pub fn keys(&self) -> KeyAmalgamationIter<'_, key::PublicParts, key::UnspecifiedRole>
1069    {
1070        KeyAmalgamationIter::new(self)
1071    }
1072
1073    /// Returns an iterator over the certificate's subkeys.
1074    ///
1075    /// This is used in many test.  But, its convenience and
1076    /// availability made us use it here and there in the code.
1077    /// Nowadays, we use it in tests, and it is merely an alias for
1078    /// the public interface.  Do not use it for new tests.
1079    #[cfg(test)]
1080    pub(crate) fn subkeys(&self)
1081        -> KeyAmalgamationIter<'_, key::PublicParts, key::SubordinateRole>
1082    {
1083        self.keys().subkeys()
1084    }
1085
1086    /// Returns an iterator over the certificate's unknown components.
1087    ///
1088    /// This function returns all unknown components even those
1089    /// without a binding signature.
1090    ///
1091    /// # Examples
1092    ///
1093    /// ```
1094    /// # use sequoia_openpgp as openpgp;
1095    /// # use openpgp::packet::prelude::*;
1096    /// # use openpgp::cert::prelude::*;
1097    /// #
1098    /// # fn main() -> openpgp::Result<()> {
1099    /// # let (cert, _) =
1100    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1101    /// #     .generate()?;
1102    /// # let tag = Tag::Private(61);
1103    /// # let unknown
1104    /// #     = Unknown::new(tag, openpgp::Error::UnsupportedPacketType(tag).into());
1105    /// # let cert = cert.insert_packets(unknown)?.0;
1106    /// println!("{}'s has {} unknown components.",
1107    ///          cert.fingerprint(),
1108    ///          cert.unknowns().count());
1109    /// for ua in cert.unknowns() {
1110    ///     println!("  Unknown component with tag {} ({}), error: {}",
1111    ///              ua.unknown().tag(), u8::from(ua.unknown().tag()), ua.unknown().error());
1112    /// }
1113    /// # assert_eq!(cert.unknowns().count(), 1);
1114    /// # assert_eq!(cert.unknowns().nth(0).unwrap().unknown().tag(), tag);
1115    /// # Ok(())
1116    /// # }
1117    /// ```
1118    pub fn unknowns(&self) -> UnknownComponentAmalgamationIter<'_> {
1119        ComponentAmalgamationIter::new(self, self.unknowns.iter())
1120    }
1121
1122    /// Returns the bad signatures.
1123    ///
1124    /// Bad signatures are signatures and revocations that we could
1125    /// not associate with one of the certificate's components.
1126    ///
1127    /// For self signatures and self revocations, we check that the
1128    /// signature is correct.  For third-party signatures and
1129    /// third-party revocations, we only check that the [digest
1130    /// prefix] is correct, because third-party keys are not
1131    /// available.  Checking the digest prefix is *not* an integrity
1132    /// check; third party-signatures and third-party revocations may
1133    /// be invalid and must still be checked for validity before use.
1134    ///
1135    /// [digest prefix]: packet::signature::Signature4::digest_prefix()
1136    ///
1137    /// # Examples
1138    ///
1139    /// ```
1140    /// # use sequoia_openpgp as openpgp;
1141    /// # use openpgp::cert::prelude::*;
1142    /// #
1143    /// # fn main() -> openpgp::Result<()> {
1144    /// # let (cert, rev) =
1145    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1146    /// #     .generate()?;
1147    /// println!("{}'s has {} bad signatures.",
1148    ///          cert.fingerprint(),
1149    ///          cert.bad_signatures().count());
1150    /// # assert_eq!(cert.bad_signatures().count(), 0);
1151    /// #     Ok(())
1152    /// # }
1153    /// ```
1154    pub fn bad_signatures(&self)
1155                          -> impl Iterator<Item = &Signature> + Send + Sync {
1156        self.primary.bad_signatures()
1157            .chain(self.userids.iter().flat_map(|u| u.bad_signatures()))
1158            .chain(self.user_attributes.iter().flat_map(|u| u.bad_signatures()))
1159            .chain(self.subkeys.iter().flat_map(|u| u.bad_signatures()))
1160            .chain(self.unknowns.iter().flat_map(|u| u.bad_signatures()))
1161            .chain(self.bad.iter())
1162    }
1163
1164    /// Returns a list of any designated revokers for this certificate.
1165    ///
1166    /// This function returns the designated revokers listed on the
1167    /// primary key's binding signatures and the certificate's direct
1168    /// key signatures.
1169    ///
1170    /// Note: the returned list is deduplicated.
1171    ///
1172    /// # Examples
1173    ///
1174    /// ```
1175    /// use sequoia_openpgp as openpgp;
1176    /// # use openpgp::Result;
1177    /// use openpgp::cert::prelude::*;
1178    /// use openpgp::policy::StandardPolicy;
1179    /// use openpgp::types::RevocationKey;
1180    ///
1181    /// # fn main() -> Result<()> {
1182    /// let p = &StandardPolicy::new();
1183    ///
1184    /// let (alice, _) =
1185    ///     CertBuilder::general_purpose(Some("alice@example.org"))
1186    ///     .generate()?;
1187    /// // Make Alice a designated revoker for Bob.
1188    /// let (bob, _) =
1189    ///     CertBuilder::general_purpose(Some("bob@example.org"))
1190    ///     .set_revocation_keys(vec![(&alice).into()])
1191    ///     .generate()?;
1192    ///
1193    /// // Make sure Alice is listed as a designated revoker for Bob.
1194    /// assert_eq!(bob.revocation_keys(p).collect::<Vec<&RevocationKey>>(),
1195    ///            vec![&(&alice).into()]);
1196    /// # Ok(()) }
1197    /// ```
1198    pub fn revocation_keys<'a>(&'a self, policy: &dyn Policy)
1199        -> impl Iterator<Item = &'a RevocationKey> + 'a
1200    {
1201        let mut keys = std::collections::HashSet::new();
1202
1203        let pk_sec = self.primary_key().key().hash_algo_security();
1204
1205        // All user ids.
1206        self.userids()
1207            .flat_map(|ua| {
1208                // All valid self-signatures.
1209                let sec = ua.userid().hash_algo_security();
1210                ua.self_signatures()
1211                    .filter(move |sig| {
1212                        policy.signature(sig, sec).is_ok()
1213                   })
1214            })
1215            // All direct-key signatures.
1216            .chain(self.primary_key()
1217                   .self_signatures()
1218                   .filter(|sig| {
1219                       policy.signature(sig, pk_sec).is_ok()
1220                   }))
1221            .flat_map(|sig| sig.revocation_keys())
1222            .for_each(|rk| { keys.insert(rk); });
1223
1224        keys.into_iter()
1225    }
1226
1227    /// Converts the certificate into an iterator over a sequence of
1228    /// packets.
1229    ///
1230    /// This function strips secrets from the keys, similar to how
1231    /// serializing a [`Cert`] would not serialize secret keys.  This
1232    /// behavior makes it harder to accidentally leak secret key
1233    /// material.
1234    ///
1235    /// If you do want to preserve secret key material, use
1236    /// [`Cert::into_tsk`] to opt in to getting the secret key
1237    /// material, then use [`TSK::into_packets`] to convert to a
1238    /// packet stream.
1239    ///
1240    /// # Examples
1241    ///
1242    /// ```
1243    /// # use sequoia_openpgp as openpgp;
1244    /// # use openpgp::cert::prelude::*;
1245    /// #
1246    /// # fn main() -> openpgp::Result<()> {
1247    /// # let (cert, _) =
1248    /// #       CertBuilder::general_purpose(Some("alice@example.org"))
1249    /// #       .generate()?;
1250    /// assert!(cert.is_tsk());
1251    /// // But:
1252    /// assert!(! Cert::from_packets(cert.into_packets())?.is_tsk());
1253    /// # Ok(()) }
1254    /// ```
1255    pub fn into_packets(self) -> impl Iterator<Item=Packet> + Send + Sync {
1256        /// Strips the secret key material.
1257        fn rewrite(mut p: impl Iterator<Item=Packet> + Send + Sync)
1258            -> impl Iterator<Item=Packet> + Send + Sync
1259        {
1260            let k: Packet = match p.next().unwrap() {
1261                Packet::PublicKey(k) =>
1262                    Packet::PublicKey(k.take_secret().0),
1263                Packet::PublicSubkey(k) =>
1264                    Packet::PublicSubkey(k.take_secret().0),
1265                _ => unreachable!(),
1266            };
1267
1268            std::iter::once(k).chain(p)
1269        }
1270
1271        rewrite(self.primary.into_packets())
1272            .chain(self.userids.into_iter().flat_map(|b| b.into_packets()))
1273            .chain(self.user_attributes.into_iter().flat_map(|b| b.into_packets()))
1274            .chain(self.subkeys.into_iter().flat_map(|b| rewrite(b.into_packets())))
1275            .chain(self.unknowns.into_iter().flat_map(|b| b.into_packets()))
1276            .chain(self.bad.into_iter().map(|s| s.into()))
1277    }
1278
1279    /// Returns the first certificate found in the sequence of packets.
1280    ///
1281    /// If the sequence of packets does not start with a certificate
1282    /// (specifically, if it does not start with a primary key
1283    /// packet), then this fails.
1284    ///
1285    /// If the sequence contains multiple certificates (i.e., it is a
1286    /// keyring), or the certificate is followed by an invalid packet
1287    /// this function will fail.  To parse keyrings, use
1288    /// [`CertParser`] instead of this function.
1289    ///
1290    /// # Examples
1291    ///
1292    /// ```
1293    /// use sequoia_openpgp as openpgp;
1294    /// use openpgp::cert::prelude::*;
1295    /// use openpgp::packet::prelude::*;
1296    /// use openpgp::PacketPile;
1297    ///
1298    /// # fn main() -> openpgp::Result<()> {
1299    /// let (cert, rev) =
1300    ///     CertBuilder::general_purpose(Some("alice@example.org"))
1301    ///     .generate()?;
1302    ///
1303    /// // We should be able to turn a certificate into a PacketPile
1304    /// // and back.
1305    /// assert!(Cert::from_packets(cert.into_packets()).is_ok());
1306    ///
1307    /// // But a revocation certificate is not a certificate, so this
1308    /// // will fail.
1309    /// let p : Vec<Packet> = vec![rev.into()];
1310    /// assert!(Cert::from_packets(p.into_iter()).is_err());
1311    /// # Ok(())
1312    /// # }
1313    /// ```
1314    pub fn from_packets(p: impl Iterator<Item=Packet> + Send + Sync) -> Result<Self> {
1315        let mut i = parser::CertParser::from_iter(p);
1316        if let Some(cert_result) = i.next() {
1317            if i.next().is_some() {
1318                Err(Error::MalformedCert(
1319                    "Additional packets found, is this a keyring?".into()
1320                ).into())
1321            } else {
1322                cert_result
1323            }
1324        } else {
1325            Err(Error::MalformedCert("No data".into()).into())
1326        }
1327    }
1328
1329    /// Converts the certificate into a `PacketPile`.
1330    ///
1331    /// # Examples
1332    ///
1333    /// ```
1334    /// # use sequoia_openpgp as openpgp;
1335    /// # use openpgp::PacketPile;
1336    /// # use openpgp::cert::prelude::*;
1337    /// #
1338    /// # fn main() -> openpgp::Result<()> {
1339    /// # let (cert, _) =
1340    /// #       CertBuilder::general_purpose(Some("alice@example.org"))
1341    /// #       .generate()?;
1342    /// let pp = cert.into_packet_pile();
1343    /// # let _ : PacketPile = pp;
1344    /// #     Ok(())
1345    /// # }
1346    /// ```
1347    pub fn into_packet_pile(self) -> PacketPile {
1348        self.into()
1349    }
1350
1351    /// Sorts and deduplicates all components and all signatures of
1352    /// all components.
1353    ///
1354    /// Signatures are compared using [`Signature::normalized_eq`]
1355    /// (i.e., the unhashed subpacket area is ignored).  If two
1356    /// signatures are considered equal, the one that comes first is
1357    /// kept.
1358    ///
1359    /// Keys are compares using [`Key::public_cmp`].  If two keys are
1360    /// considered equivalent, then the one with secret key material
1361    /// is kept.  If they both have secret key material, then the one
1362    /// that comes first is kept.
1363    fn sort_and_dedup(&mut self) {
1364        self.primary.sort_and_dedup();
1365
1366        self.bad.sort_by(Signature::normalized_cmp);
1367        self.bad.dedup_by(|a, b| a.normalized_eq(b));
1368        // Order bad signatures so that the most recent one comes
1369        // first.
1370        self.bad.sort_by(sig_cmp);
1371
1372        self.userids.sort_and_dedup(UserID::cmp, |_, _| {});
1373        self.user_attributes.sort_and_dedup(UserAttribute::cmp, |_, _| {});
1374        // XXX: If we have two keys with the same public parts and
1375        // different non-empty secret parts, then the one that comes
1376        // first will be dropped, the one that comes later will be
1377        // kept.
1378        //
1379        // This can happen if:
1380        //
1381        //   - One is corrupted
1382        //   - There are two versions that are encrypted differently
1383        //
1384        // If the order of the keys is unpredictable, this effect is
1385        // unpredictable!  However, if we merge two canonicalized
1386        // certs with Cert::merge_public_and_secret, then we know the
1387        // order: the version in `self` comes first, the version in
1388        // `other` comes last.
1389        self.subkeys.sort_and_dedup(Key::public_cmp,
1390            |a, b| {
1391                // Recall: if a and b are equal, a will be dropped.
1392                // Also, the elements are given in the opposite order
1393                // from their order in the vector.
1394                //
1395                // Prefer the secret in `a`, i.e. the "later" one.
1396                if a.has_secret() {
1397                    std::mem::swap(a, b);
1398                }
1399            });
1400
1401        self.unknowns.sort_and_dedup(Unknown::best_effort_cmp, |_, _| {});
1402    }
1403
1404    fn canonicalize(mut self) -> Self {
1405        tracer!(TRACE, "canonicalize", 0);
1406        t!("Canonicalizing {}", self.primary_key().key().fingerprint());
1407        use SignatureType::*;
1408
1409        // Before we do anything, we'll order and deduplicate the
1410        // components.  If two components are the same, they will be
1411        // merged, and their signatures will also be deduplicated.
1412        // This improves the performance considerably when we update a
1413        // certificate, because the certificates will be most likely
1414        // almost identical, and we avoid about half of the signature
1415        // verifications.
1416        self.sort_and_dedup();
1417
1418        // Now we verify the self signatures.  There are a few things
1419        // that we need to be aware of:
1420        //
1421        //  - Signatures may be invalid.  These should be dropped.
1422        //
1423        //  - Signatures may be out of order.  These should be
1424        //    reordered so that we have the latest self signature and
1425        //    we don't drop a userid or subkey that is actually
1426        //    valid.
1427
1428        // We collect bad signatures here in self.bad.  Below, we'll
1429        // test whether they are just out of order by checking them
1430        // against all userids and subkeys.  Furthermore, this may be
1431        // a partial Cert that is merged into an older copy.
1432
1433        // desc: a description of the component
1434        // binding: the binding to check
1435        // sigs: a vector of sigs in $binding to check
1436        macro_rules! check {
1437            ($desc:expr, $binding:expr, $sigs:ident,
1438             $hash_method:ident,    // method to hash the signature
1439             $sig_type_pat:pat,     // pattern to test signature types against
1440             $($hash_args:expr),* // additional arguments to pass to hash_method
1441            ) => ({
1442                let sigs = $binding.$sigs.take();
1443                t!("check!({}, {}, {} ({:?}), {}, ...)",
1444                   $desc, stringify!($binding), stringify!($sigs), sigs,
1445                   stringify!($hash_method));
1446                for sig in sigs.into_iter() {
1447                    // Use hash prefix as heuristic.
1448                    let key = self.primary.key();
1449                    match sig.hash_algo().context().and_then(|ctx| {
1450                        let mut ctx = ctx.for_signature(sig.version());
1451                        if matches!(sig.typ(), $sig_type_pat) {
1452                            sig.$hash_method(&mut ctx, key, $($hash_args),*)?;
1453                            ctx.into_digest()
1454                        } else {
1455                            Err(Error::UnsupportedSignatureType(sig.typ()).into())
1456                        }
1457                    }) {
1458                      Ok(hash) => {
1459                        if &sig.digest_prefix()[..] == &hash[..2] {
1460                            sig.set_computed_digest(Some(hash));
1461                            $binding.$sigs.push(sig);
1462                        } else {
1463                            t!("Sig {:02X}{:02X}, type = {} \
1464                                doesn't belong to {} (computed hash's prefix: {:02X}{:02X})",
1465                               sig.digest_prefix()[0], sig.digest_prefix()[1],
1466                               sig.typ(), $desc,
1467                               hash[0], hash[1]);
1468
1469                            self.bad.push(sig);
1470                        }
1471                      },
1472                      Err(e) => {
1473                        // Hashing failed, we likely don't support the
1474                        // hash algorithm, or the signature type was
1475                        // bad.
1476                        t!("Sig {:02X}{:02X}, type = {}: {}",
1477                           sig.digest_prefix()[0], sig.digest_prefix()[1],
1478                           sig.typ(), e);
1479
1480                        self.bad.push(sig);
1481                      },
1482                    }
1483                }
1484            });
1485            ($desc:expr, $binding:expr, $sigs:ident,
1486             $hash_method:ident, $sig_type_pat:pat) => ({
1487                check!($desc, $binding, $sigs, $hash_method, $sig_type_pat, )
1488            });
1489        }
1490
1491        // The same as check!, but for third party signatures.  If we
1492        // do have the key that made the signature, we can verify it
1493        // like in check!.  Otherwise, we use the hash prefix as
1494        // heuristic approximating the verification.
1495        macro_rules! check_3rd_party {
1496            ($desc:expr,            // a description of the component
1497             $binding:expr,         // the binding to check
1498             $sigs:ident,           // a vector of sigs in $binding to check
1499             $lookup_fn:expr,       // a function to lookup keys
1500             $verify_method:ident,  // the method to call to verify it
1501             $hash_method:ident,    // the method to call to compute the hash
1502             $sig_type_pat:pat,     // pattern to test signature types against
1503             $($verify_args:expr),* // additional arguments to pass to the above
1504            ) => ({
1505                let sigs = mem::take(&mut $binding.$sigs);
1506                t!("check_3rd_party!({}, {}, {} ({:?}_, {}, {}, ...)",
1507                   $desc, stringify!($binding), stringify!($sigs), sigs,
1508                   stringify!($verify_method), stringify!($hash_method));
1509                for sig in sigs {
1510                    // Use hash prefix as heuristic.
1511                    let key = self.primary.key();
1512                    match sig.hash_algo().context().and_then(|ctx| {
1513                        let mut ctx = ctx.for_signature(sig.version());
1514                        if matches!(sig.typ(), $sig_type_pat) {
1515                            sig.$hash_method(&mut ctx, key, $($verify_args),*)?;
1516                            ctx.into_digest()
1517                        } else {
1518                            Err(Error::UnsupportedSignatureType(sig.typ()).into())
1519                        }
1520                    }) {
1521                      Ok(hash) => {
1522                        if &sig.digest_prefix()[..] == &hash[..2] {
1523                            // See if we can get the key for a
1524                            // positive verification.
1525                            if let Some(key) = $lookup_fn(&sig) {
1526                                if let Ok(()) = sig.$verify_method(
1527                                    &key, self.primary.key(), $($verify_args),*)
1528                                {
1529                                    $binding.$sigs.push(sig);
1530                                } else {
1531                                    t!("Sig {:02X}{:02X}, type = {} \
1532                                        doesn't belong to {}",
1533                                       sig.digest_prefix()[0],
1534                                       sig.digest_prefix()[1],
1535                                       sig.typ(), $desc);
1536
1537                                    self.bad.push(sig);
1538                                }
1539                            } else {
1540                                // No key, we need to trust our heuristic.
1541                                sig.set_computed_digest(Some(hash));
1542                                $binding.$sigs.push(sig);
1543                            }
1544                        } else {
1545                            t!("Sig {:02X}{:02X}, type = {} \
1546                                doesn't belong to {} (computed hash's prefix: {:02X}{:02X})",
1547                               sig.digest_prefix()[0], sig.digest_prefix()[1],
1548                               sig.typ(), $desc,
1549                               hash[0], hash[1]);
1550
1551                            self.bad.push(sig);
1552                        }
1553                      },
1554                      Err(e) => {
1555                        // Hashing failed, we likely don't support the
1556                        // hash algorithm, or the signature type was
1557                        // bad.
1558                        t!("Sig {:02X}{:02X}, type = {}: {}",
1559                           sig.digest_prefix()[0], sig.digest_prefix()[1],
1560                           sig.typ(), e);
1561
1562                        self.bad.push(sig);
1563                      },
1564                    }
1565                }
1566            });
1567            ($desc:expr, $binding:expr, $sigs:ident, $lookup_fn:expr,
1568             $verify_method:ident, $hash_method:ident, $sig_type_pat:pat) => ({
1569                 check_3rd_party!($desc, $binding, $sigs, $lookup_fn,
1570                                  $verify_method, $hash_method, $sig_type_pat, )
1571            });
1572        }
1573
1574        // Placeholder lookup function.
1575        fn lookup_fn(_: &Signature)
1576                     -> Option<Key<key::PublicParts, key::UnspecifiedRole>> {
1577            None
1578        }
1579
1580        check!("primary key",
1581               self.primary, self_signatures, hash_direct_key, DirectKey);
1582        check!("primary key",
1583               self.primary, self_revocations, hash_direct_key, KeyRevocation);
1584        check_3rd_party!("primary key",
1585                         self.primary, certifications, lookup_fn,
1586                         verify_direct_key, hash_direct_key, DirectKey);
1587        check_3rd_party!("primary key",
1588                         self.primary, other_revocations, lookup_fn,
1589                         verify_primary_key_revocation, hash_direct_key,
1590                         KeyRevocation);
1591
1592        // Attestations are never associated with a primary key.  If
1593        // there are any, they need to be reordered.
1594        self.bad.append(&mut self.primary.attestations.take());
1595
1596        for ua in self.userids.iter_mut() {
1597            check!(format!("userid \"{}\"",
1598                           String::from_utf8_lossy(ua.userid().value())),
1599                   ua, self_signatures, hash_userid_binding,
1600                   GenericCertification | PersonaCertification
1601                   | CasualCertification | PositiveCertification,
1602                   ua.userid());
1603            check!(format!("userid \"{}\"",
1604                           String::from_utf8_lossy(ua.userid().value())),
1605                   ua, self_revocations, hash_userid_binding,
1606                   CertificationRevocation,
1607                   ua.userid());
1608            check!(format!("userid \"{}\"",
1609                           String::from_utf8_lossy(ua.userid().value())),
1610                   ua, attestations, hash_userid_approval,
1611                   CertificationApproval,
1612                   ua.userid());
1613            check_3rd_party!(
1614                format!("userid \"{}\"",
1615                        String::from_utf8_lossy(ua.userid().value())),
1616                ua, certifications, lookup_fn,
1617                verify_userid_binding, hash_userid_binding,
1618                GenericCertification | PersonaCertification
1619                    | CasualCertification | PositiveCertification,
1620                ua.userid());
1621            check_3rd_party!(
1622                format!("userid \"{}\"",
1623                        String::from_utf8_lossy(ua.userid().value())),
1624                ua, other_revocations, lookup_fn,
1625                verify_userid_revocation, hash_userid_binding,
1626                CertificationRevocation,
1627                ua.userid());
1628        }
1629
1630        for binding in self.user_attributes.iter_mut() {
1631            check!("user attribute",
1632                   binding, self_signatures, hash_user_attribute_binding,
1633                   GenericCertification | PersonaCertification
1634                   | CasualCertification | PositiveCertification,
1635                   binding.user_attribute());
1636            check!("user attribute",
1637                   binding, self_revocations, hash_user_attribute_binding,
1638                   CertificationRevocation,
1639                   binding.user_attribute());
1640            check!("user attribute",
1641                   binding, attestations, hash_user_attribute_approval,
1642                   CertificationApproval,
1643                   binding.user_attribute());
1644            check_3rd_party!(
1645                "user attribute",
1646                binding, certifications, lookup_fn,
1647                verify_user_attribute_binding, hash_user_attribute_binding,
1648                GenericCertification | PersonaCertification
1649                    | CasualCertification | PositiveCertification,
1650                binding.user_attribute());
1651            check_3rd_party!(
1652                "user attribute",
1653                binding, other_revocations, lookup_fn,
1654                verify_user_attribute_revocation, hash_user_attribute_binding,
1655                CertificationRevocation,
1656                binding.user_attribute());
1657        }
1658
1659        for binding in self.subkeys.iter_mut() {
1660            check!(format!("subkey {}", binding.key().keyid()),
1661                   binding, self_signatures, hash_subkey_binding,
1662                   SubkeyBinding,
1663                   binding.key());
1664            check!(format!("subkey {}", binding.key().keyid()),
1665                   binding, self_revocations, hash_subkey_binding,
1666                   SubkeyRevocation,
1667                   binding.key());
1668            check_3rd_party!(
1669                format!("subkey {}", binding.key().keyid()),
1670                binding, certifications, lookup_fn,
1671                verify_subkey_binding, hash_subkey_binding,
1672                SubkeyBinding,
1673                binding.key());
1674            check_3rd_party!(
1675                format!("subkey {}", binding.key().keyid()),
1676                binding, other_revocations, lookup_fn,
1677                verify_subkey_revocation, hash_subkey_binding,
1678                SubkeyRevocation,
1679                binding.key());
1680
1681            // Attestations are never associated with a subkey.  If
1682            // there are any, they need to be reordered.
1683            self.bad.append(&mut binding.attestations.take());
1684        }
1685
1686        // See if the signatures that didn't validate are just out of
1687        // place.
1688        let mut bad_sigs: Vec<(Option<usize>, Signature)> =
1689            std::mem::take(&mut self.bad).into_iter()
1690            .map(|sig| {
1691                t!("We're going to reconsider bad signature {:?}", sig);
1692                (None, sig)
1693            })
1694            .collect();
1695        t!("Attempting to reorder {} signatures", bad_sigs.len());
1696
1697        // Do the same for signatures on unknown components, but
1698        // remember where we took them from.
1699        for (i, c) in self.unknowns.iter_mut().enumerate() {
1700            for sig in
1701                c.self_signatures.take().into_iter()
1702                .chain(
1703                    std::mem::take(&mut c.certifications).into_iter())
1704                .chain(
1705                    c.attestations.take().into_iter())
1706                .chain(
1707                    c.self_revocations.take().into_iter())
1708                .chain(
1709                    std::mem::take(&mut c.other_revocations).into_iter())
1710            {
1711                t!("We're going to reconsider {:?} on unknown component #{}",
1712                   sig, i);
1713                bad_sigs.push((Some(i), sig));
1714            }
1715        }
1716
1717        let primary_fp: KeyHandle = self.key_handle();
1718
1719        'outer: for (unknown_idx, sig) in bad_sigs {
1720            // Did we find a new place for sig?
1721            let mut found_component = false;
1722
1723            // Is this signature a self-signature?
1724            let issuers =
1725                sig.get_issuers();
1726            let is_selfsig =
1727                issuers.is_empty()
1728                || issuers.iter().any(|kh| kh.aliases(&primary_fp));
1729
1730            macro_rules! check_one {
1731                ($desc:expr,            // a description of the component
1732                 $sigs:expr,            // where to put $sig if successful
1733                 $sig:ident,            // the signature to check
1734                 $hash_method:ident,    // the method to compute the hash
1735                 $($verify_args:expr),* // additional arguments for the above
1736                ) => ({
1737                   if is_selfsig {
1738                     t!("check_one!({}, {:?}, {:?}/{}, {}, ...)",
1739                      $desc, $sigs, $sig, $sig.typ(),
1740                      stringify!($hash_method));
1741                     // Use hash prefix as heuristic.
1742                     let key = self.primary.key();
1743                     match $sig.hash_algo().context()
1744                         .and_then(|ctx| {
1745                             let mut ctx =
1746                                 ctx.for_signature($sig.version());
1747
1748                             $sig.$hash_method(&mut ctx, key,
1749                                              $($verify_args),*)?;
1750                             ctx.into_digest()
1751                         })
1752                     {
1753                       Ok(hash) => {
1754                         if &$sig.digest_prefix()[..] == &hash[..2] {
1755                             t!("Sig {:02X}{:02X}, {:?} \
1756                                 was out of place.  Likely belongs to {}.",
1757                                $sig.digest_prefix()[0],
1758                                $sig.digest_prefix()[1],
1759                                $sig.typ(), $desc);
1760
1761                             $sigs.push({
1762                                 let sig = $sig.clone();
1763                                 sig.set_computed_digest(Some(hash));
1764                                 sig
1765                             });
1766
1767                             // The cost of missing a revocation
1768                             // certificate merely because we put
1769                             // it into the wrong place seem to
1770                             // outweigh the cost of duplicating
1771                             // it.
1772                             t!("Will keep trying to match this sig to \
1773                                 other components (found before? {:?})...",
1774                                found_component);
1775                             found_component = true;
1776                         } else {
1777                             t!("Sig {:02X}{:02X}, {:?} \
1778                                 does not belong to {}: \
1779                                 hash prefix mismatch {}",
1780                                $sig.digest_prefix()[0],
1781                                $sig.digest_prefix()[1],
1782                                $sig.typ(), $desc,
1783                                crate::fmt::hex::encode(&hash));
1784                         }
1785                       },
1786                       Err(e) => {
1787                           t!("Sig {:02X}{:02X}, type = {}: {}",
1788                              $sig.digest_prefix()[0], $sig.digest_prefix()[1],
1789                              $sig.typ(), e);
1790                       },
1791                     }
1792                   }
1793                 });
1794                ($desc:expr, $sigs:expr, $sig:ident,
1795                 $hash_method:ident) => ({
1796                    check_one!($desc, $sigs, $sig, $hash_method,)
1797                });
1798            }
1799
1800            // The same as check_one!, but for third party signatures.
1801            // If we do have the key that made the signature, we can
1802            // verify it like in check!.  Otherwise, we use the hash
1803            // prefix as heuristic approximating the verification.
1804            macro_rules! check_one_3rd_party {
1805                ($desc:expr,            // a description of the component
1806                 $sigs:expr,            // where to put $sig if successful
1807                 $sig:ident,            // the signature to check
1808                 $lookup_fn:expr,       // a function to lookup keys
1809                 $verify_method:ident,  // the method to verify it
1810                 $hash_method:ident,    // the method to compute the hash
1811                 $($verify_args:expr),* // additional arguments for the above
1812                ) => ({
1813                  if ! is_selfsig {
1814                    t!("check_one_3rd_party!({}, {}, {:?}, {}, {}, ...)",
1815                       $desc, stringify!($sigs), $sig,
1816                       stringify!($verify_method), stringify!($hash_method));
1817                    if let Some(key) = $lookup_fn(&$sig) {
1818                        match $sig.$verify_method(&key,
1819                                                 self.primary.key(),
1820                                                 $($verify_args),*)
1821                        {
1822                          Ok(()) => {
1823                            t!("Sig {:02X}{:02X}, {:?} \
1824                                was out of place.  Belongs to {}.",
1825                               $sig.digest_prefix()[0],
1826                               $sig.digest_prefix()[1],
1827                               $sig.typ(), $desc);
1828
1829                            $sigs.push($sig);
1830                            continue 'outer;
1831                          },
1832                          Err(err) => {
1833                            t!("Sig {:02X}{:02X}, type = {} \
1834                                doesn't belong to {}: {:?}",
1835                               $sig.digest_prefix()[0], $sig.digest_prefix()[1],
1836                               $sig.typ(), $desc, err);
1837                          },
1838                       }
1839                    } else {
1840                        // Use hash prefix as heuristic.
1841                        let key = self.primary.key();
1842                        match $sig.hash_algo().context()
1843                            .and_then(|ctx| {
1844                                let mut ctx =
1845                                    ctx.for_signature($sig.version());
1846                                $sig.$hash_method(&mut ctx, key,
1847                                                 $($verify_args),*)?;
1848                                ctx.into_digest()
1849                            })
1850                        {
1851                          Ok(hash) => {
1852                            if &$sig.digest_prefix()[..] == &hash[..2] {
1853                                t!("Sig {:02X}{:02X}, {:?} \
1854                                    was out of place.  Likely belongs to {}.",
1855                                   $sig.digest_prefix()[0],
1856                                   $sig.digest_prefix()[1],
1857                                   $sig.typ(), $desc);
1858
1859                                $sigs.push({
1860                                    let sig = $sig.clone();
1861                                    sig.set_computed_digest(Some(hash));
1862                                    sig
1863                                });
1864
1865                                // The cost of missing a revocation
1866                                // certificate merely because we put
1867                                // it into the wrong place seem to
1868                                // outweigh the cost of duplicating
1869                                // it.
1870                                t!("Will keep trying to match this sig to \
1871                                    other components (found before? {:?})...",
1872                                   found_component);
1873                                found_component = true;
1874                            } else {
1875                                t!("Sig {:02X}{:02X}, {:?} \
1876                                    does not belong to {}: \
1877                                    hash prefix mismatch {}",
1878                                   $sig.digest_prefix()[0],
1879                                   $sig.digest_prefix()[1],
1880                                   $sig.typ(), $desc,
1881                                   crate::fmt::hex::encode(&hash));
1882                            }
1883                          },
1884                          Err(e) => {
1885                            t!("Sig {:02X}{:02X}, type = {}: {}",
1886                               $sig.digest_prefix()[0], $sig.digest_prefix()[1],
1887                               $sig.typ(), e);
1888                          },
1889                        }
1890                    }
1891                  }
1892                });
1893                ($desc:expr, $sigs:expr, $sig:ident, $lookup_fn:expr,
1894                 $verify_method:ident, $hash_method:ident) => ({
1895                     check_one_3rd_party!($desc, $sigs, $sig, $lookup_fn,
1896                                          $verify_method, $hash_method, )
1897                 });
1898            }
1899
1900            match sig.typ() {
1901                DirectKey => {
1902                    check_one!("primary key", self.primary.self_signatures,
1903                               sig, hash_direct_key);
1904                    check_one_3rd_party!(
1905                        "primary key", self.primary.certifications, sig,
1906                        lookup_fn,
1907                        verify_direct_key, hash_direct_key);
1908                },
1909
1910                KeyRevocation => {
1911                    check_one!("primary key", self.primary.self_revocations,
1912                               sig, hash_direct_key);
1913                    check_one_3rd_party!(
1914                        "primary key", self.primary.other_revocations, sig,
1915                        lookup_fn, verify_primary_key_revocation,
1916                        hash_direct_key);
1917                },
1918
1919                GenericCertification | PersonaCertification
1920                    | CasualCertification | PositiveCertification =>
1921                {
1922                    for binding in self.userids.iter_mut() {
1923                        check_one!(format!("userid \"{}\"",
1924                                           String::from_utf8_lossy(
1925                                               binding.userid().value())),
1926                                   binding.self_signatures, sig,
1927                                   hash_userid_binding, binding.userid());
1928                        check_one_3rd_party!(
1929                            format!("userid \"{}\"",
1930                                    String::from_utf8_lossy(
1931                                        binding.userid().value())),
1932                            binding.certifications, sig, lookup_fn,
1933                            verify_userid_binding, hash_userid_binding,
1934                            binding.userid());
1935                    }
1936
1937                    for binding in self.user_attributes.iter_mut() {
1938                        check_one!("user attribute",
1939                                   binding.self_signatures, sig,
1940                                   hash_user_attribute_binding,
1941                                   binding.user_attribute());
1942                        check_one_3rd_party!(
1943                            "user attribute",
1944                            binding.certifications, sig, lookup_fn,
1945                            verify_user_attribute_binding,
1946                            hash_user_attribute_binding,
1947                            binding.user_attribute());
1948                    }
1949                },
1950
1951                crate::types::SignatureType::CertificationApproval => {
1952                    for binding in self.userids.iter_mut() {
1953                        check_one!(format!("userid \"{}\"",
1954                                           String::from_utf8_lossy(
1955                                               binding.userid().value())),
1956                                   binding.attestations, sig,
1957                                   hash_userid_approval, binding.userid());
1958                    }
1959
1960                    for binding in self.user_attributes.iter_mut() {
1961                        check_one!("user attribute",
1962                                   binding.attestations, sig,
1963                                   hash_user_attribute_approval,
1964                                   binding.user_attribute());
1965                    }
1966                },
1967
1968                CertificationRevocation => {
1969                    for binding in self.userids.iter_mut() {
1970                        check_one!(format!("userid \"{}\"",
1971                                           String::from_utf8_lossy(
1972                                               binding.userid().value())),
1973                                   binding.self_revocations, sig,
1974                                   hash_userid_binding,
1975                                   binding.userid());
1976                        check_one_3rd_party!(
1977                            format!("userid \"{}\"",
1978                                    String::from_utf8_lossy(
1979                                        binding.userid().value())),
1980                            binding.other_revocations, sig, lookup_fn,
1981                            verify_userid_revocation, hash_userid_binding,
1982                            binding.userid());
1983                    }
1984
1985                    for binding in self.user_attributes.iter_mut() {
1986                        check_one!("user attribute",
1987                                   binding.self_revocations, sig,
1988                                   hash_user_attribute_binding,
1989                                   binding.user_attribute());
1990                        check_one_3rd_party!(
1991                            "user attribute",
1992                            binding.other_revocations, sig, lookup_fn,
1993                            verify_user_attribute_revocation,
1994                            hash_user_attribute_binding,
1995                            binding.user_attribute());
1996                    }
1997                },
1998
1999                SubkeyBinding => {
2000                    for binding in self.subkeys.iter_mut() {
2001                        check_one!(format!("subkey {}", binding.key().keyid()),
2002                                   binding.self_signatures, sig,
2003                                   hash_subkey_binding, binding.key());
2004                        check_one_3rd_party!(
2005                            format!("subkey {}", binding.key().keyid()),
2006                            binding.certifications, sig, lookup_fn,
2007                            verify_subkey_binding, hash_subkey_binding,
2008                            binding.key());
2009                    }
2010                },
2011
2012                SubkeyRevocation => {
2013                    for binding in self.subkeys.iter_mut() {
2014                        check_one!(format!("subkey {}", binding.key().keyid()),
2015                                   binding.self_revocations, sig,
2016                                   hash_subkey_binding, binding.key());
2017                        check_one_3rd_party!(
2018                            format!("subkey {}", binding.key().keyid()),
2019                            binding.other_revocations, sig, lookup_fn,
2020                            verify_subkey_revocation, hash_subkey_binding,
2021                            binding.key());
2022                    }
2023                },
2024
2025                typ => {
2026                    t!("Odd signature type: {:?}", typ);
2027                },
2028            }
2029
2030            if found_component {
2031                continue;
2032            }
2033
2034            // Keep them for later.
2035            t!("{} {:02X}{:02X}, {:?}, originally found on {:?} \
2036                doesn't belong to any known component or is bad.",
2037               if is_selfsig { "Self-sig" } else { "3rd-party-sig" },
2038               sig.digest_prefix()[0], sig.digest_prefix()[1],
2039               sig.typ(), unknown_idx);
2040
2041            if let Some(i) = unknown_idx {
2042                let is_revocation = match sig.typ() {
2043                    CertificationRevocation | KeyRevocation | SubkeyRevocation
2044                        => true,
2045                    _ => false,
2046                };
2047                match (is_selfsig, is_revocation) {
2048                    (false, false) =>
2049                        self.unknowns[i].certifications.push(sig),
2050                    (false, true) =>
2051                        self.unknowns[i].other_revocations.push(sig),
2052                    (true, false) =>
2053                        self.unknowns[i].self_signatures.push(sig),
2054                    (true, true) =>
2055                        self.unknowns[i].self_revocations.push(sig),
2056                }
2057            } else {
2058                self.bad.push(sig);
2059            }
2060        }
2061
2062        if !self.bad.is_empty() {
2063            t!("{}: ignoring {} bad self signatures",
2064               self.keyid(), self.bad.len());
2065        }
2066
2067        // Sort again.  We may have moved signatures to the right
2068        // component, and we need to ensure they are in the right spot
2069        // (i.e. newest first).
2070        self.sort_and_dedup();
2071
2072        // XXX: Check if the sigs in other_sigs issuer are actually
2073        // designated revokers for this key (listed in a "Revocation
2074        // Key" subpacket in *any* non-revoked self signature).  Only
2075        // if that is the case should a sig be considered a potential
2076        // revocation.  (This applies to
2077        // self.primary_other_revocations as well as
2078        // self.userids().other_revocations, etc.)  If not, put the
2079        // sig on the bad list.
2080        //
2081        // Note: just because the Cert doesn't indicate that a key is a
2082        // designed revoker doesn't mean that it isn't---we might just
2083        // be missing the signature.  In other words, this is a policy
2084        // decision, but given how easy it could be to create rogue
2085        // revocations, is probably the better to reject such
2086        // signatures than to keep them around and have many keys
2087        // being shown as "potentially revoked".
2088
2089        // XXX Do some more canonicalization.
2090
2091        self
2092    }
2093
2094    /// Returns the certificate's fingerprint as a `KeyHandle`.
2095    ///
2096    /// # Examples
2097    ///
2098    /// ```
2099    /// # use sequoia_openpgp as openpgp;
2100    /// # use openpgp::cert::prelude::*;
2101    /// # use openpgp::KeyHandle;
2102    /// #
2103    /// # fn main() -> openpgp::Result<()> {
2104    /// # let (cert, _) =
2105    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
2106    /// #     .generate()?;
2107    /// #
2108    /// println!("{}", cert.key_handle());
2109    ///
2110    /// // This always returns a fingerprint.
2111    /// match cert.key_handle() {
2112    ///     KeyHandle::Fingerprint(_) => (),
2113    ///     KeyHandle::KeyID(_) => unreachable!(),
2114    /// }
2115    /// #
2116    /// # Ok(())
2117    /// # }
2118    /// ```
2119    pub fn key_handle(&self) -> KeyHandle {
2120        self.primary.key().key_handle()
2121    }
2122
2123    /// Returns the certificate's fingerprint.
2124    ///
2125    /// # Examples
2126    ///
2127    /// ```
2128    /// # use sequoia_openpgp as openpgp;
2129    /// # use openpgp::cert::prelude::*;
2130    /// #
2131    /// # fn main() -> openpgp::Result<()> {
2132    /// # let (cert, _) =
2133    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
2134    /// #     .generate()?;
2135    /// #
2136    /// println!("{}", cert.fingerprint());
2137    /// #
2138    /// # Ok(())
2139    /// # }
2140    /// ```
2141    pub fn fingerprint(&self) -> Fingerprint {
2142        self.primary.key().fingerprint()
2143    }
2144
2145    /// Returns the certificate's Key ID.
2146    ///
2147    /// As a general rule of thumb, you should prefer the fingerprint
2148    /// as it is possible to create keys with a colliding Key ID using
2149    /// a [birthday attack].
2150    ///
2151    /// [birthday attack]: https://nullprogram.com/blog/2019/07/22/
2152    ///
2153    /// # Examples
2154    ///
2155    /// ```
2156    /// # use sequoia_openpgp as openpgp;
2157    /// # use openpgp::cert::prelude::*;
2158    /// #
2159    /// # fn main() -> openpgp::Result<()> {
2160    /// # let (cert, _) =
2161    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
2162    /// #     .generate()?;
2163    /// #
2164    /// println!("{}", cert.keyid());
2165    /// #
2166    /// # Ok(())
2167    /// # }
2168    /// ```
2169    pub fn keyid(&self) -> KeyID {
2170        self.primary.key().keyid()
2171    }
2172
2173    /// Merges `other` into `self`, ignoring secret key material in
2174    /// `other`.
2175    ///
2176    /// If `other` is a different certificate, then an error is
2177    /// returned.
2178    ///
2179    /// Merging two versions of a certificate is complicated, because
2180    /// there may be multiple variants of the same key or signature
2181    /// packet.  It is possible to have multiple variants of a key
2182    /// packet if one contains secret key material, and the other
2183    /// does not, or if both contain secret key material that is
2184    /// protected in different ways, e.g., a different algorithm, or a
2185    /// different password.  Multiple variants of a signature packet
2186    /// are possible when the unhashed subpacket areas differ.
2187    ///
2188    /// This routine is different from [`Cert::insert_packets`] in the
2189    /// following ways:
2190    ///
2191    ///   - `Cert::merge_public` strictly prefers keys in `self` to
2192    ///     those in `other`.  That is, if a primary key or subkey
2193    ///     appears in both `self` and `other`, the version in `self`
2194    ///     is kept.  In contrast, [`Cert::insert_packets`] prefers
2195    ///     the new variant.
2196    ///
2197    ///   - If `other` contains a new subkey, `Cert::merge_public`
2198    ///     merges it into the certificate, but strips any secret key
2199    ///     material.  In contrast, [`Cert::insert_packets`] preserves
2200    ///     the secret key material.
2201    ///
2202    ///   - If both `self` and `other` contain two variants of a
2203    ///     signature (that is, a signature packet that is identical
2204    ///     expect for the contents of the unhashed subpacket area),
2205    ///     `Cert::merge_public` merges the two variants using
2206    ///     [`Signature::merge`], which combines the unhashed
2207    ///     subpacket areas.  [`Cert::insert_packets`] just takes the
2208    ///     new signature packet.
2209    ///
2210    /// This function is appropriate to merge certificate material
2211    /// from untrusted sources like keyservers, because it only adds
2212    /// data to the existing certificate, it never overwrites existing
2213    /// data, and it doesn't import secret key material, which may
2214    /// have been manipulated by an attacker.
2215    ///
2216    /// [`Cert::merge_public_and_secret`] is similar to this function,
2217    /// but merges in secret key material from `other`.
2218    ///
2219    /// # Examples
2220    ///
2221    /// Merge a certificate from an untrusted source:
2222    ///
2223    /// ```
2224    /// # use sequoia_openpgp as openpgp;
2225    /// # use openpgp::cert::prelude::*;
2226    /// #
2227    /// # fn main() -> openpgp::Result<()> {
2228    /// # let (local, _) =
2229    /// #       CertBuilder::general_purpose(Some("alice@example.org"))
2230    /// #       .generate()?;
2231    /// # let keyserver = local.clone();
2232    /// // Merge the local version with the version from the keyserver.
2233    /// let cert = local.merge_public(keyserver)?;
2234    /// # let _ = cert;
2235    /// # Ok(()) }
2236    /// ```
2237    ///
2238    /// Secret key material in `other` is stripped, even if the
2239    /// variant of the packet in `self` doesn't have secret key
2240    /// material:
2241    ///
2242    /// ```
2243    /// use sequoia_openpgp as openpgp;
2244    /// use openpgp::cert::CertBuilder;
2245    ///
2246    /// # fn main() -> openpgp::Result<()> {
2247    /// // Create a new key.
2248    /// let (cert, rev) =
2249    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2250    ///       .generate()?;
2251    /// assert!(cert.is_tsk());
2252    ///
2253    /// let stripped = cert.clone().strip_secret_key_material();
2254    /// assert!(! stripped.is_tsk());
2255    ///
2256    /// // Merge `cert` into `stripped`.
2257    /// let merged = stripped.merge_public(cert).expect("same certificate");
2258    /// assert!(! merged.is_tsk());
2259    ///
2260    /// # Ok(()) }
2261    /// ```
2262    ///
2263    /// Secret key material from `self` is preferred to secret key
2264    /// material from `other`:
2265    ///
2266    /// ```
2267    /// use sequoia_openpgp as openpgp;
2268    /// use openpgp::crypto::Password;
2269    /// use openpgp::cert::prelude::*;
2270    /// use openpgp::Packet;
2271    ///
2272    /// # fn main() -> openpgp::Result<()> {
2273    /// let p0 = Password::from("old password");
2274    /// let p1 = Password::from("new password");
2275    ///
2276    /// // Create a new key.
2277    /// let (cert, rev) =
2278    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2279    ///       .set_password(Some(p0.clone()))
2280    ///       .generate()?;
2281    /// assert!(cert.is_tsk());
2282    ///
2283    /// // Change the password for the primary key.
2284    /// let pk = cert.primary_key().key().clone().parts_into_secret()?
2285    ///     .decrypt_secret(&p0)?
2286    ///     .encrypt_secret(&p1)?;
2287    /// let other = Cert::try_from(vec![ Packet::from(pk) ])
2288    ///     .expect("a primary key is a certificate");
2289    ///
2290    /// // Merge `other` into `cert`.
2291    /// let merged = cert.merge_public(other).expect("same certificate");
2292    ///
2293    /// // `merged` has the secret key material from `cert`, which is
2294    /// // password protected with `p0`, not `other`, which is password
2295    /// // protected with `p1`.
2296    /// assert!(merged.primary_key().key().clone().parts_into_secret()?
2297    ///         .decrypt_secret(&p0).is_ok());
2298    /// # Ok(()) }
2299    /// ```
2300    ///
2301    /// The unhashed subpacket areas of two variants of a signature
2302    /// are merged:
2303    ///
2304    /// ```
2305    /// use sequoia_openpgp as openpgp;
2306    /// use openpgp::Packet;
2307    /// use openpgp::cert::prelude::*;
2308    /// use openpgp::packet::signature::subpacket::Subpacket;
2309    /// use openpgp::packet::signature::subpacket::SubpacketTag;
2310    /// use openpgp::packet::signature::subpacket::SubpacketValue;
2311    ///
2312    /// # fn main() -> openpgp::Result<()> {
2313    /// // Create a new key.
2314    /// let (cert, rev) =
2315    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2316    ///       .generate()?;
2317    /// assert!(cert.is_tsk());
2318    ///
2319    /// // Add a subpacket to the unhashed subpacket area.
2320    /// let subpacket_a = Subpacket::new(
2321    ///     SubpacketValue::Unknown {
2322    ///         tag: SubpacketTag::Private(100),
2323    ///         body: Vec::new(),
2324    ///     },
2325    ///     false).expect("valid");
2326    /// let subpacket_b = Subpacket::new(
2327    ///     SubpacketValue::Unknown {
2328    ///         tag: SubpacketTag::Private(101),
2329    ///         body: Vec::new(),
2330    ///     },
2331    ///     false).expect("valid");
2332    ///
2333    /// let mut cert_a = cert.clone().into_packets().collect::<Vec<Packet>>();
2334    /// match cert_a[1] {
2335    ///     Packet::Signature(ref mut sig) => {
2336    ///         let unhashed_area = sig.unhashed_area_mut();
2337    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_none());
2338    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_none());
2339    ///         unhashed_area.add(subpacket_a.clone());
2340    ///     }
2341    ///     _ => panic!("Second packet is the direct signature packet."),
2342    /// };
2343    /// let cert_a = Cert::try_from(cert_a).expect("valid");
2344    ///
2345    /// let mut cert_b = cert.clone().into_packets().collect::<Vec<Packet>>();
2346    /// match cert_b[1] {
2347    ///     Packet::Signature(ref mut sig) => {
2348    ///         let unhashed_area = sig.unhashed_area_mut();
2349    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_none());
2350    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_none());
2351    ///         unhashed_area.add(subpacket_b.clone());
2352    ///     }
2353    ///     _ => panic!("Second packet is the direct signature packet."),
2354    /// };
2355    /// let cert_b = Cert::try_from(cert_b).expect("valid");
2356    ///
2357    /// // When we merge `cert_b` into `cert_a`, the signature packets
2358    /// // are merged:
2359    /// let merged = cert_a.clone().merge_public(cert_b.clone())
2360    ///     .expect("same certificate")
2361    ///     .into_packets()
2362    ///     .collect::<Vec<Packet>>();
2363    /// match merged[1] {
2364    ///     Packet::Signature(ref sig) => {
2365    ///         let unhashed_area = sig.unhashed_area();
2366    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_some());
2367    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_some());
2368    ///     }
2369    ///     _ => panic!("Second packet is the direct signature packet."),
2370    /// };
2371    ///
2372    /// // Likewise, when we merge `cert_a` into `cert_b`, the signature
2373    /// // packets are merged:
2374    /// let merged = cert_b.clone().merge_public(cert_a.clone())
2375    ///     .expect("same certificate")
2376    ///     .into_packets()
2377    ///     .collect::<Vec<Packet>>();
2378    /// match merged[1] {
2379    ///     Packet::Signature(ref sig) => {
2380    ///         let unhashed_area = sig.unhashed_area();
2381    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_some());
2382    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_some());
2383    ///     }
2384    ///     _ => panic!("Second packet is the direct signature packet."),
2385    /// };
2386    /// # Ok(()) }
2387    /// ```
2388    pub fn merge_public(self, other: Cert) -> Result<Self> {
2389        // Strip all secrets from `other`.
2390        let other_public = other.strip_secret_key_material();
2391        // Then merge it.
2392        self.merge_public_and_secret(other_public)
2393    }
2394
2395    /// Merges `other` into `self`, including secret key material.
2396    ///
2397    /// If `other` is a different certificate, then an error is
2398    /// returned.
2399    ///
2400    /// This function is like [`Cert::merge_public`] except:
2401    ///
2402    ///   - if two variants of the same key have secret key material,
2403    ///     then the version in `other` is preferred,
2404    ///
2405    ///   - if there are two variants of the same key, and one has
2406    ///     secret key material, that variant is preferred.
2407    ///
2408    /// This is different from [`Cert::insert_packets`], which
2409    /// unconditionally prefers keys in the packets that are being
2410    /// merged into the certificate.
2411    ///
2412    /// It is important to only merge key material from trusted
2413    /// sources using this function, because it may be used to import
2414    /// secret key material.  Secret key material is not authenticated
2415    /// by OpenPGP, and there are plausible attack scenarios where a
2416    /// malicious actor injects secret key material.
2417    ///
2418    /// To merge only public key material, which is always safe, use
2419    /// [`Cert::merge_public`].
2420    ///
2421    /// # Examples
2422    ///
2423    /// Merge a certificate from a trusted source:
2424    ///
2425    /// ```
2426    /// # use sequoia_openpgp as openpgp;
2427    /// # use openpgp::cert::prelude::*;
2428    /// #
2429    /// # fn main() -> openpgp::Result<()> {
2430    /// # let (local, _) =
2431    /// #       CertBuilder::general_purpose(Some("alice@example.org"))
2432    /// #       .generate()?;
2433    /// # let other_device = local.clone();
2434    /// // Merge the local version with the version from your other device.
2435    /// let cert = local.merge_public_and_secret(other_device)?;
2436    /// # let _ = cert;
2437    /// # Ok(()) }
2438    /// ```
2439    ///
2440    /// Secret key material is preferred to no secret key material:
2441    ///
2442    /// ```
2443    /// use sequoia_openpgp as openpgp;
2444    /// use openpgp::cert::CertBuilder;
2445    ///
2446    /// # fn main() -> openpgp::Result<()> {
2447    /// // Create a new key.
2448    /// let (cert, rev) =
2449    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2450    ///       .generate()?;
2451    /// assert!(cert.is_tsk());
2452    ///
2453    /// let stripped = cert.clone().strip_secret_key_material();
2454    /// assert!(! stripped.is_tsk());
2455    ///
2456    /// // If we merge `cert` into `stripped`, the secret key material is
2457    /// // preserved:
2458    /// let merged = stripped.clone().merge_public_and_secret(cert.clone())
2459    ///     .expect("same certificate");
2460    /// assert!(merged.is_tsk());
2461    ///
2462    /// // Likewise if we merge `stripped` into `cert`:
2463    /// let merged = cert.merge_public_and_secret(stripped)
2464    ///     .expect("same certificate");
2465    /// assert!(merged.is_tsk());
2466    ///
2467    /// # Ok(()) }
2468    /// ```
2469    ///
2470    /// Secret key material in `other` is preferred:
2471    ///
2472    /// ```
2473    /// use sequoia_openpgp as openpgp;
2474    /// use openpgp::crypto::Password;
2475    /// use openpgp::cert::prelude::*;
2476    /// use openpgp::Packet;
2477    ///
2478    /// # fn main() -> openpgp::Result<()> {
2479    /// let p0 = Password::from("old password");
2480    /// let p1 = Password::from("new password");
2481    ///
2482    /// // Create a new key.
2483    /// let (cert, rev) =
2484    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2485    ///       .set_password(Some(p0.clone()))
2486    ///       .generate()?;
2487    /// assert!(cert.is_tsk());
2488    ///
2489    /// // Change the password for the primary key.
2490    /// let pk = cert.primary_key().key().clone().parts_into_secret()?
2491    ///     .decrypt_secret(&p0)?
2492    ///     .encrypt_secret(&p1)?;
2493    /// let other = Cert::try_from(vec![ Packet::from(pk) ])
2494    ///     .expect("a primary key is a certificate");
2495    ///
2496    /// // Merge `other` into `cert`.
2497    /// let merged = cert.merge_public_and_secret(other).expect("same certificate");
2498    ///
2499    /// // `merged` has the secret key material from `other`, which is
2500    /// // password protected with `p1`, not `self`, which is password
2501    /// // protected with `p0`.
2502    /// assert!(merged.primary_key().key().clone().parts_into_secret()?
2503    ///         .decrypt_secret(&p1).is_ok());
2504    /// # Ok(()) }
2505    /// ```
2506    ///
2507    /// The unhashed subpacket areas of two variants of a signature
2508    /// are merged:
2509    ///
2510    /// ```
2511    /// use sequoia_openpgp as openpgp;
2512    /// use openpgp::Packet;
2513    /// use openpgp::cert::prelude::*;
2514    /// use openpgp::packet::signature::subpacket::Subpacket;
2515    /// use openpgp::packet::signature::subpacket::SubpacketTag;
2516    /// use openpgp::packet::signature::subpacket::SubpacketValue;
2517    ///
2518    /// # fn main() -> openpgp::Result<()> {
2519    /// // Create a new key.
2520    /// let (cert, rev) =
2521    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2522    ///       .generate()?;
2523    /// assert!(cert.is_tsk());
2524    ///
2525    /// // Add a subpacket to the unhashed subpacket area.
2526    /// let subpacket_a = Subpacket::new(
2527    ///     SubpacketValue::Unknown {
2528    ///         tag: SubpacketTag::Private(100),
2529    ///         body: Vec::new(),
2530    ///     },
2531    ///     false).expect("valid");
2532    /// let subpacket_b = Subpacket::new(
2533    ///     SubpacketValue::Unknown {
2534    ///         tag: SubpacketTag::Private(101),
2535    ///         body: Vec::new(),
2536    ///     },
2537    ///     false).expect("valid");
2538    ///
2539    /// let mut cert_a = cert.clone().into_packets().collect::<Vec<Packet>>();
2540    /// match cert_a[1] {
2541    ///     Packet::Signature(ref mut sig) => {
2542    ///         let unhashed_area = sig.unhashed_area_mut();
2543    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_none());
2544    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_none());
2545    ///         unhashed_area.add(subpacket_a.clone());
2546    ///     }
2547    ///     _ => panic!("Second packet is the direct signature packet."),
2548    /// };
2549    /// let cert_a = Cert::try_from(cert_a).expect("valid");
2550    ///
2551    /// let mut cert_b = cert.clone().into_packets().collect::<Vec<Packet>>();
2552    /// match cert_b[1] {
2553    ///     Packet::Signature(ref mut sig) => {
2554    ///         let unhashed_area = sig.unhashed_area_mut();
2555    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_none());
2556    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_none());
2557    ///         unhashed_area.add(subpacket_b.clone());
2558    ///     }
2559    ///     _ => panic!("Second packet is the direct signature packet."),
2560    /// };
2561    /// let cert_b = Cert::try_from(cert_b).expect("valid");
2562    ///
2563    /// // When we merge `cert_b` into `cert_a`, the signature packets
2564    /// // are merged:
2565    /// let merged = cert_a.clone().merge_public_and_secret(cert_b.clone())
2566    ///     .expect("same certificate")
2567    ///     .into_packets()
2568    ///     .collect::<Vec<Packet>>();
2569    /// match merged[1] {
2570    ///     Packet::Signature(ref sig) => {
2571    ///         let unhashed_area = sig.unhashed_area();
2572    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_some());
2573    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_some());
2574    ///     }
2575    ///     _ => panic!("Second packet is the direct signature packet."),
2576    /// };
2577    ///
2578    /// // Likewise, when we merge `cert_a` into `cert_b`, the signature
2579    /// // packets are merged:
2580    /// let merged = cert_b.clone().merge_public_and_secret(cert_a.clone())
2581    ///     .expect("same certificate")
2582    ///     .into_packets()
2583    ///     .collect::<Vec<Packet>>();
2584    /// match merged[1] {
2585    ///     Packet::Signature(ref sig) => {
2586    ///         let unhashed_area = sig.unhashed_area();
2587    ///         assert!(unhashed_area.subpacket(subpacket_a.tag()).is_some());
2588    ///         assert!(unhashed_area.subpacket(subpacket_b.tag()).is_some());
2589    ///     }
2590    ///     _ => panic!("Second packet is the direct signature packet."),
2591    /// };
2592    /// # Ok(()) }
2593    /// ```
2594    pub fn merge_public_and_secret(mut self, mut other: Cert) -> Result<Self> {
2595        if self.fingerprint() != other.fingerprint() {
2596            // The primary key is not the same.  There is nothing to
2597            // do.
2598            return Err(Error::InvalidArgument(
2599                "Primary key mismatch".into()).into());
2600        }
2601
2602        // Prefer the secret in `other`.
2603        if other.primary.key().has_secret() {
2604            std::mem::swap(self.primary.key_mut(), other.primary.key_mut());
2605        }
2606
2607        self.primary.self_signatures.append(
2608            &mut other.primary.self_signatures);
2609        self.primary.attestations.append(
2610            &mut other.primary.attestations);
2611        self.primary.certifications.append(
2612            &mut other.primary.certifications);
2613        self.primary.self_revocations.append(
2614            &mut other.primary.self_revocations);
2615        self.primary.other_revocations.append(
2616            &mut other.primary.other_revocations);
2617
2618        self.userids.append(&mut other.userids);
2619        self.user_attributes.append(&mut other.user_attributes);
2620        self.subkeys.append(&mut other.subkeys);
2621        self.bad.append(&mut other.bad);
2622
2623        Ok(self.canonicalize())
2624    }
2625
2626    // Returns whether the specified packet is a valid start of a
2627    // certificate.
2628    fn valid_start<T>(tag: T) -> Result<()>
2629        where T: Into<Tag>
2630    {
2631        let tag = tag.into();
2632        match tag {
2633            Tag::SecretKey | Tag::PublicKey => Ok(()),
2634            _ => Err(Error::MalformedCert(
2635                format!("A certificate does not start with a {}",
2636                        tag)).into()),
2637        }
2638    }
2639
2640    // Returns whether the specified packet can occur in a
2641    // certificate.
2642    //
2643    // This function rejects all packets that are known to not belong
2644    // in a certificate.  It conservatively accepts unknown packets
2645    // based on the assumption that they are some new component type
2646    // from the future.
2647    fn valid_packet<T>(tag: T) -> Result<()>
2648        where T: Into<Tag>
2649    {
2650        let tag = tag.into();
2651        match tag {
2652            // Packets that definitely don't belong in a certificate.
2653            Tag::Reserved
2654                | Tag::PKESK
2655                | Tag::SKESK
2656                | Tag::OnePassSig
2657                | Tag::CompressedData
2658                | Tag::SED
2659                | Tag::Literal
2660                | Tag::SEIP
2661                | Tag::MDC
2662                | Tag::AED =>
2663            {
2664                Err(Error::MalformedCert(
2665                    format!("A certificate cannot not include a {}",
2666                            tag)).into())
2667            }
2668            // The rest either definitely belong in a certificate or
2669            // are unknown (and conservatively accepted for future
2670            // compatibility).
2671            _ => Ok(()),
2672        }
2673    }
2674
2675    /// Adds packets to the certificate.
2676    ///
2677    /// This function turns the certificate into a sequence of
2678    /// packets, appends the packets to the end of it, and
2679    /// canonicalizes the result.  [Known packets that don't belong in
2680    /// a TPK or TSK] cause this function to return an error.  Unknown
2681    /// packets are retained and added to the list of [unknown
2682    /// components].  The goal is to provide some future
2683    /// compatibility.
2684    ///
2685    /// If a key is merged that already exists in the certificate, it
2686    /// replaces the existing key.  This way, secret key material can
2687    /// be added, removed, encrypted, or decrypted.
2688    ///
2689    /// Similarly, if a signature is merged that already exists in the
2690    /// certificate, it replaces the existing signature.  This way,
2691    /// the unhashed subpacket area can be updated.
2692    ///
2693    /// On success, this function returns the certificate with the
2694    /// packets merged in, and a boolean indicating whether the
2695    /// certificate actually changed.  Changed here means that at
2696    /// least one new packet was added, or an existing packet was
2697    /// updated.  Alternatively, changed means that the serialized
2698    /// form has changed.
2699    ///
2700    /// [Known packets that don't belong in a TPK or TSK]: https://www.rfc-editor.org/rfc/rfc9580.html#section-10
2701    /// [unknown components]: Cert::unknowns()
2702    ///
2703    /// # Examples
2704    ///
2705    /// ```
2706    /// use sequoia_openpgp as openpgp;
2707    /// use openpgp::cert::prelude::*;
2708    /// use openpgp::packet::prelude::*;
2709    /// use openpgp::serialize::Serialize;
2710    /// use openpgp::parse::Parse;
2711    /// use openpgp::types::DataFormat;
2712    ///
2713    /// # fn main() -> openpgp::Result<()> {
2714    /// // Create a new key.
2715    /// let (cert, rev) =
2716    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2717    ///       .generate()?;
2718    /// assert!(cert.is_tsk());
2719    ///
2720    ///
2721    /// // Merging in the certificate doesn't change it.
2722    /// let identical_cert = cert.clone();
2723    /// let (cert, changed) =
2724    ///     cert.insert_packets(identical_cert.into_tsk().into_packets())?;
2725    /// assert!(! changed);
2726    ///
2727    ///
2728    /// // Merge in the revocation certificate.
2729    /// assert_eq!(cert.primary_key().self_revocations().count(), 0);
2730    /// let (cert, changed) = cert.insert_packets(rev)?;
2731    /// assert!(changed);
2732    /// assert_eq!(cert.primary_key().self_revocations().count(), 1);
2733    ///
2734    ///
2735    /// // Add an unknown packet.
2736    /// let tag = Tag::Private(61.into());
2737    /// let unknown = Unknown::new(tag,
2738    ///     openpgp::Error::UnsupportedPacketType(tag).into());
2739    ///
2740    /// // It shows up as an unknown component.
2741    /// let (cert, changed) = cert.insert_packets(unknown)?;
2742    /// assert!(changed);
2743    /// assert_eq!(cert.unknowns().count(), 1);
2744    /// for p in cert.unknowns() {
2745    ///     assert_eq!(p.unknown().tag(), tag);
2746    /// }
2747    ///
2748    ///
2749    /// // Try and merge a literal data packet.
2750    /// let mut lit = Literal::new(DataFormat::Unicode);
2751    /// lit.set_body(b"test".to_vec());
2752    ///
2753    /// // Merging packets that are known to not belong to a
2754    /// // certificate result in an error.
2755    /// assert!(cert.insert_packets(lit).is_err());
2756    /// #     Ok(())
2757    /// # }
2758    /// ```
2759    ///
2760    /// Remove secret key material:
2761    ///
2762    /// ```
2763    /// use sequoia_openpgp as openpgp;
2764    /// use openpgp::cert::prelude::*;
2765    /// use openpgp::packet::prelude::*;
2766    ///
2767    /// # fn main() -> openpgp::Result<()> {
2768    /// // Create a new key.
2769    /// let (cert, _) =
2770    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2771    ///       .generate()?;
2772    /// assert!(cert.is_tsk());
2773    ///
2774    /// // We just created the key, so all the keys have secret key
2775    /// // material.
2776    /// let mut pk = cert.primary_key().key().clone();
2777    ///
2778    /// // Split off the secret key material.
2779    /// let (pk, sk) = pk.take_secret();
2780    /// assert!(sk.is_some());
2781    /// assert!(! pk.has_secret());
2782    ///
2783    /// // Merge in the public key.  Recall: the packets that are
2784    /// // being merged into the certificate take precedence.
2785    /// let (cert, changed) = cert.insert_packets(pk)?;
2786    /// assert!(changed);
2787    ///
2788    /// // The secret key material is stripped.
2789    /// assert!(! cert.primary_key().key().has_secret());
2790    /// #     Ok(())
2791    /// # }
2792    /// ```
2793    ///
2794    /// Update a binding signature's unhashed subpacket area:
2795    ///
2796    /// ```
2797    /// # fn main() -> sequoia_openpgp::Result<()> {
2798    /// use sequoia_openpgp as openpgp;
2799    /// use openpgp::cert::prelude::*;
2800    /// use openpgp::packet::prelude::*;
2801    /// use openpgp::packet::signature::subpacket::*;
2802    ///
2803    /// // Create a new key.
2804    /// let (cert, _) =
2805    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2806    ///       .generate()?;
2807    /// assert_eq!(cert.userids().nth(0).unwrap().self_signatures().count(), 1);
2808    ///
2809    /// // Grab the binding signature so that we can modify it.
2810    /// let mut sig =
2811    ///     cert.userids().nth(0).unwrap().self_signatures().nth(0)
2812    ///     .unwrap().clone();
2813    ///
2814    /// // Add a notation subpacket.  Note that the information is not
2815    /// // authenticated, therefore it may only be trusted if the
2816    /// // certificate with the signature is placed in a trusted store.
2817    /// let notation = NotationData::new("retrieved-from@example.org",
2818    ///                                  "generated-locally",
2819    ///                                  NotationDataFlags::empty()
2820    ///                                      .set_human_readable());
2821    /// sig.unhashed_area_mut().add(
2822    ///     Subpacket::new(SubpacketValue::NotationData(notation), false)?)?;
2823    ///
2824    /// // Merge in the signature.  Recall: the packets that are
2825    /// // being merged into the certificate take precedence.
2826    /// let (cert, changed) = cert.insert_packets(sig)?;
2827    /// assert!(changed);
2828    ///
2829    /// // The old binding signature is replaced.
2830    /// assert_eq!(cert.userids().nth(0).unwrap().self_signatures().count(), 1);
2831    /// assert_eq!(cert.userids().nth(0).unwrap().self_signatures().nth(0)
2832    ///                .unwrap()
2833    ///                .unhashed_area()
2834    ///                .subpackets(SubpacketTag::NotationData).count(), 1);
2835    /// # Ok(()) }
2836    /// ```
2837    pub fn insert_packets<I>(self, packets: I)
2838        -> Result<(Self, bool)>
2839        where I: IntoIterator,
2840              I::Item: Into<Packet>,
2841    {
2842        self.insert_packets_merge(packets, |_old, new| Ok(new))
2843    }
2844
2845    /// Adds packets to the certificate with an explicit merge policy.
2846    ///
2847    /// Like [`Cert::insert_packets`], but also takes a function that
2848    /// will be called on inserts and replacements that can be used to
2849    /// log changes to the certificate, and to influence how packets
2850    /// are merged.  The merge function takes two parameters, an
2851    /// optional existing packet, and the packet to be merged in.
2852    ///
2853    /// If a new packet is inserted, there is no packet currently in
2854    /// the certificate.  Hence, the first parameter to the merge
2855    /// function is `None`.
2856    ///
2857    /// If an existing packet is updated, there is a packet currently
2858    /// in the certificate that matches the given packet.  Hence, the
2859    /// first parameter to the merge function is
2860    /// `Some(existing_packet)`.
2861    ///
2862    /// Both packets given to the merge function are considered equal
2863    /// when considering the normalized form (only comparing public
2864    /// key parameters and ignoring unhashed signature subpackets, see
2865    /// [`Packet::normalized_hash`]).  It must return a packet that
2866    /// equals the input packet.  In practice that means that the
2867    /// merge function returns either the old packet, the new packet,
2868    /// or a combination of both packets.  If the merge function
2869    /// returns a different packet, this function returns
2870    /// [`Error::InvalidOperation`].
2871    ///
2872    /// If the merge function returns the existing packet, this
2873    /// function will still consider this as a change to the
2874    /// certificate.  In other words, it may return that the
2875    /// certificate has changed even if the serialized representation
2876    /// has not changed.
2877    ///
2878    /// # Examples
2879    ///
2880    /// In the first example, we give an explicit merge function that
2881    /// just returns the new packet.  This policy prefers the new
2882    /// packet.  This is the policy used by [`Cert::insert_packets`].
2883    ///
2884    /// ```
2885    /// use sequoia_openpgp as openpgp;
2886    /// use openpgp::crypto::Password;
2887    /// use openpgp::cert::prelude::CertBuilder;
2888    ///
2889    /// # fn main() -> openpgp::Result<()> {
2890    /// let p0 = Password::from("old password");
2891    /// let p1 = Password::from("new password");
2892    ///
2893    /// // Create a new key.
2894    /// let (cert, rev) =
2895    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2896    ///       .set_password(Some(p0.clone()))
2897    ///       .generate()?;
2898    /// assert!(cert.is_tsk());
2899    ///
2900    /// // Change the password for the primary key.
2901    /// let pk = cert.primary_key().key().clone().parts_into_secret()?
2902    ///     .decrypt_secret(&p0)?
2903    ///     .encrypt_secret(&p1)?;
2904    ///
2905    /// // Merge it back in, with a policy projecting to the new packet.
2906    /// let (cert, changed) =
2907    ///     cert.insert_packets_merge(pk, |_old, new| Ok(new))?;
2908    /// assert!(changed);
2909    ///
2910    /// // Make sure we can still decrypt the primary key using the
2911    /// // new password.
2912    /// assert!(cert.primary_key().key().clone().parts_into_secret()?
2913    ///         .decrypt_secret(&p1).is_ok());
2914    /// # Ok(()) }
2915    /// ```
2916    ///
2917    /// In the second example, we give an explicit merge function that
2918    /// returns the old packet if given, falling back to the new
2919    /// packet, if not.  This policy prefers the existing packets.
2920    ///
2921    /// ```
2922    /// use sequoia_openpgp as openpgp;
2923    /// use openpgp::crypto::Password;
2924    /// use openpgp::cert::prelude::CertBuilder;
2925    ///
2926    /// # fn main() -> openpgp::Result<()> {
2927    /// let p0 = Password::from("old password");
2928    /// let p1 = Password::from("new password");
2929    ///
2930    /// // Create a new key.
2931    /// let (cert, rev) =
2932    ///       CertBuilder::general_purpose(Some("alice@example.org"))
2933    ///       .set_password(Some(p0.clone()))
2934    ///       .generate()?;
2935    /// assert!(cert.is_tsk());
2936    ///
2937    /// // Change the password for the primary key.
2938    /// let pk = cert.primary_key().key().clone().parts_into_secret()?
2939    ///     .decrypt_secret(&p0)?
2940    ///     .encrypt_secret(&p1)?;
2941    ///
2942    /// // Merge it back in, with a policy preferring the old packet.
2943    /// let (cert, changed) =
2944    ///     cert.insert_packets_merge(pk, |old, new| Ok(old.unwrap_or(new)))?;
2945    /// assert!(changed); // Overestimates changes.
2946    ///
2947    /// // Make sure we can still decrypt the primary key using the
2948    /// // old password.
2949    /// assert!(cert.primary_key().key().clone().parts_into_secret()?
2950    ///         .decrypt_secret(&p0).is_ok());
2951    /// # Ok(()) }
2952    /// ```
2953    pub fn insert_packets_merge<P, I>(self, packets: P, merge: I)
2954        -> Result<(Self, bool)>
2955        where P: IntoIterator,
2956              P::Item: Into<Packet>,
2957              I: FnMut(Option<Packet>, Packet) -> Result<Packet>,
2958    {
2959        self.insert_packets_(&mut packets.into_iter().map(Into::into),
2960                             Box::new(merge))
2961    }
2962
2963    /// Adds packets to the certificate with an explicit merge policy.
2964    ///
2965    /// This implements all the Cert::insert_packets* functions.  Its
2966    /// arguments `packets` and `merge` use dynamic dispatch so that
2967    /// we avoid the cost of monomorphization.
2968    fn insert_packets_<'a>(self,
2969                           packets: &mut dyn Iterator<Item = Packet>,
2970                           mut merge: Box<dyn FnMut(Option<Packet>, Packet)
2971                                                    -> Result<Packet> + 'a>)
2972        -> Result<(Self, bool)>
2973    {
2974        let mut changed = false;
2975        let mut combined =
2976            self.as_tsk().into_packets().collect::<Vec<_>>();
2977
2978        // Hashes a packet ignoring the unhashed subpacket area and
2979        // any secret key material.
2980        let hash_packet = |p: &Packet| -> u64 {
2981            let mut hasher = DefaultHasher::new();
2982            p.normalized_hash(&mut hasher);
2983            hasher.finish()
2984        };
2985
2986        // BTreeMap of (hash) -> Vec<index in combined>.
2987        //
2988        // We don't use a HashMap, because the key would be a
2989        // reference to the packets in combined, which would prevent
2990        // us from modifying combined.
2991        //
2992        // Note: we really don't want to dedup components now, because
2993        // we want to keep signatures immediately after their
2994        // components.
2995        let mut packet_map: BTreeMap<u64, Vec<usize>> = BTreeMap::new();
2996        for (i, p) in combined.iter().enumerate() {
2997            match packet_map.entry(hash_packet(p)) {
2998                Entry::Occupied(mut oe) => {
2999                    oe.get_mut().push(i)
3000                }
3001                Entry::Vacant(ve) => {
3002                    ve.insert(vec![ i ]);
3003                }
3004            }
3005        }
3006
3007        enum Action {
3008            Drop,
3009            Overwrite(usize),
3010            Insert,
3011        }
3012        use Action::*;
3013
3014        // Now we merge in the new packets.
3015        for p in packets {
3016            Cert::valid_packet(&p)?;
3017
3018            let hash = hash_packet(&p);
3019            let mut action = Insert;
3020            if let Some(combined_i) = packet_map.get(&hash) {
3021                for i in combined_i {
3022                    let i: usize = *i;
3023                    let (same, identical) = match (&p, &combined[i]) {
3024                        // For keys, only compare the public bits.  If
3025                        // they match, then we keep whatever is in the
3026                        // new key.
3027                        (Packet::PublicKey(a), Packet::PublicKey(b)) =>
3028                            (a.public_cmp(b) == Ordering::Equal,
3029                             a == b),
3030                        (Packet::SecretKey(a), Packet::SecretKey(b)) =>
3031                            (a.public_cmp(b) == Ordering::Equal,
3032                             a == b),
3033                        (Packet::PublicKey(a), Packet::SecretKey(b)) =>
3034                            (a.public_cmp(b) == Ordering::Equal,
3035                             false),
3036                        (Packet::SecretKey(a), Packet::PublicKey(b)) =>
3037                            (a.public_cmp(b) == Ordering::Equal,
3038                             false),
3039
3040                        (Packet::PublicSubkey(a), Packet::PublicSubkey(b)) =>
3041                            (a.public_cmp(b) == Ordering::Equal,
3042                             a == b),
3043                        (Packet::SecretSubkey(a), Packet::SecretSubkey(b)) =>
3044                            (a.public_cmp(b) == Ordering::Equal,
3045                             a == b),
3046                        (Packet::PublicSubkey(a), Packet::SecretSubkey(b)) =>
3047                            (a.public_cmp(b) == Ordering::Equal,
3048                             false),
3049                        (Packet::SecretSubkey(a), Packet::PublicSubkey(b)) =>
3050                            (a.public_cmp(b) == Ordering::Equal,
3051                             false),
3052
3053                        // For signatures, don't compare the unhashed
3054                        // subpacket areas.  If it's the same
3055                        // signature, then we keep what is the new
3056                        // signature's unhashed subpacket area.
3057                        (Packet::Signature(a), Packet::Signature(b)) =>
3058                            (a.normalized_eq(b),
3059                             a == b),
3060
3061                        (a, b) => {
3062                            let identical = a == b;
3063                            (identical, identical)
3064                        }
3065                    };
3066
3067                    if same {
3068                        if identical {
3069                            action = Drop;
3070                        } else {
3071                            action = Overwrite(i);
3072                        }
3073                        break;
3074                    }
3075                }
3076            }
3077
3078            match action {
3079                Drop => (),
3080                Overwrite(i) => {
3081                    // Existing packet.
3082                    let existing =
3083                        std::mem::replace(&mut combined[i],
3084                                          Packet::Marker(Default::default()));
3085                    let merged = merge(Some(existing), p)?;
3086                    let merged_hash = hash_packet(&merged);
3087                    if hash != merged_hash {
3088                        return Err(Error::InvalidOperation(
3089                            format!("merge function changed packet hash \
3090                                     (expected: {}, got: {})",
3091                                    hash, merged_hash)).into());
3092                    }
3093
3094                    combined[i] = merged;
3095                    changed = true;
3096                },
3097                Insert => {
3098                    // New packet.
3099                    let merged = merge(None, p)?;
3100                    let merged_hash = hash_packet(&merged);
3101                    if hash != merged_hash {
3102                        return Err(Error::InvalidOperation(
3103                            format!("merge function changed packet hash \
3104                                     (expected: {}, got: {})",
3105                                    hash, merged_hash)).into());
3106                    }
3107
3108                    // Add it to combined.
3109                    combined.push(merged);
3110                    changed = true;
3111
3112                    // Because the caller might insert the same packet
3113                    // multiple times, we need to also add it to
3114                    // packet_map.
3115                    let i = combined.len() - 1;
3116                    match packet_map.entry(hash) {
3117                        Entry::Occupied(mut oe) => {
3118                            oe.get_mut().push(i)
3119                        }
3120                        Entry::Vacant(ve) => {
3121                            ve.insert(vec![ i ]);
3122                        }
3123                    }
3124                }
3125            }
3126        }
3127
3128        Cert::try_from(combined).map(|cert| (cert, changed))
3129    }
3130
3131    /// Returns whether at least one of the keys includes secret
3132    /// key material.
3133    ///
3134    /// This returns true if either the primary key or at least one of
3135    /// the subkeys includes secret key material.
3136    ///
3137    /// # Examples
3138    ///
3139    /// ```
3140    /// use sequoia_openpgp as openpgp;
3141    /// use openpgp::cert::prelude::*;
3142    /// use openpgp::policy::StandardPolicy;
3143    /// use openpgp::serialize::Serialize;
3144    /// use openpgp::parse::Parse;
3145    ///
3146    /// # fn main() -> openpgp::Result<()> {
3147    /// let p = &StandardPolicy::new();
3148    ///
3149    /// // Create a new key.
3150    /// let (cert, _) =
3151    ///       CertBuilder::general_purpose(Some("alice@example.org"))
3152    ///       .generate()?;
3153    /// assert!(cert.is_tsk());
3154    ///
3155    /// // If we serialize the certificate, the secret key material is
3156    /// // stripped, unless we first convert it to a TSK.
3157    ///
3158    /// let mut buffer = Vec::new();
3159    /// cert.as_tsk().serialize(&mut buffer);
3160    /// let cert = Cert::from_bytes(&buffer)?;
3161    /// assert!(cert.is_tsk());
3162    ///
3163    /// // Now round trip it without first converting it to a TSK.  This
3164    /// // drops the secret key material.
3165    /// let mut buffer = Vec::new();
3166    /// cert.serialize(&mut buffer);
3167    /// let cert = Cert::from_bytes(&buffer)?;
3168    /// assert!(!cert.is_tsk());
3169    /// #     Ok(())
3170    /// # }
3171    /// ```
3172    pub fn is_tsk(&self) -> bool {
3173        if self.primary_key().has_secret() {
3174            return true;
3175        }
3176        self.keys().subkeys().any(|sk| {
3177            sk.key().has_secret()
3178        })
3179    }
3180
3181    /// Strips any secret key material.
3182    ///
3183    /// # Examples
3184    ///
3185    /// ```
3186    /// use sequoia_openpgp as openpgp;
3187    /// use openpgp::cert::prelude::*;
3188    ///
3189    /// # fn main() -> openpgp::Result<()> {
3190    ///
3191    /// // Create a new key.
3192    /// let (cert, _) =
3193    ///       CertBuilder::general_purpose(Some("alice@example.org"))
3194    ///       .generate()?;
3195    /// assert!(cert.is_tsk());
3196    ///
3197    /// let cert = cert.strip_secret_key_material();
3198    /// assert!(! cert.is_tsk());
3199    /// #     Ok(())
3200    /// # }
3201    /// ```
3202    pub fn strip_secret_key_material(mut self) -> Cert {
3203        self.primary.key_mut().steal_secret();
3204        self.subkeys.iter_mut().for_each(|sk| {
3205            sk.key_mut().steal_secret();
3206        });
3207        self
3208    }
3209
3210    /// Retains only the userids specified by the predicate.
3211    ///
3212    /// Removes all the userids for which the given predicate returns
3213    /// false.
3214    ///
3215    /// # Warning
3216    ///
3217    /// Because userid binding signatures are traditionally used to
3218    /// provide additional information like the certificate holder's
3219    /// algorithm preferences (see [`Preferences`]) and primary key
3220    /// flags (see [`ValidKeyAmalgamation::key_flags`]).  Removing a
3221    /// userid may inadvertently change this information.
3222    ///
3223    ///   [`ValidKeyAmalgamation::key_flags`]: amalgamation::key::ValidKeyAmalgamation::key_flags()
3224    ///
3225    /// # Examples
3226    ///
3227    /// ```
3228    /// # fn main() -> sequoia_openpgp::Result<()> {
3229    /// use sequoia_openpgp as openpgp;
3230    /// use openpgp::cert::prelude::*;
3231    ///
3232    /// // Create a new key.
3233    /// let (cert, _) =
3234    ///       CertBuilder::general_purpose(Some("alice@example.org"))
3235    ///       .add_userid("Alice Lovelace <alice@lovelace.name>")
3236    ///       .generate()?;
3237    /// assert_eq!(cert.userids().count(), 2);
3238    ///
3239    /// let cert = cert.retain_userids(|ua| {
3240    ///     if let Ok(Some(address)) = ua.userid().email() {
3241    ///         address == "alice@example.org" // Only keep this one.
3242    ///     } else {
3243    ///         false                          // Drop malformed userids.
3244    ///     }
3245    /// });
3246    /// assert_eq!(cert.userids().count(), 1);
3247    /// assert_eq!(cert.userids().nth(0).unwrap().userid().email()?.unwrap(),
3248    ///            "alice@example.org");
3249    /// # Ok(()) }
3250    /// ```
3251    pub fn retain_userids<P>(mut self, mut predicate: P) -> Cert
3252        where P: FnMut(UserIDAmalgamation) -> bool,
3253    {
3254        let mut keep = vec![false; self.userids.len()];
3255        for (i, a) in self.userids().enumerate() {
3256            keep[i] = predicate(a);
3257        }
3258        // Note: Vec::retain visits the elements in the original
3259        // order.
3260        let mut keep = keep.iter();
3261        self.userids.retain(|_| *keep.next().unwrap());
3262        self
3263    }
3264
3265    /// Retains only the user attributes specified by the predicate.
3266    ///
3267    /// Removes all the user attributes for which the given predicate
3268    /// returns false.
3269    ///
3270    /// # Examples
3271    ///
3272    /// ```
3273    /// # fn main() -> sequoia_openpgp::Result<()> {
3274    /// use sequoia_openpgp as openpgp;
3275    /// use openpgp::cert::prelude::*;
3276    ///
3277    /// // Create a new key.
3278    /// let (cert, _) =
3279    ///       CertBuilder::general_purpose(Some("alice@example.org"))
3280    ///       // Add nonsensical user attribute.
3281    ///       .add_user_attribute(vec![0, 1, 2])
3282    ///       .generate()?;
3283    /// assert_eq!(cert.user_attributes().count(), 1);
3284    ///
3285    /// // Strip all user attributes
3286    /// let cert = cert.retain_user_attributes(|_| false);
3287    /// assert_eq!(cert.user_attributes().count(), 0);
3288    /// # Ok(()) }
3289    /// ```
3290    pub fn retain_user_attributes<P>(mut self, mut predicate: P) -> Cert
3291        where P: FnMut(UserAttributeAmalgamation) -> bool,
3292    {
3293        let mut keep = vec![false; self.user_attributes.len()];
3294        for (i, a) in self.user_attributes().enumerate() {
3295            keep[i] = predicate(a);
3296        }
3297        // Note: Vec::retain visits the elements in the original
3298        // order.
3299        let mut keep = keep.iter();
3300        self.user_attributes.retain(|_| *keep.next().unwrap());
3301        self
3302    }
3303
3304    /// Retains only the subkeys specified by the predicate.
3305    ///
3306    /// Removes all the subkeys for which the given predicate returns
3307    /// false.
3308    ///
3309    /// # Examples
3310    ///
3311    /// ```
3312    /// # fn main() -> sequoia_openpgp::Result<()> {
3313    /// use sequoia_openpgp as openpgp;
3314    /// use openpgp::policy::StandardPolicy;
3315    /// use openpgp::cert::prelude::*;
3316    ///
3317    /// // Create a new key.
3318    /// let (cert, _) =
3319    ///       CertBuilder::new()
3320    ///       .add_userid("Alice Lovelace <alice@lovelace.name>")
3321    ///       .add_transport_encryption_subkey()
3322    ///       .add_storage_encryption_subkey()
3323    ///       .generate()?;
3324    /// assert_eq!(cert.keys().subkeys().count(), 2);
3325    ///
3326    /// // Retain only the transport encryption subkey.  For that, we
3327    /// // need to examine the key flags, therefore we need to turn
3328    /// // the `KeyAmalgamation` into a `ValidKeyAmalgamation` under a
3329    /// // policy.
3330    /// let p = &StandardPolicy::new();
3331    /// let cert = cert.retain_subkeys(|ka| {
3332    ///     if let Ok(vka) = ka.with_policy(p, None) {
3333    ///         vka.key_flags().map(|flags| flags.for_transport_encryption())
3334    ///             .unwrap_or(false)      // Keep transport encryption keys.
3335    ///     } else {
3336    ///         false                      // Drop unbound keys.
3337    ///     }
3338    /// });
3339    /// assert_eq!(cert.keys().subkeys().count(), 1);
3340    /// assert!(cert.with_policy(p, None)?.keys().subkeys().nth(0).unwrap()
3341    ///             .key_flags().unwrap().for_transport_encryption());
3342    /// # Ok(()) }
3343    /// ```
3344    pub fn retain_subkeys<P>(mut self, mut predicate: P) -> Cert
3345        where P: FnMut(SubordinateKeyAmalgamation<crate::packet::key::PublicParts>) -> bool,
3346    {
3347        let mut keep = vec![false; self.subkeys.len()];
3348        for (i, a) in self.keys().subkeys().enumerate() {
3349            keep[i] = predicate(a);
3350        }
3351        // Note: Vec::retain visits the elements in the original
3352        // order.
3353        let mut keep = keep.iter();
3354        self.subkeys.retain(|_| *keep.next().unwrap());
3355        self
3356    }
3357
3358    /// Associates a policy and a reference time with the certificate.
3359    ///
3360    /// This is used to turn a `Cert` into a
3361    /// [`ValidCert`].  (See also [`ValidateAmalgamation`],
3362    /// which does the same for component amalgamations.)
3363    ///
3364    /// A certificate is considered valid if:
3365    ///
3366    ///   - It has a self signature that is live at time `t`.
3367    ///
3368    ///   - The policy considers it acceptable.
3369    ///
3370    /// This doesn't say anything about whether the certificate itself
3371    /// is alive (see [`ValidCert::alive`]) or revoked (see
3372    /// [`ValidCert::revocation_status`]).
3373    ///
3374    /// [`ValidateAmalgamation`]: amalgamation::ValidateAmalgamation
3375    /// [`ValidCert::alive`]: ValidCert::alive()
3376    /// [`ValidCert::revocation_status`]: ValidCert::revocation_status()
3377    ///
3378    /// # Examples
3379    ///
3380    /// ```
3381    /// use sequoia_openpgp as openpgp;
3382    /// # use openpgp::cert::prelude::*;
3383    /// use openpgp::policy::StandardPolicy;
3384    ///
3385    /// # fn main() -> openpgp::Result<()> {
3386    /// let p = &StandardPolicy::new();
3387    ///
3388    /// #     let (cert, _) =
3389    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3390    /// #         .generate()?;
3391    /// let vc = cert.with_policy(p, None)?;
3392    /// # assert!(std::ptr::eq(vc.policy(), p));
3393    /// #     Ok(())
3394    /// # }
3395    /// ```
3396    pub fn with_policy<'a, T>(&'a self, policy: &'a dyn Policy, time: T)
3397                              -> Result<ValidCert<'a>>
3398        where T: Into<Option<time::SystemTime>>,
3399    {
3400        let time = time.into().unwrap_or_else(crate::now);
3401        self.primary_key().with_policy(policy, time)?;
3402
3403        Ok(ValidCert {
3404            cert: self,
3405            policy,
3406            time,
3407        })
3408    }
3409}
3410
3411use crate::serialize::TSK;
3412impl<'a> TSK<'a> {
3413    /// Converts the certificate into an iterator over a sequence of
3414    /// packets.
3415    ///
3416    /// This function emits secret key packets, modulo the keys that
3417    /// are filtered (see [`TSK::set_filter`]).  If requested, missing
3418    /// secret key material is replaced by stubs (see
3419    /// [`TSK::emit_secret_key_stubs`]).
3420    ///
3421    /// # Examples
3422    ///
3423    /// ```
3424    /// # use sequoia_openpgp as openpgp;
3425    /// # use openpgp::cert::prelude::*;
3426    /// # use openpgp::serialize::{Serialize, SerializeInto};
3427    /// #
3428    /// # fn main() -> openpgp::Result<()> {
3429    /// # let (cert, _) =
3430    /// #       CertBuilder::general_purpose(Some("alice@example.org"))
3431    /// #       .generate()?;
3432    /// assert!(cert.is_tsk());
3433    /// let a = cert.as_tsk().to_vec()?;
3434    /// let mut b = Vec::new();
3435    /// cert.into_tsk().into_packets()
3436    ///     .for_each(|p| p.serialize(&mut b).unwrap());
3437    /// assert_eq!(a, b);
3438    /// # Ok(()) }
3439    /// ```
3440    pub fn into_packets(self) -> impl Iterator<Item=Packet> + Send + Sync + 'a {
3441        /// Strips the secret key material if the filter rejects it,
3442        /// and optionally inserts secret key stubs.
3443        fn rewrite<'a>(
3444            filter: &Box<dyn Fn(&key::UnspecifiedSecret) -> bool + Send + Sync + 'a>,
3445            emit_secret_key_stubs: bool,
3446            mut p: impl Iterator<Item=Packet> + Send + Sync)
3447            -> impl Iterator<Item=Packet> + Send + Sync
3448        {
3449            let k: Packet = match p.next().unwrap() {
3450                Packet::PublicKey(mut k) => {
3451                    if ! k.role_as_unspecified().parts_as_secret()
3452                        .map(|k| (filter)(k))
3453                        .unwrap_or(false)
3454                    {
3455                        k = k.take_secret().0;
3456                    }
3457
3458                    if ! k.has_secret() && emit_secret_key_stubs {
3459                        k = TSK::add_stub(k).into();
3460                    }
3461
3462                    if k.has_secret() {
3463                        Packet::SecretKey(k.parts_into_secret().unwrap())
3464                    } else {
3465                        Packet::PublicKey(k)
3466                    }
3467                }
3468                Packet::PublicSubkey(mut k) => {
3469                    if ! k.role_as_unspecified().parts_as_secret()
3470                        .map(|k| (filter)(k))
3471                        .unwrap_or(false)
3472                    {
3473                        k = k.take_secret().0;
3474                    }
3475
3476                    if ! k.has_secret() && emit_secret_key_stubs {
3477                        k = TSK::add_stub(k).into();
3478                    }
3479
3480                    if k.has_secret() {
3481                        Packet::SecretSubkey(k.parts_into_secret().unwrap())
3482                    } else {
3483                        Packet::PublicSubkey(k)
3484                    }
3485                }
3486                _ => unreachable!(),
3487            };
3488
3489            std::iter::once(k).chain(p)
3490        }
3491
3492        let (cert, filter, emit_secret_key_stubs) = self.decompose();
3493        let cert = cert.into_owned();
3494
3495        rewrite(&filter, emit_secret_key_stubs, cert.primary.into_packets())
3496            .chain(cert.userids.into_iter().flat_map(|b| b.into_packets()))
3497            .chain(cert.user_attributes.into_iter().flat_map(|b| b.into_packets()))
3498            .chain(cert.subkeys.into_iter().flat_map(
3499                move |b| rewrite(&filter, emit_secret_key_stubs, b.into_packets())))
3500            .chain(cert.unknowns.into_iter().flat_map(|b| b.into_packets()))
3501            .chain(cert.bad.into_iter().map(|s| s.into()))
3502    }
3503}
3504
3505impl TryFrom<PacketParserResult<'_>> for Cert {
3506    type Error = anyhow::Error;
3507
3508    /// Returns the Cert found in the packet stream.
3509    ///
3510    /// If the sequence contains multiple certificates (i.e., it is a
3511    /// keyring), or the certificate is followed by an invalid packet
3512    /// this function will fail.  To parse keyrings, use
3513    /// [`CertParser`] instead of this function.
3514    fn try_from(ppr: PacketParserResult) -> Result<Self> {
3515        let mut parser = parser::CertParser::from(ppr);
3516        if let Some(cert_result) = parser.next() {
3517            if parser.next().is_some() {
3518                Err(Error::MalformedCert(
3519                    "Additional packets found, is this a keyring?".into()
3520                ).into())
3521            } else {
3522                cert_result
3523            }
3524        } else {
3525            Err(Error::MalformedCert("No data".into()).into())
3526        }
3527    }
3528}
3529
3530impl TryFrom<Vec<Packet>> for Cert {
3531    type Error = anyhow::Error;
3532
3533    fn try_from(p: Vec<Packet>) -> Result<Self> {
3534        Cert::from_packets(p.into_iter())
3535    }
3536}
3537
3538impl TryFrom<Packet> for Cert {
3539    type Error = anyhow::Error;
3540
3541    fn try_from(p: Packet) -> Result<Self> {
3542        Cert::from_packets(std::iter::once(p))
3543    }
3544}
3545
3546impl TryFrom<PacketPile> for Cert {
3547    type Error = anyhow::Error;
3548
3549    /// Returns the certificate found in the `PacketPile`.
3550    ///
3551    /// If the [`PacketPile`] does not start with a certificate
3552    /// (specifically, if it does not start with a primary key
3553    /// packet), then this fails.
3554    ///
3555    /// If the sequence contains multiple certificates (i.e., it is a
3556    /// keyring), or the certificate is followed by an invalid packet
3557    /// this function will fail.  To parse keyrings, use
3558    /// [`CertParser`] instead of this function.
3559    ///
3560    /// # Examples
3561    ///
3562    /// ```
3563    /// use sequoia_openpgp as openpgp;
3564    /// use openpgp::cert::prelude::*;
3565    /// use openpgp::packet::prelude::*;
3566    /// use openpgp::PacketPile;
3567    /// use std::convert::TryFrom;
3568    ///
3569    /// # fn main() -> openpgp::Result<()> {
3570    /// let (cert, rev) =
3571    ///     CertBuilder::general_purpose(Some("alice@example.org"))
3572    ///     .generate()?;
3573    ///
3574    /// // We should be able to turn a certificate into a PacketPile
3575    /// // and back.
3576    /// let pp : PacketPile = cert.into();
3577    /// assert!(Cert::try_from(pp).is_ok());
3578    ///
3579    /// // But a revocation certificate is not a certificate, so this
3580    /// // will fail.
3581    /// let pp : PacketPile = Packet::from(rev).into();
3582    /// assert!(Cert::try_from(pp).is_err());
3583    /// # Ok(())
3584    /// # }
3585    /// ```
3586    fn try_from(p: PacketPile) -> Result<Self> {
3587        Self::from_packets(p.into_children())
3588    }
3589}
3590
3591/// A `Cert` plus a `Policy` and a reference time.
3592///
3593/// A `ValidCert` combines a [`Cert`] with a [`Policy`] and a
3594/// reference time.  This allows it to implement methods that require
3595/// a `Policy` and a reference time without requiring the caller to
3596/// explicitly pass them in.  Embedding them in the `ValidCert` data
3597/// structure rather than having the caller pass them in explicitly
3598/// helps ensure that multipart operations, even those that span
3599/// multiple functions, use the same `Policy` and reference time.
3600/// This avoids a subtle class of bugs in which different views of a
3601/// certificate are unintentionally used.
3602///
3603/// A `ValidCert` is typically obtained by transforming a `Cert` using
3604/// [`Cert::with_policy`].
3605///
3606/// A `ValidCert` is guaranteed to have a valid and live binding
3607/// signature at the specified reference time.  Note: this only means
3608/// that the binding signature is live; it says nothing about whether
3609/// the certificate or any component is live.  If you care about those
3610/// things, then you need to check them separately.
3611///
3612/// [`Policy`]: crate::policy::Policy
3613/// [`Cert::with_policy`]: Cert::with_policy()
3614///
3615/// # Examples
3616///
3617/// ```
3618/// use sequoia_openpgp as openpgp;
3619/// # use openpgp::cert::prelude::*;
3620/// use openpgp::policy::StandardPolicy;
3621///
3622/// # fn main() -> openpgp::Result<()> {
3623/// let p = &StandardPolicy::new();
3624///
3625/// # let (cert, _) = CertBuilder::new()
3626/// #     .add_userid("Alice")
3627/// #     .add_signing_subkey()
3628/// #     .add_transport_encryption_subkey()
3629/// #     .generate()?;
3630/// let vc = cert.with_policy(p, None)?;
3631/// # assert!(std::ptr::eq(vc.policy(), p));
3632/// # Ok(()) }
3633/// ```
3634#[derive(Debug, Clone)]
3635pub struct ValidCert<'a> {
3636    cert: &'a Cert,
3637    policy: &'a dyn Policy,
3638    // The reference time.
3639    time: time::SystemTime,
3640}
3641assert_send_and_sync!(ValidCert<'_>);
3642
3643impl<'a> fmt::Display for ValidCert<'a> {
3644    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3645        write!(f, "{}", self.cert().fingerprint())
3646    }
3647}
3648
3649impl<'a> ValidCert<'a> {
3650    /// Returns the underlying certificate.
3651    ///
3652    /// # Examples
3653    ///
3654    /// ```
3655    /// use sequoia_openpgp as openpgp;
3656    /// # use openpgp::cert::prelude::*;
3657    /// use openpgp::policy::StandardPolicy;
3658    ///
3659    /// # fn main() -> openpgp::Result<()> {
3660    /// let p = &StandardPolicy::new();
3661    ///
3662    /// # let (cert, _) = CertBuilder::new()
3663    /// #     .add_userid("Alice")
3664    /// #     .add_signing_subkey()
3665    /// #     .add_transport_encryption_subkey()
3666    /// #     .generate()?;
3667    /// let vc = cert.with_policy(p, None)?;
3668    /// assert!(std::ptr::eq(vc.cert(), &cert));
3669    /// # assert!(std::ptr::eq(vc.policy(), p));
3670    /// # Ok(()) }
3671    /// ```
3672    pub fn cert(&self) -> &'a Cert {
3673        self.cert
3674    }
3675
3676    /// Returns the associated reference time.
3677    ///
3678    /// # Examples
3679    ///
3680    /// ```
3681    /// # use std::time::{SystemTime, Duration, UNIX_EPOCH};
3682    /// #
3683    /// use sequoia_openpgp as openpgp;
3684    /// # use openpgp::cert::prelude::*;
3685    /// use openpgp::policy::StandardPolicy;
3686    ///
3687    /// # fn main() -> openpgp::Result<()> {
3688    /// let p = &StandardPolicy::new();
3689    ///
3690    /// let t = UNIX_EPOCH + Duration::from_secs(1307732220);
3691    /// #     let (cert, _) =
3692    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3693    /// #         .set_creation_time(t)
3694    /// #         .generate()?;
3695    /// let vc = cert.with_policy(p, t)?;
3696    /// assert_eq!(vc.time(), t);
3697    /// #     Ok(())
3698    /// # }
3699    /// ```
3700    pub fn time(&self) -> time::SystemTime {
3701        self.time
3702    }
3703
3704    /// Returns the associated policy.
3705    ///
3706    /// # Examples
3707    ///
3708    /// ```
3709    /// use sequoia_openpgp as openpgp;
3710    /// # use openpgp::cert::prelude::*;
3711    /// use openpgp::policy::StandardPolicy;
3712    ///
3713    /// # fn main() -> openpgp::Result<()> {
3714    /// let p = &StandardPolicy::new();
3715    ///
3716    /// #     let (cert, _) =
3717    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3718    /// #         .generate()?;
3719    /// let vc = cert.with_policy(p, None)?;
3720    /// assert!(std::ptr::eq(vc.policy(), p));
3721    /// #     Ok(())
3722    /// # }
3723    /// ```
3724    pub fn policy(&self) -> &'a dyn Policy {
3725        self.policy
3726    }
3727
3728    /// Changes the associated policy and reference time.
3729    ///
3730    /// If `time` is `None`, the current time is used.
3731    ///
3732    /// Returns an error if the certificate is not valid for the given
3733    /// policy at the specified time.
3734    ///
3735    /// # Examples
3736    ///
3737    /// ```
3738    /// use sequoia_openpgp as openpgp;
3739    /// # use openpgp::cert::prelude::*;
3740    /// use openpgp::policy::{StandardPolicy, NullPolicy};
3741    ///
3742    /// # fn main() -> openpgp::Result<()> {
3743    /// #     let (cert, _) =
3744    /// #         CertBuilder::general_purpose(Some("alice@example.org"))
3745    /// #         .generate()?;
3746    /// let sp = &StandardPolicy::new();
3747    /// let vc = cert.with_policy(sp, None)?;
3748    ///
3749    /// // ...
3750    ///
3751    /// // Now with a different policy.
3752    /// let np = unsafe { &NullPolicy::new() };
3753    /// let vc = vc.with_policy(np, None)?;
3754    /// #     Ok(())
3755    /// # }
3756    /// ```
3757    pub fn with_policy<T>(self, policy: &'a dyn Policy, time: T)
3758        -> Result<ValidCert<'a>>
3759        where T: Into<Option<time::SystemTime>>,
3760    {
3761        self.cert.with_policy(policy, time)
3762    }
3763
3764    /// Returns the certificate's direct key signature as of the
3765    /// reference time.
3766    ///
3767    /// Subpackets on direct key signatures apply to all components of
3768    /// the certificate, cf. [Section 5.2.3.10 of RFC 9580].
3769    ///
3770    /// [Section 5.2.3.10 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
3771    ///
3772    /// # Examples
3773    ///
3774    /// ```
3775    /// use sequoia_openpgp as openpgp;
3776    /// # use openpgp::cert::prelude::*;
3777    /// use sequoia_openpgp::policy::StandardPolicy;
3778    ///
3779    /// # fn main() -> openpgp::Result<()> {
3780    /// let p = &StandardPolicy::new();
3781    ///
3782    /// # let (cert, _) = CertBuilder::new()
3783    /// #     .add_userid("Alice")
3784    /// #     .add_signing_subkey()
3785    /// #     .add_transport_encryption_subkey()
3786    /// #     .generate()?;
3787    /// let vc = cert.with_policy(p, None)?;
3788    /// println!("{:?}", vc.direct_key_signature());
3789    /// # assert!(vc.direct_key_signature().is_ok());
3790    /// # Ok(()) }
3791    /// ```
3792    pub fn direct_key_signature(&self) -> Result<&'a Signature>
3793    {
3794        self.cert.primary.binding_signature(self.policy(), self.time())
3795    }
3796
3797    /// Returns the certificate's revocation status.
3798    ///
3799    /// A certificate is considered revoked at time `t` if:
3800    ///
3801    ///   - There is a valid and live revocation at time `t` that is
3802    ///     newer than all valid and live self signatures at time `t`,
3803    ///     or
3804    ///
3805    ///   - There is a valid [hard revocation] (even if it is not live
3806    ///     at time `t`, and even if there is a newer self signature).
3807    ///
3808    /// [hard revocation]: crate::types::RevocationType::Hard
3809    ///
3810    /// Note: certificates and subkeys have different revocation
3811    /// criteria from [User IDs] and [User Attributes].
3812    ///
3813    //  Pending https://github.com/rust-lang/rust/issues/85960, should be
3814    //  [User IDs]: bundle::ComponentBundle<UserID>::revocation_status
3815    //  [User Attributes]: bundle::ComponentBundle<UserAttribute>::revocation_status
3816    /// [User IDs]: bundle::ComponentBundle#method.revocation_status-1
3817    /// [User Attributes]: bundle::ComponentBundle#method.revocation_status-2
3818    ///
3819    /// # Examples
3820    ///
3821    /// ```
3822    /// use sequoia_openpgp as openpgp;
3823    /// use openpgp::cert::prelude::*;
3824    /// use openpgp::types::RevocationStatus;
3825    /// use openpgp::policy::StandardPolicy;
3826    ///
3827    /// # fn main() -> openpgp::Result<()> {
3828    /// let p = &StandardPolicy::new();
3829    ///
3830    /// let (cert, rev) =
3831    ///     CertBuilder::general_purpose(Some("alice@example.org"))
3832    ///     .generate()?;
3833    ///
3834    /// // Not revoked.
3835    /// assert_eq!(cert.with_policy(p, None)?.revocation_status(),
3836    ///            RevocationStatus::NotAsFarAsWeKnow);
3837    ///
3838    /// // Merge the revocation certificate.  `cert` is now considered
3839    /// // to be revoked.
3840    /// let cert = cert.insert_packets(rev.clone())?.0;
3841    /// assert_eq!(cert.with_policy(p, None)?.revocation_status(),
3842    ///            RevocationStatus::Revoked(vec![&rev.into()]));
3843    /// #     Ok(())
3844    /// # }
3845    /// ```
3846    pub fn revocation_status(&self) -> RevocationStatus<'a> {
3847        self.cert.revocation_status(self.policy, self.time)
3848    }
3849
3850    /// Returns whether the certificate is alive at the
3851    /// reference time.
3852    ///
3853    /// A certificate is considered to be alive at time `t` if the
3854    /// primary key is alive at time `t`.
3855    ///
3856    /// A valid certificate's primary key is guaranteed to have [a live
3857    /// binding signature], however, that does not mean that the
3858    /// [primary key is necessarily alive].
3859    ///
3860    /// [a live binding signature]: amalgamation::ValidateAmalgamation
3861    /// [primary key is necessarily alive]: amalgamation::key::ValidKeyAmalgamation::alive()
3862    ///
3863    /// # Examples
3864    ///
3865    /// ```
3866    /// use std::time;
3867    /// use sequoia_openpgp as openpgp;
3868    /// use openpgp::cert::prelude::*;
3869    /// use openpgp::policy::StandardPolicy;
3870    ///
3871    /// # fn main() -> openpgp::Result<()> {
3872    /// let p = &StandardPolicy::new();
3873    ///
3874    /// let a_second = time::Duration::from_secs(1);
3875    ///
3876    /// let creation_time = time::SystemTime::now();
3877    /// let before_creation = creation_time - a_second;
3878    /// let validity_period = 60 * a_second;
3879    /// let expiration_time = creation_time + validity_period;
3880    /// let before_expiration_time = expiration_time - a_second;
3881    /// let after_expiration_time = expiration_time + a_second;
3882    ///
3883    /// let (cert, _) = CertBuilder::new()
3884    ///     .add_userid("Alice")
3885    ///     .set_creation_time(creation_time)
3886    ///     .set_validity_period(validity_period)
3887    ///     .generate()?;
3888    ///
3889    /// // There is no binding signature before the certificate was created.
3890    /// assert!(cert.with_policy(p, before_creation).is_err());
3891    /// assert!(cert.with_policy(p, creation_time)?.alive().is_ok());
3892    /// assert!(cert.with_policy(p, before_expiration_time)?.alive().is_ok());
3893    /// // The binding signature is still alive, but the key has expired.
3894    /// assert!(cert.with_policy(p, expiration_time)?.alive().is_err());
3895    /// assert!(cert.with_policy(p, after_expiration_time)?.alive().is_err());
3896    /// # Ok(()) }
3897    pub fn alive(&self) -> Result<()> {
3898        self.primary_key().alive()
3899    }
3900
3901    /// Returns the certificate's primary key.
3902    ///
3903    /// A key's secret key material may be protected with a
3904    /// password.  In such cases, it needs to be decrypted before it
3905    /// can be used to decrypt data or generate a signature.  Refer to
3906    /// [`Key::decrypt_secret`] for details.
3907    ///
3908    /// [`Key::decrypt_secret`]: crate::packet::Key::decrypt_secret()
3909    ///
3910    /// # Examples
3911    ///
3912    /// ```
3913    /// # use sequoia_openpgp as openpgp;
3914    /// # use openpgp::cert::prelude::*;
3915    /// # use openpgp::policy::StandardPolicy;
3916    /// #
3917    /// # fn main() -> openpgp::Result<()> {
3918    /// # let p = &StandardPolicy::new();
3919    /// # let (cert, _) = CertBuilder::new()
3920    /// #     .add_userid("Alice")
3921    /// #     .generate()?;
3922    /// # let vc = cert.with_policy(p, None)?;
3923    /// #
3924    /// let primary = vc.primary_key();
3925    /// // The certificate's fingerprint *is* the primary key's fingerprint.
3926    /// assert_eq!(vc.cert().fingerprint(), primary.key().fingerprint());
3927    /// # Ok(()) }
3928    pub fn primary_key(&self)
3929        -> ValidPrimaryKeyAmalgamation<'a, key::PublicParts>
3930    {
3931        self.cert.primary_key().with_policy(self.policy, self.time)
3932            .expect("A ValidKeyAmalgamation must have a ValidPrimaryKeyAmalgamation")
3933    }
3934
3935    /// Returns an iterator over the certificate's valid keys.
3936    ///
3937    /// That is, this returns an iterator over the primary key and any
3938    /// subkeys.
3939    ///
3940    /// The iterator always returns the primary key first.  The order
3941    /// of the subkeys is undefined.
3942    ///
3943    /// To only iterate over the certificate's subkeys, call
3944    /// [`ValidKeyAmalgamationIter::subkeys`] on the returned iterator
3945    /// instead of skipping the first key: this causes the iterator to
3946    /// return values with a more accurate type.
3947    ///
3948    /// A key's secret key material may be protected with a
3949    /// password.  In such cases, it needs to be decrypted before it
3950    /// can be used to decrypt data or generate a signature.  Refer to
3951    /// [`Key::decrypt_secret`] for details.
3952    ///
3953    /// [`ValidKeyAmalgamationIter::subkeys`]: amalgamation::key::ValidKeyAmalgamationIter::subkeys()
3954    /// [`Key::decrypt_secret`]: crate::packet::Key::decrypt_secret()
3955    ///
3956    /// # Examples
3957    ///
3958    /// ```
3959    /// use sequoia_openpgp as openpgp;
3960    /// use openpgp::cert::prelude::*;
3961    /// use openpgp::policy::StandardPolicy;
3962    ///
3963    /// # fn main() -> openpgp::Result<()> {
3964    /// let p = &StandardPolicy::new();
3965    ///
3966    /// // Create a key with two subkeys: one for signing and one for
3967    /// // encrypting data in transit.
3968    /// let (cert, _) = CertBuilder::new()
3969    ///     .add_userid("Alice")
3970    ///     .add_signing_subkey()
3971    ///     .add_transport_encryption_subkey()
3972    ///     .generate()?;
3973    /// // They should all be valid.
3974    /// assert_eq!(cert.with_policy(p, None)?.keys().count(), 1 + 2);
3975    /// #     Ok(())
3976    /// # }
3977    /// ```
3978    pub fn keys(&self) -> ValidKeyAmalgamationIter<'a, key::PublicParts, key::UnspecifiedRole> {
3979        self.cert.keys().with_policy(self.policy, self.time)
3980    }
3981
3982    /// Returns the primary User ID at the reference time, if any.
3983    ///
3984    /// A certificate may not have a primary User ID if it doesn't
3985    /// have any valid User IDs.  If a certificate has at least one
3986    /// valid User ID at time `t`, then it has a primary User ID at
3987    /// time `t`.
3988    ///
3989    /// The primary User ID is determined as follows:
3990    ///
3991    ///   - Discard User IDs that are not valid or not alive at time `t`.
3992    ///
3993    ///   - Order the remaining User IDs by whether a User ID does not
3994    ///     have a valid self-revocation (i.e., non-revoked first,
3995    ///     ignoring third-party revocations).
3996    ///
3997    ///   - Break ties by ordering by whether the User ID is [marked
3998    ///     as being the primary User ID].
3999    ///
4000    ///   - Break ties by ordering by the binding signature's creation
4001    ///     time, most recent first.
4002    ///
4003    /// If there are multiple User IDs that are ordered first, then
4004    /// one is chosen in a deterministic, but undefined manner
4005    /// (currently, we order the value of the User IDs
4006    /// lexographically, but you shouldn't rely on this).
4007    ///
4008    /// [marked as being the primary User ID]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.27
4009    ///
4010    /// # Examples
4011    ///
4012    /// ```
4013    /// use std::time;
4014    /// use sequoia_openpgp as openpgp;
4015    /// use openpgp::cert::prelude::*;
4016    /// use openpgp::packet::prelude::*;
4017    /// use openpgp::policy::StandardPolicy;
4018    ///
4019    /// # fn main() -> openpgp::Result<()> {
4020    /// let p = &StandardPolicy::new();
4021    ///
4022    /// let t1 = time::SystemTime::now();
4023    /// let t2 = t1 + time::Duration::from_secs(1);
4024    ///
4025    /// let (cert, _) = CertBuilder::new()
4026    ///     .set_creation_time(t1)
4027    ///     .add_userid("Alice")
4028    ///     .generate()?;
4029    /// let mut signer = cert
4030    ///     .primary_key().key().clone().parts_into_secret()?.into_keypair()?;
4031    ///
4032    /// // There is only one User ID.  It must be the primary User ID.
4033    /// let vc = cert.with_policy(p, t1)?;
4034    /// let alice = vc.primary_userid().unwrap();
4035    /// assert_eq!(alice.userid().value(), b"Alice");
4036    /// // By default, the primary User ID flag is set.
4037    /// assert!(alice.binding_signature().primary_userid().is_some());
4038    ///
4039    /// let template: signature::SignatureBuilder
4040    ///     = alice.binding_signature().clone().into();
4041    ///
4042    /// // Add another user id whose creation time is after the
4043    /// // existing User ID, and doesn't have the User ID set.
4044    /// let sig = template.clone()
4045    ///     .set_signature_creation_time(t2)?
4046    ///     .set_primary_userid(false)?;
4047    /// let bob: UserID = "Bob".into();
4048    /// let sig = bob.bind(&mut signer, &cert, sig)?;
4049    /// let cert = cert.insert_packets(vec![Packet::from(bob), sig.into()])?.0;
4050    /// # assert_eq!(cert.userids().count(), 2);
4051    ///
4052    /// // Alice should still be the primary User ID, because it has the
4053    /// // primary User ID flag set.
4054    /// let alice = cert.with_policy(p, t2)?.primary_userid().unwrap();
4055    /// assert_eq!(alice.userid().value(), b"Alice");
4056    ///
4057    ///
4058    /// // Add another User ID, whose binding signature's creation
4059    /// // time is after Alice's and also has the primary User ID flag set.
4060    /// let sig = template.clone()
4061    ///    .set_signature_creation_time(t2)?;
4062    /// let carol: UserID = "Carol".into();
4063    /// let sig = carol.bind(&mut signer, &cert, sig)?;
4064    /// let cert = cert.insert_packets(vec![Packet::from(carol), sig.into()])?.0;
4065    /// # assert_eq!(cert.userids().count(), 3);
4066    ///
4067    /// // It should now be the primary User ID, because it is the
4068    /// // newest User ID with the primary User ID bit is set.
4069    /// let carol = cert.with_policy(p, t2)?.primary_userid().unwrap();
4070    /// assert_eq!(carol.userid().value(), b"Carol");
4071    /// # Ok(()) }
4072    pub fn primary_userid(&self) -> Result<ValidUserIDAmalgamation<'a>>
4073    {
4074        self.cert.primary_userid_relaxed(self.policy(), self.time(), true)
4075    }
4076
4077    /// Returns an iterator over the certificate's valid User IDs.
4078    ///
4079    /// # Examples
4080    ///
4081    /// ```
4082    /// # use std::time;
4083    /// use sequoia_openpgp as openpgp;
4084    /// # use openpgp::cert::prelude::*;
4085    /// use openpgp::packet::prelude::*;
4086    /// use openpgp::policy::StandardPolicy;
4087    ///
4088    /// # fn main() -> openpgp::Result<()> {
4089    /// let p = &StandardPolicy::new();
4090    ///
4091    /// # let t0 = time::SystemTime::now() - time::Duration::from_secs(10);
4092    /// # let t1 = t0 + time::Duration::from_secs(1);
4093    /// # let t2 = t1 + time::Duration::from_secs(1);
4094    /// # let (cert, _) =
4095    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4096    /// #     .set_creation_time(t0)
4097    /// #     .generate()?;
4098    /// // `cert` was created at t0.  Add a second User ID at t1.
4099    /// let userid = UserID::from("alice@example.com");
4100    /// // Use the primary User ID's current binding signature as the
4101    /// // basis for the new User ID's binding signature.
4102    /// let template : signature::SignatureBuilder
4103    ///     = cert.with_policy(p, None)?
4104    ///           .primary_userid()?
4105    ///           .binding_signature()
4106    ///           .clone()
4107    ///           .into();
4108    /// let sig = template.set_signature_creation_time(t1)?;
4109    /// let mut signer = cert
4110    ///     .primary_key().key().clone().parts_into_secret()?.into_keypair()?;
4111    /// let binding = userid.bind(&mut signer, &cert, sig)?;
4112    /// // Merge it.
4113    /// let cert = cert.insert_packets(
4114    ///     vec![Packet::from(userid), binding.into()])?.0;
4115    ///
4116    /// // At t0, the new User ID is not yet valid (it doesn't have a
4117    /// // binding signature that is live at t0).  Thus, it is not
4118    /// // returned.
4119    /// let vc = cert.with_policy(p, t0)?;
4120    /// assert_eq!(vc.userids().count(), 1);
4121    /// // But, at t1, we see both User IDs.
4122    /// let vc = cert.with_policy(p, t1)?;
4123    /// assert_eq!(vc.userids().count(), 2);
4124    /// #     Ok(())
4125    /// # }
4126    /// ```
4127    pub fn userids(&self) -> ValidUserIDAmalgamationIter<'a> {
4128        self.cert.userids().with_policy(self.policy, self.time)
4129    }
4130
4131    /// Returns the primary User Attribute, if any.
4132    ///
4133    /// If a certificate has any valid User Attributes, then it has a
4134    /// primary User Attribute.  In other words, it will not have a
4135    /// primary User Attribute at time `t` if there are no valid User
4136    /// Attributes at time `t`.
4137    ///
4138    /// The primary User Attribute is determined in the same way as
4139    /// the primary User ID.  See the documentation of
4140    /// [`ValidCert::primary_userid`] for details.
4141    ///
4142    /// [`ValidCert::primary_userid`]: ValidCert::primary_userid()
4143    ///
4144    /// # Examples
4145    ///
4146    /// ```
4147    /// use sequoia_openpgp as openpgp;
4148    /// # use openpgp::cert::prelude::*;
4149    /// use openpgp::policy::StandardPolicy;
4150    ///
4151    /// # fn main() -> openpgp::Result<()> {
4152    /// let p = &StandardPolicy::new();
4153    ///
4154    /// # let (cert, _) =
4155    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4156    /// #     .generate()?;
4157    /// let vc = cert.with_policy(p, None)?;
4158    /// let ua = vc.primary_user_attribute();
4159    /// # // We don't have a user attributes.  So, this should return an
4160    /// # // error.
4161    /// # assert!(ua.is_err());
4162    /// #     Ok(())
4163    /// # }
4164    /// ```
4165    pub fn primary_user_attribute(&self)
4166        -> Result<ValidComponentAmalgamation<'a, UserAttribute>>
4167    {
4168        ValidComponentAmalgamation::primary(self.cert,
4169                                            self.cert.user_attributes.iter(),
4170                                            self.policy(), self.time(), true)
4171    }
4172
4173    /// Returns an iterator over the certificate's valid
4174    /// `UserAttribute`s.
4175    ///
4176    /// # Examples
4177    ///
4178    /// ```
4179    /// use sequoia_openpgp as openpgp;
4180    /// # use openpgp::cert::prelude::*;
4181    /// # use openpgp::packet::prelude::*;
4182    /// # use openpgp::packet::user_attribute::Subpacket;
4183    /// use openpgp::policy::StandardPolicy;
4184    ///
4185    /// # fn main() -> openpgp::Result<()> {
4186    /// let p = &StandardPolicy::new();
4187    ///
4188    /// # let (cert, _) =
4189    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4190    /// #     .generate()?;
4191    /// #
4192    /// # // Create some user attribute. Doctests do not pass cfg(test),
4193    /// # // so UserAttribute::arbitrary is not available
4194    /// # let sp = Subpacket::Unknown(7, vec![7; 7].into_boxed_slice());
4195    /// # let ua = UserAttribute::new(&[sp]);
4196    /// #
4197    /// // Add a User Attribute without a self-signature to the certificate.
4198    /// let cert = cert.insert_packets(ua)?.0;
4199    /// assert_eq!(cert.user_attributes().count(), 1);
4200    ///
4201    /// // Without a self-signature, it is definitely not valid.
4202    /// let vc = cert.with_policy(p, None)?;
4203    /// assert_eq!(vc.user_attributes().count(), 0);
4204    /// #     Ok(())
4205    /// # }
4206    /// ```
4207    pub fn user_attributes(&self) -> ValidUserAttributeAmalgamationIter<'a> {
4208        self.cert.user_attributes().with_policy(self.policy, self.time)
4209    }
4210
4211    /// Returns a list of any designated revokers for this certificate.
4212    ///
4213    /// This function returns the designated revokers listed on the
4214    /// primary key's binding signatures and the certificate's direct
4215    /// key signatures.
4216    ///
4217    /// Note: the returned list is deduplicated.
4218    ///
4219    /// In order to preserve our API during the 1.x series, this
4220    /// function takes an optional policy argument.  It should be
4221    /// `None`, but if it is `Some(_)`, it will be used instead of the
4222    /// `ValidCert`'s policy.  This makes the function signature
4223    /// compatible with [`Cert::revocation_keys`].
4224    ///
4225    /// # Examples
4226    ///
4227    /// ```
4228    /// use sequoia_openpgp as openpgp;
4229    /// # use openpgp::Result;
4230    /// use openpgp::cert::prelude::*;
4231    /// use openpgp::policy::StandardPolicy;
4232    /// use openpgp::types::RevocationKey;
4233    ///
4234    /// # fn main() -> Result<()> {
4235    /// let p = &StandardPolicy::new();
4236    ///
4237    /// let (alice, _) =
4238    ///     CertBuilder::general_purpose(Some("alice@example.org"))
4239    ///     .generate()?;
4240    /// // Make Alice a designated revoker for Bob.
4241    /// let (bob, _) =
4242    ///     CertBuilder::general_purpose(Some("bob@example.org"))
4243    ///     .set_revocation_keys(vec![(&alice).into()])
4244    ///     .generate()?;
4245    ///
4246    /// // Make sure Alice is listed as a designated revoker for Bob.
4247    /// assert_eq!(bob.with_policy(p, None)?.revocation_keys()
4248    ///            .collect::<Vec<&RevocationKey>>(),
4249    ///            vec![&(&alice).into()]);
4250    /// # Ok(()) }
4251    /// ```
4252    pub fn revocation_keys(&self)
4253        -> impl Iterator<Item = &'a RevocationKey> + 'a
4254    {
4255        self.cert.revocation_keys(self.policy())
4256    }
4257
4258    /// Returns the certificate's fingerprint as a `KeyHandle`.
4259    ///
4260    /// # Examples
4261    ///
4262    /// ```
4263    /// # use sequoia_openpgp as openpgp;
4264    /// # use openpgp::cert::prelude::*;
4265    /// # use openpgp::KeyHandle;
4266    /// # use openpgp::policy::StandardPolicy;
4267    /// #
4268    /// # fn main() -> openpgp::Result<()> {
4269    /// let p = &StandardPolicy::new();
4270    ///
4271    /// # let (cert, _) =
4272    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4273    /// #     .generate()?;
4274    /// #
4275    /// println!("{}", cert.with_policy(p, None)?.key_handle());
4276    ///
4277    /// // This always returns a fingerprint.
4278    /// match cert.with_policy(p, None)?.key_handle() {
4279    ///     KeyHandle::Fingerprint(_) => (),
4280    ///     KeyHandle::KeyID(_) => unreachable!(),
4281    /// }
4282    /// #
4283    /// # Ok(())
4284    /// # }
4285    /// ```
4286    pub fn key_handle(&self) -> KeyHandle {
4287        self.cert().key_handle()
4288    }
4289
4290    /// Returns the certificate's fingerprint.
4291    ///
4292    /// # Examples
4293    ///
4294    /// ```
4295    /// # use sequoia_openpgp as openpgp;
4296    /// # use openpgp::cert::prelude::*;
4297    /// # use openpgp::policy::StandardPolicy;
4298    /// #
4299    /// # fn main() -> openpgp::Result<()> {
4300    /// let p = &StandardPolicy::new();
4301    ///
4302    /// # let (cert, _) =
4303    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4304    /// #     .generate()?;
4305    /// #
4306    /// println!("{}", cert.with_policy(p, None)?.fingerprint());
4307    /// #
4308    /// # Ok(())
4309    /// # }
4310    /// ```
4311    pub fn fingerprint(&self) -> Fingerprint {
4312        self.cert().fingerprint()
4313    }
4314
4315    /// Returns the certificate's Key ID.
4316    ///
4317    /// As a general rule of thumb, you should prefer the fingerprint
4318    /// as it is possible to create keys with a colliding Key ID using
4319    /// a [birthday attack].
4320    ///
4321    /// [birthday attack]: https://nullprogram.com/blog/2019/07/22/
4322    ///
4323    /// # Examples
4324    ///
4325    /// ```
4326    /// # use sequoia_openpgp as openpgp;
4327    /// # use openpgp::cert::prelude::*;
4328    /// # use openpgp::policy::StandardPolicy;
4329    /// #
4330    /// # fn main() -> openpgp::Result<()> {
4331    /// let p = &StandardPolicy::new();
4332    ///
4333    /// # let (cert, _) =
4334    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
4335    /// #     .generate()?;
4336    /// #
4337    /// println!("{}", cert.with_policy(p, None)?.keyid());
4338    /// #
4339    /// # Ok(())
4340    /// # }
4341    /// ```
4342    pub fn keyid(&self) -> KeyID {
4343        self.cert().keyid()
4344    }
4345}
4346
4347macro_rules! impl_pref {
4348    ($subpacket:ident, $rt:ty) => {
4349        #[allow(deprecated)]
4350        fn $subpacket(&self) -> Option<$rt>
4351        {
4352            // When addressed by the fingerprint or keyid, we first
4353            // look on the primary User ID and then fall back to the
4354            // direct key signature.  We need to be careful to handle
4355            // the case where there are no User IDs.
4356            #[allow(deprecated)]
4357            if let Ok(u) = self.primary_userid() {
4358                u.$subpacket()
4359            } else if let Ok(sig) = self.direct_key_signature() {
4360                sig.$subpacket()
4361            } else {
4362                None
4363            }
4364        }
4365    }
4366}
4367
4368impl<'a> seal::Sealed for ValidCert<'a> {}
4369impl<'a> Preferences<'a> for ValidCert<'a>
4370{
4371    impl_pref!(preferred_symmetric_algorithms, &'a [SymmetricAlgorithm]);
4372    impl_pref!(preferred_hash_algorithms, &'a [HashAlgorithm]);
4373    impl_pref!(preferred_compression_algorithms, &'a [CompressionAlgorithm]);
4374    impl_pref!(preferred_aead_ciphersuites, &'a [(SymmetricAlgorithm, AEADAlgorithm)]);
4375    impl_pref!(key_server_preferences, KeyServerPreferences);
4376    impl_pref!(preferred_key_server, &'a [u8]);
4377    impl_pref!(policy_uri, &'a [u8]);
4378    impl_pref!(features, Features);
4379}
4380
4381#[cfg(test)]
4382mod test {
4383    use std::convert::TryInto;
4384
4385    use crate::crypto::PublicKeyAlgorithm;
4386    use crate::serialize::Serialize;
4387    use crate::policy::StandardPolicy as P;
4388    use crate::types::Curve;
4389    use crate::packet::signature;
4390    use crate::policy::HashAlgoSecurity;
4391    use super::*;
4392
4393    use crate::{
4394        KeyID,
4395        types::KeyFlags,
4396    };
4397
4398    fn parse_cert(data: &[u8], as_message: bool) -> Result<Cert> {
4399        if as_message {
4400            let pile = PacketPile::from_bytes(data).unwrap();
4401            Cert::try_from(pile)
4402        } else {
4403            Cert::from_bytes(data)
4404        }
4405    }
4406
4407    #[test]
4408    fn broken() {
4409        use crate::types::Timestamp;
4410        for i in 0..2 {
4411            let cert = parse_cert(crate::tests::key("testy-broken-no-pk.pgp"),
4412                                i == 0);
4413            assert_match!(Error::MalformedCert(_)
4414                          = cert.err().unwrap().downcast::<Error>().unwrap());
4415
4416            // According to 4880, a Cert must have a UserID.  But, we
4417            // don't require it.
4418            let cert = parse_cert(crate::tests::key("testy-broken-no-uid.pgp"),
4419                                i == 0);
4420            assert!(cert.is_ok());
4421
4422            // We have:
4423            //
4424            //   [ pk, user id, sig, subkey ]
4425            let cert = parse_cert(crate::tests::key("testy-broken-no-sig-on-subkey.pgp"),
4426                                i == 0).unwrap();
4427            assert_eq!(cert.primary.key().creation_time(),
4428                       Timestamp::from(1511355130).into());
4429            assert_eq!(cert.userids.len(), 1);
4430            assert_eq!(cert.userids[0].userid().value(),
4431                       &b"Testy McTestface <testy@example.org>"[..]);
4432            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4433            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4434                       .digest_prefix(),
4435                       &[ 0xc6, 0x8f ]);
4436            assert_eq!(cert.user_attributes.len(), 0);
4437            assert_eq!(cert.subkeys.len(), 1);
4438        }
4439    }
4440
4441    #[test]
4442    fn basics() {
4443        use crate::types::Timestamp;
4444        for i in 0..2 {
4445            let cert = parse_cert(crate::tests::key("testy.pgp"),
4446                                i == 0).unwrap();
4447            assert_eq!(cert.primary.key().creation_time(),
4448                       Timestamp::from(1511355130).into());
4449            assert_eq!(format!("{:X}", cert.fingerprint()),
4450                       "3E8877C877274692975189F5D03F6F865226FE8B");
4451
4452            assert_eq!(cert.userids.len(), 1, "number of userids");
4453            assert_eq!(cert.userids[0].userid().value(),
4454                       &b"Testy McTestface <testy@example.org>"[..]);
4455            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4456            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4457                       .digest_prefix(),
4458                       &[ 0xc6, 0x8f ]);
4459
4460            assert_eq!(cert.user_attributes.len(), 0);
4461
4462            assert_eq!(cert.subkeys.len(), 1, "number of subkeys");
4463            assert_eq!(cert.subkeys[0].key().creation_time(),
4464                       Timestamp::from(1511355130).into());
4465            assert_eq!(cert.subkeys[0].self_signatures().next().unwrap()
4466                       .digest_prefix(),
4467                       &[ 0xb7, 0xb9 ]);
4468
4469            let cert = parse_cert(crate::tests::key("testy-no-subkey.pgp"),
4470                                i == 0).unwrap();
4471            assert_eq!(cert.primary.key().creation_time(),
4472                       Timestamp::from(1511355130).into());
4473            assert_eq!(format!("{:X}", cert.fingerprint()),
4474                       "3E8877C877274692975189F5D03F6F865226FE8B");
4475
4476            assert_eq!(cert.user_attributes.len(), 0);
4477
4478            assert_eq!(cert.userids.len(), 1, "number of userids");
4479            assert_eq!(cert.userids[0].userid().value(),
4480                       &b"Testy McTestface <testy@example.org>"[..]);
4481            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4482            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4483                       .digest_prefix(),
4484                       &[ 0xc6, 0x8f ]);
4485
4486            assert_eq!(cert.subkeys.len(), 0, "number of subkeys");
4487
4488            let cert = parse_cert(crate::tests::key("testy.asc"), i == 0).unwrap();
4489            assert_eq!(format!("{:X}", cert.fingerprint()),
4490                       "3E8877C877274692975189F5D03F6F865226FE8B");
4491        }
4492    }
4493
4494    #[test]
4495    fn only_a_public_key() {
4496        // Make sure the Cert parser can parse a key that just consists
4497        // of a public key---no signatures, no user ids, nothing.
4498        let cert = Cert::from_bytes(crate::tests::key("testy-only-a-pk.pgp")).unwrap();
4499        assert_eq!(cert.userids.len(), 0);
4500        assert_eq!(cert.user_attributes.len(), 0);
4501        assert_eq!(cert.subkeys.len(), 0);
4502    }
4503
4504    #[test]
4505    fn merge() {
4506        use crate::tests::key;
4507        let cert_base = Cert::from_bytes(key("bannon-base.pgp")).unwrap();
4508
4509        // When we merge it with itself, we should get the exact same
4510        // thing.
4511        let merged = cert_base.clone().merge_public_and_secret(cert_base.clone()).unwrap();
4512        assert_eq!(cert_base, merged);
4513
4514        let cert_add_uid_1
4515            = Cert::from_bytes(key("bannon-add-uid-1-whitehouse.gov.pgp"))
4516                .unwrap();
4517        let cert_add_uid_2
4518            = Cert::from_bytes(key("bannon-add-uid-2-fox.com.pgp"))
4519                .unwrap();
4520        // Duplicate user id, but with a different self-sig.
4521        let cert_add_uid_3
4522            = Cert::from_bytes(key("bannon-add-uid-3-whitehouse.gov-dup.pgp"))
4523                .unwrap();
4524
4525        let cert_all_uids
4526            = Cert::from_bytes(key("bannon-all-uids.pgp"))
4527            .unwrap();
4528        // We have four User ID packets, but one has the same User ID,
4529        // just with a different self-signature.
4530        assert_eq!(cert_all_uids.userids.len(), 3);
4531
4532        // Merge in order.
4533        let merged = cert_base.clone().merge_public_and_secret(cert_add_uid_1.clone()).unwrap()
4534            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4535            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap();
4536        assert_eq!(cert_all_uids, merged);
4537
4538        // Merge in reverse order.
4539        let merged = cert_base.clone()
4540            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap()
4541            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4542            .merge_public_and_secret(cert_add_uid_1.clone()).unwrap();
4543        assert_eq!(cert_all_uids, merged);
4544
4545        let cert_add_subkey_1
4546            = Cert::from_bytes(key("bannon-add-subkey-1.pgp")).unwrap();
4547        let cert_add_subkey_2
4548            = Cert::from_bytes(key("bannon-add-subkey-2.pgp")).unwrap();
4549        let cert_add_subkey_3
4550            = Cert::from_bytes(key("bannon-add-subkey-3.pgp")).unwrap();
4551
4552        let cert_all_subkeys
4553            = Cert::from_bytes(key("bannon-all-subkeys.pgp")).unwrap();
4554
4555        // Merge the first user, then the second, then the third.
4556        let merged = cert_base.clone().merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4557            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4558            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap();
4559        assert_eq!(cert_all_subkeys, merged);
4560
4561        // Merge the third user, then the second, then the first.
4562        let merged = cert_base.clone().merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4563            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4564            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap();
4565        assert_eq!(cert_all_subkeys, merged);
4566
4567        // Merge a lot.
4568        let merged = cert_base.clone()
4569            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4570            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4571            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4572            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4573            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4574            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4575            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4576            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4577            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap();
4578        assert_eq!(cert_all_subkeys, merged);
4579
4580        let cert_all
4581            = Cert::from_bytes(key("bannon-all-uids-subkeys.pgp"))
4582            .unwrap();
4583
4584        // Merge all the subkeys with all the uids.
4585        let merged = cert_all_subkeys.clone()
4586            .merge_public_and_secret(cert_all_uids.clone()).unwrap();
4587        assert_eq!(cert_all, merged);
4588
4589        // Merge all uids with all the subkeys.
4590        let merged = cert_all_uids.clone()
4591            .merge_public_and_secret(cert_all_subkeys.clone()).unwrap();
4592        assert_eq!(cert_all, merged);
4593
4594        // All the subkeys and the uids in a mixed up order.
4595        let merged = cert_base.clone()
4596            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4597            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4598            .merge_public_and_secret(cert_add_uid_1.clone()).unwrap()
4599            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4600            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4601            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap()
4602            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4603            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4604            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap();
4605        assert_eq!(cert_all, merged);
4606
4607        // Certifications.
4608        let cert_donald_signs_base
4609            = Cert::from_bytes(key("bannon-the-donald-signs-base.pgp"))
4610            .unwrap();
4611        let cert_donald_signs_all
4612            = Cert::from_bytes(key("bannon-the-donald-signs-all-uids.pgp"))
4613            .unwrap();
4614        let cert_ivanka_signs_base
4615            = Cert::from_bytes(key("bannon-ivanka-signs-base.pgp"))
4616            .unwrap();
4617        let cert_ivanka_signs_all
4618            = Cert::from_bytes(key("bannon-ivanka-signs-all-uids.pgp"))
4619            .unwrap();
4620
4621        assert!(cert_donald_signs_base.userids.len() == 1);
4622        assert!(cert_donald_signs_base.userids[0].self_signatures().count() == 1);
4623        assert!(cert_base.userids[0].certifications.is_empty());
4624        assert!(cert_donald_signs_base.userids[0].certifications.len() == 1);
4625
4626        let merged = cert_donald_signs_base.clone()
4627            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap();
4628        assert!(merged.userids.len() == 1);
4629        assert!(merged.userids[0].self_signatures().count() == 1);
4630        assert!(merged.userids[0].certifications.len() == 2);
4631
4632        let merged = cert_donald_signs_base.clone()
4633            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap();
4634        assert!(merged.userids.len() == 3);
4635        assert!(merged.userids[0].self_signatures().count() == 1);
4636        // There should be two certifications from the Donald on the
4637        // first user id.
4638        assert!(merged.userids[0].certifications.len() == 2);
4639        assert!(merged.userids[1].certifications.len() == 1);
4640        assert!(merged.userids[2].certifications.len() == 1);
4641
4642        let merged = cert_donald_signs_base.clone()
4643            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4644            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4645            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap();
4646        assert!(merged.userids.len() == 3);
4647        assert!(merged.userids[0].self_signatures().count() == 1);
4648        // There should be two certifications from each of the Donald
4649        // and Ivanka on the first user id, and one each on the rest.
4650        assert!(merged.userids[0].certifications.len() == 4);
4651        assert!(merged.userids[1].certifications.len() == 2);
4652        assert!(merged.userids[2].certifications.len() == 2);
4653
4654        // Same as above, but redundant.
4655        let merged = cert_donald_signs_base.clone()
4656            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4657            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4658            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4659            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap()
4660            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4661            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4662            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4663            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap();
4664        assert!(merged.userids.len() == 3);
4665        assert!(merged.userids[0].self_signatures().count() == 1);
4666        // There should be two certifications from each of the Donald
4667        // and Ivanka on the first user id, and one each on the rest.
4668        assert!(merged.userids[0].certifications.len() == 4);
4669        assert!(merged.userids[1].certifications.len() == 2);
4670        assert!(merged.userids[2].certifications.len() == 2);
4671    }
4672
4673    #[test]
4674    fn out_of_order_self_sigs_test() {
4675        // neal-out-of-order.pgp contains all the self-signatures,
4676        // but some are out of order.  The canonicalization step
4677        // should reorder them.
4678        //
4679        // original order/new order:
4680        //
4681        //  1/ 1. pk
4682        //  2/ 2. user id #1: neal@walfield.org (good)
4683        //  3/ 3. sig over user ID #1
4684        //
4685        //  4/ 4. user id #2: neal@gnupg.org (good)
4686        //  5/ 7. sig over user ID #3
4687        //  6/ 5. sig over user ID #2
4688        //
4689        //  7/ 6. user id #3: neal@g10code.com (bad)
4690        //
4691        //  8/ 8. user ID #4: neal@pep.foundation (bad)
4692        //  9/11. sig over user ID #5
4693        //
4694        // 10/10. user id #5: neal@pep-project.org (bad)
4695        // 11/ 9. sig over user ID #4
4696        //
4697        // 12/12. user ID #6: neal@sequoia-pgp.org (good)
4698        // 13/13. sig over user ID #6
4699        //
4700        // ----------------------------------------------
4701        //
4702        // 14/14. signing subkey #1: 7223B56678E02528 (good)
4703        // 15/15. sig over subkey #1
4704        // 16/16. sig over subkey #1
4705        //
4706        // 17/17. encryption subkey #2: C2B819056C652598 (good)
4707        // 18/18. sig over subkey #2
4708        // 19/21. sig over subkey #3
4709        // 20/22. sig over subkey #3
4710        //
4711        // 21/20. auth subkey #3: A3506AFB820ABD08 (bad)
4712        // 22/19. sig over subkey #2
4713
4714        let cert = Cert::from_bytes(crate::tests::key("neal-sigs-out-of-order.pgp"))
4715            .unwrap();
4716
4717        let mut userids = cert.userids()
4718            .map(|u| String::from_utf8_lossy(u.userid().value()).into_owned())
4719            .collect::<Vec<String>>();
4720        userids.sort();
4721
4722        assert_eq!(userids,
4723                   &[ "Neal H. Walfield <neal@g10code.com>",
4724                      "Neal H. Walfield <neal@gnupg.org>",
4725                      "Neal H. Walfield <neal@pep-project.org>",
4726                      "Neal H. Walfield <neal@pep.foundation>",
4727                      "Neal H. Walfield <neal@sequoia-pgp.org>",
4728                      "Neal H. Walfield <neal@walfield.org>",
4729                   ]);
4730
4731        let mut subkeys = cert.subkeys()
4732            .map(|sk| Some(sk.key().keyid()))
4733            .collect::<Vec<Option<KeyID>>>();
4734        subkeys.sort();
4735        assert_eq!(subkeys,
4736                   &[ "7223B56678E02528".parse().ok(),
4737                      "A3506AFB820ABD08".parse().ok(),
4738                      "C2B819056C652598".parse().ok(),
4739                   ]);
4740
4741        // DKG's key has all the self-signatures moved to the last
4742        // subkey; all user ids/user attributes/subkeys have nothing.
4743        let cert =
4744            Cert::from_bytes(crate::tests::key("dkg-sigs-out-of-order.pgp")).unwrap();
4745
4746        let mut userids = cert.userids()
4747            .map(|u| String::from_utf8_lossy(u.userid().value()).into_owned())
4748            .collect::<Vec<String>>();
4749        userids.sort();
4750
4751        assert_eq!(userids,
4752                   &[ "Daniel Kahn Gillmor <dkg-debian.org@fifthhorseman.net>",
4753                      "Daniel Kahn Gillmor <dkg@aclu.org>",
4754                      "Daniel Kahn Gillmor <dkg@astro.columbia.edu>",
4755                      "Daniel Kahn Gillmor <dkg@debian.org>",
4756                      "Daniel Kahn Gillmor <dkg@fifthhorseman.net>",
4757                      "Daniel Kahn Gillmor <dkg@openflows.com>",
4758                   ]);
4759
4760        assert_eq!(cert.user_attributes.len(), 1);
4761
4762        let mut subkeys = cert.subkeys()
4763            .map(|sk| Some(sk.key().keyid()))
4764            .collect::<Vec<Option<KeyID>>>();
4765        subkeys.sort();
4766        assert_eq!(subkeys,
4767                   &[ "1075 8EBD BD7C FAB5".parse().ok(),
4768                      "1258 68EA 4BFA 08E4".parse().ok(),
4769                      "1498 ADC6 C192 3237".parse().ok(),
4770                      "24EC FF5A FF68 370A".parse().ok(),
4771                      "3714 7292 14D5 DA70".parse().ok(),
4772                      "3B7A A7F0 14E6 9B5A".parse().ok(),
4773                      "5B58 DCF9 C341 6611".parse().ok(),
4774                      "A524 01B1 1BFD FA5C".parse().ok(),
4775                      "A70A 96E1 439E A852".parse().ok(),
4776                      "C61B D3EC 2148 4CFF".parse().ok(),
4777                      "CAEF A883 2167 5333".parse().ok(),
4778                      "DC10 4C4E 0CA7 57FB".parse().ok(),
4779                      "E3A3 2229 449B 0350".parse().ok(),
4780                   ]);
4781
4782    }
4783
4784    /// Tests how we deal with v3 keys, certs, and certifications.
4785    #[test]
4786    fn v3_packets() {
4787        // v3 primary keys are not supported.
4788
4789        let cert = Cert::from_bytes(crate::tests::key("john-v3.pgp"));
4790        assert_match!(Error::UnsupportedCert(..)
4791                      = cert.err().unwrap().downcast::<Error>().unwrap());
4792
4793        let cert = Cert::from_bytes(crate::tests::key("john-v3-secret.pgp"));
4794        assert_match!(Error::UnsupportedCert(..)
4795                      = cert.err().unwrap().downcast::<Error>().unwrap());
4796
4797        // Lutz's key is a v3 key.
4798        let cert = Cert::from_bytes(crate::tests::key("lutz.pgp"));
4799        assert_match!(Error::UnsupportedCert(..)
4800                      = cert.err().unwrap().downcast::<Error>().unwrap());
4801
4802        // v3 certifications are not supported
4803
4804        // dkg's includes some v3 signatures.
4805        let cert = Cert::from_bytes(crate::tests::key("dkg.pgp"));
4806        assert!(cert.is_ok(), "dkg.pgp: {:?}", cert);
4807    }
4808
4809    #[test]
4810    fn keyring_with_v3_public_keys() {
4811        let dkg = crate::tests::key("dkg.pgp");
4812        let lutz = crate::tests::key("lutz.pgp");
4813
4814        let cert = Cert::from_bytes(dkg);
4815        assert!(cert.is_ok(), "dkg.pgp: {:?}", cert);
4816
4817        // Keyring with two good keys
4818        let mut combined = vec![];
4819        combined.extend_from_slice(dkg);
4820        combined.extend_from_slice(dkg);
4821        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4822            .map(|certr| certr.is_ok())
4823            .collect::<Vec<bool>>();
4824        assert_eq!(certs, &[ true, true ]);
4825
4826        // Keyring with a good key, and a bad key.
4827        let mut combined = vec![];
4828        combined.extend_from_slice(dkg);
4829        combined.extend_from_slice(lutz);
4830        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4831            .map(|certr| certr.is_ok())
4832            .collect::<Vec<bool>>();
4833        assert_eq!(certs, &[ true, false ]);
4834
4835        // Keyring with a bad key, and a good key.
4836        let mut combined = vec![];
4837        combined.extend_from_slice(lutz);
4838        combined.extend_from_slice(dkg);
4839        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4840            .map(|certr| certr.is_ok())
4841            .collect::<Vec<bool>>();
4842        assert_eq!(certs, &[ false, true ]);
4843
4844        // Keyring with a good key, a bad key, and a good key.
4845        let mut combined = vec![];
4846        combined.extend_from_slice(dkg);
4847        combined.extend_from_slice(lutz);
4848        combined.extend_from_slice(dkg);
4849        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4850            .map(|certr| certr.is_ok())
4851            .collect::<Vec<bool>>();
4852        assert_eq!(certs, &[ true, false, true ]);
4853
4854        // Keyring with a good key, a bad key, and a bad key.
4855        let mut combined = vec![];
4856        combined.extend_from_slice(dkg);
4857        combined.extend_from_slice(lutz);
4858        combined.extend_from_slice(lutz);
4859        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4860            .map(|certr| certr.is_ok())
4861            .collect::<Vec<bool>>();
4862        assert_eq!(certs, &[ true, false, false ]);
4863
4864        // Keyring with a good key, a bad key, a bad key, and a good key.
4865        let mut combined = vec![];
4866        combined.extend_from_slice(dkg);
4867        combined.extend_from_slice(lutz);
4868        combined.extend_from_slice(lutz);
4869        combined.extend_from_slice(dkg);
4870        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4871            .map(|certr| certr.is_ok())
4872            .collect::<Vec<bool>>();
4873        assert_eq!(certs, &[ true, false, false, true ]);
4874    }
4875
4876    #[test]
4877    fn merge_with_incomplete_update() {
4878        let p = &P::new();
4879
4880        let cert = Cert::from_bytes(crate::tests::key("about-to-expire.expired.pgp"))
4881            .unwrap();
4882        cert.primary_key().with_policy(p, None).unwrap().alive().unwrap_err();
4883
4884        let update =
4885            Cert::from_bytes(crate::tests::key("about-to-expire.update-no-uid.pgp"))
4886            .unwrap();
4887        let cert = cert.merge_public_and_secret(update).unwrap();
4888        cert.primary_key().with_policy(p, None).unwrap().alive().unwrap();
4889    }
4890
4891    #[test]
4892    fn packet_pile_roundtrip() {
4893        // Make sure Cert::try_from(Cert::to_packet_pile(cert))
4894        // does a clean round trip.
4895
4896        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
4897        let cert2
4898            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4899        assert_eq!(cert, cert2);
4900
4901        let cert = Cert::from_bytes(
4902            crate::tests::key("already-revoked-direct-revocation.pgp")).unwrap();
4903        let cert2
4904            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4905        assert_eq!(cert, cert2);
4906
4907        let cert = Cert::from_bytes(
4908            crate::tests::key("already-revoked-userid-revocation.pgp")).unwrap();
4909        let cert2
4910            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4911        assert_eq!(cert, cert2);
4912
4913        let cert = Cert::from_bytes(
4914            crate::tests::key("already-revoked-subkey-revocation.pgp")).unwrap();
4915        let cert2
4916            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4917        assert_eq!(cert, cert2);
4918    }
4919
4920    #[test]
4921    fn insert_packets_add_sig() {
4922        use crate::armor;
4923        use crate::packet::Tag;
4924
4925        // Merge the revocation certificate into the Cert and make sure
4926        // it shows up.
4927        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
4928
4929        let rev = crate::tests::key("already-revoked.rev");
4930        let rev = PacketPile::from_reader(armor::Reader::from_reader(rev, None))
4931            .unwrap();
4932
4933        let rev : Vec<Packet> = rev.into_children().collect();
4934        assert_eq!(rev.len(), 1);
4935        assert_eq!(rev[0].tag(), Tag::Signature);
4936
4937        let packets_pre_merge = cert.clone().into_packets().count();
4938        let cert = cert.insert_packets(rev).unwrap().0;
4939        let packets_post_merge = cert.clone().into_packets().count();
4940        assert_eq!(packets_post_merge, packets_pre_merge + 1);
4941    }
4942
4943    #[test]
4944    fn insert_packets_update_sig() -> Result<()> {
4945        use std::time::Duration;
4946
4947        use crate::packet::signature::subpacket::Subpacket;
4948        use crate::packet::signature::subpacket::SubpacketValue;
4949
4950        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
4951            .generate()?;
4952        let packets = cert.clone().into_packets().count();
4953
4954        // Merge a signature with different unhashed subpacket areas.
4955        // Make sure only the last variant is merged.
4956        let sig = cert.primary_key().self_signatures().next()
4957            .expect("binding signature");
4958
4959        let a = Subpacket::new(
4960            SubpacketValue::SignatureExpirationTime(
4961                Duration::new(1, 0).try_into()?),
4962            false)?;
4963        let b = Subpacket::new(
4964            SubpacketValue::SignatureExpirationTime(
4965                Duration::new(2, 0).try_into()?),
4966            false)?;
4967
4968        let mut sig_a = sig.clone();
4969        sig_a.unhashed_area_mut().add(a)?;
4970        let mut sig_b = sig.clone();
4971        sig_b.unhashed_area_mut().add(b)?;
4972
4973        // Insert sig_a, make sure it (and it alone) appears.
4974        let cert2 = cert.clone().insert_packets(sig_a.clone())?.0;
4975        let mut sigs = cert2.primary_key().self_signatures();
4976        assert_eq!(sigs.next(), Some(&sig_a));
4977        assert!(sigs.next().is_none());
4978        assert_eq!(cert2.clone().into_packets().count(), packets);
4979
4980        // Insert sig_b, make sure it (and it alone) appears.
4981        let cert2 = cert.clone().insert_packets(sig_b.clone())?.0;
4982        let mut sigs = cert2.primary_key().self_signatures();
4983        assert_eq!(sigs.next(), Some(&sig_b));
4984        assert!(sigs.next().is_none());
4985        assert_eq!(cert2.clone().into_packets().count(), packets);
4986
4987        // Insert sig_a and sig_b.  Make sure sig_b (and it alone)
4988        // appears.
4989        let cert2 = cert.clone().insert_packets(
4990            vec![ sig_a.clone(), sig_b.clone() ])?.0;
4991        let mut sigs = cert2.primary_key().self_signatures();
4992        assert_eq!(sigs.next(), Some(&sig_b));
4993        assert!(sigs.next().is_none());
4994        assert_eq!(cert2.clone().into_packets().count(), packets);
4995
4996        // Insert sig_b and sig_a.  Make sure sig_a (and it alone)
4997        // appears.
4998        let cert2 = cert.clone().insert_packets(
4999            vec![ sig_b.clone(), sig_a.clone() ])?.0;
5000        let mut sigs = cert2.primary_key().self_signatures();
5001        assert_eq!(sigs.next(), Some(&sig_a));
5002        assert!(sigs.next().is_none());
5003        assert_eq!(cert2.clone().into_packets().count(), packets);
5004
5005        Ok(())
5006    }
5007
5008    #[test]
5009    fn insert_packets_add_userid() -> Result<()> {
5010        let (cert, _) = CertBuilder::general_purpose(Some("a"))
5011            .generate()?;
5012        let packets = cert.clone().into_packets().count();
5013
5014        let uid_a = UserID::from("a");
5015        let uid_b = UserID::from("b");
5016
5017        // Insert a, make sure it appears once.
5018        let cert2 = cert.clone().insert_packets(uid_a.clone())?.0;
5019        let mut uids = cert2.userids();
5020        assert_eq!(uids.next().unwrap().userid(), &uid_a);
5021        assert!(uids.next().is_none());
5022        assert_eq!(cert2.clone().into_packets().count(), packets);
5023
5024        // Insert b, make sure it also appears.
5025        let cert2 = cert.clone().insert_packets(uid_b.clone())?.0;
5026        let mut uids: Vec<UserID>
5027            = cert2.userids().map(|ua| ua.userid().clone()).collect();
5028        uids.sort();
5029        let mut uids = uids.iter();
5030        assert_eq!(uids.next().unwrap(), &uid_a);
5031        assert_eq!(uids.next().unwrap(), &uid_b);
5032        assert!(uids.next().is_none());
5033        assert_eq!(cert2.clone().into_packets().count(), packets + 1);
5034
5035        Ok(())
5036    }
5037
5038    #[test]
5039    fn insert_packets_update_key() -> Result<()> {
5040        use crate::crypto::Password;
5041
5042        let (cert, _) = CertBuilder::new().generate()?;
5043        let packets = cert.clone().into_packets().count();
5044        assert_eq!(cert.keys().count(), 1);
5045
5046        let key = cert.keys().secret().next().unwrap().key()
5047            .role_as_primary();
5048        assert!(key.has_secret());
5049        let key_a = key.clone().encrypt_secret(&Password::from("a"))?;
5050        let key_b = key.clone().encrypt_secret(&Password::from("b"))?;
5051
5052        // Insert variant a.
5053        let cert2 = cert.clone().insert_packets(key_a.clone())?.0;
5054        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5055                   &key_a);
5056        assert_eq!(cert2.clone().into_packets().count(), packets);
5057
5058        // Insert variant b.
5059        let cert2 = cert.clone().insert_packets(key_b.clone())?.0;
5060        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5061                   &key_b);
5062        assert_eq!(cert2.clone().into_packets().count(), packets);
5063
5064        // Insert variant a then b.  We should keep b.
5065        let cert2 = cert.clone().insert_packets(
5066            vec![ key_a.clone(), key_b.clone() ])?.0;
5067        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5068                   &key_b);
5069        assert_eq!(cert2.clone().into_packets().count(), packets);
5070
5071        // Insert variant b then a.  We should keep a.
5072        let cert2 = cert.clone().insert_packets(
5073            vec![ key_b.clone(), key_a.clone() ])?.0;
5074        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5075                   &key_a);
5076        assert_eq!(cert2.clone().into_packets().count(), packets);
5077
5078        Ok(())
5079    }
5080
5081    #[test]
5082    fn set_validity_period() {
5083        let p = &P::new();
5084
5085        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
5086            .generate().unwrap();
5087        assert_eq!(cert.clone().into_packet_pile().children().count(),
5088                   1 // primary key
5089                   + 1 // direct key signature
5090                   + 1 // userid
5091                   + 1 // binding signature
5092                   + 1 // subkey
5093                   + 1 // binding signature
5094                   + 1 // subkey
5095                   + 1 // binding signature
5096        );
5097        let cert = check_set_validity_period(p, cert);
5098        assert_eq!(cert.clone().into_packet_pile().children().count(),
5099                   1 // primary key
5100                   + 1 // direct key signature
5101                   + 2 // two new direct key signatures
5102                   + 1 // userid
5103                   + 1 // binding signature
5104                   + 2 // two new binding signatures
5105                   + 1 // subkey
5106                   + 1 // binding signature
5107                   + 1 // subkey
5108                   + 1 // binding signature
5109        );
5110    }
5111
5112    #[test]
5113    fn set_validity_period_two_uids() -> Result<()> {
5114        use quickcheck::{Arbitrary, Gen};
5115        let mut gen = Gen::new(16);
5116        let p = &P::new();
5117
5118        let userid1 = UserID::arbitrary(&mut gen);
5119        // The two user ids need to be unique.
5120        let mut userid2 = UserID::arbitrary(&mut gen);
5121        while userid1 == userid2 {
5122            userid2 = UserID::arbitrary(&mut gen);
5123        }
5124
5125        let (cert, _) = CertBuilder::general_purpose(
5126            Some(userid1))
5127            .add_userid(userid2)
5128            .generate()?;
5129        let primary_uid = cert.with_policy(p, None)?.primary_userid()?.userid().clone();
5130        assert_eq!(cert.clone().into_packet_pile().children().count(),
5131                   1 // primary key
5132                   + 1 // direct key signature
5133                   + 1 // userid
5134                   + 1 // binding signature
5135                   + 1 // userid
5136                   + 1 // binding signature
5137                   + 1 // subkey
5138                   + 1 // binding signature
5139                   + 1 // subkey
5140                   + 1 // binding signature
5141        );
5142        let cert = check_set_validity_period(p, cert);
5143        assert_eq!(cert.clone().into_packet_pile().children().count(),
5144                   1 // primary key
5145                   + 1 // direct key signature
5146                   + 2 // two new direct key signatures
5147                   + 1 // userid
5148                   + 1 // binding signature
5149                   + 2 // two new binding signatures
5150                   + 1 // userid
5151                   + 1 // binding signature
5152                   + 2 // two new binding signatures
5153                   + 1 // subkey
5154                   + 1 // binding signature
5155                   + 1 // subkey
5156                   + 1 // binding signature
5157        );
5158        assert_eq!(&primary_uid, cert.with_policy(p, None)?.primary_userid()?.userid());
5159        Ok(())
5160    }
5161
5162    #[test]
5163    fn set_validity_period_uidless() {
5164        use crate::types::Duration;
5165        let p = &P::new();
5166
5167        let (cert, _) = CertBuilder::new()
5168            .set_validity_period(None) // Just to assert this works.
5169            .set_validity_period(Some(Duration::weeks(52).unwrap().try_into().unwrap()))
5170            .generate().unwrap();
5171        assert_eq!(cert.clone().into_packet_pile().children().count(),
5172                   1 // primary key
5173                   + 1 // direct key signature
5174        );
5175        let cert = check_set_validity_period(p, cert);
5176        assert_eq!(cert.clone().into_packet_pile().children().count(),
5177                   1 // primary key
5178                   + 1 // direct key signature
5179                   + 2 // two new direct key signatures
5180        );
5181    }
5182    fn check_set_validity_period(policy: &dyn Policy, cert: Cert) -> Cert {
5183        let now = cert.primary_key().key().creation_time();
5184        let a_sec = time::Duration::new(1, 0);
5185
5186        let expiry_orig = cert.primary_key().with_policy(policy, now).unwrap()
5187            .key_validity_period()
5188            .expect("Keys expire by default.");
5189
5190        let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5191            .unwrap().into_keypair().unwrap();
5192
5193        // Clear the expiration.
5194        let as_of1 = now + time::Duration::new(10, 0);
5195        let cert = cert.set_validity_period_as_of(
5196            policy, &mut keypair, None, as_of1).unwrap();
5197        {
5198            // If t < as_of1, we should get the original expiry.
5199            assert_eq!(cert.primary_key().with_policy(policy, now).unwrap()
5200                           .key_validity_period(),
5201                       Some(expiry_orig));
5202            assert_eq!(cert.primary_key().with_policy(policy, as_of1 - a_sec).unwrap()
5203                           .key_validity_period(),
5204                       Some(expiry_orig));
5205            // If t >= as_of1, we should get the new expiry.
5206            assert_eq!(cert.primary_key().with_policy(policy, as_of1).unwrap()
5207                           .key_validity_period(),
5208                       None);
5209        }
5210
5211        // Shorten the expiry.  (The default expiration should be at
5212        // least a few weeks, so removing an hour should still keep us
5213        // over 0.)
5214        let expiry_new = expiry_orig - time::Duration::new(60 * 60, 0);
5215        assert!(expiry_new > time::Duration::new(0, 0));
5216
5217        let as_of2 = as_of1 + time::Duration::new(10, 0);
5218        let cert = cert.set_validity_period_as_of(
5219            policy, &mut keypair, Some(expiry_new), as_of2).unwrap();
5220        {
5221            // If t < as_of1, we should get the original expiry.
5222            assert_eq!(cert.primary_key().with_policy(policy, now).unwrap()
5223                           .key_validity_period(),
5224                       Some(expiry_orig));
5225            assert_eq!(cert.primary_key().with_policy(policy, as_of1 - a_sec).unwrap()
5226                           .key_validity_period(),
5227                       Some(expiry_orig));
5228            // If as_of1 <= t < as_of2, we should get the second
5229            // expiry (None).
5230            assert_eq!(cert.primary_key().with_policy(policy, as_of1).unwrap()
5231                           .key_validity_period(),
5232                       None);
5233            assert_eq!(cert.primary_key().with_policy(policy, as_of2 - a_sec).unwrap()
5234                           .key_validity_period(),
5235                       None);
5236            // If t <= as_of2, we should get the new expiry.
5237            assert_eq!(cert.primary_key().with_policy(policy, as_of2).unwrap()
5238                           .key_validity_period(),
5239                       Some(expiry_new));
5240        }
5241        cert
5242    }
5243
5244    #[test]
5245    fn direct_key_sig() {
5246        use crate::types::SignatureType;
5247        // XXX: testing sequoia against itself isn't optimal, but I couldn't
5248        // find a tool to generate direct key signatures :-(
5249
5250        let p = &P::new();
5251
5252        let (cert1, _) = CertBuilder::new().generate().unwrap();
5253        let mut buf = Vec::default();
5254
5255        cert1.serialize(&mut buf).unwrap();
5256        let cert2 = Cert::from_bytes(&buf).unwrap();
5257
5258        assert_eq!(
5259            cert2.primary_key().with_policy(p, None).unwrap()
5260                .direct_key_signature().unwrap().typ(),
5261            SignatureType::DirectKey);
5262        assert_eq!(cert2.userids().count(), 0);
5263    }
5264
5265    #[test]
5266    fn revoked() {
5267        fn check(cert: &Cert, direct_revoked: bool,
5268                 userid_revoked: bool, subkey_revoked: bool) {
5269            let p = &P::new();
5270
5271            // If we have a user id---even if it is revoked---we have
5272            // a primary key signature.
5273            let typ = cert.primary_key().with_policy(p, None).unwrap()
5274                .binding_signature().typ();
5275            assert_eq!(typ, SignatureType::PositiveCertification,
5276                       "{:#?}", cert);
5277
5278            let revoked = cert.revocation_status(p, None);
5279            if direct_revoked {
5280                assert_match!(RevocationStatus::Revoked(_) = revoked,
5281                              "{:#?}", cert);
5282            } else {
5283                assert_eq!(revoked, RevocationStatus::NotAsFarAsWeKnow,
5284                           "{:#?}", cert);
5285            }
5286
5287            for userid in cert.userids().with_policy(p, None) {
5288                let typ = userid.binding_signature().typ();
5289                assert_eq!(typ, SignatureType::PositiveCertification,
5290                           "{:#?}", cert);
5291
5292                let revoked = userid.revocation_status();
5293                if userid_revoked {
5294                    assert_match!(RevocationStatus::Revoked(_) = revoked);
5295                } else {
5296                    assert_eq!(RevocationStatus::NotAsFarAsWeKnow, revoked,
5297                               "{:#?}", cert);
5298                }
5299            }
5300
5301            for subkey in cert.subkeys() {
5302                let typ = subkey.binding_signature(p, None).unwrap().typ();
5303                assert_eq!(typ, SignatureType::SubkeyBinding,
5304                           "{:#?}", cert);
5305
5306                let revoked = subkey.revocation_status(p, None);
5307                if subkey_revoked {
5308                    assert_match!(RevocationStatus::Revoked(_) = revoked);
5309                } else {
5310                    assert_eq!(RevocationStatus::NotAsFarAsWeKnow, revoked,
5311                               "{:#?}", cert);
5312                }
5313            }
5314        }
5315
5316        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
5317        check(&cert, false, false, false);
5318
5319        let d = Cert::from_bytes(
5320            crate::tests::key("already-revoked-direct-revocation.pgp")).unwrap();
5321        check(&d, true, false, false);
5322
5323        check(&cert.clone().merge_public_and_secret(d.clone()).unwrap(), true, false, false);
5324        // Make sure the merge order does not matter.
5325        check(&d.clone().merge_public_and_secret(cert.clone()).unwrap(), true, false, false);
5326
5327        let u = Cert::from_bytes(
5328            crate::tests::key("already-revoked-userid-revocation.pgp")).unwrap();
5329        check(&u, false, true, false);
5330
5331        check(&cert.clone().merge_public_and_secret(u.clone()).unwrap(), false, true, false);
5332        check(&u.clone().merge_public_and_secret(cert.clone()).unwrap(), false, true, false);
5333
5334        let k = Cert::from_bytes(
5335            crate::tests::key("already-revoked-subkey-revocation.pgp")).unwrap();
5336        check(&k, false, false, true);
5337
5338        check(&cert.clone().merge_public_and_secret(k.clone()).unwrap(), false, false, true);
5339        check(&k.clone().merge_public_and_secret(cert.clone()).unwrap(), false, false, true);
5340
5341        // direct and user id revocation.
5342        check(&d.clone().merge_public_and_secret(u.clone()).unwrap(), true, true, false);
5343        check(&u.clone().merge_public_and_secret(d.clone()).unwrap(), true, true, false);
5344
5345        // direct and subkey revocation.
5346        check(&d.clone().merge_public_and_secret(k.clone()).unwrap(), true, false, true);
5347        check(&k.clone().merge_public_and_secret(d.clone()).unwrap(), true, false, true);
5348
5349        // user id and subkey revocation.
5350        check(&u.clone().merge_public_and_secret(k.clone()).unwrap(), false, true, true);
5351        check(&k.clone().merge_public_and_secret(u.clone()).unwrap(), false, true, true);
5352
5353        // direct, user id and subkey revocation.
5354        check(&d.clone().merge_public_and_secret(u.clone().merge_public_and_secret(k.clone()).unwrap()).unwrap(),
5355              true, true, true);
5356        check(&d.clone().merge_public_and_secret(k.clone().merge_public_and_secret(u.clone()).unwrap()).unwrap(),
5357              true, true, true);
5358    }
5359
5360    #[test]
5361    fn revoke() {
5362        let p = &P::new();
5363
5364        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
5365            .generate().unwrap();
5366        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5367                   cert.revocation_status(p, None));
5368
5369        let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5370            .unwrap().into_keypair().unwrap();
5371
5372        let sig = CertRevocationBuilder::new()
5373            .set_reason_for_revocation(
5374                ReasonForRevocation::KeyCompromised,
5375                b"It was the maid :/").unwrap()
5376            .build(&mut keypair, &cert, None)
5377            .unwrap();
5378        assert_eq!(sig.typ(), SignatureType::KeyRevocation);
5379        assert_eq!(sig.issuers().collect::<Vec<_>>(),
5380                   vec![ &cert.keyid() ]);
5381        assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
5382                   vec![ &cert.fingerprint() ]);
5383
5384        let cert = cert.insert_packets(sig).unwrap().0;
5385        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, None));
5386
5387
5388        // Have other revoke cert.
5389        let (other, _) = CertBuilder::general_purpose(Some("Test 2"))
5390            .generate().unwrap();
5391
5392        let mut keypair = other.primary_key().key().clone().parts_into_secret()
5393            .unwrap().into_keypair().unwrap();
5394
5395        let sig = CertRevocationBuilder::new()
5396            .set_reason_for_revocation(
5397                ReasonForRevocation::KeyCompromised,
5398                b"It was the maid :/").unwrap()
5399            .build(&mut keypair, &cert, None)
5400            .unwrap();
5401
5402        assert_eq!(sig.typ(), SignatureType::KeyRevocation);
5403        assert_eq!(sig.issuers().collect::<Vec<_>>(),
5404                   vec![ &other.keyid() ]);
5405        assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
5406                   vec![ &other.fingerprint() ]);
5407    }
5408
5409    #[test]
5410    fn revoke_subkey() {
5411        let p = &P::new();
5412        let (cert, _) = CertBuilder::new()
5413            .add_transport_encryption_subkey()
5414            .generate().unwrap();
5415
5416        let sig = {
5417            let subkey = cert.subkeys().next().unwrap();
5418            assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5419                       subkey.revocation_status(p, None));
5420
5421            let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5422                .unwrap().into_keypair().unwrap();
5423            SubkeyRevocationBuilder::new()
5424                .set_reason_for_revocation(
5425                    ReasonForRevocation::UIDRetired,
5426                    b"It was the maid :/").unwrap()
5427                .build(&mut keypair, &cert, subkey.key(), None)
5428                .unwrap()
5429        };
5430        assert_eq!(sig.typ(), SignatureType::SubkeyRevocation);
5431        let cert = cert.insert_packets(sig).unwrap().0;
5432        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5433                   cert.revocation_status(p, None));
5434
5435        let subkey = cert.subkeys().next().unwrap();
5436        assert_match!(RevocationStatus::Revoked(_)
5437                      = subkey.revocation_status(p, None));
5438    }
5439
5440    #[test]
5441    fn revoke_uid() {
5442        let p = &P::new();
5443        let (cert, _) = CertBuilder::new()
5444            .add_userid("Test1")
5445            .add_userid("Test2")
5446            .generate().unwrap();
5447
5448        let sig = {
5449            let uid = cert.userids().with_policy(p, None).nth(1).unwrap();
5450            assert_eq!(RevocationStatus::NotAsFarAsWeKnow, uid.revocation_status());
5451
5452            let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5453                .unwrap().into_keypair().unwrap();
5454            UserIDRevocationBuilder::new()
5455                .set_reason_for_revocation(
5456                    ReasonForRevocation::UIDRetired,
5457                    b"It was the maid :/").unwrap()
5458                .build(&mut keypair, &cert, uid.userid(), None)
5459                .unwrap()
5460        };
5461        assert_eq!(sig.typ(), SignatureType::CertificationRevocation);
5462        let cert = cert.insert_packets(sig).unwrap().0;
5463        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5464                   cert.revocation_status(p, None));
5465
5466        let uid = cert.userids().with_policy(p, None).nth(1).unwrap();
5467        assert_match!(RevocationStatus::Revoked(_) = uid.revocation_status());
5468    }
5469
5470    #[test]
5471    fn key_revoked() {
5472        use crate::types::Features;
5473        use crate::packet::key::Key6;
5474        use rand::{rng, Rng, distr::Open01};
5475
5476        let p = &P::new();
5477
5478        /*
5479         * t1: 1st binding sig ctime
5480         * t2: soft rev sig ctime
5481         * t3: 2nd binding sig ctime
5482         * t4: hard rev sig ctime
5483         *
5484         * [0,t1): invalid, but not revoked
5485         * [t1,t2): valid (not revocations)
5486         * [t2,t3): revoked (soft revocation)
5487         * [t3,t4): valid again (new self sig)
5488         * [t4,inf): hard revocation (hard revocation)
5489         *
5490         * Once the hard revocation is merged, then the Cert is
5491         * considered revoked at all times.
5492         */
5493        let t1 = time::UNIX_EPOCH + time::Duration::new(946681200, 0);  // 2000-1-1
5494        let t2 = time::UNIX_EPOCH + time::Duration::new(978303600, 0);  // 2001-1-1
5495        let t3 = time::UNIX_EPOCH + time::Duration::new(1009839600, 0); // 2002-1-1
5496        let t4 = time::UNIX_EPOCH + time::Duration::new(1041375600, 0); // 2003-1-1
5497
5498        let mut key: key::SecretKey
5499            = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
5500        key.set_creation_time(t1).unwrap();
5501        let mut pair = key.clone().into_keypair().unwrap();
5502        let (bind1, rev1, bind2, rev2) = {
5503            let bind1 = signature::SignatureBuilder::new(SignatureType::DirectKey)
5504                .set_features(Features::sequoia()).unwrap()
5505                .set_key_flags(KeyFlags::empty()).unwrap()
5506                .set_signature_creation_time(t1).unwrap()
5507                .set_key_validity_period(Some(time::Duration::new(10 * 52 * 7 * 24 * 60 * 60, 0))).unwrap()
5508                .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
5509                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5510
5511            let rev1 = signature::SignatureBuilder::new(SignatureType::KeyRevocation)
5512                .set_signature_creation_time(t2).unwrap()
5513                .set_reason_for_revocation(ReasonForRevocation::KeySuperseded,
5514                                           &b""[..]).unwrap()
5515                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5516
5517            let bind2 = signature::SignatureBuilder::new(SignatureType::DirectKey)
5518                .set_features(Features::sequoia()).unwrap()
5519                .set_key_flags(KeyFlags::empty()).unwrap()
5520                .set_signature_creation_time(t3).unwrap()
5521                .set_key_validity_period(Some(time::Duration::new(10 * 52 * 7 * 24 * 60 * 60, 0))).unwrap()
5522                .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
5523                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5524
5525            let rev2 = signature::SignatureBuilder::new(SignatureType::KeyRevocation)
5526                .set_signature_creation_time(t4).unwrap()
5527                .set_reason_for_revocation(ReasonForRevocation::KeyCompromised,
5528                                           &b""[..]).unwrap()
5529                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5530
5531            (bind1, rev1, bind2, rev2)
5532        };
5533        let pk : key::PublicKey = key.into();
5534        let cert = Cert::try_from(vec![
5535            pk.into(),
5536            bind1.into(),
5537            bind2.into(),
5538            rev1.into()
5539        ]).unwrap();
5540
5541        let f1: f32 = rng().sample(Open01);
5542        let f2: f32 = rng().sample(Open01);
5543        let f3: f32 = rng().sample(Open01);
5544        let f4: f32 = rng().sample(Open01);
5545        let te1 = t1 - time::Duration::new((60. * 60. * 24. * 300.0 * f1) as u64, 0);
5546        let t12 = t1 + time::Duration::new((60. * 60. * 24. * 300.0 * f2) as u64, 0);
5547        let t23 = t2 + time::Duration::new((60. * 60. * 24. * 300.0 * f3) as u64, 0);
5548        let t34 = t3 + time::Duration::new((60. * 60. * 24. * 300.0 * f4) as u64, 0);
5549
5550        assert_eq!(cert.revocation_status(p, te1), RevocationStatus::NotAsFarAsWeKnow);
5551        assert_eq!(cert.revocation_status(p, t12), RevocationStatus::NotAsFarAsWeKnow);
5552        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t23));
5553        assert_eq!(cert.revocation_status(p, t34), RevocationStatus::NotAsFarAsWeKnow);
5554
5555        // Merge in the hard revocation.
5556        let cert = cert.insert_packets(rev2).unwrap().0;
5557        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, te1));
5558        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t12));
5559        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t23));
5560        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t34));
5561        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t4));
5562        assert_match!(RevocationStatus::Revoked(_)
5563                      = cert.revocation_status(p, crate::now()));
5564    }
5565
5566    #[test]
5567    fn key_revoked2() {
5568        tracer!(true, "cert_revoked2", 0);
5569
5570        let p = &P::new();
5571
5572        fn cert_revoked<T>(p: &dyn Policy, cert: &Cert, t: T) -> bool
5573            where T: Into<Option<time::SystemTime>>
5574        {
5575            !matches!(
5576                cert.revocation_status(p, t),
5577                RevocationStatus::NotAsFarAsWeKnow
5578            )
5579        }
5580
5581        fn subkey_revoked<T>(p: &dyn Policy, cert: &Cert, t: T) -> bool
5582            where T: Into<Option<time::SystemTime>>
5583        {
5584            !matches!(
5585                cert.subkeys().next().unwrap().bundle().revocation_status(p, t),
5586                RevocationStatus::NotAsFarAsWeKnow
5587            )
5588        }
5589
5590        let tests : [(&str, Box<dyn Fn(&dyn Policy, &Cert, _) -> bool>); 2] = [
5591            ("cert", Box::new(cert_revoked)),
5592            ("subkey", Box::new(subkey_revoked)),
5593        ];
5594
5595        for (f, revoked) in tests.iter()
5596        {
5597            t!("Checking {} revocation", f);
5598
5599            t!("Normal key");
5600            let cert = Cert::from_bytes(
5601                crate::tests::key(
5602                    &format!("really-revoked-{}-0-public.pgp", f))).unwrap();
5603            let selfsig0 = cert.primary_key().with_policy(p, None).unwrap()
5604                .binding_signature().signature_creation_time().unwrap();
5605
5606            assert!(!revoked(p, &cert, Some(selfsig0)));
5607            assert!(!revoked(p, &cert, None));
5608
5609            t!("Soft revocation");
5610            let cert = cert.merge_public_and_secret(
5611                Cert::from_bytes(
5612                    crate::tests::key(
5613                        &format!("really-revoked-{}-1-soft-revocation.pgp", f))
5614                ).unwrap()).unwrap();
5615            // A soft revocation made after `t` is ignored when
5616            // determining whether the key is revoked at time `t`.
5617            assert!(!revoked(p, &cert, Some(selfsig0)));
5618            assert!(revoked(p, &cert, None));
5619
5620            t!("New self signature");
5621            let cert = cert.merge_public_and_secret(
5622                Cert::from_bytes(
5623                    crate::tests::key(
5624                        &format!("really-revoked-{}-2-new-self-sig.pgp", f))
5625                ).unwrap()).unwrap();
5626            assert!(!revoked(p, &cert, Some(selfsig0)));
5627            // Newer self-sig override older soft revocations.
5628            assert!(!revoked(p, &cert, None));
5629
5630            t!("Hard revocation");
5631            let cert = cert.merge_public_and_secret(
5632                Cert::from_bytes(
5633                    crate::tests::key(
5634                        &format!("really-revoked-{}-3-hard-revocation.pgp", f))
5635                ).unwrap()).unwrap();
5636            // Hard revocations trump all.
5637            assert!(revoked(p, &cert, Some(selfsig0)));
5638            assert!(revoked(p, &cert, None));
5639
5640            t!("New self signature");
5641            let cert = cert.merge_public_and_secret(
5642                Cert::from_bytes(
5643                    crate::tests::key(
5644                        &format!("really-revoked-{}-4-new-self-sig.pgp", f))
5645                ).unwrap()).unwrap();
5646            assert!(revoked(p, &cert, Some(selfsig0)));
5647            assert!(revoked(p, &cert, None));
5648        }
5649    }
5650
5651    #[test]
5652    fn userid_revoked2() {
5653        fn check_userids<T>(p: &dyn Policy, cert: &Cert, revoked: bool, t: T)
5654            where T: Into<Option<time::SystemTime>>, T: Copy
5655        {
5656            assert_match!(RevocationStatus::NotAsFarAsWeKnow
5657                          = cert.revocation_status(p, None));
5658
5659            let mut slim_shady = false;
5660            let mut eminem = false;
5661            for b in cert.userids().with_policy(p, t) {
5662                if b.userid().value() == b"Slim Shady" {
5663                    assert!(!slim_shady);
5664                    slim_shady = true;
5665
5666                    if revoked {
5667                        assert_match!(RevocationStatus::Revoked(_)
5668                                      = b.revocation_status());
5669                    } else {
5670                        assert_match!(RevocationStatus::NotAsFarAsWeKnow
5671                                      = b.revocation_status());
5672                    }
5673                } else {
5674                    assert!(!eminem);
5675                    eminem = true;
5676
5677                    assert_match!(RevocationStatus::NotAsFarAsWeKnow
5678                                  = b.revocation_status());
5679                }
5680            }
5681
5682            assert!(slim_shady);
5683            assert!(eminem);
5684        }
5685
5686        fn check_uas<T>(p: &dyn Policy, cert: &Cert, revoked: bool, t: T)
5687            where T: Into<Option<time::SystemTime>>, T: Copy
5688        {
5689            assert_match!(RevocationStatus::NotAsFarAsWeKnow
5690                          = cert.revocation_status(p, None));
5691
5692            assert_eq!(cert.user_attributes().count(), 1);
5693            let ua = cert.user_attributes().next().unwrap();
5694            if revoked {
5695                assert_match!(RevocationStatus::Revoked(_)
5696                              = ua.revocation_status(p, t));
5697            } else {
5698                assert_match!(RevocationStatus::NotAsFarAsWeKnow
5699                              = ua.revocation_status(p, t));
5700            }
5701        }
5702
5703        tracer!(true, "userid_revoked2", 0);
5704
5705        let p = &P::new();
5706        let tests : [(&str, Box<dyn Fn(&dyn Policy, &Cert, bool, _)>); 2] = [
5707            ("userid", Box::new(check_userids)),
5708            ("user-attribute", Box::new(check_uas)),
5709        ];
5710
5711        for (f, check) in tests.iter()
5712        {
5713            t!("Checking {} revocation", f);
5714
5715            t!("Normal key");
5716            let cert = Cert::from_bytes(
5717                crate::tests::key(
5718                    &format!("really-revoked-{}-0-public.pgp", f))).unwrap();
5719
5720            let now = crate::now();
5721            let selfsig0
5722                = cert.userids().with_policy(p, now).map(|b| {
5723                    b.binding_signature().signature_creation_time().unwrap()
5724                })
5725                .max().unwrap();
5726
5727            check(p, &cert, false, selfsig0);
5728            check(p, &cert, false, now);
5729
5730            // A soft-revocation.
5731            let cert = cert.merge_public_and_secret(
5732                Cert::from_bytes(
5733                    crate::tests::key(
5734                        &format!("really-revoked-{}-1-soft-revocation.pgp", f))
5735                ).unwrap()).unwrap();
5736
5737            check(p, &cert, false, selfsig0);
5738            check(p, &cert, true, now);
5739
5740            // A new self signature.  This should override the soft-revocation.
5741            let cert = cert.merge_public_and_secret(
5742                Cert::from_bytes(
5743                    crate::tests::key(
5744                        &format!("really-revoked-{}-2-new-self-sig.pgp", f))
5745                ).unwrap()).unwrap();
5746
5747            check(p, &cert, false, selfsig0);
5748            check(p, &cert, false, now);
5749
5750            // A hard revocation.  Unlike for Certs, this does NOT trump
5751            // everything.
5752            let cert = cert.merge_public_and_secret(
5753                Cert::from_bytes(
5754                    crate::tests::key(
5755                        &format!("really-revoked-{}-3-hard-revocation.pgp", f))
5756                ).unwrap()).unwrap();
5757
5758            check(p, &cert, false, selfsig0);
5759            check(p, &cert, true, now);
5760
5761            // A newer self signature.
5762            let cert = cert.merge_public_and_secret(
5763                Cert::from_bytes(
5764                    crate::tests::key(
5765                        &format!("really-revoked-{}-4-new-self-sig.pgp", f))
5766                ).unwrap()).unwrap();
5767
5768            check(p, &cert, false, selfsig0);
5769            check(p, &cert, false, now);
5770        }
5771    }
5772
5773    #[test]
5774    fn unrevoked() {
5775        let p = &P::new();
5776        let cert =
5777            Cert::from_bytes(crate::tests::key("un-revoked-userid.pgp")).unwrap();
5778
5779        for uid in cert.userids().with_policy(p, None) {
5780            assert_eq!(uid.revocation_status(), RevocationStatus::NotAsFarAsWeKnow);
5781        }
5782    }
5783
5784    #[test]
5785    fn is_tsk() {
5786        let cert = Cert::from_bytes(
5787            crate::tests::key("already-revoked.pgp")).unwrap();
5788        assert!(! cert.is_tsk());
5789
5790        let cert = Cert::from_bytes(
5791            crate::tests::key("already-revoked-private.pgp")).unwrap();
5792        assert!(cert.is_tsk());
5793    }
5794
5795    #[test]
5796    fn export_only_exports_public_key() {
5797        let cert = Cert::from_bytes(
5798            crate::tests::key("testy-new-private.pgp")).unwrap();
5799        assert!(cert.is_tsk());
5800
5801        let mut v = Vec::new();
5802        cert.serialize(&mut v).unwrap();
5803        let cert = Cert::from_bytes(&v).unwrap();
5804        assert!(! cert.is_tsk());
5805    }
5806
5807    // Make sure that when merging two Certs, the primary key and
5808    // subkeys with and without a private key are merged.
5809    #[test]
5810    fn public_private_merge() {
5811        let (tsk, _) = CertBuilder::general_purpose(Some("foo@example.com"))
5812            .generate().unwrap();
5813        // tsk is now a cert, but it still has its private bits.
5814        assert!(tsk.primary.key().has_secret());
5815        assert!(tsk.is_tsk());
5816        let subkey_count = tsk.subkeys().count();
5817        assert!(subkey_count > 0);
5818        assert!(tsk.subkeys().all(|k| k.key().has_secret()));
5819
5820        // This will write out the tsk as a cert, i.e., without any
5821        // private bits.
5822        let mut cert_bytes = Vec::new();
5823        tsk.serialize(&mut cert_bytes).unwrap();
5824
5825        // Reading it back in, the private bits have been stripped.
5826        let cert = Cert::from_bytes(&cert_bytes[..]).unwrap();
5827        assert!(! cert.primary.key().has_secret());
5828        assert!(!cert.is_tsk());
5829        assert!(cert.subkeys().all(|k| ! k.key().has_secret()));
5830
5831        let merge1 = cert.clone().merge_public_and_secret(tsk.clone()).unwrap();
5832        assert!(merge1.is_tsk());
5833        assert!(merge1.primary.key().has_secret());
5834        assert_eq!(merge1.subkeys().count(), subkey_count);
5835        assert!(merge1.subkeys().all(|k| k.key().has_secret()));
5836
5837        let merge2 = tsk.clone().merge_public_and_secret(cert.clone()).unwrap();
5838        assert!(merge2.is_tsk());
5839        assert!(merge2.primary.key().has_secret());
5840        assert_eq!(merge2.subkeys().count(), subkey_count);
5841        assert!(merge2.subkeys().all(|k| k.key().has_secret()));
5842    }
5843
5844    #[test]
5845    fn issue_120() {
5846        let cert = "
5847-----BEGIN PGP ARMORED FILE-----
5848
5849xcBNBFoVcvoBCACykTKOJddF8SSUAfCDHk86cNTaYnjCoy72rMgWJsrMLnz/V16B
5850J9M7l6nrQ0JMnH2Du02A3w+kNb5q97IZ/M6NkqOOl7uqjyRGPV+XKwt0G5mN/ovg
58518630BZAYS3QzavYf3tni9aikiGH+zTFX5pynTNfYRXNBof3Xfzl92yad2bIt4ITD
5852NfKPvHRko/tqWbclzzEn72gGVggt1/k/0dKhfsGzNogHxg4GIQ/jR/XcqbDFR3RC
5853/JJjnTOUPGsC1y82Xlu8udWBVn5mlDyxkad5laUpWWg17anvczEAyx4TTOVItLSu
585443iPdKHSs9vMXWYID0bg913VusZ2Ofv690nDABEBAAHNJFRlc3R5IE1jVGVzdGZh
5855Y2UgPHRlc3R5QGV4YW1wbGUub3JnPsLAlAQTAQgAPhYhBD6Id8h3J0aSl1GJ9dA/
5856b4ZSJv6LBQJaFXL6AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ
5857ENA/b4ZSJv6Lxo8H/1XMt+Nqa6e0SG/up3ypKe5nplA0p/9j/s2EIsP8S8uPUd+c
5858WS17XOmPwkNDmHeL3J6hzwL74NlYSLEtyf7WoOV74xAKQA9WkqaKPHCtpll8aFWA
5859ktQDLWTPeKuUuSlobAoRtO17ZmheSQzmm7JYt4Ahkxt3agqGT05OsaAey6nIKqpq
5860ArokvdHTZ7AFZeSJIWmuCoT9M1lo3LAtLnRGOhBMJ5dDIeOwflJwNBXlJVi4mDPK
5861+fumV0MbSPvZd1/ivFjSpQyudWWtv1R1nAK7+a4CPTGxPvAQkLtRsL/V+Q7F3BJG
5862jAn4QVx8p4t3NOPuNgcoZpLBE3sc4Nfs5/CphMLHwE0EWhVy+gEIALSpjYD+tuWC
5863rj6FGP6crQjQzVlH+7axoM1ooTwiPs4fzzt2iLw3CJyDUviM5F9ZBQTei635RsAR
5864a/CJTSQYAEU5yXXxhoe0OtwnuvsBSvVT7Fox3pkfNTQmwMvkEbodhfKpqBbDKCL8
5865f5A8Bb7aISsLf0XRHWDkHVqlz8LnOR3f44wEWiTeIxLc8S1QtwX/ExyW47oPsjs9
5866ShCmwfSpcngH/vGBRTO7WeI54xcAtKSm/20B/MgrUl5qFo17kUWot2C6KjuZKkHk
58673WZmJwQz+6rTB11w4AXt8vKkptYQCkfat2FydGpgRO5dVg6aWNJefOJNkC7MmlzC
5868ZrrAK8FJ6jcAEQEAAcLAdgQYAQgAIBYhBD6Id8h3J0aSl1GJ9dA/b4ZSJv6LBQJa
5869FXL6AhsMAAoJENA/b4ZSJv6Lt7kH/jPr5wg8lcamuLj4lydYiLttvvTtDTlD1TL+
5870IfwVARB/ruoerlEDr0zX1t3DCEcvJDiZfOqJbXtHt70+7NzFXrYxfaNFmikMgSQT
5871XqHrMQho4qpseVOeJPWGzGOcrxCdw/ZgrWbkDlAU5KaIvk+M4wFPivjbtW2Ro2/F
5872J4I/ZHhJlIPmM+hUErHC103b08pBENXDQlXDma7LijH5kWhyfF2Ji7Ft0EjghBaW
5873AeGalQHjc5kAZu5R76Mwt06MEQ/HL1pIvufTFxkr/SzIv8Ih7Kexb0IrybmfD351
5874Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g=
5875=1Vzu
5876-----END PGP ARMORED FILE-----
5877";
5878        assert!(Cert::from_bytes(cert).is_err());
5879    }
5880
5881    #[test]
5882    fn missing_uids() {
5883        let (cert, _) = CertBuilder::new()
5884            .add_userid("test1@example.com")
5885            .add_userid("test2@example.com")
5886            .add_transport_encryption_subkey()
5887            .add_certification_subkey()
5888            .generate().unwrap();
5889        assert_eq!(cert.subkeys().count(), 2);
5890        let pile = cert
5891            .into_packet_pile()
5892            .into_children()
5893            .filter(|pkt| {
5894                match pkt {
5895                    &Packet::PublicKey(_) | &Packet::PublicSubkey(_)
5896                    | &Packet::SecretKey(_) | &Packet::SecretSubkey(_) => true,
5897                    &Packet::Signature(ref sig) => {
5898                        sig.typ() == SignatureType::DirectKey
5899                            || sig.typ() == SignatureType::SubkeyBinding
5900                    }
5901                    e => {
5902                        eprintln!("{:?}", e);
5903                        false
5904                    }
5905                }
5906            })
5907        .collect::<Vec<_>>();
5908        eprintln!("parse back");
5909        let cert = Cert::try_from(pile).unwrap();
5910
5911        assert_eq!(cert.subkeys().count(), 2);
5912    }
5913
5914    #[test]
5915    fn signature_order() {
5916        let p = &P::new();
5917        let neal = Cert::from_bytes(crate::tests::key("neal.pgp")).unwrap();
5918
5919        // This test is useless if we don't have some lists with more
5920        // than one signature.
5921        let mut cmps = 0;
5922
5923        for uid in neal.userids() {
5924            for sigs in [
5925                uid.self_signatures().collect::<Vec<_>>(),
5926                uid.certifications().collect::<Vec<_>>(),
5927                uid.self_revocations().collect::<Vec<_>>(),
5928                uid.other_revocations().collect::<Vec<_>>()
5929            ].iter() {
5930                for sigs in sigs.windows(2) {
5931                    cmps += 1;
5932                    assert!(sigs[0].signature_creation_time()
5933                            >= sigs[1].signature_creation_time());
5934                }
5935            }
5936
5937            // Make sure we return the most recent first.
5938            assert_eq!(uid.self_signatures().next().unwrap(),
5939                       uid.binding_signature(p, None).unwrap());
5940        }
5941
5942        assert!(cmps > 0);
5943    }
5944
5945    #[test]
5946    fn cert_reject_keyrings() {
5947        let mut keyring = Vec::new();
5948        keyring.extend_from_slice(crate::tests::key("neal.pgp"));
5949        keyring.extend_from_slice(crate::tests::key("neal.pgp"));
5950        assert!(Cert::from_bytes(&keyring).is_err());
5951    }
5952
5953    #[test]
5954    fn primary_userid() {
5955        // 'really-revoked-userid' has two user ids.  One of them is
5956        // revoked and then restored.  Neither of the user ids has the
5957        // primary userid bit set.
5958        //
5959        // This test makes sure that Cert::primary_userid prefers
5960        // unrevoked user ids to revoked user ids, even if the latter
5961        // have newer self signatures.
5962
5963        let p = &P::new();
5964        let cert = Cert::from_bytes(
5965            crate::tests::key("really-revoked-userid-0-public.pgp")).unwrap();
5966
5967        let now = crate::now();
5968        let selfsig0
5969            = cert.userids().with_policy(p, now).map(|b| {
5970                b.binding_signature().signature_creation_time().unwrap()
5971            })
5972            .max().unwrap();
5973
5974        // The self-sig for:
5975        //
5976        //   Slim Shady: 2019-09-14T14:21
5977        //   Eminem:     2019-09-14T14:22
5978        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
5979                   .primary_userid().unwrap().userid().value(),
5980                   b"Eminem");
5981        assert_eq!(cert.with_policy(p, now).unwrap()
5982                   .primary_userid().unwrap().userid().value(),
5983                   b"Eminem");
5984
5985        // A soft-revocation for "Slim Shady".
5986        let cert = cert.merge_public_and_secret(
5987            Cert::from_bytes(
5988                crate::tests::key("really-revoked-userid-1-soft-revocation.pgp")
5989            ).unwrap()).unwrap();
5990
5991        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
5992                   .primary_userid().unwrap().userid().value(),
5993                   b"Eminem");
5994        assert_eq!(cert.with_policy(p, now).unwrap()
5995                   .primary_userid().unwrap().userid().value(),
5996                   b"Eminem");
5997
5998        // A new self signature for "Slim Shady".  This should
5999        // override the soft-revocation.
6000        let cert = cert.merge_public_and_secret(
6001            Cert::from_bytes(
6002                crate::tests::key("really-revoked-userid-2-new-self-sig.pgp")
6003            ).unwrap()).unwrap();
6004
6005        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6006                   .primary_userid().unwrap().userid().value(),
6007                   b"Eminem");
6008        assert_eq!(cert.with_policy(p, now).unwrap()
6009                   .primary_userid().unwrap().userid().value(),
6010                   b"Slim Shady");
6011
6012        // A hard revocation for "Slim Shady".
6013        let cert = cert.merge_public_and_secret(
6014            Cert::from_bytes(
6015                crate::tests::key("really-revoked-userid-3-hard-revocation.pgp")
6016            ).unwrap()).unwrap();
6017
6018        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6019                   .primary_userid().unwrap().userid().value(),
6020                   b"Eminem");
6021        assert_eq!(cert.with_policy(p, now).unwrap()
6022                   .primary_userid().unwrap().userid().value(),
6023                   b"Eminem");
6024
6025        // A newer self signature for "Slim Shady". Unlike for Certs, this
6026        // does NOT trump everything.
6027        let cert = cert.merge_public_and_secret(
6028            Cert::from_bytes(
6029                crate::tests::key("really-revoked-userid-4-new-self-sig.pgp")
6030            ).unwrap()).unwrap();
6031
6032        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6033                   .primary_userid().unwrap().userid().value(),
6034                   b"Eminem");
6035        assert_eq!(cert.with_policy(p, now).unwrap()
6036                   .primary_userid().unwrap().userid().value(),
6037                   b"Slim Shady");
6038
6039        // Play with the primary user id flag.
6040
6041        let cert = Cert::from_bytes(
6042            crate::tests::key("primary-key-0-public.pgp")).unwrap();
6043        let selfsig0
6044            = cert.userids().with_policy(p, now).map(|b| {
6045                b.binding_signature().signature_creation_time().unwrap()
6046            })
6047            .max().unwrap();
6048
6049        // There is only a single User ID.
6050        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6051                   .primary_userid().unwrap().userid().value(),
6052                   b"aaaaa");
6053        assert_eq!(cert.with_policy(p, now).unwrap()
6054                   .primary_userid().unwrap().userid().value(),
6055                   b"aaaaa");
6056
6057
6058        // Add a second user id.  Since neither is marked primary, the
6059        // newer one should be considered primary.
6060        let cert = cert.merge_public_and_secret(
6061            Cert::from_bytes(
6062                crate::tests::key("primary-key-1-add-userid-bbbbb.pgp")
6063            ).unwrap()).unwrap();
6064
6065        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6066                   .primary_userid().unwrap().userid().value(),
6067                   b"aaaaa");
6068        assert_eq!(cert.with_policy(p, now).unwrap()
6069                   .primary_userid().unwrap().userid().value(),
6070                   b"bbbbb");
6071
6072        // Mark aaaaa as primary.  It is now primary and the newest one.
6073        let cert = cert.merge_public_and_secret(
6074            Cert::from_bytes(
6075                crate::tests::key("primary-key-2-make-aaaaa-primary.pgp")
6076            ).unwrap()).unwrap();
6077
6078        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6079                   .primary_userid().unwrap().userid().value(),
6080                   b"aaaaa");
6081        assert_eq!(cert.with_policy(p, now).unwrap()
6082                   .primary_userid().unwrap().userid().value(),
6083                   b"aaaaa");
6084
6085        // Update the preferences on bbbbb.  It is now the newest, but
6086        // it is not marked as primary.
6087        let cert = cert.merge_public_and_secret(
6088            Cert::from_bytes(
6089                crate::tests::key("primary-key-3-make-bbbbb-new-self-sig.pgp")
6090            ).unwrap()).unwrap();
6091
6092        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6093                   .primary_userid().unwrap().userid().value(),
6094                   b"aaaaa");
6095        assert_eq!(cert.with_policy(p, now).unwrap()
6096                   .primary_userid().unwrap().userid().value(),
6097                   b"aaaaa");
6098
6099        // Mark bbbbb as primary.  It is now the newest and marked as
6100        // primary.
6101        let cert = cert.merge_public_and_secret(
6102            Cert::from_bytes(
6103                crate::tests::key("primary-key-4-make-bbbbb-primary.pgp")
6104            ).unwrap()).unwrap();
6105
6106        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6107                   .primary_userid().unwrap().userid().value(),
6108                   b"aaaaa");
6109        assert_eq!(cert.with_policy(p, now).unwrap()
6110                   .primary_userid().unwrap().userid().value(),
6111                   b"bbbbb");
6112
6113        // Update the preferences on aaaaa.  It is now has the newest
6114        // self sig, but that self sig does not say that it is
6115        // primary.
6116        let cert = cert.merge_public_and_secret(
6117            Cert::from_bytes(
6118                crate::tests::key("primary-key-5-make-aaaaa-self-sig.pgp")
6119            ).unwrap()).unwrap();
6120
6121        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6122                   .primary_userid().unwrap().userid().value(),
6123                   b"aaaaa");
6124        assert_eq!(cert.with_policy(p, now).unwrap()
6125                   .primary_userid().unwrap().userid().value(),
6126                   b"bbbbb");
6127
6128        // Hard revoke aaaaa.  Unlike with Certs, a hard revocation is
6129        // not treated specially.
6130        let cert = cert.merge_public_and_secret(
6131            Cert::from_bytes(
6132                crate::tests::key("primary-key-6-revoked-aaaaa.pgp")
6133            ).unwrap()).unwrap();
6134
6135        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6136                   .primary_userid().unwrap().userid().value(),
6137                   b"aaaaa");
6138        assert_eq!(cert.with_policy(p, now).unwrap()
6139                   .primary_userid().unwrap().userid().value(),
6140                   b"bbbbb");
6141    }
6142
6143    #[test]
6144    fn binding_signature_lookup() {
6145        // Check that searching for the right binding signature works
6146        // even when there are signatures with the same time.
6147
6148        use crate::types::Features;
6149        use crate::packet::key::Key6;
6150
6151        let p = &P::new();
6152
6153        let a_sec = time::Duration::new(1, 0);
6154        let time_zero = time::UNIX_EPOCH;
6155
6156        let t1 = time::UNIX_EPOCH + time::Duration::new(946681200, 0);  // 2000-1-1
6157        let t2 = time::UNIX_EPOCH + time::Duration::new(978303600, 0);  // 2001-1-1
6158        let t3 = time::UNIX_EPOCH + time::Duration::new(1009839600, 0); // 2002-1-1
6159        let t4 = time::UNIX_EPOCH + time::Duration::new(1041375600, 0); // 2003-1-1
6160
6161        let mut key: key::SecretKey
6162            = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
6163        key.set_creation_time(t1).unwrap();
6164        let mut pair = key.clone().into_keypair().unwrap();
6165        let pk : key::PublicKey = key.clone().into();
6166        let mut cert = Cert::try_from(vec![
6167            pk.into(),
6168        ]).unwrap();
6169        let uid: UserID = "foo@example.org".into();
6170        let sig = uid.certify(&mut pair, &cert,
6171                              SignatureType::PositiveCertification,
6172                              None,
6173                              t1).unwrap();
6174        cert = cert.insert_packets(
6175            vec![Packet::from(uid), sig.into()]).unwrap().0;
6176
6177        const N: usize = 5;
6178        for (t, offset) in &[ (t2, 0), (t4, 0), (t3, 1 * N), (t1, 3 * N) ] {
6179            for i in 0..N {
6180                let binding = signature::SignatureBuilder::new(SignatureType::DirectKey)
6181                    .set_features(Features::sequoia()).unwrap()
6182                    .set_key_flags(KeyFlags::empty()).unwrap()
6183                    .set_signature_creation_time(t1).unwrap()
6184                    // Vary this...
6185                    .set_key_validity_period(Some(
6186                        time::Duration::new((1 + i as u64) * 24 * 60 * 60, 0)))
6187                    .unwrap()
6188                    .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
6189                    .set_signature_creation_time(*t).unwrap()
6190                    .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
6191
6192                let binding : Packet = binding.into();
6193
6194                cert = cert.insert_packets(binding).unwrap().0;
6195                // A time that matches multiple signatures.
6196                let direct_signatures =
6197                    cert.primary_key().bundle().self_signatures()
6198                    .collect::<Vec<_>>();
6199                assert_eq!(cert.primary_key().with_policy(p, *t).unwrap()
6200                           .direct_key_signature().ok(),
6201                           direct_signatures.get(*offset).cloned());
6202                // A time that doesn't match any signature.
6203                assert_eq!(cert.primary_key().with_policy(p, *t + a_sec).unwrap()
6204                           .direct_key_signature().ok(),
6205                           direct_signatures.get(*offset).cloned());
6206
6207                // The current time, which should use the first signature.
6208                assert_eq!(cert.primary_key().with_policy(p, None).unwrap()
6209                           .direct_key_signature().ok(),
6210                           direct_signatures.get(0).cloned());
6211
6212                // The beginning of time, which should return no
6213                // binding signatures.
6214                assert!(cert.primary_key().with_policy(p, time_zero).is_err());
6215            }
6216        }
6217    }
6218
6219    #[test]
6220    fn keysigning_party() {
6221        use crate::packet::signature;
6222
6223        for cs in &[ CipherSuite::Cv25519,
6224                     CipherSuite::Cv448,
6225                     CipherSuite::P256,
6226                     CipherSuite::P384,
6227                     CipherSuite::P521,
6228                     CipherSuite::RSA2k ]
6229        {
6230            if cs.is_supported().is_err() {
6231                eprintln!("Skipping {:?} because it is not supported.", cs);
6232                continue;
6233            }
6234
6235            let (alice, _) = CertBuilder::new()
6236                .set_cipher_suite(*cs)
6237                .add_userid("alice@foo.com")
6238                .generate().unwrap();
6239
6240            let (bob, _) = CertBuilder::new()
6241                .set_cipher_suite(*cs)
6242                .add_userid("bob@bar.com")
6243                .add_signing_subkey()
6244                .generate().unwrap();
6245
6246            assert_eq!(bob.userids().len(), 1);
6247            let bob_userid_binding = bob.userids().next().unwrap();
6248            assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com");
6249
6250            let sig_template
6251                = signature::SignatureBuilder::new(SignatureType::GenericCertification)
6252                      .set_trust_signature(255, 120)
6253                      .unwrap();
6254
6255            // Have alice certify the binding "bob@bar.com" and bob's key.
6256            let alice_certifies_bob
6257                = bob_userid_binding.userid().bind(
6258                    &mut alice.primary_key().key().clone().parts_into_secret()
6259                        .unwrap().into_keypair().unwrap(),
6260                    &bob,
6261                    sig_template).unwrap();
6262
6263            let bob = bob.insert_packets(alice_certifies_bob.clone()).unwrap().0;
6264
6265            // Make sure the certification is merged, and put in the right
6266            // place.
6267            assert_eq!(bob.userids().len(), 1);
6268            let bob_userid_binding = bob.userids().next().unwrap();
6269            assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com");
6270
6271            // Canonicalizing Bob's cert without having Alice's key
6272            // has to resort to a heuristic to order third party
6273            // signatures.  However, since we know the signature's
6274            // type (GenericCertification), we know that it can only
6275            // go to the only userid, so there is no ambiguity in this
6276            // case.
6277            assert_eq!(bob_userid_binding.certifications().collect::<Vec<_>>(),
6278                       vec![&alice_certifies_bob]);
6279
6280            // Make sure the certification is correct.
6281            alice_certifies_bob
6282                .verify_userid_binding(alice.primary_key().key(),
6283                                       bob.primary_key().key(),
6284                                       bob_userid_binding.userid()).unwrap();
6285        }
6286   }
6287
6288    #[test]
6289    fn decrypt_encrypt_secrets() -> Result<()> {
6290        let p: crate::crypto::Password = "streng geheim".into();
6291        let (mut cert, _) = CertBuilder::new()
6292            .add_transport_encryption_subkey()
6293            .set_password(Some(p.clone()))
6294            .generate()?;
6295        assert_eq!(cert.keys().secret().count(), 2);
6296        assert_eq!(cert.keys().unencrypted_secret().count(), 0);
6297
6298        for (i, ka) in cert.clone().keys().secret().enumerate() {
6299            let key = ka.key().clone().decrypt_secret(&p)?;
6300            cert = if i == 0 {
6301                cert.insert_packets(key.role_into_primary())?.0
6302            } else {
6303                cert.insert_packets(key.role_into_subordinate())?.0
6304            };
6305            assert_eq!(cert.keys().secret().count(), 2);
6306            assert_eq!(cert.keys().unencrypted_secret().count(), i + 1);
6307        }
6308
6309        assert_eq!(cert.keys().secret().count(), 2);
6310        assert_eq!(cert.keys().unencrypted_secret().count(), 2);
6311
6312        for (i, ka) in cert.clone().keys().secret().enumerate() {
6313            let key = ka.key().clone().encrypt_secret(&p)?;
6314            cert = if i == 0 {
6315                cert.insert_packets(key.role_into_primary())?.0
6316            } else {
6317                cert.insert_packets(key.role_into_subordinate())?.0
6318            };
6319            assert_eq!(cert.keys().secret().count(), 2);
6320            assert_eq!(cert.keys().unencrypted_secret().count(), 2 - 1 - i);
6321        }
6322
6323        assert_eq!(cert.keys().secret().count(), 2);
6324        assert_eq!(cert.keys().unencrypted_secret().count(), 0);
6325        Ok(())
6326    }
6327
6328    /// Tests that Cert:.into_packets() and Cert::serialize(..) agree.
6329    #[test]
6330    fn test_into_packets() -> Result<()> {
6331        use crate::serialize::SerializeInto;
6332
6333        let dkg = Cert::from_bytes(crate::tests::key("dkg.pgp"))?;
6334        let mut buf = Vec::new();
6335        for p in dkg.clone().into_packets() {
6336            p.serialize(&mut buf)?;
6337        }
6338        let dkg = dkg.to_vec()?;
6339        #[expect(clippy::overly_complex_bool_expr)]
6340        if false && buf != dkg {
6341            std::fs::write("/tmp/buf", &buf)?;
6342            std::fs::write("/tmp/dkg", &dkg)?;
6343        }
6344        assert_eq!(buf, dkg);
6345        Ok(())
6346    }
6347
6348    #[test]
6349    fn test_canonicalization() -> Result<()> {
6350        let p = crate::policy::StandardPolicy::new();
6351
6352        let primary: Key<_, key::PrimaryRole> =
6353            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6354        let cert = Cert::try_from(vec![primary.into()])?;
6355
6356        // We now add components without binding signatures.  They
6357        // should be kept, be enumerable, but ignored if a policy is
6358        // applied.
6359
6360        // Add a bare userid.
6361        let uid = UserID::from("foo@example.org");
6362        let cert = cert.insert_packets(uid)?.0;
6363        assert_eq!(cert.userids().count(), 1);
6364        assert_eq!(cert.userids().with_policy(&p, None).count(), 0);
6365
6366        // Add a bare user attribute.
6367        use packet::user_attribute::{Subpacket, Image};
6368        let ua = UserAttribute::new(&[
6369            Subpacket::Image(
6370                Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
6371        ])?;
6372        let cert = cert.insert_packets(ua)?.0;
6373        assert_eq!(cert.user_attributes().count(), 1);
6374        assert_eq!(cert.user_attributes().with_policy(&p, None).count(), 0);
6375
6376        // Add a bare signing subkey.
6377        let signing_subkey: Key<_, key::SubordinateRole> =
6378            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6379        let _signing_subkey_pair = signing_subkey.clone().into_keypair()?;
6380        let cert = cert.insert_packets(signing_subkey)?.0;
6381        assert_eq!(cert.keys().subkeys().count(), 1);
6382        assert_eq!(cert.keys().subkeys().with_policy(&p, None).count(), 0);
6383
6384        // Add a component that Sequoia doesn't understand.
6385        let mut fake_key = packet::Unknown::new(
6386            packet::Tag::PublicSubkey, anyhow::anyhow!("fake key"));
6387        fake_key.set_body("fake key".into());
6388        let cert = cert.insert_packets(vec![Packet::from(fake_key)])?.0;
6389        assert_eq!(cert.unknowns().count(), 1);
6390        assert_eq!(cert.unknowns().next().unwrap().unknown().tag(),
6391                   packet::Tag::PublicSubkey);
6392
6393        Ok(())
6394    }
6395
6396    #[test]
6397    #[allow(deprecated)]
6398    fn canonicalize_with_v3_sig() -> Result<()> {
6399        skip_unless_supported!(crate::types::PublicKeyAlgorithm::DSA);
6400
6401        // This test relies on being able to validate SHA-1
6402        // signatures.  The standard policy rejects SHA-1.  So, use a
6403        // custom policy.
6404        let p = &P::new();
6405        let sha1 =
6406            p.hash_cutoff(
6407                HashAlgorithm::SHA1, HashAlgoSecurity::CollisionResistance)
6408            .unwrap();
6409        let p = &P::at(sha1 - std::time::Duration::from_secs(1));
6410
6411        let cert = Cert::from_bytes(
6412            crate::tests::key("eike-v3-v4.pgp"))?;
6413        dbg!(&cert);
6414        assert_eq!(cert.userids()
6415                   .with_policy(p, None)
6416                   .count(), 1);
6417        Ok(())
6418    }
6419
6420    /// Asserts that key expiration times on direct key signatures are
6421    /// honored.
6422    #[test]
6423    fn issue_215() {
6424        let p = &P::new();
6425         let cert = Cert::from_bytes(crate::tests::key(
6426            "issue-215-expiration-on-direct-key-sig.pgp")).unwrap();
6427        assert_match!(
6428            Error::Expired(_)
6429                = cert.with_policy(p, None).unwrap().alive()
6430                .unwrap_err().downcast().unwrap());
6431        assert_match!(
6432            Error::Expired(_)
6433                = cert.primary_key().with_policy(p, None).unwrap()
6434                    .alive().unwrap_err().downcast().unwrap());
6435    }
6436
6437    /// Tests that secrets are kept when merging.
6438    #[test]
6439    fn merge_keeps_secrets() -> Result<()> {
6440        let (cert_s, _) =
6441            CertBuilder::general_purpose(Some("uid")).generate()?;
6442        let cert_p = cert_s.clone().strip_secret_key_material();
6443
6444        // Merge key into cert.
6445        let cert = cert_p.clone().merge_public_and_secret(cert_s.clone())?;
6446        assert!(cert.keys().all(|ka| ka.has_secret()));
6447
6448        // Merge cert into key.
6449        let cert = cert_s.clone().merge_public_and_secret(cert_p.clone())?;
6450        assert!(cert.keys().all(|ka| ka.has_secret()));
6451
6452        Ok(())
6453    }
6454
6455    /// Tests that secrets that are merged in are preferred to
6456    /// existing secrets.
6457    #[test]
6458    fn merge_prefers_merged_in_secrets() -> Result<()> {
6459        let pw: crate::crypto::Password = "foo".into();
6460        let (cert_encrypted_secrets, _) =
6461            CertBuilder::general_purpose(Some("uid"))
6462            .set_password(Some(pw.clone()))
6463            .generate()?;
6464
6465        let mut cert_plain_secrets = cert_encrypted_secrets.clone();
6466        for ka in cert_encrypted_secrets.keys().secret() {
6467            assert!(! ka.key().has_unencrypted_secret());
6468            let key = ka.key().clone().decrypt_secret(&pw)?;
6469            assert!(key.has_unencrypted_secret());
6470
6471            let key: Packet = if ka.primary() {
6472                key.role_into_primary().into()
6473            } else {
6474                key.role_into_subordinate().into()
6475            };
6476
6477            cert_plain_secrets =
6478                cert_plain_secrets.insert_packets(vec![key])?.0;
6479        }
6480        assert!(
6481            cert_plain_secrets.keys().all(|ka| ka.key().has_unencrypted_secret()));
6482
6483        // Merge unencrypted secrets into encrypted secrets.
6484        let cert = cert_encrypted_secrets.clone().merge_public_and_secret(
6485            cert_plain_secrets.clone())?;
6486        assert!(cert.keys().all(|ka| ka.key().has_unencrypted_secret()));
6487
6488        // Merge encrypted secrets into unencrypted secrets.
6489        let cert = cert_plain_secrets.clone().merge_public_and_secret(
6490            cert_encrypted_secrets.clone())?;
6491        assert!(cert.keys().all(|ka| ka.has_secret()
6492                                && ! ka.key().has_unencrypted_secret()));
6493
6494        Ok(())
6495    }
6496
6497    /// Tests that secrets are kept when canonicalizing.
6498    #[test]
6499    fn canonicalizing_keeps_secrets() -> Result<()> {
6500        let primary: Key<_, key::PrimaryRole> =
6501            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6502        let mut primary_pair = primary.clone().into_keypair()?;
6503        let cert = Cert::try_from(vec![primary.clone().into()])?;
6504
6505        let subkey_sec: Key<_, key::SubordinateRole> =
6506            key::Key6::generate_ecc(false, Curve::Cv25519)?.into();
6507        let subkey_pub = subkey_sec.clone().take_secret().0;
6508        let builder = signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
6509            .set_key_flags(KeyFlags::empty()
6510                           .set_transport_encryption())?;
6511        let binding = subkey_sec.bind(&mut primary_pair, &cert, builder)?;
6512
6513        let cert = Cert::try_from(vec![
6514            primary.clone().into(),
6515            subkey_pub.clone().into(),
6516            binding.clone().into(),
6517            subkey_sec.clone().into(),
6518            binding.clone().into(),
6519        ])?;
6520        assert_eq!(cert.keys().subkeys().count(), 1);
6521        assert_eq!(cert.keys().unencrypted_secret().subkeys().count(), 1);
6522
6523        let cert = Cert::try_from(vec![
6524            primary.clone().into(),
6525            subkey_sec.clone().into(),
6526            binding.clone().into(),
6527            subkey_pub.clone().into(),
6528            binding.clone().into(),
6529        ])?;
6530        assert_eq!(cert.keys().subkeys().count(), 1);
6531        assert_eq!(cert.keys().unencrypted_secret().subkeys().count(), 1);
6532        Ok(())
6533    }
6534
6535    /// Demonstrates that subkeys are kept if a userid is later added
6536    /// without any keyflags.
6537    #[test]
6538    fn issue_361() -> Result<()> {
6539        let (cert, _) = CertBuilder::new()
6540            .add_transport_encryption_subkey()
6541            .generate()?;
6542        let p = &P::new();
6543        let cert_at = cert.with_policy(p,
6544                                       cert.primary_key().key().creation_time()
6545                                       + time::Duration::new(300, 0))
6546            .unwrap();
6547        assert_eq!(cert_at.userids().count(), 0);
6548        assert_eq!(cert_at.keys().count(), 2);
6549
6550        let mut primary_pair = cert.primary_key().key().clone()
6551            .parts_into_secret()?.into_keypair()?;
6552        let uid: UserID = "foo@example.org".into();
6553        let sig = uid.bind(
6554            &mut primary_pair, &cert,
6555            signature::SignatureBuilder::new(SignatureType::PositiveCertification))?;
6556        let cert = cert.insert_packets(vec![
6557            Packet::from(uid),
6558            sig.into(),
6559        ])?.0;
6560
6561        let cert_at = cert.with_policy(p,
6562                                       cert.primary_key().key().creation_time()
6563                                       + time::Duration::new(300, 0))
6564            .unwrap();
6565        assert_eq!(cert_at.userids().count(), 1);
6566        assert_eq!(cert_at.keys().count(), 2);
6567        Ok(())
6568    }
6569
6570    /// Demonstrates that binding signatures are considered valid even
6571    /// if the primary key is not marked as certification-capable.
6572    #[test]
6573    fn issue_321() -> Result<()> {
6574        let cert = Cert::from_bytes(
6575            crate::tests::file("contrib/pep/pEpkey-netpgp.asc"))?;
6576        assert_eq!(cert.userids().count(), 1);
6577        assert_eq!(cert.keys().count(), 1);
6578
6579        let mut p = P::new();
6580        p.accept_hash(HashAlgorithm::SHA1);
6581        let cert_at = cert.with_policy(&p, cert.primary_key().key().creation_time())
6582            .unwrap();
6583        assert_eq!(cert_at.userids().count(), 1);
6584        assert_eq!(cert_at.keys().count(), 1);
6585        Ok(())
6586    }
6587
6588    #[test]
6589    fn policy_uri_some() -> Result<()> {
6590        use crate::packet::prelude::SignatureBuilder;
6591        use crate::policy::StandardPolicy;
6592
6593        let p = &StandardPolicy::new();
6594
6595        let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
6596
6597        let sig = SignatureBuilder::from(
6598            alice
6599            .with_policy(p, None)?
6600            .direct_key_signature().expect("Direct key signature")
6601            .clone()
6602        )
6603            .set_policy_uri("https://example.org/~alice/signing-policy.txt")?;
6604        assert_eq!(sig.policy_uri(), Some("https://example.org/~alice/signing-policy.txt".as_bytes()));
6605        Ok(())
6606    }
6607
6608    #[test]
6609    fn policy_uri_none() -> Result<()> {
6610        use crate::packet::prelude::SignatureBuilder;
6611        use crate::policy::StandardPolicy;
6612
6613        let p = &StandardPolicy::new();
6614
6615        let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
6616
6617        let sig = SignatureBuilder::from(
6618            alice
6619            .with_policy(p, None)?
6620            .direct_key_signature().expect("Direct key signature")
6621            .clone()
6622        );
6623        assert_eq!(sig.policy_uri(), None);
6624        Ok(())
6625    }
6626
6627    #[test]
6628    #[allow(deprecated)]
6629    fn different_preferences() -> Result<()> {
6630        use crate::cert::Preferences;
6631        let p = &crate::policy::StandardPolicy::new();
6632
6633        // This key returns different preferences depending on how you
6634        // address it.  (It has two user ids and the user ids have
6635        // different preference packets on their respective self
6636        // signatures.)
6637
6638        let cert = Cert::from_bytes(
6639            crate::tests::key("different-preferences.asc"))?;
6640        assert_eq!(cert.userids().count(), 2);
6641
6642        if let Some(userid) = cert.userids().next() {
6643            assert_eq!(userid.userid().value(),
6644                       &b"Alice Confusion <alice@example.com>"[..]);
6645
6646            let userid = userid.with_policy(p, None).expect("valid");
6647
6648            use crate::types::SymmetricAlgorithm::*;
6649            assert_eq!(userid.preferred_symmetric_algorithms(),
6650                       Some(&[ AES256, AES192, AES128, TripleDES ][..]));
6651
6652            use crate::types::HashAlgorithm::*;
6653            assert_eq!(userid.preferred_hash_algorithms(),
6654                       Some(&[ SHA512, SHA384, SHA256, SHA224, SHA1 ][..]));
6655
6656            use crate::types::CompressionAlgorithm::*;
6657            assert_eq!(userid.preferred_compression_algorithms(),
6658                       Some(&[ Zlib, BZip2, Zip ][..]));
6659
6660            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6661
6662            // assert_eq!(userid.key_server_preferences(),
6663            //            Some(KeyServerPreferences::new(&[])));
6664
6665            assert_eq!(userid.features(),
6666                       Some(Features::new(&[]).set_seipdv1()));
6667        } else {
6668            panic!("two user ids");
6669        }
6670
6671        if let Some(userid) = cert.userids().next() {
6672            assert_eq!(userid.userid().value(),
6673                       &b"Alice Confusion <alice@example.com>"[..]);
6674
6675            let userid = userid.with_policy(p, None).expect("valid");
6676
6677            use crate::types::SymmetricAlgorithm::*;
6678            assert_eq!(userid.preferred_symmetric_algorithms(),
6679                       Some(&[ AES256, AES192, AES128, TripleDES ][..]));
6680
6681            use crate::types::HashAlgorithm::*;
6682            assert_eq!(userid.preferred_hash_algorithms(),
6683                       Some(&[ SHA512, SHA384, SHA256, SHA224, SHA1 ][..]));
6684
6685            use crate::types::CompressionAlgorithm::*;
6686            assert_eq!(userid.preferred_compression_algorithms(),
6687                       Some(&[ Zlib, BZip2, Zip ][..]));
6688
6689            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6690
6691            assert_eq!(userid.key_server_preferences(),
6692                       Some(KeyServerPreferences::new(&[0x80])));
6693
6694            assert_eq!(userid.features(),
6695                       Some(Features::new(&[]).set_seipdv1()));
6696
6697            // Using the certificate should choose the primary user
6698            // id, which is this one (because it is lexicographically
6699            // earlier).
6700            let cert = cert.with_policy(p, None).expect("valid");
6701            assert_eq!(userid.preferred_symmetric_algorithms(),
6702                       cert.preferred_symmetric_algorithms());
6703            assert_eq!(userid.preferred_hash_algorithms(),
6704                       cert.preferred_hash_algorithms());
6705            assert_eq!(userid.preferred_compression_algorithms(),
6706                       cert.preferred_compression_algorithms());
6707            assert_eq!(userid.preferred_aead_ciphersuites(),
6708                       cert.preferred_aead_ciphersuites());
6709            assert_eq!(userid.key_server_preferences(),
6710                       cert.key_server_preferences());
6711            assert_eq!(userid.features(),
6712                       cert.features());
6713        } else {
6714            panic!("two user ids");
6715        }
6716
6717        if let Some(userid) = cert.userids().nth(1) {
6718            assert_eq!(userid.userid().value(),
6719                       &b"Alice Confusion <alice@example.net>"[..]);
6720
6721            let userid = userid.with_policy(p, None).expect("valid");
6722
6723            use crate::types::SymmetricAlgorithm::*;
6724            assert_eq!(userid.preferred_symmetric_algorithms(),
6725                       Some(&[ AES192, AES256, AES128, TripleDES ][..]));
6726
6727            use crate::types::HashAlgorithm::*;
6728            assert_eq!(userid.preferred_hash_algorithms(),
6729                       Some(&[ SHA384, SHA512, SHA256, SHA224, SHA1 ][..]));
6730
6731            use crate::types::CompressionAlgorithm::*;
6732            assert_eq!(userid.preferred_compression_algorithms(),
6733                       Some(&[ BZip2, Zlib, Zip ][..]));
6734
6735            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6736
6737            assert_eq!(userid.key_server_preferences(),
6738                       Some(KeyServerPreferences::new(&[0x80])));
6739
6740            assert_eq!(userid.features(),
6741                       Some(Features::new(&[]).set_seipdv1()));
6742        } else {
6743            panic!("two user ids");
6744        }
6745
6746        Ok(())
6747    }
6748
6749    #[test]
6750    fn unsigned_components() -> Result<()> {
6751        // We have a certificate with an unsigned User ID, User
6752        // Attribute, encryption-capable subkey, and signing-capable
6753        // subkey.  (Actually, they are signed, but the signatures are
6754        // bad.)  We expect that when we parse such a certificate the
6755        // unsigned components are not dropped and they appear when
6756        // iterating over the components using, e.g., Cert::userids,
6757        // but not when we check for valid components.
6758
6759        let p = &crate::policy::StandardPolicy::new();
6760
6761        let cert = Cert::from_bytes(
6762            crate::tests::key("certificate-with-unsigned-components.asc"))?;
6763
6764        assert_eq!(cert.userids().count(), 2);
6765        assert_eq!(cert.userids().with_policy(p, None).count(), 1);
6766
6767        assert_eq!(cert.user_attributes().count(), 2);
6768        assert_eq!(cert.user_attributes().with_policy(p, None).count(), 1);
6769
6770        assert_eq!(cert.keys().count(), 1 + 4);
6771        assert_eq!(cert.keys().with_policy(p, None).count(), 1 + 2);
6772        Ok(())
6773    }
6774
6775    #[test]
6776    fn issue_504() -> Result<()> {
6777        let mut keyring = crate::tests::key("testy.pgp").to_vec();
6778        keyring.extend_from_slice(crate::tests::key("testy-new.pgp"));
6779
6780        // TryFrom<PacketPile>
6781        let pp = PacketPile::from_bytes(&keyring)?;
6782        assert!(matches!(
6783            Cert::try_from(pp.clone()).unwrap_err().downcast().unwrap(),
6784            Error::MalformedCert(_)
6785        ));
6786
6787        // Cert::TryFrom<Vec<Packet>>
6788        let v: Vec<Packet> = pp.into();
6789        assert!(matches!(
6790            Cert::try_from(v.clone()).unwrap_err().downcast().unwrap(),
6791            Error::MalformedCert(_)
6792        ));
6793
6794        // Cert::from_packet
6795        assert!(matches!(
6796            Cert::from_packets(v.into_iter()).unwrap_err().downcast().unwrap(),
6797            Error::MalformedCert(_)
6798        ));
6799
6800        // Cert::TryFrom<PacketParserResult>
6801        let ppr = PacketParser::from_bytes(&keyring)?;
6802        assert!(matches!(
6803            Cert::try_from(ppr).unwrap_err().downcast().unwrap(),
6804            Error::MalformedCert(_)
6805        ));
6806        Ok(())
6807    }
6808
6809    /// Tests whether the policy is applied to primary key binding
6810    /// signatures.
6811    #[test]
6812    fn issue_531() -> Result<()> {
6813        let cert =
6814            Cert::from_bytes(crate::tests::key("peter-sha1-backsig.pgp"))?;
6815        let p = unsafe { &crate::policy::NullPolicy::new() };
6816        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 1);
6817        let mut p = crate::policy::StandardPolicy::new();
6818        p.reject_hash(HashAlgorithm::SHA1);
6819        assert_eq!(cert.with_policy(&p, None)?.keys().for_signing().count(), 0);
6820        Ok(())
6821    }
6822
6823    /// Tests whether expired primary key binding signatures are
6824    /// rejected.
6825    #[test]
6826    fn issue_539() -> Result<()> {
6827        let cert =
6828            Cert::from_bytes(crate::tests::key("peter-expired-backsig.pgp"))?;
6829        let p = unsafe { &crate::policy::NullPolicy::new() };
6830        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 0);
6831        let p = &crate::policy::StandardPolicy::new();
6832        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 0);
6833        Ok(())
6834    }
6835
6836    /// Tests whether signatures are properly deduplicated.
6837    #[test]
6838    fn issue_568() -> Result<()> {
6839        use crate::packet::signature::subpacket::*;
6840
6841        let (cert, _) = CertBuilder::general_purpose(
6842            Some("alice@example.org")).generate().unwrap();
6843        assert_eq!(cert.userids().count(), 1);
6844        assert_eq!(cert.subkeys().count(), 2);
6845        assert_eq!(cert.unknowns().count(), 0);
6846        assert_eq!(cert.bad_signatures().count(), 0);
6847        assert_eq!(cert.userids().next().unwrap().self_signatures().count(), 1);
6848        assert_eq!(cert.subkeys().next().unwrap().self_signatures().count(), 1);
6849        assert_eq!(cert.subkeys().nth(1).unwrap().self_signatures().count(), 1);
6850
6851        // Create a variant of cert where the signatures have
6852        // additional information in the unhashed area.
6853        let cert_b = cert.clone();
6854        let mut packets = crate::PacketPile::from(cert_b).into_children()
6855            .collect::<Vec<_>>();
6856        for p in packets.iter_mut() {
6857            if let Packet::Signature(sig) = p {
6858                assert_eq!(sig.hashed_area().subpackets(
6859                    SubpacketTag::IssuerFingerprint).count(),
6860                           1);
6861                sig.unhashed_area_mut().add(Subpacket::new(
6862                    SubpacketValue::Issuer("AAAA BBBB CCCC DDDD".parse()?),
6863                    false)?)?;
6864            }
6865        }
6866        let cert_b = Cert::from_packets(packets.into_iter())?;
6867        let cert = cert.merge_public_and_secret(cert_b)?;
6868        assert_eq!(cert.userids().count(), 1);
6869        assert_eq!(cert.subkeys().count(), 2);
6870        assert_eq!(cert.unknowns().count(), 0);
6871        assert_eq!(cert.bad_signatures().count(), 0);
6872        assert_eq!(cert.userids().next().unwrap().self_signatures().count(), 1);
6873        assert_eq!(cert.subkeys().next().unwrap().self_signatures().count(), 1);
6874        assert_eq!(cert.subkeys().nth(1).unwrap().self_signatures().count(), 1);
6875
6876        Ok(())
6877    }
6878
6879    /// Checks that missing or bad embedded signatures cause the
6880    /// signature to be considered bad.
6881    #[test]
6882    fn missing_backsig_is_bad() -> Result<()> {
6883        use crate::packet::{
6884            key::Key6,
6885            signature::{
6886                SignatureBuilder,
6887                subpacket::{Subpacket, SubpacketValue},
6888            },
6889        };
6890
6891        // We'll study this certificate, because it contains a
6892        // signing-capable subkey.
6893        let cert = crate::Cert::from_bytes(crate::tests::key(
6894            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6895        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
6896            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6897        assert_eq!(pp.children().count(), 5);
6898
6899        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
6900            // Add a bogus but plausible embedded signature subpacket.
6901            let key: key::SecretKey
6902                = Key6::generate_ecc(true, Curve::Ed25519)?.into();
6903            let mut pair = key.into_keypair()?;
6904
6905            sig.unhashed_area_mut().replace(Subpacket::new(
6906                SubpacketValue::EmbeddedSignature(
6907                    SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
6908                        .sign_primary_key_binding(
6909                            &mut pair,
6910                            cert.primary_key().key(),
6911                            cert.keys().subkeys().next().unwrap().key())?),
6912                false)?)?;
6913        } else {
6914            panic!("expected a signature");
6915        }
6916
6917        // Parse into cert.
6918        use std::convert::TryFrom;
6919        let malicious_cert = Cert::try_from(pp)?;
6920        // The subkey binding signature should no longer check out.
6921        let p = &crate::policy::StandardPolicy::new();
6922        assert_eq!(malicious_cert.with_policy(p, None)?.keys().subkeys()
6923                   .for_signing().count(), 0);
6924        // Instead, it should be considered bad.
6925        assert_eq!(malicious_cert.bad_signatures().count(), 1);
6926        Ok(())
6927    }
6928
6929    /// Checks that multiple embedded signatures are correctly
6930    /// handled.
6931    #[test]
6932    fn multiple_embedded_signatures() -> Result<()> {
6933        use crate::packet::{
6934            key::Key6,
6935            signature::{
6936                SignatureBuilder,
6937                subpacket::{Subpacket, SubpacketValue},
6938            },
6939        };
6940
6941        // We'll study this certificate, because it contains a
6942        // signing-capable subkey.
6943        let cert = crate::Cert::from_bytes(crate::tests::key(
6944            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6945
6946        // Add a bogus but plausible embedded signature subpacket with
6947        // this key.
6948        let key: key::SecretKey
6949            = Key6::generate_ecc(true, Curve::Ed25519)?.into();
6950        let mut pair = key.into_keypair()?;
6951
6952        // Create a malicious cert to merge in.
6953        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
6954            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6955        assert_eq!(pp.children().count(), 5);
6956
6957        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
6958            // Prepend a bad backsig.
6959            let backsig = sig.embedded_signatures().next().unwrap().clone();
6960            sig.unhashed_area_mut().replace(Subpacket::new(
6961                SubpacketValue::EmbeddedSignature(
6962                    SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
6963                        .sign_primary_key_binding(
6964                            &mut pair,
6965                            cert.primary_key().key(),
6966                            cert.keys().subkeys().next().unwrap().key())?),
6967                false)?)?;
6968            sig.unhashed_area_mut().add(Subpacket::new(
6969                SubpacketValue::EmbeddedSignature(backsig), false)?)?;
6970        } else {
6971            panic!("expected a signature");
6972        }
6973
6974        // Parse into cert.
6975        use std::convert::TryFrom;
6976        let malicious_cert = Cert::try_from(pp)?;
6977        // The subkey binding signature should still be fine.
6978        let p = &crate::policy::StandardPolicy::new();
6979        assert_eq!(malicious_cert.with_policy(p, None)?.keys().subkeys()
6980                   .for_signing().count(), 1);
6981        assert_eq!(malicious_cert.bad_signatures().count(), 0);
6982
6983        // Now try to merge it in.
6984        let merged = cert.clone().merge_public_and_secret(malicious_cert.clone())?;
6985        // The subkey binding signature should still be fine.
6986        assert_eq!(merged.with_policy(p, None)?.keys().subkeys()
6987                   .for_signing().count(), 1);
6988        let sig = merged.with_policy(p, None)?.keys().subkeys()
6989            .for_signing().next().unwrap().binding_signature();
6990        assert_eq!(sig.embedded_signatures().count(), 2);
6991
6992        // Now the other way around.
6993        let merged = malicious_cert.clone().merge_public_and_secret(cert.clone())?;
6994        // The subkey binding signature should still be fine.
6995        assert_eq!(merged.with_policy(p, None)?.keys().subkeys()
6996                   .for_signing().count(), 1);
6997        let sig = merged.with_policy(p, None)?.keys().subkeys()
6998            .for_signing().next().unwrap().binding_signature();
6999        assert_eq!(sig.embedded_signatures().count(), 2);
7000        Ok(())
7001    }
7002
7003    /// Checks that Cert::merge(cert, cert) == cert.
7004    #[test]
7005    fn issue_579() -> Result<()> {
7006        use std::convert::TryFrom;
7007        use crate::packet::signature::subpacket::SubpacketTag;
7008
7009        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
7010            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
7011        assert_eq!(pp.children().count(), 5);
7012        // Drop issuer information from the unhashed areas.
7013        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[2]) {
7014            sig.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
7015        } else {
7016            panic!("expected a signature");
7017        }
7018        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
7019            sig.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
7020        } else {
7021            panic!("expected a signature");
7022        }
7023
7024        let cert = Cert::try_from(pp)?;
7025        assert_eq!(cert.clone().merge_public_and_secret(cert.clone())?, cert);
7026
7027        Ok(())
7028    }
7029
7030    /// Checks that Cert::merge_public ignores secret key material.
7031    #[test]
7032    fn merge_public() -> Result<()> {
7033        let cert =
7034            Cert::from_bytes(crate::tests::key("testy-new.pgp"))?;
7035        let key =
7036            Cert::from_bytes(crate::tests::key("testy-new-private.pgp"))?;
7037
7038        assert!(! cert.is_tsk());
7039        assert!(key.is_tsk());
7040
7041        // Secrets are ignored in `other`.
7042        let merged = cert.clone().merge_public(key.clone())?;
7043        assert!(! merged.is_tsk());
7044        assert_eq!(merged, cert);
7045
7046        // Secrets are retained in `self`.
7047        let merged = key.clone().merge_public(cert.clone())?;
7048        assert!(merged.is_tsk());
7049        assert_eq!(merged, key);
7050
7051        Ok(())
7052    }
7053
7054    /// Make sure we can parse a key where the primary key is its own
7055    /// subkeys.
7056    #[test]
7057    fn primary_key_is_subkey() -> Result<()> {
7058        let p = &crate::policy::StandardPolicy::new();
7059
7060        let cert =
7061            Cert::from_bytes(crate::tests::key("primary-key-is-also-subkey.pgp"))?;
7062
7063        // There should be three keys:
7064        //
7065        //     Fingerprint: 8E8C 33FA 4626 3379 76D9  7978 069C 0C34 8DD8 2C19
7066        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7067        // Public-key size: 256 bits
7068        //      Secret key: Unencrypted
7069        //   Creation time: 2018-06-11 14:12:09 UTC
7070        //       Key flags: certification, signing
7071        //
7072        //          Subkey: 8E8C 33FA 4626 3379 76D9  7978 069C 0C34 8DD8 2C19
7073        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7074        // Public-key size: 256 bits
7075        //      Secret key: Unencrypted
7076        //   Creation time: 2018-06-11 14:12:09 UTC
7077        //       Key flags: certification, signing
7078        //
7079        //          Subkey: 061C 3CA4 4AFF 0EC5 8DC6  6E95 22E3 FAFE 96B5 6C32
7080        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7081        // Public-key size: 256 bits
7082        //      Secret key: Unencrypted
7083        //   Creation time: 2018-08-27 10:55:43 UTC
7084        //       Key flags: signing
7085        //
7086        //          UserID: Emmelie Dorothea Dina Samantha Awina Ed25519
7087        assert_eq!(cert.keys().count(), 3);
7088
7089        // Make sure there is a subkey with the same fingerprint as
7090        // the primary key.
7091        assert!(cert.keys().subkeys().any(|k| {
7092            k.key().fingerprint() == cert.primary_key().key().fingerprint()
7093        }));
7094
7095        // Make sure the self sig is valid, too.
7096        assert_eq!(cert.keys().count(), 3);
7097
7098        let vc = cert.with_policy(p, None)?;
7099        assert!(vc.keys().subkeys().any(|k| {
7100            k.key().fingerprint() == vc.primary_key().key().fingerprint()
7101        }));
7102
7103        Ok(())
7104    }
7105
7106    /// Makes sure that certification approval key signatures are
7107    /// correctly handled.
7108    #[test]
7109    fn certificaton_approval_signatures() -> Result<()> {
7110        use crate::{
7111            packet::signature::SignatureBuilder,
7112            types::*,
7113        };
7114        let p = &crate::policy::StandardPolicy::new();
7115
7116        let (alice, _) = CertBuilder::new()
7117            .add_userid("alice@foo.com")
7118            .generate()?;
7119        let mut alice_signer =
7120            alice.primary_key().key().clone().parts_into_secret()?
7121            .into_keypair()?;
7122
7123        let (bob, _) = CertBuilder::new()
7124            .add_userid("bob@bar.com")
7125            .generate()?;
7126        let mut bob_signer =
7127            bob.primary_key().key().clone().parts_into_secret()?
7128            .into_keypair()?;
7129        let bob_pristine = bob.clone();
7130
7131        // Have Alice certify the binding between "bob@bar.com" and
7132        // Bob's key.
7133        let alice_certifies_bob
7134            = bob.userids().next().unwrap().userid().bind(
7135                &mut alice_signer, &bob,
7136                SignatureBuilder::new(SignatureType::GenericCertification))?;
7137        let bob = bob.insert_packets(vec![
7138            alice_certifies_bob.clone(),
7139        ])?.0;
7140
7141        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7142                   .certifications().count(), 1);
7143        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7144                   .approved_certifications().count(), 0);
7145
7146        // Have Bob attest that certification.
7147        let attestations =
7148            bob.userids().next().unwrap().approve_of_certifications(
7149                p,
7150                None,
7151                &mut bob_signer,
7152                vec![&alice_certifies_bob])?;
7153        assert_eq!(attestations.len(), 1);
7154        let attestation = attestations[0].clone();
7155
7156        let bob = bob.insert_packets(vec![
7157            attestation.clone(),
7158        ])?.0;
7159
7160        assert_eq!(bob.bad_signatures().count(), 0);
7161        assert_eq!(bob.userids().next().unwrap().certifications().next(),
7162                   Some(&alice_certifies_bob));
7163        assert_eq!(bob.userids().next().unwrap().bundle().approvals().next().unwrap(),
7164                   &attestation);
7165        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7166                   .certifications().count(), 1);
7167        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7168                   .approved_certifications().count(), 1);
7169
7170        // Check that attested key signatures are kept over merges.
7171        let bob_ = bob.clone().merge_public(bob_pristine.clone())?;
7172        assert_eq!(bob_.bad_signatures().count(), 0);
7173        assert_eq!(bob_.userids().next().unwrap().certifications().next(),
7174                   Some(&alice_certifies_bob));
7175        assert_eq!(bob_.userids().next().unwrap().bundle().approvals().next().unwrap(),
7176                   &attestation);
7177        assert_eq!(bob_.with_policy(p, None)?.userids().next().unwrap()
7178                   .approved_certifications().count(), 1);
7179
7180        // And the other way around.
7181        let bob_ = bob_pristine.clone().merge_public(bob.clone())?;
7182        assert_eq!(bob_.bad_signatures().count(), 0);
7183        assert_eq!(bob_.userids().next().unwrap().certifications().next(),
7184                   Some(&alice_certifies_bob));
7185        assert_eq!(bob_.userids().next().unwrap().bundle().approvals().next().unwrap(),
7186                   &attestation);
7187        assert_eq!(bob_.with_policy(p, None)?.userids().next().unwrap()
7188                   .approved_certifications().count(), 1);
7189
7190        // Have Bob withdraw any prior attestations.
7191
7192        let attestations =
7193            bob.userids().next().unwrap().approve_of_certifications(
7194                p,
7195                None,
7196                &mut bob_signer,
7197                &[])?;
7198        assert_eq!(attestations.len(), 1);
7199        let attestation = attestations[0].clone();
7200
7201        let bob = bob.insert_packets(vec![
7202            attestation.clone(),
7203        ])?.0;
7204
7205        assert_eq!(bob.bad_signatures().count(), 0);
7206        assert_eq!(bob.userids().next().unwrap().certifications().next(),
7207                   Some(&alice_certifies_bob));
7208        assert_eq!(bob.userids().next().unwrap().bundle().approvals().next().unwrap(),
7209                   &attestation);
7210        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7211                   .certifications().count(), 1);
7212        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7213                   .approved_certifications().count(), 0);
7214
7215
7216        Ok(())
7217    }
7218
7219    /// Makes sure that certification approval key signatures are
7220    /// correctly handled.
7221    #[test]
7222    fn certification_approval_key_signatures_dkgpg() -> Result<()> {
7223        const DUMP: bool = false;
7224        let p = &crate::policy::StandardPolicy::new();
7225
7226        let test = Cert::from_bytes(crate::tests::key("1pa3pc-dkgpg.pgp"))?;
7227        assert_eq!(test.bad_signatures().count(), 0);
7228        assert_eq!(test.userids().next().unwrap().certifications().count(),
7229                   1);
7230        assert_eq!(test.userids().next().unwrap().bundle().approvals().count(),
7231                   1);
7232
7233        let attestation =
7234            test.userids().next().unwrap().bundle().approvals().next().unwrap();
7235
7236        if DUMP {
7237            for (i, d) in attestation.approved_certifications()?.enumerate() {
7238                crate::fmt::hex::Dumper::new(std::io::stderr(), "")
7239                    .write(d, format!("expected digest {}", i))?;
7240            }
7241        }
7242
7243        let digests: std::collections::HashSet<_> =
7244            attestation.approved_certifications()?.collect();
7245
7246        for (i, certification) in
7247            test.userids().next().unwrap().certifications().enumerate()
7248        {
7249            // Hash the certification.
7250            let mut h = attestation.hash_algo().context()?
7251                .for_signature(attestation.version());
7252            certification.hash_for_confirmation(&mut h)?;
7253            let digest = h.into_digest()?;
7254
7255            if DUMP {
7256                crate::fmt::hex::Dumper::new(std::io::stderr(), "")
7257                    .write(&digest, format!("computed digest {}", i))?;
7258            }
7259
7260            assert!(digests.contains(&digest[..]));
7261        }
7262
7263        assert_eq!(test.with_policy(p, None)?.userids().next().unwrap()
7264                   .certifications().count(), 1);
7265        assert_eq!(test.with_policy(p, None)?.userids().next().unwrap()
7266                   .approved_certifications().count(), 1);
7267
7268        Ok(())
7269    }
7270
7271    /// Makes sure that certification approval key signatures are
7272    /// correctly reordered.
7273    #[test]
7274    fn certification_approval_key_signature_out_of_order() -> Result<()> {
7275        let p = &crate::policy::StandardPolicy::new();
7276
7277        let (alice, _) = CertBuilder::general_purpose(
7278            Some("alice@example.org")).generate().unwrap();
7279        assert!(alice.keys().subkeys().count() > 0);
7280        let mut alice_signer =
7281            alice.primary_key().key().clone().parts_into_secret()?
7282            .into_keypair()?;
7283
7284        // Now, create new attestation signatures.
7285        let mut attestation_signatures = Vec::new();
7286        for uid in alice.userids() {
7287            attestation_signatures.append(&mut uid.approve_of_certifications(
7288                p,
7289                None,
7290                &mut alice_signer,
7291                uid.certifications(),
7292            )?);
7293        }
7294
7295        // Add the new signatures.  This appends the attestation
7296        // signature so that it is considered part of last component,
7297        // a subkey.
7298        let alice2 = alice.insert_packets(attestation_signatures)?.0;
7299
7300        // Now we make sure the attestation signature was correctly reordered.
7301        assert_eq!(alice2.bad_signatures().count(), 0);
7302        let ua = alice2.userids().next().unwrap();
7303        assert_eq!(ua.approvals().count(), 1);
7304
7305        Ok(())
7306    }
7307
7308    /// Makes sure that marker packets are ignored when parsing certs.
7309    #[test]
7310    fn marker_packets() -> Result<()> {
7311        let cert = Cert::from_bytes(crate::tests::key("neal.pgp"))?;
7312        let mut buf = Vec::new();
7313        Packet::Marker(Default::default()).serialize(&mut buf)?;
7314        cert.serialize(&mut buf)?;
7315
7316        let cert_ = Cert::from_bytes(&buf)?;
7317        assert_eq!(cert, cert_);
7318        Ok(())
7319    }
7320
7321    /// Checks that messing with a revocation signature merely
7322    /// invalidates the signature and keeps the cert's revocation
7323    /// status unchanged.
7324    #[test]
7325    fn issue_486() -> Result<()> {
7326        use crate::{
7327            crypto::mpi,
7328            types::RevocationStatus::*,
7329            packet::signature::Signature4,
7330            policy::StandardPolicy,
7331        };
7332        let p = &StandardPolicy::new();
7333
7334        let (cert, revocation) = CertBuilder::new().generate()?;
7335
7336        // Base case.
7337        let c = cert.clone().insert_packets(Some(revocation.clone()))?.0;
7338        if let Revoked(_) = c.revocation_status(p, None) {
7339            // cert is considered revoked
7340        } else {
7341            panic!("Should be revoked, but is not: {:?}",
7342                   c.revocation_status(p, None));
7343        }
7344
7345        // Breaking the revocation signature by changing the MPIs.
7346        let c = cert.clone().insert_packets(Some(
7347            Signature4::new(
7348                revocation.typ(),
7349                revocation.pk_algo(),
7350                revocation.hash_algo(),
7351                revocation.hashed_area().clone(),
7352                revocation.unhashed_area().clone(),
7353                *revocation.digest_prefix(),
7354                // MPI is replaced with a dummy one
7355                mpi::Signature::RSA {
7356                    s: mpi::MPI::from(vec![1, 2, 3])
7357                })))?.0;
7358        if let NotAsFarAsWeKnow = c.revocation_status(p, None) {
7359            assert_eq!(c.bad_signatures().count(), 1);
7360        } else {
7361            panic!("Should not be revoked, but is: {:?}",
7362                   c.revocation_status(p, None));
7363        }
7364
7365        // Breaking the revocation signature by changing the MPIs and
7366        // the digest prefix.
7367        let c = cert.clone().insert_packets(Some(
7368            Signature4::new(
7369                revocation.typ(),
7370                revocation.pk_algo(),
7371                revocation.hash_algo(),
7372                revocation.hashed_area().clone(),
7373                revocation.unhashed_area().clone(),
7374                // Prefix replaced with a dummy one
7375                [0, 1],
7376                // MPI is replaced with a dummy one
7377                mpi::Signature::RSA {
7378                    s: mpi::MPI::from(vec![1, 2, 3])
7379                })))?.0;
7380        if let NotAsFarAsWeKnow = c.revocation_status(p, None) {
7381            assert_eq!(c.bad_signatures().count(), 1);
7382        } else {
7383            panic!("Should not be revoked, but is: {:?}",
7384                   c.revocation_status(p, None));
7385        }
7386
7387        Ok(())
7388    }
7389
7390    /// Tests v3 binding signatures.
7391    #[test]
7392    #[allow(deprecated)]
7393    fn v3_binding_signature() -> Result<()> {
7394        skip_unless_supported!(crate::types::PublicKeyAlgorithm::DSA);
7395
7396        let c = Cert::from_bytes(
7397            crate::tests::key("pgp5-dsa-elg-v3-subkey-binding.pgp"))?;
7398        assert_eq!(c.bad_signatures().count(), 0);
7399
7400        let np = unsafe { crate::policy::NullPolicy::new() };
7401
7402        // The subkey is interesting because it is bound using a v3
7403        // signature.
7404        let vcert = c.with_policy(&np, None)?;
7405        assert_eq!(vcert.keys().subkeys().count(), 1);
7406
7407        // XXX: Unfortunately, it being a v3 signature, the subkey has
7408        // no keyflags, limiting its usefulness for now.
7409
7410        // The subkey is interesting because it is bound using a v3
7411        // signature.
7412        assert_eq!(c.keys().subkeys().with_policy(&np, None).count(), 1);
7413
7414        Ok(())
7415    }
7416
7417    /// Tests v3 revocation signatures.
7418    #[test]
7419    fn v3_revocation_signature() -> Result<()> {
7420        skip_unless_supported!(crate::types::PublicKeyAlgorithm::ECDSA);
7421        skip_unless_supported!(crate::types::Curve::NistP521);
7422
7423        let c = Cert::from_bytes(
7424            crate::tests::key("v4-revoked-by-v3.pgp"))?;
7425        assert_eq!(c.bad_signatures().count(), 0);
7426
7427        let sp = crate::policy::StandardPolicy::new();
7428        assert!(matches!(c.revocation_status(&sp, None),
7429                         RevocationStatus::Revoked(_)));
7430        Ok(())
7431    }
7432
7433    #[test]
7434    fn v6_minimal_cert() -> Result<()> {
7435        let p = &crate::policy::StandardPolicy::new();
7436        let t = None; // XXX
7437        let cert = Cert::from_bytes(
7438            crate::tests::file("crypto-refresh/v6-minimal-cert.key"))?;
7439        assert_eq!(cert.userids().count(), 0);
7440        let vcert = cert.with_policy(p, t)?;
7441        assert_eq!(vcert.keys().count(), 2);
7442        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7443        assert_eq!(vcert.keys().unencrypted_secret().count(), 0);
7444        assert_eq!(vcert.keys().for_signing().count(), 1);
7445        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7446
7447        let cert = Cert::from_bytes(
7448            crate::tests::file("crypto-refresh/v6-minimal-secret.key")).unwrap();
7449        assert_eq!(cert.userids().count(), 0);
7450        let vcert = cert.with_policy(p, t)?;
7451        assert_eq!(vcert.keys().count(), 2);
7452        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7453        assert_eq!(vcert.keys().unencrypted_secret().count(), 2);
7454        assert_eq!(vcert.keys().for_signing().count(), 1);
7455        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7456
7457        // The following key uses Argon2, and it takes 2 GiB to
7458        // efficiently derive the KEK.  This isn't viable on 32 bit
7459        // architectures.
7460        let name = if cfg!(target_pointer_width = "16") {
7461            return Ok(()); // No chance we even got here.
7462        } else if cfg!(target_pointer_width = "32") {
7463            // For 32 bit architectures, we have a test vector which
7464            // uses the "SECOND RECOMMENDED" parameter choice for
7465            // memory constrained systems (see Section 4 of RFC 9106).
7466            "v6-minimal-secret-locked-for-constrained-envs.key"
7467        } else {
7468            // 64 bit or weird.  Good luck.
7469            "v6-minimal-secret-locked.key"
7470        };
7471
7472        let cert = Cert::from_bytes(
7473            crate::tests::file(&format!("crypto-refresh/{}", name)))?;
7474        assert_eq!(cert.userids().count(), 0);
7475        let vcert = cert.with_policy(p, t)?;
7476        assert_eq!(vcert.keys().count(), 2);
7477        assert_eq!(vcert.keys().encrypted_secret().count(), 2);
7478        assert_eq!(vcert.keys().unencrypted_secret().count(), 0);
7479        assert_eq!(vcert.keys().for_signing().count(), 1);
7480        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7481
7482        let password = "correct horse battery staple".into();
7483        for skb in vcert.keys().encrypted_secret() {
7484            skb.key().secret().clone().decrypt(skb.key(), &password)?;
7485        }
7486
7487        Ok(())
7488    }
7489
7490    // Check that the certificate is valid, and has a primary key and
7491    // an encryption capable subkey.  Check that same for the key
7492    // variant, but also assert that the keys have unencrypted secret
7493    // key material.
7494    fn test_parse_certificate(algo: PublicKeyAlgorithm,
7495                              cert_file: &str, key_file: &str)
7496        -> Result<()>
7497    {
7498        skip_unless_supported!(algo);
7499
7500        eprintln!("Test {}\n-  {}\n-  {}", algo, cert_file, key_file);
7501
7502        let p = &crate::policy::StandardPolicy::new();
7503        let t = None;
7504        let cert = Cert::from_bytes(
7505            crate::tests::file(cert_file))?;
7506        assert_eq!(cert.userids().count(), 1);
7507        let vcert = cert.with_policy(p, t)?;
7508        assert_eq!(vcert.keys().count(), 2);
7509        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7510        assert_eq!(vcert.keys().unencrypted_secret().count(), 0);
7511        assert_eq!(vcert.keys().for_signing().count(), 1);
7512        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7513
7514        let cert = Cert::from_bytes(
7515            crate::tests::file(key_file))?;
7516        assert_eq!(cert.userids().count(), 1);
7517        let vcert = cert.with_policy(p, t)?;
7518        assert_eq!(vcert.keys().count(), 2);
7519        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7520        assert_eq!(vcert.keys().unencrypted_secret().count(), 2);
7521        assert_eq!(vcert.keys().for_signing().count(), 1);
7522        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7523
7524        Ok(())
7525    }
7526
7527    // Check that we can parse the certificates and that they have the
7528    // expected form.
7529    #[test]
7530    fn parse_certificates() -> Result<()> {
7531        use crate::tests::PQC_CERT_PAIRS;
7532
7533        for (algo, cert_file, key_file) in PQC_CERT_PAIRS {
7534            assert!(test_parse_certificate(*algo, cert_file, key_file).is_ok());
7535        }
7536
7537        Ok(())
7538    }
7539}