openmls/key_packages/
lifetime.rs1#[cfg(target_arch = "wasm32")]
2use fluvio_wasm_timer::{SystemTime, UNIX_EPOCH};
3#[cfg(not(target_arch = "wasm32"))]
4use std::time::{SystemTime, UNIX_EPOCH};
5
6use serde::{Deserialize, Serialize};
7use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};
8
9const DEFAULT_KEY_PACKAGE_LIFETIME_SECONDS: u64 = 60 * 60 * 24 * 28 * 3;
12
13const DEFAULT_KEY_PACKAGE_LIFETIME_MARGIN_SECONDS: u64 = 60 * 60;
17
18const MAX_LEAF_NODE_LIFETIME_RANGE_SECONDS: u64 =
21 DEFAULT_KEY_PACKAGE_LIFETIME_MARGIN_SECONDS + DEFAULT_KEY_PACKAGE_LIFETIME_SECONDS;
22
23#[derive(
41 PartialEq,
42 Eq,
43 Copy,
44 Clone,
45 Debug,
46 TlsSerialize,
47 TlsSize,
48 TlsDeserialize,
49 TlsDeserializeBytes,
50 Serialize,
51 Deserialize,
52)]
53pub struct Lifetime {
54 not_before: u64,
55 not_after: u64,
56}
57
58impl Lifetime {
59 pub fn new(t: u64) -> Self {
63 let lifetime_margin: u64 = DEFAULT_KEY_PACKAGE_LIFETIME_MARGIN_SECONDS;
64 let now = SystemTime::now()
65 .duration_since(UNIX_EPOCH)
66 .expect("SystemTime before UNIX EPOCH!")
67 .as_secs();
68 let not_before = now - lifetime_margin;
69 let not_after = now + t;
70 Self {
71 not_before,
72 not_after,
73 }
74 }
75
76 pub fn is_valid(&self) -> bool {
78 match SystemTime::now()
79 .duration_since(UNIX_EPOCH)
80 .map(|duration| duration.as_secs())
81 {
82 Ok(elapsed) => self.not_before < elapsed && elapsed < self.not_after,
83 Err(_) => {
84 log::error!("SystemTime before UNIX EPOCH.");
85 false
86 }
87 }
88 }
89
90 pub fn has_acceptable_range(&self) -> bool {
94 self.not_after.saturating_sub(self.not_before) <= MAX_LEAF_NODE_LIFETIME_RANGE_SECONDS
95 }
96
97 pub fn not_before(&self) -> u64 {
99 self.not_before
100 }
101
102 pub fn not_after(&self) -> u64 {
104 self.not_after
105 }
106}
107
108impl Default for Lifetime {
109 fn default() -> Self {
110 Lifetime::new(DEFAULT_KEY_PACKAGE_LIFETIME_SECONDS)
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use tls_codec::{Deserialize, Serialize};
117
118 use super::Lifetime;
119
120 #[test]
121 fn lifetime() {
122 let ext = Lifetime::default();
124 assert!(ext.is_valid());
125
126 let ext = Lifetime::new(0);
128 std::thread::sleep(std::time::Duration::from_secs(1));
129 assert!(!ext.is_valid());
130
131 let serialized = ext
133 .tls_serialize_detached()
134 .expect("error encoding life time extension");
135 let ext_deserialized = Lifetime::tls_deserialize(&mut serialized.as_slice())
136 .expect("Error deserializing lifetime");
137 assert!(!ext_deserialized.is_valid());
138 }
139}