1use zeroize::Zeroize;
2
3use crate::{
4 CryptoKeystoreResult, Sha256Hash,
5 traits::{EntityBase, EntityGetBorrowed as _, KeyType, OwnedKeyType, PrimaryKey, SearchableEntity as _},
6};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::From, derive_more::Into, derive_more::AsRef)]
10pub struct ParentGroupId<'a>(&'a [u8]);
11
12impl<'a> KeyType for ParentGroupId<'a> {
13 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
14 self.0.into()
15 }
16}
17
18#[derive(
20 core_crypto_macros::Debug,
21 Clone,
22 PartialEq,
23 Eq,
24 Zeroize,
25 core_crypto_macros::Entity,
26 serde::Serialize,
27 serde::Deserialize,
28)]
29#[zeroize(drop)]
30#[entity(collection_name = "mls_groups")]
31#[sensitive]
32pub struct PersistedMlsGroup {
33 #[entity(id, hex, column = "id_hex")]
34 pub id: Vec<u8>,
35 pub state: Vec<u8>,
36 #[entity(unencrypted_wasm)]
37 pub parent_id: Option<Vec<u8>>,
38}
39
40impl PersistedMlsGroup {
41 pub async fn parent_group(
43 &self,
44 conn: &mut <Self as EntityBase>::ConnectionType,
45 ) -> CryptoKeystoreResult<Option<Self>> {
46 let Some(parent_id) = self.parent_id.as_deref() else {
47 return Ok(None);
48 };
49
50 Self::get_borrowed(conn, parent_id).await
51 }
52
53 pub async fn child_groups(
55 &self,
56 conn: &mut <Self as EntityBase>::ConnectionType,
57 ) -> CryptoKeystoreResult<Vec<Self>> {
58 let parent_id = self.id.as_slice();
59 Self::find_all_matching(conn, &parent_id.into()).await
60 }
61}
62
63#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
65#[zeroize(drop)]
66pub struct PersistedMlsPendingGroup {
67 #[sensitive]
68 pub id: Vec<u8>,
69 #[sensitive]
70 pub state: Vec<u8>,
71 #[sensitive]
72 pub parent_id: Option<Vec<u8>>,
73 pub custom_configuration: Vec<u8>,
74}
75
76#[derive(
81 Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, derive_more::AsRef, derive_more::Deref, derive_more::From,
82)]
83pub struct ConversationId<'a>(&'a [u8]);
84
85impl<'a> KeyType for ConversationId<'a> {
86 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
87 self.0.into()
88 }
89}
90
91pub struct MlsPendingMessagePrimaryKey(u128);
102
103impl From<&MlsPendingMessage> for MlsPendingMessagePrimaryKey {
104 fn from(value: &MlsPendingMessage) -> Self {
105 let mut hasher = twox_hash::xxhash3_128::Hasher::new();
106 hasher.write(&value.foreign_id);
107 hasher.write(&value.message);
108 Self(hasher.finish_128())
109 }
110}
111
112impl KeyType for MlsPendingMessagePrimaryKey {
113 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
114 self.0.to_be_bytes().as_slice().to_owned().into()
115 }
116}
117
118impl OwnedKeyType for MlsPendingMessagePrimaryKey {
119 fn from_bytes(bytes: &[u8]) -> Option<Self> {
120 let array = bytes.try_into().ok()?;
121 Some(Self(u128::from_be_bytes(array)))
122 }
123}
124
125#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
127#[zeroize(drop)]
128pub struct MlsPendingMessage {
129 #[sensitive]
130 pub foreign_id: Vec<u8>,
131 pub message: Vec<u8>,
132}
133
134impl PrimaryKey for MlsPendingMessage {
135 type PrimaryKey = MlsPendingMessagePrimaryKey;
136 fn primary_key(&self) -> Self::PrimaryKey {
137 self.into()
138 }
139}
140
141#[derive(
149 core_crypto_macros::Debug,
150 Clone,
151 PartialEq,
152 Eq,
153 Zeroize,
154 core_crypto_macros::Entity,
155 serde::Serialize,
156 serde::Deserialize,
157)]
158#[entity(collection_name = "mls_buffered_commits")]
159pub struct StoredBufferedCommit {
160 #[entity(id, hex, column = "conversation_id_hex")]
161 #[sensitive]
162 conversation_id: Vec<u8>,
163 commit_data: Vec<u8>,
164}
165
166impl StoredBufferedCommit {
167 pub fn new(conversation_id: Vec<u8>, commit_data: Vec<u8>) -> Self {
169 Self {
170 conversation_id,
171 commit_data,
172 }
173 }
174
175 pub fn conversation_id(&self) -> &[u8] {
176 &self.conversation_id
177 }
178
179 pub fn commit_data(&self) -> &[u8] {
180 &self.commit_data
181 }
182
183 pub fn into_commit_data(self) -> Vec<u8> {
184 self.commit_data
185 }
186}
187
188#[derive(Debug, Default, Clone, Copy, serde::Serialize)]
193pub struct CredentialFindFilters<'a> {
194 pub hash: Option<Sha256Hash>,
196 pub public_key: Option<&'a [u8]>,
198 pub session_id: Option<&'a [u8]>,
200 pub ciphersuite: Option<u16>,
202 pub earliest_validity: Option<u64>,
204}
205
206impl<'a> KeyType for CredentialFindFilters<'a> {
207 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
208 postcard::to_stdvec(self)
209 .expect("serializing these filters cannot fail")
210 .into()
211 }
212}
213
214#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
216#[zeroize(drop)]
217pub struct StoredCredential {
218 #[sensitive]
220 pub session_id: Vec<u8>,
221 #[sensitive]
222 pub credential: Vec<u8>,
223 pub created_at: u64,
224 pub ciphersuite: u16,
225 #[sensitive]
226 pub public_key: Vec<u8>,
227 #[sensitive]
228 pub private_key: Vec<u8>,
229}
230
231#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
233#[zeroize(drop)]
234#[sensitive]
235pub struct StoredHpkePrivateKey {
236 pub sk: Vec<u8>,
237 pub pk: Vec<u8>,
238}
239
240#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
242#[zeroize(drop)]
243#[sensitive]
244pub struct StoredEncryptionKeyPair {
245 pub sk: Vec<u8>,
246 pub pk: Vec<u8>,
247}
248
249#[derive(
251 core_crypto_macros::Debug,
252 Clone,
253 PartialEq,
254 Eq,
255 Zeroize,
256 core_crypto_macros::Entity,
257 serde::Serialize,
258 serde::Deserialize,
259)]
260#[zeroize(drop)]
261#[entity(collection_name = "mls_epoch_encryption_keypairs")]
262pub struct StoredEpochEncryptionKeypair {
263 #[entity(hex, column = "id_hex")]
264 pub id: Vec<u8>,
265 #[sensitive]
266 pub keypairs: Vec<u8>,
267}
268
269#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
271#[zeroize(drop)]
272#[sensitive]
273pub struct StoredPskBundle {
274 pub psk_id: Vec<u8>,
275 pub psk: Vec<u8>,
276}
277
278#[derive(
280 core_crypto_macros::Debug,
281 Clone,
282 PartialEq,
283 Eq,
284 Zeroize,
285 core_crypto_macros::Entity,
286 serde::Serialize,
287 serde::Deserialize,
288)]
289#[zeroize(drop)]
290#[entity(collection_name = "mls_keypackages")]
291pub struct StoredKeypackage {
292 #[entity(id, hex, column = "keypackage_ref_hex")]
293 pub keypackage_ref: Vec<u8>,
294 #[sensitive]
295 pub keypackage: Vec<u8>,
296}
297
298#[derive(
301 core_crypto_macros::Debug,
302 Clone,
303 PartialEq,
304 Eq,
305 Zeroize,
306 core_crypto_macros::Entity,
307 serde::Serialize,
308 serde::Deserialize,
309)]
310#[zeroize(drop)]
311#[entity(collection_name = "e2ei_enrollment", no_upsert)]
312pub struct StoredE2eiEnrollment {
313 pub id: Vec<u8>,
314 pub content: Vec<u8>,
315}
316
317#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
319#[zeroize(drop)]
320pub struct E2eiRefreshToken {
321 pub content: Vec<u8>,
322}
323
324#[derive(core_crypto_macros::Debug, Clone, PartialEq, Eq, Zeroize, serde::Serialize, serde::Deserialize)]
325#[zeroize(drop)]
326pub struct E2eiAcmeCA {
327 pub content: Vec<u8>,
328}
329
330#[derive(
331 core_crypto_macros::Debug,
332 Clone,
333 PartialEq,
334 Eq,
335 Zeroize,
336 core_crypto_macros::Entity,
337 serde::Serialize,
338 serde::Deserialize,
339)]
340#[zeroize(drop)]
341pub struct E2eiIntermediateCert {
342 #[entity(id)]
345 pub ski_aki_pair: String,
346 pub content: Vec<u8>,
347}
348
349#[derive(
350 core_crypto_macros::Debug,
351 Clone,
352 PartialEq,
353 Eq,
354 Zeroize,
355 core_crypto_macros::Entity,
356 serde::Serialize,
357 serde::Deserialize,
358)]
359#[zeroize(drop)]
360pub struct E2eiCrl {
361 #[entity(id)]
362 pub distribution_point: String,
363 pub content: Vec<u8>,
364}