use core_group::create_commit_params::CreateCommitParams;
use openmls_traits::signatures::Signer;
use crate::{messages::group_info::GroupInfo, treesync::LeafNode, versions::ProtocolVersion};
use super::*;
impl MlsGroup {
#[allow(clippy::type_complexity)]
pub fn self_update<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
signer: &impl Signer,
) -> Result<
(MlsMessageOut, Option<MlsMessageOut>, Option<GroupInfo>),
SelfUpdateError<KeyStore::Error>,
> {
self.is_operational()?;
let params = CreateCommitParams::builder()
.framing_parameters(self.framing_parameters())
.proposal_store(&self.proposal_store)
.build();
let create_commit_result = self.group.create_commit(params, backend, signer)?;
let mls_message = self.content_to_mls_message(create_commit_result.commit, backend)?;
self.group_state = MlsGroupState::PendingCommit(Box::new(PendingCommitState::Member(
create_commit_result.staged_commit,
)));
self.flag_state_change();
Ok((
mls_message,
create_commit_result
.welcome_option
.map(|w| MlsMessageOut::from_welcome(w, self.group.version())),
create_commit_result.group_info,
))
}
fn _propose_self_udpate<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
signer: &impl Signer,
leaf_node: Option<LeafNode>,
) -> Result<AuthenticatedContent, ProposeSelfUpdateError<KeyStore::Error>> {
self.is_operational()?;
let mut own_leaf = self
.group
.public_group()
.leaf(self.own_leaf_index())
.ok_or_else(|| LibraryError::custom("The tree is broken. Couldn't find own leaf."))?
.clone();
if let Some(leaf) = leaf_node {
own_leaf.update_and_re_sign(
None,
leaf,
self.group_id().clone(),
self.own_leaf_index(),
signer,
)?
} else {
let keypair = own_leaf.rekey(
self.group_id(),
self.own_leaf_index(),
self.ciphersuite(),
ProtocolVersion::default(), backend,
signer,
)?;
keypair
.write_to_key_store(backend)
.map_err(ProposeSelfUpdateError::KeyStoreError)?;
};
let update_proposal = self.group.create_update_proposal(
self.framing_parameters(),
own_leaf.clone(),
signer,
)?;
self.own_leaf_nodes.push(own_leaf);
Ok(update_proposal)
}
pub fn propose_self_update<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
signer: &impl Signer,
leaf_node: Option<LeafNode>,
) -> Result<(MlsMessageOut, ProposalRef), ProposeSelfUpdateError<KeyStore::Error>> {
let update_proposal = self._propose_self_udpate(backend, signer, leaf_node)?;
let proposal = QueuedProposal::from_authenticated_content_by_ref(
self.ciphersuite(),
backend,
update_proposal.clone(),
)?;
let proposal_ref = proposal.proposal_reference();
self.proposal_store.add(proposal);
let mls_message = self.content_to_mls_message(update_proposal, backend)?;
self.flag_state_change();
Ok((mls_message, proposal_ref))
}
pub fn propose_self_update_by_value<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
signer: &impl Signer,
leaf_node: Option<LeafNode>,
) -> Result<(MlsMessageOut, ProposalRef), ProposeSelfUpdateError<KeyStore::Error>> {
let update_proposal = self._propose_self_udpate(backend, signer, leaf_node)?;
let proposal = QueuedProposal::from_authenticated_content_by_value(
self.ciphersuite(),
backend,
update_proposal.clone(),
)?;
let proposal_ref = proposal.proposal_reference();
self.proposal_store.add(proposal);
let mls_message = self.content_to_mls_message(update_proposal, backend)?;
self.flag_state_change();
Ok((mls_message, proposal_ref))
}
}