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::serialize::Serialize;
4386    use crate::policy::StandardPolicy as P;
4387    use crate::types::Curve;
4388    use crate::packet::signature;
4389    use crate::policy::HashAlgoSecurity;
4390    use super::*;
4391
4392    use crate::{
4393        KeyID,
4394        types::KeyFlags,
4395    };
4396
4397    fn parse_cert(data: &[u8], as_message: bool) -> Result<Cert> {
4398        if as_message {
4399            let pile = PacketPile::from_bytes(data).unwrap();
4400            Cert::try_from(pile)
4401        } else {
4402            Cert::from_bytes(data)
4403        }
4404    }
4405
4406    #[test]
4407    fn broken() {
4408        use crate::types::Timestamp;
4409        for i in 0..2 {
4410            let cert = parse_cert(crate::tests::key("testy-broken-no-pk.pgp"),
4411                                i == 0);
4412            assert_match!(Error::MalformedCert(_)
4413                          = cert.err().unwrap().downcast::<Error>().unwrap());
4414
4415            // According to 4880, a Cert must have a UserID.  But, we
4416            // don't require it.
4417            let cert = parse_cert(crate::tests::key("testy-broken-no-uid.pgp"),
4418                                i == 0);
4419            assert!(cert.is_ok());
4420
4421            // We have:
4422            //
4423            //   [ pk, user id, sig, subkey ]
4424            let cert = parse_cert(crate::tests::key("testy-broken-no-sig-on-subkey.pgp"),
4425                                i == 0).unwrap();
4426            assert_eq!(cert.primary.key().creation_time(),
4427                       Timestamp::from(1511355130).into());
4428            assert_eq!(cert.userids.len(), 1);
4429            assert_eq!(cert.userids[0].userid().value(),
4430                       &b"Testy McTestface <testy@example.org>"[..]);
4431            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4432            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4433                       .digest_prefix(),
4434                       &[ 0xc6, 0x8f ]);
4435            assert_eq!(cert.user_attributes.len(), 0);
4436            assert_eq!(cert.subkeys.len(), 1);
4437        }
4438    }
4439
4440    #[test]
4441    fn basics() {
4442        use crate::types::Timestamp;
4443        for i in 0..2 {
4444            let cert = parse_cert(crate::tests::key("testy.pgp"),
4445                                i == 0).unwrap();
4446            assert_eq!(cert.primary.key().creation_time(),
4447                       Timestamp::from(1511355130).into());
4448            assert_eq!(format!("{:X}", cert.fingerprint()),
4449                       "3E8877C877274692975189F5D03F6F865226FE8B");
4450
4451            assert_eq!(cert.userids.len(), 1, "number of userids");
4452            assert_eq!(cert.userids[0].userid().value(),
4453                       &b"Testy McTestface <testy@example.org>"[..]);
4454            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4455            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4456                       .digest_prefix(),
4457                       &[ 0xc6, 0x8f ]);
4458
4459            assert_eq!(cert.user_attributes.len(), 0);
4460
4461            assert_eq!(cert.subkeys.len(), 1, "number of subkeys");
4462            assert_eq!(cert.subkeys[0].key().creation_time(),
4463                       Timestamp::from(1511355130).into());
4464            assert_eq!(cert.subkeys[0].self_signatures().next().unwrap()
4465                       .digest_prefix(),
4466                       &[ 0xb7, 0xb9 ]);
4467
4468            let cert = parse_cert(crate::tests::key("testy-no-subkey.pgp"),
4469                                i == 0).unwrap();
4470            assert_eq!(cert.primary.key().creation_time(),
4471                       Timestamp::from(1511355130).into());
4472            assert_eq!(format!("{:X}", cert.fingerprint()),
4473                       "3E8877C877274692975189F5D03F6F865226FE8B");
4474
4475            assert_eq!(cert.user_attributes.len(), 0);
4476
4477            assert_eq!(cert.userids.len(), 1, "number of userids");
4478            assert_eq!(cert.userids[0].userid().value(),
4479                       &b"Testy McTestface <testy@example.org>"[..]);
4480            assert_eq!(cert.userids[0].self_signatures().count(), 1);
4481            assert_eq!(cert.userids[0].self_signatures().next().unwrap()
4482                       .digest_prefix(),
4483                       &[ 0xc6, 0x8f ]);
4484
4485            assert_eq!(cert.subkeys.len(), 0, "number of subkeys");
4486
4487            let cert = parse_cert(crate::tests::key("testy.asc"), i == 0).unwrap();
4488            assert_eq!(format!("{:X}", cert.fingerprint()),
4489                       "3E8877C877274692975189F5D03F6F865226FE8B");
4490        }
4491    }
4492
4493    #[test]
4494    fn only_a_public_key() {
4495        // Make sure the Cert parser can parse a key that just consists
4496        // of a public key---no signatures, no user ids, nothing.
4497        let cert = Cert::from_bytes(crate::tests::key("testy-only-a-pk.pgp")).unwrap();
4498        assert_eq!(cert.userids.len(), 0);
4499        assert_eq!(cert.user_attributes.len(), 0);
4500        assert_eq!(cert.subkeys.len(), 0);
4501    }
4502
4503    #[test]
4504    fn merge() {
4505        use crate::tests::key;
4506        let cert_base = Cert::from_bytes(key("bannon-base.pgp")).unwrap();
4507
4508        // When we merge it with itself, we should get the exact same
4509        // thing.
4510        let merged = cert_base.clone().merge_public_and_secret(cert_base.clone()).unwrap();
4511        assert_eq!(cert_base, merged);
4512
4513        let cert_add_uid_1
4514            = Cert::from_bytes(key("bannon-add-uid-1-whitehouse.gov.pgp"))
4515                .unwrap();
4516        let cert_add_uid_2
4517            = Cert::from_bytes(key("bannon-add-uid-2-fox.com.pgp"))
4518                .unwrap();
4519        // Duplicate user id, but with a different self-sig.
4520        let cert_add_uid_3
4521            = Cert::from_bytes(key("bannon-add-uid-3-whitehouse.gov-dup.pgp"))
4522                .unwrap();
4523
4524        let cert_all_uids
4525            = Cert::from_bytes(key("bannon-all-uids.pgp"))
4526            .unwrap();
4527        // We have four User ID packets, but one has the same User ID,
4528        // just with a different self-signature.
4529        assert_eq!(cert_all_uids.userids.len(), 3);
4530
4531        // Merge in order.
4532        let merged = cert_base.clone().merge_public_and_secret(cert_add_uid_1.clone()).unwrap()
4533            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4534            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap();
4535        assert_eq!(cert_all_uids, merged);
4536
4537        // Merge in reverse order.
4538        let merged = cert_base.clone()
4539            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap()
4540            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4541            .merge_public_and_secret(cert_add_uid_1.clone()).unwrap();
4542        assert_eq!(cert_all_uids, merged);
4543
4544        let cert_add_subkey_1
4545            = Cert::from_bytes(key("bannon-add-subkey-1.pgp")).unwrap();
4546        let cert_add_subkey_2
4547            = Cert::from_bytes(key("bannon-add-subkey-2.pgp")).unwrap();
4548        let cert_add_subkey_3
4549            = Cert::from_bytes(key("bannon-add-subkey-3.pgp")).unwrap();
4550
4551        let cert_all_subkeys
4552            = Cert::from_bytes(key("bannon-all-subkeys.pgp")).unwrap();
4553
4554        // Merge the first user, then the second, then the third.
4555        let merged = cert_base.clone().merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4556            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4557            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap();
4558        assert_eq!(cert_all_subkeys, merged);
4559
4560        // Merge the third user, then the second, then the first.
4561        let merged = cert_base.clone().merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4562            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4563            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap();
4564        assert_eq!(cert_all_subkeys, merged);
4565
4566        // Merge a lot.
4567        let merged = cert_base.clone()
4568            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4569            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4570            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4571            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4572            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4573            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4574            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4575            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4576            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap();
4577        assert_eq!(cert_all_subkeys, merged);
4578
4579        let cert_all
4580            = Cert::from_bytes(key("bannon-all-uids-subkeys.pgp"))
4581            .unwrap();
4582
4583        // Merge all the subkeys with all the uids.
4584        let merged = cert_all_subkeys.clone()
4585            .merge_public_and_secret(cert_all_uids.clone()).unwrap();
4586        assert_eq!(cert_all, merged);
4587
4588        // Merge all uids with all the subkeys.
4589        let merged = cert_all_uids.clone()
4590            .merge_public_and_secret(cert_all_subkeys.clone()).unwrap();
4591        assert_eq!(cert_all, merged);
4592
4593        // All the subkeys and the uids in a mixed up order.
4594        let merged = cert_base.clone()
4595            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4596            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap()
4597            .merge_public_and_secret(cert_add_uid_1.clone()).unwrap()
4598            .merge_public_and_secret(cert_add_subkey_3.clone()).unwrap()
4599            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4600            .merge_public_and_secret(cert_add_uid_3.clone()).unwrap()
4601            .merge_public_and_secret(cert_add_subkey_2.clone()).unwrap()
4602            .merge_public_and_secret(cert_add_subkey_1.clone()).unwrap()
4603            .merge_public_and_secret(cert_add_uid_2.clone()).unwrap();
4604        assert_eq!(cert_all, merged);
4605
4606        // Certifications.
4607        let cert_donald_signs_base
4608            = Cert::from_bytes(key("bannon-the-donald-signs-base.pgp"))
4609            .unwrap();
4610        let cert_donald_signs_all
4611            = Cert::from_bytes(key("bannon-the-donald-signs-all-uids.pgp"))
4612            .unwrap();
4613        let cert_ivanka_signs_base
4614            = Cert::from_bytes(key("bannon-ivanka-signs-base.pgp"))
4615            .unwrap();
4616        let cert_ivanka_signs_all
4617            = Cert::from_bytes(key("bannon-ivanka-signs-all-uids.pgp"))
4618            .unwrap();
4619
4620        assert!(cert_donald_signs_base.userids.len() == 1);
4621        assert!(cert_donald_signs_base.userids[0].self_signatures().count() == 1);
4622        assert!(cert_base.userids[0].certifications.is_empty());
4623        assert!(cert_donald_signs_base.userids[0].certifications.len() == 1);
4624
4625        let merged = cert_donald_signs_base.clone()
4626            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap();
4627        assert!(merged.userids.len() == 1);
4628        assert!(merged.userids[0].self_signatures().count() == 1);
4629        assert!(merged.userids[0].certifications.len() == 2);
4630
4631        let merged = cert_donald_signs_base.clone()
4632            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap();
4633        assert!(merged.userids.len() == 3);
4634        assert!(merged.userids[0].self_signatures().count() == 1);
4635        // There should be two certifications from the Donald on the
4636        // first user id.
4637        assert!(merged.userids[0].certifications.len() == 2);
4638        assert!(merged.userids[1].certifications.len() == 1);
4639        assert!(merged.userids[2].certifications.len() == 1);
4640
4641        let merged = cert_donald_signs_base.clone()
4642            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4643            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4644            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap();
4645        assert!(merged.userids.len() == 3);
4646        assert!(merged.userids[0].self_signatures().count() == 1);
4647        // There should be two certifications from each of the Donald
4648        // and Ivanka on the first user id, and one each on the rest.
4649        assert!(merged.userids[0].certifications.len() == 4);
4650        assert!(merged.userids[1].certifications.len() == 2);
4651        assert!(merged.userids[2].certifications.len() == 2);
4652
4653        // Same as above, but redundant.
4654        let merged = cert_donald_signs_base.clone()
4655            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4656            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4657            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4658            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap()
4659            .merge_public_and_secret(cert_ivanka_signs_base.clone()).unwrap()
4660            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4661            .merge_public_and_secret(cert_donald_signs_all.clone()).unwrap()
4662            .merge_public_and_secret(cert_ivanka_signs_all.clone()).unwrap();
4663        assert!(merged.userids.len() == 3);
4664        assert!(merged.userids[0].self_signatures().count() == 1);
4665        // There should be two certifications from each of the Donald
4666        // and Ivanka on the first user id, and one each on the rest.
4667        assert!(merged.userids[0].certifications.len() == 4);
4668        assert!(merged.userids[1].certifications.len() == 2);
4669        assert!(merged.userids[2].certifications.len() == 2);
4670    }
4671
4672    #[test]
4673    fn out_of_order_self_sigs_test() {
4674        // neal-out-of-order.pgp contains all the self-signatures,
4675        // but some are out of order.  The canonicalization step
4676        // should reorder them.
4677        //
4678        // original order/new order:
4679        //
4680        //  1/ 1. pk
4681        //  2/ 2. user id #1: neal@walfield.org (good)
4682        //  3/ 3. sig over user ID #1
4683        //
4684        //  4/ 4. user id #2: neal@gnupg.org (good)
4685        //  5/ 7. sig over user ID #3
4686        //  6/ 5. sig over user ID #2
4687        //
4688        //  7/ 6. user id #3: neal@g10code.com (bad)
4689        //
4690        //  8/ 8. user ID #4: neal@pep.foundation (bad)
4691        //  9/11. sig over user ID #5
4692        //
4693        // 10/10. user id #5: neal@pep-project.org (bad)
4694        // 11/ 9. sig over user ID #4
4695        //
4696        // 12/12. user ID #6: neal@sequoia-pgp.org (good)
4697        // 13/13. sig over user ID #6
4698        //
4699        // ----------------------------------------------
4700        //
4701        // 14/14. signing subkey #1: 7223B56678E02528 (good)
4702        // 15/15. sig over subkey #1
4703        // 16/16. sig over subkey #1
4704        //
4705        // 17/17. encryption subkey #2: C2B819056C652598 (good)
4706        // 18/18. sig over subkey #2
4707        // 19/21. sig over subkey #3
4708        // 20/22. sig over subkey #3
4709        //
4710        // 21/20. auth subkey #3: A3506AFB820ABD08 (bad)
4711        // 22/19. sig over subkey #2
4712
4713        let cert = Cert::from_bytes(crate::tests::key("neal-sigs-out-of-order.pgp"))
4714            .unwrap();
4715
4716        let mut userids = cert.userids()
4717            .map(|u| String::from_utf8_lossy(u.userid().value()).into_owned())
4718            .collect::<Vec<String>>();
4719        userids.sort();
4720
4721        assert_eq!(userids,
4722                   &[ "Neal H. Walfield <neal@g10code.com>",
4723                      "Neal H. Walfield <neal@gnupg.org>",
4724                      "Neal H. Walfield <neal@pep-project.org>",
4725                      "Neal H. Walfield <neal@pep.foundation>",
4726                      "Neal H. Walfield <neal@sequoia-pgp.org>",
4727                      "Neal H. Walfield <neal@walfield.org>",
4728                   ]);
4729
4730        let mut subkeys = cert.subkeys()
4731            .map(|sk| Some(sk.key().keyid()))
4732            .collect::<Vec<Option<KeyID>>>();
4733        subkeys.sort();
4734        assert_eq!(subkeys,
4735                   &[ "7223B56678E02528".parse().ok(),
4736                      "A3506AFB820ABD08".parse().ok(),
4737                      "C2B819056C652598".parse().ok(),
4738                   ]);
4739
4740        // DKG's key has all the self-signatures moved to the last
4741        // subkey; all user ids/user attributes/subkeys have nothing.
4742        let cert =
4743            Cert::from_bytes(crate::tests::key("dkg-sigs-out-of-order.pgp")).unwrap();
4744
4745        let mut userids = cert.userids()
4746            .map(|u| String::from_utf8_lossy(u.userid().value()).into_owned())
4747            .collect::<Vec<String>>();
4748        userids.sort();
4749
4750        assert_eq!(userids,
4751                   &[ "Daniel Kahn Gillmor <dkg-debian.org@fifthhorseman.net>",
4752                      "Daniel Kahn Gillmor <dkg@aclu.org>",
4753                      "Daniel Kahn Gillmor <dkg@astro.columbia.edu>",
4754                      "Daniel Kahn Gillmor <dkg@debian.org>",
4755                      "Daniel Kahn Gillmor <dkg@fifthhorseman.net>",
4756                      "Daniel Kahn Gillmor <dkg@openflows.com>",
4757                   ]);
4758
4759        assert_eq!(cert.user_attributes.len(), 1);
4760
4761        let mut subkeys = cert.subkeys()
4762            .map(|sk| Some(sk.key().keyid()))
4763            .collect::<Vec<Option<KeyID>>>();
4764        subkeys.sort();
4765        assert_eq!(subkeys,
4766                   &[ "1075 8EBD BD7C FAB5".parse().ok(),
4767                      "1258 68EA 4BFA 08E4".parse().ok(),
4768                      "1498 ADC6 C192 3237".parse().ok(),
4769                      "24EC FF5A FF68 370A".parse().ok(),
4770                      "3714 7292 14D5 DA70".parse().ok(),
4771                      "3B7A A7F0 14E6 9B5A".parse().ok(),
4772                      "5B58 DCF9 C341 6611".parse().ok(),
4773                      "A524 01B1 1BFD FA5C".parse().ok(),
4774                      "A70A 96E1 439E A852".parse().ok(),
4775                      "C61B D3EC 2148 4CFF".parse().ok(),
4776                      "CAEF A883 2167 5333".parse().ok(),
4777                      "DC10 4C4E 0CA7 57FB".parse().ok(),
4778                      "E3A3 2229 449B 0350".parse().ok(),
4779                   ]);
4780
4781    }
4782
4783    /// Tests how we deal with v3 keys, certs, and certifications.
4784    #[test]
4785    fn v3_packets() {
4786        // v3 primary keys are not supported.
4787
4788        let cert = Cert::from_bytes(crate::tests::key("john-v3.pgp"));
4789        assert_match!(Error::UnsupportedCert(..)
4790                      = cert.err().unwrap().downcast::<Error>().unwrap());
4791
4792        let cert = Cert::from_bytes(crate::tests::key("john-v3-secret.pgp"));
4793        assert_match!(Error::UnsupportedCert(..)
4794                      = cert.err().unwrap().downcast::<Error>().unwrap());
4795
4796        // Lutz's key is a v3 key.
4797        let cert = Cert::from_bytes(crate::tests::key("lutz.pgp"));
4798        assert_match!(Error::UnsupportedCert(..)
4799                      = cert.err().unwrap().downcast::<Error>().unwrap());
4800
4801        // v3 certifications are not supported
4802
4803        // dkg's includes some v3 signatures.
4804        let cert = Cert::from_bytes(crate::tests::key("dkg.pgp"));
4805        assert!(cert.is_ok(), "dkg.pgp: {:?}", cert);
4806    }
4807
4808    #[test]
4809    fn keyring_with_v3_public_keys() {
4810        let dkg = crate::tests::key("dkg.pgp");
4811        let lutz = crate::tests::key("lutz.pgp");
4812
4813        let cert = Cert::from_bytes(dkg);
4814        assert!(cert.is_ok(), "dkg.pgp: {:?}", cert);
4815
4816        // Keyring with two good keys
4817        let mut combined = vec![];
4818        combined.extend_from_slice(dkg);
4819        combined.extend_from_slice(dkg);
4820        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4821            .map(|certr| certr.is_ok())
4822            .collect::<Vec<bool>>();
4823        assert_eq!(certs, &[ true, true ]);
4824
4825        // Keyring with a good key, and a bad key.
4826        let mut combined = vec![];
4827        combined.extend_from_slice(dkg);
4828        combined.extend_from_slice(lutz);
4829        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4830            .map(|certr| certr.is_ok())
4831            .collect::<Vec<bool>>();
4832        assert_eq!(certs, &[ true, false ]);
4833
4834        // Keyring with a bad key, and a good key.
4835        let mut combined = vec![];
4836        combined.extend_from_slice(lutz);
4837        combined.extend_from_slice(dkg);
4838        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4839            .map(|certr| certr.is_ok())
4840            .collect::<Vec<bool>>();
4841        assert_eq!(certs, &[ false, true ]);
4842
4843        // Keyring with a good key, a bad key, and a good key.
4844        let mut combined = vec![];
4845        combined.extend_from_slice(dkg);
4846        combined.extend_from_slice(lutz);
4847        combined.extend_from_slice(dkg);
4848        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4849            .map(|certr| certr.is_ok())
4850            .collect::<Vec<bool>>();
4851        assert_eq!(certs, &[ true, false, true ]);
4852
4853        // Keyring with a good key, a bad key, and a bad key.
4854        let mut combined = vec![];
4855        combined.extend_from_slice(dkg);
4856        combined.extend_from_slice(lutz);
4857        combined.extend_from_slice(lutz);
4858        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4859            .map(|certr| certr.is_ok())
4860            .collect::<Vec<bool>>();
4861        assert_eq!(certs, &[ true, false, false ]);
4862
4863        // Keyring with a good key, a bad key, a bad key, and a good key.
4864        let mut combined = vec![];
4865        combined.extend_from_slice(dkg);
4866        combined.extend_from_slice(lutz);
4867        combined.extend_from_slice(lutz);
4868        combined.extend_from_slice(dkg);
4869        let certs = CertParser::from_bytes(&combined[..]).unwrap()
4870            .map(|certr| certr.is_ok())
4871            .collect::<Vec<bool>>();
4872        assert_eq!(certs, &[ true, false, false, true ]);
4873    }
4874
4875    #[test]
4876    fn merge_with_incomplete_update() {
4877        let p = &P::new();
4878
4879        let cert = Cert::from_bytes(crate::tests::key("about-to-expire.expired.pgp"))
4880            .unwrap();
4881        cert.primary_key().with_policy(p, None).unwrap().alive().unwrap_err();
4882
4883        let update =
4884            Cert::from_bytes(crate::tests::key("about-to-expire.update-no-uid.pgp"))
4885            .unwrap();
4886        let cert = cert.merge_public_and_secret(update).unwrap();
4887        cert.primary_key().with_policy(p, None).unwrap().alive().unwrap();
4888    }
4889
4890    #[test]
4891    fn packet_pile_roundtrip() {
4892        // Make sure Cert::try_from(Cert::to_packet_pile(cert))
4893        // does a clean round trip.
4894
4895        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
4896        let cert2
4897            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4898        assert_eq!(cert, cert2);
4899
4900        let cert = Cert::from_bytes(
4901            crate::tests::key("already-revoked-direct-revocation.pgp")).unwrap();
4902        let cert2
4903            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4904        assert_eq!(cert, cert2);
4905
4906        let cert = Cert::from_bytes(
4907            crate::tests::key("already-revoked-userid-revocation.pgp")).unwrap();
4908        let cert2
4909            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4910        assert_eq!(cert, cert2);
4911
4912        let cert = Cert::from_bytes(
4913            crate::tests::key("already-revoked-subkey-revocation.pgp")).unwrap();
4914        let cert2
4915            = Cert::try_from(cert.clone().into_packet_pile()).unwrap();
4916        assert_eq!(cert, cert2);
4917    }
4918
4919    #[test]
4920    fn insert_packets_add_sig() {
4921        use crate::armor;
4922        use crate::packet::Tag;
4923
4924        // Merge the revocation certificate into the Cert and make sure
4925        // it shows up.
4926        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
4927
4928        let rev = crate::tests::key("already-revoked.rev");
4929        let rev = PacketPile::from_reader(armor::Reader::from_reader(rev, None))
4930            .unwrap();
4931
4932        let rev : Vec<Packet> = rev.into_children().collect();
4933        assert_eq!(rev.len(), 1);
4934        assert_eq!(rev[0].tag(), Tag::Signature);
4935
4936        let packets_pre_merge = cert.clone().into_packets().count();
4937        let cert = cert.insert_packets(rev).unwrap().0;
4938        let packets_post_merge = cert.clone().into_packets().count();
4939        assert_eq!(packets_post_merge, packets_pre_merge + 1);
4940    }
4941
4942    #[test]
4943    fn insert_packets_update_sig() -> Result<()> {
4944        use std::time::Duration;
4945
4946        use crate::packet::signature::subpacket::Subpacket;
4947        use crate::packet::signature::subpacket::SubpacketValue;
4948
4949        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
4950            .generate()?;
4951        let packets = cert.clone().into_packets().count();
4952
4953        // Merge a signature with different unhashed subpacket areas.
4954        // Make sure only the last variant is merged.
4955        let sig = cert.primary_key().self_signatures().next()
4956            .expect("binding signature");
4957
4958        let a = Subpacket::new(
4959            SubpacketValue::SignatureExpirationTime(
4960                Duration::new(1, 0).try_into()?),
4961            false)?;
4962        let b = Subpacket::new(
4963            SubpacketValue::SignatureExpirationTime(
4964                Duration::new(2, 0).try_into()?),
4965            false)?;
4966
4967        let mut sig_a = sig.clone();
4968        sig_a.unhashed_area_mut().add(a)?;
4969        let mut sig_b = sig.clone();
4970        sig_b.unhashed_area_mut().add(b)?;
4971
4972        // Insert sig_a, make sure it (and it alone) appears.
4973        let cert2 = cert.clone().insert_packets(sig_a.clone())?.0;
4974        let mut sigs = cert2.primary_key().self_signatures();
4975        assert_eq!(sigs.next(), Some(&sig_a));
4976        assert!(sigs.next().is_none());
4977        assert_eq!(cert2.clone().into_packets().count(), packets);
4978
4979        // Insert sig_b, make sure it (and it alone) appears.
4980        let cert2 = cert.clone().insert_packets(sig_b.clone())?.0;
4981        let mut sigs = cert2.primary_key().self_signatures();
4982        assert_eq!(sigs.next(), Some(&sig_b));
4983        assert!(sigs.next().is_none());
4984        assert_eq!(cert2.clone().into_packets().count(), packets);
4985
4986        // Insert sig_a and sig_b.  Make sure sig_b (and it alone)
4987        // appears.
4988        let cert2 = cert.clone().insert_packets(
4989            vec![ sig_a.clone(), sig_b.clone() ])?.0;
4990        let mut sigs = cert2.primary_key().self_signatures();
4991        assert_eq!(sigs.next(), Some(&sig_b));
4992        assert!(sigs.next().is_none());
4993        assert_eq!(cert2.clone().into_packets().count(), packets);
4994
4995        // Insert sig_b and sig_a.  Make sure sig_a (and it alone)
4996        // appears.
4997        let cert2 = cert.clone().insert_packets(
4998            vec![ sig_b.clone(), sig_a.clone() ])?.0;
4999        let mut sigs = cert2.primary_key().self_signatures();
5000        assert_eq!(sigs.next(), Some(&sig_a));
5001        assert!(sigs.next().is_none());
5002        assert_eq!(cert2.clone().into_packets().count(), packets);
5003
5004        Ok(())
5005    }
5006
5007    #[test]
5008    fn insert_packets_add_userid() -> Result<()> {
5009        let (cert, _) = CertBuilder::general_purpose(Some("a"))
5010            .generate()?;
5011        let packets = cert.clone().into_packets().count();
5012
5013        let uid_a = UserID::from("a");
5014        let uid_b = UserID::from("b");
5015
5016        // Insert a, make sure it appears once.
5017        let cert2 = cert.clone().insert_packets(uid_a.clone())?.0;
5018        let mut uids = cert2.userids();
5019        assert_eq!(uids.next().unwrap().userid(), &uid_a);
5020        assert!(uids.next().is_none());
5021        assert_eq!(cert2.clone().into_packets().count(), packets);
5022
5023        // Insert b, make sure it also appears.
5024        let cert2 = cert.clone().insert_packets(uid_b.clone())?.0;
5025        let mut uids: Vec<UserID>
5026            = cert2.userids().map(|ua| ua.userid().clone()).collect();
5027        uids.sort();
5028        let mut uids = uids.iter();
5029        assert_eq!(uids.next().unwrap(), &uid_a);
5030        assert_eq!(uids.next().unwrap(), &uid_b);
5031        assert!(uids.next().is_none());
5032        assert_eq!(cert2.clone().into_packets().count(), packets + 1);
5033
5034        Ok(())
5035    }
5036
5037    #[test]
5038    fn insert_packets_update_key() -> Result<()> {
5039        use crate::crypto::Password;
5040
5041        let (cert, _) = CertBuilder::new().generate()?;
5042        let packets = cert.clone().into_packets().count();
5043        assert_eq!(cert.keys().count(), 1);
5044
5045        let key = cert.keys().secret().next().unwrap().key()
5046            .role_as_primary();
5047        assert!(key.has_secret());
5048        let key_a = key.clone().encrypt_secret(&Password::from("a"))?;
5049        let key_b = key.clone().encrypt_secret(&Password::from("b"))?;
5050
5051        // Insert variant a.
5052        let cert2 = cert.clone().insert_packets(key_a.clone())?.0;
5053        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5054                   &key_a);
5055        assert_eq!(cert2.clone().into_packets().count(), packets);
5056
5057        // Insert variant b.
5058        let cert2 = cert.clone().insert_packets(key_b.clone())?.0;
5059        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5060                   &key_b);
5061        assert_eq!(cert2.clone().into_packets().count(), packets);
5062
5063        // Insert variant a then b.  We should keep b.
5064        let cert2 = cert.clone().insert_packets(
5065            vec![ key_a.clone(), key_b.clone() ])?.0;
5066        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5067                   &key_b);
5068        assert_eq!(cert2.clone().into_packets().count(), packets);
5069
5070        // Insert variant b then a.  We should keep a.
5071        let cert2 = cert.clone().insert_packets(
5072            vec![ key_b.clone(), key_a.clone() ])?.0;
5073        assert_eq!(cert2.primary_key().key().parts_as_secret().unwrap(),
5074                   &key_a);
5075        assert_eq!(cert2.clone().into_packets().count(), packets);
5076
5077        Ok(())
5078    }
5079
5080    #[test]
5081    fn set_validity_period() {
5082        let p = &P::new();
5083
5084        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
5085            .generate().unwrap();
5086        assert_eq!(cert.clone().into_packet_pile().children().count(),
5087                   1 // primary key
5088                   + 1 // direct key signature
5089                   + 1 // userid
5090                   + 1 // binding signature
5091                   + 1 // subkey
5092                   + 1 // binding signature
5093                   + 1 // subkey
5094                   + 1 // binding signature
5095        );
5096        let cert = check_set_validity_period(p, cert);
5097        assert_eq!(cert.clone().into_packet_pile().children().count(),
5098                   1 // primary key
5099                   + 1 // direct key signature
5100                   + 2 // two new direct key signatures
5101                   + 1 // userid
5102                   + 1 // binding signature
5103                   + 2 // two new binding signatures
5104                   + 1 // subkey
5105                   + 1 // binding signature
5106                   + 1 // subkey
5107                   + 1 // binding signature
5108        );
5109    }
5110
5111    #[test]
5112    fn set_validity_period_two_uids() -> Result<()> {
5113        use quickcheck::{Arbitrary, Gen};
5114        let mut gen = Gen::new(16);
5115        let p = &P::new();
5116
5117        let userid1 = UserID::arbitrary(&mut gen);
5118        // The two user ids need to be unique.
5119        let mut userid2 = UserID::arbitrary(&mut gen);
5120        while userid1 == userid2 {
5121            userid2 = UserID::arbitrary(&mut gen);
5122        }
5123
5124        let (cert, _) = CertBuilder::general_purpose(
5125            Some(userid1))
5126            .add_userid(userid2)
5127            .generate()?;
5128        let primary_uid = cert.with_policy(p, None)?.primary_userid()?.userid().clone();
5129        assert_eq!(cert.clone().into_packet_pile().children().count(),
5130                   1 // primary key
5131                   + 1 // direct key signature
5132                   + 1 // userid
5133                   + 1 // binding signature
5134                   + 1 // userid
5135                   + 1 // binding signature
5136                   + 1 // subkey
5137                   + 1 // binding signature
5138                   + 1 // subkey
5139                   + 1 // binding signature
5140        );
5141        let cert = check_set_validity_period(p, cert);
5142        assert_eq!(cert.clone().into_packet_pile().children().count(),
5143                   1 // primary key
5144                   + 1 // direct key signature
5145                   + 2 // two new direct key signatures
5146                   + 1 // userid
5147                   + 1 // binding signature
5148                   + 2 // two new binding signatures
5149                   + 1 // userid
5150                   + 1 // binding signature
5151                   + 2 // two new binding signatures
5152                   + 1 // subkey
5153                   + 1 // binding signature
5154                   + 1 // subkey
5155                   + 1 // binding signature
5156        );
5157        assert_eq!(&primary_uid, cert.with_policy(p, None)?.primary_userid()?.userid());
5158        Ok(())
5159    }
5160
5161    #[test]
5162    fn set_validity_period_uidless() {
5163        use crate::types::Duration;
5164        let p = &P::new();
5165
5166        let (cert, _) = CertBuilder::new()
5167            .set_validity_period(None) // Just to assert this works.
5168            .set_validity_period(Some(Duration::weeks(52).unwrap().try_into().unwrap()))
5169            .generate().unwrap();
5170        assert_eq!(cert.clone().into_packet_pile().children().count(),
5171                   1 // primary key
5172                   + 1 // direct key signature
5173        );
5174        let cert = check_set_validity_period(p, cert);
5175        assert_eq!(cert.clone().into_packet_pile().children().count(),
5176                   1 // primary key
5177                   + 1 // direct key signature
5178                   + 2 // two new direct key signatures
5179        );
5180    }
5181    fn check_set_validity_period(policy: &dyn Policy, cert: Cert) -> Cert {
5182        let now = cert.primary_key().key().creation_time();
5183        let a_sec = time::Duration::new(1, 0);
5184
5185        let expiry_orig = cert.primary_key().with_policy(policy, now).unwrap()
5186            .key_validity_period()
5187            .expect("Keys expire by default.");
5188
5189        let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5190            .unwrap().into_keypair().unwrap();
5191
5192        // Clear the expiration.
5193        let as_of1 = now + time::Duration::new(10, 0);
5194        let cert = cert.set_validity_period_as_of(
5195            policy, &mut keypair, None, as_of1).unwrap();
5196        {
5197            // If t < as_of1, we should get the original expiry.
5198            assert_eq!(cert.primary_key().with_policy(policy, now).unwrap()
5199                           .key_validity_period(),
5200                       Some(expiry_orig));
5201            assert_eq!(cert.primary_key().with_policy(policy, as_of1 - a_sec).unwrap()
5202                           .key_validity_period(),
5203                       Some(expiry_orig));
5204            // If t >= as_of1, we should get the new expiry.
5205            assert_eq!(cert.primary_key().with_policy(policy, as_of1).unwrap()
5206                           .key_validity_period(),
5207                       None);
5208        }
5209
5210        // Shorten the expiry.  (The default expiration should be at
5211        // least a few weeks, so removing an hour should still keep us
5212        // over 0.)
5213        let expiry_new = expiry_orig - time::Duration::new(60 * 60, 0);
5214        assert!(expiry_new > time::Duration::new(0, 0));
5215
5216        let as_of2 = as_of1 + time::Duration::new(10, 0);
5217        let cert = cert.set_validity_period_as_of(
5218            policy, &mut keypair, Some(expiry_new), as_of2).unwrap();
5219        {
5220            // If t < as_of1, we should get the original expiry.
5221            assert_eq!(cert.primary_key().with_policy(policy, now).unwrap()
5222                           .key_validity_period(),
5223                       Some(expiry_orig));
5224            assert_eq!(cert.primary_key().with_policy(policy, as_of1 - a_sec).unwrap()
5225                           .key_validity_period(),
5226                       Some(expiry_orig));
5227            // If as_of1 <= t < as_of2, we should get the second
5228            // expiry (None).
5229            assert_eq!(cert.primary_key().with_policy(policy, as_of1).unwrap()
5230                           .key_validity_period(),
5231                       None);
5232            assert_eq!(cert.primary_key().with_policy(policy, as_of2 - a_sec).unwrap()
5233                           .key_validity_period(),
5234                       None);
5235            // If t <= as_of2, we should get the new expiry.
5236            assert_eq!(cert.primary_key().with_policy(policy, as_of2).unwrap()
5237                           .key_validity_period(),
5238                       Some(expiry_new));
5239        }
5240        cert
5241    }
5242
5243    #[test]
5244    fn direct_key_sig() {
5245        use crate::types::SignatureType;
5246        // XXX: testing sequoia against itself isn't optimal, but I couldn't
5247        // find a tool to generate direct key signatures :-(
5248
5249        let p = &P::new();
5250
5251        let (cert1, _) = CertBuilder::new().generate().unwrap();
5252        let mut buf = Vec::default();
5253
5254        cert1.serialize(&mut buf).unwrap();
5255        let cert2 = Cert::from_bytes(&buf).unwrap();
5256
5257        assert_eq!(
5258            cert2.primary_key().with_policy(p, None).unwrap()
5259                .direct_key_signature().unwrap().typ(),
5260            SignatureType::DirectKey);
5261        assert_eq!(cert2.userids().count(), 0);
5262    }
5263
5264    #[test]
5265    fn revoked() {
5266        fn check(cert: &Cert, direct_revoked: bool,
5267                 userid_revoked: bool, subkey_revoked: bool) {
5268            let p = &P::new();
5269
5270            // If we have a user id---even if it is revoked---we have
5271            // a primary key signature.
5272            let typ = cert.primary_key().with_policy(p, None).unwrap()
5273                .binding_signature().typ();
5274            assert_eq!(typ, SignatureType::PositiveCertification,
5275                       "{:#?}", cert);
5276
5277            let revoked = cert.revocation_status(p, None);
5278            if direct_revoked {
5279                assert_match!(RevocationStatus::Revoked(_) = revoked,
5280                              "{:#?}", cert);
5281            } else {
5282                assert_eq!(revoked, RevocationStatus::NotAsFarAsWeKnow,
5283                           "{:#?}", cert);
5284            }
5285
5286            for userid in cert.userids().with_policy(p, None) {
5287                let typ = userid.binding_signature().typ();
5288                assert_eq!(typ, SignatureType::PositiveCertification,
5289                           "{:#?}", cert);
5290
5291                let revoked = userid.revocation_status();
5292                if userid_revoked {
5293                    assert_match!(RevocationStatus::Revoked(_) = revoked);
5294                } else {
5295                    assert_eq!(RevocationStatus::NotAsFarAsWeKnow, revoked,
5296                               "{:#?}", cert);
5297                }
5298            }
5299
5300            for subkey in cert.subkeys() {
5301                let typ = subkey.binding_signature(p, None).unwrap().typ();
5302                assert_eq!(typ, SignatureType::SubkeyBinding,
5303                           "{:#?}", cert);
5304
5305                let revoked = subkey.revocation_status(p, None);
5306                if subkey_revoked {
5307                    assert_match!(RevocationStatus::Revoked(_) = revoked);
5308                } else {
5309                    assert_eq!(RevocationStatus::NotAsFarAsWeKnow, revoked,
5310                               "{:#?}", cert);
5311                }
5312            }
5313        }
5314
5315        let cert = Cert::from_bytes(crate::tests::key("already-revoked.pgp")).unwrap();
5316        check(&cert, false, false, false);
5317
5318        let d = Cert::from_bytes(
5319            crate::tests::key("already-revoked-direct-revocation.pgp")).unwrap();
5320        check(&d, true, false, false);
5321
5322        check(&cert.clone().merge_public_and_secret(d.clone()).unwrap(), true, false, false);
5323        // Make sure the merge order does not matter.
5324        check(&d.clone().merge_public_and_secret(cert.clone()).unwrap(), true, false, false);
5325
5326        let u = Cert::from_bytes(
5327            crate::tests::key("already-revoked-userid-revocation.pgp")).unwrap();
5328        check(&u, false, true, false);
5329
5330        check(&cert.clone().merge_public_and_secret(u.clone()).unwrap(), false, true, false);
5331        check(&u.clone().merge_public_and_secret(cert.clone()).unwrap(), false, true, false);
5332
5333        let k = Cert::from_bytes(
5334            crate::tests::key("already-revoked-subkey-revocation.pgp")).unwrap();
5335        check(&k, false, false, true);
5336
5337        check(&cert.clone().merge_public_and_secret(k.clone()).unwrap(), false, false, true);
5338        check(&k.clone().merge_public_and_secret(cert.clone()).unwrap(), false, false, true);
5339
5340        // direct and user id revocation.
5341        check(&d.clone().merge_public_and_secret(u.clone()).unwrap(), true, true, false);
5342        check(&u.clone().merge_public_and_secret(d.clone()).unwrap(), true, true, false);
5343
5344        // direct and subkey revocation.
5345        check(&d.clone().merge_public_and_secret(k.clone()).unwrap(), true, false, true);
5346        check(&k.clone().merge_public_and_secret(d.clone()).unwrap(), true, false, true);
5347
5348        // user id and subkey revocation.
5349        check(&u.clone().merge_public_and_secret(k.clone()).unwrap(), false, true, true);
5350        check(&k.clone().merge_public_and_secret(u.clone()).unwrap(), false, true, true);
5351
5352        // direct, user id and subkey revocation.
5353        check(&d.clone().merge_public_and_secret(u.clone().merge_public_and_secret(k.clone()).unwrap()).unwrap(),
5354              true, true, true);
5355        check(&d.clone().merge_public_and_secret(k.clone().merge_public_and_secret(u.clone()).unwrap()).unwrap(),
5356              true, true, true);
5357    }
5358
5359    #[test]
5360    fn revoke() {
5361        let p = &P::new();
5362
5363        let (cert, _) = CertBuilder::general_purpose(Some("Test"))
5364            .generate().unwrap();
5365        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5366                   cert.revocation_status(p, None));
5367
5368        let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5369            .unwrap().into_keypair().unwrap();
5370
5371        let sig = CertRevocationBuilder::new()
5372            .set_reason_for_revocation(
5373                ReasonForRevocation::KeyCompromised,
5374                b"It was the maid :/").unwrap()
5375            .build(&mut keypair, &cert, None)
5376            .unwrap();
5377        assert_eq!(sig.typ(), SignatureType::KeyRevocation);
5378        assert_eq!(sig.issuers().collect::<Vec<_>>(),
5379                   vec![ &cert.keyid() ]);
5380        assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
5381                   vec![ &cert.fingerprint() ]);
5382
5383        let cert = cert.insert_packets(sig).unwrap().0;
5384        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, None));
5385
5386
5387        // Have other revoke cert.
5388        let (other, _) = CertBuilder::general_purpose(Some("Test 2"))
5389            .generate().unwrap();
5390
5391        let mut keypair = other.primary_key().key().clone().parts_into_secret()
5392            .unwrap().into_keypair().unwrap();
5393
5394        let sig = CertRevocationBuilder::new()
5395            .set_reason_for_revocation(
5396                ReasonForRevocation::KeyCompromised,
5397                b"It was the maid :/").unwrap()
5398            .build(&mut keypair, &cert, None)
5399            .unwrap();
5400
5401        assert_eq!(sig.typ(), SignatureType::KeyRevocation);
5402        assert_eq!(sig.issuers().collect::<Vec<_>>(),
5403                   vec![ &other.keyid() ]);
5404        assert_eq!(sig.issuer_fingerprints().collect::<Vec<_>>(),
5405                   vec![ &other.fingerprint() ]);
5406    }
5407
5408    #[test]
5409    fn revoke_subkey() {
5410        let p = &P::new();
5411        let (cert, _) = CertBuilder::new()
5412            .add_transport_encryption_subkey()
5413            .generate().unwrap();
5414
5415        let sig = {
5416            let subkey = cert.subkeys().next().unwrap();
5417            assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5418                       subkey.revocation_status(p, None));
5419
5420            let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5421                .unwrap().into_keypair().unwrap();
5422            SubkeyRevocationBuilder::new()
5423                .set_reason_for_revocation(
5424                    ReasonForRevocation::UIDRetired,
5425                    b"It was the maid :/").unwrap()
5426                .build(&mut keypair, &cert, subkey.key(), None)
5427                .unwrap()
5428        };
5429        assert_eq!(sig.typ(), SignatureType::SubkeyRevocation);
5430        let cert = cert.insert_packets(sig).unwrap().0;
5431        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5432                   cert.revocation_status(p, None));
5433
5434        let subkey = cert.subkeys().next().unwrap();
5435        assert_match!(RevocationStatus::Revoked(_)
5436                      = subkey.revocation_status(p, None));
5437    }
5438
5439    #[test]
5440    fn revoke_uid() {
5441        let p = &P::new();
5442        let (cert, _) = CertBuilder::new()
5443            .add_userid("Test1")
5444            .add_userid("Test2")
5445            .generate().unwrap();
5446
5447        let sig = {
5448            let uid = cert.userids().with_policy(p, None).nth(1).unwrap();
5449            assert_eq!(RevocationStatus::NotAsFarAsWeKnow, uid.revocation_status());
5450
5451            let mut keypair = cert.primary_key().key().clone().parts_into_secret()
5452                .unwrap().into_keypair().unwrap();
5453            UserIDRevocationBuilder::new()
5454                .set_reason_for_revocation(
5455                    ReasonForRevocation::UIDRetired,
5456                    b"It was the maid :/").unwrap()
5457                .build(&mut keypair, &cert, uid.userid(), None)
5458                .unwrap()
5459        };
5460        assert_eq!(sig.typ(), SignatureType::CertificationRevocation);
5461        let cert = cert.insert_packets(sig).unwrap().0;
5462        assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
5463                   cert.revocation_status(p, None));
5464
5465        let uid = cert.userids().with_policy(p, None).nth(1).unwrap();
5466        assert_match!(RevocationStatus::Revoked(_) = uid.revocation_status());
5467    }
5468
5469    #[test]
5470    fn key_revoked() {
5471        use crate::types::Features;
5472        use crate::packet::key::Key6;
5473        use rand::{thread_rng, Rng, distributions::Open01};
5474
5475        let p = &P::new();
5476
5477        /*
5478         * t1: 1st binding sig ctime
5479         * t2: soft rev sig ctime
5480         * t3: 2nd binding sig ctime
5481         * t4: hard rev sig ctime
5482         *
5483         * [0,t1): invalid, but not revoked
5484         * [t1,t2): valid (not revocations)
5485         * [t2,t3): revoked (soft revocation)
5486         * [t3,t4): valid again (new self sig)
5487         * [t4,inf): hard revocation (hard revocation)
5488         *
5489         * Once the hard revocation is merged, then the Cert is
5490         * considered revoked at all times.
5491         */
5492        let t1 = time::UNIX_EPOCH + time::Duration::new(946681200, 0);  // 2000-1-1
5493        let t2 = time::UNIX_EPOCH + time::Duration::new(978303600, 0);  // 2001-1-1
5494        let t3 = time::UNIX_EPOCH + time::Duration::new(1009839600, 0); // 2002-1-1
5495        let t4 = time::UNIX_EPOCH + time::Duration::new(1041375600, 0); // 2003-1-1
5496
5497        let mut key: key::SecretKey
5498            = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
5499        key.set_creation_time(t1).unwrap();
5500        let mut pair = key.clone().into_keypair().unwrap();
5501        let (bind1, rev1, bind2, rev2) = {
5502            let bind1 = signature::SignatureBuilder::new(SignatureType::DirectKey)
5503                .set_features(Features::sequoia()).unwrap()
5504                .set_key_flags(KeyFlags::empty()).unwrap()
5505                .set_signature_creation_time(t1).unwrap()
5506                .set_key_validity_period(Some(time::Duration::new(10 * 52 * 7 * 24 * 60 * 60, 0))).unwrap()
5507                .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
5508                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5509
5510            let rev1 = signature::SignatureBuilder::new(SignatureType::KeyRevocation)
5511                .set_signature_creation_time(t2).unwrap()
5512                .set_reason_for_revocation(ReasonForRevocation::KeySuperseded,
5513                                           &b""[..]).unwrap()
5514                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5515
5516            let bind2 = signature::SignatureBuilder::new(SignatureType::DirectKey)
5517                .set_features(Features::sequoia()).unwrap()
5518                .set_key_flags(KeyFlags::empty()).unwrap()
5519                .set_signature_creation_time(t3).unwrap()
5520                .set_key_validity_period(Some(time::Duration::new(10 * 52 * 7 * 24 * 60 * 60, 0))).unwrap()
5521                .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
5522                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5523
5524            let rev2 = signature::SignatureBuilder::new(SignatureType::KeyRevocation)
5525                .set_signature_creation_time(t4).unwrap()
5526                .set_reason_for_revocation(ReasonForRevocation::KeyCompromised,
5527                                           &b""[..]).unwrap()
5528                .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
5529
5530            (bind1, rev1, bind2, rev2)
5531        };
5532        let pk : key::PublicKey = key.into();
5533        let cert = Cert::try_from(vec![
5534            pk.into(),
5535            bind1.into(),
5536            bind2.into(),
5537            rev1.into()
5538        ]).unwrap();
5539
5540        let f1: f32 = thread_rng().sample(Open01);
5541        let f2: f32 = thread_rng().sample(Open01);
5542        let f3: f32 = thread_rng().sample(Open01);
5543        let f4: f32 = thread_rng().sample(Open01);
5544        let te1 = t1 - time::Duration::new((60. * 60. * 24. * 300.0 * f1) as u64, 0);
5545        let t12 = t1 + time::Duration::new((60. * 60. * 24. * 300.0 * f2) as u64, 0);
5546        let t23 = t2 + time::Duration::new((60. * 60. * 24. * 300.0 * f3) as u64, 0);
5547        let t34 = t3 + time::Duration::new((60. * 60. * 24. * 300.0 * f4) as u64, 0);
5548
5549        assert_eq!(cert.revocation_status(p, te1), RevocationStatus::NotAsFarAsWeKnow);
5550        assert_eq!(cert.revocation_status(p, t12), RevocationStatus::NotAsFarAsWeKnow);
5551        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t23));
5552        assert_eq!(cert.revocation_status(p, t34), RevocationStatus::NotAsFarAsWeKnow);
5553
5554        // Merge in the hard revocation.
5555        let cert = cert.insert_packets(rev2).unwrap().0;
5556        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, te1));
5557        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t12));
5558        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t23));
5559        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t34));
5560        assert_match!(RevocationStatus::Revoked(_) = cert.revocation_status(p, t4));
5561        assert_match!(RevocationStatus::Revoked(_)
5562                      = cert.revocation_status(p, crate::now()));
5563    }
5564
5565    #[test]
5566    fn key_revoked2() {
5567        tracer!(true, "cert_revoked2", 0);
5568
5569        let p = &P::new();
5570
5571        fn cert_revoked<T>(p: &dyn Policy, cert: &Cert, t: T) -> bool
5572            where T: Into<Option<time::SystemTime>>
5573        {
5574            !matches!(
5575                cert.revocation_status(p, t),
5576                RevocationStatus::NotAsFarAsWeKnow
5577            )
5578        }
5579
5580        fn subkey_revoked<T>(p: &dyn Policy, cert: &Cert, t: T) -> bool
5581            where T: Into<Option<time::SystemTime>>
5582        {
5583            !matches!(
5584                cert.subkeys().next().unwrap().bundle().revocation_status(p, t),
5585                RevocationStatus::NotAsFarAsWeKnow
5586            )
5587        }
5588
5589        let tests : [(&str, Box<dyn Fn(&dyn Policy, &Cert, _) -> bool>); 2] = [
5590            ("cert", Box::new(cert_revoked)),
5591            ("subkey", Box::new(subkey_revoked)),
5592        ];
5593
5594        for (f, revoked) in tests.iter()
5595        {
5596            t!("Checking {} revocation", f);
5597
5598            t!("Normal key");
5599            let cert = Cert::from_bytes(
5600                crate::tests::key(
5601                    &format!("really-revoked-{}-0-public.pgp", f))).unwrap();
5602            let selfsig0 = cert.primary_key().with_policy(p, None).unwrap()
5603                .binding_signature().signature_creation_time().unwrap();
5604
5605            assert!(!revoked(p, &cert, Some(selfsig0)));
5606            assert!(!revoked(p, &cert, None));
5607
5608            t!("Soft revocation");
5609            let cert = cert.merge_public_and_secret(
5610                Cert::from_bytes(
5611                    crate::tests::key(
5612                        &format!("really-revoked-{}-1-soft-revocation.pgp", f))
5613                ).unwrap()).unwrap();
5614            // A soft revocation made after `t` is ignored when
5615            // determining whether the key is revoked at time `t`.
5616            assert!(!revoked(p, &cert, Some(selfsig0)));
5617            assert!(revoked(p, &cert, None));
5618
5619            t!("New self signature");
5620            let cert = cert.merge_public_and_secret(
5621                Cert::from_bytes(
5622                    crate::tests::key(
5623                        &format!("really-revoked-{}-2-new-self-sig.pgp", f))
5624                ).unwrap()).unwrap();
5625            assert!(!revoked(p, &cert, Some(selfsig0)));
5626            // Newer self-sig override older soft revocations.
5627            assert!(!revoked(p, &cert, None));
5628
5629            t!("Hard revocation");
5630            let cert = cert.merge_public_and_secret(
5631                Cert::from_bytes(
5632                    crate::tests::key(
5633                        &format!("really-revoked-{}-3-hard-revocation.pgp", f))
5634                ).unwrap()).unwrap();
5635            // Hard revocations trump all.
5636            assert!(revoked(p, &cert, Some(selfsig0)));
5637            assert!(revoked(p, &cert, None));
5638
5639            t!("New self signature");
5640            let cert = cert.merge_public_and_secret(
5641                Cert::from_bytes(
5642                    crate::tests::key(
5643                        &format!("really-revoked-{}-4-new-self-sig.pgp", f))
5644                ).unwrap()).unwrap();
5645            assert!(revoked(p, &cert, Some(selfsig0)));
5646            assert!(revoked(p, &cert, None));
5647        }
5648    }
5649
5650    #[test]
5651    fn userid_revoked2() {
5652        fn check_userids<T>(p: &dyn Policy, cert: &Cert, revoked: bool, t: T)
5653            where T: Into<Option<time::SystemTime>>, T: Copy
5654        {
5655            assert_match!(RevocationStatus::NotAsFarAsWeKnow
5656                          = cert.revocation_status(p, None));
5657
5658            let mut slim_shady = false;
5659            let mut eminem = false;
5660            for b in cert.userids().with_policy(p, t) {
5661                if b.userid().value() == b"Slim Shady" {
5662                    assert!(!slim_shady);
5663                    slim_shady = true;
5664
5665                    if revoked {
5666                        assert_match!(RevocationStatus::Revoked(_)
5667                                      = b.revocation_status());
5668                    } else {
5669                        assert_match!(RevocationStatus::NotAsFarAsWeKnow
5670                                      = b.revocation_status());
5671                    }
5672                } else {
5673                    assert!(!eminem);
5674                    eminem = true;
5675
5676                    assert_match!(RevocationStatus::NotAsFarAsWeKnow
5677                                  = b.revocation_status());
5678                }
5679            }
5680
5681            assert!(slim_shady);
5682            assert!(eminem);
5683        }
5684
5685        fn check_uas<T>(p: &dyn Policy, cert: &Cert, revoked: bool, t: T)
5686            where T: Into<Option<time::SystemTime>>, T: Copy
5687        {
5688            assert_match!(RevocationStatus::NotAsFarAsWeKnow
5689                          = cert.revocation_status(p, None));
5690
5691            assert_eq!(cert.user_attributes().count(), 1);
5692            let ua = cert.user_attributes().next().unwrap();
5693            if revoked {
5694                assert_match!(RevocationStatus::Revoked(_)
5695                              = ua.revocation_status(p, t));
5696            } else {
5697                assert_match!(RevocationStatus::NotAsFarAsWeKnow
5698                              = ua.revocation_status(p, t));
5699            }
5700        }
5701
5702        tracer!(true, "userid_revoked2", 0);
5703
5704        let p = &P::new();
5705        let tests : [(&str, Box<dyn Fn(&dyn Policy, &Cert, bool, _)>); 2] = [
5706            ("userid", Box::new(check_userids)),
5707            ("user-attribute", Box::new(check_uas)),
5708        ];
5709
5710        for (f, check) in tests.iter()
5711        {
5712            t!("Checking {} revocation", f);
5713
5714            t!("Normal key");
5715            let cert = Cert::from_bytes(
5716                crate::tests::key(
5717                    &format!("really-revoked-{}-0-public.pgp", f))).unwrap();
5718
5719            let now = crate::now();
5720            let selfsig0
5721                = cert.userids().with_policy(p, now).map(|b| {
5722                    b.binding_signature().signature_creation_time().unwrap()
5723                })
5724                .max().unwrap();
5725
5726            check(p, &cert, false, selfsig0);
5727            check(p, &cert, false, now);
5728
5729            // A soft-revocation.
5730            let cert = cert.merge_public_and_secret(
5731                Cert::from_bytes(
5732                    crate::tests::key(
5733                        &format!("really-revoked-{}-1-soft-revocation.pgp", f))
5734                ).unwrap()).unwrap();
5735
5736            check(p, &cert, false, selfsig0);
5737            check(p, &cert, true, now);
5738
5739            // A new self signature.  This should override the soft-revocation.
5740            let cert = cert.merge_public_and_secret(
5741                Cert::from_bytes(
5742                    crate::tests::key(
5743                        &format!("really-revoked-{}-2-new-self-sig.pgp", f))
5744                ).unwrap()).unwrap();
5745
5746            check(p, &cert, false, selfsig0);
5747            check(p, &cert, false, now);
5748
5749            // A hard revocation.  Unlike for Certs, this does NOT trump
5750            // everything.
5751            let cert = cert.merge_public_and_secret(
5752                Cert::from_bytes(
5753                    crate::tests::key(
5754                        &format!("really-revoked-{}-3-hard-revocation.pgp", f))
5755                ).unwrap()).unwrap();
5756
5757            check(p, &cert, false, selfsig0);
5758            check(p, &cert, true, now);
5759
5760            // A newer self signature.
5761            let cert = cert.merge_public_and_secret(
5762                Cert::from_bytes(
5763                    crate::tests::key(
5764                        &format!("really-revoked-{}-4-new-self-sig.pgp", f))
5765                ).unwrap()).unwrap();
5766
5767            check(p, &cert, false, selfsig0);
5768            check(p, &cert, false, now);
5769        }
5770    }
5771
5772    #[test]
5773    fn unrevoked() {
5774        let p = &P::new();
5775        let cert =
5776            Cert::from_bytes(crate::tests::key("un-revoked-userid.pgp")).unwrap();
5777
5778        for uid in cert.userids().with_policy(p, None) {
5779            assert_eq!(uid.revocation_status(), RevocationStatus::NotAsFarAsWeKnow);
5780        }
5781    }
5782
5783    #[test]
5784    fn is_tsk() {
5785        let cert = Cert::from_bytes(
5786            crate::tests::key("already-revoked.pgp")).unwrap();
5787        assert!(! cert.is_tsk());
5788
5789        let cert = Cert::from_bytes(
5790            crate::tests::key("already-revoked-private.pgp")).unwrap();
5791        assert!(cert.is_tsk());
5792    }
5793
5794    #[test]
5795    fn export_only_exports_public_key() {
5796        let cert = Cert::from_bytes(
5797            crate::tests::key("testy-new-private.pgp")).unwrap();
5798        assert!(cert.is_tsk());
5799
5800        let mut v = Vec::new();
5801        cert.serialize(&mut v).unwrap();
5802        let cert = Cert::from_bytes(&v).unwrap();
5803        assert!(! cert.is_tsk());
5804    }
5805
5806    // Make sure that when merging two Certs, the primary key and
5807    // subkeys with and without a private key are merged.
5808    #[test]
5809    fn public_private_merge() {
5810        let (tsk, _) = CertBuilder::general_purpose(Some("foo@example.com"))
5811            .generate().unwrap();
5812        // tsk is now a cert, but it still has its private bits.
5813        assert!(tsk.primary.key().has_secret());
5814        assert!(tsk.is_tsk());
5815        let subkey_count = tsk.subkeys().count();
5816        assert!(subkey_count > 0);
5817        assert!(tsk.subkeys().all(|k| k.key().has_secret()));
5818
5819        // This will write out the tsk as a cert, i.e., without any
5820        // private bits.
5821        let mut cert_bytes = Vec::new();
5822        tsk.serialize(&mut cert_bytes).unwrap();
5823
5824        // Reading it back in, the private bits have been stripped.
5825        let cert = Cert::from_bytes(&cert_bytes[..]).unwrap();
5826        assert!(! cert.primary.key().has_secret());
5827        assert!(!cert.is_tsk());
5828        assert!(cert.subkeys().all(|k| ! k.key().has_secret()));
5829
5830        let merge1 = cert.clone().merge_public_and_secret(tsk.clone()).unwrap();
5831        assert!(merge1.is_tsk());
5832        assert!(merge1.primary.key().has_secret());
5833        assert_eq!(merge1.subkeys().count(), subkey_count);
5834        assert!(merge1.subkeys().all(|k| k.key().has_secret()));
5835
5836        let merge2 = tsk.clone().merge_public_and_secret(cert.clone()).unwrap();
5837        assert!(merge2.is_tsk());
5838        assert!(merge2.primary.key().has_secret());
5839        assert_eq!(merge2.subkeys().count(), subkey_count);
5840        assert!(merge2.subkeys().all(|k| k.key().has_secret()));
5841    }
5842
5843    #[test]
5844    fn issue_120() {
5845        let cert = "
5846-----BEGIN PGP ARMORED FILE-----
5847
5848xcBNBFoVcvoBCACykTKOJddF8SSUAfCDHk86cNTaYnjCoy72rMgWJsrMLnz/V16B
5849J9M7l6nrQ0JMnH2Du02A3w+kNb5q97IZ/M6NkqOOl7uqjyRGPV+XKwt0G5mN/ovg
58508630BZAYS3QzavYf3tni9aikiGH+zTFX5pynTNfYRXNBof3Xfzl92yad2bIt4ITD
5851NfKPvHRko/tqWbclzzEn72gGVggt1/k/0dKhfsGzNogHxg4GIQ/jR/XcqbDFR3RC
5852/JJjnTOUPGsC1y82Xlu8udWBVn5mlDyxkad5laUpWWg17anvczEAyx4TTOVItLSu
585343iPdKHSs9vMXWYID0bg913VusZ2Ofv690nDABEBAAHNJFRlc3R5IE1jVGVzdGZh
5854Y2UgPHRlc3R5QGV4YW1wbGUub3JnPsLAlAQTAQgAPhYhBD6Id8h3J0aSl1GJ9dA/
5855b4ZSJv6LBQJaFXL6AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ
5856ENA/b4ZSJv6Lxo8H/1XMt+Nqa6e0SG/up3ypKe5nplA0p/9j/s2EIsP8S8uPUd+c
5857WS17XOmPwkNDmHeL3J6hzwL74NlYSLEtyf7WoOV74xAKQA9WkqaKPHCtpll8aFWA
5858ktQDLWTPeKuUuSlobAoRtO17ZmheSQzmm7JYt4Ahkxt3agqGT05OsaAey6nIKqpq
5859ArokvdHTZ7AFZeSJIWmuCoT9M1lo3LAtLnRGOhBMJ5dDIeOwflJwNBXlJVi4mDPK
5860+fumV0MbSPvZd1/ivFjSpQyudWWtv1R1nAK7+a4CPTGxPvAQkLtRsL/V+Q7F3BJG
5861jAn4QVx8p4t3NOPuNgcoZpLBE3sc4Nfs5/CphMLHwE0EWhVy+gEIALSpjYD+tuWC
5862rj6FGP6crQjQzVlH+7axoM1ooTwiPs4fzzt2iLw3CJyDUviM5F9ZBQTei635RsAR
5863a/CJTSQYAEU5yXXxhoe0OtwnuvsBSvVT7Fox3pkfNTQmwMvkEbodhfKpqBbDKCL8
5864f5A8Bb7aISsLf0XRHWDkHVqlz8LnOR3f44wEWiTeIxLc8S1QtwX/ExyW47oPsjs9
5865ShCmwfSpcngH/vGBRTO7WeI54xcAtKSm/20B/MgrUl5qFo17kUWot2C6KjuZKkHk
58663WZmJwQz+6rTB11w4AXt8vKkptYQCkfat2FydGpgRO5dVg6aWNJefOJNkC7MmlzC
5867ZrrAK8FJ6jcAEQEAAcLAdgQYAQgAIBYhBD6Id8h3J0aSl1GJ9dA/b4ZSJv6LBQJa
5868FXL6AhsMAAoJENA/b4ZSJv6Lt7kH/jPr5wg8lcamuLj4lydYiLttvvTtDTlD1TL+
5869IfwVARB/ruoerlEDr0zX1t3DCEcvJDiZfOqJbXtHt70+7NzFXrYxfaNFmikMgSQT
5870XqHrMQho4qpseVOeJPWGzGOcrxCdw/ZgrWbkDlAU5KaIvk+M4wFPivjbtW2Ro2/F
5871J4I/ZHhJlIPmM+hUErHC103b08pBENXDQlXDma7LijH5kWhyfF2Ji7Ft0EjghBaW
5872AeGalQHjc5kAZu5R76Mwt06MEQ/HL1pIvufTFxkr/SzIv8Ih7Kexb0IrybmfD351
5873Pu1xwz57O4zo1VYf6TqHJzVC3OMvMUM2hhdecMUe5x6GorNaj6g=
5874=1Vzu
5875-----END PGP ARMORED FILE-----
5876";
5877        assert!(Cert::from_bytes(cert).is_err());
5878    }
5879
5880    #[test]
5881    fn missing_uids() {
5882        let (cert, _) = CertBuilder::new()
5883            .add_userid("test1@example.com")
5884            .add_userid("test2@example.com")
5885            .add_transport_encryption_subkey()
5886            .add_certification_subkey()
5887            .generate().unwrap();
5888        assert_eq!(cert.subkeys().count(), 2);
5889        let pile = cert
5890            .into_packet_pile()
5891            .into_children()
5892            .filter(|pkt| {
5893                match pkt {
5894                    &Packet::PublicKey(_) | &Packet::PublicSubkey(_)
5895                    | &Packet::SecretKey(_) | &Packet::SecretSubkey(_) => true,
5896                    &Packet::Signature(ref sig) => {
5897                        sig.typ() == SignatureType::DirectKey
5898                            || sig.typ() == SignatureType::SubkeyBinding
5899                    }
5900                    e => {
5901                        eprintln!("{:?}", e);
5902                        false
5903                    }
5904                }
5905            })
5906        .collect::<Vec<_>>();
5907        eprintln!("parse back");
5908        let cert = Cert::try_from(pile).unwrap();
5909
5910        assert_eq!(cert.subkeys().count(), 2);
5911    }
5912
5913    #[test]
5914    fn signature_order() {
5915        let p = &P::new();
5916        let neal = Cert::from_bytes(crate::tests::key("neal.pgp")).unwrap();
5917
5918        // This test is useless if we don't have some lists with more
5919        // than one signature.
5920        let mut cmps = 0;
5921
5922        for uid in neal.userids() {
5923            for sigs in [
5924                uid.self_signatures().collect::<Vec<_>>(),
5925                uid.certifications().collect::<Vec<_>>(),
5926                uid.self_revocations().collect::<Vec<_>>(),
5927                uid.other_revocations().collect::<Vec<_>>()
5928            ].iter() {
5929                for sigs in sigs.windows(2) {
5930                    cmps += 1;
5931                    assert!(sigs[0].signature_creation_time()
5932                            >= sigs[1].signature_creation_time());
5933                }
5934            }
5935
5936            // Make sure we return the most recent first.
5937            assert_eq!(uid.self_signatures().next().unwrap(),
5938                       uid.binding_signature(p, None).unwrap());
5939        }
5940
5941        assert!(cmps > 0);
5942    }
5943
5944    #[test]
5945    fn cert_reject_keyrings() {
5946        let mut keyring = Vec::new();
5947        keyring.extend_from_slice(crate::tests::key("neal.pgp"));
5948        keyring.extend_from_slice(crate::tests::key("neal.pgp"));
5949        assert!(Cert::from_bytes(&keyring).is_err());
5950    }
5951
5952    #[test]
5953    fn primary_userid() {
5954        // 'really-revoked-userid' has two user ids.  One of them is
5955        // revoked and then restored.  Neither of the user ids has the
5956        // primary userid bit set.
5957        //
5958        // This test makes sure that Cert::primary_userid prefers
5959        // unrevoked user ids to revoked user ids, even if the latter
5960        // have newer self signatures.
5961
5962        let p = &P::new();
5963        let cert = Cert::from_bytes(
5964            crate::tests::key("really-revoked-userid-0-public.pgp")).unwrap();
5965
5966        let now = crate::now();
5967        let selfsig0
5968            = cert.userids().with_policy(p, now).map(|b| {
5969                b.binding_signature().signature_creation_time().unwrap()
5970            })
5971            .max().unwrap();
5972
5973        // The self-sig for:
5974        //
5975        //   Slim Shady: 2019-09-14T14:21
5976        //   Eminem:     2019-09-14T14:22
5977        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
5978                   .primary_userid().unwrap().userid().value(),
5979                   b"Eminem");
5980        assert_eq!(cert.with_policy(p, now).unwrap()
5981                   .primary_userid().unwrap().userid().value(),
5982                   b"Eminem");
5983
5984        // A soft-revocation for "Slim Shady".
5985        let cert = cert.merge_public_and_secret(
5986            Cert::from_bytes(
5987                crate::tests::key("really-revoked-userid-1-soft-revocation.pgp")
5988            ).unwrap()).unwrap();
5989
5990        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
5991                   .primary_userid().unwrap().userid().value(),
5992                   b"Eminem");
5993        assert_eq!(cert.with_policy(p, now).unwrap()
5994                   .primary_userid().unwrap().userid().value(),
5995                   b"Eminem");
5996
5997        // A new self signature for "Slim Shady".  This should
5998        // override the soft-revocation.
5999        let cert = cert.merge_public_and_secret(
6000            Cert::from_bytes(
6001                crate::tests::key("really-revoked-userid-2-new-self-sig.pgp")
6002            ).unwrap()).unwrap();
6003
6004        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6005                   .primary_userid().unwrap().userid().value(),
6006                   b"Eminem");
6007        assert_eq!(cert.with_policy(p, now).unwrap()
6008                   .primary_userid().unwrap().userid().value(),
6009                   b"Slim Shady");
6010
6011        // A hard revocation for "Slim Shady".
6012        let cert = cert.merge_public_and_secret(
6013            Cert::from_bytes(
6014                crate::tests::key("really-revoked-userid-3-hard-revocation.pgp")
6015            ).unwrap()).unwrap();
6016
6017        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6018                   .primary_userid().unwrap().userid().value(),
6019                   b"Eminem");
6020        assert_eq!(cert.with_policy(p, now).unwrap()
6021                   .primary_userid().unwrap().userid().value(),
6022                   b"Eminem");
6023
6024        // A newer self signature for "Slim Shady". Unlike for Certs, this
6025        // does NOT trump everything.
6026        let cert = cert.merge_public_and_secret(
6027            Cert::from_bytes(
6028                crate::tests::key("really-revoked-userid-4-new-self-sig.pgp")
6029            ).unwrap()).unwrap();
6030
6031        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6032                   .primary_userid().unwrap().userid().value(),
6033                   b"Eminem");
6034        assert_eq!(cert.with_policy(p, now).unwrap()
6035                   .primary_userid().unwrap().userid().value(),
6036                   b"Slim Shady");
6037
6038        // Play with the primary user id flag.
6039
6040        let cert = Cert::from_bytes(
6041            crate::tests::key("primary-key-0-public.pgp")).unwrap();
6042        let selfsig0
6043            = cert.userids().with_policy(p, now).map(|b| {
6044                b.binding_signature().signature_creation_time().unwrap()
6045            })
6046            .max().unwrap();
6047
6048        // There is only a single User ID.
6049        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6050                   .primary_userid().unwrap().userid().value(),
6051                   b"aaaaa");
6052        assert_eq!(cert.with_policy(p, now).unwrap()
6053                   .primary_userid().unwrap().userid().value(),
6054                   b"aaaaa");
6055
6056
6057        // Add a second user id.  Since neither is marked primary, the
6058        // newer one should be considered primary.
6059        let cert = cert.merge_public_and_secret(
6060            Cert::from_bytes(
6061                crate::tests::key("primary-key-1-add-userid-bbbbb.pgp")
6062            ).unwrap()).unwrap();
6063
6064        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6065                   .primary_userid().unwrap().userid().value(),
6066                   b"aaaaa");
6067        assert_eq!(cert.with_policy(p, now).unwrap()
6068                   .primary_userid().unwrap().userid().value(),
6069                   b"bbbbb");
6070
6071        // Mark aaaaa as primary.  It is now primary and the newest one.
6072        let cert = cert.merge_public_and_secret(
6073            Cert::from_bytes(
6074                crate::tests::key("primary-key-2-make-aaaaa-primary.pgp")
6075            ).unwrap()).unwrap();
6076
6077        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6078                   .primary_userid().unwrap().userid().value(),
6079                   b"aaaaa");
6080        assert_eq!(cert.with_policy(p, now).unwrap()
6081                   .primary_userid().unwrap().userid().value(),
6082                   b"aaaaa");
6083
6084        // Update the preferences on bbbbb.  It is now the newest, but
6085        // it is not marked as primary.
6086        let cert = cert.merge_public_and_secret(
6087            Cert::from_bytes(
6088                crate::tests::key("primary-key-3-make-bbbbb-new-self-sig.pgp")
6089            ).unwrap()).unwrap();
6090
6091        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6092                   .primary_userid().unwrap().userid().value(),
6093                   b"aaaaa");
6094        assert_eq!(cert.with_policy(p, now).unwrap()
6095                   .primary_userid().unwrap().userid().value(),
6096                   b"aaaaa");
6097
6098        // Mark bbbbb as primary.  It is now the newest and marked as
6099        // primary.
6100        let cert = cert.merge_public_and_secret(
6101            Cert::from_bytes(
6102                crate::tests::key("primary-key-4-make-bbbbb-primary.pgp")
6103            ).unwrap()).unwrap();
6104
6105        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6106                   .primary_userid().unwrap().userid().value(),
6107                   b"aaaaa");
6108        assert_eq!(cert.with_policy(p, now).unwrap()
6109                   .primary_userid().unwrap().userid().value(),
6110                   b"bbbbb");
6111
6112        // Update the preferences on aaaaa.  It is now has the newest
6113        // self sig, but that self sig does not say that it is
6114        // primary.
6115        let cert = cert.merge_public_and_secret(
6116            Cert::from_bytes(
6117                crate::tests::key("primary-key-5-make-aaaaa-self-sig.pgp")
6118            ).unwrap()).unwrap();
6119
6120        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6121                   .primary_userid().unwrap().userid().value(),
6122                   b"aaaaa");
6123        assert_eq!(cert.with_policy(p, now).unwrap()
6124                   .primary_userid().unwrap().userid().value(),
6125                   b"bbbbb");
6126
6127        // Hard revoke aaaaa.  Unlike with Certs, a hard revocation is
6128        // not treated specially.
6129        let cert = cert.merge_public_and_secret(
6130            Cert::from_bytes(
6131                crate::tests::key("primary-key-6-revoked-aaaaa.pgp")
6132            ).unwrap()).unwrap();
6133
6134        assert_eq!(cert.with_policy(p, selfsig0).unwrap()
6135                   .primary_userid().unwrap().userid().value(),
6136                   b"aaaaa");
6137        assert_eq!(cert.with_policy(p, now).unwrap()
6138                   .primary_userid().unwrap().userid().value(),
6139                   b"bbbbb");
6140    }
6141
6142    #[test]
6143    fn binding_signature_lookup() {
6144        // Check that searching for the right binding signature works
6145        // even when there are signatures with the same time.
6146
6147        use crate::types::Features;
6148        use crate::packet::key::Key6;
6149
6150        let p = &P::new();
6151
6152        let a_sec = time::Duration::new(1, 0);
6153        let time_zero = time::UNIX_EPOCH;
6154
6155        let t1 = time::UNIX_EPOCH + time::Duration::new(946681200, 0);  // 2000-1-1
6156        let t2 = time::UNIX_EPOCH + time::Duration::new(978303600, 0);  // 2001-1-1
6157        let t3 = time::UNIX_EPOCH + time::Duration::new(1009839600, 0); // 2002-1-1
6158        let t4 = time::UNIX_EPOCH + time::Duration::new(1041375600, 0); // 2003-1-1
6159
6160        let mut key: key::SecretKey
6161            = Key6::generate_ecc(true, Curve::Ed25519).unwrap().into();
6162        key.set_creation_time(t1).unwrap();
6163        let mut pair = key.clone().into_keypair().unwrap();
6164        let pk : key::PublicKey = key.clone().into();
6165        let mut cert = Cert::try_from(vec![
6166            pk.into(),
6167        ]).unwrap();
6168        let uid: UserID = "foo@example.org".into();
6169        let sig = uid.certify(&mut pair, &cert,
6170                              SignatureType::PositiveCertification,
6171                              None,
6172                              t1).unwrap();
6173        cert = cert.insert_packets(
6174            vec![Packet::from(uid), sig.into()]).unwrap().0;
6175
6176        const N: usize = 5;
6177        for (t, offset) in &[ (t2, 0), (t4, 0), (t3, 1 * N), (t1, 3 * N) ] {
6178            for i in 0..N {
6179                let binding = signature::SignatureBuilder::new(SignatureType::DirectKey)
6180                    .set_features(Features::sequoia()).unwrap()
6181                    .set_key_flags(KeyFlags::empty()).unwrap()
6182                    .set_signature_creation_time(t1).unwrap()
6183                    // Vary this...
6184                    .set_key_validity_period(Some(
6185                        time::Duration::new((1 + i as u64) * 24 * 60 * 60, 0)))
6186                    .unwrap()
6187                    .set_preferred_hash_algorithms(vec![HashAlgorithm::SHA512]).unwrap()
6188                    .set_signature_creation_time(*t).unwrap()
6189                    .sign_direct_key(&mut pair, key.parts_as_public()).unwrap();
6190
6191                let binding : Packet = binding.into();
6192
6193                cert = cert.insert_packets(binding).unwrap().0;
6194                // A time that matches multiple signatures.
6195                let direct_signatures =
6196                    cert.primary_key().bundle().self_signatures()
6197                    .collect::<Vec<_>>();
6198                assert_eq!(cert.primary_key().with_policy(p, *t).unwrap()
6199                           .direct_key_signature().ok(),
6200                           direct_signatures.get(*offset).cloned());
6201                // A time that doesn't match any signature.
6202                assert_eq!(cert.primary_key().with_policy(p, *t + a_sec).unwrap()
6203                           .direct_key_signature().ok(),
6204                           direct_signatures.get(*offset).cloned());
6205
6206                // The current time, which should use the first signature.
6207                assert_eq!(cert.primary_key().with_policy(p, None).unwrap()
6208                           .direct_key_signature().ok(),
6209                           direct_signatures.get(0).cloned());
6210
6211                // The beginning of time, which should return no
6212                // binding signatures.
6213                assert!(cert.primary_key().with_policy(p, time_zero).is_err());
6214            }
6215        }
6216    }
6217
6218    #[test]
6219    fn keysigning_party() {
6220        use crate::packet::signature;
6221
6222        for cs in &[ CipherSuite::Cv25519,
6223                     CipherSuite::P256,
6224                     CipherSuite::P384,
6225                     CipherSuite::P521,
6226                     CipherSuite::RSA2k ]
6227        {
6228            if cs.is_supported().is_err() {
6229                eprintln!("Skipping {:?} because it is not supported.", cs);
6230                continue;
6231            }
6232
6233            let (alice, _) = CertBuilder::new()
6234                .set_cipher_suite(*cs)
6235                .add_userid("alice@foo.com")
6236                .generate().unwrap();
6237
6238            let (bob, _) = CertBuilder::new()
6239                .set_cipher_suite(*cs)
6240                .add_userid("bob@bar.com")
6241                .add_signing_subkey()
6242                .generate().unwrap();
6243
6244            assert_eq!(bob.userids().len(), 1);
6245            let bob_userid_binding = bob.userids().next().unwrap();
6246            assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com");
6247
6248            let sig_template
6249                = signature::SignatureBuilder::new(SignatureType::GenericCertification)
6250                      .set_trust_signature(255, 120)
6251                      .unwrap();
6252
6253            // Have alice certify the binding "bob@bar.com" and bob's key.
6254            let alice_certifies_bob
6255                = bob_userid_binding.userid().bind(
6256                    &mut alice.primary_key().key().clone().parts_into_secret()
6257                        .unwrap().into_keypair().unwrap(),
6258                    &bob,
6259                    sig_template).unwrap();
6260
6261            let bob = bob.insert_packets(alice_certifies_bob.clone()).unwrap().0;
6262
6263            // Make sure the certification is merged, and put in the right
6264            // place.
6265            assert_eq!(bob.userids().len(), 1);
6266            let bob_userid_binding = bob.userids().next().unwrap();
6267            assert_eq!(bob_userid_binding.userid().value(), b"bob@bar.com");
6268
6269            // Canonicalizing Bob's cert without having Alice's key
6270            // has to resort to a heuristic to order third party
6271            // signatures.  However, since we know the signature's
6272            // type (GenericCertification), we know that it can only
6273            // go to the only userid, so there is no ambiguity in this
6274            // case.
6275            assert_eq!(bob_userid_binding.certifications().collect::<Vec<_>>(),
6276                       vec![&alice_certifies_bob]);
6277
6278            // Make sure the certification is correct.
6279            alice_certifies_bob
6280                .verify_userid_binding(alice.primary_key().key(),
6281                                       bob.primary_key().key(),
6282                                       bob_userid_binding.userid()).unwrap();
6283        }
6284   }
6285
6286    #[test]
6287    fn decrypt_encrypt_secrets() -> Result<()> {
6288        let p: crate::crypto::Password = "streng geheim".into();
6289        let (mut cert, _) = CertBuilder::new()
6290            .add_transport_encryption_subkey()
6291            .set_password(Some(p.clone()))
6292            .generate()?;
6293        assert_eq!(cert.keys().secret().count(), 2);
6294        assert_eq!(cert.keys().unencrypted_secret().count(), 0);
6295
6296        for (i, ka) in cert.clone().keys().secret().enumerate() {
6297            let key = ka.key().clone().decrypt_secret(&p)?;
6298            cert = if i == 0 {
6299                cert.insert_packets(key.role_into_primary())?.0
6300            } else {
6301                cert.insert_packets(key.role_into_subordinate())?.0
6302            };
6303            assert_eq!(cert.keys().secret().count(), 2);
6304            assert_eq!(cert.keys().unencrypted_secret().count(), i + 1);
6305        }
6306
6307        assert_eq!(cert.keys().secret().count(), 2);
6308        assert_eq!(cert.keys().unencrypted_secret().count(), 2);
6309
6310        for (i, ka) in cert.clone().keys().secret().enumerate() {
6311            let key = ka.key().clone().encrypt_secret(&p)?;
6312            cert = if i == 0 {
6313                cert.insert_packets(key.role_into_primary())?.0
6314            } else {
6315                cert.insert_packets(key.role_into_subordinate())?.0
6316            };
6317            assert_eq!(cert.keys().secret().count(), 2);
6318            assert_eq!(cert.keys().unencrypted_secret().count(), 2 - 1 - i);
6319        }
6320
6321        assert_eq!(cert.keys().secret().count(), 2);
6322        assert_eq!(cert.keys().unencrypted_secret().count(), 0);
6323        Ok(())
6324    }
6325
6326    /// Tests that Cert:.into_packets() and Cert::serialize(..) agree.
6327    #[test]
6328    fn test_into_packets() -> Result<()> {
6329        use crate::serialize::SerializeInto;
6330
6331        let dkg = Cert::from_bytes(crate::tests::key("dkg.pgp"))?;
6332        let mut buf = Vec::new();
6333        for p in dkg.clone().into_packets() {
6334            p.serialize(&mut buf)?;
6335        }
6336        let dkg = dkg.to_vec()?;
6337        if false && buf != dkg {
6338            std::fs::write("/tmp/buf", &buf)?;
6339            std::fs::write("/tmp/dkg", &dkg)?;
6340        }
6341        assert_eq!(buf, dkg);
6342        Ok(())
6343    }
6344
6345    #[test]
6346    fn test_canonicalization() -> Result<()> {
6347        let p = crate::policy::StandardPolicy::new();
6348
6349        let primary: Key<_, key::PrimaryRole> =
6350            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6351        let cert = Cert::try_from(vec![primary.into()])?;
6352
6353        // We now add components without binding signatures.  They
6354        // should be kept, be enumerable, but ignored if a policy is
6355        // applied.
6356
6357        // Add a bare userid.
6358        let uid = UserID::from("foo@example.org");
6359        let cert = cert.insert_packets(uid)?.0;
6360        assert_eq!(cert.userids().count(), 1);
6361        assert_eq!(cert.userids().with_policy(&p, None).count(), 0);
6362
6363        // Add a bare user attribute.
6364        use packet::user_attribute::{Subpacket, Image};
6365        let ua = UserAttribute::new(&[
6366            Subpacket::Image(
6367                Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
6368        ])?;
6369        let cert = cert.insert_packets(ua)?.0;
6370        assert_eq!(cert.user_attributes().count(), 1);
6371        assert_eq!(cert.user_attributes().with_policy(&p, None).count(), 0);
6372
6373        // Add a bare signing subkey.
6374        let signing_subkey: Key<_, key::SubordinateRole> =
6375            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6376        let _signing_subkey_pair = signing_subkey.clone().into_keypair()?;
6377        let cert = cert.insert_packets(signing_subkey)?.0;
6378        assert_eq!(cert.keys().subkeys().count(), 1);
6379        assert_eq!(cert.keys().subkeys().with_policy(&p, None).count(), 0);
6380
6381        // Add a component that Sequoia doesn't understand.
6382        let mut fake_key = packet::Unknown::new(
6383            packet::Tag::PublicSubkey, anyhow::anyhow!("fake key"));
6384        fake_key.set_body("fake key".into());
6385        let cert = cert.insert_packets(vec![Packet::from(fake_key)])?.0;
6386        assert_eq!(cert.unknowns().count(), 1);
6387        assert_eq!(cert.unknowns().next().unwrap().unknown().tag(),
6388                   packet::Tag::PublicSubkey);
6389
6390        Ok(())
6391    }
6392
6393    #[test]
6394    #[allow(deprecated)]
6395    fn canonicalize_with_v3_sig() -> Result<()> {
6396        skip_unless_supported!(crate::types::PublicKeyAlgorithm::DSA);
6397
6398        // This test relies on being able to validate SHA-1
6399        // signatures.  The standard policy rejects SHA-1.  So, use a
6400        // custom policy.
6401        let p = &P::new();
6402        let sha1 =
6403            p.hash_cutoff(
6404                HashAlgorithm::SHA1, HashAlgoSecurity::CollisionResistance)
6405            .unwrap();
6406        let p = &P::at(sha1 - std::time::Duration::from_secs(1));
6407
6408        let cert = Cert::from_bytes(
6409            crate::tests::key("eike-v3-v4.pgp"))?;
6410        dbg!(&cert);
6411        assert_eq!(cert.userids()
6412                   .with_policy(p, None)
6413                   .count(), 1);
6414        Ok(())
6415    }
6416
6417    /// Asserts that key expiration times on direct key signatures are
6418    /// honored.
6419    #[test]
6420    fn issue_215() {
6421        let p = &P::new();
6422         let cert = Cert::from_bytes(crate::tests::key(
6423            "issue-215-expiration-on-direct-key-sig.pgp")).unwrap();
6424        assert_match!(
6425            Error::Expired(_)
6426                = cert.with_policy(p, None).unwrap().alive()
6427                .unwrap_err().downcast().unwrap());
6428        assert_match!(
6429            Error::Expired(_)
6430                = cert.primary_key().with_policy(p, None).unwrap()
6431                    .alive().unwrap_err().downcast().unwrap());
6432    }
6433
6434    /// Tests that secrets are kept when merging.
6435    #[test]
6436    fn merge_keeps_secrets() -> Result<()> {
6437        let (cert_s, _) =
6438            CertBuilder::general_purpose(Some("uid")).generate()?;
6439        let cert_p = cert_s.clone().strip_secret_key_material();
6440
6441        // Merge key into cert.
6442        let cert = cert_p.clone().merge_public_and_secret(cert_s.clone())?;
6443        assert!(cert.keys().all(|ka| ka.has_secret()));
6444
6445        // Merge cert into key.
6446        let cert = cert_s.clone().merge_public_and_secret(cert_p.clone())?;
6447        assert!(cert.keys().all(|ka| ka.has_secret()));
6448
6449        Ok(())
6450    }
6451
6452    /// Tests that secrets that are merged in are preferred to
6453    /// existing secrets.
6454    #[test]
6455    fn merge_prefers_merged_in_secrets() -> Result<()> {
6456        let pw: crate::crypto::Password = "foo".into();
6457        let (cert_encrypted_secrets, _) =
6458            CertBuilder::general_purpose(Some("uid"))
6459            .set_password(Some(pw.clone()))
6460            .generate()?;
6461
6462        let mut cert_plain_secrets = cert_encrypted_secrets.clone();
6463        for ka in cert_encrypted_secrets.keys().secret() {
6464            assert!(! ka.key().has_unencrypted_secret());
6465            let key = ka.key().clone().decrypt_secret(&pw)?;
6466            assert!(key.has_unencrypted_secret());
6467
6468            let key: Packet = if ka.primary() {
6469                key.role_into_primary().into()
6470            } else {
6471                key.role_into_subordinate().into()
6472            };
6473
6474            cert_plain_secrets =
6475                cert_plain_secrets.insert_packets(vec![key])?.0;
6476        }
6477        assert!(
6478            cert_plain_secrets.keys().all(|ka| ka.key().has_unencrypted_secret()));
6479
6480        // Merge unencrypted secrets into encrypted secrets.
6481        let cert = cert_encrypted_secrets.clone().merge_public_and_secret(
6482            cert_plain_secrets.clone())?;
6483        assert!(cert.keys().all(|ka| ka.key().has_unencrypted_secret()));
6484
6485        // Merge encrypted secrets into unencrypted secrets.
6486        let cert = cert_plain_secrets.clone().merge_public_and_secret(
6487            cert_encrypted_secrets.clone())?;
6488        assert!(cert.keys().all(|ka| ka.has_secret()
6489                                && ! ka.key().has_unencrypted_secret()));
6490
6491        Ok(())
6492    }
6493
6494    /// Tests that secrets are kept when canonicalizing.
6495    #[test]
6496    fn canonicalizing_keeps_secrets() -> Result<()> {
6497        let primary: Key<_, key::PrimaryRole> =
6498            key::Key6::generate_ecc(true, Curve::Ed25519)?.into();
6499        let mut primary_pair = primary.clone().into_keypair()?;
6500        let cert = Cert::try_from(vec![primary.clone().into()])?;
6501
6502        let subkey_sec: Key<_, key::SubordinateRole> =
6503            key::Key6::generate_ecc(false, Curve::Cv25519)?.into();
6504        let subkey_pub = subkey_sec.clone().take_secret().0;
6505        let builder = signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
6506            .set_key_flags(KeyFlags::empty()
6507                           .set_transport_encryption())?;
6508        let binding = subkey_sec.bind(&mut primary_pair, &cert, builder)?;
6509
6510        let cert = Cert::try_from(vec![
6511            primary.clone().into(),
6512            subkey_pub.clone().into(),
6513            binding.clone().into(),
6514            subkey_sec.clone().into(),
6515            binding.clone().into(),
6516        ])?;
6517        assert_eq!(cert.keys().subkeys().count(), 1);
6518        assert_eq!(cert.keys().unencrypted_secret().subkeys().count(), 1);
6519
6520        let cert = Cert::try_from(vec![
6521            primary.clone().into(),
6522            subkey_sec.clone().into(),
6523            binding.clone().into(),
6524            subkey_pub.clone().into(),
6525            binding.clone().into(),
6526        ])?;
6527        assert_eq!(cert.keys().subkeys().count(), 1);
6528        assert_eq!(cert.keys().unencrypted_secret().subkeys().count(), 1);
6529        Ok(())
6530    }
6531
6532    /// Demonstrates that subkeys are kept if a userid is later added
6533    /// without any keyflags.
6534    #[test]
6535    fn issue_361() -> Result<()> {
6536        let (cert, _) = CertBuilder::new()
6537            .add_transport_encryption_subkey()
6538            .generate()?;
6539        let p = &P::new();
6540        let cert_at = cert.with_policy(p,
6541                                       cert.primary_key().key().creation_time()
6542                                       + time::Duration::new(300, 0))
6543            .unwrap();
6544        assert_eq!(cert_at.userids().count(), 0);
6545        assert_eq!(cert_at.keys().count(), 2);
6546
6547        let mut primary_pair = cert.primary_key().key().clone()
6548            .parts_into_secret()?.into_keypair()?;
6549        let uid: UserID = "foo@example.org".into();
6550        let sig = uid.bind(
6551            &mut primary_pair, &cert,
6552            signature::SignatureBuilder::new(SignatureType::PositiveCertification))?;
6553        let cert = cert.insert_packets(vec![
6554            Packet::from(uid),
6555            sig.into(),
6556        ])?.0;
6557
6558        let cert_at = cert.with_policy(p,
6559                                       cert.primary_key().key().creation_time()
6560                                       + time::Duration::new(300, 0))
6561            .unwrap();
6562        assert_eq!(cert_at.userids().count(), 1);
6563        assert_eq!(cert_at.keys().count(), 2);
6564        Ok(())
6565    }
6566
6567    /// Demonstrates that binding signatures are considered valid even
6568    /// if the primary key is not marked as certification-capable.
6569    #[test]
6570    fn issue_321() -> Result<()> {
6571        let cert = Cert::from_bytes(
6572            crate::tests::file("contrib/pep/pEpkey-netpgp.asc"))?;
6573        assert_eq!(cert.userids().count(), 1);
6574        assert_eq!(cert.keys().count(), 1);
6575
6576        let mut p = P::new();
6577        p.accept_hash(HashAlgorithm::SHA1);
6578        let cert_at = cert.with_policy(&p, cert.primary_key().key().creation_time())
6579            .unwrap();
6580        assert_eq!(cert_at.userids().count(), 1);
6581        assert_eq!(cert_at.keys().count(), 1);
6582        Ok(())
6583    }
6584
6585    #[test]
6586    fn policy_uri_some() -> Result<()> {
6587        use crate::packet::prelude::SignatureBuilder;
6588        use crate::policy::StandardPolicy;
6589
6590        let p = &StandardPolicy::new();
6591
6592        let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
6593
6594        let sig = SignatureBuilder::from(
6595            alice
6596            .with_policy(p, None)?
6597            .direct_key_signature().expect("Direct key signature")
6598            .clone()
6599        )
6600            .set_policy_uri("https://example.org/~alice/signing-policy.txt")?;
6601        assert_eq!(sig.policy_uri(), Some("https://example.org/~alice/signing-policy.txt".as_bytes()));
6602        Ok(())
6603    }
6604
6605    #[test]
6606    fn policy_uri_none() -> Result<()> {
6607        use crate::packet::prelude::SignatureBuilder;
6608        use crate::policy::StandardPolicy;
6609
6610        let p = &StandardPolicy::new();
6611
6612        let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
6613
6614        let sig = SignatureBuilder::from(
6615            alice
6616            .with_policy(p, None)?
6617            .direct_key_signature().expect("Direct key signature")
6618            .clone()
6619        );
6620        assert_eq!(sig.policy_uri(), None);
6621        Ok(())
6622    }
6623
6624    #[test]
6625    #[allow(deprecated)]
6626    fn different_preferences() -> Result<()> {
6627        use crate::cert::Preferences;
6628        let p = &crate::policy::StandardPolicy::new();
6629
6630        // This key returns different preferences depending on how you
6631        // address it.  (It has two user ids and the user ids have
6632        // different preference packets on their respective self
6633        // signatures.)
6634
6635        let cert = Cert::from_bytes(
6636            crate::tests::key("different-preferences.asc"))?;
6637        assert_eq!(cert.userids().count(), 2);
6638
6639        if let Some(userid) = cert.userids().next() {
6640            assert_eq!(userid.userid().value(),
6641                       &b"Alice Confusion <alice@example.com>"[..]);
6642
6643            let userid = userid.with_policy(p, None).expect("valid");
6644
6645            use crate::types::SymmetricAlgorithm::*;
6646            assert_eq!(userid.preferred_symmetric_algorithms(),
6647                       Some(&[ AES256, AES192, AES128, TripleDES ][..]));
6648
6649            use crate::types::HashAlgorithm::*;
6650            assert_eq!(userid.preferred_hash_algorithms(),
6651                       Some(&[ SHA512, SHA384, SHA256, SHA224, SHA1 ][..]));
6652
6653            use crate::types::CompressionAlgorithm::*;
6654            assert_eq!(userid.preferred_compression_algorithms(),
6655                       Some(&[ Zlib, BZip2, Zip ][..]));
6656
6657            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6658
6659            // assert_eq!(userid.key_server_preferences(),
6660            //            Some(KeyServerPreferences::new(&[])));
6661
6662            assert_eq!(userid.features(),
6663                       Some(Features::new(&[]).set_seipdv1()));
6664        } else {
6665            panic!("two user ids");
6666        }
6667
6668        if let Some(userid) = cert.userids().next() {
6669            assert_eq!(userid.userid().value(),
6670                       &b"Alice Confusion <alice@example.com>"[..]);
6671
6672            let userid = userid.with_policy(p, None).expect("valid");
6673
6674            use crate::types::SymmetricAlgorithm::*;
6675            assert_eq!(userid.preferred_symmetric_algorithms(),
6676                       Some(&[ AES256, AES192, AES128, TripleDES ][..]));
6677
6678            use crate::types::HashAlgorithm::*;
6679            assert_eq!(userid.preferred_hash_algorithms(),
6680                       Some(&[ SHA512, SHA384, SHA256, SHA224, SHA1 ][..]));
6681
6682            use crate::types::CompressionAlgorithm::*;
6683            assert_eq!(userid.preferred_compression_algorithms(),
6684                       Some(&[ Zlib, BZip2, Zip ][..]));
6685
6686            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6687
6688            assert_eq!(userid.key_server_preferences(),
6689                       Some(KeyServerPreferences::new(&[0x80])));
6690
6691            assert_eq!(userid.features(),
6692                       Some(Features::new(&[]).set_seipdv1()));
6693
6694            // Using the certificate should choose the primary user
6695            // id, which is this one (because it is lexicographically
6696            // earlier).
6697            let cert = cert.with_policy(p, None).expect("valid");
6698            assert_eq!(userid.preferred_symmetric_algorithms(),
6699                       cert.preferred_symmetric_algorithms());
6700            assert_eq!(userid.preferred_hash_algorithms(),
6701                       cert.preferred_hash_algorithms());
6702            assert_eq!(userid.preferred_compression_algorithms(),
6703                       cert.preferred_compression_algorithms());
6704            assert_eq!(userid.preferred_aead_ciphersuites(),
6705                       cert.preferred_aead_ciphersuites());
6706            assert_eq!(userid.key_server_preferences(),
6707                       cert.key_server_preferences());
6708            assert_eq!(userid.features(),
6709                       cert.features());
6710        } else {
6711            panic!("two user ids");
6712        }
6713
6714        if let Some(userid) = cert.userids().nth(1) {
6715            assert_eq!(userid.userid().value(),
6716                       &b"Alice Confusion <alice@example.net>"[..]);
6717
6718            let userid = userid.with_policy(p, None).expect("valid");
6719
6720            use crate::types::SymmetricAlgorithm::*;
6721            assert_eq!(userid.preferred_symmetric_algorithms(),
6722                       Some(&[ AES192, AES256, AES128, TripleDES ][..]));
6723
6724            use crate::types::HashAlgorithm::*;
6725            assert_eq!(userid.preferred_hash_algorithms(),
6726                       Some(&[ SHA384, SHA512, SHA256, SHA224, SHA1 ][..]));
6727
6728            use crate::types::CompressionAlgorithm::*;
6729            assert_eq!(userid.preferred_compression_algorithms(),
6730                       Some(&[ BZip2, Zlib, Zip ][..]));
6731
6732            assert_eq!(userid.preferred_aead_ciphersuites(), None);
6733
6734            assert_eq!(userid.key_server_preferences(),
6735                       Some(KeyServerPreferences::new(&[0x80])));
6736
6737            assert_eq!(userid.features(),
6738                       Some(Features::new(&[]).set_seipdv1()));
6739        } else {
6740            panic!("two user ids");
6741        }
6742
6743        Ok(())
6744    }
6745
6746    #[test]
6747    fn unsigned_components() -> Result<()> {
6748        // We have a certificate with an unsigned User ID, User
6749        // Attribute, encryption-capable subkey, and signing-capable
6750        // subkey.  (Actually, they are signed, but the signatures are
6751        // bad.)  We expect that when we parse such a certificate the
6752        // unsigned components are not dropped and they appear when
6753        // iterating over the components using, e.g., Cert::userids,
6754        // but not when we check for valid components.
6755
6756        let p = &crate::policy::StandardPolicy::new();
6757
6758        let cert = Cert::from_bytes(
6759            crate::tests::key("certificate-with-unsigned-components.asc"))?;
6760
6761        assert_eq!(cert.userids().count(), 2);
6762        assert_eq!(cert.userids().with_policy(p, None).count(), 1);
6763
6764        assert_eq!(cert.user_attributes().count(), 2);
6765        assert_eq!(cert.user_attributes().with_policy(p, None).count(), 1);
6766
6767        assert_eq!(cert.keys().count(), 1 + 4);
6768        assert_eq!(cert.keys().with_policy(p, None).count(), 1 + 2);
6769        Ok(())
6770    }
6771
6772    #[test]
6773    fn issue_504() -> Result<()> {
6774        let mut keyring = crate::tests::key("testy.pgp").to_vec();
6775        keyring.extend_from_slice(crate::tests::key("testy-new.pgp"));
6776
6777        // TryFrom<PacketPile>
6778        let pp = PacketPile::from_bytes(&keyring)?;
6779        assert!(matches!(
6780            Cert::try_from(pp.clone()).unwrap_err().downcast().unwrap(),
6781            Error::MalformedCert(_)
6782        ));
6783
6784        // Cert::TryFrom<Vec<Packet>>
6785        let v: Vec<Packet> = pp.into();
6786        assert!(matches!(
6787            Cert::try_from(v.clone()).unwrap_err().downcast().unwrap(),
6788            Error::MalformedCert(_)
6789        ));
6790
6791        // Cert::from_packet
6792        assert!(matches!(
6793            Cert::from_packets(v.into_iter()).unwrap_err().downcast().unwrap(),
6794            Error::MalformedCert(_)
6795        ));
6796
6797        // Cert::TryFrom<PacketParserResult>
6798        let ppr = PacketParser::from_bytes(&keyring)?;
6799        assert!(matches!(
6800            Cert::try_from(ppr).unwrap_err().downcast().unwrap(),
6801            Error::MalformedCert(_)
6802        ));
6803        Ok(())
6804    }
6805
6806    /// Tests whether the policy is applied to primary key binding
6807    /// signatures.
6808    #[test]
6809    fn issue_531() -> Result<()> {
6810        let cert =
6811            Cert::from_bytes(crate::tests::key("peter-sha1-backsig.pgp"))?;
6812        let p = unsafe { &crate::policy::NullPolicy::new() };
6813        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 1);
6814        let mut p = crate::policy::StandardPolicy::new();
6815        p.reject_hash(HashAlgorithm::SHA1);
6816        assert_eq!(cert.with_policy(&p, None)?.keys().for_signing().count(), 0);
6817        Ok(())
6818    }
6819
6820    /// Tests whether expired primary key binding signatures are
6821    /// rejected.
6822    #[test]
6823    fn issue_539() -> Result<()> {
6824        let cert =
6825            Cert::from_bytes(crate::tests::key("peter-expired-backsig.pgp"))?;
6826        let p = unsafe { &crate::policy::NullPolicy::new() };
6827        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 0);
6828        let p = &crate::policy::StandardPolicy::new();
6829        assert_eq!(cert.with_policy(p, None)?.keys().for_signing().count(), 0);
6830        Ok(())
6831    }
6832
6833    /// Tests whether signatures are properly deduplicated.
6834    #[test]
6835    fn issue_568() -> Result<()> {
6836        use crate::packet::signature::subpacket::*;
6837
6838        let (cert, _) = CertBuilder::general_purpose(
6839            Some("alice@example.org")).generate().unwrap();
6840        assert_eq!(cert.userids().count(), 1);
6841        assert_eq!(cert.subkeys().count(), 2);
6842        assert_eq!(cert.unknowns().count(), 0);
6843        assert_eq!(cert.bad_signatures().count(), 0);
6844        assert_eq!(cert.userids().next().unwrap().self_signatures().count(), 1);
6845        assert_eq!(cert.subkeys().next().unwrap().self_signatures().count(), 1);
6846        assert_eq!(cert.subkeys().nth(1).unwrap().self_signatures().count(), 1);
6847
6848        // Create a variant of cert where the signatures have
6849        // additional information in the unhashed area.
6850        let cert_b = cert.clone();
6851        let mut packets = crate::PacketPile::from(cert_b).into_children()
6852            .collect::<Vec<_>>();
6853        for p in packets.iter_mut() {
6854            if let Packet::Signature(sig) = p {
6855                assert_eq!(sig.hashed_area().subpackets(
6856                    SubpacketTag::IssuerFingerprint).count(),
6857                           1);
6858                sig.unhashed_area_mut().add(Subpacket::new(
6859                    SubpacketValue::Issuer("AAAA BBBB CCCC DDDD".parse()?),
6860                    false)?)?;
6861            }
6862        }
6863        let cert_b = Cert::from_packets(packets.into_iter())?;
6864        let cert = cert.merge_public_and_secret(cert_b)?;
6865        assert_eq!(cert.userids().count(), 1);
6866        assert_eq!(cert.subkeys().count(), 2);
6867        assert_eq!(cert.unknowns().count(), 0);
6868        assert_eq!(cert.bad_signatures().count(), 0);
6869        assert_eq!(cert.userids().next().unwrap().self_signatures().count(), 1);
6870        assert_eq!(cert.subkeys().next().unwrap().self_signatures().count(), 1);
6871        assert_eq!(cert.subkeys().nth(1).unwrap().self_signatures().count(), 1);
6872
6873        Ok(())
6874    }
6875
6876    /// Checks that missing or bad embedded signatures cause the
6877    /// signature to be considered bad.
6878    #[test]
6879    fn missing_backsig_is_bad() -> Result<()> {
6880        use crate::packet::{
6881            key::Key6,
6882            signature::{
6883                SignatureBuilder,
6884                subpacket::{Subpacket, SubpacketValue},
6885            },
6886        };
6887
6888        // We'll study this certificate, because it contains a
6889        // signing-capable subkey.
6890        let cert = crate::Cert::from_bytes(crate::tests::key(
6891            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6892        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
6893            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6894        assert_eq!(pp.children().count(), 5);
6895
6896        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
6897            // Add a bogus but plausible embedded signature subpacket.
6898            let key: key::SecretKey
6899                = Key6::generate_ecc(true, Curve::Ed25519)?.into();
6900            let mut pair = key.into_keypair()?;
6901
6902            sig.unhashed_area_mut().replace(Subpacket::new(
6903                SubpacketValue::EmbeddedSignature(
6904                    SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
6905                        .sign_primary_key_binding(
6906                            &mut pair,
6907                            cert.primary_key().key(),
6908                            cert.keys().subkeys().next().unwrap().key())?),
6909                false)?)?;
6910        } else {
6911            panic!("expected a signature");
6912        }
6913
6914        // Parse into cert.
6915        use std::convert::TryFrom;
6916        let malicious_cert = Cert::try_from(pp)?;
6917        // The subkey binding signature should no longer check out.
6918        let p = &crate::policy::StandardPolicy::new();
6919        assert_eq!(malicious_cert.with_policy(p, None)?.keys().subkeys()
6920                   .for_signing().count(), 0);
6921        // Instead, it should be considered bad.
6922        assert_eq!(malicious_cert.bad_signatures().count(), 1);
6923        Ok(())
6924    }
6925
6926    /// Checks that multiple embedded signatures are correctly
6927    /// handled.
6928    #[test]
6929    fn multiple_embedded_signatures() -> Result<()> {
6930        use crate::packet::{
6931            key::Key6,
6932            signature::{
6933                SignatureBuilder,
6934                subpacket::{Subpacket, SubpacketValue},
6935            },
6936        };
6937
6938        // We'll study this certificate, because it contains a
6939        // signing-capable subkey.
6940        let cert = crate::Cert::from_bytes(crate::tests::key(
6941            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6942
6943        // Add a bogus but plausible embedded signature subpacket with
6944        // this key.
6945        let key: key::SecretKey
6946            = Key6::generate_ecc(true, Curve::Ed25519)?.into();
6947        let mut pair = key.into_keypair()?;
6948
6949        // Create a malicious cert to merge in.
6950        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
6951            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
6952        assert_eq!(pp.children().count(), 5);
6953
6954        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
6955            // Prepend a bad backsig.
6956            let backsig = sig.embedded_signatures().next().unwrap().clone();
6957            sig.unhashed_area_mut().replace(Subpacket::new(
6958                SubpacketValue::EmbeddedSignature(
6959                    SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
6960                        .sign_primary_key_binding(
6961                            &mut pair,
6962                            cert.primary_key().key(),
6963                            cert.keys().subkeys().next().unwrap().key())?),
6964                false)?)?;
6965            sig.unhashed_area_mut().add(Subpacket::new(
6966                SubpacketValue::EmbeddedSignature(backsig), false)?)?;
6967        } else {
6968            panic!("expected a signature");
6969        }
6970
6971        // Parse into cert.
6972        use std::convert::TryFrom;
6973        let malicious_cert = Cert::try_from(pp)?;
6974        // The subkey binding signature should still be fine.
6975        let p = &crate::policy::StandardPolicy::new();
6976        assert_eq!(malicious_cert.with_policy(p, None)?.keys().subkeys()
6977                   .for_signing().count(), 1);
6978        assert_eq!(malicious_cert.bad_signatures().count(), 0);
6979
6980        // Now try to merge it in.
6981        let merged = cert.clone().merge_public_and_secret(malicious_cert.clone())?;
6982        // The subkey binding signature should still be fine.
6983        assert_eq!(merged.with_policy(p, None)?.keys().subkeys()
6984                   .for_signing().count(), 1);
6985        let sig = merged.with_policy(p, None)?.keys().subkeys()
6986            .for_signing().next().unwrap().binding_signature();
6987        assert_eq!(sig.embedded_signatures().count(), 2);
6988
6989        // Now the other way around.
6990        let merged = malicious_cert.clone().merge_public_and_secret(cert.clone())?;
6991        // The subkey binding signature should still be fine.
6992        assert_eq!(merged.with_policy(p, None)?.keys().subkeys()
6993                   .for_signing().count(), 1);
6994        let sig = merged.with_policy(p, None)?.keys().subkeys()
6995            .for_signing().next().unwrap().binding_signature();
6996        assert_eq!(sig.embedded_signatures().count(), 2);
6997        Ok(())
6998    }
6999
7000    /// Checks that Cert::merge(cert, cert) == cert.
7001    #[test]
7002    fn issue_579() -> Result<()> {
7003        use std::convert::TryFrom;
7004        use crate::packet::signature::subpacket::SubpacketTag;
7005
7006        let mut pp = crate::PacketPile::from_bytes(crate::tests::key(
7007            "emmelie-dorothea-dina-samantha-awina-ed25519.pgp"))?;
7008        assert_eq!(pp.children().count(), 5);
7009        // Drop issuer information from the unhashed areas.
7010        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[2]) {
7011            sig.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
7012        } else {
7013            panic!("expected a signature");
7014        }
7015        if let Some(Packet::Signature(sig)) = pp.path_ref_mut(&[4]) {
7016            sig.unhashed_area_mut().remove_all(SubpacketTag::Issuer);
7017        } else {
7018            panic!("expected a signature");
7019        }
7020
7021        let cert = Cert::try_from(pp)?;
7022        assert_eq!(cert.clone().merge_public_and_secret(cert.clone())?, cert);
7023
7024        Ok(())
7025    }
7026
7027    /// Checks that Cert::merge_public ignores secret key material.
7028    #[test]
7029    fn merge_public() -> Result<()> {
7030        let cert =
7031            Cert::from_bytes(crate::tests::key("testy-new.pgp"))?;
7032        let key =
7033            Cert::from_bytes(crate::tests::key("testy-new-private.pgp"))?;
7034
7035        assert!(! cert.is_tsk());
7036        assert!(key.is_tsk());
7037
7038        // Secrets are ignored in `other`.
7039        let merged = cert.clone().merge_public(key.clone())?;
7040        assert!(! merged.is_tsk());
7041        assert_eq!(merged, cert);
7042
7043        // Secrets are retained in `self`.
7044        let merged = key.clone().merge_public(cert.clone())?;
7045        assert!(merged.is_tsk());
7046        assert_eq!(merged, key);
7047
7048        Ok(())
7049    }
7050
7051    /// Make sure we can parse a key where the primary key is its own
7052    /// subkeys.
7053    #[test]
7054    fn primary_key_is_subkey() -> Result<()> {
7055        let p = &crate::policy::StandardPolicy::new();
7056
7057        let cert =
7058            Cert::from_bytes(crate::tests::key("primary-key-is-also-subkey.pgp"))?;
7059
7060        // There should be three keys:
7061        //
7062        //     Fingerprint: 8E8C 33FA 4626 3379 76D9  7978 069C 0C34 8DD8 2C19
7063        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7064        // Public-key size: 256 bits
7065        //      Secret key: Unencrypted
7066        //   Creation time: 2018-06-11 14:12:09 UTC
7067        //       Key flags: certification, signing
7068        //
7069        //          Subkey: 8E8C 33FA 4626 3379 76D9  7978 069C 0C34 8DD8 2C19
7070        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7071        // Public-key size: 256 bits
7072        //      Secret key: Unencrypted
7073        //   Creation time: 2018-06-11 14:12:09 UTC
7074        //       Key flags: certification, signing
7075        //
7076        //          Subkey: 061C 3CA4 4AFF 0EC5 8DC6  6E95 22E3 FAFE 96B5 6C32
7077        // Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
7078        // Public-key size: 256 bits
7079        //      Secret key: Unencrypted
7080        //   Creation time: 2018-08-27 10:55:43 UTC
7081        //       Key flags: signing
7082        //
7083        //          UserID: Emmelie Dorothea Dina Samantha Awina Ed25519
7084        assert_eq!(cert.keys().count(), 3);
7085
7086        // Make sure there is a subkey with the same fingerprint as
7087        // the primary key.
7088        assert!(cert.keys().subkeys().any(|k| {
7089            k.key().fingerprint() == cert.primary_key().key().fingerprint()
7090        }));
7091
7092        // Make sure the self sig is valid, too.
7093        assert_eq!(cert.keys().count(), 3);
7094
7095        let vc = cert.with_policy(p, None)?;
7096        assert!(vc.keys().subkeys().any(|k| {
7097            k.key().fingerprint() == vc.primary_key().key().fingerprint()
7098        }));
7099
7100        Ok(())
7101    }
7102
7103    /// Makes sure that certification approval key signatures are
7104    /// correctly handled.
7105    #[test]
7106    fn certificaton_approval_signatures() -> Result<()> {
7107        use crate::{
7108            packet::signature::SignatureBuilder,
7109            types::*,
7110        };
7111        let p = &crate::policy::StandardPolicy::new();
7112
7113        let (alice, _) = CertBuilder::new()
7114            .add_userid("alice@foo.com")
7115            .generate()?;
7116        let mut alice_signer =
7117            alice.primary_key().key().clone().parts_into_secret()?
7118            .into_keypair()?;
7119
7120        let (bob, _) = CertBuilder::new()
7121            .add_userid("bob@bar.com")
7122            .generate()?;
7123        let mut bob_signer =
7124            bob.primary_key().key().clone().parts_into_secret()?
7125            .into_keypair()?;
7126        let bob_pristine = bob.clone();
7127
7128        // Have Alice certify the binding between "bob@bar.com" and
7129        // Bob's key.
7130        let alice_certifies_bob
7131            = bob.userids().next().unwrap().userid().bind(
7132                &mut alice_signer, &bob,
7133                SignatureBuilder::new(SignatureType::GenericCertification))?;
7134        let bob = bob.insert_packets(vec![
7135            alice_certifies_bob.clone(),
7136        ])?.0;
7137
7138        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7139                   .certifications().count(), 1);
7140        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7141                   .approved_certifications().count(), 0);
7142
7143        // Have Bob attest that certification.
7144        let attestations =
7145            bob.userids().next().unwrap().approve_of_certifications(
7146                p,
7147                None,
7148                &mut bob_signer,
7149                vec![&alice_certifies_bob])?;
7150        assert_eq!(attestations.len(), 1);
7151        let attestation = attestations[0].clone();
7152
7153        let bob = bob.insert_packets(vec![
7154            attestation.clone(),
7155        ])?.0;
7156
7157        assert_eq!(bob.bad_signatures().count(), 0);
7158        assert_eq!(bob.userids().next().unwrap().certifications().next(),
7159                   Some(&alice_certifies_bob));
7160        assert_eq!(bob.userids().next().unwrap().bundle().approvals().next().unwrap(),
7161                   &attestation);
7162        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7163                   .certifications().count(), 1);
7164        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7165                   .approved_certifications().count(), 1);
7166
7167        // Check that attested key signatures are kept over merges.
7168        let bob_ = bob.clone().merge_public(bob_pristine.clone())?;
7169        assert_eq!(bob_.bad_signatures().count(), 0);
7170        assert_eq!(bob_.userids().next().unwrap().certifications().next(),
7171                   Some(&alice_certifies_bob));
7172        assert_eq!(bob_.userids().next().unwrap().bundle().approvals().next().unwrap(),
7173                   &attestation);
7174        assert_eq!(bob_.with_policy(p, None)?.userids().next().unwrap()
7175                   .approved_certifications().count(), 1);
7176
7177        // And the other way around.
7178        let bob_ = bob_pristine.clone().merge_public(bob.clone())?;
7179        assert_eq!(bob_.bad_signatures().count(), 0);
7180        assert_eq!(bob_.userids().next().unwrap().certifications().next(),
7181                   Some(&alice_certifies_bob));
7182        assert_eq!(bob_.userids().next().unwrap().bundle().approvals().next().unwrap(),
7183                   &attestation);
7184        assert_eq!(bob_.with_policy(p, None)?.userids().next().unwrap()
7185                   .approved_certifications().count(), 1);
7186
7187        // Have Bob withdraw any prior attestations.
7188
7189        let attestations =
7190            bob.userids().next().unwrap().approve_of_certifications(
7191                p,
7192                None,
7193                &mut bob_signer,
7194                &[])?;
7195        assert_eq!(attestations.len(), 1);
7196        let attestation = attestations[0].clone();
7197
7198        let bob = bob.insert_packets(vec![
7199            attestation.clone(),
7200        ])?.0;
7201
7202        assert_eq!(bob.bad_signatures().count(), 0);
7203        assert_eq!(bob.userids().next().unwrap().certifications().next(),
7204                   Some(&alice_certifies_bob));
7205        assert_eq!(bob.userids().next().unwrap().bundle().approvals().next().unwrap(),
7206                   &attestation);
7207        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7208                   .certifications().count(), 1);
7209        assert_eq!(bob.with_policy(p, None)?.userids().next().unwrap()
7210                   .approved_certifications().count(), 0);
7211
7212
7213        Ok(())
7214    }
7215
7216    /// Makes sure that certification approval key signatures are
7217    /// correctly handled.
7218    #[test]
7219    fn certification_approval_key_signatures_dkgpg() -> Result<()> {
7220        const DUMP: bool = false;
7221        let p = &crate::policy::StandardPolicy::new();
7222
7223        let test = Cert::from_bytes(crate::tests::key("1pa3pc-dkgpg.pgp"))?;
7224        assert_eq!(test.bad_signatures().count(), 0);
7225        assert_eq!(test.userids().next().unwrap().certifications().count(),
7226                   1);
7227        assert_eq!(test.userids().next().unwrap().bundle().approvals().count(),
7228                   1);
7229
7230        let attestation =
7231            test.userids().next().unwrap().bundle().approvals().next().unwrap();
7232
7233        if DUMP {
7234            for (i, d) in attestation.approved_certifications()?.enumerate() {
7235                crate::fmt::hex::Dumper::new(std::io::stderr(), "")
7236                    .write(d, format!("expected digest {}", i))?;
7237            }
7238        }
7239
7240        let digests: std::collections::HashSet<_> =
7241            attestation.approved_certifications()?.collect();
7242
7243        for (i, certification) in
7244            test.userids().next().unwrap().certifications().enumerate()
7245        {
7246            // Hash the certification.
7247            let mut h = attestation.hash_algo().context()?
7248                .for_signature(attestation.version());
7249            certification.hash_for_confirmation(&mut h)?;
7250            let digest = h.into_digest()?;
7251
7252            if DUMP {
7253                crate::fmt::hex::Dumper::new(std::io::stderr(), "")
7254                    .write(&digest, format!("computed digest {}", i))?;
7255            }
7256
7257            assert!(digests.contains(&digest[..]));
7258        }
7259
7260        assert_eq!(test.with_policy(p, None)?.userids().next().unwrap()
7261                   .certifications().count(), 1);
7262        assert_eq!(test.with_policy(p, None)?.userids().next().unwrap()
7263                   .approved_certifications().count(), 1);
7264
7265        Ok(())
7266    }
7267
7268    /// Makes sure that certification approval key signatures are
7269    /// correctly reordered.
7270    #[test]
7271    fn certification_approval_key_signature_out_of_order() -> Result<()> {
7272        let p = &crate::policy::StandardPolicy::new();
7273
7274        let (alice, _) = CertBuilder::general_purpose(
7275            Some("alice@example.org")).generate().unwrap();
7276        assert!(alice.keys().subkeys().count() > 0);
7277        let mut alice_signer =
7278            alice.primary_key().key().clone().parts_into_secret()?
7279            .into_keypair()?;
7280
7281        // Now, create new attestation signatures.
7282        let mut attestation_signatures = Vec::new();
7283        for uid in alice.userids() {
7284            attestation_signatures.append(&mut uid.approve_of_certifications(
7285                p,
7286                None,
7287                &mut alice_signer,
7288                uid.certifications(),
7289            )?);
7290        }
7291
7292        // Add the new signatures.  This appends the attestation
7293        // signature so that it is considered part of last component,
7294        // a subkey.
7295        let alice2 = alice.insert_packets(attestation_signatures)?.0;
7296
7297        // Now we make sure the attestation signature was correctly reordered.
7298        assert_eq!(alice2.bad_signatures().count(), 0);
7299        let ua = alice2.userids().next().unwrap();
7300        assert_eq!(ua.approvals().count(), 1);
7301
7302        Ok(())
7303    }
7304
7305    /// Makes sure that marker packets are ignored when parsing certs.
7306    #[test]
7307    fn marker_packets() -> Result<()> {
7308        let cert = Cert::from_bytes(crate::tests::key("neal.pgp"))?;
7309        let mut buf = Vec::new();
7310        Packet::Marker(Default::default()).serialize(&mut buf)?;
7311        cert.serialize(&mut buf)?;
7312
7313        let cert_ = Cert::from_bytes(&buf)?;
7314        assert_eq!(cert, cert_);
7315        Ok(())
7316    }
7317
7318    /// Checks that messing with a revocation signature merely
7319    /// invalidates the signature and keeps the cert's revocation
7320    /// status unchanged.
7321    #[test]
7322    fn issue_486() -> Result<()> {
7323        use crate::{
7324            crypto::mpi,
7325            types::RevocationStatus::*,
7326            packet::signature::Signature4,
7327            policy::StandardPolicy,
7328        };
7329        let p = &StandardPolicy::new();
7330
7331        let (cert, revocation) = CertBuilder::new().generate()?;
7332
7333        // Base case.
7334        let c = cert.clone().insert_packets(Some(revocation.clone()))?.0;
7335        if let Revoked(_) = c.revocation_status(p, None) {
7336            // cert is considered revoked
7337        } else {
7338            panic!("Should be revoked, but is not: {:?}",
7339                   c.revocation_status(p, None));
7340        }
7341
7342        // Breaking the revocation signature by changing the MPIs.
7343        let c = cert.clone().insert_packets(Some(
7344            Signature4::new(
7345                revocation.typ(),
7346                revocation.pk_algo(),
7347                revocation.hash_algo(),
7348                revocation.hashed_area().clone(),
7349                revocation.unhashed_area().clone(),
7350                *revocation.digest_prefix(),
7351                // MPI is replaced with a dummy one
7352                mpi::Signature::RSA {
7353                    s: mpi::MPI::from(vec![1, 2, 3])
7354                })))?.0;
7355        if let NotAsFarAsWeKnow = c.revocation_status(p, None) {
7356            assert_eq!(c.bad_signatures().count(), 1);
7357        } else {
7358            panic!("Should not be revoked, but is: {:?}",
7359                   c.revocation_status(p, None));
7360        }
7361
7362        // Breaking the revocation signature by changing the MPIs and
7363        // the digest prefix.
7364        let c = cert.clone().insert_packets(Some(
7365            Signature4::new(
7366                revocation.typ(),
7367                revocation.pk_algo(),
7368                revocation.hash_algo(),
7369                revocation.hashed_area().clone(),
7370                revocation.unhashed_area().clone(),
7371                // Prefix replaced with a dummy one
7372                [0, 1],
7373                // MPI is replaced with a dummy one
7374                mpi::Signature::RSA {
7375                    s: mpi::MPI::from(vec![1, 2, 3])
7376                })))?.0;
7377        if let NotAsFarAsWeKnow = c.revocation_status(p, None) {
7378            assert_eq!(c.bad_signatures().count(), 1);
7379        } else {
7380            panic!("Should not be revoked, but is: {:?}",
7381                   c.revocation_status(p, None));
7382        }
7383
7384        Ok(())
7385    }
7386
7387    /// Tests v3 binding signatures.
7388    #[test]
7389    #[allow(deprecated)]
7390    fn v3_binding_signature() -> Result<()> {
7391        skip_unless_supported!(crate::types::PublicKeyAlgorithm::DSA);
7392
7393        let c = Cert::from_bytes(
7394            crate::tests::key("pgp5-dsa-elg-v3-subkey-binding.pgp"))?;
7395        assert_eq!(c.bad_signatures().count(), 0);
7396
7397        let np = unsafe { crate::policy::NullPolicy::new() };
7398
7399        // The subkey is interesting because it is bound using a v3
7400        // signature.
7401        let vcert = c.with_policy(&np, None)?;
7402        assert_eq!(vcert.keys().subkeys().count(), 1);
7403
7404        // A v3 signature has no subpackets, so there are no key
7405        // flags.  But, we then consider the key role and public key
7406        // algorithm.
7407        assert_eq!(vcert.keys().for_signing().count(), 1);
7408        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
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        // A v3 signature has no subpackets, so there are no key
7415        // flags.  But, we then consider the key role and public key
7416        // algorithm.
7417        assert_eq!(c.keys().with_policy(&np, None).for_signing().count(), 1);
7418        assert_eq!(c.keys().with_policy(&np, None)
7419                   .for_transport_encryption().count(), 1);
7420
7421        Ok(())
7422    }
7423
7424    /// Tests v3 revocation signatures.
7425    #[test]
7426    fn v3_revocation_signature() -> Result<()> {
7427        skip_unless_supported!(crate::types::PublicKeyAlgorithm::ECDSA);
7428        skip_unless_supported!(crate::types::Curve::NistP521);
7429
7430        let c = Cert::from_bytes(
7431            crate::tests::key("v4-revoked-by-v3.pgp"))?;
7432        assert_eq!(c.bad_signatures().count(), 0);
7433
7434        let sp = crate::policy::StandardPolicy::new();
7435        assert!(matches!(c.revocation_status(&sp, None),
7436                         RevocationStatus::Revoked(_)));
7437        Ok(())
7438    }
7439
7440    #[test]
7441    fn v6_minimal_cert() -> Result<()> {
7442        let p = &crate::policy::StandardPolicy::new();
7443        let t = None; // XXX
7444        let cert = Cert::from_bytes(
7445            crate::tests::file("crypto-refresh/v6-minimal-cert.key"))?;
7446        assert_eq!(cert.userids().count(), 0);
7447        let vcert = cert.with_policy(p, t)?;
7448        assert_eq!(vcert.keys().count(), 2);
7449        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7450        assert_eq!(vcert.keys().unencrypted_secret().count(), 0);
7451        assert_eq!(vcert.keys().for_signing().count(), 1);
7452        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7453
7454        let cert = Cert::from_bytes(
7455            crate::tests::file("crypto-refresh/v6-minimal-secret.key")).unwrap();
7456        assert_eq!(cert.userids().count(), 0);
7457        let vcert = cert.with_policy(p, t)?;
7458        assert_eq!(vcert.keys().count(), 2);
7459        assert_eq!(vcert.keys().encrypted_secret().count(), 0);
7460        assert_eq!(vcert.keys().unencrypted_secret().count(), 2);
7461        assert_eq!(vcert.keys().for_signing().count(), 1);
7462        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7463
7464        // The following key uses Argon2, and it takes 2 GiB to
7465        // efficiently derive the KEK.  This isn't viable on 32 bit
7466        // architectures.
7467        let name = if cfg!(target_pointer_width = "16") {
7468            return Ok(()); // No chance we even got here.
7469        } else if cfg!(target_pointer_width = "32") {
7470            // For 32 bit architectures, we have a test vector which
7471            // uses the "SECOND RECOMMENDED" parameter choice for
7472            // memory constrained systems (see Section 4 of RFC 9106).
7473            "v6-minimal-secret-locked-for-constrained-envs.key"
7474        } else {
7475            // 64 bit or weird.  Good luck.
7476            "v6-minimal-secret-locked.key"
7477        };
7478
7479        let cert = Cert::from_bytes(
7480            crate::tests::file(&format!("crypto-refresh/{}", name)))?;
7481        assert_eq!(cert.userids().count(), 0);
7482        let vcert = cert.with_policy(p, t)?;
7483        assert_eq!(vcert.keys().count(), 2);
7484        assert_eq!(vcert.keys().encrypted_secret().count(), 2);
7485        assert_eq!(vcert.keys().unencrypted_secret().count(), 0);
7486        assert_eq!(vcert.keys().for_signing().count(), 1);
7487        assert_eq!(vcert.keys().for_transport_encryption().count(), 1);
7488
7489        let password = "correct horse battery staple".into();
7490        for skb in vcert.keys().encrypted_secret() {
7491            skb.key().secret().clone().decrypt(skb.key(), &password)?;
7492        }
7493
7494        Ok(())
7495    }
7496}