From 117ebeaf4b03cf8578b76e74adb13081ecccdc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 29 Jul 2020 12:47:36 +0200 Subject: [PATCH] crypto: Return requests when you want to accept a verification. --- matrix_sdk_base/src/lib.rs | 2 +- matrix_sdk_crypto/src/verification/machine.rs | 59 ++----------- matrix_sdk_crypto/src/verification/mod.rs | 87 +++++++++++++++++-- matrix_sdk_crypto/src/verification/sas.rs | 25 ++++-- 4 files changed, 109 insertions(+), 64 deletions(-) diff --git a/matrix_sdk_base/src/lib.rs b/matrix_sdk_base/src/lib.rs index dc565c34..71844731 100644 --- a/matrix_sdk_base/src/lib.rs +++ b/matrix_sdk_base/src/lib.rs @@ -51,7 +51,7 @@ pub use models::Room; pub use state::{AllRooms, ClientState}; #[cfg(feature = "encryption")] -pub use matrix_sdk_crypto::{Device, TrustState}; +pub use matrix_sdk_crypto::{Device, Sas, TrustState}; #[cfg(feature = "messages")] #[cfg_attr(docsrs, doc(cfg(feature = "messages")))] diff --git a/matrix_sdk_crypto/src/verification/machine.rs b/matrix_sdk_crypto/src/verification/machine.rs index f5439740..be1f81a4 100644 --- a/matrix_sdk_crypto/src/verification/machine.rs +++ b/matrix_sdk_crypto/src/verification/machine.rs @@ -12,23 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::BTreeMap; use std::sync::Arc; use dashmap::DashMap; use matrix_sdk_common::{ - api::r0::to_device::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices}, + api::r0::to_device::send_event_to_device::Request as ToDeviceRequest, events::{ key::verification::start::StartEventContent, AnyToDeviceEvent, AnyToDeviceEventContent, - EventType, }, identifiers::{DeviceId, UserId}, locks::RwLock, - uuid::Uuid, }; -use super::Sas; +use super::{content_to_request, Sas}; use crate::{Account, CryptoStore, CryptoStoreError}; #[derive(Clone, Debug)] @@ -53,35 +50,13 @@ impl VerificationMachine { self.verifications.get(transaction_id).map(|s| s.clone()) } - fn content_to_request( - &self, - recipient: &UserId, - recipient_device: &DeviceId, - content: AnyToDeviceEventContent, - ) -> ToDeviceRequest { - let mut messages = BTreeMap::new(); - let mut user_messages = BTreeMap::new(); - - user_messages.insert( - DeviceIdOrAllDevices::DeviceId(recipient_device.into()), - serde_json::value::to_raw_value(&content).expect("Can't serialize to-device content"), - ); - messages.insert(recipient.clone(), user_messages); - - ToDeviceRequest { - txn_id: Uuid::new_v4().to_string(), - event_type: EventType::KeyVerificationAccept, - messages, - } - } - fn queue_up_content( &self, recipient: &UserId, recipient_device: &DeviceId, content: AnyToDeviceEventContent, ) { - let request = self.content_to_request(recipient, recipient_device, content); + let request = content_to_request(recipient, recipient_device, content); self.outgoing_to_device_messages .insert(request.txn_id.clone(), request); @@ -165,7 +140,7 @@ mod test { }; use super::{Sas, VerificationMachine}; - use crate::verification::test::wrap_any_to_device_content; + use crate::verification::test::{get_content_from_request, wrap_any_to_device_content}; use crate::{store::memorystore::MemoryStore, Account, CryptoStore, Device}; fn alice_id() -> UserId { @@ -222,12 +197,7 @@ mod test { let mut event = alice .accept() - .map(|c| { - wrap_any_to_device_content( - alice.user_id(), - AnyToDeviceEventContent::KeyVerificationAccept(c), - ) - }) + .map(|c| wrap_any_to_device_content(alice.user_id(), get_content_from_request(&c))) .unwrap(); let mut event = bob @@ -247,23 +217,8 @@ mod test { let txn_id = request.txn_id.clone(); - let mut event = wrap_any_to_device_content( - alice.user_id(), - AnyToDeviceEventContent::KeyVerificationKey( - serde_json::from_str( - request - .messages - .values() - .next() - .unwrap() - .values() - .next() - .unwrap() - .get(), - ) - .unwrap(), - ), - ); + let mut event = + wrap_any_to_device_content(alice.user_id(), get_content_from_request(&request)); drop(request); alice_machine.mark_requests_as_sent(&txn_id); diff --git a/matrix_sdk_crypto/src/verification/mod.rs b/matrix_sdk_crypto/src/verification/mod.rs index 27390940..6592115f 100644 --- a/matrix_sdk_crypto/src/verification/mod.rs +++ b/matrix_sdk_crypto/src/verification/mod.rs @@ -17,9 +17,17 @@ use std::convert::TryInto; use olm_rs::sas::OlmSas; -use matrix_sdk_common::api::r0::keys::{AlgorithmAndDeviceId, KeyAlgorithm}; -use matrix_sdk_common::events::{key::verification::mac::MacEventContent, ToDeviceEvent}; -use matrix_sdk_common::identifiers::DeviceId; +use matrix_sdk_common::{ + api::r0::{ + keys::{AlgorithmAndDeviceId, KeyAlgorithm}, + to_device::{send_event_to_device::Request as ToDeviceRequest, DeviceIdOrAllDevices}, + }, + events::{ + key::verification::mac::MacEventContent, AnyToDeviceEventContent, EventType, ToDeviceEvent, + }, + identifiers::{DeviceId, UserId}, + uuid::Uuid, +}; use crate::{Account, Device}; @@ -400,10 +408,45 @@ fn get_decimal(sas: &OlmSas, ids: &SasIds, flow_id: &str, we_started: bool) -> ( (first + 1000, second + 1000, third + 1000) } +pub(crate) fn content_to_request( + recipient: &UserId, + recipient_device: &DeviceId, + content: AnyToDeviceEventContent, +) -> ToDeviceRequest { + let mut messages = BTreeMap::new(); + let mut user_messages = BTreeMap::new(); + + user_messages.insert( + DeviceIdOrAllDevices::DeviceId(recipient_device.into()), + serde_json::value::to_raw_value(&content).expect("Can't serialize to-device content"), + ); + messages.insert(recipient.clone(), user_messages); + + let event_type = match content { + AnyToDeviceEventContent::KeyVerificationAccept(_) => EventType::KeyVerificationAccept, + AnyToDeviceEventContent::KeyVerificationStart(_) => EventType::KeyVerificationStart, + AnyToDeviceEventContent::KeyVerificationKey(_) => EventType::KeyVerificationKey, + AnyToDeviceEventContent::KeyVerificationMac(_) => EventType::KeyVerificationMac, + AnyToDeviceEventContent::KeyVerificationCancel(_) => EventType::KeyVerificationCancel, + _ => unreachable!(), + }; + + ToDeviceRequest { + txn_id: Uuid::new_v4().to_string(), + event_type, + messages, + } +} + #[cfg(test)] mod test { - use matrix_sdk_common::events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent}; - use matrix_sdk_common::identifiers::UserId; + use serde_json::Value; + + use matrix_sdk_common::{ + api::r0::to_device::send_event_to_device::Request as ToDeviceRequest, + events::{AnyToDeviceEvent, AnyToDeviceEventContent, EventType, ToDeviceEvent}, + identifiers::UserId, + }; pub(crate) fn wrap_any_to_device_content( sender: &UserId, @@ -438,4 +481,38 @@ mod test { _ => unreachable!(), } } + + pub(crate) fn get_content_from_request(request: &ToDeviceRequest) -> AnyToDeviceEventContent { + let json: Value = serde_json::from_str( + request + .messages + .values() + .next() + .unwrap() + .values() + .next() + .unwrap() + .get(), + ) + .unwrap(); + + match request.event_type { + EventType::KeyVerificationStart => { + AnyToDeviceEventContent::KeyVerificationStart(serde_json::from_value(json).unwrap()) + } + EventType::KeyVerificationKey => { + AnyToDeviceEventContent::KeyVerificationKey(serde_json::from_value(json).unwrap()) + } + EventType::KeyVerificationAccept => AnyToDeviceEventContent::KeyVerificationAccept( + serde_json::from_value(json).unwrap(), + ), + EventType::KeyVerificationMac => { + AnyToDeviceEventContent::KeyVerificationMac(serde_json::from_value(json).unwrap()) + } + EventType::KeyVerificationCancel => AnyToDeviceEventContent::KeyVerificationCancel( + serde_json::from_value(json).unwrap(), + ), + _ => unreachable!(), + } + } } diff --git a/matrix_sdk_crypto/src/verification/sas.rs b/matrix_sdk_crypto/src/verification/sas.rs index 0ed3fb1a..35da093b 100644 --- a/matrix_sdk_crypto/src/verification/sas.rs +++ b/matrix_sdk_crypto/src/verification/sas.rs @@ -20,6 +20,7 @@ use std::{ use olm_rs::{sas::OlmSas, utility::OlmUtility}; use matrix_sdk_common::{ + api::r0::to_device::send_event_to_device::Request as ToDeviceRequest, events::{ key::verification::{ accept::AcceptEventContent, @@ -36,7 +37,9 @@ use matrix_sdk_common::{ uuid::Uuid, }; -use super::{get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds}; +use super::{ + content_to_request, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds, +}; use crate::{Account, Device}; #[derive(Clone, Debug)] @@ -136,8 +139,11 @@ impl Sas { /// /// This does nothing if the verification was already accepted, otherwise it /// returns an `AcceptEventContent` that needs to be sent out. - pub fn accept(&self) -> Option { - self.inner.lock().unwrap().accept() + pub fn accept(&self) -> Option { + self.inner.lock().unwrap().accept().map(|c| { + let content = AnyToDeviceEventContent::KeyVerificationAccept(c); + self.content_to_request(content) + }) } /// Confirm the Sas verification. @@ -197,6 +203,10 @@ impl Sas { pub(crate) fn verified_devices(&self) -> Option>>> { self.inner.lock().unwrap().verified_devices() } + + pub(crate) fn content_to_request(&self, content: AnyToDeviceEventContent) -> ToDeviceRequest { + content_to_request(self.other_user_id(), self.other_device_id(), content) + } } #[derive(Clone, Debug)] @@ -1053,7 +1063,7 @@ impl SasState { mod test { use std::convert::TryFrom; - use crate::verification::test::wrap_any_to_device_content; + use crate::verification::test::{get_content_from_request, wrap_any_to_device_content}; use crate::{Account, Device}; use matrix_sdk_common::events::{AnyToDeviceEvent, EventContent, ToDeviceEvent}; use matrix_sdk_common::identifiers::{DeviceId, UserId}; @@ -1178,9 +1188,12 @@ mod test { let event = wrap_to_device_event(alice.user_id(), content); let bob = Sas::from_start_event(bob, alice_device, &event).unwrap(); - let event = wrap_to_device_event(bob.user_id(), bob.accept().unwrap()); + let mut event = wrap_any_to_device_content( + bob.user_id(), + get_content_from_request(&bob.accept().unwrap()), + ); - let content = alice.receive_event(&mut AnyToDeviceEvent::KeyVerificationAccept(event)); + let content = alice.receive_event(&mut event); assert!(!alice.can_be_presented()); assert!(!bob.can_be_presented());