core_crypto/transaction_context/
proteus.rs1use super::{Error, Result, TransactionContext, TransactionContextInner};
4use crate::{RecursiveError, proteus::ProteusCentral};
5
6impl TransactionContext {
7 pub async fn proteus_init(&self) -> Result<()> {
9 let keystore = self.database().await?;
10 let proteus_client = ProteusCentral::try_new(&keystore)
11 .await
12 .map_err(RecursiveError::root("creating new proteus client"))?;
13
14 let _ = proteus_client
16 .last_resort_prekey(&keystore)
17 .await
18 .map_err(RecursiveError::root("getting last resort prekey"))?;
19
20 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
21 return Err(Error::InvalidTransactionContext);
22 };
23 let mut guard = core_crypto.proteus.lock().await;
24 *guard = Some(proteus_client);
25 Ok(())
26 }
27
28 pub async fn proteus_session_from_prekey(&self, session_id: &str, prekey: &[u8]) -> Result<()> {
33 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
34 return Err(Error::InvalidTransactionContext);
35 };
36 let mut guard = core_crypto.proteus.lock().await;
37 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
38 let keystore = self.database().await?;
39 let session = proteus
40 .session_from_prekey(session_id, prekey)
41 .await
42 .map_err(RecursiveError::root("creating proteus session from prekey"))?;
43 ProteusCentral::session_save_by_ref(&keystore, session)
44 .await
45 .map_err(RecursiveError::root("saving proteus session by ref"))?;
46 Ok(())
47 }
48
49 pub async fn proteus_session_from_message(&self, session_id: &str, envelope: &[u8]) -> Result<Vec<u8>> {
54 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
55 return Err(Error::InvalidTransactionContext);
56 };
57 let mut guard = core_crypto.proteus.lock().await;
58 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
59 let mut keystore = self.database().await?;
60 let (session, message) = proteus
61 .session_from_message(&mut keystore, session_id, envelope)
62 .await
63 .map_err(RecursiveError::root("creating proteus sesseion from message"))?;
64 ProteusCentral::session_save_by_ref(&keystore, session)
65 .await
66 .map_err(RecursiveError::root("saving proteus session by ref"))?;
67 Ok(message)
68 }
69
70 pub async fn proteus_session_save(&self, session_id: &str) -> Result<()> {
75 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
76 return Err(Error::InvalidTransactionContext);
77 };
78 let mut guard = core_crypto.proteus.lock().await;
79 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
80 let keystore = self.database().await?;
81 proteus
82 .session_save(&keystore, session_id)
83 .await
84 .map_err(RecursiveError::root("saving proteus session"))
85 .map_err(Into::into)
86 }
87
88 pub async fn proteus_session_delete(&self, session_id: &str) -> Result<()> {
93 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
94 return Err(Error::InvalidTransactionContext);
95 };
96 let mut guard = core_crypto.proteus.lock().await;
97 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
98 let keystore = self.database().await?;
99 proteus
100 .session_delete(&keystore, session_id)
101 .await
102 .map_err(RecursiveError::root("deleting proteus session"))
103 .map_err(Into::into)
104 }
105
106 pub async fn proteus_session_exists(&self, session_id: &str) -> Result<bool> {
111 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
112 return Err(Error::InvalidTransactionContext);
113 };
114 let mut guard = core_crypto.proteus.lock().await;
115 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
116 let keystore = self.database().await?;
117 Ok(proteus.session_exists(session_id, &keystore).await)
118 }
119
120 pub async fn proteus_decrypt(&self, session_id: &str, ciphertext: &[u8]) -> Result<Vec<u8>> {
125 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
126 return Err(Error::InvalidTransactionContext);
127 };
128 let mut guard = core_crypto.proteus.lock().await;
129 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
130 let mut keystore = self.database().await?;
131 proteus
132 .decrypt(&mut keystore, session_id, ciphertext)
133 .await
134 .map_err(RecursiveError::root("decrypting proteus message"))
135 .map_err(Into::into)
136 }
137
138 pub async fn proteus_encrypt(&self, session_id: &str, plaintext: &[u8]) -> Result<Vec<u8>> {
143 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
144 return Err(Error::InvalidTransactionContext);
145 };
146 let mut guard = core_crypto.proteus.lock().await;
147 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
148 let mut keystore = self.database().await?;
149 proteus
150 .encrypt(&mut keystore, session_id, plaintext)
151 .await
152 .map_err(RecursiveError::root("encrypting proteus message"))
153 .map_err(Into::into)
154 }
155
156 pub async fn proteus_encrypt_batched(
162 &self,
163 sessions: &[impl AsRef<str>],
164 plaintext: &[u8],
165 ) -> Result<std::collections::HashMap<String, Vec<u8>>> {
166 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
167 return Err(Error::InvalidTransactionContext);
168 };
169 let mut guard = core_crypto.proteus.lock().await;
170 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
171 let mut keystore = self.database().await?;
172 proteus
173 .encrypt_batched(&mut keystore, sessions, plaintext)
174 .await
175 .map_err(RecursiveError::root("batch encrypting proteus message"))
176 .map_err(Into::into)
177 }
178
179 pub async fn proteus_new_prekey(&self, prekey_id: u16) -> Result<Vec<u8>> {
184 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
185 return Err(Error::InvalidTransactionContext);
186 };
187 let mut guard = core_crypto.proteus.lock().await;
188 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
189 let keystore = self.database().await?;
190 proteus
191 .new_prekey(prekey_id, &keystore)
192 .await
193 .map_err(RecursiveError::root("new proteus prekey"))
194 .map_err(Into::into)
195 }
196
197 pub async fn proteus_new_prekey_auto(&self) -> Result<(u16, Vec<u8>)> {
203 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
204 return Err(Error::InvalidTransactionContext);
205 };
206 let mut guard = core_crypto.proteus.lock().await;
207 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
208 let keystore = self.database().await?;
209 proteus
210 .new_prekey_auto(&keystore)
211 .await
212 .map_err(RecursiveError::root("proteus new prekey auto"))
213 .map_err(Into::into)
214 }
215
216 pub async fn proteus_last_resort_prekey(&self) -> Result<Vec<u8>> {
218 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
219 return Err(Error::InvalidTransactionContext);
220 };
221 let mut guard = core_crypto.proteus.lock().await;
222 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
223 let keystore = self.database().await?;
224
225 proteus
226 .last_resort_prekey(&keystore)
227 .await
228 .map_err(RecursiveError::root("getting proteus last resort prekey"))
229 .map_err(Into::into)
230 }
231
232 pub fn proteus_last_resort_prekey_id() -> u16 {
234 ProteusCentral::last_resort_prekey_id()
235 }
236
237 pub async fn proteus_fingerprint(&self) -> Result<String> {
242 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
243 return Err(Error::InvalidTransactionContext);
244 };
245 let mut guard = core_crypto.proteus.lock().await;
246 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
247 Ok(proteus.fingerprint())
248 }
249
250 pub async fn proteus_fingerprint_local(&self, session_id: &str) -> Result<String> {
255 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
256 return Err(Error::InvalidTransactionContext);
257 };
258 let mut guard = core_crypto.proteus.lock().await;
259 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
260 let keystore = self.database().await?;
261 proteus
262 .fingerprint_local(session_id, &keystore)
263 .await
264 .map_err(RecursiveError::root("getting proteus fingerprint local"))
265 .map_err(Into::into)
266 }
267
268 pub async fn proteus_fingerprint_remote(&self, session_id: &str) -> Result<String> {
273 let TransactionContextInner::Valid { core_crypto, .. } = &*self.inner.read().await else {
274 return Err(Error::InvalidTransactionContext);
275 };
276 let mut guard = core_crypto.proteus.lock().await;
277 let proteus = guard.as_mut().ok_or(Error::ProteusNotInitialized)?;
278 let keystore = self.database().await?;
279 proteus
280 .fingerprint_remote(session_id, &keystore)
281 .await
282 .map_err(RecursiveError::root("geeting proteus fingerprint remote"))
283 .map_err(Into::into)
284 }
285}