diff --git a/matrix_qrcode/Cargo.toml b/matrix_qrcode/Cargo.toml index 28edd7d63..3932e4bf1 100644 --- a/matrix_qrcode/Cargo.toml +++ b/matrix_qrcode/Cargo.toml @@ -20,5 +20,5 @@ byteorder = "1.4.3" image = { version = "0.23.14", optional = true } qrcode = { version = "0.12.0", default-features = false } rqrr = { version = "0.3.2" , optional = true } -ruma-identifiers = "0.19.1" +ruma-identifiers = { version = "0.19.3", git = "https://github.com/ruma/ruma", rev = "d73ab8add" } thiserror = "1.0.24" diff --git a/matrix_sdk/Cargo.toml b/matrix_sdk/Cargo.toml index 86c41c064..a4cec562a 100644 --- a/matrix_sdk/Cargo.toml +++ b/matrix_sdk/Cargo.toml @@ -56,6 +56,8 @@ default_features = false [dependencies.ruma] version = "0.1.2" +git = "https://github.com/ruma/ruma" +rev = "d73ab8add" features = ["client-api-c", "compat", "unstable-pre-spec"] [dependencies.tokio-stream] diff --git a/matrix_sdk/examples/emoji_verification.rs b/matrix_sdk/examples/emoji_verification.rs index ac212aec0..60e93b6cf 100644 --- a/matrix_sdk/examples/emoji_verification.rs +++ b/matrix_sdk/examples/emoji_verification.rs @@ -142,7 +142,7 @@ async fn login( if let Some(Verification::SasV1(sas)) = client .get_verification( &e.sender, - e.content.relation.event_id.as_str(), + e.content.relates_to.event_id.as_str(), ) .await { @@ -153,7 +153,7 @@ async fn login( if let Some(Verification::SasV1(sas)) = client .get_verification( &e.sender, - e.content.relation.event_id.as_str(), + e.content.relates_to.event_id.as_str(), ) .await { diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 2dff600b1..21de669f6 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -1786,8 +1786,8 @@ impl Client { request: &ToDeviceRequest, ) -> Result { let txn_id_string = request.txn_id_string(); - let request = RumaToDeviceRequest::new( - request.event_type.clone(), + let request = RumaToDeviceRequest::new_raw( + request.event_type.as_str(), &txn_id_string, request.messages.clone(), ); diff --git a/matrix_sdk/src/event_handler/mod.rs b/matrix_sdk/src/event_handler/mod.rs index 41a086184..666bb7571 100644 --- a/matrix_sdk/src/event_handler/mod.rs +++ b/matrix_sdk/src/event_handler/mod.rs @@ -47,6 +47,7 @@ use ruma::{ GlobalAccountDataEvent, RoomAccountDataEvent, StrippedStateEvent, SyncEphemeralRoomEvent, SyncMessageEvent, SyncStateEvent, }, + serde::Raw, RoomId, }; use serde_json::value::RawValue as RawJsonValue; @@ -89,14 +90,24 @@ impl Handler { self.handle_room_account_data_event(room.clone(), &event).await; } - for event in room_info.state.events.iter().filter_map(|e| e.deserialize().ok()) { - self.handle_state_event(room.clone(), &event).await; + for (raw_event, event) in room_info.state.events.iter().filter_map(|e| { + if let Ok(d) = e.deserialize() { + Some((e, d)) + } else { + None + } + }) { + self.handle_state_event(room.clone(), &event, raw_event).await; } - for event in - room_info.timeline.events.iter().filter_map(|e| e.event.deserialize().ok()) - { - self.handle_timeline_event(room.clone(), &event).await; + for (raw_event, event) in room_info.timeline.events.iter().filter_map(|e| { + if let Ok(d) = e.event.deserialize() { + Some((&e.event, d)) + } else { + None + } + }) { + self.handle_timeline_event(room.clone(), &event, raw_event).await; } } } @@ -109,14 +120,24 @@ impl Handler { self.handle_room_account_data_event(room.clone(), &event).await; } - for event in room_info.state.events.iter().filter_map(|e| e.deserialize().ok()) { - self.handle_state_event(room.clone(), &event).await; + for (raw_event, event) in room_info.state.events.iter().filter_map(|e| { + if let Ok(d) = e.deserialize() { + Some((e, d)) + } else { + None + } + }) { + self.handle_state_event(room.clone(), &event, raw_event).await; } - for event in - room_info.timeline.events.iter().filter_map(|e| e.event.deserialize().ok()) - { - self.handle_timeline_event(room.clone(), &event).await; + for (raw_event, event) in room_info.timeline.events.iter().filter_map(|e| { + if let Ok(d) = e.event.deserialize() { + Some((&e.event, d)) + } else { + None + } + }) { + self.handle_timeline_event(room.clone(), &event, raw_event).await; } } } @@ -144,7 +165,12 @@ impl Handler { } } - async fn handle_timeline_event(&self, room: Room, event: &AnySyncRoomEvent) { + async fn handle_timeline_event( + &self, + room: Room, + event: &AnySyncRoomEvent, + raw_event: &Raw, + ) { match event { AnySyncRoomEvent::State(event) => match event { AnySyncStateEvent::RoomMember(e) => self.on_room_member(room, e).await, @@ -157,10 +183,25 @@ impl Handler { AnySyncStateEvent::RoomPowerLevels(e) => self.on_room_power_levels(room, e).await, AnySyncStateEvent::RoomTombstone(e) => self.on_room_tombstone(room, e).await, AnySyncStateEvent::RoomJoinRules(e) => self.on_room_join_rules(room, e).await, - AnySyncStateEvent::Custom(e) => { - self.on_custom_event(room, &CustomEvent::State(e)).await + AnySyncStateEvent::PolicyRuleRoom(_) + | AnySyncStateEvent::PolicyRuleServer(_) + | AnySyncStateEvent::PolicyRuleUser(_) + | AnySyncStateEvent::RoomCreate(_) + | AnySyncStateEvent::RoomEncryption(_) + | AnySyncStateEvent::RoomGuestAccess(_) + | AnySyncStateEvent::RoomHistoryVisibility(_) + | AnySyncStateEvent::RoomPinnedEvents(_) + | AnySyncStateEvent::RoomServerAcl(_) + | AnySyncStateEvent::RoomThirdPartyInvite(_) + | AnySyncStateEvent::RoomTopic(_) + | AnySyncStateEvent::SpaceChild(_) + | AnySyncStateEvent::SpaceParent(_) => {} + _ => { + if let Ok(e) = raw_event.deserialize_as::>() + { + self.on_custom_event(room, &CustomEvent::State(&e)).await; + } } - _ => {} }, AnySyncRoomEvent::Message(event) => match event { AnySyncMessageEvent::RoomMessage(e) => self.on_room_message(room, e).await, @@ -169,23 +210,40 @@ impl Handler { } AnySyncMessageEvent::RoomRedaction(e) => self.on_room_redaction(room, e).await, AnySyncMessageEvent::Reaction(e) => self.on_room_reaction(room, e).await, - AnySyncMessageEvent::Custom(e) => { - self.on_custom_event(room, &CustomEvent::Message(e)).await - } AnySyncMessageEvent::CallInvite(e) => self.on_room_call_invite(room, e).await, AnySyncMessageEvent::CallAnswer(e) => self.on_room_call_answer(room, e).await, AnySyncMessageEvent::CallCandidates(e) => { self.on_room_call_candidates(room, e).await } AnySyncMessageEvent::CallHangup(e) => self.on_room_call_hangup(room, e).await, - _ => {} + AnySyncMessageEvent::KeyVerificationReady(_) + | AnySyncMessageEvent::KeyVerificationStart(_) + | AnySyncMessageEvent::KeyVerificationCancel(_) + | AnySyncMessageEvent::KeyVerificationAccept(_) + | AnySyncMessageEvent::KeyVerificationKey(_) + | AnySyncMessageEvent::KeyVerificationMac(_) + | AnySyncMessageEvent::KeyVerificationDone(_) + | AnySyncMessageEvent::RoomEncrypted(_) + | AnySyncMessageEvent::Sticker(_) => {} + _ => { + if let Ok(e) = + raw_event.deserialize_as::>() + { + self.on_custom_event(room, &CustomEvent::Message(&e)).await; + } + } }, AnySyncRoomEvent::RedactedState(_event) => {} AnySyncRoomEvent::RedactedMessage(_event) => {} } } - async fn handle_state_event(&self, room: Room, event: &AnySyncStateEvent) { + async fn handle_state_event( + &self, + room: Room, + event: &AnySyncStateEvent, + raw_event: &Raw, + ) { match event { AnySyncStateEvent::RoomMember(member) => self.on_state_member(room, member).await, AnySyncStateEvent::RoomName(name) => self.on_state_name(room, name).await, @@ -202,10 +260,24 @@ impl Handler { // TODO make `on_state_tombstone` method self.on_room_tombstone(room, tomb).await } - AnySyncStateEvent::Custom(custom) => { - self.on_custom_event(room, &CustomEvent::State(custom)).await + AnySyncStateEvent::PolicyRuleRoom(_) + | AnySyncStateEvent::PolicyRuleServer(_) + | AnySyncStateEvent::PolicyRuleUser(_) + | AnySyncStateEvent::RoomCreate(_) + | AnySyncStateEvent::RoomEncryption(_) + | AnySyncStateEvent::RoomGuestAccess(_) + | AnySyncStateEvent::RoomHistoryVisibility(_) + | AnySyncStateEvent::RoomPinnedEvents(_) + | AnySyncStateEvent::RoomServerAcl(_) + | AnySyncStateEvent::RoomThirdPartyInvite(_) + | AnySyncStateEvent::RoomTopic(_) + | AnySyncStateEvent::SpaceChild(_) + | AnySyncStateEvent::SpaceParent(_) => {} + _ => { + if let Ok(e) = raw_event.deserialize_as::>() { + self.on_custom_event(room, &CustomEvent::State(&e)).await; + } } - _ => {} } } diff --git a/matrix_sdk_appservice/Cargo.toml b/matrix_sdk_appservice/Cargo.toml index f14096c23..4a21b3df7 100644 --- a/matrix_sdk_appservice/Cargo.toml +++ b/matrix_sdk_appservice/Cargo.toml @@ -33,6 +33,8 @@ matrix-sdk = { version = "0.2", path = "../matrix_sdk", default-features = false [dependencies.ruma] version = "0.1.2" +git = "https://github.com/ruma/ruma" +rev = "d73ab8add" features = ["client-api-c", "appservice-api-s", "unstable-pre-spec"] [dev-dependencies] diff --git a/matrix_sdk_base/Cargo.toml b/matrix_sdk_base/Cargo.toml index 2adcac7a8..10af93438 100644 --- a/matrix_sdk_base/Cargo.toml +++ b/matrix_sdk_base/Cargo.toml @@ -26,7 +26,7 @@ docs = ["encryption", "sled_cryptostore"] [dependencies] dashmap = "4.0.2" lru = "0.6.5" -ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"] } +ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" } serde = { version = "1.0.122", features = ["rc"] } serde_json = "1.0.61" tracing = "0.1.22" diff --git a/matrix_sdk_common/Cargo.toml b/matrix_sdk_common/Cargo.toml index 4839c98a9..3eb20b6dc 100644 --- a/matrix_sdk_common/Cargo.toml +++ b/matrix_sdk_common/Cargo.toml @@ -13,7 +13,7 @@ version = "0.2.0" [dependencies] async-trait = "0.1.42" instant = { version = "0.1.9", features = ["wasm-bindgen", "now"] } -ruma = { version = "0.1.2", features = ["client-api-c"] } +ruma = { version = "0.1.2", features = ["client-api-c"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" } serde = "1.0.122" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/matrix_sdk_crypto/Cargo.toml b/matrix_sdk_crypto/Cargo.toml index bbad56e7c..cfa3c4dad 100644 --- a/matrix_sdk_crypto/Cargo.toml +++ b/matrix_sdk_crypto/Cargo.toml @@ -22,7 +22,7 @@ docs = ["sled_cryptostore"] [dependencies] matrix-qrcode = { version = "0.1.0", path = "../matrix_qrcode" } matrix-sdk-common = { version = "0.2.0", path = "../matrix_sdk_common" } -ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"] } +ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" } olm-rs = { version = "1.0.0", features = ["serde"] } getrandom = "0.2.2" diff --git a/matrix_sdk_crypto/src/identities/device.rs b/matrix_sdk_crypto/src/identities/device.rs index 0fef3a7a4..f57e62ff8 100644 --- a/matrix_sdk_crypto/src/identities/device.rs +++ b/matrix_sdk_crypto/src/identities/device.rs @@ -25,11 +25,10 @@ use std::{ use atomic::Atomic; use matrix_sdk_common::locks::Mutex; use ruma::{ - api::client::r0::keys::SignedKey, - encryption::DeviceKeys, + encryption::{DeviceKeys, SignedKey}, events::{ forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, - room::encrypted::EncryptedEventContent, EventType, + room::encrypted::EncryptedEventContent, AnyToDeviceEventContent, }, identifiers::{ DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, UserId, @@ -176,15 +175,12 @@ impl Device { /// /// # Arguments /// - /// * `event_type` - The type of the event. - /// /// * `content` - The content of the event that should be encrypted. pub(crate) async fn encrypt( &self, - event_type: EventType, - content: Value, + content: AnyToDeviceEventContent, ) -> OlmResult<(Session, EncryptedEventContent)> { - self.inner.encrypt(&*self.verification_machine.store, event_type, content).await + self.inner.encrypt(&*self.verification_machine.store, content).await } /// Encrypt the given inbound group session as a forwarded room key for this @@ -213,8 +209,7 @@ impl Device { ); }; - let content = serde_json::to_value(content)?; - self.encrypt(EventType::ForwardedRoomKey, content).await + self.encrypt(AnyToDeviceEventContent::ForwardedRoomKey(content)).await } } @@ -421,8 +416,7 @@ impl ReadOnlyDevice { pub(crate) async fn encrypt( &self, store: &dyn CryptoStore, - event_type: EventType, - content: Value, + content: AnyToDeviceEventContent, ) -> OlmResult<(Session, EncryptedEventContent)> { let sender_key = if let Some(k) = self.get_key(DeviceKeyAlgorithm::Curve25519) { k @@ -455,7 +449,7 @@ impl ReadOnlyDevice { return Err(OlmError::MissingSession); }; - let message = session.encrypt(self, event_type, content).await?; + let message = session.encrypt(self, content).await?; Ok((session, message)) } diff --git a/matrix_sdk_crypto/src/identities/user.rs b/matrix_sdk_crypto/src/identities/user.rs index 2015e56ce..e983f7867 100644 --- a/matrix_sdk_crypto/src/identities/user.rs +++ b/matrix_sdk_crypto/src/identities/user.rs @@ -22,7 +22,7 @@ use std::{ }; use ruma::{ - api::client::r0::keys::{CrossSigningKey, KeyUsage}, + encryption::{CrossSigningKey, KeyUsage}, DeviceKeyId, UserId, }; use serde::{Deserialize, Serialize}; diff --git a/matrix_sdk_crypto/src/key_request.rs b/matrix_sdk_crypto/src/key_request.rs index 9732d8d42..ba3d12872 100644 --- a/matrix_sdk_crypto/src/key_request.rs +++ b/matrix_sdk_crypto/src/key_request.rs @@ -20,21 +20,20 @@ // If we don't trust the device store an object that remembers the request and // let the users introspect that object. -use std::{collections::BTreeMap, sync::Arc}; +use std::sync::Arc; use dashmap::{mapref::entry::Entry, DashMap, DashSet}; use matrix_sdk_common::uuid::Uuid; use ruma::{ - api::client::r0::to_device::DeviceIdOrAllDevices, events::{ forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, room_key_request::{Action, RequestedKeyInfo, RoomKeyRequestToDeviceEventContent}, - AnyToDeviceEvent, EventType, ToDeviceEvent, + AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent, }, identifiers::{DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId}, + to_device::DeviceIdOrAllDevices, }; use serde::{Deserialize, Serialize}; -use serde_json::value::to_raw_value; use thiserror::Error; use tracing::{error, info, trace, warn}; @@ -150,7 +149,7 @@ pub struct OutgoingKeyRequest { } impl OutgoingKeyRequest { - fn to_request(&self, own_device_id: &DeviceId) -> Result { + fn to_request(&self, own_device_id: &DeviceId) -> OutgoingRequest { let content = RoomKeyRequestToDeviceEventContent::new( Action::Request, Some(self.info.clone()), @@ -158,13 +157,17 @@ impl OutgoingKeyRequest { self.request_id.to_string(), ); - wrap_key_request_content(self.request_recipient.clone(), self.request_id, &content) + let request = ToDeviceRequest::new_with_id( + &self.request_recipient, + DeviceIdOrAllDevices::AllDevices, + AnyToDeviceEventContent::RoomKeyRequest(content), + self.request_id, + ); + + OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) } } - fn to_cancellation( - &self, - own_device_id: &DeviceId, - ) -> Result { + fn to_cancellation(&self, own_device_id: &DeviceId) -> OutgoingRequest { let content = RoomKeyRequestToDeviceEventContent::new( Action::CancelRequest, None, @@ -172,8 +175,13 @@ impl OutgoingKeyRequest { self.request_id.to_string(), ); - let id = Uuid::new_v4(); - wrap_key_request_content(self.request_recipient.clone(), id, &content) + let request = ToDeviceRequest::new( + &self.request_recipient, + DeviceIdOrAllDevices::AllDevices, + AnyToDeviceEventContent::RoomKeyRequest(content), + ); + + OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) } } } @@ -187,26 +195,6 @@ impl PartialEq for OutgoingKeyRequest { } } -fn wrap_key_request_content( - recipient: UserId, - id: Uuid, - content: &RoomKeyRequestToDeviceEventContent, -) -> Result { - let mut messages = BTreeMap::new(); - - messages - .entry(recipient) - .or_insert_with(BTreeMap::new) - .insert(DeviceIdOrAllDevices::AllDevices, to_raw_value(content)?); - - Ok(OutgoingRequest { - request_id: id, - request: Arc::new( - ToDeviceRequest { event_type: EventType::RoomKeyRequest, txn_id: id, messages }.into(), - ), - }) -} - impl KeyRequestMachine { pub fn new( user_id: Arc, @@ -229,13 +217,14 @@ impl KeyRequestMachine { /// Load stored outgoing requests that were not yet sent out. async fn load_outgoing_requests(&self) -> Result, CryptoStoreError> { - self.store + Ok(self + .store .get_unsent_key_requests() .await? .into_iter() .filter(|i| !i.sent_out) - .map(|info| info.to_request(self.device_id()).map_err(CryptoStoreError::from)) - .collect() + .map(|info| info.to_request(self.device_id())) + .collect()) } /// Our own user id. @@ -448,23 +437,15 @@ impl KeyRequestMachine { let (used_session, content) = device.encrypt_session(session.clone(), message_index).await?; - let id = Uuid::new_v4(); - let mut messages = BTreeMap::new(); - - messages.entry(device.user_id().to_owned()).or_insert_with(BTreeMap::new).insert( - DeviceIdOrAllDevices::DeviceId(device.device_id().into()), - to_raw_value(&content)?, + let request = ToDeviceRequest::new( + device.user_id(), + device.device_id().to_owned(), + AnyToDeviceEventContent::RoomEncrypted(content), ); - let request = OutgoingRequest { - request_id: id, - request: Arc::new( - ToDeviceRequest { event_type: EventType::RoomEncrypted, txn_id: id, messages } - .into(), - ), - }; - - self.outgoing_to_device_requests.insert(id, request); + let request = + OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) }; + self.outgoing_to_device_requests.insert(request.request_id, request); Ok(used_session) } @@ -594,8 +575,8 @@ impl KeyRequestMachine { let request = self.store.get_key_request_by_info(&key_info).await?; if let Some(request) = request { - let cancel = request.to_cancellation(self.device_id())?; - let request = request.to_request(self.device_id())?; + let cancel = request.to_cancellation(self.device_id()); + let request = request.to_request(self.device_id()); Ok((Some(cancel), request)) } else { @@ -618,7 +599,7 @@ impl KeyRequestMachine { sent_out: false, }; - let outgoing_request = request.to_request(self.device_id())?; + let outgoing_request = request.to_request(self.device_id()); self.save_outgoing_key_info(request).await?; Ok(outgoing_request) @@ -717,7 +698,7 @@ impl KeyRequestMachine { // can delete it in one transaction. self.delete_key_info(&key_info).await?; - let request = key_info.to_cancellation(self.device_id())?; + let request = key_info.to_cancellation(self.device_id()); self.outgoing_to_device_requests.insert(request.request_id, request); Ok(()) @@ -789,13 +770,14 @@ mod test { use matrix_sdk_common::locks::Mutex; use matrix_sdk_test::async_test; use ruma::{ - api::client::r0::to_device::DeviceIdOrAllDevices, events::{ forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, room::encrypted::EncryptedEventContent, room_key_request::RoomKeyRequestToDeviceEventContent, AnyToDeviceEvent, ToDeviceEvent, }, - room_id, user_id, DeviceIdBox, RoomId, UserId, + room_id, + to_device::DeviceIdOrAllDevices, + user_id, DeviceIdBox, RoomId, UserId, }; use super::{KeyRequestMachine, KeyshareDecision}; @@ -1203,8 +1185,7 @@ mod test { .unwrap() .get(&DeviceIdOrAllDevices::AllDevices) .unwrap(); - let content: RoomKeyRequestToDeviceEventContent = - serde_json::from_str(content.get()).unwrap(); + let content: RoomKeyRequestToDeviceEventContent = content.deserialize_as().unwrap(); alice_machine.mark_outgoing_request_as_sent(id).await.unwrap(); @@ -1233,7 +1214,7 @@ mod test { .unwrap() .get(&DeviceIdOrAllDevices::DeviceId(alice_device_id())) .unwrap(); - let content: EncryptedEventContent = serde_json::from_str(content.get()).unwrap(); + let content: EncryptedEventContent = content.deserialize_as().unwrap(); bob_machine.mark_outgoing_request_as_sent(id).await.unwrap(); @@ -1336,8 +1317,7 @@ mod test { .unwrap() .get(&DeviceIdOrAllDevices::AllDevices) .unwrap(); - let content: RoomKeyRequestToDeviceEventContent = - serde_json::from_str(content.get()).unwrap(); + let content: RoomKeyRequestToDeviceEventContent = content.deserialize_as().unwrap(); alice_machine.mark_outgoing_request_as_sent(id).await.unwrap(); @@ -1382,7 +1362,7 @@ mod test { .unwrap() .get(&DeviceIdOrAllDevices::DeviceId(alice_device_id())) .unwrap(); - let content: EncryptedEventContent = serde_json::from_str(content.get()).unwrap(); + let content: EncryptedEventContent = content.deserialize_as().unwrap(); bob_machine.mark_outgoing_request_as_sent(id).await.unwrap(); diff --git a/matrix_sdk_crypto/src/machine.rs b/matrix_sdk_crypto/src/machine.rs index a22e79291..46763f5a7 100644 --- a/matrix_sdk_crypto/src/machine.rs +++ b/matrix_sdk_crypto/src/machine.rs @@ -755,11 +755,11 @@ impl OlmMachine { | AnyToDeviceEvent::KeyVerificationStart(..) => { self.handle_verification_event(event).await; } - AnyToDeviceEvent::Dummy(_) => {} - AnyToDeviceEvent::RoomKey(_) => {} - AnyToDeviceEvent::ForwardedRoomKey(_) => {} - AnyToDeviceEvent::RoomEncrypted(_) => {} - AnyToDeviceEvent::Custom(_) => {} + AnyToDeviceEvent::Dummy(_) + | AnyToDeviceEvent::RoomKey(_) + | AnyToDeviceEvent::ForwardedRoomKey(_) + | AnyToDeviceEvent::RoomEncrypted(_) => {} + _ => {} } } @@ -1231,21 +1231,22 @@ pub(crate) mod test { use matrix_sdk_test::test_json; use ruma::{ api::{ - client::r0::keys::{claim_keys, get_keys, upload_keys, OneTimeKey}, + client::r0::keys::{claim_keys, get_keys, upload_keys}, IncomingResponse, }, + encryption::OneTimeKey, events::{ + dummy::DummyToDeviceEventContent, room::{ encrypted::EncryptedEventContent, message::{MessageEventContent, MessageType}, }, AnyMessageEventContent, AnySyncMessageEvent, AnySyncRoomEvent, AnyToDeviceEvent, - EventType, SyncMessageEvent, ToDeviceEvent, Unsigned, + AnyToDeviceEventContent, SyncMessageEvent, ToDeviceEvent, Unsigned, }, identifiers::{ event_id, room_id, user_id, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, UserId, }, - serde::Raw, uint, MilliSecondsSinceUnixEpoch, }; use serde_json::json; @@ -1291,12 +1292,16 @@ pub(crate) mod test { fn to_device_requests_to_content(requests: Vec>) -> EncryptedEventContent { let to_device_request = &requests[0]; - let content: Raw = serde_json::from_str( - to_device_request.messages.values().next().unwrap().values().next().unwrap().get(), - ) - .unwrap(); - - content.deserialize().unwrap() + to_device_request + .messages + .values() + .next() + .unwrap() + .values() + .next() + .unwrap() + .deserialize_as() + .unwrap() } pub(crate) async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) { @@ -1358,7 +1363,10 @@ pub(crate) mod test { let bob_device = alice.get_device(&bob.user_id, &bob.device_id).await.unwrap().unwrap(); - let (session, content) = bob_device.encrypt(EventType::Dummy, json!({})).await.unwrap(); + let (session, content) = bob_device + .encrypt(AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new())) + .await + .unwrap(); alice.store.save_sessions(&[session]).await.unwrap(); let event = ToDeviceEvent { sender: alice.user_id().clone(), content }; @@ -1593,7 +1601,11 @@ pub(crate) mod test { let event = ToDeviceEvent { sender: alice.user_id().clone(), - content: bob_device.encrypt(EventType::Dummy, json!({})).await.unwrap().1, + content: bob_device + .encrypt(AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new())) + .await + .unwrap() + .1, }; let event = bob.decrypt_to_device_event(&event).await.unwrap().event.deserialize().unwrap(); diff --git a/matrix_sdk_crypto/src/olm/account.rs b/matrix_sdk_crypto/src/olm/account.rs index 2ed7750bb..718080fb6 100644 --- a/matrix_sdk_crypto/src/olm/account.rs +++ b/matrix_sdk_crypto/src/olm/account.rs @@ -30,13 +30,9 @@ use olm_rs::{ session::{OlmMessage, PreKeyMessage}, PicklingMode, }; -#[cfg(test)] -use ruma::events::EventType; use ruma::{ - api::client::r0::keys::{ - upload_keys, upload_signatures::Request as SignatureUploadRequest, OneTimeKey, SignedKey, - }, - encryption::DeviceKeys, + api::client::r0::keys::{upload_keys, upload_signatures::Request as SignatureUploadRequest}, + encryption::{DeviceKeys, OneTimeKey, SignedKey}, events::{ room::encrypted::{EncryptedEventContent, EncryptedEventScheme}, AnyToDeviceEvent, ToDeviceEvent, @@ -993,6 +989,8 @@ impl ReadOnlyAccount { #[cfg(test)] pub(crate) async fn create_session_for(&self, other: &ReadOnlyAccount) -> (Session, Session) { + use ruma::events::{dummy::DummyToDeviceEventContent, AnyToDeviceEventContent}; + other.generate_one_time_keys_helper(1).await; let one_time = other.signed_one_time_keys().await.unwrap(); @@ -1003,7 +1001,10 @@ impl ReadOnlyAccount { other.mark_keys_as_published().await; - let message = our_session.encrypt(&device, EventType::Dummy, json!({})).await.unwrap(); + let message = our_session + .encrypt(&device, AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new())) + .await + .unwrap(); let content = if let EncryptedEventScheme::OlmV1Curve25519AesSha2(c) = message.scheme { c } else { diff --git a/matrix_sdk_crypto/src/olm/group_sessions/inbound.rs b/matrix_sdk_crypto/src/olm/group_sessions/inbound.rs index e557d585c..75b6529b9 100644 --- a/matrix_sdk_crypto/src/olm/group_sessions/inbound.rs +++ b/matrix_sdk_crypto/src/olm/group_sessions/inbound.rs @@ -320,11 +320,9 @@ impl InboundGroupSession { decrypted_object.get_mut("content").map(|c| c.as_object_mut()).flatten() { if !decrypted_content.contains_key("m.relates_to") { - if let Some(relation) = &event.content.relates_to { - decrypted_content.insert( - "m.relates_to".to_owned(), - serde_json::to_value(relation).unwrap_or_default(), - ); + let content = serde_json::to_value(&event.content)?; + if let Some(relation) = content.as_object().and_then(|o| o.get("m.relates_to")) { + decrypted_content.insert("m.relates_to".to_owned(), relation.to_owned()); } } } diff --git a/matrix_sdk_crypto/src/olm/group_sessions/outbound.rs b/matrix_sdk_crypto/src/olm/group_sessions/outbound.rs index fc24d369d..b432e44e5 100644 --- a/matrix_sdk_crypto/src/olm/group_sessions/outbound.rs +++ b/matrix_sdk_crypto/src/olm/group_sessions/outbound.rs @@ -34,20 +34,20 @@ use olm_rs::{ errors::OlmGroupSessionError, outbound_group_session::OlmOutboundGroupSession, PicklingMode, }; use ruma::{ - api::client::r0::to_device::DeviceIdOrAllDevices, events::{ room::{ encrypted::{EncryptedEventContent, EncryptedEventScheme, MegolmV1AesSha2ContentInit}, encryption::EncryptionEventContent, history_visibility::HistoryVisibility, - message::Relation, }, - AnyMessageEventContent, EventContent, + room_key::RoomKeyToDeviceEventContent, + AnyMessageEventContent, AnyToDeviceEventContent, EventContent, }, + to_device::DeviceIdOrAllDevices, DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId, }; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::json; use tracing::{debug, error, trace}; use super::{ @@ -277,13 +277,8 @@ impl OutboundGroupSession { "type": content.event_type(), }); - let relates_to: Option = json_content - .get("content") - .map(|c| c.get("m.relates_to").cloned().map(|r| serde_json::from_value(r).ok())) - .flatten() - .flatten(); - let plaintext = json_content.to_string(); + let relation = content.relation(); let ciphertext = self.encrypt_helper(plaintext).await; @@ -297,7 +292,7 @@ impl OutboundGroupSession { EncryptedEventContent::new( EncryptedEventScheme::MegolmV1AesSha2(encrypted_content), - relates_to, + relation, ) } @@ -361,16 +356,15 @@ impl OutboundGroupSession { session.session_message_index() } - /// Get the outbound group session key as a json value that can be sent as a - /// m.room_key. - pub async fn as_json(&self) -> Value { - json!({ - "algorithm": EventEncryptionAlgorithm::MegolmV1AesSha2, - "room_id": &*self.room_id, - "session_id": &*self.session_id, - "session_key": self.session_key().await, - "chain_index": self.message_index().await, - }) + pub(crate) async fn as_content(&self) -> AnyToDeviceEventContent { + let session_key = self.session_key().await; + + AnyToDeviceEventContent::RoomKey(RoomKeyToDeviceEventContent::new( + EventEncryptionAlgorithm::MegolmV1AesSha2, + self.room_id().to_owned(), + self.session_id().to_owned(), + session_key.0.clone(), + )) } /// Has or will the session be shared with the given user/device pair. diff --git a/matrix_sdk_crypto/src/olm/mod.rs b/matrix_sdk_crypto/src/olm/mod.rs index e6fb47439..027670258 100644 --- a/matrix_sdk_crypto/src/olm/mod.rs +++ b/matrix_sdk_crypto/src/olm/mod.rs @@ -63,9 +63,8 @@ pub(crate) mod test { use olm_rs::session::OlmMessage; use ruma::{ - api::client::r0::keys::SignedKey, - events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, room_id, user_id, - DeviceId, UserId, + encryption::SignedKey, events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, + room_id, user_id, DeviceId, UserId, }; use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session}; diff --git a/matrix_sdk_crypto/src/olm/session.rs b/matrix_sdk_crypto/src/olm/session.rs index be34a3760..10fdd5ca9 100644 --- a/matrix_sdk_crypto/src/olm/session.rs +++ b/matrix_sdk_crypto/src/olm/session.rs @@ -26,12 +26,12 @@ use ruma::{ CiphertextInfo, EncryptedEventContent, EncryptedEventScheme, OlmV1Curve25519AesSha2Content, }, - EventType, + AnyToDeviceEventContent, EventContent, }, identifiers::{DeviceId, DeviceKeyAlgorithm, UserId}, }; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::json; use super::{deserialize_instant, serialize_instant, IdentityKeys}; use crate::{ @@ -105,21 +105,17 @@ impl Session { /// encrypted, this needs to be the device that was used to create this /// session with. /// - /// * `event_type` - The type of the event. - /// /// * `content` - The content of the event. pub async fn encrypt( &mut self, recipient_device: &ReadOnlyDevice, - event_type: EventType, - content: Value, + content: AnyToDeviceEventContent, ) -> OlmResult { let recipient_signing_key = recipient_device .get_key(DeviceKeyAlgorithm::Ed25519) .ok_or(EventError::MissingSigningKey)?; - let relates_to = - content.get("m.relates_to").cloned().and_then(|v| serde_json::from_value(v).ok()); + let event_type = content.event_type(); let payload = json!({ "sender": self.user_id.as_str(), @@ -149,7 +145,7 @@ impl Session { content, self.our_identity_keys.curve25519().to_string(), )), - relates_to, + None, )) } diff --git a/matrix_sdk_crypto/src/olm/signing/mod.rs b/matrix_sdk_crypto/src/olm/signing/mod.rs index 3f28b6ad4..523c274b5 100644 --- a/matrix_sdk_crypto/src/olm/signing/mod.rs +++ b/matrix_sdk_crypto/src/olm/signing/mod.rs @@ -25,8 +25,8 @@ use std::{ use matrix_sdk_common::locks::Mutex; use pk_signing::{MasterSigning, PickledSignings, SelfSigning, Signing, SigningError, UserSigning}; use ruma::{ - api::client::r0::keys::{upload_signatures::Request as SignatureUploadRequest, KeyUsage}, - encryption::DeviceKeys, + api::client::r0::keys::upload_signatures::Request as SignatureUploadRequest, + encryption::{DeviceKeys, KeyUsage}, DeviceKeyAlgorithm, DeviceKeyId, UserId, }; use serde::{Deserialize, Serialize}; @@ -403,7 +403,7 @@ mod test { use std::{collections::BTreeMap, sync::Arc}; use matrix_sdk_test::async_test; - use ruma::{api::client::r0::keys::CrossSigningKey, user_id, UserId}; + use ruma::{encryption::CrossSigningKey, user_id, UserId}; use super::{PrivateCrossSigningIdentity, Signing}; use crate::{ diff --git a/matrix_sdk_crypto/src/olm/signing/pk_signing.rs b/matrix_sdk_crypto/src/olm/signing/pk_signing.rs index 0da882d36..00589e6d2 100644 --- a/matrix_sdk_crypto/src/olm/signing/pk_signing.rs +++ b/matrix_sdk_crypto/src/olm/signing/pk_signing.rs @@ -24,8 +24,7 @@ use olm_rs::pk::OlmPkSigning; #[cfg(test)] use olm_rs::{errors::OlmUtilityError, utility::OlmUtility}; use ruma::{ - api::client::r0::keys::{CrossSigningKey, KeyUsage}, - encryption::DeviceKeys, + encryption::{CrossSigningKey, DeviceKeys, KeyUsage}, serde::CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId, }; diff --git a/matrix_sdk_crypto/src/requests.rs b/matrix_sdk_crypto/src/requests.rs index 318e80008..428edaef4 100644 --- a/matrix_sdk_crypto/src/requests.rs +++ b/matrix_sdk_crypto/src/requests.rs @@ -25,16 +25,17 @@ use ruma::{ Request as SignatureUploadRequest, Response as SignatureUploadResponse, }, upload_signing_keys::Response as SigningKeysUploadResponse, - CrossSigningKey, }, message::send_message_event::Response as RoomMessageResponse, - to_device::{send_event_to_device::Response as ToDeviceResponse, DeviceIdOrAllDevices}, + to_device::send_event_to_device::Response as ToDeviceResponse, }, + encryption::CrossSigningKey, events::{AnyMessageEventContent, AnyToDeviceEventContent, EventContent, EventType}, + serde::Raw, + to_device::DeviceIdOrAllDevices, DeviceIdBox, RoomId, UserId, }; use serde::{Deserialize, Serialize}; -use serde_json::value::RawValue as RawJsonValue; /// Customized version of /// `ruma_client_api::r0::to_device::send_event_to_device::Request`, @@ -54,7 +55,7 @@ pub struct ToDeviceRequest { /// The content's type for this field will be updated in a future /// release, until then you can create a value using /// `serde_json::value::to_raw_value`. - pub messages: BTreeMap>>, + pub messages: BTreeMap>>, } impl ToDeviceRequest { @@ -73,18 +74,24 @@ impl ToDeviceRequest { recipient: &UserId, recipient_device: impl Into, content: AnyToDeviceEventContent, + ) -> Self { + Self::new_with_id(recipient, recipient_device, content, Uuid::new_v4()) + } + + pub(crate) fn new_with_id( + recipient: &UserId, + recipient_device: impl Into, + content: AnyToDeviceEventContent, + txn_id: Uuid, ) -> Self { let mut messages = BTreeMap::new(); let mut user_messages = BTreeMap::new(); - - user_messages.insert( - 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 = EventType::from(content.event_type()); - ToDeviceRequest { txn_id: Uuid::new_v4(), event_type, messages } + user_messages.insert(recipient_device.into(), Raw::from(content)); + messages.insert(recipient.clone(), user_messages); + + ToDeviceRequest { event_type, txn_id, messages } } /// Gets the transaction ID as a string. diff --git a/matrix_sdk_crypto/src/session_manager/group_sessions.rs b/matrix_sdk_crypto/src/session_manager/group_sessions.rs index 5d084a4c9..f4b210a6b 100644 --- a/matrix_sdk_crypto/src/session_manager/group_sessions.rs +++ b/matrix_sdk_crypto/src/session_manager/group_sessions.rs @@ -21,14 +21,14 @@ use dashmap::DashMap; use futures::future::join_all; use matrix_sdk_common::{executor::spawn, uuid::Uuid}; use ruma::{ - api::client::r0::to_device::DeviceIdOrAllDevices, events::{ room::{encrypted::EncryptedEventContent, history_visibility::HistoryVisibility}, - AnyMessageEventContent, EventType, + AnyMessageEventContent, AnyToDeviceEventContent, EventType, }, + serde::Raw, + to_device::DeviceIdOrAllDevices, DeviceId, DeviceIdBox, RoomId, UserId, }; -use serde_json::Value; use tracing::{debug, info, trace}; use crate::{ @@ -224,22 +224,22 @@ impl GroupSessionManager { /// Encrypt the given content for the given devices and create a to-device /// requests that sends the encrypted content to them. async fn encrypt_session_for( - content: Value, + content: AnyToDeviceEventContent, devices: Vec, ) -> OlmResult<(Uuid, ToDeviceRequest, Vec)> { let mut messages = BTreeMap::new(); let mut changed_sessions = Vec::new(); - let encrypt = |device: Device, content: Value| async move { + let encrypt = |device: Device, content: AnyToDeviceEventContent| async move { let mut message = BTreeMap::new(); - let encrypted = device.encrypt(EventType::RoomKey, content.clone()).await; + let encrypted = device.encrypt(content.clone()).await; let used_session = match encrypted { Ok((session, encrypted)) => { message.entry(device.user_id().clone()).or_insert_with(BTreeMap::new).insert( DeviceIdOrAllDevices::DeviceId(device.device_id().into()), - serde_json::value::to_raw_value(&encrypted)?, + Raw::from(AnyToDeviceEventContent::RoomEncrypted(encrypted)), ); Some(session) } @@ -375,7 +375,7 @@ impl GroupSessionManager { pub async fn encrypt_request( chunk: Vec, - content: Value, + content: AnyToDeviceEventContent, outbound: OutboundGroupSession, message_index: u32, being_shared: Arc>, @@ -466,7 +466,7 @@ impl GroupSessionManager { .flatten() .collect(); - let key_content = outbound.as_json().await; + let key_content = outbound.as_content().await; let message_index = outbound.message_index().await; if !devices.is_empty() { diff --git a/matrix_sdk_crypto/src/session_manager/sessions.rs b/matrix_sdk_crypto/src/session_manager/sessions.rs index 657de1702..3b742e7fc 100644 --- a/matrix_sdk_crypto/src/session_manager/sessions.rs +++ b/matrix_sdk_crypto/src/session_manager/sessions.rs @@ -17,15 +17,13 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration}; use dashmap::{DashMap, DashSet}; use matrix_sdk_common::uuid::Uuid; use ruma::{ - api::client::r0::{ - keys::claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, - to_device::DeviceIdOrAllDevices, + api::client::r0::keys::claim_keys::{ + Request as KeysClaimRequest, Response as KeysClaimResponse, }, assign, - events::EventType, + events::{dummy::DummyToDeviceEventContent, AnyToDeviceEventContent}, DeviceId, DeviceIdBox, DeviceKeyAlgorithm, UserId, }; -use serde_json::{json, value::to_raw_value}; use tracing::{error, info, warn}; use crate::{ @@ -118,28 +116,21 @@ impl SessionManager { async fn check_if_unwedged(&self, user_id: &UserId, device_id: &DeviceId) -> OlmResult<()> { if self.wedged_devices.get(user_id).map(|d| d.remove(device_id)).flatten().is_some() { if let Some(device) = self.store.get_device(user_id, device_id).await? { - let (_, content) = device.encrypt(EventType::Dummy, json!({})).await?; - let id = Uuid::new_v4(); - let mut messages = BTreeMap::new(); + let content = AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new()); + let (_, content) = device.encrypt(content).await?; - messages.entry(device.user_id().to_owned()).or_insert_with(BTreeMap::new).insert( - DeviceIdOrAllDevices::DeviceId(device.device_id().into()), - to_raw_value(&content)?, + let request = ToDeviceRequest::new( + device.user_id(), + device.device_id().to_owned(), + AnyToDeviceEventContent::RoomEncrypted(content), ); let request = OutgoingRequest { - request_id: id, - request: Arc::new( - ToDeviceRequest { - event_type: EventType::RoomEncrypted, - txn_id: id, - messages, - } - .into(), - ), + request_id: request.txn_id, + request: Arc::new(request.into()), }; - self.outgoing_to_device_requests.insert(id, request); + self.outgoing_to_device_requests.insert(request.request_id, request); } } diff --git a/matrix_sdk_crypto/src/store/sled.rs b/matrix_sdk_crypto/src/store/sled.rs index afa41a059..8dd547c7c 100644 --- a/matrix_sdk_crypto/src/store/sled.rs +++ b/matrix_sdk_crypto/src/store/sled.rs @@ -757,7 +757,7 @@ mod test { use matrix_sdk_test::async_test; use olm_rs::outbound_group_session::OlmOutboundGroupSession; use ruma::{ - api::client::r0::keys::SignedKey, + encryption::SignedKey, events::room_key_request::RequestedKeyInfo, identifiers::{room_id, user_id, DeviceId, EventEncryptionAlgorithm, UserId}, }; diff --git a/matrix_sdk_crypto/src/verification/event_enums.rs b/matrix_sdk_crypto/src/verification/event_enums.rs index a8805d708..2c28feb79 100644 --- a/matrix_sdk_crypto/src/verification/event_enums.rs +++ b/matrix_sdk_crypto/src/verification/event_enums.rs @@ -79,8 +79,7 @@ impl AnyEvent<'_> { | AnyMessageEvent::RoomEncrypted(_) | AnyMessageEvent::RoomMessageFeedback(_) | AnyMessageEvent::RoomRedaction(_) - | AnyMessageEvent::Sticker(_) - | AnyMessageEvent::Custom(_) => None, + | AnyMessageEvent::Sticker(_) => None, AnyMessageEvent::RoomMessage(m) => { if let MessageType::VerificationRequest(v) = &m.content.msgtype { Some(RequestContent::from(v).into()) @@ -105,14 +104,14 @@ impl AnyEvent<'_> { AnyMessageEvent::KeyVerificationDone(e) => { Some(DoneContent::from(&e.content).into()) } + _ => None, }, AnyEvent::ToDevice(e) => match e { AnyToDeviceEvent::Dummy(_) | AnyToDeviceEvent::RoomKey(_) | AnyToDeviceEvent::RoomKeyRequest(_) | AnyToDeviceEvent::ForwardedRoomKey(_) - | AnyToDeviceEvent::RoomEncrypted(_) - | AnyToDeviceEvent::Custom(_) => None, + | AnyToDeviceEvent::RoomEncrypted(_) => None, AnyToDeviceEvent::KeyVerificationRequest(e) => { Some(RequestContent::from(&e.content).into()) } @@ -137,6 +136,7 @@ impl AnyEvent<'_> { AnyToDeviceEvent::KeyVerificationDone(e) => { Some(DoneContent::from(&e.content).into()) } + _ => None, }, } } @@ -178,30 +178,30 @@ impl TryFrom<&AnyMessageEvent> for FlowId { | AnyMessageEvent::RoomEncrypted(_) | AnyMessageEvent::RoomMessageFeedback(_) | AnyMessageEvent::RoomRedaction(_) - | AnyMessageEvent::Sticker(_) - | AnyMessageEvent::Custom(_) => Err(()), + | AnyMessageEvent::Sticker(_) => Err(()), AnyMessageEvent::KeyVerificationReady(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::RoomMessage(e) => Ok(FlowId::from((&e.room_id, &e.event_id))), AnyMessageEvent::KeyVerificationStart(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::KeyVerificationCancel(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::KeyVerificationAccept(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::KeyVerificationKey(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::KeyVerificationMac(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } AnyMessageEvent::KeyVerificationDone(e) => { - Ok(FlowId::from((&e.room_id, &e.content.relation.event_id))) + Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id))) } + _ => Err(()), } } } @@ -215,8 +215,7 @@ impl TryFrom<&AnyToDeviceEvent> for FlowId { | AnyToDeviceEvent::RoomKey(_) | AnyToDeviceEvent::RoomKeyRequest(_) | AnyToDeviceEvent::ForwardedRoomKey(_) - | AnyToDeviceEvent::RoomEncrypted(_) - | AnyToDeviceEvent::Custom(_) => Err(()), + | AnyToDeviceEvent::RoomEncrypted(_) => Err(()), AnyToDeviceEvent::KeyVerificationRequest(e) => { Ok(FlowId::from(e.content.transaction_id.to_owned())) } @@ -241,6 +240,7 @@ impl TryFrom<&AnyToDeviceEvent> for FlowId { AnyToDeviceEvent::KeyVerificationDone(e) => { Ok(FlowId::from(e.content.transaction_id.to_owned())) } + _ => Err(()), } } } @@ -397,7 +397,7 @@ impl<'a> StartContent<'a> { pub fn flow_id(&self) -> &str { match self { Self::ToDevice(c) => &c.transaction_id, - Self::Room(c) => c.relation.event_id.as_str(), + Self::Room(c) => c.relates_to.event_id.as_str(), } } @@ -449,7 +449,7 @@ impl<'a> DoneContent<'a> { pub fn flow_id(&self) -> &str { match self { Self::ToDevice(c) => &c.transaction_id, - Self::Room(c) => c.relation.event_id.as_str(), + Self::Room(c) => c.relates_to.event_id.as_str(), } } } @@ -464,7 +464,7 @@ impl AcceptContent<'_> { pub fn flow_id(&self) -> &str { match self { Self::ToDevice(c) => &c.transaction_id, - Self::Room(c) => c.relation.event_id.as_str(), + Self::Room(c) => c.relates_to.event_id.as_str(), } } @@ -495,7 +495,7 @@ impl KeyContent<'_> { pub fn flow_id(&self) -> &str { match self { Self::ToDevice(c) => &c.transaction_id, - Self::Room(c) => c.relation.event_id.as_str(), + Self::Room(c) => c.relates_to.event_id.as_str(), } } @@ -517,7 +517,7 @@ impl MacContent<'_> { pub fn flow_id(&self) -> &str { match self { Self::ToDevice(c) => &c.transaction_id, - Self::Room(c) => c.relation.event_id.as_str(), + Self::Room(c) => c.relates_to.event_id.as_str(), } } @@ -582,7 +582,7 @@ impl OwnedStartContent { pub fn flow_id(&self) -> FlowId { match self { Self::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()), - Self::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()), + Self::Room(r, c) => FlowId::InRoom(r.clone(), c.relates_to.event_id.clone()), } } @@ -688,72 +688,65 @@ impl From for OutgoingContent { #[cfg(test)] impl TryFrom for OutgoingContent { - type Error = (); + type Error = String; - fn try_from(value: ToDeviceRequest) -> Result { + fn try_from(request: ToDeviceRequest) -> Result { use ruma::events::EventType; use serde_json::Value; let json: Value = serde_json::from_str( - value + request .messages .values() .next() - .and_then(|m| m.values().next().map(|j| j.get())) - .ok_or(())?, + .and_then(|m| m.values().next()) + .map(|c| c.json().get()) + .ok_or_else(|| "Content is missing from the request".to_owned())?, ) - .map_err(|_| ())?; + .map_err(|e| e.to_string())?; - match value.event_type { - EventType::KeyVerificationRequest => { - Ok(AnyToDeviceEventContent::KeyVerificationRequest( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()) - } - EventType::KeyVerificationReady => Ok(AnyToDeviceEventContent::KeyVerificationReady( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationDone => Ok(AnyToDeviceEventContent::KeyVerificationDone( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationStart => Ok(AnyToDeviceEventContent::KeyVerificationStart( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationKey => Ok(AnyToDeviceEventContent::KeyVerificationKey( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationAccept => Ok(AnyToDeviceEventContent::KeyVerificationAccept( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationMac => Ok(AnyToDeviceEventContent::KeyVerificationMac( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - EventType::KeyVerificationCancel => Ok(AnyToDeviceEventContent::KeyVerificationCancel( - serde_json::from_value(json).map_err(|_| ())?, - ) - .into()), - _ => Err(()), - } + let content = match request.event_type { + EventType::KeyVerificationStart => AnyToDeviceEventContent::KeyVerificationStart( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationKey => AnyToDeviceEventContent::KeyVerificationKey( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationAccept => AnyToDeviceEventContent::KeyVerificationAccept( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationMac => AnyToDeviceEventContent::KeyVerificationMac( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationCancel => AnyToDeviceEventContent::KeyVerificationCancel( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationReady => AnyToDeviceEventContent::KeyVerificationReady( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationDone => AnyToDeviceEventContent::KeyVerificationDone( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + EventType::KeyVerificationRequest => AnyToDeviceEventContent::KeyVerificationRequest( + serde_json::from_value(json).map_err(|e| e.to_string())?, + ), + e => return Err(format!("Unsupported event type {}", e)), + }; + + Ok(content.into()) } } #[cfg(test)] impl TryFrom for OutgoingContent { - type Error = (); + type Error = String; - fn try_from(value: OutgoingRequest) -> Result { + fn try_from(value: OutgoingRequest) -> Result { match value.request() { - crate::OutgoingRequests::KeysUpload(_) => Err(()), - crate::OutgoingRequests::KeysQuery(_) => Err(()), + crate::OutgoingRequests::KeysUpload(_) => Err("Invalid request type".to_owned()), + crate::OutgoingRequests::KeysQuery(_) => Err("Invalid request type".to_owned()), crate::OutgoingRequests::ToDeviceRequest(r) => Self::try_from(r.clone()), - crate::OutgoingRequests::SignatureUpload(_) => Err(()), + crate::OutgoingRequests::SignatureUpload(_) => Err("Invalid request type".to_owned()), crate::OutgoingRequests::RoomMessage(r) => Ok(Self::from(r.clone())), } } diff --git a/matrix_sdk_crypto/src/verification/mod.rs b/matrix_sdk_crypto/src/verification/mod.rs index 0a8f789ea..fd9850e29 100644 --- a/matrix_sdk_crypto/src/verification/mod.rs +++ b/matrix_sdk_crypto/src/verification/mod.rs @@ -525,10 +525,9 @@ impl IdentitiesBeingVerified { #[cfg(test)] pub(crate) mod test { use ruma::{ - events::{AnyToDeviceEvent, AnyToDeviceEventContent, EventType, ToDeviceEvent}, + events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent}, UserId, }; - use serde_json::Value; use super::event_enums::OutgoingContent; use crate::{ @@ -540,7 +539,7 @@ pub(crate) mod test { sender: &UserId, request: &OutgoingVerificationRequest, ) -> AnyToDeviceEvent { - let content = get_content_from_request(request); + let content = request.to_owned().into(); wrap_any_to_device_content(sender, content) } @@ -589,36 +588,4 @@ pub(crate) mod test { _ => unreachable!(), } } - - pub(crate) fn get_content_from_request( - request: &OutgoingVerificationRequest, - ) -> OutgoingContent { - let request = - if let OutgoingVerificationRequest::ToDevice(r) = request { r } else { unreachable!() }; - - 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!(), - } - .into() - } } diff --git a/matrix_sdk_crypto/src/verification/requests.rs b/matrix_sdk_crypto/src/verification/requests.rs index 9711caa62..7eb621c6c 100644 --- a/matrix_sdk_crypto/src/verification/requests.rs +++ b/matrix_sdk_crypto/src/verification/requests.rs @@ -19,7 +19,6 @@ use std::sync::{Arc, Mutex}; use matrix_qrcode::QrVerificationData; use matrix_sdk_common::uuid::Uuid; use ruma::{ - api::client::r0::to_device::DeviceIdOrAllDevices, events::{ key::verification::{ cancel::CancelCode, @@ -31,6 +30,7 @@ use ruma::{ room::message::KeyVerificationRequestEventContent, AnyMessageEventContent, AnyToDeviceEventContent, }, + to_device::DeviceIdOrAllDevices, DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId, }; use tracing::{info, trace, warn}; @@ -51,9 +51,9 @@ use crate::{ }; const SUPPORTED_METHODS: &[VerificationMethod] = &[ - VerificationMethod::MSasV1, - VerificationMethod::MQrCodeShowV1, - VerificationMethod::MReciprocateV1, + VerificationMethod::SasV1, + VerificationMethod::QrCodeShowV1, + VerificationMethod::ReciprocateV1, ]; /// An object controlling key verification requests. @@ -780,8 +780,8 @@ impl RequestState { // If we didn't state that we support showing QR codes or if the other // side doesn't support scanning QR codes bail early. - if !self.state.our_methods.contains(&VerificationMethod::MQrCodeShowV1) - || !self.state.their_methods.contains(&VerificationMethod::MQrScanShowV1) + if !self.state.our_methods.contains(&VerificationMethod::QrCodeShowV1) + || !self.state.their_methods.contains(&VerificationMethod::QrCodeScanV1) { return Ok(None); } @@ -942,7 +942,7 @@ impl RequestState { account: ReadOnlyAccount, private_identity: PrivateCrossSigningIdentity, ) -> Result, CryptoStoreError> { - if !self.state.their_methods.contains(&VerificationMethod::MSasV1) { + if !self.state.their_methods.contains(&VerificationMethod::SasV1) { return Ok(None); } diff --git a/matrix_sdk_crypto/src/verification/sas/mod.rs b/matrix_sdk_crypto/src/verification/sas/mod.rs index 4e50d89a8..fb9a5be6d 100644 --- a/matrix_sdk_crypto/src/verification/sas/mod.rs +++ b/matrix_sdk_crypto/src/verification/sas/mod.rs @@ -476,12 +476,12 @@ impl AcceptSettings { fn apply(self, mut content: OwnedAcceptContent) -> OwnedAcceptContent { match &mut content { OwnedAcceptContent::ToDevice(AcceptToDeviceEventContent { - method: AcceptMethod::MSasV1(c), + method: AcceptMethod::SasV1(c), .. }) | OwnedAcceptContent::Room( _, - AcceptEventContent { method: AcceptMethod::MSasV1(c), .. }, + AcceptEventContent { method: AcceptMethod::SasV1(c), .. }, ) => { c.short_authentication_string.retain(|sas| self.allowed_methods.contains(sas)); content diff --git a/matrix_sdk_crypto/src/verification/sas/sas_state.rs b/matrix_sdk_crypto/src/verification/sas/sas_state.rs index f3d82488d..2c63bbc34 100644 --- a/matrix_sdk_crypto/src/verification/sas/sas_state.rs +++ b/matrix_sdk_crypto/src/verification/sas/sas_state.rs @@ -102,7 +102,7 @@ impl TryFrom for AcceptedProtocols { Err(CancelCode::UnknownMethod) } else { Ok(Self { - method: VerificationMethod::MSasV1, + method: VerificationMethod::SasV1, hash: content.hash, key_agreement_protocol: content.key_agreement_protocol, message_auth_code: content.message_authentication_code, @@ -149,7 +149,7 @@ impl TryFrom<&SasV1Content> for AcceptedProtocols { } Ok(Self { - method: VerificationMethod::MSasV1, + method: VerificationMethod::SasV1, hash: HashAlgorithm::Sha256, key_agreement_protocol: KeyAgreementProtocol::Curve25519HkdfSha256, message_auth_code: MessageAuthenticationCode::HkdfHmacSha256, @@ -163,7 +163,7 @@ impl TryFrom<&SasV1Content> for AcceptedProtocols { impl Default for AcceptedProtocols { fn default() -> Self { AcceptedProtocols { - method: VerificationMethod::MSasV1, + method: VerificationMethod::SasV1, hash: HashAlgorithm::Sha256, key_agreement_protocol: KeyAgreementProtocol::Curve25519HkdfSha256, message_auth_code: MessageAuthenticationCode::HkdfHmacSha256, @@ -450,7 +450,7 @@ impl SasState { ) -> Result, SasState> { self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?; - if let AcceptMethod::MSasV1(content) = content.method() { + if let AcceptMethod::SasV1(content) = content.method() { let accepted_protocols = AcceptedProtocols::try_from(content.clone()).map_err(|c| self.clone().cancel(c))?; @@ -560,7 +560,7 @@ impl SasState { /// been started because of a /// m.key.verification.request -> m.key.verification.ready flow. pub fn as_content(&self) -> OwnedAcceptContent { - let method = AcceptMethod::MSasV1( + let method = AcceptMethod::SasV1( AcceptV1ContentInit { commitment: self.state.commitment.clone(), hash: self.state.accepted_protocols.hash.clone(), @@ -684,10 +684,10 @@ impl SasState { pub fn as_content(&self) -> OutgoingContent { match &*self.verification_flow_id { FlowId::ToDevice(s) => { - AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent { - transaction_id: s.to_string(), - key: self.inner.lock().unwrap().public_key(), - }) + AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent::new( + s.to_string(), + self.inner.lock().unwrap().public_key(), + )) .into() } FlowId::InRoom(r, e) => ( @@ -710,10 +710,10 @@ impl SasState { pub fn as_content(&self) -> OutgoingContent { match &*self.verification_flow_id { FlowId::ToDevice(s) => { - AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent { - transaction_id: s.to_string(), - key: self.inner.lock().unwrap().public_key(), - }) + AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent::new( + s.to_string(), + self.inner.lock().unwrap().public_key(), + )) .into() } FlowId::InRoom(r, e) => ( @@ -1090,11 +1090,12 @@ mod test { use ruma::{ events::key::verification::{ - accept::{AcceptMethod, CustomContent}, - start::{CustomContent as CustomStartContent, StartMethod}, + accept::{AcceptMethod, AcceptToDeviceEventContent}, + start::{StartMethod, StartToDeviceEventContent}, }, DeviceId, UserId, }; + use serde_json::json; use super::{Accepted, Created, SasState, Started}; use crate::{ @@ -1227,7 +1228,7 @@ mod test { let mut method = content.method_mut(); match &mut method { - AcceptMethod::MSasV1(ref mut c) => { + AcceptMethod::SasV1(ref mut c) => { c.commitment = "".to_string(); } _ => panic!("Unknown accept event content"), @@ -1266,7 +1267,7 @@ mod test { let mut method = content.method_mut(); match &mut method { - AcceptMethod::MSasV1(ref mut c) => { + AcceptMethod::SasV1(ref mut c) => { c.short_authentication_string = vec![]; } _ => panic!("Unknown accept event content"), @@ -1283,14 +1284,13 @@ mod test { async fn sas_unknown_method() { let (alice, bob) = get_sas_pair().await; - let mut content = bob.as_content(); - let method = content.method_mut(); - - *method = AcceptMethod::Custom(CustomContent { - method: "m.sas.custom".to_string(), - data: Default::default(), + let content = json!({ + "method": "m.sas.custom", + "method_data": "something", + "transaction_id": "some_id", }); + let content: AcceptToDeviceEventContent = serde_json::from_value(content).unwrap(); let content = AcceptContent::from(&content); alice @@ -1331,22 +1331,22 @@ mod test { ) .expect_err("Didn't cancel on invalid MAC method"); - let mut start_content = alice_sas.as_content(); - let method = start_content.method_mut(); - - *method = StartMethod::Custom(CustomStartContent { - method: "m.sas.custom".to_string(), - data: Default::default(), + let content = json!({ + "method": "m.sas.custom", + "from_device": "DEVICEID", + "method_data": "something", + "transaction_id": "some_id", }); - let flow_id = start_content.flow_id(); - let content = StartContent::from(&start_content); + let content: StartToDeviceEventContent = serde_json::from_value(content).unwrap(); + let content = StartContent::from(&content); + let flow_id = content.flow_id().to_owned(); SasState::::from_start_event( bob.clone(), alice_device, None, - flow_id, + flow_id.into(), &content, false, ) diff --git a/matrix_sdk_test/Cargo.toml b/matrix_sdk_test/Cargo.toml index f640d00ff..cbb03617b 100644 --- a/matrix_sdk_test/Cargo.toml +++ b/matrix_sdk_test/Cargo.toml @@ -18,6 +18,6 @@ http = "0.2.3" lazy_static = "1.4.0" matrix-sdk-common = { version = "0.2.0", path = "../matrix_sdk_common" } matrix-sdk-test-macros = { version = "0.1.0", path = "../matrix_sdk_test_macros" } -ruma = { version = "0.1.2", features = ["client-api-c"] } +ruma = { version = "0.1.2", features = ["client-api-c"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" } serde = "1.0.122" serde_json = "1.0.61"