openmls/group/mls_group/application.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
use openmls_traits::signatures::Signer;
use crate::storage::OpenMlsProvider;
use super::{errors::CreateMessageError, *};
impl MlsGroup {
// === Application messages ===
/// Creates an application message.
/// Returns `CreateMessageError::MlsGroupStateError::UseAfterEviction`
/// if the member is no longer part of the group.
/// Returns `CreateMessageError::MlsGroupStateError::PendingProposal` if pending proposals
/// exist. In that case `.process_pending_proposals()` must be called first
/// and incoming messages from the DS must be processed afterwards.
pub fn create_message<Provider: OpenMlsProvider>(
&mut self,
provider: &Provider,
signer: &impl Signer,
message: &[u8],
) -> Result<MlsMessageOut, CreateMessageError> {
if !self.is_active() {
return Err(CreateMessageError::GroupStateError(
MlsGroupStateError::UseAfterEviction,
));
}
if !self.proposal_store().is_empty() {
return Err(CreateMessageError::GroupStateError(
MlsGroupStateError::PendingProposal,
));
}
let authenticated_content = AuthenticatedContent::new_application(
self.own_leaf_index(),
&self.aad,
message,
self.context(),
signer,
)?;
let ciphertext = self
.encrypt(authenticated_content, provider)
// We know the application message is wellformed and we have the key material of the current epoch
.map_err(|_| LibraryError::custom("Malformed plaintext"))?;
self.reset_aad();
Ok(MlsMessageOut::from_private_message(
ciphertext,
self.version(),
))
}
}