diff options
author | Neal H. Walfield <neal@pep.foundation> | 2022-03-07 14:53:15 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2022-03-07 19:44:56 +0100 |
commit | e3eb9a71267b910c4a21f29aecc5cd05c2f105e3 (patch) | |
tree | c1cb9aec8bf29af6613b4228256a9d19f6587271 | |
parent | 8379e8823c46336fbc561d3149c8c50a83674935 (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/NEWS | 1 | ||||
-rw-r--r-- | openpgp/src/packet/signature.rs | 104 |
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. |