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 close(self) -> MlsProviderResult<()> {
143 self.key_store.close().await.map_err(Into::into)
144 }
145
146 pub fn keystore(&self) -> CryptoKeystore {
148 self.key_store.clone()
149 }
150
151 pub fn unwrap_keystore(self) -> CryptoKeystore {
153 self.key_store
154 }
155}
156
157impl openmls_traits::OpenMlsCryptoProvider for MlsCryptoProvider {
158 type CryptoProvider = RustCrypto;
159 type RandProvider = RustCrypto;
160 type KeyStoreProvider = CryptoKeystore;
161 type AuthenticationServiceProvider = PkiEnvironmentProvider;
162
163 fn crypto(&self) -> &Self::CryptoProvider {
164 &self.crypto
165 }
166
167 fn rand(&self) -> &Self::RandProvider {
168 &self.crypto
169 }
170
171 fn key_store(&self) -> &Self::KeyStoreProvider {
172 &self.key_store
173 }
174
175 fn authentication_service(&self) -> &Self::AuthenticationServiceProvider {
176 &self.pki_env
177 }
178}