1use crate::{
2 SensitiveBytes,
3 credential::Credential,
4 crypto::SignaturePublicKey,
5 defs::{CredentialType, ExtensionType, ProposalType},
6};
7
8pub mod commits;
9pub mod extensions;
10pub mod group_info;
11pub mod proposals;
12pub mod welcome;
13
14pub type HashReference = SensitiveBytes;
15pub type ProposalRef = HashReference;
16pub type KeyPackageRef = HashReference;
17
18pub type GroupId = Vec<u8>;
19pub type GroupIdRef<'a> = &'a [u8];
20
21#[derive(
22 Debug,
23 Clone,
24 Copy,
25 PartialEq,
26 Eq,
27 tls_codec::TlsSerialize,
28 tls_codec::TlsDeserialize,
29 tls_codec::TlsSize,
30)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct KeyPackageLifetime {
33 pub not_before: u64,
34 pub not_after: u64,
35}
36
37impl KeyPackageLifetime {
38 pub const LIFETIME_WIGGLE_ROOM: u64 = 50_400;
40 #[cfg(not(feature = "test-vectors"))]
41 pub const MAX_LEAF_NODE_ACCEPTABLE_RANGE: u64 = 8_035_200;
43 #[cfg(feature = "test-vectors")]
44 pub const MAX_LEAF_NODE_ACCEPTABLE_RANGE: u64 = u64::MAX - Self::LIFETIME_WIGGLE_ROOM;
45
46 pub fn validate_range(&self) -> bool {
50 if self.not_after < self.not_before {
51 return false;
52 }
53
54 let kp_range = self.not_after.saturating_sub(self.not_before);
55 let acceptable_range =
56 Self::MAX_LEAF_NODE_ACCEPTABLE_RANGE.saturating_add(Self::LIFETIME_WIGGLE_ROOM);
57 kp_range <= acceptable_range
58 }
59
60 pub fn validate_expiration(&self) -> bool {
62 let now = now();
63 self.not_before < now && now < self.not_after
64 }
65}
66
67#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
68fn now() -> u64 {
69 let val = js_sys::Date::now();
70 std::time::Duration::from_millis(val as u64).as_secs()
71}
72
73#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
74fn now() -> u64 {
75 let now = std::time::SystemTime::now();
76 now.duration_since(std::time::SystemTime::UNIX_EPOCH)
77 .expect("System clock is before UNIX_EPOCH")
78 .as_secs()
79}
80
81impl Default for KeyPackageLifetime {
82 fn default() -> Self {
83 let now = now();
84 let not_before = now.saturating_sub(Self::LIFETIME_WIGGLE_ROOM);
85 let not_after = now.saturating_add(Self::MAX_LEAF_NODE_ACCEPTABLE_RANGE);
86 Self {
87 not_before,
88 not_after,
89 }
90 }
91}
92
93#[derive(
94 Debug,
95 Clone,
96 PartialEq,
97 Eq,
98 tls_codec::TlsSerialize,
99 tls_codec::TlsDeserialize,
100 tls_codec::TlsSize,
101)]
102#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
103pub struct ExternalSender {
104 pub signature_key: SignaturePublicKey,
105 pub credential: Credential,
106}
107
108#[derive(
109 Debug,
110 Clone,
111 Default,
112 PartialEq,
113 Eq,
114 tls_codec::TlsSerialize,
115 tls_codec::TlsDeserialize,
116 tls_codec::TlsSize,
117)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119pub struct RequiredCapabilities {
120 pub extension_types: Vec<ExtensionType>,
121 pub proposal_types: Vec<ProposalType>,
122 pub credential_types: Vec<CredentialType>,
123}