core_crypto_ffi/generic/context/
e2ei.rs1use 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 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 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 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 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 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 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 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 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 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 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 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 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 pub async fn e2ei_is_pki_env_setup(&self) -> CoreCryptoResult<bool> {
176 Ok(self.context.e2ei_is_pki_env_setup().await?)
177 }
178
179 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 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 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 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}