mls_crypto_provider/
lib.rs1#![doc = include_str!("../README.md")]
2
3pub use core_crypto_keystore::{Connection as CryptoKeystore, DatabaseKey};
4
5mod crypto_provider;
6mod error;
7mod pki;
8
9pub use error::{MlsProviderError, MlsProviderResult};
10
11pub use crypto_provider::RustCrypto;
12
13pub use pki::{CertProfile, CertificateGenerationArgs, PkiKeypair};
14
15use crate::pki::PkiEnvironmentProvider;
16
17pub mod reexports {
18 pub use rand_core;
19}
20
21pub type RawEntropySeed = <rand_chacha::ChaCha20Rng as rand::SeedableRng>::Seed;
23
24#[derive(Debug, Clone, Default, PartialEq, Eq, zeroize::ZeroizeOnDrop)]
25#[repr(transparent)]
26pub struct EntropySeed(RawEntropySeed);
28
29impl EntropySeed {
30 pub const EXPECTED_LEN: usize = std::mem::size_of::<EntropySeed>() / std::mem::size_of::<u8>();
31
32 pub fn try_from_slice(data: &[u8]) -> MlsProviderResult<Self> {
33 if data.len() < Self::EXPECTED_LEN {
34 return Err(MlsProviderError::EntropySeedLengthError {
35 actual: data.len(),
36 expected: Self::EXPECTED_LEN,
37 });
38 }
39
40 let mut inner = RawEntropySeed::default();
41 inner.copy_from_slice(&data[..Self::EXPECTED_LEN]);
42
43 Ok(Self(inner))
44 }
45
46 pub fn from_raw(raw: RawEntropySeed) -> Self {
47 Self(raw)
48 }
49}
50
51impl std::ops::Deref for EntropySeed {
52 type Target = [u8];
53 fn deref(&self) -> &Self::Target {
54 &self.0
55 }
56}
57
58impl std::ops::DerefMut for EntropySeed {
59 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut self.0
61 }
62}
63
64pub struct MlsCryptoProviderConfiguration<'a> {
65 pub db_path: &'a str,
67 pub db_key: DatabaseKey,
69 pub in_memory: bool,
71 pub entropy_seed: Option<EntropySeed>,
73}
74
75#[derive(Debug, Clone)]
76pub struct MlsCryptoProvider {
77 crypto: RustCrypto,
78 key_store: CryptoKeystore,
79 pki_env: PkiEnvironmentProvider,
80}
81
82impl MlsCryptoProvider {
83 pub async fn try_new_with_configuration(config: MlsCryptoProviderConfiguration<'_>) -> MlsProviderResult<Self> {
85 let crypto = config.entropy_seed.map(RustCrypto::new_with_seed).unwrap_or_default();
86 let key_store = if config.in_memory {
87 CryptoKeystore::open_in_memory_with_key("", &config.db_key).await?
88 } else {
89 CryptoKeystore::open_with_key(config.db_path, &config.db_key).await?
90 };
91 Ok(Self {
92 crypto,
93 key_store,
94 pki_env: PkiEnvironmentProvider::default(),
95 })
96 }
97
98 pub async fn try_new(db_path: impl AsRef<str>, db_key: &DatabaseKey) -> MlsProviderResult<Self> {
99 let crypto = RustCrypto::default();
100 let key_store = CryptoKeystore::open_with_key(db_path, db_key).await?;
101 Ok(Self {
102 crypto,
103 key_store,
104 pki_env: PkiEnvironmentProvider::default(),
105 })
106 }
107
108 pub async fn try_new_in_memory(db_key: &DatabaseKey) -> MlsProviderResult<Self> {
109 let crypto = RustCrypto::default();
110 let key_store = CryptoKeystore::open_in_memory_with_key("", db_key).await?;
111 Ok(Self {
112 crypto,
113 key_store,
114 pki_env: PkiEnvironmentProvider::default(),
115 })
116 }
117
118 pub fn new_with_store(key_store: CryptoKeystore, entropy_seed: Option<EntropySeed>) -> Self {
120 let crypto = entropy_seed.map(RustCrypto::new_with_seed).unwrap_or_default();
121 Self {
122 crypto,
123 key_store,
124 pki_env: PkiEnvironmentProvider::default(),
125 }
126 }
127
128 pub async fn new_transaction(&self) -> MlsProviderResult<()> {
131 self.key_store.new_transaction().await.map_err(Into::into)
132 }
133
134 pub async fn update_pki_env(
136 &self,
137 pki_env: wire_e2e_identity::prelude::x509::revocation::PkiEnvironment,
138 ) -> MlsProviderResult<()> {
139 self.pki_env.update_env(pki_env).await
140 }
141
142 pub async fn is_pki_env_setup(&self) -> bool {
144 self.pki_env.is_env_setup().await
145 }
146
147 pub fn reseed(&self, entropy_seed: Option<EntropySeed>) -> MlsProviderResult<()> {
151 self.crypto.reseed(entropy_seed)
152 }
153
154 pub async fn can_close(&self) -> bool {
165 self.key_store.can_close().await
166 }
167
168 pub async fn close(self) -> MlsProviderResult<()> {
172 self.key_store.close().await.map_err(Into::into)
173 }
174
175 pub fn keystore(&self) -> CryptoKeystore {
177 self.key_store.clone()
178 }
179
180 pub fn unwrap_keystore(self) -> CryptoKeystore {
182 self.key_store
183 }
184}
185
186impl openmls_traits::OpenMlsCryptoProvider for MlsCryptoProvider {
187 type CryptoProvider = RustCrypto;
188 type RandProvider = RustCrypto;
189 type KeyStoreProvider = CryptoKeystore;
190 type AuthenticationServiceProvider = PkiEnvironmentProvider;
191
192 fn crypto(&self) -> &Self::CryptoProvider {
193 &self.crypto
194 }
195
196 fn rand(&self) -> &Self::RandProvider {
197 &self.crypto
198 }
199
200 fn key_store(&self) -> &Self::KeyStoreProvider {
201 &self.key_store
202 }
203
204 fn authentication_service(&self) -> &Self::AuthenticationServiceProvider {
205 &self.pki_env
206 }
207}