sequoia_openpgp/cert/
bundle.rs

1//! A certificate component and its associated signatures.
2//!
3//! Certificates ([`Cert`]s) are a collection of components where each
4//! component corresponds to a [`Packet`], and each component has zero
5//! or more associated [`Signature`]s.  A [`ComponentBundle`]
6//! encapsulates a component and its associated signatures.
7//!
8//! Sequoia supports four different kinds of components: [`Key`]s,
9//! [`UserID`]s, [`UserAttribute`]s, and [`Unknown`] components.  The
10//! `Unknown` component has two purposes.  First, it is used to store
11//! packets that appear in a certificate and have an unknown [`Tag`].
12//! By not silently dropping these packets, it is possible to round
13//! trip certificates without losing any information.  This provides a
14//! measure of future compatibility.  Second, the `Unknown` component
15//! is used to store unsupported components.  For instance, Sequoia
16//! doesn't support v3 `Key`s, which are deprecated, or v5 `Key`s,
17//! which are still being standardized.  Because these keys are
18//! effectively unusable, they are stored as `Unknown` components
19//! instead of `Key`s.
20//!
21//! There are four types of signatures associated with a component:
22//! self signatures, self revocations, third-party signatures, and
23//! third-party revocations.  When parsing a certificate, self
24//! signatures and self revocations are checked for validity and
25//! invalid signatures and revocations are discarded.  Since the keys
26//! are not normally available, third-party signatures and third-party
27//! revocations cannot be rigorously (i.e., cryptographically) checked
28//! for validity.
29//!
30//! With the exception of the primary key, a component's self
31//! signatures are binding signatures.  A binding signature firstly
32//! binds the component to the certificate.  That is, it provides
33//! cryptographic evidence that the certificate holder intended for
34//! the component to be associated with the certificate.  Binding
35//! signatures also provide information about the component.  For
36//! instance, the binding signature for a subkey includes its
37//! capabilities, and its expiry time.
38//!
39//! Since the primary key is the embodiment of the certificate, there
40//! is nothing to bind it to.  Correspondingly, self signatures on a
41//! primary key are called direct key signatures.  Direct key
42//! signatures are used to provide information about the whole
43//! certificate.  For instance, they can include the default `Key`
44//! expiry time.  This is used if a subkey's binding signature doesn't
45//! include an expiry.
46//!
47//! Self-revocations are revocation certificates issued by the key
48//! certificate holder.
49//!
50//! Third-party signatures are typically signatures certifying that a
51//! `User ID` or `User Attribute` accurately describes the certificate
52//! holder.  This information is used by trust models, like the Web of
53//! Trust, to indirectly authenticate keys.
54//!
55//! Third-party revocations are revocations issued by another
56//! certificate.  They should normally only be respected if the
57//! certificate holder made the issuer a so-called [designated
58//! revoker].
59//!
60//! # Important
61//!
62//! When looking up information about a component, it is generally
63//! better to use the [`ComponentAmalgamation`] or [`KeyAmalgamation`]
64//! data structures.  These data structures provide convenience
65//! methods that implement the [complicated semantics] for correctly
66//! locating information.
67//!
68//! [`Cert`]: super
69//! [`Packet`]: crate::packet
70//! [`Signature`]: crate::packet::signature
71//! [`Key`]: crate::packet::key
72//! [`UserID`]: crate::packet::UserID
73//! [`UserAttribute`]: crate::packet::user_attribute
74//! [`Unknown`]: crate::packet::Unknown
75//! [`Tag`]: crate::packet::Tag
76//! [designated revoker]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.23
77//! [`ComponentAmalgamation`]: super::amalgamation
78//! [`KeyAmalgamation`]: super::amalgamation::key::KeyAmalgamation
79//! [complicated semantics]: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.10
80
81use std::time;
82use std::cmp::{self, Ordering};
83use std::ops::{Deref, DerefMut};
84use std::sync::Arc;
85
86use crate::{
87    cert::lazysigs::{LazySignatures, SigState},
88    Error,
89    packet::Signature,
90    packet::Key,
91    packet::key,
92    packet::UserID,
93    packet::UserAttribute,
94    packet::Unknown,
95    Packet,
96    policy::HashAlgoSecurity,
97    policy::Policy,
98    Result,
99};
100use crate::types::{
101    RevocationType,
102    RevocationStatus,
103};
104
105use super::{
106    sig_cmp,
107    canonical_signature_order,
108};
109
110/// A certificate component and its associated signatures.
111///
112/// [See the module level documentation](self) for a detailed
113/// description.
114#[derive(Debug, Clone, PartialEq)]
115pub struct ComponentBundle<C> {
116    component: C,
117
118    pub(super) hash_algo_security: HashAlgoSecurity,
119
120    // Self signatures.
121    pub(super) self_signatures: LazySignatures,
122
123    /// If set, is equal to `component`, and provides context to
124    /// verify primary key binding signatures.
125    backsig_signer: Option<Key<key::PublicParts, key::SubordinateRole>>,
126
127    // Third-party certifications.  (In general, this will only be by
128    // designated revokers.)
129    pub(super) certifications: Vec<Signature>,
130
131    // Attestation key signatures.
132    pub(super) attestations: LazySignatures,
133
134    // Self revocations.
135    pub(super) self_revocations: LazySignatures,
136
137    // Third-party revocations (e.g., designated revokers).
138    pub(super) other_revocations: Vec<Signature>,
139}
140assert_send_and_sync!(ComponentBundle<C> where C);
141
142/// A key (primary or subkey, public or private) and any associated
143/// signatures.
144///
145/// [See the module level documentation.](self)
146pub type KeyBundle<KeyPart, KeyRole> = ComponentBundle<Key<KeyPart, KeyRole>>;
147
148/// A primary key and any associated signatures.
149///
150/// [See the module level documentation.](self)
151pub type PrimaryKeyBundle<KeyPart> =
152    KeyBundle<KeyPart, key::PrimaryRole>;
153
154/// A subkey and any associated signatures.
155///
156/// [See the module level documentation.](self)
157pub type SubkeyBundle<KeyPart>
158    = KeyBundle<KeyPart, key::SubordinateRole>;
159
160/// A User ID and any associated signatures.
161///
162/// [See the module level documentation.](self)
163pub type UserIDBundle = ComponentBundle<UserID>;
164
165/// A User Attribute and any associated signatures.
166///
167/// [See the module level documentation.](self)
168pub type UserAttributeBundle = ComponentBundle<UserAttribute>;
169
170/// An unknown component and any associated signatures.
171///
172/// Note: all signatures are stored as certifications.
173///
174/// [See the module level documentation.](self)
175pub type UnknownBundle = ComponentBundle<Unknown>;
176
177
178impl<C> ComponentBundle<C> {
179    /// Creates a new component.
180    ///
181    /// Should only be used from the cert parser.  However, we cannot
182    /// use `pub(in ...)` because the cert parser isn't an ancestor of
183    /// this module.
184    pub(crate) fn new(component: C,
185                      hash_algo_security: HashAlgoSecurity,
186                      sigs: Vec<Signature>,
187                      primary_key: Arc<Key<key::PublicParts, key::PrimaryRole>>)
188           -> ComponentBundle<C>
189    {
190        ComponentBundle {
191            component,
192            hash_algo_security,
193            self_signatures: LazySignatures::new(primary_key.clone()),
194            backsig_signer: None,
195            certifications: sigs,
196            attestations: LazySignatures::new(primary_key.clone()),
197            self_revocations: LazySignatures::new(primary_key),
198            other_revocations: vec![],
199        }
200    }
201
202    /// Returns a reference to the bundle's component.
203    ///
204    /// # Examples
205    ///
206    /// ```
207    /// # use sequoia_openpgp as openpgp;
208    /// # use openpgp::cert::prelude::*;
209    /// #
210    /// # fn main() -> openpgp::Result<()> {
211    /// # let (cert, _) =
212    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
213    /// #     .generate()?;
214    /// // Display some information about any unknown components.
215    /// for u in cert.unknowns() {
216    ///     eprintln!(" - {:?}", u.bundle().component());
217    /// }
218    /// # Ok(()) }
219    /// ```
220    pub fn component(&self) -> &C {
221        &self.component
222    }
223
224    /// Returns a mutable reference to the component.
225    pub(crate) fn component_mut(&mut self) -> &mut C {
226        &mut self.component
227    }
228
229    /// Returns the active binding signature at time `t`.
230    ///
231    /// The active binding signature is the most recent, non-revoked
232    /// self-signature that is valid according to the `policy` and
233    /// alive at time `t` (`creation time <= t`, `t < expiry`).  If
234    /// there are multiple such signatures then the signatures are
235    /// ordered by their MPIs interpreted as byte strings.
236    ///
237    /// # Examples
238    ///
239    /// ```
240    /// # use sequoia_openpgp as openpgp;
241    /// # use openpgp::cert::prelude::*;
242    /// use openpgp::policy::StandardPolicy;
243    /// #
244    /// # fn main() -> openpgp::Result<()> {
245    /// let p = &StandardPolicy::new();
246    ///
247    /// # let (cert, _) =
248    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
249    /// #     .generate()?;
250    /// // Display information about each User ID's current active
251    /// // binding signature (the `time` parameter is `None`), if any.
252    /// for ua in cert.userids() {
253    ///     eprintln!("{:?}", ua.bundle().binding_signature(p, None));
254    /// }
255    /// # Ok(()) }
256    /// ```
257    pub fn binding_signature<T>(&self, policy: &dyn Policy, t: T)
258                                -> Result<&Signature>
259        where T: Into<Option<time::SystemTime>>
260    {
261        let t = t.into().unwrap_or_else(crate::now);
262
263      /// Finds the active binding signature.
264      ///
265      /// This function does not depend on the type of `C`, but it
266      /// is unfortunately monomorphized for every `C`.  Prevent
267      /// this by moving the code to a function independent of `C`.
268      fn find_binding_signature<'s>(policy: &dyn Policy,
269                                    self_signatures: &'s LazySignatures,
270                                    backsig_signer:
271                                    Option<&Key<key::PublicParts, key::SubordinateRole>>,
272                                    hash_algo_security: HashAlgoSecurity,
273                                    t: time::SystemTime)
274                                    -> Result<&'s Signature>
275      {
276        // Recall: the signatures are sorted by their creation time in
277        // descending order, i.e., newest first.
278        //
279        // We want the newest signature that is older than `t`, or
280        // that has been created at `t`.  So, search for `t`.
281
282        // We search all signatures without triggering the signature
283        // verification.  Later, we will verify the candidates, and
284        // reject bad signatures.
285        let unverified_self_signatures = self_signatures.as_slice_unverified();
286
287        let i =
288            // Usually, the first signature is what we are looking for.
289            // Short circuit the binary search.
290              if unverified_self_signatures.get(0)
291              .filter(|s| s.signature_creation_time().map(|c| t >= c)
292                      .unwrap_or(false))
293              .filter(
294                  // Verify the signature now.
295                  |_| matches!(self_signatures.verify_sig(0, backsig_signer),
296                               Ok(SigState::Good)))
297              .is_some()
298            {
299                0
300            } else {
301                match unverified_self_signatures.binary_search_by(
302                    |s| canonical_signature_order(
303                        s.signature_creation_time(), Some(t)))
304                {
305                    // If there are multiple matches, then we need to search
306                    // backwards to find the first one.  Consider:
307                    //
308                    //     t: 9 8 8 8 8 7
309                    //     i: 0 1 2 3 4 5
310                    //
311                    // If we are looking for t == 8, then binary_search could
312                    // return index 1, 2, 3 or 4.
313                    Ok(mut i) => {
314                        while i > 0
315                            && unverified_self_signatures[i - 1].signature_creation_time()
316                            == Some(t)
317                        {
318                            i -= 1;
319                        }
320                        i
321                    }
322
323                    // There was no match.  `i` is where a new element could
324                    // be inserted while maintaining the sorted order.
325                    // Consider:
326                    //
327                    //    t: 9 8 6 5
328                    //    i: 0 1 2 3
329                    //
330                    // If we are looing for t == 7, then binary_search will
331                    // return i == 2.  That's exactly where we should start
332                    // looking.
333                    Err(i) => i,
334                }
335            };
336
337        let mut sig = None;
338
339        // Prefer the first error, which is the error arising from the
340        // most recent binding signature that wasn't created after
341        // `t`.
342        let mut error = None;
343
344        'next_sig: for (j, s) in unverified_self_signatures[i..].iter()
345            .enumerate()
346        {
347            if let Err(e) = s.signature_alive(t, time::Duration::new(0, 0)) {
348                // We know that t >= signature's creation time.  So,
349                // it is expired.  But an older signature might not
350                // be.  So, keep trying.
351                if error.is_none() {
352                    error = Some(e);
353                }
354                continue;
355            }
356
357            if let Err(e) = policy.signature(s, hash_algo_security)
358            {
359                if error.is_none() {
360                    error = Some(e);
361                }
362                continue;
363            }
364
365            // Verify the signature now.
366            if ! matches!(self_signatures.verify_sig(i + j, backsig_signer),
367                          Ok(SigState::Good)) {
368                // Reject bad signatures.
369                continue;
370            }
371
372            // The signature is good, but we may still need to verify the
373            // back sig.
374            if s.typ() == crate::types::SignatureType::SubkeyBinding &&
375                s.key_flags().map(|kf| kf.for_signing()).unwrap_or(false)
376            {
377                let mut n = 0;
378                let mut one_good_backsig = false;
379                'next_backsig: for backsig in s.embedded_signatures() {
380                    n += 1;
381                    if let Err(e) = backsig.signature_alive(
382                        t, time::Duration::new(0, 0))
383                    {
384                        // The primary key binding signature is not
385                        // alive.
386                        if error.is_none() {
387                            error = Some(e);
388                        }
389                        continue 'next_backsig;
390                    }
391
392                    if let Err(e) = policy
393                        .signature(backsig, hash_algo_security)
394                    {
395                        if error.is_none() {
396                            error = Some(e);
397                        }
398                        continue 'next_backsig;
399                    }
400
401                    one_good_backsig = true;
402                }
403
404                if n == 0 {
405                    // This shouldn't happen because
406                    // Signature::verify_subkey_binding checks for the
407                    // primary key binding signature.  But, better be
408                    // safe.
409                    if error.is_none() {
410                        error = Some(Error::BadSignature(
411                            "Primary key binding signature missing".into())
412                                     .into());
413                    }
414                    continue 'next_sig;
415                }
416
417                if ! one_good_backsig {
418                    continue 'next_sig;
419                }
420            }
421
422            sig = Some(s);
423            break;
424        }
425
426        if let Some(sig) = sig {
427            Ok(sig)
428        } else if let Some(err) = error {
429            Err(err)
430        } else {
431            Err(Error::NoBindingSignature(t).into())
432        }
433      }
434
435        find_binding_signature(
436            policy,
437            &self.self_signatures,
438            self.backsig_signer.as_ref(),
439            self.hash_algo_security, t)
440    }
441
442    /// Returns the component's self-signatures.
443    ///
444    /// The signatures are validated, and they are sorted by their
445    /// creation time, most recent first.
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// # use sequoia_openpgp as openpgp;
451    /// # use openpgp::cert::prelude::*;
452    /// use openpgp::policy::StandardPolicy;
453    /// #
454    /// # fn main() -> openpgp::Result<()> {
455    /// let p = &StandardPolicy::new();
456    ///
457    /// # let (cert, _) =
458    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
459    /// #     .generate()?;
460    /// for (i, ka) in cert.keys().enumerate() {
461    ///     eprintln!("Key #{} ({}) has {:?} self signatures",
462    ///               i, ka.key().fingerprint(),
463    ///               ka.bundle().self_signatures().count());
464    /// }
465    /// # Ok(()) }
466    /// ```
467    pub fn self_signatures(&self)
468                           -> impl Iterator<Item=&Signature> + Send + Sync {
469        self.self_signatures.iter_verified(self.backsig_signer.as_ref())
470    }
471
472    /// Returns the component's third-party certifications.
473    ///
474    /// The signatures are *not* validated.  They are sorted by their
475    /// creation time, most recent first.
476    ///
477    /// # Examples
478    ///
479    /// ```
480    /// # use sequoia_openpgp as openpgp;
481    /// # use openpgp::cert::prelude::*;
482    /// use openpgp::policy::StandardPolicy;
483    /// #
484    /// # fn main() -> openpgp::Result<()> {
485    /// let p = &StandardPolicy::new();
486    ///
487    /// # let (cert, _) =
488    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
489    /// #     .generate()?;
490    /// for ua in cert.userids() {
491    ///     eprintln!("User ID {} has {:?} unverified, third-party certifications",
492    ///               String::from_utf8_lossy(ua.userid().value()),
493    ///               ua.bundle().certifications().count());
494    /// }
495    /// # Ok(()) }
496    /// ```
497    pub fn certifications(&self)
498                          -> impl Iterator<Item=&Signature> + Send + Sync {
499        self.certifications.iter()
500    }
501
502    /// Returns the component's revocations that were issued by the
503    /// certificate holder.
504    ///
505    /// The revocations are validated, and they are sorted by their
506    /// creation time, most recent first.
507    ///
508    /// # Examples
509    ///
510    /// ```
511    /// # use sequoia_openpgp as openpgp;
512    /// # use openpgp::cert::prelude::*;
513    /// use openpgp::policy::StandardPolicy;
514    /// #
515    /// # fn main() -> openpgp::Result<()> {
516    /// let p = &StandardPolicy::new();
517    ///
518    /// # let (cert, _) =
519    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
520    /// #     .generate()?;
521    /// for u in cert.userids() {
522    ///     eprintln!("User ID {} has {:?} revocation certificates.",
523    ///               String::from_utf8_lossy(u.userid().value()),
524    ///               u.bundle().self_revocations().count());
525    /// }
526    /// # Ok(()) }
527    /// ```
528    pub fn self_revocations(&self)
529                            -> impl Iterator<Item=&Signature> + Send + Sync {
530        self.self_revocations.iter_verified(self.backsig_signer.as_ref())
531    }
532
533    /// Returns the component's revocations that were issued by other
534    /// certificates.
535    ///
536    /// The revocations are *not* validated.  They are sorted by their
537    /// creation time, most recent first.
538    ///
539    /// # Examples
540    ///
541    /// ```
542    /// # use sequoia_openpgp as openpgp;
543    /// # use openpgp::cert::prelude::*;
544    /// use openpgp::policy::StandardPolicy;
545    /// #
546    /// # fn main() -> openpgp::Result<()> {
547    /// let p = &StandardPolicy::new();
548    ///
549    /// # let (cert, _) =
550    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
551    /// #     .generate()?;
552    /// for u in cert.userids() {
553    ///     eprintln!("User ID {} has {:?} unverified, third-party revocation certificates.",
554    ///               String::from_utf8_lossy(u.userid().value()),
555    ///               u.bundle().other_revocations().count());
556    /// }
557    /// # Ok(()) }
558    /// ```
559    pub fn other_revocations(&self)
560                             -> impl Iterator<Item=&Signature> + Send + Sync {
561        self.other_revocations.iter()
562    }
563
564    /// Returns all the component's Certification Approval Key
565    /// Signatures.
566    ///
567    /// This feature is [experimental](crate#experimental-features).
568    ///
569    /// The signatures are validated, and they are sorted by their
570    /// creation time, most recent first.
571    ///
572    /// A certificate owner can use Certification Approval Key
573    /// Signatures to approve of third party certifications.
574    /// Currently, only user ID and user attribute certifications can
575    /// be approved.  See [Approved Certifications subpacket] for
576    /// details.
577    ///
578    ///   [Approved Certifications subpacket]: https://www.ietf.org/archive/id/draft-dkg-openpgp-1pa3pc-02.html#approved-certifications-subpacket
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// # use sequoia_openpgp as openpgp;
584    /// # fn main() -> openpgp::Result<()> {
585    /// # use openpgp::cert::prelude::*;
586    /// use openpgp::policy::StandardPolicy;
587    /// let p = &StandardPolicy::new();
588    ///
589    /// # let (cert, _) =
590    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
591    /// #     .generate()?;
592    /// for (i, uid) in cert.userids().enumerate() {
593    ///     eprintln!("UserID #{} ({:?}) has {:?} certification approval key signatures",
594    ///               i, uid.userid().email(),
595    ///               uid.bundle().approvals().count());
596    /// }
597    /// # Ok(()) }
598    /// ```
599    pub fn approvals(&self)
600                     -> impl Iterator<Item = &Signature> + Send + Sync
601    {
602        self.attestations.iter_verified(None)
603    }
604
605    /// Returns all the component's signatures.
606    ///
607    /// Only the self-signatures are validated.  The signatures are
608    /// sorted first by type, then by creation time.  The self
609    /// revocations come first, then the self signatures,
610    /// then any certification approval key signatures,
611    /// certifications, and third-party revocations coming last.  This
612    /// function may return additional types of signatures that could
613    /// be associated to this component.
614    ///
615    /// # Examples
616    ///
617    /// ```
618    /// # use sequoia_openpgp as openpgp;
619    /// # use openpgp::cert::prelude::*;
620    /// use openpgp::policy::StandardPolicy;
621    /// #
622    /// # fn main() -> openpgp::Result<()> {
623    /// let p = &StandardPolicy::new();
624    ///
625    /// # let (cert, _) =
626    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
627    /// #     .generate()?;
628    /// for (i, ka) in cert.keys().enumerate() {
629    ///     eprintln!("Key #{} ({}) has {:?} signatures",
630    ///               i, ka.key().fingerprint(),
631    ///               ka.bundle().signatures().count());
632    /// }
633    /// # Ok(()) }
634    /// ```
635    pub fn signatures(&self)
636                      -> impl Iterator<Item = &Signature> + Send + Sync
637    {
638        self.self_revocations()
639            .chain(self.self_signatures())
640            .chain(self.approvals())
641            .chain(self.certifications())
642            .chain(self.other_revocations())
643    }
644
645    /// Returns all the bundles' bad signatures.
646    pub(crate) fn bad_signatures(&self)
647        -> impl Iterator<Item = &Signature> + Send + Sync
648    {
649        self.self_signatures.iter_bad(self.backsig_signer.as_ref())
650            .chain(self.self_revocations.iter_bad(self.backsig_signer.as_ref()))
651    }
652
653    /// Returns the component's revocation status at time `t`.
654    ///
655    /// A component is considered to be revoked at time `t` if:
656    ///
657    ///   - There is a live revocation at time `t` that is newer than
658    ///     all live self signatures at time `t`.
659    ///
660    ///   - `hard_revocations_are_final` is true, and there is a hard
661    ///     revocation (even if it is not yet live at time `t`, and
662    ///     even if there is a newer self-signature).
663    ///
664    /// selfsig must be the newest live self signature at time `t`.
665    pub(crate) fn _revocation_status<'a, T>(&'a self, policy: &dyn Policy, t: T,
666                                            hard_revocations_are_final: bool,
667                                            selfsig: Option<&Signature>)
668        -> RevocationStatus<'a>
669        where T: Into<Option<time::SystemTime>>
670    {
671        // Fallback time.
672        let time_zero = || time::UNIX_EPOCH;
673        let t = t.into().unwrap_or_else(crate::now);
674        let selfsig_creation_time
675            = selfsig.and_then(|s| s.signature_creation_time())
676                     .unwrap_or_else(time_zero);
677
678        tracer!(super::TRACE, "ComponentBundle::_revocation_status", 0);
679        t!("hard_revocations_are_final: {}, selfsig: {:?}, t: {:?}",
680           hard_revocations_are_final,
681           selfsig_creation_time,
682           t);
683        if let Some(selfsig) = selfsig {
684            assert!(
685                selfsig.signature_alive(t, time::Duration::new(0, 0)).is_ok());
686        }
687
688        let check = |revs: &mut dyn Iterator<Item=&'a Signature>, sec: HashAlgoSecurity|
689            -> Option<Vec<&'a Signature>>
690        {
691            let revs = revs.filter(|rev| {
692                if let Err(err) = policy.signature(rev, sec) {
693                    t!("  revocation rejected by caller policy: {}", err);
694                    false
695                } else if hard_revocations_are_final
696                    && rev.reason_for_revocation()
697                    .map(|(r, _)| {
698                        r.revocation_type() == RevocationType::Hard
699                    })
700                // If there is no Reason for Revocation
701                // packet, assume that it is a hard
702                // revocation.
703                    .unwrap_or(true)
704                {
705                    t!("  got a hard revocation: {:?}, {:?}",
706                       rev.signature_creation_time()
707                       .unwrap_or_else(time_zero),
708                       rev.reason_for_revocation()
709                       .map(|r| (r.0, String::from_utf8_lossy(r.1))));
710                    true
711                } else if selfsig_creation_time
712                    > rev.signature_creation_time().unwrap_or_else(time_zero)
713                {
714                    // This comes after the hard revocation check,
715                    // because a hard revocation is always valid.
716                    t!("  newer binding signature trumps soft revocation ({:?} > {:?})",
717                       selfsig_creation_time,
718                       rev.signature_creation_time().unwrap_or_else(time_zero));
719                    false
720                } else if let Err(err)
721                    = rev.signature_alive(t, time::Duration::new(0, 0))
722                {
723                    // This comes after the hard revocation check,
724                    // because a hard revocation is always valid.
725                    t!("  revocation not alive ({:?} - {:?}): {}",
726                       rev.signature_creation_time().unwrap_or_else(time_zero),
727                       rev.signature_validity_period()
728                           .unwrap_or_else(|| time::Duration::new(0, 0)),
729                       err);
730                    false
731                } else {
732                    t!("  got a revocation: {:?} ({:?})",
733                       rev.signature_creation_time().unwrap_or_else(time_zero),
734                       rev.reason_for_revocation()
735                           .map(|r| (r.0, String::from_utf8_lossy(r.1))));
736                    true
737                }
738            }).collect::<Vec<&Signature>>();
739
740            if revs.is_empty() {
741                None
742            } else {
743                Some(revs)
744            }
745        };
746
747        if let Some(revs)
748            = check(&mut self.self_revocations.iter_verified(self.backsig_signer.as_ref()),
749                    self.hash_algo_security)
750        {
751            t!("-> RevocationStatus::Revoked({})", revs.len());
752            RevocationStatus::Revoked(revs)
753        } else if let Some(revs)
754            = check(&mut self.other_revocations.iter(), Default::default())
755        {
756            t!("-> RevocationStatus::CouldBe({})", revs.len());
757            RevocationStatus::CouldBe(revs)
758        } else {
759            t!("-> RevocationStatus::NotAsFarAsWeKnow");
760            RevocationStatus::NotAsFarAsWeKnow
761        }
762    }
763
764    /// Turns the `ComponentBundle` into an iterator over its
765    /// `Packet`s.
766    ///
767    /// The signatures are ordered as follows:
768    ///
769    ///   - Self revocations,
770    ///   - Self signatures,
771    ///   - Third-party signatures, and
772    ///   - Third-party revocations.
773    ///
774    /// For a given type of signature, the signatures are ordered by
775    /// their creation time, most recent first.
776    ///
777    /// When turning the `Key` in a `KeyBundle` into a `Packet`, this
778    /// function uses the component's type (`C`) to determine the
779    /// packet's type; the type is not a function of whether the key
780    /// has secret key material.
781    pub(crate) fn into_packets(self)
782                               -> impl Iterator<Item=Packet> + Send + Sync
783        where Packet: From<C>
784    {
785        let p : Packet = self.component.into();
786        std::iter::once(p)
787            .chain(self.self_revocations.into_unverified().map(|s| s.into()))
788            .chain(self.self_signatures.into_unverified().map(|s| s.into()))
789            .chain(self.attestations.into_unverified().map(|s| s.into()))
790            .chain(self.certifications.into_iter().map(|s| s.into()))
791            .chain(self.other_revocations.into_iter().map(|s| s.into()))
792    }
793
794    // Sorts and dedups the binding's signatures.
795    //
796    // Note: this uses Signature::normalized_eq to compare signatures.
797    // That function ignores unhashed packets.  If there are two
798    // signatures that only differ in their unhashed subpackets, they
799    // will be deduped.  The unhashed areas are merged as discussed in
800    // Signature::merge.
801    pub(crate) fn sort_and_dedup(&mut self)
802    {
803        // `same_bucket` function for Vec::dedup_by that compares
804        // signatures and merges them if they are equal modulo
805        // unhashed subpackets.
806        fn sig_merge(a: &mut Signature, b: &mut Signature) -> bool {
807            // If a == b, a is removed.  Hence, we merge into b.
808            if a.normalized_eq(b) {
809                b.merge_internal(a)
810                    .expect("checked for equality above");
811                true
812            } else {
813                false
814            }
815        }
816
817        // If two signatures are merged, we also do some fixups.  Make
818        // sure we also do this to signatures that are not merged, so
819        // that `cert.merge(cert) == cert`.
820        fn sig_fixup(sig: &mut Signature) {
821            // Add missing issuer information.  This is a best effort
822            // though.  If the unhashed area is full, there is nothing
823            // we can do.
824            let _ = sig.add_missing_issuers();
825
826            // Merging Signatures sorts the unhashed subpacket area.
827            // Do the same.
828            sig.unhashed_area_mut().sort();
829        }
830
831        self.self_signatures.sort_by(Signature::normalized_cmp);
832        self.self_signatures.dedup_by(sig_merge);
833        // Order self signatures so that the most recent one comes
834        // first.
835        self.self_signatures.sort_by(sig_cmp);
836        self.self_signatures.iter_mut_unverified().for_each(sig_fixup);
837
838        self.attestations.sort_by(Signature::normalized_cmp);
839        self.attestations.dedup_by(sig_merge);
840        self.attestations.sort_by(sig_cmp);
841        self.attestations.iter_mut_unverified().for_each(sig_fixup);
842
843        self.certifications.sort_by(Signature::normalized_cmp);
844        self.certifications.dedup_by(sig_merge);
845        // There is no need to sort the certifications, but doing so
846        // has the advantage that the most recent ones (and therefore
847        // presumably the more relevant ones) come first.  Also,
848        // cert::test::signature_order checks that the signatures are
849        // sorted.
850        self.certifications.sort_by(sig_cmp);
851        self.certifications.iter_mut().for_each(sig_fixup);
852
853        self.self_revocations.sort_by(Signature::normalized_cmp);
854        self.self_revocations.dedup_by(sig_merge);
855        self.self_revocations.sort_by(sig_cmp);
856        self.self_revocations.iter_mut_unverified().for_each(sig_fixup);
857
858        self.other_revocations.sort_by(Signature::normalized_cmp);
859        self.other_revocations.dedup_by(sig_merge);
860        self.other_revocations.sort_by(sig_cmp);
861        self.other_revocations.iter_mut().for_each(sig_fixup);
862    }
863}
864
865impl<P: key::KeyParts, R: key::KeyRole> ComponentBundle<Key<P, R>> {
866    /// Returns a reference to the key.
867    ///
868    /// This is just a type-specific alias for
869    /// [`ComponentBundle::component`].
870    ///
871    /// [`ComponentBundle::component`]: ComponentBundle::component()
872    ///
873    /// # Examples
874    ///
875    /// ```
876    /// # use sequoia_openpgp as openpgp;
877    /// # use openpgp::cert::prelude::*;
878    /// #
879    /// # fn main() -> openpgp::Result<()> {
880    /// # let (cert, _) =
881    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
882    /// #     .generate()?;
883    /// // Display some information about the keys.
884    /// for ka in cert.keys() {
885    ///     eprintln!(" - {:?}", ka.bundle().key());
886    /// }
887    /// # Ok(()) }
888    /// ```
889    pub fn key(&self) -> &Key<P, R> {
890        self.component()
891    }
892
893    /// Returns a mut reference to the key.
894    pub(crate) fn key_mut(&mut self) -> &mut Key<P, R> {
895        self.component_mut()
896    }
897
898    pub(crate) fn set_role(&mut self, role: key::KeyRoleRT) {
899        self.key_mut().set_role(role);
900    }
901
902    /// Forwarder for the conversion macros.
903    pub(crate) fn has_secret(&self) -> bool {
904        self.key().has_secret()
905    }
906}
907
908impl<P: key::KeyParts> ComponentBundle<Key<P, key::SubordinateRole>> {
909    /// Creates a new subkey component.
910    ///
911    /// Should only be used from the cert parser.  However, we cannot
912    /// use `pub(in ...)` because the cert parser isn't an ancestor of
913    /// this module.
914    pub(crate) fn new_subkey(component: Key<P, key::SubordinateRole>,
915                             hash_algo_security: HashAlgoSecurity,
916                             sigs: Vec<Signature>,
917                             primary_key: Arc<Key<key::PublicParts, key::PrimaryRole>>)
918           -> Self
919    {
920        let backsig_signer = component.pk_algo().for_signing()
921            .then(|| component.parts_as_public().clone());
922        ComponentBundle {
923            component,
924            hash_algo_security,
925            self_signatures: LazySignatures::new(primary_key.clone()),
926            backsig_signer,
927            certifications: sigs,
928            attestations: LazySignatures::new(primary_key.clone()),
929            self_revocations: LazySignatures::new(primary_key),
930            other_revocations: vec![],
931        }
932    }
933
934    /// Returns the subkey's revocation status at time `t`.
935    ///
936    /// A subkey is revoked at time `t` if:
937    ///
938    ///   - There is a live revocation at time `t` that is newer than
939    ///     all live self signatures at time `t`, or
940    ///
941    ///   - There is a hard revocation (even if it is not live at
942    ///     time `t`, and even if there is a newer self-signature).
943    ///
944    /// Note: Certs and subkeys have different criteria from User IDs
945    /// and User Attributes.
946    ///
947    /// Note: this only returns whether this subkey is revoked; it
948    /// does not imply anything about the Cert or other components.
949    ///
950    /// # Examples
951    ///
952    /// ```
953    /// # use sequoia_openpgp as openpgp;
954    /// # use openpgp::cert::prelude::*;
955    /// use openpgp::policy::StandardPolicy;
956    /// #
957    /// # fn main() -> openpgp::Result<()> {
958    /// let p = &StandardPolicy::new();
959    ///
960    /// # let (cert, _) =
961    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
962    /// #     .generate()?;
963    /// // Display the subkeys' revocation status.
964    /// for ka in cert.keys().subkeys() {
965    ///     eprintln!(" Revocation status of {}: {:?}",
966    ///               ka.key().fingerprint(),
967    ///               ka.bundle().revocation_status(p, None));
968    /// }
969    /// # Ok(()) }
970    /// ```
971    pub fn revocation_status<T>(&self, policy: &dyn Policy, t: T)
972        -> RevocationStatus
973        where T: Into<Option<time::SystemTime>>
974    {
975        let t = t.into();
976        self._revocation_status(policy, t, true,
977                                self.binding_signature(policy, t).ok())
978    }
979}
980
981impl ComponentBundle<UserID> {
982    /// Returns a reference to the User ID.
983    ///
984    /// This is just a type-specific alias for
985    /// [`ComponentBundle::component`].
986    ///
987    /// [`ComponentBundle::component`]: ComponentBundle::component()
988    ///
989    /// # Examples
990    ///
991    /// ```
992    /// # use sequoia_openpgp as openpgp;
993    /// # use openpgp::cert::prelude::*;
994    /// #
995    /// # fn main() -> openpgp::Result<()> {
996    /// # let (cert, _) =
997    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
998    /// #     .generate()?;
999    /// // Display some information about the User IDs.
1000    /// for ua in cert.userids() {
1001    ///     eprintln!(" - {:?}", ua.bundle().userid());
1002    /// }
1003    /// # Ok(()) }
1004    /// ```
1005    pub fn userid(&self) -> &UserID {
1006        self.component()
1007    }
1008
1009    /// Returns the User ID's revocation status at time `t`.<a
1010    /// name="userid_revocation_status"></a>
1011    ///
1012    /// <!-- Why we have the above anchor:
1013    ///      https://github.com/rust-lang/rust/issues/71912 -->
1014    ///
1015    /// A User ID is revoked at time `t` if:
1016    ///
1017    ///   - There is a live revocation at time `t` that is newer than
1018    ///     all live self signatures at time `t`.
1019    ///
1020    /// Note: Certs and subkeys have different criteria from User IDs
1021    /// and User Attributes.
1022    ///
1023    /// Note: this only returns whether this User ID is revoked; it
1024    /// does not imply anything about the Cert or other components.
1025    //
1026    /// # Examples
1027    ///
1028    /// ```
1029    /// # use sequoia_openpgp as openpgp;
1030    /// # use openpgp::cert::prelude::*;
1031    /// use openpgp::policy::StandardPolicy;
1032    /// #
1033    /// # fn main() -> openpgp::Result<()> {
1034    /// let p = &StandardPolicy::new();
1035    ///
1036    /// # let (cert, _) =
1037    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1038    /// #     .generate()?;
1039    /// // Display the User IDs' revocation status.
1040    /// for ua in cert.userids() {
1041    ///     eprintln!(" Revocation status of {}: {:?}",
1042    ///               String::from_utf8_lossy(ua.userid().value()),
1043    ///               ua.bundle().revocation_status(p, None));
1044    /// }
1045    /// # Ok(()) }
1046    /// ```
1047    pub fn revocation_status<T>(&self, policy: &dyn Policy, t: T)
1048        -> RevocationStatus
1049        where T: Into<Option<time::SystemTime>>
1050    {
1051        let t = t.into();
1052        self._revocation_status(policy, t, false, self.binding_signature(policy, t).ok())
1053    }
1054}
1055
1056impl ComponentBundle<UserAttribute> {
1057    /// Returns a reference to the User Attribute.
1058    ///
1059    /// This is just a type-specific alias for
1060    /// [`ComponentBundle::component`].
1061    ///
1062    /// [`ComponentBundle::component`]: ComponentBundle::component()
1063    ///
1064    /// # Examples
1065    ///
1066    /// ```
1067    /// # use sequoia_openpgp as openpgp;
1068    /// # use openpgp::cert::prelude::*;
1069    /// #
1070    /// # fn main() -> openpgp::Result<()> {
1071    /// # let (cert, _) =
1072    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1073    /// #     .generate()?;
1074    /// // Display some information about the User Attributes
1075    /// for ua in cert.user_attributes() {
1076    ///     eprintln!(" - {:?}", ua.bundle().user_attribute());
1077    /// }
1078    /// # Ok(()) }
1079    /// ```
1080    pub fn user_attribute(&self) -> &UserAttribute {
1081        self.component()
1082    }
1083
1084    /// Returns the User Attribute's revocation status at time `t`.
1085    ///
1086    /// A User Attribute is revoked at time `t` if:
1087    ///
1088    ///   - There is a live revocation at time `t` that is newer than
1089    ///     all live self signatures at time `t`.
1090    ///
1091    /// Note: Certs and subkeys have different criteria from User IDs
1092    /// and User Attributes.
1093    ///
1094    /// Note: this only returns whether this User Attribute is revoked;
1095    /// it does not imply anything about the Cert or other components.
1096    //
1097    /// # Examples
1098    ///
1099    /// ```
1100    /// # use sequoia_openpgp as openpgp;
1101    /// # use openpgp::cert::prelude::*;
1102    /// use openpgp::policy::StandardPolicy;
1103    /// #
1104    /// # fn main() -> openpgp::Result<()> {
1105    /// let p = &StandardPolicy::new();
1106    ///
1107    /// # let (cert, _) =
1108    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1109    /// #     .generate()?;
1110    /// // Display the User Attributes' revocation status.
1111    /// for (i, ua) in cert.user_attributes().enumerate() {
1112    ///     eprintln!(" Revocation status of User Attribute #{}: {:?}",
1113    ///               i, ua.bundle().revocation_status(p, None));
1114    /// }
1115    /// # Ok(()) }
1116    /// ```
1117    pub fn revocation_status<T>(&self, policy: &dyn Policy, t: T)
1118        -> RevocationStatus
1119        where T: Into<Option<time::SystemTime>>
1120    {
1121        let t = t.into();
1122        self._revocation_status(policy, t, false,
1123                                self.binding_signature(policy, t).ok())
1124    }
1125}
1126
1127impl ComponentBundle<Unknown> {
1128    /// Returns a reference to the unknown component.
1129    ///
1130    /// This is just a type-specific alias for
1131    /// [`ComponentBundle::component`].
1132    ///
1133    /// [`ComponentBundle::component`]: ComponentBundle::component()
1134    ///
1135    /// # Examples
1136    ///
1137    /// ```
1138    /// # use sequoia_openpgp as openpgp;
1139    /// # use openpgp::cert::prelude::*;
1140    /// #
1141    /// # fn main() -> openpgp::Result<()> {
1142    /// # let (cert, _) =
1143    /// #     CertBuilder::general_purpose(Some("alice@example.org"))
1144    /// #     .generate()?;
1145    /// // Display some information about the User Attributes
1146    /// for u in cert.unknowns() {
1147    ///     eprintln!(" - {:?}", u.unknown());
1148    /// }
1149    /// # Ok(()) }
1150    /// ```
1151    pub fn unknown(&self) -> &Unknown {
1152        self.component()
1153    }
1154}
1155
1156/// A collection of `ComponentBundles`.
1157///
1158/// Note: we need this, because we can't `impl Vec<ComponentBundles>`.
1159#[derive(Debug, Clone, PartialEq)]
1160pub(super) struct ComponentBundles<C>
1161    where ComponentBundle<C>: cmp::PartialEq
1162{
1163    bundles: Vec<ComponentBundle<C>>,
1164}
1165
1166impl<C> Default for ComponentBundles<C>
1167where
1168    ComponentBundle<C>: cmp::PartialEq,
1169{
1170        fn default() -> Self {
1171        ComponentBundles {
1172            bundles: vec![],
1173        }
1174    }
1175}
1176
1177impl<C> Deref for ComponentBundles<C>
1178    where ComponentBundle<C>: cmp::PartialEq
1179{
1180    type Target = Vec<ComponentBundle<C>>;
1181
1182    fn deref(&self) -> &Self::Target {
1183        &self.bundles
1184    }
1185}
1186
1187impl<C> DerefMut for ComponentBundles<C>
1188    where ComponentBundle<C>: cmp::PartialEq
1189{
1190    fn deref_mut(&mut self) -> &mut Vec<ComponentBundle<C>> {
1191        &mut self.bundles
1192    }
1193}
1194
1195impl<C> From<ComponentBundles<C>> for Vec<ComponentBundle<C>>
1196    where ComponentBundle<C>: cmp::PartialEq
1197{
1198    fn from(cb: ComponentBundles<C>) -> Vec<ComponentBundle<C>> {
1199        cb.bundles
1200    }
1201}
1202
1203impl<C> From<Vec<ComponentBundle<C>>> for ComponentBundles<C>
1204    where ComponentBundle<C>: cmp::PartialEq
1205{
1206    fn from(bundles: Vec<ComponentBundle<C>>) -> ComponentBundles<C> {
1207        ComponentBundles {
1208            bundles,
1209        }
1210    }
1211}
1212
1213impl<C> IntoIterator for ComponentBundles<C>
1214    where ComponentBundle<C>: cmp::PartialEq
1215{
1216    type Item = ComponentBundle<C>;
1217    type IntoIter = std::vec::IntoIter<Self::Item>;
1218
1219    fn into_iter(self) -> Self::IntoIter {
1220        self.bundles.into_iter()
1221    }
1222}
1223
1224impl<C> ComponentBundles<C>
1225    where ComponentBundle<C>: cmp::PartialEq
1226{
1227    // Sort and dedup the components.
1228    //
1229    // `cmp` is a function to sort the components for deduping.
1230    //
1231    // `merge` is a function that merges the first component into the
1232    // second component.
1233    pub(super) fn sort_and_dedup<F, F2>(&mut self, cmp: F, merge: F2)
1234        where F: Fn(&C, &C) -> Ordering,
1235              F2: Fn(&mut C, &mut C)
1236    {
1237        // We dedup by component (not bundles!).  To do this, we need
1238        // to sort the bundles by their components.
1239
1240        self.bundles.sort_by(
1241            |a, b| cmp(&a.component, &b.component));
1242
1243        self.bundles.dedup_by(|a, b| {
1244            if cmp(&a.component, &b.component) == Ordering::Equal {
1245                // Merge.
1246                merge(&mut a.component, &mut b.component);
1247
1248                // Recall: if a and b are equal, a will be dropped.
1249                // Also, the elements are given in the opposite order
1250                // from their order in the vector.
1251                b.self_signatures.append(&mut a.self_signatures);
1252                b.attestations.append(&mut a.attestations);
1253                b.certifications.append(&mut a.certifications);
1254                b.self_revocations.append(&mut a.self_revocations);
1255                b.other_revocations.append(&mut a.other_revocations);
1256
1257                true
1258            } else {
1259                false
1260            }
1261        });
1262
1263        // And sort the certificates.
1264        for b in self.bundles.iter_mut() {
1265            b.sort_and_dedup();
1266        }
1267    }
1268}
1269
1270/// A vecor of key (primary or subkey, public or private) and any
1271/// associated signatures.
1272pub(super) type KeyBundles<KeyPart, KeyRole>
1273    = ComponentBundles<Key<KeyPart, KeyRole>>;
1274
1275/// A vector of subkeys and any associated signatures.
1276pub(super) type SubkeyBundles<KeyPart>
1277    = KeyBundles<KeyPart, key::SubordinateRole>;
1278
1279/// A vector of key (primary or subkey, public or private) and any
1280/// associated signatures.
1281#[allow(dead_code)]
1282pub(super) type GenericKeyBundles
1283    = ComponentBundles<Key<key::UnspecifiedParts, key::UnspecifiedRole>>;
1284
1285/// A vector of User ID bundles and any associated signatures.
1286pub(super) type UserIDBundles = ComponentBundles<UserID>;
1287
1288/// A vector of User Attribute bundles and any associated signatures.
1289pub(super) type UserAttributeBundles = ComponentBundles<UserAttribute>;
1290
1291/// A vector of unknown components and any associated signatures.
1292///
1293/// Note: all signatures are stored as certifications.
1294pub(super) type UnknownBundles = ComponentBundles<Unknown>;