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