diff options
Diffstat (limited to 'src/time.rs')
-rw-r--r-- | src/time.rs | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/time.rs b/src/time.rs index d1f2ec5..c0ef8bf 100644 --- a/src/time.rs +++ b/src/time.rs @@ -3,7 +3,7 @@ use core::fmt; use core::time::Duration; use der::asn1::{GeneralizedTime, UtcTime}; -use der::{Choice, DateTime, Decode, Error, Result, Sequence, ValueOrd}; +use der::{Choice, DateTime, Sequence, ValueOrd}; #[cfg(feature = "std")] use std::time::SystemTime; @@ -21,9 +21,13 @@ use std::time::SystemTime; /// /// [RFC 5280 Section 4.1.2.5]: https://tools.ietf.org/html/rfc5280#section-4.1.2.5 /// [RFC 5280 Appendix A]: https://tools.ietf.org/html/rfc5280#page-117 +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Choice, Copy, Clone, Debug, Eq, PartialEq, ValueOrd)] pub enum Time { - /// Legacy UTC time (has 2-digit year, valid only through 2050). + /// Legacy UTC time (has 2-digit year, valid from 1970 to 2049). + /// + /// Note: RFC 5280 specifies 1950-2049, however due to common operations working on + /// `UNIX_EPOCH` this implementation's lower bound is 1970. #[asn1(type = "UTCTime")] UtcTime(UtcTime), @@ -33,6 +37,10 @@ pub enum Time { } impl Time { + /// Time used for Certificate who do not expire. + pub const INFINITY: Time = + Time::GeneralTime(GeneralizedTime::from_date_time(DateTime::INFINITY)); + /// Get duration since `UNIX_EPOCH`. pub fn to_unix_duration(self) -> Duration { match self { @@ -51,17 +59,30 @@ impl Time { /// Convert to [`SystemTime`]. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn to_system_time(&self) -> SystemTime { match self { Time::UtcTime(t) => t.to_system_time(), Time::GeneralTime(t) => t.to_system_time(), } } + + /// Convert time to UTCTime representation + /// As per RFC 5280: 4.1.2.5, date through 2049 should be expressed as UTC Time. + #[cfg(feature = "builder")] + pub(crate) fn rfc5280_adjust_utc_time(&mut self) -> der::Result<()> { + if let Time::GeneralTime(t) = self { + let date = t.to_date_time(); + if date.year() <= UtcTime::MAX_YEAR { + *self = Time::UtcTime(UtcTime::from_date_time(date)?); + } + } + + Ok(()) + } } impl fmt::Display for Time { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.to_date_time()) } } @@ -79,7 +100,6 @@ impl From<GeneralizedTime> for Time { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl From<Time> for SystemTime { fn from(time: Time) -> SystemTime { time.to_system_time() @@ -87,7 +107,6 @@ impl From<Time> for SystemTime { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl From<&Time> for SystemTime { fn from(time: &Time) -> SystemTime { time.to_system_time() @@ -95,11 +114,10 @@ impl From<&Time> for SystemTime { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl TryFrom<SystemTime> for Time { - type Error = Error; + type Error = der::Error; - fn try_from(time: SystemTime) -> Result<Time> { + fn try_from(time: SystemTime) -> der::Result<Time> { Ok(GeneralizedTime::try_from(time)?.into()) } } @@ -113,6 +131,7 @@ impl TryFrom<SystemTime> for Time { /// } /// ``` /// [RFC 5280 Section 4.1.2.5]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5 +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] pub struct Validity { /// notBefore value @@ -125,8 +144,7 @@ pub struct Validity { impl Validity { /// Creates a `Validity` which starts now and lasts for `duration`. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - pub fn from_now(duration: Duration) -> Result<Self> { + pub fn from_now(duration: Duration) -> der::Result<Self> { let now = SystemTime::now(); let then = now + duration; @@ -136,11 +154,3 @@ impl Validity { }) } } - -impl<'a> TryFrom<&'a [u8]> for Validity { - type Error = Error; - - fn try_from(bytes: &'a [u8]) -> Result<Self> { - Self::from_der(bytes) - } -} |