//! Component amalgamations.
//!
//! Whereas a `ComponentBundle` groups a `Component` with its self
//! signatures, its third-party signatures, and its revocation
//! certificates, an `Amalgamation` groups a `ComponentBundle` with
//! all of the necessary context needed to correctly implement
//! relevant functionality related to the component. Specifically, a
//! `Amalgamation` includes a reference to the `ComponentBundle`, and
//! a reference to the containing certificate.
//!
//! A notable differences between `ComponentBundle`s and
//! `Amalgamation`s is that a `ComponentBundle`, owns its data, but an
//! `Amalgamation` only references the contained data.
use std::borrow::Borrow;
use std::time;
use std::time::SystemTime;
use std::clone::Clone;
use crate::{
cert::prelude::*,
Error,
packet::Signature,
Result,
policy::Policy,
types::{
AEADAlgorithm,
CompressionAlgorithm,
Features,
HashAlgorithm,
KeyFlags,
KeyServerPreferences,
RevocationKey,
RevocationStatus,
SymmetricAlgorithm,
},
};
mod iter;
pub use iter::{
ComponentAmalgamationIter,
ValidComponentAmalgamationIter,
};
mod keyiter;
pub use keyiter::{
KeyAmalgamationIter,
ValidKeyAmalgamationIter,
};
mod key;
pub use key::{
ErasedKeyAmalgamation,
KeyAmalgamation,
PrimaryKey,
PrimaryKeyAmalgamation,
SubordinateKeyAmalgamation,
ValidErasedKeyAmalgamation,
ValidKeyAmalgamation,
ValidPrimaryKeyAmalgamation,
ValidSubordinateKeyAmalgamation,
};
/// Applies a policy to an amalgamation.
///
/// Note: This trait is split off from the `Amalgamation` trait, to
/// reduce code duplication: it is often possible to provide blanket
/// implementations of `Amalgamation`, but the `ValidateAmalgamation`
/// trait can only be implemented on more concrete types.
pub trait ValidateAmalgamation<'a, C: 'a> {
/// The type returned by `with_policy`.
type V;
/// Changes the amalgamation's policy.
///
/// If `time` is `None`, the current time is used.
fn with_policy<T>(self, policy: &'a dyn Policy, time: T) -> Result<Self::V>
where T: Into<Option<time::SystemTime>>,
Self: Sized;
}
/// Applies a policy to an amalgamation.
///
/// This is an internal variant of `ValidateAmalgamation`, which
/// allows validating a component for an otherwise invalid
/// certificate. See `ValidComponentAmalgamation::primary` for an
/// explanation.
trait ValidateAmalgamationRelaxed<'a, C: 'a> {
/// The type returned by `with_policy`.
type V;
/// Changes the amalgamation's policy.
///
/// If `time` is `None`, the current time is used.
///
/// If `valid_cert` is `false`, then this does not also check
/// whether the certificate is valid; it only checks whether the
/// component is valid. Normally, this should be `true`. This
/// option is only expose to allow breaking an infinite recursion:
///
/// - To check if a certificate is valid, we check if the
/// primary key is valid.
///
/// - To check if the primary key is valid, we need the primary
/// key's self signature
///
/// - To find the primary key's self signature, we need to find
/// the primary user id
///
/// - To find the primary user id, we need to check if the user
/// id is valid.
///
/// - To check if the user id is valid, we need to check that
/// the corresponding certificate is valid.
fn with_policy_relaxed<T>(self, policy: &'a dyn Policy, time: T,
valid_cert: bool) -> Result<Self::V>
where T: Into<Option<time::SystemTime>>,
Self: Sized;
}
/// An amalgamation with a policy and a reference time.
///
/// In a certain sense, a `ValidAmalgamation` provides a view of an
/// `Amalgamation` as it was a