diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-07-04 15:52:21 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-07-04 15:52:21 +0200 |
commit | dff6bc3e86c4cacfe9153d46e7be2b6484e086b9 (patch) | |
tree | 06a5a5be1b4373557dc9af27b30f29a8f7bba200 | |
parent | 415e46bdcbb95d5ac1ba9c93177c610fa64ba35f (diff) |
openpgp: Add and use a module for time and duration conversion.
-rw-r--r-- | openpgp/src/conversions.rs | 54 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 2 | ||||
-rw-r--r-- | openpgp/src/subpacket.rs | 32 |
3 files changed, 63 insertions, 25 deletions
diff --git a/openpgp/src/conversions.rs b/openpgp/src/conversions.rs new file mode 100644 index 00000000..b2dfc549 --- /dev/null +++ b/openpgp/src/conversions.rs @@ -0,0 +1,54 @@ +//! Conversions for primitive OpenPGP types. + +use time; + +use Error; +use Result; + +/// Conversions for OpenPGP time stamps. +pub trait Time { + /// Converts an OpenPGP time stamp to broken-down time. + fn from_pgp(u32) -> Self; + /// Converts broken-down time to an OpenPGP time stamp. + fn to_pgp(&self) -> Result<u32>; +} + +impl Time for time::Tm { + fn from_pgp(timestamp: u32) -> Self { + time::at_utc(time::Timespec::new(timestamp as i64, 0)) + } + + fn to_pgp(&self) -> Result<u32> { + let epoch = self.to_timespec().sec; + if epoch > ::std::u32::MAX as i64 { + return Err(Error::InvalidArgument( + format!("Time exceeds u32 epoch: {:?}", self)) + .into()); + } + Ok(epoch as u32) + } +} + +/// Conversions for OpenPGP durations. +pub trait Duration { + /// Converts an OpenPGP duration to ISO 8601 time duration. + fn from_pgp(u32) -> Self; + /// Converts ISO 8601 time duration to an OpenPGP duration. + fn to_pgp(&self) -> Result<u32>; +} + +impl Duration for time::Duration { + fn from_pgp(duration: u32) -> Self { + time::Duration::seconds(duration as i64) + } + + fn to_pgp(&self) -> Result<u32> { + let secs = self.num_seconds(); + if secs > ::std::u32::MAX as i64 { + return Err(Error::InvalidArgument( + format!("Duration exceeds u32: {:?}", self)) + .into()); + } + Ok(secs as u32) + } +} diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index b24e88ee..72fa4911 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -67,6 +67,8 @@ pub mod autocrypt; pub mod ctb; use ctb::{CTB, CTBOld, CTBNew}; +pub mod conversions; + pub mod packet; use packet::{BodyLength, Header, Container}; pub mod subpacket; diff --git a/openpgp/src/subpacket.rs b/openpgp/src/subpacket.rs index 8e589e2d..84d34ad9 100644 --- a/openpgp/src/subpacket.rs +++ b/openpgp/src/subpacket.rs @@ -77,6 +77,10 @@ use constants::{ HashAlgorithm, PublicKeyAlgorithm, }; +use conversions::{ + Time, + Duration, +}; #[cfg(test)] use std::path::PathBuf; @@ -1233,28 +1237,6 @@ const KEY_FLAG_AUTHENTICATE: u8 = 0x20; /// than one person. const KEY_FLAG_GROUP_KEY: u8 = 0x80; -/// Converts structured time to OpenPGP time. -fn tm2pgp(t: time::Tm) -> Result<u32> { - let epoch = t.to_timespec().sec; - if epoch > ::std::u32::MAX as i64 { - return Err(Error::InvalidArgument( - format!("Time exceeds u32 epoch: {:?}", t)) - .into()); - } - Ok(epoch as u32) -} - -/// Converts structured duration to OpenPGP duration. -fn duration2pgp(d: time::Duration) -> Result<u32> { - let secs = d.num_seconds(); - if secs > ::std::u32::MAX as i64 { - return Err(Error::InvalidArgument( - format!("Duration exceeds u32 epoch: {:?}", d)) - .into()); - } - Ok(secs as u32) -} - impl Signature { /// Returns the *last* instance of the specified subpacket. fn subpacket<'a>(&'a self, tag: SubpacketTag) -> Option<Subpacket<'a>> { @@ -1317,7 +1299,7 @@ impl Signature { pub fn set_signature_creation_time(&mut self, creation_time: time::Tm) -> Result<()> { self.hashed_area.replace(Subpacket::new( - SubpacketValue::SignatureCreationTime(tm2pgp(creation_time)?), + SubpacketValue::SignatureCreationTime(creation_time.to_pgp()?), true)?) } @@ -1352,7 +1334,7 @@ impl Signature { -> Result<()> { if let Some(e) = expiration { self.hashed_area.replace(Subpacket::new( - SubpacketValue::SignatureExpirationTime(duration2pgp(e)?), + SubpacketValue::SignatureExpirationTime(e.to_pgp()?), true)?) } else { self.hashed_area.remove_all(SubpacketTag::SignatureExpirationTime); @@ -1577,7 +1559,7 @@ impl Signature { -> Result<()> { if let Some(e) = expiration { self.hashed_area.replace(Subpacket::new( - SubpacketValue::KeyExpirationTime(duration2pgp(e)?), + SubpacketValue::KeyExpirationTime(e.to_pgp()?), true)?) } else { self.hashed_area.remove_all(SubpacketTag::KeyExpirationTime); |