1use openmls_traits::storage::{traits, Entity, Key, CURRENT_VERSION};
11
12use crate::binary_tree::LeafNodeIndex;
13use crate::group::proposal_store::QueuedProposal;
14use crate::group::{MlsGroupJoinConfig, MlsGroupState};
15use crate::{
16 ciphersuite::hash_ref::ProposalRef,
17 group::{GroupContext, GroupId, InterimTranscriptHash},
18 messages::ConfirmationTag,
19 treesync::{LeafNode, TreeSync},
20};
21use crate::{
22 group::{past_secrets::MessageSecretsStore, GroupEpoch},
23 prelude::KeyPackageBundle,
24 schedule::{
25 psk::{store::ResumptionPskStore, PskBundle},
26 GroupEpochSecrets, Psk,
27 },
28 treesync::{node::encryption_keys::EncryptionKeyPair, EncryptionKey},
29};
30
31#[cfg(test)]
32pub mod kat_storage_stability;
33
34pub trait StorageProvider: openmls_traits::storage::StorageProvider<CURRENT_VERSION> {}
37
38pub trait PublicStorageProvider:
41 openmls_traits::public_storage::PublicStorageProvider<
42 CURRENT_VERSION,
43 PublicError = <Self as PublicStorageProvider>::Error,
44>
45{
46 type Error: core::fmt::Debug + std::error::Error;
49}
50
51impl<P: openmls_traits::storage::StorageProvider<CURRENT_VERSION>> StorageProvider for P {}
52
53impl<P: openmls_traits::public_storage::PublicStorageProvider<CURRENT_VERSION>>
54 PublicStorageProvider for P
55{
56 type Error = P::PublicError;
57}
58
59pub trait OpenMlsProvider:
63 openmls_traits::OpenMlsProvider<StorageProvider = Self::Storage>
64{
65 type Storage: StorageProvider<Error = Self::StorageError>;
67 type StorageError: std::error::Error;
69}
70
71impl<
72 Error: std::error::Error,
73 SP: StorageProvider<Error = Error>,
74 OP: openmls_traits::OpenMlsProvider<StorageProvider = SP>,
75 > OpenMlsProvider for OP
76{
77 type Storage = SP;
78 type StorageError = Error;
79}
80
81impl Entity<CURRENT_VERSION> for QueuedProposal {}
84impl traits::QueuedProposal<CURRENT_VERSION> for QueuedProposal {}
85
86impl Entity<CURRENT_VERSION> for TreeSync {}
87impl traits::TreeSync<CURRENT_VERSION> for TreeSync {}
88
89impl Key<CURRENT_VERSION> for GroupId {}
90impl traits::GroupId<CURRENT_VERSION> for GroupId {}
91
92impl Key<CURRENT_VERSION> for ProposalRef {}
93impl Entity<CURRENT_VERSION> for ProposalRef {}
94impl traits::ProposalRef<CURRENT_VERSION> for ProposalRef {}
95impl traits::HashReference<CURRENT_VERSION> for ProposalRef {}
96
97impl Entity<CURRENT_VERSION> for GroupContext {}
98impl traits::GroupContext<CURRENT_VERSION> for GroupContext {}
99
100impl Entity<CURRENT_VERSION> for InterimTranscriptHash {}
101impl traits::InterimTranscriptHash<CURRENT_VERSION> for InterimTranscriptHash {}
102
103impl Entity<CURRENT_VERSION> for ConfirmationTag {}
104impl traits::ConfirmationTag<CURRENT_VERSION> for ConfirmationTag {}
105
106impl Entity<CURRENT_VERSION> for KeyPackageBundle {}
107impl traits::KeyPackage<CURRENT_VERSION> for KeyPackageBundle {}
108
109impl Key<CURRENT_VERSION> for EncryptionKey {}
110impl traits::EncryptionKey<CURRENT_VERSION> for EncryptionKey {}
111
112impl Entity<CURRENT_VERSION> for EncryptionKeyPair {}
113impl traits::HpkeKeyPair<CURRENT_VERSION> for EncryptionKeyPair {}
114
115impl Entity<CURRENT_VERSION> for LeafNodeIndex {}
116impl traits::LeafNodeIndex<CURRENT_VERSION> for LeafNodeIndex {}
117
118impl Entity<CURRENT_VERSION> for GroupEpochSecrets {}
119impl traits::GroupEpochSecrets<CURRENT_VERSION> for GroupEpochSecrets {}
120
121impl Entity<CURRENT_VERSION> for MessageSecretsStore {}
122impl traits::MessageSecrets<CURRENT_VERSION> for MessageSecretsStore {}
123
124impl Entity<CURRENT_VERSION> for ResumptionPskStore {}
125impl traits::ResumptionPskStore<CURRENT_VERSION> for ResumptionPskStore {}
126
127impl Entity<CURRENT_VERSION> for MlsGroupJoinConfig {}
128impl traits::MlsGroupJoinConfig<CURRENT_VERSION> for MlsGroupJoinConfig {}
129
130impl Entity<CURRENT_VERSION> for MlsGroupState {}
131impl traits::GroupState<CURRENT_VERSION> for MlsGroupState {}
132
133impl Entity<CURRENT_VERSION> for LeafNode {}
134impl traits::LeafNode<CURRENT_VERSION> for LeafNode {}
135
136impl Key<CURRENT_VERSION> for GroupEpoch {}
139impl traits::EpochKey<CURRENT_VERSION> for GroupEpoch {}
140
141impl Key<CURRENT_VERSION> for Psk {}
142impl traits::PskId<CURRENT_VERSION> for Psk {}
143
144impl Entity<CURRENT_VERSION> for PskBundle {}
145impl traits::PskBundle<CURRENT_VERSION> for PskBundle {}
146
147#[cfg(test)]
148mod test {
149 use crate::{
150 group::mls_group::tests_and_kats::utils::setup_client, prelude::KeyPackageBuilder,
151 };
152
153 use super::*;
154
155 use openmls_rust_crypto::{MemoryStorage, OpenMlsRustCrypto};
156 use openmls_traits::{
157 storage::{traits as type_traits, StorageProvider, V_TEST},
158 types::{Ciphersuite, HpkePrivateKey},
159 OpenMlsProvider,
160 };
161 use serde::{Deserialize, Serialize};
162
163 #[derive(Serialize, Deserialize)]
166 struct NewKeyPackageBundle {
167 ciphersuite: Ciphersuite,
168 key_package: crate::key_packages::KeyPackage,
169 private_init_key: HpkePrivateKey,
170 private_encryption_key: crate::treesync::node::encryption_keys::EncryptionPrivateKey,
171 }
172
173 impl Entity<V_TEST> for NewKeyPackageBundle {}
174 impl type_traits::KeyPackage<V_TEST> for NewKeyPackageBundle {}
175
176 impl Key<V_TEST> for EncryptionKey {}
177 impl type_traits::EncryptionKey<V_TEST> for EncryptionKey {}
178
179 impl Entity<V_TEST> for EncryptionKeyPair {}
180 impl type_traits::HpkeKeyPair<V_TEST> for EncryptionKeyPair {}
181
182 impl Key<V_TEST> for ProposalRef {}
183 impl type_traits::HashReference<V_TEST> for ProposalRef {}
184
185 #[test]
186 fn key_packages_key_upgrade() {
187 let provider = OpenMlsRustCrypto::default();
189
190 let (credential_with_key, _kpb, signer, _pk) = setup_client(
191 "Alice",
192 Ciphersuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519,
193 &provider,
194 );
195
196 let key_package_bundle = KeyPackageBuilder::new()
198 .build(
199 Ciphersuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519,
200 &provider,
201 &signer,
202 credential_with_key,
203 )
204 .unwrap();
205
206 let key_package = key_package_bundle.key_package();
207 let key_package_ref = key_package.hash_ref(provider.crypto()).unwrap();
208
209 let new_storage_provider = MemoryStorage::default();
213
214 let read_key_package_bundle: crate::prelude::KeyPackageBundle =
216 <MemoryStorage as StorageProvider<CURRENT_VERSION>>::key_package(
217 provider.storage(),
218 &key_package_ref,
219 )
220 .unwrap()
221 .unwrap();
222
223 let new_key_package_bundle = NewKeyPackageBundle {
225 ciphersuite: read_key_package_bundle.key_package().ciphersuite(),
226 key_package: read_key_package_bundle.key_package().clone(),
227 private_init_key: read_key_package_bundle.init_private_key().clone(),
228 private_encryption_key: read_key_package_bundle.private_encryption_key.clone(),
229 };
230
231 <MemoryStorage as StorageProvider<V_TEST>>::write_key_package(
233 &new_storage_provider,
234 &key_package_ref,
235 &new_key_package_bundle,
236 )
237 .unwrap();
238
239 let read_new_key_package_bundle: NewKeyPackageBundle =
241 <MemoryStorage as StorageProvider<V_TEST>>::key_package(
242 &new_storage_provider,
243 &key_package_ref,
244 )
245 .unwrap()
246 .unwrap();
247
248 assert_eq!(
251 &read_new_key_package_bundle.key_package,
252 key_package_bundle.key_package()
253 );
254 assert_eq!(
255 read_new_key_package_bundle.ciphersuite,
256 key_package_bundle.key_package().ciphersuite()
257 );
258 assert_eq!(
259 &read_new_key_package_bundle.private_encryption_key,
260 &key_package_bundle.private_encryption_key
261 );
262 assert_eq!(
263 &read_new_key_package_bundle.private_init_key,
264 &key_package_bundle.private_init_key
265 );
266 }
267}