openmls/group/mls_group/
updates.rs1use commit_builder::CommitMessageBundle;
2use errors::{ProposeSelfUpdateError, SelfUpdateError};
3use openmls_traits::{signatures::Signer, storage::StorageProvider as _};
4
5use crate::{storage::OpenMlsProvider, treesync::LeafNodeParameters};
6
7use super::*;
8
9impl MlsGroup {
10 pub fn self_update<Provider: OpenMlsProvider>(
24 &mut self,
25 provider: &Provider,
26 signer: &impl Signer,
27 leaf_node_parameters: LeafNodeParameters,
28 ) -> Result<CommitMessageBundle, SelfUpdateError<Provider::StorageError>> {
29 self.is_operational()?;
30
31 let bundle = self
32 .commit_builder()
33 .leaf_node_parameters(leaf_node_parameters)
34 .consume_proposal_store(true)
35 .load_psks(provider.storage())?
36 .build(provider.rand(), provider.crypto(), signer, |_| true)?
37 .stage_commit(provider)?;
38
39 self.reset_aad();
40
41 Ok(bundle)
42 }
43
44 pub fn self_update_with_new_signer<Provider: OpenMlsProvider>(
63 &mut self,
64 provider: &Provider,
65 old_signer: &impl Signer,
66 new_signer: &impl Signer,
67 leaf_node_parameters: LeafNodeParameters,
68 ) -> Result<CommitMessageBundle, SelfUpdateError<Provider::StorageError>> {
69 self.is_operational()?;
70
71 let bundle = self
72 .commit_builder()
73 .leaf_node_parameters(leaf_node_parameters)
74 .consume_proposal_store(true)
75 .load_psks(provider.storage())?
76 .build_with_new_signer(
77 provider.rand(),
78 provider.crypto(),
79 old_signer,
80 new_signer,
81 |_| true,
82 )?
83 .stage_commit(provider)?;
84
85 self.reset_aad();
86
87 Ok(bundle)
88 }
89
90 fn _propose_self_update<Provider: OpenMlsProvider>(
94 &mut self,
95 provider: &Provider,
96 signer: &impl Signer,
97 leaf_node_parmeters: LeafNodeParameters,
98 ) -> Result<AuthenticatedContent, ProposeSelfUpdateError<Provider::StorageError>> {
99 self.is_operational()?;
100
101 let mut own_leaf = self
106 .public_group()
107 .leaf(self.own_leaf_index())
108 .ok_or_else(|| LibraryError::custom("The tree is broken. Couldn't find own leaf."))?
109 .clone();
110
111 own_leaf.update(
112 self.ciphersuite(),
113 provider,
114 signer,
115 self.group_id().clone(),
116 self.own_leaf_index(),
117 leaf_node_parmeters,
118 )?;
119
120 let update_proposal =
121 self.create_update_proposal(self.framing_parameters(), own_leaf.clone(), signer)?;
122
123 provider
124 .storage()
125 .append_own_leaf_node(self.group_id(), &own_leaf)
126 .map_err(ProposeSelfUpdateError::StorageError)?;
127 self.own_leaf_nodes.push(own_leaf);
128
129 Ok(update_proposal)
130 }
131
132 pub fn propose_self_update<Provider: OpenMlsProvider>(
136 &mut self,
137 provider: &Provider,
138 signer: &impl Signer,
139 leaf_node_parameters: LeafNodeParameters,
140 ) -> Result<(MlsMessageOut, ProposalRef), ProposeSelfUpdateError<Provider::StorageError>> {
141 let update_proposal = self._propose_self_update(provider, signer, leaf_node_parameters)?;
142 let proposal = QueuedProposal::from_authenticated_content_by_ref(
143 self.ciphersuite(),
144 provider.crypto(),
145 update_proposal.clone(),
146 )?;
147 let proposal_ref = proposal.proposal_reference();
148 provider
149 .storage()
150 .queue_proposal(self.group_id(), &proposal_ref, &proposal)
151 .map_err(ProposeSelfUpdateError::StorageError)?;
152 self.proposal_store_mut().add(proposal);
153
154 let mls_message = self.content_to_mls_message(update_proposal, provider)?;
155
156 self.reset_aad();
157 Ok((mls_message, proposal_ref))
158 }
159}