pub struct MlsGroup { /* private fields */ }
Expand description
A MlsGroup
represents an [CoreGroup] with
an easier, high-level API designed to be used in production. The API exposes
high level functions to manage a group by adding/removing members, get the
current member list, etc.
The API is modeled such that it can serve as a direct interface to the
Delivery Service. Functions that modify the public state of the group will
return a Vec<MLSMessage>
that can be sent to the Delivery
Service directly. Conversely, incoming messages from the Delivery Service
can be fed into process_message().
A MlsGroup
has an internal queue of pending proposals that builds up
as new messages are processed. When creating proposals, those messages are
not automatically appended to this queue, instead they have to be processed
again through process_message(). This
allows the Delivery Service to reject them (e.g. if they reference the wrong
epoch).
If incoming messages or applied operations are semantically or syntactically incorrect, an error event will be returned with a corresponding error message and the state of the group will remain unchanged.
The application policy for the group can be enforced by implementing the
validator callback functions and selectively allowing/ disallowing each
operation (see [MlsGroupCallbacks
])
Changes to the group state are dispatched as events through callback
functions (see [MlsGroupCallbacks
]).
An MlsGroup
has an internal state variable determining if it is active or
inactive, as well as if it has a pending commit. See MlsGroupState
for
more information.
Implementations
pub fn create_message(
&mut self,
backend: &impl OpenMlsCryptoProvider,
message: &[u8]
) -> Result<MlsMessageOut, MlsGroupError>
pub fn create_message(
&mut self,
backend: &impl OpenMlsCryptoProvider,
message: &[u8]
) -> Result<MlsMessageOut, MlsGroupError>
Creates an application message.
Returns MlsGroupError::UseAfterEviction(UseAfterEviction::Error)
if the member is no longer part of the group.
Returns MlsGroupError::PendingProposalsExist
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 new(
backend: &impl OpenMlsCryptoProvider,
mls_group_config: &MlsGroupConfig,
group_id: GroupId,
key_package_hash: &[u8]
) -> Result<Self, MlsGroupError>
pub fn new(
backend: &impl OpenMlsCryptoProvider,
mls_group_config: &MlsGroupConfig,
group_id: GroupId,
key_package_hash: &[u8]
) -> Result<Self, MlsGroupError>
Creates a new group from scratch with only the creator as a member. This
function removes the KeyPackageBundle
corresponding to the
key_package_hash
from the backend
. Throws an error if no
KeyPackageBundle
can be found.
pub fn new_from_welcome(
backend: &impl OpenMlsCryptoProvider,
mls_group_config: &MlsGroupConfig,
welcome: Welcome,
ratchet_tree: Option<Vec<Option<Node>>>
) -> Result<Self, MlsGroupError>
pub fn new_from_welcome(
backend: &impl OpenMlsCryptoProvider,
mls_group_config: &MlsGroupConfig,
welcome: Welcome,
ratchet_tree: Option<Vec<Option<Node>>>
) -> Result<Self, MlsGroupError>
Creates a new group from a Welcome
message
pub fn join_by_external_commit(
backend: &impl OpenMlsCryptoProvider,
tree_option: Option<&[Option<Node>]>,
verifiable_public_group_state: VerifiablePublicGroupState,
mls_group_config: &MlsGroupConfig,
aad: &[u8],
credential_bundle: &CredentialBundle,
proposal_store: ProposalStore
) -> Result<(Self, MlsMessageOut), MlsGroupError>
pub fn join_by_external_commit(
backend: &impl OpenMlsCryptoProvider,
tree_option: Option<&[Option<Node>]>,
verifiable_public_group_state: VerifiablePublicGroupState,
mls_group_config: &MlsGroupConfig,
aad: &[u8],
credential_bundle: &CredentialBundle,
proposal_store: ProposalStore
) -> Result<(Self, MlsMessageOut), MlsGroupError>
Join an existing group through an External Commit.
The resulting MlsGroup
instance starts off with a pending
commit (the external commit, which adds this client to the group).
Merging this commit is necessary for this MlsGroup
instance to
function properly, as, for example, this client is not yet part of the
tree. As a result, it is not possible to clear the pending commit. If
the external commit was rejected due to an epoch change, the
MlsGroup
instance has to be discarded and a new one has to be
created using this function based on the latest ratchet_tree
and
public group state. For more information on the external init process,
please see Section 11.2.1 in the MLS specification.
pub fn export_secret(
&self,
backend: &impl OpenMlsCryptoProvider,
label: &str,
context: &[u8],
key_length: usize
) -> Result<Vec<u8>, MlsGroupError>
pub fn export_secret(
&self,
backend: &impl OpenMlsCryptoProvider,
label: &str,
context: &[u8],
key_length: usize
) -> Result<Vec<u8>, MlsGroupError>
Exports a secret from the current epoch
Returns the authentication secret
Returns a resumption secret for a given epoch. If no resumption secret
is available None
is returned.
pub fn export_public_group_state(
&self,
backend: &impl OpenMlsCryptoProvider
) -> Result<PublicGroupState, MlsGroupError>
pub fn export_public_group_state(
&self,
backend: &impl OpenMlsCryptoProvider
) -> Result<PublicGroupState, MlsGroupError>
Exports the public group state.
pub fn add_members(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_packages: &[KeyPackage]
) -> Result<(MlsMessageOut, Welcome), MlsGroupError>
pub fn add_members(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_packages: &[KeyPackage]
) -> Result<(MlsMessageOut, Welcome), MlsGroupError>
Adds members to the group
New members are added by providing a KeyPackage
for each member.
This operation results in a Commit with a path
, i.e. it includes an
update of the committer’s leaf KeyPackage.
If successful, it returns a tuple of MlsMessageOut and Welcome.
Returns an error if there is a pending commit.
pub fn remove_members(
&mut self,
backend: &impl OpenMlsCryptoProvider,
members: &[KeyPackageRef]
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
pub fn remove_members(
&mut self,
backend: &impl OpenMlsCryptoProvider,
members: &[KeyPackageRef]
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
Removes members from the group
Members are removed by providing the index of their leaf in the tree.
If successful, it returns a tuple of MlsMessageOut
and an optional Welcome
.
The Welcome is Some when the queue of pending proposals contained add proposals
Returns an error if there is a pending commit.
pub fn propose_add_member(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package: &KeyPackage
) -> Result<MlsMessageOut, MlsGroupError>
pub fn propose_add_member(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package: &KeyPackage
) -> Result<MlsMessageOut, MlsGroupError>
Creates proposals to add members to the group
Returns an error if there is a pending commit.
pub fn propose_remove_member(
&mut self,
backend: &impl OpenMlsCryptoProvider,
member: &KeyPackageRef
) -> Result<MlsMessageOut, MlsGroupError>
pub fn propose_remove_member(
&mut self,
backend: &impl OpenMlsCryptoProvider,
member: &KeyPackageRef
) -> Result<MlsMessageOut, MlsGroupError>
Creates proposals to remove members from the group
Returns an error if there is a pending commit.
pub fn leave_group(
&mut self,
backend: &impl OpenMlsCryptoProvider
) -> Result<MlsMessageOut, MlsGroupError>
pub fn leave_group(
&mut self,
backend: &impl OpenMlsCryptoProvider
) -> Result<MlsMessageOut, MlsGroupError>
Leave the group
Returns an error if there is a pending commit.
Gets a list of KeyPackage
s of the current group members.
pub fn parse_message(
&mut self,
message: MlsMessageIn,
backend: &impl OpenMlsCryptoProvider
) -> Result<UnverifiedMessage, MlsGroupError>
pub fn parse_message(
&mut self,
message: MlsMessageIn,
backend: &impl OpenMlsCryptoProvider
) -> Result<UnverifiedMessage, MlsGroupError>
This function is used to parse messages from the DS. It checks for syntactic errors and makes some semantic checks as well. If the input is a [MlsCiphertext] message, it will be decrypted. Returns an UnverifiedMessage that can be inspected and later processed in [self::process_unverified_message()].
pub fn process_unverified_message(
&mut self,
unverified_message: UnverifiedMessage,
signature_key: Option<&SignaturePublicKey>,
backend: &impl OpenMlsCryptoProvider
) -> Result<ProcessedMessage, MlsGroupError>
pub fn process_unverified_message(
&mut self,
unverified_message: UnverifiedMessage,
signature_key: Option<&SignaturePublicKey>,
backend: &impl OpenMlsCryptoProvider
) -> Result<ProcessedMessage, MlsGroupError>
This processing function does most of the semantic verifications. It returns a ProcessedMessage enum.
Stores a standalone proposal in the internal ProposalStore
pub fn commit_to_pending_proposals(
&mut self,
backend: &impl OpenMlsCryptoProvider
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
pub fn commit_to_pending_proposals(
&mut self,
backend: &impl OpenMlsCryptoProvider
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
Create a Commit message that covers the pending proposals that are currently stored in the group’s ProposalStore.
Returns an error if there is a pending commit.
pub fn merge_staged_commit(
&mut self,
staged_commit: StagedCommit
) -> Result<(), MlsGroupError>
pub fn merge_staged_commit(
&mut self,
staged_commit: StagedCommit
) -> Result<(), MlsGroupError>
Merge a StagedCommit into the group after inspection. As this advances the epoch of the group, it also clears any pending commits.
Merges the pending StagedCommit
and, if the merge was successful,
clears the field by setting it to None
.
pub fn self_update(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package_bundle_option: Option<KeyPackageBundle>
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
pub fn self_update(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package_bundle_option: Option<KeyPackageBundle>
) -> Result<(MlsMessageOut, Option<Welcome>), MlsGroupError>
Updates the own leaf node
A KeyPackageBundle
can optionally
be provided. If not, a new one will be created on the fly.
If successful, it returns a tuple of MlsMessageOut
and an optional Welcome
.
The Welcome is Some when the queue of pending proposals contained add proposals.
Returns an error if there is a pending commit.
pub fn propose_self_update(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package_bundle_option: Option<KeyPackageBundle>
) -> Result<MlsMessageOut, MlsGroupError>
pub fn propose_self_update(
&mut self,
backend: &impl OpenMlsCryptoProvider,
key_package_bundle_option: Option<KeyPackageBundle>
) -> Result<MlsMessageOut, MlsGroupError>
Creates a proposal to update the own leaf node
Gets the configuration
Sets the configuration
Gets the AAD used in the framing
Returns the group’s ciphersuite
Returns whether the own client is still a member of the group or if it was already evicted
Returns own credential. If the group is inactive, it returns a
UseAfterEviction
error.
Get the KeyPackageRef
of the client owning this group.
Return the epoch
Returns an Iterator
over staged proposals.
Returns a reference to the StagedCommit
of the most recently created
commit. If there was no commit created in this epoch, either because
this commit or another commit was merged, it returns None
.
Sets the group_state
to MlsGroupState::Operational
, thus clearing
any potentially pending commits.
Returns an error if the group was created through an external commit and
the resulting external commit has not been merged yet. For more
information, see MlsGroup::join_by_external_commit()
.
Use with caution! This function should only be used if it is clear that the pending commit will not be used in the group. In particular, if a pending commit is later accepted by the group, this client will lack the key material to encrypt or decrypt group messages.
Loads the state from persisted state
Returns true
if the internal state has changed and needs to be persisted and
false
otherwise. Calling [save()] resets the value to false
.
Export the Ratchet Tree