pub struct Group<C>where
C: ClientConfig,{ /* private fields */ }
Expand description
An MLS end-to-end encrypted group.
§Group Evolution
MLS Groups are evolved via a propose-then-commit system. Each group state
produced by a commit is called an epoch and can produce and consume
application, proposal, and commit messages. A commit is used
to advance to the next epoch by applying existing proposals sent in
the current epoch by-reference along with an optional set of proposals
that are included by-value using a CommitBuilder
.
Implementations§
source§impl<C> Group<C>where
C: ClientConfig + Clone,
impl<C> Group<C>where
C: ClientConfig + Clone,
sourcepub fn commit(
&mut self,
authenticated_data: Vec<u8>,
) -> Result<CommitOutput, MlsError>
pub fn commit( &mut self, authenticated_data: Vec<u8>, ) -> Result<CommitOutput, MlsError>
Perform a commit of received proposals.
This function is the equivalent of Group::commit_builder
immediately
followed by CommitBuilder::build
. Any received proposals since the
last commit will be included in the resulting message by-reference.
Data provided in the authenticated_data
field will be placed into
the resulting commit message unencrypted.
§Pending Commits
When a commit is created, it is not applied immediately in order to allow for the resolution of conflicts when multiple members of a group attempt to make commits at the same time. For example, a central relay can be used to decide which commit should be accepted by the group by determining a consistent view of commit packet order for all clients.
Pending commits are stored internally as part of the group’s state so they do not need to be tracked outside of this library. Any commit message that is processed before calling Group::apply_pending_commit will clear the currently pending commit.
§Empty Commits
Sending a commit that contains no proposals is a valid operation within the MLS protocol. It is useful for providing stronger forward secrecy and post-compromise security, especially for long running groups when group membership does not change often.
§Path Updates
Path updates provide forward secrecy and post-compromise security
within the MLS protocol.
The path_required
option returned by MlsRules::commit_options
controls the ability of a group to send a commit without a path update.
An update path will automatically be sent if there are no proposals
in the commit, or if any proposal other than
Add
,
Psk
,
or ReInit
are part of the commit.
sourcepub fn commit_builder(&mut self) -> CommitBuilder<'_, C>
pub fn commit_builder(&mut self) -> CommitBuilder<'_, C>
Create a new commit builder that can include proposals by-value.
source§impl<C> Group<C>where
C: ClientConfig + Clone,
impl<C> Group<C>where
C: ClientConfig + Clone,
sourcepub fn branch(
&self,
sub_group_id: Vec<u8>,
new_key_packages: Vec<MlsMessage>,
) -> Result<(Group<C>, Vec<MlsMessage>), MlsError>
pub fn branch( &self, sub_group_id: Vec<u8>, new_key_packages: Vec<MlsMessage>, ) -> Result<(Group<C>, Vec<MlsMessage>), MlsError>
Create a sub-group from a subset of the current group members.
Membership within the resulting sub-group is indicated by providing a
key package that produces the same
identity value
as an existing group member. The identity value of each key package
is determined using the
IdentityProvider
that is currently in use by this group instance.
sourcepub fn join_subgroup(
&self,
welcome: &MlsMessage,
tree_data: Option<ExportedTree<'_>>,
) -> Result<(Group<C>, NewMemberInfo), MlsError>
pub fn join_subgroup( &self, welcome: &MlsMessage, tree_data: Option<ExportedTree<'_>>, ) -> Result<(Group<C>, NewMemberInfo), MlsError>
Join a subgroup that was created by Group::branch
.
sourcepub fn get_reinit_client(
self,
new_signer: Option<SignatureSecretKey>,
new_signing_identity: Option<SigningIdentity>,
) -> Result<ReinitClient<C>, MlsError>
pub fn get_reinit_client( self, new_signer: Option<SignatureSecretKey>, new_signing_identity: Option<SigningIdentity>, ) -> Result<ReinitClient<C>, MlsError>
Generate a ReinitClient
that can be used to create or join a new group
that is based on properties defined by a ReInitProposal
committed in a previously accepted commit. This is the only action available
after accepting such a commit. The old group can no longer be used according to the RFC.
If the ReInitProposal
changes the ciphersuite, then new_signer
and new_signer_identity
must be set and match the new ciphersuite, as indicated by
pending_reinit_ciphersuite
of the StateUpdate
outputted after processing the
commit to the reinit proposal. The value of identity
must be the same for new_signing_identity
and the current identity in use by this
group instance.
source§impl<C> Group<C>where
C: ClientConfig + Clone,
impl<C> Group<C>where
C: ClientConfig + Clone,
sourcepub fn write_to_storage(&mut self) -> Result<(), MlsError>
pub fn write_to_storage(&mut self) -> Result<(), MlsError>
Write the current state of the group to the
GroupStorageProvider
that is currently in use by the group.
source§impl<C> Group<C>where
C: ClientConfig + Clone,
impl<C> Group<C>where
C: ClientConfig + Clone,
sourcepub fn current_epoch(&self) -> u64
pub fn current_epoch(&self) -> u64
The current epoch of the group. This value is incremented each
time a Group::commit
message is processed.
sourcepub fn current_member_index(&self) -> u32
pub fn current_member_index(&self) -> u32
Index within the group’s state for the local group instance.
This index corresponds to indexes in content descriptions within
ReceivedMessage
.
sourcepub fn current_member_signing_identity(
&self,
) -> Result<&SigningIdentity, MlsError>
pub fn current_member_signing_identity( &self, ) -> Result<&SigningIdentity, MlsError>
Signing identity currently in use by the local group instance.
sourcepub fn member_at_index(&self, index: u32) -> Option<Member>
pub fn member_at_index(&self, index: u32) -> Option<Member>
Member at a specific index in the group state.
These indexes correspond to indexes in content descriptions within
ReceivedMessage
.
sourcepub fn propose_add(
&mut self,
key_package: MlsMessage,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_add( &mut self, key_package: MlsMessage, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that adds a new member to the group.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_update(
&mut self,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_update( &mut self, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that updates your own public keys.
This proposal is useful for contributing additional forward secrecy
and post-compromise security to the group without having to perform
the necessary computation of a Group::commit
.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_update_with_identity(
&mut self,
signer: SignatureSecretKey,
signing_identity: SigningIdentity,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_update_with_identity( &mut self, signer: SignatureSecretKey, signing_identity: SigningIdentity, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that updates your own public keys as well as your credential.
This proposal is useful for contributing additional forward secrecy
and post-compromise security to the group without having to perform
the necessary computation of a Group::commit
.
Identity updates are allowed by the group by default assuming that the
new identity provided is considered
valid
by and matches the output of the
identity
function of the current
IdentityProvider
.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_remove(
&mut self,
index: u32,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_remove( &mut self, index: u32, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that removes an existing member from the group.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_external_psk(
&mut self,
psk: ExternalPskId,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_external_psk( &mut self, psk: ExternalPskId, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that adds an external pre shared key to the group.
Each group member will need to have the PSK associated with
ExternalPskId
installed within
the PreSharedKeyStorage
in use by this group upon processing a commit that
contains this proposal.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_resumption_psk(
&mut self,
psk_epoch: u64,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_resumption_psk( &mut self, psk_epoch: u64, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that adds a pre shared key from a previous epoch to the current group state.
Each group member will need to have the secret state from psk_epoch
.
In particular, the members who joined between psk_epoch
and the
current epoch cannot process a commit containing this proposal.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_reinit(
&mut self,
group_id: Option<Vec<u8>>,
version: ProtocolVersion,
cipher_suite: CipherSuite,
extensions: ExtensionList,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_reinit( &mut self, group_id: Option<Vec<u8>>, version: ProtocolVersion, cipher_suite: CipherSuite, extensions: ExtensionList, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that requests for this group to be reinitialized.
Once a ReInitProposal
has been sent, another group member can complete reinitialization of
the group by calling Group::get_reinit_client
.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_group_context_extensions(
&mut self,
extensions: ExtensionList,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_group_context_extensions( &mut self, extensions: ExtensionList, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a proposal message that sets extensions stored in the group state.
§Warning
This function does not create a diff that will be applied to the current set of extension that are in use. In order for an existing extension to not be overwritten by this proposal, it must be included in the new set of extensions being proposed.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn propose_custom(
&mut self,
proposal: CustomProposal,
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn propose_custom( &mut self, proposal: CustomProposal, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Create a custom proposal message.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn clear_proposal_cache(&mut self)
pub fn clear_proposal_cache(&mut self)
Delete all sent and received proposals cached for commit.
sourcepub fn encrypt_application_message(
&mut self,
message: &[u8],
authenticated_data: Vec<u8>,
) -> Result<MlsMessage, MlsError>
pub fn encrypt_application_message( &mut self, message: &[u8], authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>
Encrypt an application message using the current group state.
authenticated_data
will be sent unencrypted along with the contents
of the proposal message.
sourcepub fn apply_pending_commit(
&mut self,
) -> Result<CommitMessageDescription, MlsError>
pub fn apply_pending_commit( &mut self, ) -> Result<CommitMessageDescription, MlsError>
Apply a pending commit that was created by Group::commit
or
CommitBuilder::build
.
sourcepub fn has_pending_commit(&self) -> bool
pub fn has_pending_commit(&self) -> bool
Returns true if a commit has been created but not yet applied
with Group::apply_pending_commit
or cleared with Group::clear_pending_commit
sourcepub fn clear_pending_commit(&mut self)
pub fn clear_pending_commit(&mut self)
Clear the currently pending commit.
This function will automatically be called in the event that a
commit message is processed using Group::process_incoming_message
before Group::apply_pending_commit
is called.
sourcepub fn process_incoming_message(
&mut self,
message: MlsMessage,
) -> Result<ReceivedMessage, MlsError>
pub fn process_incoming_message( &mut self, message: MlsMessage, ) -> Result<ReceivedMessage, MlsError>
Process an inbound message for this group.
§Warning
Changes to the group’s state as a result of processing message
will
not be persisted by the
GroupStateStorage
in use by this group until Group::write_to_storage
is called.
sourcepub fn process_incoming_message_with_time(
&mut self,
message: MlsMessage,
time: MlsTime,
) -> Result<ReceivedMessage, MlsError>
pub fn process_incoming_message_with_time( &mut self, message: MlsMessage, time: MlsTime, ) -> Result<ReceivedMessage, MlsError>
Process an inbound message for this group, providing additional context with a message timestamp.
Providing a timestamp is useful when the
IdentityProvider
in use by the group can determine validity based on a timestamp.
For example, this allows for checking X.509 certificate expiration
at the time when message
was received by a server rather than when
a specific client asynchronously received message
§Warning
Changes to the group’s state as a result of processing message
will
not be persisted by the
GroupStateStorage
in use by this group until Group::write_to_storage
is called.
sourcepub fn member_with_identity(&self, identity: &[u8]) -> Result<Member, MlsError>
pub fn member_with_identity(&self, identity: &[u8]) -> Result<Member, MlsError>
Find a group member by identity
This function determines identity by calling the
IdentityProvider
currently in use by the group.
sourcepub fn group_info_message_allowing_ext_commit(
&self,
with_tree_in_extension: bool,
) -> Result<MlsMessage, MlsError>
pub fn group_info_message_allowing_ext_commit( &self, with_tree_in_extension: bool, ) -> Result<MlsMessage, MlsError>
Create a group info message that can be used for external proposals and commits.
The returned GroupInfo
is suitable for one external commit for the current epoch.
If with_tree_in_extension
is set to true, the returned GroupInfo
contains the
ratchet tree and therefore contains all information needed to join the group. Otherwise,
the ratchet tree must be obtained separately, e.g. via
(ExternalClient::export_tree)crate::external_client::ExternalGroup::export_tree.
sourcepub fn group_info_message(
&self,
with_tree_in_extension: bool,
) -> Result<MlsMessage, MlsError>
pub fn group_info_message( &self, with_tree_in_extension: bool, ) -> Result<MlsMessage, MlsError>
Create a group info message that can be used for external proposals.
pub fn group_info_message_internal( &self, initial_extensions: ExtensionList, with_tree_in_extension: bool, ) -> Result<MlsMessage, MlsError>
sourcepub fn context(&self) -> &GroupContext
pub fn context(&self) -> &GroupContext
Get the current group context summarizing various information about the group.
sourcepub fn epoch_authenticator(&self) -> Result<Secret, MlsError>
pub fn epoch_authenticator(&self) -> Result<Secret, MlsError>
Get the epoch_authenticator of the current epoch.
pub fn export_secret( &self, label: &[u8], context: &[u8], len: usize, ) -> Result<Secret, MlsError>
sourcepub fn export_tree(&self) -> ExportedTree<'_>
pub fn export_tree(&self) -> ExportedTree<'_>
Export the current epoch’s ratchet tree in serialized format.
This function is used to provide the current group tree to new members
when the ratchet_tree_extension
is not used according to MlsRules::commit_options
.
sourcepub fn protocol_version(&self) -> ProtocolVersion
pub fn protocol_version(&self) -> ProtocolVersion
Current version of the MLS protocol in use by this group.
sourcepub fn cipher_suite(&self) -> CipherSuite
pub fn cipher_suite(&self) -> CipherSuite
Current cipher suite in use by this group.
sourcepub fn equal_group_state(a: &Group<C>, b: &Group<C>) -> bool
pub fn equal_group_state(a: &Group<C>, b: &Group<C>) -> bool
Determines equality of two different groups internal states. Useful for testing.