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 Hash,
28 tls_codec::TlsSerialize,
29 tls_codec::TlsDeserialize,
30 tls_codec::TlsSize,
31)]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33pub struct KeyPackageLifetime {
34 pub not_before: u64,
35 pub not_after: u64,
36}
37
38impl KeyPackageLifetime {
39 pub const LIFETIME_WIGGLE_ROOM: u64 = 50_400;
41 #[cfg(not(feature = "test-vectors"))]
42 pub const MAX_LEAF_NODE_ACCEPTABLE_RANGE: u64 = 8_035_200;
44 #[cfg(feature = "test-vectors")]
45 pub const MAX_LEAF_NODE_ACCEPTABLE_RANGE: u64 = u64::MAX - Self::LIFETIME_WIGGLE_ROOM;
46
47 pub fn validate_range(&self) -> bool {
51 if self.not_after < self.not_before {
52 return false;
53 }
54
55 let kp_range = self.not_after.saturating_sub(self.not_before);
56 let acceptable_range =
57 Self::MAX_LEAF_NODE_ACCEPTABLE_RANGE.saturating_add(Self::LIFETIME_WIGGLE_ROOM);
58 kp_range <= acceptable_range
59 }
60
61 pub fn validate_expiration(&self) -> bool {
63 let now = now();
64 self.not_before < now && now < self.not_after
65 }
66}
67
68#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
69fn now() -> u64 {
70 let val = js_sys::Date::now();
71 std::time::Duration::from_millis(val as u64).as_secs()
72}
73
74#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
75fn now() -> u64 {
76 let now = std::time::SystemTime::now();
77 now.duration_since(std::time::SystemTime::UNIX_EPOCH)
78 .expect("System clock is before UNIX_EPOCH")
79 .as_secs()
80}
81
82impl Default for KeyPackageLifetime {
83 fn default() -> Self {
84 let now = now();
85 let not_before = now.saturating_sub(Self::LIFETIME_WIGGLE_ROOM);
86 let not_after = now.saturating_add(Self::MAX_LEAF_NODE_ACCEPTABLE_RANGE);
87 Self {
88 not_before,
89 not_after,
90 }
91 }
92}
93
94#[derive(
95 Debug,
96 Clone,
97 PartialEq,
98 Eq,
99 Hash,
100 tls_codec::TlsSerialize,
101 tls_codec::TlsDeserialize,
102 tls_codec::TlsSize,
103)]
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105pub struct ExternalSender {
106 pub signature_key: SignaturePublicKey,
107 pub credential: Credential,
108}
109
110#[derive(
111 Debug,
112 Clone,
113 Default,
114 PartialEq,
115 Eq,
116 Hash,
117 tls_codec::TlsSerialize,
118 tls_codec::TlsDeserialize,
119 tls_codec::TlsSize,
120)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122pub struct RequiredCapabilities {
123 pub extension_types: Vec<ExtensionType>,
124 pub proposal_types: Vec<ProposalType>,
125 pub credential_types: Vec<CredentialType>,
126}