summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-02-19 14:21:59 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-02-19 14:21:59 +0100
commitfd5ec44b717b20e5937f018b924325bac3035f2a (patch)
tree425a39e5d9753e8db4453496ba4077be6efa6e65
parentd0cba99a6c34443456816366a294f4f335499b4d (diff)
openpgp: New type CertAmalgamation that fixes policy and time.
- Fixes #426.
-rw-r--r--openpgp/src/cert/mod.rs128
1 files changed, 127 insertions, 1 deletions
diff --git a/openpgp/src/cert/mod.rs b/openpgp/src/cert/mod.rs
index 2efafef9..86f141a1 100644
--- a/openpgp/src/cert/mod.rs
+++ b/openpgp/src/cert/mod.rs
@@ -58,6 +58,7 @@ use components::{
mod component_iter;
use component_iter::{
ComponentIter,
+ ValidComponentIter,
};
mod keyiter;
mod key_amalgamation;
@@ -66,11 +67,15 @@ mod revoke;
pub use self::builder::{CertBuilder, CipherSuite};
-use keyiter::KeyIter;
+use keyiter::{
+ KeyIter,
+ ValidKeyIter,
+};
use key_amalgamation::{
KeyAmalgamation,
PrimaryKeyAmalgamation,
ValidKeyAmalgamation,
+ ValidPrimaryKeyAmalgamation,
};
pub use parser::{
@@ -1402,6 +1407,127 @@ impl Cert {
sk.key().has_secret()
})
}
+
+ /// Fixes a time and policy for use with this certificate.
+ ///
+ /// If `time` is `None`, the current time is used.
+ pub fn with_policy<'a, T>(&'a self, policy: &'a dyn Policy, time: T)
+ -> CertAmalgamation<'a>
+ where T: Into<Option<time::SystemTime>>,
+ {
+ CertAmalgamation {
+ cert: self,
+ policy,
+ time: time.into().unwrap_or_else(time::SystemTime::now),
+ }
+ }
+}
+
+/// A certificate under a given policy at a given time.
+pub struct CertAmalgamation<'a> {
+ cert: &'a Cert,
+ policy: &'a dyn Policy,
+ // The reference time.
+ time: time::SystemTime,
+}
+
+impl<'a> std::ops::Deref for CertAmalgamation<'a> {
+ type Target = Cert;
+
+ fn deref(&self) -> &Self::Target {
+ self.cert
+ }
+}
+
+impl<'a> CertAmalgamation<'a> {
+ /// Returns the amalgamation's reference time.
+ ///
+ /// For queries that are with respect to a point in time, this
+ /// determines that point in time.
+ pub fn time(&self) -> time::SystemTime {
+ self.time
+ }
+
+ /// Returns the amalgamation's policy.
+ pub fn policy(&self) -> &'a dyn Policy {
+ self.policy
+ }
+
+ /// Changes the amalgamation's policy.
+ ///
+ /// If `time` is `None`, the current time is used.
+ pub fn with_policy<T>(self, policy: &'a dyn Policy, time: T) -> Self
+ where T: Into<Option<time::SystemTime>>,
+ {
+ CertAmalgamation {
+ cert: self.cert,
+ policy,
+ time: time.into().unwrap_or_else(time::SystemTime::now),
+ }
+ }
+
+ /// Returns the Cert's revocation status.
+ ///
+ /// A Cert is revoked if:
+ ///
+ /// - There is a live revocation that is newer than all live
+ /// self signatures, or
+ ///
+ /// - There is a hard revocation (even if it is not live at time
+ /// `t`, and even if there is a newer self-signature).
+ ///
+ /// Note: Certs and subkeys have different criteria from User IDs
+ /// and User Attributes.
+ ///
+ /// Note: this only returns whether this Cert is revoked; it does
+ /// not imply anything about the Cert or other components.
+ pub fn revoked(&self) -> RevocationStatus {
+ self.cert.revoked(self.policy, self.time)
+ }
+
+ /// Returns whether or not the Cert is alive.
+ pub fn alive(&self) -> Result<()> {
+ self.cert.alive(self.policy, self.time)
+ }
+
+ /// Returns the amalgamated primary key.
+ pub fn primary_key(&self)
+ -> Result<ValidPrimaryKeyAmalgamation<key::PublicParts>>
+ {
+ self.cert.primary_key().with_policy(self.policy, self.time)
+ }
+
+ /// Returns an iterator over the certificate's keys.
+ ///
+ /// That is, this returns an iterator over the primary key and any
+ /// subkeys.
+ pub fn keys(&self) -> ValidKeyIter<key::PublicParts> {
+ self.cert.keys().with_policy(self.policy, self.time)
+ }
+
+ /// Returns the amalgamated primary userid, if any.
+ pub fn primary_userid(&self)
+ -> Option<ValidComponentAmalgamation<'a, UserID>>
+ {
+ self.cert.primary_userid(self.policy, self.time)
+ }
+
+ /// Returns an iterator over the Cert's userids.
+ pub fn userids(&self) -> ValidComponentIter<UserID> {
+ self.cert.userids().with_policy(self.policy, self.time)
+ }
+
+ /// Returns the amalgamated primary user attribute, if any.
+ pub fn primary_user_attribute(&self)
+ -> Option<ValidComponentAmalgamation<'a, UserAttribute>>
+ {
+ self.cert.primary_user_attribute(self.policy, self.time)
+ }
+
+ /// Returns an iterator over the Cert's `UserAttributeBundle`s.
+ pub fn user_attributes(&self) -> ValidComponentIter<UserAttribute> {
+ self.cert.user_attributes().with_policy(self.policy, self.time)
+ }
}
#[cfg(test)]