Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add update path accessor #77

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions openmls/src/group/core_group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl CoreGroupBuilder {
/// [`OpenMlsCryptoProvider`].
pub(crate) async fn build<KeyStore: OpenMlsKeyStore>(
self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
signer: &impl Signer,
) -> Result<CoreGroup, CoreGroupBuildError<KeyStore::Error>> {
let (public_group_builder, commit_secret, leaf_keypair) =
Expand All @@ -270,7 +270,7 @@ impl CoreGroupBuilder {
.map_err(LibraryError::unexpected_crypto_error)?,
&serialized_group_context,
)
.map_err(LibraryError::unexpected_crypto_error)?;
.map_err(LibraryError::unexpected_crypto_error)?;

// TODO(#1357)
let resumption_psk_store = ResumptionPskStore::new(32);
Expand Down Expand Up @@ -407,7 +407,7 @@ impl CoreGroup {
self.context(),
signer,
)
.map_err(ValidationError::LibraryError)
.map_err(ValidationError::LibraryError)
}

// 11.1.4. PreSharedKey
Expand Down Expand Up @@ -437,7 +437,7 @@ impl CoreGroup {
pub(crate) fn members_support_extensions<'a>(
&self,
extensions: &Extensions,
pending_proposals: impl Iterator<Item = &'a QueuedProposal>,
pending_proposals: impl Iterator<Item=&'a QueuedProposal>,
) -> Result<(), MemberExtensionValidationError> {
let required_extension = extensions
.iter()
Expand Down Expand Up @@ -470,7 +470,7 @@ impl CoreGroup {
&self,
framing_parameters: FramingParameters,
extensions: Extensions,
pending_proposals: impl Iterator<Item = &'a QueuedProposal>,
pending_proposals: impl Iterator<Item=&'a QueuedProposal>,
signer: &impl Signer,
) -> Result<AuthenticatedContent, ProposeGroupContextExtensionError> {
// Ensure that the group supports all the extensions that are wanted.
Expand All @@ -485,7 +485,7 @@ impl CoreGroup {
self.context(),
signer,
)
.map_err(|e| e.into())
.map_err(|e| e.into())
}
/// Create a `ReInit` proposal
pub(crate) fn create_reinit_proposal(
Expand All @@ -512,7 +512,7 @@ impl CoreGroup {
self.context(),
signer,
)
.map_err(|e| e.into())
.map_err(|e| e.into())
}
// Create application message
pub(crate) fn create_application_message(
Expand Down Expand Up @@ -815,7 +815,7 @@ impl CoreGroup {
/// Returns an error if access to the key store fails.
pub(super) async fn store_epoch_keypairs<KeyStore: OpenMlsKeyStore>(
&self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
epoch_encryption_keypair: EpochEncryptionKeyPair,
) -> Result<(), KeyStore::Error> {
let k = EpochKeypairId::new(
Expand All @@ -835,7 +835,7 @@ impl CoreGroup {
/// Returns `None` if access to the key store fails.
pub(super) async fn read_epoch_keypairs<KeyStore: OpenMlsKeyStore>(
&self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
) -> EpochEncryptionKeyPair {
let k = EpochKeypairId::new(
self.group_id(),
Expand All @@ -855,7 +855,7 @@ impl CoreGroup {
/// Returns an error if access to the key store fails.
pub(super) async fn delete_previous_epoch_keypairs<KeyStore: OpenMlsKeyStore>(
&self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
) -> Result<(), KeyStore::Error> {
let k = EpochKeypairId::new(
self.group_id(),
Expand All @@ -871,7 +871,7 @@ impl CoreGroup {
pub(crate) async fn create_commit<KeyStore: OpenMlsKeyStore>(
&self,
mut params: CreateCommitParams<'_>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
signer: &impl Signer,
) -> Result<CreateCommitResult, CreateCommitError<KeyStore::Error>> {
let ciphersuite = self.ciphersuite();
Expand All @@ -890,15 +890,15 @@ impl CoreGroup {
params.inline_proposals(),
self.own_leaf_index(),
)
.map_err(|e| match e {
crate::group::errors::ProposalQueueError::LibraryError(e) => e.into(),
crate::group::errors::ProposalQueueError::ProposalNotFound => {
CreateCommitError::MissingProposal
}
crate::group::errors::ProposalQueueError::SenderError(_) => {
CreateCommitError::WrongProposalSenderType
}
})?;
.map_err(|e| match e {
crate::group::errors::ProposalQueueError::LibraryError(e) => e.into(),
crate::group::errors::ProposalQueueError::ProposalNotFound => {
CreateCommitError::MissingProposal
}
crate::group::errors::ProposalQueueError::SenderError(_) => {
CreateCommitError::WrongProposalSenderType
}
})?;

// TODO: #581 Filter proposals by support
// 11.2:
Expand Down Expand Up @@ -968,7 +968,7 @@ impl CoreGroup {

all_proposals.find_map(|p| {
match p {
Proposal::Update(UpdateProposal{leaf_node}) => Some(leaf_node.clone()),
Proposal::Update(UpdateProposal { leaf_node }) => Some(leaf_node.clone()),
_ => None,
}
})
Expand All @@ -985,7 +985,7 @@ impl CoreGroup {
params.commit_type(),
signer,
params.take_credential_with_key(),
apply_proposals_values.extensions
apply_proposals_values.extensions,
)?
} else {
// If path is not needed, update the group context and return
Expand All @@ -994,6 +994,11 @@ impl CoreGroup {
PathComputationResult::default()
};

let update_path_leaf_node = path_computation_result
.encrypted_path
.as_ref()
.map(|path| path.leaf_node().clone());

// Create commit message
let commit = Commit {
proposals: proposal_reference_list,
Expand Down Expand Up @@ -1023,7 +1028,7 @@ impl CoreGroup {
self.group_epoch_secrets().init_secret(),
&serialized_provisional_group_context,
)
.map_err(LibraryError::unexpected_crypto_error)?;
.map_err(LibraryError::unexpected_crypto_error)?;

// Prepare the PskSecret
let psk_secret = {
Expand All @@ -1032,7 +1037,7 @@ impl CoreGroup {
&self.resumption_psk_store,
&apply_proposals_values.presharedkeys,
)
.await?;
.await?;

PskSecret::new(backend, ciphersuite, psks).await?
};
Expand Down Expand Up @@ -1154,6 +1159,7 @@ impl CoreGroup {
// The committer is not allowed to include their own update
// proposal, so there is no extra keypair to store here.
None,
update_path_leaf_node,
);
let staged_commit_state = match params.commit_type() {
CommitType::Member => StagedCommitState::GroupMember(Box::new(staged_commit_state)),
Expand Down Expand Up @@ -1185,7 +1191,7 @@ impl MlsGroup {
/// re-export
pub async fn delete_previous_epoch_keypairs<KeyStore: OpenMlsKeyStore>(
&self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
) -> Result<(), KeyStore::Error> {
self.group.delete_previous_epoch_keypairs(backend).await
}
Expand Down
51 changes: 37 additions & 14 deletions openmls/src/group/core_group/staged_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ impl CoreGroup {
&init_secret,
serialized_provisional_group_context,
)
.map_err(LibraryError::unexpected_crypto_error)?
.map_err(LibraryError::unexpected_crypto_error)?
} else {
JoinerSecret::new(
backend,
commit_secret,
epoch_secrets.init_secret(),
serialized_provisional_group_context,
)
.map_err(LibraryError::unexpected_crypto_error)?
.map_err(LibraryError::unexpected_crypto_error)?
};

// Prepare the PskSecret
Expand All @@ -61,7 +61,7 @@ impl CoreGroup {
&self.resumption_psk_store,
&apply_proposals_values.presharedkeys,
)
.await?;
.await?;

PskSecret::new(backend, self.ciphersuite(), psks).await?
};
Expand Down Expand Up @@ -151,7 +151,7 @@ impl CoreGroup {
}

// Determine if Commit has a path
let (commit_secret, new_keypairs, new_leaf_keypair_option) =
let (commit_secret, new_keypairs, new_leaf_keypair_option, update_path_leaf_node) =
if let Some(path) = commit.path.clone() {
// Update the public group
// ValSem202: Path must be the right length
Expand Down Expand Up @@ -194,7 +194,14 @@ impl CoreGroup {
debug_assert!(false);
None
};
(commit_secret, new_keypairs, new_leaf_keypair_option)

// Return the leaf node in the update path so the credential can be validated.
// Since the diff has already been updated, this should be the same as the leaf
// at the sender index.
let update_path_leaf_node = Some(path.leaf_node().clone());
debug_assert_eq!(diff.leaf(sender_index), path.leaf_node().into());

(commit_secret, new_keypairs, new_leaf_keypair_option, update_path_leaf_node)
} else {
if apply_proposals_values.path_required {
// ValSem201
Expand All @@ -208,6 +215,7 @@ impl CoreGroup {
CommitSecret::zero_secret(ciphersuite, self.version()),
vec![],
None,
None,
)
};

Expand Down Expand Up @@ -264,6 +272,7 @@ impl CoreGroup {
staged_diff,
new_keypairs,
new_leaf_keypair_option,
update_path_leaf_node,
)));

Ok(StagedCommit::new(proposal_queue, staged_commit_state))
Expand All @@ -276,7 +285,7 @@ impl CoreGroup {
/// might throw a `LibraryError`.
pub(crate) async fn merge_commit<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
staged_commit: StagedCommit,
) -> Result<Option<MessageSecrets>, MergeCommitError<KeyStore::Error>> {
// Get all keypairs from the old epoch, so we can later store the ones
Expand All @@ -300,7 +309,7 @@ impl CoreGroup {

async fn merge_member_commit<KeyStore: OpenMlsKeyStore>(
&mut self,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider = KeyStore>,
backend: &impl OpenMlsCryptoProvider<KeyStoreProvider=KeyStore>,
mut old_epoch_keypairs: EpochEncryptionKeyPair,
mut state: Box<MemberStagedCommitState>,
is_member: bool,
Expand Down Expand Up @@ -343,7 +352,7 @@ impl CoreGroup {
return Err(LibraryError::custom(
"We should have all the private key material we need.",
)
.into());
.into());
}

// Store the relevant keys under the new epoch
Expand Down Expand Up @@ -390,7 +399,7 @@ impl CoreGroup {
leaf_node_keypairs,
backend,
)
.await
.await
}
}

Expand Down Expand Up @@ -419,27 +428,27 @@ impl StagedCommit {
}

/// Returns the Add proposals that are covered by the Commit message as in iterator over [QueuedAddProposal].
pub fn add_proposals(&self) -> impl Iterator<Item = QueuedAddProposal> {
pub fn add_proposals(&self) -> impl Iterator<Item=QueuedAddProposal> {
self.staged_proposal_queue.add_proposals()
}

/// Returns the Remove proposals that are covered by the Commit message as in iterator over [QueuedRemoveProposal].
pub fn remove_proposals(&self) -> impl Iterator<Item = QueuedRemoveProposal> {
pub fn remove_proposals(&self) -> impl Iterator<Item=QueuedRemoveProposal> {
self.staged_proposal_queue.remove_proposals()
}

/// Returns the Update proposals that are covered by the Commit message as in iterator over [QueuedUpdateProposal].
pub fn update_proposals(&self) -> impl Iterator<Item = QueuedUpdateProposal> {
pub fn update_proposals(&self) -> impl Iterator<Item=QueuedUpdateProposal> {
self.staged_proposal_queue.update_proposals()
}

/// Returns the PresharedKey proposals that are covered by the Commit message as in iterator over [QueuedPskProposal].
pub fn psk_proposals(&self) -> impl Iterator<Item = QueuedPskProposal> {
pub fn psk_proposals(&self) -> impl Iterator<Item=QueuedPskProposal> {
self.staged_proposal_queue.psk_proposals()
}

/// Returns an interator over all [`QueuedProposal`]s
pub fn queued_proposals(&self) -> impl Iterator<Item = &QueuedProposal> {
pub fn queued_proposals(&self) -> impl Iterator<Item=&QueuedProposal> {
self.staged_proposal_queue.queued_proposals()
}

Expand Down Expand Up @@ -469,6 +478,17 @@ impl StagedCommit {
StagedCommitState::ExternalMember(diff) => &diff.staged_diff.confirmation_tag,
}
}


/// Returns the leaf node of the (optional) update path.
pub fn get_update_path_leaf_node(&self) -> Option<&LeafNode> {
match self.state {
StagedCommitState::PublicState(_) => None,
StagedCommitState::GroupMember(ref member) | StagedCommitState::ExternalMember(ref member) => {
member.update_path_leaf_node.as_ref()
}
}
}
}

/// This struct is used internally by [StagedCommit] to encapsulate all the modified group state.
Expand All @@ -479,6 +499,7 @@ pub(crate) struct MemberStagedCommitState {
staged_diff: StagedPublicGroupDiff,
new_keypairs: Vec<EncryptionKeyPair>,
maybe_new_leaf_keypair: Option<EncryptionKeyPair>,
update_path_leaf_node: Option<LeafNode>,
}

impl MemberStagedCommitState {
Expand All @@ -488,13 +509,15 @@ impl MemberStagedCommitState {
staged_diff: StagedPublicGroupDiff,
new_keypairs: Vec<EncryptionKeyPair>,
maybe_new_leaf_keypair: Option<EncryptionKeyPair>,
update_path_leaf_node: Option<LeafNode>,
) -> Self {
Self {
group_epoch_secrets,
message_secrets,
staged_diff,
new_keypairs,
maybe_new_leaf_keypair,
update_path_leaf_node,
}
}

Expand Down
Loading