From 54f473929bb38fb7939db64c7065cc3dd061ec04 Mon Sep 17 00:00:00 2001 From: beltram Date: Mon, 24 Jul 2023 17:41:24 +0200 Subject: [PATCH] works --- crypto/src/mls/conversation/merge.rs | 47 ++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/crypto/src/mls/conversation/merge.rs b/crypto/src/mls/conversation/merge.rs index 18be8d346d..0f60c090e9 100644 --- a/crypto/src/mls/conversation/merge.rs +++ b/crypto/src/mls/conversation/merge.rs @@ -11,6 +11,7 @@ //! | 1+ pend. Proposal | ❌ | ✅ | //! +use core_crypto_keystore::entities::MlsEncryptionKeyPair; use openmls::prelude::MlsGroupStateError; use openmls_traits::OpenMlsCryptoProvider; @@ -27,8 +28,19 @@ impl MlsConversation { /// see [MlsCentral::commit_accepted] #[cfg_attr(test, crate::durable)] pub async fn commit_accepted(&mut self, backend: &MlsCryptoProvider) -> CryptoResult<()> { + // openmls stores here all the encryption keypairs used for update proposals.. + let previous_own_leaf_nodes = self.group.own_leaf_nodes.clone(); + self.group.merge_pending_commit(backend).await.map_err(MlsError::from)?; - self.persist_group_when_changed(backend, false).await + self.persist_group_when_changed(backend, false).await?; + + // ..so if there's any, we clear them after the commit is merged + for oln in &previous_own_leaf_nodes { + let ek = oln.encryption_key().as_slice(); + let _ = backend.key_store().remove::(ek).await; + } + + Ok(()) } /// see [MlsCentral::clear_pending_proposal] @@ -79,7 +91,6 @@ impl MlsCentral { /// to be used for the new epoch. /// We can now safely "merge" it (effectively apply the commit to the group) and update it /// in the keystore. The previous can be discarded to respect Forward Secrecy. - #[cfg_attr(test, crate::idempotent)] pub async fn commit_accepted(&mut self, conversation_id: &ConversationId) -> CryptoResult<()> { self.get_conversation(conversation_id) .await? @@ -210,6 +221,38 @@ pub mod tests { ) .await } + + // #[apply(all_cred_cipher)] + // #[wasm_bindgen_test] + #[async_std::test] + pub async fn should_clean_associated_key_material(/*case: TestCase*/) { + let case = TestCase::default(); + run_test_with_client_ids(case.clone(), ["alice"], move |[mut alice_central]| { + Box::pin(async move { + let id = conversation_id(); + alice_central + .new_conversation(id.clone(), case.credential_type, case.cfg.clone()) + .await + .unwrap(); + + let initial_count = alice_central.count_entities().await; + + alice_central.new_update_proposal(&id).await.unwrap(); + let post_proposal_count = alice_central.count_entities().await; + assert_eq!( + post_proposal_count.encryption_keypair, + initial_count.encryption_keypair + 1 + ); + + alice_central.commit_pending_proposals(&id).await.unwrap(); + alice_central.commit_accepted(&id).await.unwrap(); + + let final_count = alice_central.count_entities().await; + assert_eq!(initial_count, final_count); + }) + }) + .await + } } pub mod clear_pending_proposal {