summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2022-03-07 14:53:15 +0100
committerNeal H. Walfield <neal@pep.foundation>2022-03-07 19:44:56 +0100
commite3eb9a71267b910c4a21f29aecc5cd05c2f105e3 (patch)
treec1cb9aec8bf29af6613b4228256a9d19f6587271
parent8379e8823c46336fbc561d3149c8c50a83674935 (diff)
openpgp: Add SignatureBuilder::effective_signature_creation_time.
- Add `SignatureBuilder::effective_signature_creation_time` to return the signature creation time that would be used were a signature generated now.
-rw-r--r--openpgp/NEWS1
-rw-r--r--openpgp/src/packet/signature.rs104
2 files changed, 86 insertions, 19 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index facde2ed..0112d874 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -5,6 +5,7 @@
* Changes in 1.9.0
** New functionality
- SignatureBuilder::set_reference_time
+ - SignatureBuilder::effective_signature_creation_time
* Changes in 1.8.0
** New functionality
- crypto::Signer::acceptable_hashes
diff --git a/openpgp/src/packet/signature.rs b/openpgp/src/packet/signature.rs
index fad0354d..614c14b7 100644
--- a/openpgp/src/packet/signature.rs
+++ b/openpgp/src/packet/signature.rs
@@ -1559,6 +1559,31 @@ impl SignatureBuilder {
/// The reference time is used when no time is specified. The
/// reference time is the current time by default and is evaluated
/// on demand.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::time::{Duration, SystemTime};
+ /// use sequoia_openpgp as openpgp;
+ /// use openpgp::types::SignatureType;
+ /// use openpgp::packet::prelude::*;
+ ///
+ /// # fn main() -> openpgp::Result<()> {
+ /// #
+ /// // If we don't set a reference time, then the current time is used
+ /// // when the signature is created.
+ /// let sig = SignatureBuilder::new(SignatureType::PositiveCertification);
+ /// let ct = sig.effective_signature_creation_time()?.expect("creation time");
+ /// assert!(SystemTime::now().duration_since(ct).expect("ct is in the past")
+ /// < Duration::new(1, 0));
+ ///
+ /// // If we set a reference time and don't set a creation time,
+ /// // then that time is used for the creation time.
+ /// let t = std::time::UNIX_EPOCH + Duration::new(1646660000, 0);
+ /// let sig = sig.set_reference_time(t);
+ /// assert_eq!(sig.effective_signature_creation_time()?, Some(t));
+ /// # Ok(()) }
+ /// ```
pub fn set_reference_time<T>(mut self, reference_time: T) -> Self
where
T: Into<Option<SystemTime>>,
@@ -1567,6 +1592,63 @@ impl SignatureBuilder {
self
}
+ /// Returns the signature creation time that would be used if a
+ /// signature were created now.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::time::{Duration, SystemTime};
+ /// use sequoia_openpgp as openpgp;
+ /// use openpgp::types::SignatureType;
+ /// use openpgp::packet::prelude::*;
+ ///
+ /// # fn main() -> openpgp::Result<()> {
+ /// #
+ /// // If we don't set a creation time, then the current time is used.
+ /// let sig = SignatureBuilder::new(SignatureType::PositiveCertification);
+ /// let ct = sig.effective_signature_creation_time()?.expect("creation time");
+ /// assert!(SystemTime::now().duration_since(ct).expect("ct is in the past")
+ /// < Duration::new(1, 0));
+ ///
+ /// // If we set a signature creation time, then we should get it back.
+ /// let t = SystemTime::now() - Duration::new(24 * 60 * 60, 0);
+ /// let sig = sig.set_signature_creation_time(t)?;
+ /// assert!(t.duration_since(
+ /// sig.effective_signature_creation_time()?.unwrap()).unwrap()
+ /// < Duration::new(1, 0));
+ /// # Ok(()) }
+ /// ```
+ pub fn effective_signature_creation_time(&self)
+ -> Result<Option<SystemTime>>
+ {
+ use std::time;
+
+ let now = || self.reference_time.unwrap_or_else(crate::now);
+
+ if ! self.overrode_creation_time {
+ // See if we want to backdate the signature.
+ if let Some(orig) = self.original_creation_time {
+ let now = now();
+ let t =
+ (orig + time::Duration::new(1, 0)).max(
+ now - time::Duration::new(SIG_BACKDATE_BY, 0));
+
+ if t > now {
+ return Err(Error::InvalidOperation(
+ "Cannot create valid signature newer than template"
+ .into()).into());
+ }
+
+ Ok(Some(t))
+ } else {
+ Ok(Some(now()))
+ }
+ } else {
+ Ok(self.signature_creation_time())
+ }
+ }
+
/// Adjusts signature prior to signing.
///
/// This function is called implicitly when a signature is created
@@ -1612,29 +1694,13 @@ impl SignatureBuilder {
/// # Ok(()) }
/// ```
pub fn pre_sign(mut self, signer: &dyn Signer) -> Result<Self> {
- use std::time;
self.pk_algo = signer.public().pk_algo();
// Set the creation time.
if ! self.overrode_creation_time {
- self =
- // See if we want to backdate the signature.
- if let Some(oct) = self.original_creation_time {
- let t =
- (oct + time::Duration::new(1, 0)).max(
- crate::now() -
- time::Duration::new(SIG_BACKDATE_BY, 0));
-
- if t > crate::now() {
- return Err(Error::InvalidOperation(
- "Cannot create valid signature newer than template"
- .into()).into());
- }
-
- self.set_signature_creation_time(t)?
- } else {
- self.set_signature_creation_time(crate::now())?
- };
+ if let Some(t) = self.effective_signature_creation_time()? {
+ self = self.set_signature_creation_time(t)?;
+ }
}
// Make sure we have an issuer packet.