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 init(not_before: u64, not_after: u64) -> Self {
78 Self {
79 not_before,
80 not_after,
81 }
82 }
83
84 pub fn is_valid(&self) -> bool {
86 match SystemTime::now()
87 .duration_since(UNIX_EPOCH)
88 .map(|duration| duration.as_secs())
89 {
90 Ok(elapsed) => self.not_before < elapsed && elapsed < self.not_after,
91 Err(_) => {
92 log::error!("SystemTime before UNIX EPOCH.");
93 false
94 }
95 }
96 }
97
98 pub fn has_acceptable_range(&self) -> bool {
102 self.not_after.saturating_sub(self.not_before) <= MAX_LEAF_NODE_LIFETIME_RANGE_SECONDS
103 }
104
105 pub fn not_before(&self) -> u64 {
107 self.not_before
108 }
109
110 pub fn not_after(&self) -> u64 {
112 self.not_after
113 }
114}
115
116impl Default for Lifetime {
117 fn default() -> Self {
118 Lifetime::new(DEFAULT_KEY_PACKAGE_LIFETIME_SECONDS)
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use tls_codec::{Deserialize, Serialize};
125
126 use super::Lifetime;
127
128 #[test]
129 fn lifetime() {
130 let ext = Lifetime::default();
132 assert!(ext.is_valid());
133
134 let ext = Lifetime::new(0);
136 std::thread::sleep(std::time::Duration::from_secs(1));
137 assert!(!ext.is_valid());
138
139 let serialized = ext
141 .tls_serialize_detached()
142 .expect("error encoding life time extension");
143 let ext_deserialized = Lifetime::tls_deserialize(&mut serialized.as_slice())
144 .expect("Error deserializing lifetime");
145 assert!(!ext_deserialized.is_valid());
146 }
147}