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};
14use typed_builder::TypedBuilder;
15
16use crate::pki::PkiEnvironmentProvider;
17
18pub mod reexports {
19 pub use rand_core;
20}
21
22pub type RawEntropySeed = <rand_chacha::ChaCha20Rng as rand::SeedableRng>::Seed;
24
25#[derive(Debug, Clone, Default, PartialEq, Eq, zeroize::ZeroizeOnDrop)]
26#[repr(transparent)]
27pub struct EntropySeed(RawEntropySeed);
29
30impl EntropySeed {
31 pub const EXPECTED_LEN: usize = std::mem::size_of::<EntropySeed>() / std::mem::size_of::<u8>();
32
33 pub fn try_from_slice(data: &[u8]) -> MlsProviderResult<Self> {
34 if data.len() < Self::EXPECTED_LEN {
35 return Err(MlsProviderError::EntropySeedLengthError {
36 actual: data.len(),
37 expected: Self::EXPECTED_LEN,
38 });
39 }
40
41 let mut inner = RawEntropySeed::default();
42 inner.copy_from_slice(&data[..Self::EXPECTED_LEN]);
43
44 Ok(Self(inner))
45 }
46
47 pub fn from_raw(raw: RawEntropySeed) -> Self {
48 Self(raw)
49 }
50}
51
52impl std::ops::Deref for EntropySeed {
53 type Target = [u8];
54 fn deref(&self) -> &Self::Target {
55 &self.0
56 }
57}
58
59impl std::ops::DerefMut for EntropySeed {
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.0
62 }
63}
64
65#[doc(hidden)]
69#[derive(TypedBuilder)]
70#[builder(build_method(into = MlsCryptoProvider))]
71pub struct MlsCryptoProviderConfiguration {
72 key_store: CryptoKeystore,
73 #[builder(default, setter(strip_option(fallback=entropy_seed_opt)))]
75 entropy_seed: Option<EntropySeed>,
76}
77
78#[derive(Debug, Clone)]
79pub struct MlsCryptoProvider {
80 crypto: RustCrypto,
81 key_store: CryptoKeystore,
82 pki_env: PkiEnvironmentProvider,
83}
84
85impl From<MlsCryptoProviderConfiguration> for MlsCryptoProvider {
86 fn from(
87 MlsCryptoProviderConfiguration {
88 key_store,
89 entropy_seed,
90 }: MlsCryptoProviderConfiguration,
91 ) -> Self {
92 let crypto = entropy_seed.map(RustCrypto::new_with_seed).unwrap_or_default();
93 let pki_env = PkiEnvironmentProvider::default();
94
95 Self {
96 crypto,
97 key_store,
98 pki_env,
99 }
100 }
101}
102
103impl MlsCryptoProvider {
104 pub fn builder() -> MlsCryptoProviderConfigurationBuilder {
110 MlsCryptoProviderConfiguration::builder()
111 }
112
113 pub async fn new_transaction(&self) -> MlsProviderResult<()> {
116 self.key_store.new_transaction().await.map_err(Into::into)
117 }
118
119 pub async fn update_pki_env(
121 &self,
122 pki_env: wire_e2e_identity::prelude::x509::revocation::PkiEnvironment,
123 ) -> MlsProviderResult<()> {
124 self.pki_env.update_env(pki_env).await
125 }
126
127 pub async fn is_pki_env_setup(&self) -> bool {
129 self.pki_env.is_env_setup().await
130 }
131
132 pub fn reseed(&self, entropy_seed: Option<EntropySeed>) -> MlsProviderResult<()> {
136 self.crypto.reseed(entropy_seed)
137 }
138
139 pub async fn can_close(&self) -> bool {
150 self.key_store.can_close().await
151 }
152
153 pub async fn close(self) -> MlsProviderResult<()> {
157 self.key_store.close().await.map_err(Into::into)
158 }
159
160 pub fn keystore(&self) -> CryptoKeystore {
162 self.key_store.clone()
163 }
164
165 pub fn unwrap_keystore(self) -> CryptoKeystore {
167 self.key_store
168 }
169}
170
171impl openmls_traits::OpenMlsCryptoProvider for MlsCryptoProvider {
172 type CryptoProvider = RustCrypto;
173 type RandProvider = RustCrypto;
174 type KeyStoreProvider = CryptoKeystore;
175 type AuthenticationServiceProvider = PkiEnvironmentProvider;
176
177 fn crypto(&self) -> &Self::CryptoProvider {
178 &self.crypto
179 }
180
181 fn rand(&self) -> &Self::RandProvider {
182 &self.crypto
183 }
184
185 fn key_store(&self) -> &Self::KeyStoreProvider {
186 &self.key_store
187 }
188
189 fn authentication_service(&self) -> &Self::AuthenticationServiceProvider {
190 &self.pki_env
191 }
192}