core_crypto/mls/conversation/immutable/
e2ei.rs1use std::{borrow::Borrow, collections::HashMap};
2
3use openmls_traits::OpenMlsCryptoProvider as _;
4use uuid::Uuid;
5
6use super::{Error, Result};
7use crate::{
8 ClientIdRef, CredentialType, E2eiConversationState, RecursiveError, Session, WireIdentity,
9 mls::credential::ext::CredentialExt as _,
10};
11
12impl super::Conversation {
13 pub async fn e2ei_conversation_state(&self) -> Result<E2eiConversationState> {
16 let backend = &self.session.crypto_provider;
17
18 let state = Session::compute_conversation_state(
19 self.cipher_suite(),
20 self.group().await.members_credentials(),
21 CredentialType::X509,
22 backend.authentication_service(),
23 )
24 .await;
25 Ok(state)
26 }
27
28 pub async fn get_device_identities(
32 &self,
33 device_ids: &[impl Borrow<ClientIdRef> + Sync],
34 ) -> Result<Vec<WireIdentity>> {
35 if device_ids.is_empty() {
36 return Err(Error::CallerError(
37 "This function accepts a list of IDs as a parameter, but that list was empty.",
38 ));
39 }
40 let mls_provider = &self.session.crypto_provider;
41 let auth_service = mls_provider.authentication_service();
42
43 let pki_env = auth_service.pki_env().await;
44
45 let mut identities = vec![];
46 for (id, credential) in self.members_with_key().await? {
47 if device_ids.iter().any(|client_id| client_id.borrow() == id.as_slice()) {
48 identities.push(
49 credential
50 .extract_identity(self.cipher_suite(), pki_env.as_deref())
51 .await
52 .map_err(RecursiveError::mls_credential("extracting identity"))?,
53 );
54 }
55 }
56 Ok(identities)
57 }
58
59 pub async fn get_user_identities(&self, user_ids: &[Uuid]) -> Result<HashMap<Uuid, Vec<WireIdentity>>> {
66 if user_ids.is_empty() {
67 return Err(Error::CallerError(
68 "This function accepts a list of IDs as a parameter, but that list was empty.",
69 ));
70 }
71 let mls_provider = &self.session.crypto_provider;
72 let auth_service = mls_provider.authentication_service();
73
74 let pki_env = auth_service.pki_env().await;
75
76 let mut identities = HashMap::new();
77 for (id, credential) in self.members_with_key().await? {
78 let user_id = &id.deserialize().user_id;
79
80 if !user_ids.contains(user_id) {
81 continue;
82 }
83
84 let identity = credential
85 .extract_identity(self.cipher_suite(), pki_env.as_deref())
86 .await
87 .map_err(RecursiveError::mls_credential("extracting identity"))?;
88 let value = identities.entry(*user_id).or_insert_with(Vec::new);
89 value.push(identity);
90 }
91
92 Ok(identities)
93 }
94}