From 1c72472706ebcbc8da63fe73076b909a5dbf8ea0 Mon Sep 17 00:00:00 2001 From: ftilde Date: Sat, 18 Dec 2021 22:41:20 +0100 Subject: [PATCH] Send Done message when confirming in MacReceived state Being in MacReceived state means that the other party has confirmed that emojis/numbers match and the sent mac messages has been successfully checked. When now confirming ourselves this means that the verification was successful and thus the Done message can be sent to the other party. --- crates/matrix-sdk-crypto/src/machine.rs | 20 +++----- .../src/verification/machine.rs | 8 +++- .../src/verification/sas/inner_sas.rs | 12 ++--- .../src/verification/sas/mod.rs | 47 +++++++++++-------- .../src/encryption/verification/sas.rs | 4 +- 5 files changed, 47 insertions(+), 44 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index d25015877..60659b333 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -2147,25 +2147,17 @@ pub(crate) mod test { assert_eq!(alice_sas.emoji(), bob_sas.emoji()); assert_eq!(alice_sas.decimals(), bob_sas.decimals()); - let event = bob_sas - .confirm() - .await - .unwrap() - .0 - .map(|r| request_to_event(bob.user_id(), &r)) - .unwrap(); + let contents = bob_sas.confirm().await.unwrap().0; + assert!(contents.len() == 1); + let event = request_to_event(bob.user_id(), &contents[0]); alice.handle_verification_event(&event).await; assert!(!alice_sas.is_done()); assert!(!bob_sas.is_done()); - let event = alice_sas - .confirm() - .await - .unwrap() - .0 - .map(|r| request_to_event(alice.user_id(), &r)) - .unwrap(); + let contents = alice_sas.confirm().await.unwrap().0; + assert!(contents.len() == 1); + let event = request_to_event(alice.user_id(), &contents[0]); assert!(alice_sas.is_done()); assert!(bob_device.verified()); diff --git a/crates/matrix-sdk-crypto/src/verification/machine.rs b/crates/matrix-sdk-crypto/src/verification/machine.rs index 6a29d9f90..4ec6d6269 100644 --- a/crates/matrix-sdk-crypto/src/verification/machine.rs +++ b/crates/matrix-sdk-crypto/src/verification/machine.rs @@ -642,12 +642,16 @@ mod test { assert!(bob.emoji().is_some()); assert_eq!(alice.emoji(), bob.emoji()); - let request = alice.confirm().await.unwrap().0.unwrap(); + let mut requests = alice.confirm().await.unwrap().0; + assert!(requests.len() == 1); + let request = requests.pop().unwrap(); let content = OutgoingContent::try_from(request).unwrap(); let content = MacContent::try_from(&content).unwrap().into(); bob.receive_any_event(alice.user_id(), &content); - let request = bob.confirm().await.unwrap().0.unwrap(); + let mut requests = bob.confirm().await.unwrap().0; + assert!(requests.len() == 1); + let request = requests.pop().unwrap(); let content = OutgoingContent::try_from(request).unwrap(); let content = MacContent::try_from(&content).unwrap().into(); alice.receive_any_event(bob.user_id(), &content); diff --git a/crates/matrix-sdk-crypto/src/verification/sas/inner_sas.rs b/crates/matrix-sdk-crypto/src/verification/sas/inner_sas.rs index 27cbbd9e6..b7e9258c3 100644 --- a/crates/matrix-sdk-crypto/src/verification/sas/inner_sas.rs +++ b/crates/matrix-sdk-crypto/src/verification/sas/inner_sas.rs @@ -228,27 +228,27 @@ impl InnerSas { (InnerSas::Cancelled(sas), Some(content)) } - pub fn confirm(self) -> (InnerSas, Option) { + pub fn confirm(self) -> (InnerSas, Vec) { match self { InnerSas::KeyReceived(s) => { let sas = s.confirm(); let content = sas.as_content(); - (InnerSas::Confirmed(sas), Some(content)) + (InnerSas::Confirmed(sas), vec![content]) } InnerSas::MacReceived(s) => { if s.started_from_request { let sas = s.confirm_and_wait_for_done(); - let content = sas.as_content(); + let contents = vec![sas.as_content(), sas.done_content()]; - (InnerSas::WaitingForDone(sas), Some(content)) + (InnerSas::WaitingForDone(sas), contents) } else { let sas = s.confirm(); let content = sas.as_content(); - (InnerSas::Done(sas), Some(content)) + (InnerSas::Done(sas), vec![content]) } } - _ => (self, None), + _ => (self, Vec::new()), } } diff --git a/crates/matrix-sdk-crypto/src/verification/sas/mod.rs b/crates/matrix-sdk-crypto/src/verification/sas/mod.rs index f8391f80d..15cdb24f5 100644 --- a/crates/matrix-sdk-crypto/src/verification/sas/mod.rs +++ b/crates/matrix-sdk-crypto/src/verification/sas/mod.rs @@ -355,27 +355,28 @@ impl Sas { /// the server. pub async fn confirm( &self, - ) -> Result< - (Option, Option), - CryptoStoreError, - > { - let (content, done) = { + ) -> Result<(Vec, Option), CryptoStoreError> + { + let (contents, done) = { let mut guard = self.inner.lock().unwrap(); let sas: InnerSas = (*guard).clone(); - let (sas, content) = sas.confirm(); + let (sas, contents) = sas.confirm(); *guard = sas; - (content, guard.is_done()) + (contents, guard.is_done()) }; - let mac_request = content.map(|c| match c { - OutgoingContent::ToDevice(c) => self.content_to_request(c).into(), - OutgoingContent::Room(r, c) => { - RoomMessageRequest { room_id: r, txn_id: Uuid::new_v4(), content: c }.into() - } - }); + let mac_requests = contents + .into_iter() + .map(|c| match c { + OutgoingContent::ToDevice(c) => self.content_to_request(c).into(), + OutgoingContent::Room(r, c) => { + RoomMessageRequest { room_id: r, txn_id: Uuid::new_v4(), content: c }.into() + } + }) + .collect::>(); - if mac_request.is_some() { + if !mac_requests.is_empty() { trace!( user_id = self.other_user_id().as_str(), device_id = self.other_device_id().as_str(), @@ -385,12 +386,14 @@ impl Sas { if done { match self.mark_as_done().await? { - VerificationResult::Cancel(c) => Ok((self.cancel_with_code(c), None)), - VerificationResult::Ok => Ok((mac_request, None)), - VerificationResult::SignatureUpload(r) => Ok((mac_request, Some(r))), + VerificationResult::Cancel(c) => { + Ok((self.cancel_with_code(c).into_iter().collect(), None)) + } + VerificationResult::Ok => Ok((mac_requests, None)), + VerificationResult::SignatureUpload(r) => Ok((mac_requests, Some(r))), } } else { - Ok((mac_request, None)) + Ok((mac_requests, None)) } } @@ -650,12 +653,16 @@ mod test { assert_eq!(alice.emoji().unwrap(), bob.emoji().unwrap()); assert_eq!(alice.decimals().unwrap(), bob.decimals().unwrap()); - let request = alice.confirm().await.unwrap().0.unwrap(); + let mut requests = alice.confirm().await.unwrap().0; + assert!(requests.len() == 1); + let request = requests.pop().unwrap(); let content = OutgoingContent::try_from(request).unwrap(); let content = MacContent::try_from(&content).unwrap(); bob.receive_any_event(alice.user_id(), &content.into()); - let request = bob.confirm().await.unwrap().0.unwrap(); + let mut requests = bob.confirm().await.unwrap().0; + assert!(requests.len() == 1); + let request = requests.pop().unwrap(); let content = OutgoingContent::try_from(request).unwrap(); let content = MacContent::try_from(&content).unwrap(); alice.receive_any_event(bob.user_id(), &content.into()); diff --git a/crates/matrix-sdk/src/encryption/verification/sas.rs b/crates/matrix-sdk/src/encryption/verification/sas.rs index ef4791f1e..b87db5a93 100644 --- a/crates/matrix-sdk/src/encryption/verification/sas.rs +++ b/crates/matrix-sdk/src/encryption/verification/sas.rs @@ -76,9 +76,9 @@ impl SasVerification { /// Confirm that the short auth strings match on both sides. pub async fn confirm(&self) -> Result<()> { - let (request, signature) = self.inner.confirm().await?; + let (requests, signature) = self.inner.confirm().await?; - if let Some(request) = request { + for request in requests { self.client.send_verification_request(request).await?; }