core_crypto/mls/conversation/immutable/
credential.rs1use std::{collections::HashMap, sync::Arc};
2
3use openmls::{
4 group::QueuedProposal,
5 prelude::{
6 Credential as MlsCredential, CredentialWithKey, LeafNode, LeafNodeIndex, Proposal, Sender, SignaturePublicKey,
7 },
8};
9
10use super::{Error, Result};
11use crate::{Credential, LeafError, RecursiveError};
12
13impl super::Conversation {
14 fn extract_own_updated_node_from_proposals<'a>(
15 own_index: &LeafNodeIndex,
16 pending_proposals: impl Iterator<Item = &'a QueuedProposal>,
17 ) -> Option<&'a LeafNode> {
18 pending_proposals
19 .filter_map(|proposal| {
20 if let Sender::Member(index) = proposal.sender()
21 && index == own_index
22 && let Proposal::Update(update_proposal) = proposal.proposal()
23 {
24 Some(update_proposal.leaf_node())
25 } else {
26 None
27 }
28 })
29 .last()
30 }
31
32 pub(crate) async fn find_current_credential(&self) -> Result<Arc<Credential>> {
34 let group = self.group().await;
37 let own_leaf =
38 Self::extract_own_updated_node_from_proposals(&group.own_leaf_index(), group.pending_proposals())
39 .or_else(|| group.own_leaf())
40 .ok_or(LeafError::InternalMlsError)?;
41 let credential = self
42 .session
43 .find_credential_by_public_key(own_leaf.signature_key())
44 .await
45 .map_err(RecursiveError::mls_client("finding current credential"))?;
46 Ok(credential)
47 }
48
49 pub async fn members(&self) -> HashMap<Vec<u8>, MlsCredential> {
51 self.group().await.members().fold(HashMap::new(), |mut acc, kp| {
55 let credential = kp.credential;
56 let id = credential.identity().to_vec();
57 acc.entry(id).or_insert(credential);
58 acc
59 })
60 }
61
62 pub async fn members_with_key(&self) -> HashMap<Vec<u8>, CredentialWithKey> {
64 self.group().await.members().fold(HashMap::new(), |mut acc, kp| {
65 let credential = kp.credential;
66 let id = credential.identity().to_vec();
67 let signature_key = SignaturePublicKey::from(kp.signature_key);
68 let credential = CredentialWithKey {
69 credential,
70 signature_key,
71 };
72 acc.entry(id).or_insert(credential);
73 acc
74 })
75 }
76
77 pub(crate) async fn own_mls_credential(&self) -> Result<MlsCredential> {
78 let credential = self
79 .group()
80 .await
81 .own_leaf_node()
82 .ok_or(Error::MlsGroupInvalidState("own_leaf_node not present in group"))?
83 .credential()
84 .to_owned();
85 Ok(credential)
86 }
87}