1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 #[cfg(mls_build_async)]
6 use alloc::boxed::Box;
7 use alloc::vec::Vec;
8 use core::fmt::{self, Debug};
9 use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
10 
11 use crate::{crypto::HpkeSecretKey, error::IntoAnyError};
12 
13 #[derive(Clone, PartialEq, Eq, MlsEncode, MlsDecode, MlsSize)]
14 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15 #[non_exhaustive]
16 /// Representation of a generated key package and secret keys.
17 pub struct KeyPackageData {
18     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
19     pub key_package_bytes: Vec<u8>,
20     pub init_key: HpkeSecretKey,
21     pub leaf_node_key: HpkeSecretKey,
22     pub expiration: u64,
23 }
24 
25 impl Debug for KeyPackageData {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result26     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27         f.debug_struct("KeyPackageData")
28             .field(
29                 "key_package_bytes",
30                 &crate::debug::pretty_bytes(&self.key_package_bytes),
31             )
32             .field("init_key", &self.init_key)
33             .field("leaf_node_key", &self.leaf_node_key)
34             .field("expiration", &self.expiration)
35             .finish()
36     }
37 }
38 
39 impl KeyPackageData {
new( key_package_bytes: Vec<u8>, init_key: HpkeSecretKey, leaf_node_key: HpkeSecretKey, expiration: u64, ) -> KeyPackageData40     pub fn new(
41         key_package_bytes: Vec<u8>,
42         init_key: HpkeSecretKey,
43         leaf_node_key: HpkeSecretKey,
44         expiration: u64,
45     ) -> KeyPackageData {
46         Self {
47             key_package_bytes,
48             init_key,
49             leaf_node_key,
50             expiration,
51         }
52     }
53 }
54 
55 /// Storage trait that maintains key package secrets.
56 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
57 #[cfg_attr(mls_build_async, maybe_async::must_be_async)]
58 pub trait KeyPackageStorage: Send + Sync {
59     /// Error type that the underlying storage mechanism returns on internal
60     /// failure.
61     type Error: IntoAnyError;
62 
63     /// Delete [`KeyPackageData`] referenced by `id`.
64     ///
65     /// This function is called automatically when the key package referenced
66     /// by `id` is used to successfully join a group.
67     ///
68     /// # Warning
69     ///
70     /// [`KeyPackageData`] internally contains secret key values. The
71     /// provided delete mechanism should securely erase data.
delete(&mut self, id: &[u8]) -> Result<(), Self::Error>72     async fn delete(&mut self, id: &[u8]) -> Result<(), Self::Error>;
73 
74     /// Store [`KeyPackageData`] that can be accessed by `id` in the future.
75     ///
76     /// This function is automatically called whenever a new key package is created.
insert(&mut self, id: Vec<u8>, pkg: KeyPackageData) -> Result<(), Self::Error>77     async fn insert(&mut self, id: Vec<u8>, pkg: KeyPackageData) -> Result<(), Self::Error>;
78 
79     /// Retrieve [`KeyPackageData`] by its `id`.
80     ///
81     /// `None` should be returned in the event that no key packages are found
82     /// that match `id`.
get(&self, id: &[u8]) -> Result<Option<KeyPackageData>, Self::Error>83     async fn get(&self, id: &[u8]) -> Result<Option<KeyPackageData>, Self::Error>;
84 }
85