openmls/group/mls_group/
targeted_messages.rs1use openmls_traits::signatures::Signer;
2
3use crate::{
4 binary_tree::array_representation::LeafNodeIndex,
5 framing::MlsMessageOut,
6 storage::OpenMlsProvider,
7 targeted_messages::{
8 self, CreateTargetedMessageError, ProcessTargetedMessageError, ProcessedTargetedMessage,
9 TargetedMessageGroupContext, TargetedMessageIn,
10 },
11};
12
13use super::*;
14
15impl MlsGroup {
16 pub fn create_targeted_message<Provider: OpenMlsProvider>(
23 &mut self,
24 provider: &Provider,
25 signer: &impl Signer,
26 recipient_leaf_index: LeafNodeIndex,
27 application_data: &[u8],
28 ) -> Result<MlsMessageOut, CreateTargetedMessageError> {
29 if !self.is_active() {
30 return Err(CreateTargetedMessageError::GroupNotActive);
31 }
32
33 let targeted_msg = {
34 let recipient_leaf = self
35 .public_group()
36 .leaf(recipient_leaf_index)
37 .ok_or(CreateTargetedMessageError::RecipientNotFound)?;
38 let recipient_encryption_key = recipient_leaf.encryption_key();
39
40 let ctx = TargetedMessageGroupContext {
41 ciphersuite: self.ciphersuite(),
42 group_id: self.group_id(),
43 epoch: self.context().epoch(),
44 exporter_secret: self.group_epoch_secrets().exporter_secret(),
45 };
46
47 targeted_messages::create_targeted_message(
48 provider.crypto(),
49 signer,
50 &ctx,
51 self.own_leaf_index(),
52 recipient_leaf_index,
53 recipient_encryption_key,
54 &self.aad,
55 application_data,
56 self.configuration().padding_size(),
57 )?
58 };
59 self.reset_aad();
60 Ok(targeted_msg.into())
61 }
62
63 #[openmls_traits::maybe_async]
67 pub async fn process_targeted_message<Provider: OpenMlsProvider>(
68 &self,
69 provider: &Provider,
70 message: &TargetedMessageIn,
71 ) -> Result<ProcessedTargetedMessage, ProcessTargetedMessageError<Provider::StorageError>> {
72 if !self.is_active() {
73 return Err(ProcessTargetedMessageError::GroupNotActive);
74 }
75
76 let own_leaf = self
77 .public_group()
78 .leaf(self.own_leaf_index())
79 .ok_or_else(|| LibraryError::custom("Own leaf node not found in tree"))?;
80
81 let own_encryption_key = own_leaf.encryption_key();
82
83 let epoch_keypairs = self
84 .read_epoch_keypairs(provider.storage())
85 .await
86 .map_err(ProcessTargetedMessageError::StorageError)?;
87
88 let own_keypair = epoch_keypairs
89 .iter()
90 .find(|kp| kp.public_key() == own_encryption_key)
91 .ok_or_else(|| LibraryError::custom("Own encryption private key not found"))?;
92
93 let leaves = self.public_group().treesync().leaves();
94
95 let ctx = TargetedMessageGroupContext {
96 ciphersuite: self.ciphersuite(),
97 group_id: self.group_id(),
98 epoch: self.context().epoch(),
99 exporter_secret: self.group_epoch_secrets().exporter_secret(),
100 };
101
102 targeted_messages::process_targeted_message(
103 provider.crypto(),
104 &ctx,
105 self.own_leaf_index(),
106 own_keypair.private_key(),
107 message,
108 &leaves,
109 )
110 }
111}