Struct mls_rs::group::Group

source ·
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,

source

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.

source

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,

source

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.

source

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.

source

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,

source

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,

source

pub fn current_epoch(&self) -> u64

The current epoch of the group. This value is incremented each time a Group::commit message is processed.

source

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.

source

pub fn current_member_signing_identity( &self, ) -> Result<&SigningIdentity, MlsError>

Signing identity currently in use by the local group instance.

source

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.

source

pub fn group_id(&self) -> &[u8]

Unique identifier for this group.

source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

pub fn clear_proposal_cache(&mut self)

Delete all sent and received proposals cached for commit.

source

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.

source

pub fn apply_pending_commit( &mut self, ) -> Result<CommitMessageDescription, MlsError>

Apply a pending commit that was created by Group::commit or CommitBuilder::build.

source

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

source

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.

source

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.

source

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.

source

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.

source

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.

source

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.

source

pub fn group_info_message_internal( &self, initial_extensions: ExtensionList, with_tree_in_extension: bool, ) -> Result<MlsMessage, MlsError>

source

pub fn context(&self) -> &GroupContext

Get the current group context summarizing various information about the group.

source

pub fn epoch_authenticator(&self) -> Result<Secret, MlsError>

Get the epoch_authenticator of the current epoch.

source

pub fn export_secret( &self, label: &[u8], context: &[u8], len: usize, ) -> Result<Secret, MlsError>

source

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.

source

pub fn protocol_version(&self) -> ProtocolVersion

Current version of the MLS protocol in use by this group.

source

pub fn cipher_suite(&self) -> CipherSuite

Current cipher suite in use by this group.

source

pub fn roster(&self) -> Roster<'_>

Current roster

source

pub fn equal_group_state(a: &Group<C>, b: &Group<C>) -> bool

Determines equality of two different groups internal states. Useful for testing.

Trait Implementations§

source§

impl<C> Clone for Group<C>
where C: ClientConfig + Clone, C::CryptoProvider: Clone, C::GroupStateStorage: Clone, C::KeyPackageRepository: Clone,

source§

fn clone(&self) -> Group<C>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<C> Freeze for Group<C>
where C: Freeze, <<C as ClientConfig>::CryptoProvider as CryptoProvider>::CipherSuiteProvider: Freeze, <C as ClientConfig>::GroupStateStorage: Freeze, <C as ClientConfig>::KeyPackageRepository: Freeze,

§

impl<C> RefUnwindSafe for Group<C>
where C: RefUnwindSafe, <<C as ClientConfig>::CryptoProvider as CryptoProvider>::CipherSuiteProvider: RefUnwindSafe, <C as ClientConfig>::GroupStateStorage: RefUnwindSafe, <C as ClientConfig>::KeyPackageRepository: RefUnwindSafe,

§

impl<C> Send for Group<C>

§

impl<C> Sync for Group<C>

§

impl<C> Unpin for Group<C>
where C: Unpin, <<C as ClientConfig>::CryptoProvider as CryptoProvider>::CipherSuiteProvider: Unpin, <C as ClientConfig>::GroupStateStorage: Unpin, <C as ClientConfig>::KeyPackageRepository: Unpin,

§

impl<C> UnwindSafe for Group<C>
where C: UnwindSafe, <<C as ClientConfig>::CryptoProvider as CryptoProvider>::CipherSuiteProvider: UnwindSafe, <C as ClientConfig>::GroupStateStorage: UnwindSafe, <C as ClientConfig>::KeyPackageRepository: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.