Revision control

Copy as Markdown

Other Tools

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright by contributors to this project.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
use crate::{client::MlsError, time::MlsTime};
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
#[derive(Clone, Debug, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode, Default)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct Lifetime {
pub not_before: u64,
pub not_after: u64,
}
impl Lifetime {
pub fn new(not_before: u64, not_after: u64) -> Lifetime {
Lifetime {
not_before,
not_after,
}
}
pub fn seconds(s: u64) -> Result<Self, MlsError> {
#[cfg(feature = "std")]
let not_before = MlsTime::now().seconds_since_epoch();
#[cfg(not(feature = "std"))]
// There is no clock on no_std, this is here just so that we can run tests.
let not_before = 3600u64;
let not_after = not_before.checked_add(s).ok_or(MlsError::TimeOverflow)?;
Ok(Lifetime {
// Subtract 1 hour to address time difference between machines
not_before: not_before - 3600,
not_after,
})
}
pub fn days(d: u32) -> Result<Self, MlsError> {
Self::seconds((d * 86400) as u64)
}
pub fn years(y: u8) -> Result<Self, MlsError> {
Self::days(365 * y as u32)
}
pub(crate) fn within_lifetime(&self, time: MlsTime) -> bool {
let since_epoch = time.seconds_since_epoch();
since_epoch >= self.not_before && since_epoch <= self.not_after
}
}
#[cfg(test)]
mod tests {
use core::time::Duration;
use super::*;
use assert_matches::assert_matches;
#[test]
fn test_lifetime_overflow() {
let res = Lifetime::seconds(u64::MAX);
assert_matches!(res, Err(MlsError::TimeOverflow))
}
#[test]
fn test_seconds() {
let seconds = 10;
let lifetime = Lifetime::seconds(seconds).unwrap();
assert_eq!(lifetime.not_after - lifetime.not_before, 3610);
}
#[test]
fn test_days() {
let days = 2;
let lifetime = Lifetime::days(days).unwrap();
assert_eq!(
lifetime.not_after - lifetime.not_before,
86400u64 * days as u64 + 3600
);
}
#[test]
fn test_years() {
let years = 2;
let lifetime = Lifetime::years(years).unwrap();
assert_eq!(
lifetime.not_after - lifetime.not_before,
86400 * 365 * years as u64 + 3600
);
}
#[test]
fn test_bounds() {
let test_lifetime = Lifetime {
not_before: 5,
not_after: 10,
};
assert!(!test_lifetime
.within_lifetime(MlsTime::from_duration_since_epoch(Duration::from_secs(4))));
assert!(!test_lifetime
.within_lifetime(MlsTime::from_duration_since_epoch(Duration::from_secs(11))));
assert!(test_lifetime
.within_lifetime(MlsTime::from_duration_since_epoch(Duration::from_secs(5))));
assert!(test_lifetime
.within_lifetime(MlsTime::from_duration_since_epoch(Duration::from_secs(10))));
assert!(test_lifetime
.within_lifetime(MlsTime::from_duration_since_epoch(Duration::from_secs(6))));
}
}