Skip to content

Commit ac7f2c9

Browse files
committed
Merge branch 'fix-verification-done-wait'
2 parents 906dcfe + b1501fc commit ac7f2c9

File tree

7 files changed

+243
-53
lines changed

7 files changed

+243
-53
lines changed

crates/matrix-sdk-crypto/src/machine.rs

Lines changed: 175 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,7 @@ pub(crate) mod test {
15681568
event_id,
15691569
events::{
15701570
dummy::ToDeviceDummyEventContent,
1571+
key::verification::VerificationMethod,
15711572
room::{
15721573
encrypted::ToDeviceRoomEncryptedEventContent,
15731574
message::{MessageType, RoomMessageEventContent},
@@ -2143,25 +2144,17 @@ pub(crate) mod test {
21432144
assert_eq!(alice_sas.emoji(), bob_sas.emoji());
21442145
assert_eq!(alice_sas.decimals(), bob_sas.decimals());
21452146

2146-
let event = bob_sas
2147-
.confirm()
2148-
.await
2149-
.unwrap()
2150-
.0
2151-
.map(|r| request_to_event(bob.user_id(), &r))
2152-
.unwrap();
2147+
let contents = bob_sas.confirm().await.unwrap().0;
2148+
assert!(contents.len() == 1);
2149+
let event = request_to_event(bob.user_id(), &contents[0]);
21532150
alice.handle_verification_event(&event).await;
21542151

21552152
assert!(!alice_sas.is_done());
21562153
assert!(!bob_sas.is_done());
21572154

2158-
let event = alice_sas
2159-
.confirm()
2160-
.await
2161-
.unwrap()
2162-
.0
2163-
.map(|r| request_to_event(alice.user_id(), &r))
2164-
.unwrap();
2155+
let contents = alice_sas.confirm().await.unwrap().0;
2156+
assert!(contents.len() == 1);
2157+
let event = request_to_event(alice.user_id(), &contents[0]);
21652158

21662159
assert!(alice_sas.is_done());
21672160
assert!(bob_device.verified());
@@ -2174,4 +2167,172 @@ pub(crate) mod test {
21742167
assert!(bob_sas.is_done());
21752168
assert!(alice_device.verified());
21762169
}
2170+
2171+
#[tokio::test]
2172+
async fn interactive_verification_started_from_request() {
2173+
let (alice, bob) = get_machine_pair_with_setup_sessions().await;
2174+
2175+
// ----------------------------------------------------------------------------
2176+
// On Alice's device:
2177+
let bob_device = alice.get_device(bob.user_id(), bob.device_id()).await.unwrap().unwrap();
2178+
2179+
assert!(!bob_device.verified());
2180+
2181+
// Alice sends a verification request with her desired methods to Bob
2182+
let (alice_ver_req, request) =
2183+
bob_device.request_verification_with_methods(vec![VerificationMethod::SasV1]).await;
2184+
2185+
// ----------------------------------------------------------------------------
2186+
// On Bobs's device:
2187+
let event = request_to_event(alice.user_id(), &request);
2188+
bob.handle_verification_event(&event).await;
2189+
let flow_id = alice_ver_req.flow_id().as_str();
2190+
2191+
let verification_request = bob.get_verification_request(alice.user_id(), flow_id).unwrap();
2192+
2193+
// Bob accepts the request, sending a Ready request
2194+
let accept_request =
2195+
verification_request.accept_with_methods(vec![VerificationMethod::SasV1]).unwrap();
2196+
// And also immediately sends a start request
2197+
let (_, start_request_from_bob) = verification_request.start_sas().await.unwrap().unwrap();
2198+
2199+
// ----------------------------------------------------------------------------
2200+
// On Alice's device:
2201+
2202+
// Alice receives the Ready
2203+
let event = request_to_event(bob.user_id(), &accept_request);
2204+
alice.handle_verification_event(&event).await;
2205+
2206+
let verification_request = alice.get_verification_request(bob.user_id(), flow_id).unwrap();
2207+
2208+
// And also immediately sends a start request
2209+
let (alice_sas, start_request_from_alice) =
2210+
verification_request.start_sas().await.unwrap().unwrap();
2211+
2212+
// Now alice receives Bob's start:
2213+
let event = request_to_event(bob.user_id(), &start_request_from_bob);
2214+
alice.handle_verification_event(&event).await;
2215+
2216+
// Since Alice's user id is lexicographically smaller than Bob's, Alice does not
2217+
// do anything with the request, however.
2218+
assert!(alice.user_id() < bob.user_id());
2219+
2220+
// ----------------------------------------------------------------------------
2221+
// On Bob's device:
2222+
2223+
// Bob receives Alice's start:
2224+
let event = request_to_event(alice.user_id(), &start_request_from_alice);
2225+
bob.handle_verification_event(&event).await;
2226+
2227+
let bob_sas = bob
2228+
.get_verification(alice.user_id(), alice_sas.flow_id().as_str())
2229+
.unwrap()
2230+
.sas_v1()
2231+
.unwrap();
2232+
2233+
assert!(alice_sas.emoji().is_none());
2234+
assert!(bob_sas.emoji().is_none());
2235+
2236+
// ... and accepts it
2237+
let event = bob_sas.accept().map(|r| request_to_event(bob.user_id(), &r)).unwrap();
2238+
2239+
// ----------------------------------------------------------------------------
2240+
// On Alice's device:
2241+
2242+
// Alice receives the Accept request:
2243+
alice.handle_verification_event(&event).await;
2244+
2245+
// Alice sends a key
2246+
let msgs = alice.verification_machine.outgoing_messages();
2247+
assert!(msgs.len() == 1);
2248+
let msg = msgs.first().unwrap();
2249+
let event = outgoing_request_to_event(alice.user_id(), msg);
2250+
alice.verification_machine.mark_request_as_sent(&msg.request_id);
2251+
2252+
// ----------------------------------------------------------------------------
2253+
// On Bob's device:
2254+
2255+
// And bob receive's it:
2256+
bob.handle_verification_event(&event).await;
2257+
2258+
// Now bob sends a key
2259+
let msgs = bob.verification_machine.outgoing_messages();
2260+
assert!(msgs.len() == 1);
2261+
let msg = msgs.first().unwrap();
2262+
let event = outgoing_request_to_event(bob.user_id(), msg);
2263+
bob.verification_machine.mark_request_as_sent(&msg.request_id);
2264+
2265+
// ----------------------------------------------------------------------------
2266+
// On Alice's device:
2267+
2268+
// And alice receives it
2269+
alice.handle_verification_event(&event).await;
2270+
2271+
// As a result, both devices now can show emojis/decimals
2272+
assert!(alice_sas.emoji().is_some());
2273+
assert!(bob_sas.emoji().is_some());
2274+
2275+
// ----------------------------------------------------------------------------
2276+
// On Bob's device:
2277+
2278+
assert_eq!(alice_sas.emoji(), bob_sas.emoji());
2279+
assert_eq!(alice_sas.decimals(), bob_sas.decimals());
2280+
2281+
// Bob first confirms that the emojis match and sends the MAC...
2282+
let contents = bob_sas.confirm().await.unwrap().0;
2283+
assert!(contents.len() == 1);
2284+
let event = request_to_event(bob.user_id(), &contents[0]);
2285+
2286+
// ----------------------------------------------------------------------------
2287+
// On Alice's device:
2288+
2289+
// ...which alice receives
2290+
alice.handle_verification_event(&event).await;
2291+
2292+
assert!(!alice_sas.is_done());
2293+
assert!(!bob_sas.is_done());
2294+
2295+
// Now alice confirms that the emojis match and sends...
2296+
let contents = alice_sas.confirm().await.unwrap().0;
2297+
assert!(contents.len() == 2);
2298+
// ... her own MAC...
2299+
let event_mac = request_to_event(alice.user_id(), &contents[0]);
2300+
// ... and a Done message
2301+
let event_done = request_to_event(alice.user_id(), &contents[1]);
2302+
2303+
// ----------------------------------------------------------------------------
2304+
// On Bob's device:
2305+
2306+
// Bob receives the MAC message
2307+
bob.handle_verification_event(&event_mac).await;
2308+
2309+
// Bob verifies that the MAC is valid and also sends a "done" message.
2310+
let msgs = bob.verification_machine.outgoing_messages();
2311+
eprintln!("{:?}", msgs);
2312+
assert!(msgs.len() == 1);
2313+
let event = msgs.first().map(|r| outgoing_request_to_event(bob.user_id(), r)).unwrap();
2314+
2315+
let alice_device =
2316+
bob.get_device(alice.user_id(), alice.device_id()).await.unwrap().unwrap();
2317+
2318+
assert!(!bob_sas.is_done());
2319+
assert!(!alice_device.verified());
2320+
// And Bob receives the Done message of alice.
2321+
bob.handle_verification_event(&event_done).await;
2322+
2323+
assert!(bob_sas.is_done());
2324+
assert!(alice_device.verified());
2325+
2326+
// ----------------------------------------------------------------------------
2327+
// On Alice's device:
2328+
2329+
assert!(!alice_sas.is_done());
2330+
assert!(!bob_device.verified());
2331+
// Alices receives the done message
2332+
eprintln!("{:?}", event);
2333+
alice.handle_verification_event(&event).await;
2334+
2335+
assert!(alice_sas.is_done());
2336+
assert!(bob_device.verified());
2337+
}
21772338
}

crates/matrix-sdk-crypto/src/verification/machine.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,18 @@ impl VerificationMachine {
471471

472472
if s.is_done() {
473473
self.mark_sas_as_done(s, content).await?;
474+
} else {
475+
// Even if we are not done (yet), there might be content to send
476+
// out, e.g. in the case where we are done with our side of the
477+
// verification process, but the other side has not yet sent their
478+
// "done".
479+
if let Some(content) = content {
480+
self.queue_up_content(
481+
s.other_user_id(),
482+
s.other_device_id(),
483+
content,
484+
);
485+
}
474486
}
475487
} else {
476488
flow_id_mismatch();
@@ -630,12 +642,16 @@ mod test {
630642
assert!(bob.emoji().is_some());
631643
assert_eq!(alice.emoji(), bob.emoji());
632644

633-
let request = alice.confirm().await.unwrap().0.unwrap();
645+
let mut requests = alice.confirm().await.unwrap().0;
646+
assert!(requests.len() == 1);
647+
let request = requests.pop().unwrap();
634648
let content = OutgoingContent::try_from(request).unwrap();
635649
let content = MacContent::try_from(&content).unwrap().into();
636650
bob.receive_any_event(alice.user_id(), &content);
637651

638-
let request = bob.confirm().await.unwrap().0.unwrap();
652+
let mut requests = bob.confirm().await.unwrap().0;
653+
assert!(requests.len() == 1);
654+
let request = requests.pop().unwrap();
639655
let content = OutgoingContent::try_from(request).unwrap();
640656
let content = MacContent::try_from(&content).unwrap().into();
641657
alice.receive_any_event(bob.user_id(), &content);

crates/matrix-sdk-crypto/src/verification/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ use matrix_sdk_common::locks::Mutex;
3131
#[cfg(feature = "qrcode")]
3232
pub use qrcode::{QrVerification, ScanError};
3333
pub use requests::VerificationRequest;
34+
#[cfg(feature = "qrcode")]
35+
use ruma::events::key::verification::done::{
36+
KeyVerificationDoneEventContent, ToDeviceKeyVerificationDoneEventContent,
37+
};
3438
use ruma::{
3539
api::client::r0::keys::upload_signatures::Request as SignatureUploadRequest,
3640
events::{
@@ -39,7 +43,6 @@ use ruma::{
3943
CancelCode, KeyVerificationCancelEventContent,
4044
ToDeviceKeyVerificationCancelEventContent,
4145
},
42-
done::{KeyVerificationDoneEventContent, ToDeviceKeyVerificationDoneEventContent},
4346
Relation,
4447
},
4548
AnyMessageEventContent, AnyToDeviceEventContent,
@@ -243,6 +246,7 @@ pub struct Done {
243246
}
244247

245248
impl Done {
249+
#[cfg(feature = "qrcode")]
246250
pub fn as_content(&self, flow_id: &FlowId) -> OutgoingContent {
247251
match flow_id {
248252
FlowId::ToDevice(t) => AnyToDeviceEventContent::KeyVerificationDone(
@@ -715,6 +719,12 @@ pub(crate) mod test {
715719
let sender = sender.to_owned();
716720

717721
match content {
722+
AnyToDeviceEventContent::KeyVerificationRequest(c) => {
723+
AnyToDeviceEvent::KeyVerificationRequest(ToDeviceEvent { sender, content: c })
724+
}
725+
AnyToDeviceEventContent::KeyVerificationReady(c) => {
726+
AnyToDeviceEvent::KeyVerificationReady(ToDeviceEvent { sender, content: c })
727+
}
718728
AnyToDeviceEventContent::KeyVerificationKey(c) => {
719729
AnyToDeviceEvent::KeyVerificationKey(ToDeviceEvent { sender, content: c })
720730
}
@@ -727,6 +737,9 @@ pub(crate) mod test {
727737
AnyToDeviceEventContent::KeyVerificationMac(c) => {
728738
AnyToDeviceEvent::KeyVerificationMac(ToDeviceEvent { sender, content: c })
729739
}
740+
AnyToDeviceEventContent::KeyVerificationDone(c) => {
741+
AnyToDeviceEvent::KeyVerificationDone(ToDeviceEvent { sender, content: c })
742+
}
730743

731744
_ => unreachable!(),
732745
}

crates/matrix-sdk-crypto/src/verification/sas/inner_sas.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,27 +228,27 @@ impl InnerSas {
228228
(InnerSas::Cancelled(sas), Some(content))
229229
}
230230

231-
pub fn confirm(self) -> (InnerSas, Option<OutgoingContent>) {
231+
pub fn confirm(self) -> (InnerSas, Vec<OutgoingContent>) {
232232
match self {
233233
InnerSas::KeyReceived(s) => {
234234
let sas = s.confirm();
235235
let content = sas.as_content();
236-
(InnerSas::Confirmed(sas), Some(content))
236+
(InnerSas::Confirmed(sas), vec![content])
237237
}
238238
InnerSas::MacReceived(s) => {
239239
if s.started_from_request {
240240
let sas = s.confirm_and_wait_for_done();
241-
let content = sas.as_content();
241+
let contents = vec![sas.as_content(), sas.done_content()];
242242

243-
(InnerSas::WaitingForDone(sas), Some(content))
243+
(InnerSas::WaitingForDone(sas), contents)
244244
} else {
245245
let sas = s.confirm();
246246
let content = sas.as_content();
247247

248-
(InnerSas::Done(sas), Some(content))
248+
(InnerSas::Done(sas), vec![content])
249249
}
250250
}
251-
_ => (self, None),
251+
_ => (self, Vec::new()),
252252
}
253253
}
254254

@@ -335,10 +335,7 @@ impl InnerSas {
335335
},
336336
AnyVerificationContent::Done(c) => match self {
337337
InnerSas::WaitingForDone(s) => match s.into_done(sender, c) {
338-
Ok(s) => {
339-
let content = s.done_content();
340-
(InnerSas::Done(s), Some(content))
341-
}
338+
Ok(s) => (InnerSas::Done(s), None),
342339
Err(s) => {
343340
let content = s.as_content();
344341
(InnerSas::Cancelled(s), Some(content))

0 commit comments

Comments
 (0)