diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
commit | a0aa2307322cd47bbf416810ac0292925e03be87 (patch) | |
tree | 37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/asn1-rs/src/datetime.rs | |
parent | Initial commit. (diff) | |
download | suricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip |
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/asn1-rs/src/datetime.rs')
-rw-r--r-- | rust/vendor/asn1-rs/src/datetime.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/rust/vendor/asn1-rs/src/datetime.rs b/rust/vendor/asn1-rs/src/datetime.rs new file mode 100644 index 0000000..613b44b --- /dev/null +++ b/rust/vendor/asn1-rs/src/datetime.rs @@ -0,0 +1,108 @@ +use crate::{Result, Tag}; +use alloc::format; +use alloc::string::ToString; +use core::fmt; +#[cfg(feature = "datetime")] +use time::OffsetDateTime; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub enum ASN1TimeZone { + /// No timezone provided + Undefined, + /// Coordinated universal time + Z, + /// Local zone, with offset to coordinated universal time + /// + /// `(offset_hour, offset_minute)` + Offset(i8, i8), +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct ASN1DateTime { + pub year: u32, + pub month: u8, + pub day: u8, + pub hour: u8, + pub minute: u8, + pub second: u8, + pub millisecond: Option<u16>, + pub tz: ASN1TimeZone, +} + +impl ASN1DateTime { + #[allow(clippy::too_many_arguments)] + pub const fn new( + year: u32, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + millisecond: Option<u16>, + tz: ASN1TimeZone, + ) -> Self { + ASN1DateTime { + year, + month, + day, + hour, + minute, + second, + millisecond, + tz, + } + } + + #[cfg(feature = "datetime")] + fn to_time_datetime( + &self, + ) -> core::result::Result<OffsetDateTime, time::error::ComponentRange> { + use std::convert::TryFrom; + use time::{Date, Month, PrimitiveDateTime, Time, UtcOffset}; + + let month = Month::try_from(self.month)?; + let date = Date::from_calendar_date(self.year as i32, month, self.day)?; + let time = Time::from_hms_milli( + self.hour, + self.minute, + self.second, + self.millisecond.unwrap_or(0), + )?; + let primitive_date = PrimitiveDateTime::new(date, time); + let offset = match self.tz { + ASN1TimeZone::Offset(h, m) => UtcOffset::from_hms(h, m, 0)?, + ASN1TimeZone::Undefined | ASN1TimeZone::Z => UtcOffset::UTC, + }; + Ok(primitive_date.assume_offset(offset)) + } + + #[cfg(feature = "datetime")] + pub fn to_datetime(&self) -> Result<OffsetDateTime> { + use crate::Error; + + self.to_time_datetime().map_err(|_| Error::InvalidDateTime) + } +} + +impl fmt::Display for ASN1DateTime { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let fractional = match self.millisecond { + None => "".to_string(), + Some(v) => format!(".{}", v), + }; + write!( + f, + "{:04}{:02}{:02}{:02}{:02}{:02}{}Z", + self.year, self.month, self.day, self.hour, self.minute, self.second, fractional, + ) + } +} + +/// Decode 2-digit decimal value +pub(crate) fn decode_decimal(tag: Tag, hi: u8, lo: u8) -> Result<u8> { + if (b'0'..=b'9').contains(&hi) && (b'0'..=b'9').contains(&lo) { + Ok((hi - b'0') * 10 + (lo - b'0')) + } else { + Err(tag.invalid_value("expected digit")) + } +} |