core_crypto_ffi/generic/context/
e2ei.rs

1use std::{collections::HashMap, ops::DerefMut};
2
3use crate::generic::{
4    context::CoreCryptoContext, Ciphersuite, ClientId, CoreCryptoResult, CrlRegistration, E2eiConversationState,
5    E2eiDumpedPkiEnv, E2eiEnrollment, MlsCredentialType, RotateBundle, WireIdentity,
6};
7use crate::CommitBundle;
8use core_crypto::{prelude::VerifiableGroupInfo, CryptoError, MlsError};
9use tls_codec::Deserialize;
10
11#[uniffi::export]
12impl CoreCryptoContext {
13    /// See [core_crypto::context::CentralContext::e2ei_new_enrollment]
14    pub async fn e2ei_new_enrollment(
15        &self,
16        client_id: String,
17        display_name: String,
18        handle: String,
19        team: Option<String>,
20        expiry_sec: u32,
21        ciphersuite: Ciphersuite,
22    ) -> CoreCryptoResult<E2eiEnrollment> {
23        Ok(self
24            .context
25            .e2ei_new_enrollment(
26                client_id.into_bytes().into(),
27                display_name,
28                handle,
29                team,
30                expiry_sec,
31                ciphersuite.into(),
32            )
33            .await
34            .map(async_lock::RwLock::new)
35            .map(std::sync::Arc::new)
36            .map(E2eiEnrollment)?)
37    }
38
39    /// See [core_crypto::context::CentralContext::e2ei_new_activation_enrollment]
40    pub async fn e2ei_new_activation_enrollment(
41        &self,
42        display_name: String,
43        handle: String,
44        team: Option<String>,
45        expiry_sec: u32,
46        ciphersuite: Ciphersuite,
47    ) -> CoreCryptoResult<E2eiEnrollment> {
48        Ok(self
49            .context
50            .e2ei_new_activation_enrollment(display_name, handle, team, expiry_sec, ciphersuite.into())
51            .await
52            .map(async_lock::RwLock::new)
53            .map(std::sync::Arc::new)
54            .map(E2eiEnrollment)?)
55    }
56
57    /// See [core_crypto::context::CentralContext::e2ei_new_rotate_enrollment]
58    pub async fn e2ei_new_rotate_enrollment(
59        &self,
60        display_name: Option<String>,
61        handle: Option<String>,
62        team: Option<String>,
63        expiry_sec: u32,
64        ciphersuite: Ciphersuite,
65    ) -> CoreCryptoResult<E2eiEnrollment> {
66        Ok(self
67            .context
68            .e2ei_new_rotate_enrollment(display_name, handle, team, expiry_sec, ciphersuite.into())
69            .await
70            .map(async_lock::RwLock::new)
71            .map(std::sync::Arc::new)
72            .map(E2eiEnrollment)?)
73    }
74
75    /// See [core_crypto::context::CentralContext::e2ei_register_acme_ca]
76    pub async fn e2ei_register_acme_ca(&self, trust_anchor_pem: String) -> CoreCryptoResult<()> {
77        self.context.e2ei_register_acme_ca(trust_anchor_pem).await?;
78        Ok(())
79    }
80
81    /// See [core_crypto::context::CentralContext::e2ei_register_intermediate_ca_pem]
82    pub async fn e2ei_register_intermediate_ca(&self, cert_pem: String) -> CoreCryptoResult<Option<Vec<String>>> {
83        Ok(self
84            .context
85            .e2ei_register_intermediate_ca_pem(cert_pem)
86            .await
87            .map(Into::into)?)
88    }
89
90    /// See [core_crypto::context::CentralContext::e2ei_register_crl]
91    pub async fn e2ei_register_crl(&self, crl_dp: String, crl_der: Vec<u8>) -> CoreCryptoResult<CrlRegistration> {
92        Ok(self.context.e2ei_register_crl(crl_dp, crl_der).await.map(Into::into)?)
93    }
94
95    /// See [core_crypto::context::CentralContext::e2ei_mls_init_only]
96    pub async fn e2ei_mls_init_only(
97        &self,
98        enrollment: std::sync::Arc<E2eiEnrollment>,
99        certificate_chain: String,
100        nb_key_package: Option<u32>,
101    ) -> CoreCryptoResult<Option<Vec<String>>> {
102        let nb_key_package = nb_key_package
103            .map(usize::try_from)
104            .transpose()
105            .map_err(CryptoError::from)?;
106
107        Ok(self
108            .context
109            .e2ei_mls_init_only(
110                enrollment.0.write().await.deref_mut(),
111                certificate_chain,
112                nb_key_package,
113            )
114            .await
115            .map(Into::into)?)
116    }
117
118    /// See [core_crypto::context::CentralContext::e2ei_rotate]
119    pub async fn e2ei_rotate(&self, conversation_id: Vec<u8>) -> CoreCryptoResult<CommitBundle> {
120        self.context.e2ei_rotate(&conversation_id, None).await?.try_into()
121    }
122
123    /// See [core_crypto::context::CentralContext::e2ei_rotate_all]
124    pub async fn e2ei_rotate_all(
125        &self,
126        enrollment: std::sync::Arc<E2eiEnrollment>,
127        certificate_chain: String,
128        new_key_packages_count: u32,
129    ) -> CoreCryptoResult<RotateBundle> {
130        self.context
131            .e2ei_rotate_all(
132                enrollment.0.write().await.deref_mut(),
133                certificate_chain,
134                new_key_packages_count as usize,
135            )
136            .await?
137            .try_into()
138    }
139
140    /// See [core_crypto::context::CentralContext::e2ei_enrollment_stash]
141    pub async fn e2ei_enrollment_stash(&self, enrollment: std::sync::Arc<E2eiEnrollment>) -> CoreCryptoResult<Vec<u8>> {
142        let enrollment = std::sync::Arc::into_inner(enrollment).ok_or_else(|| CryptoError::LockPoisonError)?;
143        let enrollment = std::sync::Arc::into_inner(enrollment.0)
144            .ok_or_else(|| CryptoError::LockPoisonError)?
145            .into_inner();
146
147        Ok(self.context.e2ei_enrollment_stash(enrollment).await?)
148    }
149
150    /// See [core_crypto::context::CentralContext::e2ei_enrollment_stash_pop]
151    pub async fn e2ei_enrollment_stash_pop(&self, handle: Vec<u8>) -> CoreCryptoResult<E2eiEnrollment> {
152        Ok(self
153            .context
154            .e2ei_enrollment_stash_pop(handle)
155            .await
156            .map(async_lock::RwLock::new)
157            .map(std::sync::Arc::new)
158            .map(E2eiEnrollment)?)
159    }
160
161    /// See [core_crypto::context::CentralContext::e2ei_conversation_state]
162    pub async fn e2ei_conversation_state(&self, conversation_id: Vec<u8>) -> CoreCryptoResult<E2eiConversationState> {
163        Ok(self
164            .context
165            .e2ei_conversation_state(&conversation_id)
166            .await
167            .map(Into::into)?)
168    }
169
170    pub async fn e2ei_dump_pki_env(&self) -> CoreCryptoResult<Option<E2eiDumpedPkiEnv>> {
171        Ok(self.context.e2ei_dump_pki_env().await?.map(Into::into))
172    }
173
174    /// See [core_crypto::mls::MlsCentral::e2ei_is_pki_env_setup]
175    pub async fn e2ei_is_pki_env_setup(&self) -> CoreCryptoResult<bool> {
176        Ok(self.context.e2ei_is_pki_env_setup().await?)
177    }
178
179    /// See [core_crypto::mls::MlsCentral::e2ei_is_enabled]
180    pub async fn e2ei_is_enabled(&self, ciphersuite: Ciphersuite) -> CoreCryptoResult<bool> {
181        let sc = core_crypto::prelude::MlsCiphersuite::from(core_crypto::prelude::CiphersuiteName::from(ciphersuite))
182            .signature_algorithm();
183        Ok(self.context.e2ei_is_enabled(sc).await?)
184    }
185
186    /// See [core_crypto::mls::MlsCentral::get_device_identities]
187    pub async fn get_device_identities(
188        &self,
189        conversation_id: Vec<u8>,
190        device_ids: Vec<ClientId>,
191    ) -> CoreCryptoResult<Vec<WireIdentity>> {
192        let device_ids = device_ids.into_iter().map(|cid| cid.0).collect::<Vec<_>>();
193        Ok(self
194            .context
195            .get_device_identities(&conversation_id, &device_ids[..])
196            .await?
197            .into_iter()
198            .map(Into::into)
199            .collect::<Vec<_>>())
200    }
201
202    /// See [core_crypto::mls::MlsCentral::get_user_identities]
203    pub async fn get_user_identities(
204        &self,
205        conversation_id: Vec<u8>,
206        user_ids: Vec<String>,
207    ) -> CoreCryptoResult<HashMap<String, Vec<WireIdentity>>> {
208        Ok(self
209            .context
210            .get_user_identities(&conversation_id, &user_ids[..])
211            .await?
212            .into_iter()
213            .map(|(k, v)| (k, v.into_iter().map(Into::into).collect()))
214            .collect::<HashMap<String, Vec<WireIdentity>>>())
215    }
216
217    /// See [core_crypto::mls::MlsCentral::get_credential_in_use]
218    pub async fn get_credential_in_use(
219        &self,
220        group_info: Vec<u8>,
221        credential_type: MlsCredentialType,
222    ) -> CoreCryptoResult<E2eiConversationState> {
223        let group_info = VerifiableGroupInfo::tls_deserialize(&mut group_info.as_slice())
224            .map_err(MlsError::from)
225            .map_err(CryptoError::from)?;
226        Ok(self
227            .context
228            .get_credential_in_use(group_info, credential_type.into())
229            .await?
230            .into())
231    }
232}