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 pub fn process_targeted_message<Provider: OpenMlsProvider>(
67 &self,
68 provider: &Provider,
69 message: &TargetedMessageIn,
70 ) -> Result<ProcessedTargetedMessage, ProcessTargetedMessageError<Provider::StorageError>> {
71 if !self.is_active() {
72 return Err(ProcessTargetedMessageError::GroupNotActive);
73 }
74
75 let own_leaf = self
76 .public_group()
77 .leaf(self.own_leaf_index())
78 .ok_or_else(|| LibraryError::custom("Own leaf node not found in tree"))?;
79
80 let own_encryption_key = own_leaf.encryption_key();
81
82 let epoch_keypairs = self
83 .read_epoch_keypairs(provider.storage())
84 .map_err(ProcessTargetedMessageError::StorageError)?;
85
86 let own_keypair = epoch_keypairs
87 .iter()
88 .find(|kp| kp.public_key() == own_encryption_key)
89 .ok_or_else(|| LibraryError::custom("Own encryption private key not found"))?;
90
91 let leaves = self.public_group().treesync().leaves();
92
93 let ctx = TargetedMessageGroupContext {
94 ciphersuite: self.ciphersuite(),
95 group_id: self.group_id(),
96 epoch: self.context().epoch(),
97 exporter_secret: self.group_epoch_secrets().exporter_secret(),
98 };
99
100 targeted_messages::process_targeted_message(
101 provider.crypto(),
102 &ctx,
103 self.own_leaf_index(),
104 own_keypair.private_key(),
105 message,
106 &leaves,
107 )
108 }
109}