diff --git a/Cargo.lock b/Cargo.lock index 390559341..514f067c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2979,6 +2979,7 @@ name = "matrix-sdk-common" version = "0.11.0" dependencies = [ "assert_matches", + "assert_matches2", "eyeball-im", "futures-core", "futures-util", diff --git a/bindings/matrix-sdk-crypto-ffi/src/machine.rs b/bindings/matrix-sdk-crypto-ffi/src/machine.rs index 66c78c3d8..ed3038a01 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/machine.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/machine.rs @@ -932,6 +932,11 @@ impl OlmMachine { encryption_info.verification_state.to_shield_state_lax().into() }, }, + AlgorithmInfo::OlmV1Curve25519AesSha2 { .. } => { + // cannot happen because `decrypt_room_event` would have fail to decrypt olm for + // a room (EventError::UnsupportedAlgorithm) + panic!("Unsupported olm algorithm in room") + } }) } diff --git a/crates/matrix-sdk-common/Cargo.toml b/crates/matrix-sdk-common/Cargo.toml index 418f4bbe5..e714f458a 100644 --- a/crates/matrix-sdk-common/Cargo.toml +++ b/crates/matrix-sdk-common/Cargo.toml @@ -51,6 +51,7 @@ web-sys = { workspace = true, features = ["console"] } [dev-dependencies] assert_matches.workspace = true +assert_matches2.workspace = true insta.workspace = true matrix-sdk-test-macros = { path = "../../testing/matrix-sdk-test-macros" } proptest.workspace = true diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index c81f7d831..32b852cdd 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -290,6 +290,12 @@ pub enum AlgorithmInfo { #[serde(default, skip_serializing_if = "Option::is_none")] session_id: Option, }, + + /// The info if the event was encrypted using m.olm.v1.curve25519-aes-sha2 + OlmV1Curve25519AesSha2 { + // The sender device key, base64 encoded + curve25519_public_key_base64: String, + }, } /// Struct containing information on how an event was decrypted. @@ -315,8 +321,11 @@ pub struct EncryptionInfo { impl EncryptionInfo { /// Helper to get the megolm session id used to encrypt. pub fn session_id(&self) -> Option<&str> { - let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = &self.algorithm_info; - session_id.as_deref() + if let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = &self.algorithm_info { + session_id.as_deref() + } else { + None + } } } @@ -337,26 +346,22 @@ impl<'de> Deserialize<'de> for EncryptionInfo { pub old_session_id: Option, } - let Helper { - sender, - sender_device, - algorithm_info: - AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, session_id }, - verification_state, - old_session_id, - } = Helper::deserialize(deserializer)?; + let Helper { sender, sender_device, algorithm_info, verification_state, old_session_id } = + Helper::deserialize(deserializer)?; - Ok(EncryptionInfo { - sender, - sender_device, - algorithm_info: AlgorithmInfo::MegolmV1AesSha2 { - // Migration, merge the old_session_id in algorithm_info - session_id: session_id.or(old_session_id), - curve25519_key, - sender_claimed_keys, - }, - verification_state, - }) + let algorithm_info = match algorithm_info { + AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, session_id } => { + AlgorithmInfo::MegolmV1AesSha2 { + // Migration, merge the old_session_id in algorithm_info + session_id: session_id.or(old_session_id), + curve25519_key, + sender_claimed_keys, + } + } + other => other, + }; + + Ok(EncryptionInfo { sender, sender_device, algorithm_info, verification_state }) } } @@ -1047,6 +1052,7 @@ mod tests { use std::{collections::BTreeMap, sync::Arc}; use assert_matches::assert_matches; + use assert_matches2::assert_let; use insta::{assert_json_snapshot, with_settings}; use ruma::{ device_id, event_id, events::room::message::RoomMessageEventContent, serde::Raw, user_id, @@ -1598,7 +1604,9 @@ mod tests { let deserialized = serde_json::from_value::(old_format).unwrap(); let expected_session_id = Some("mysessionid76".to_owned()); - let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = deserialized.algorithm_info.clone(); + assert_let!( + AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = deserialized.algorithm_info.clone() + ); assert_eq!(session_id, expected_session_id); assert_json_snapshot!(deserialized); diff --git a/crates/matrix-sdk-crypto/CHANGELOG.md b/crates/matrix-sdk-crypto/CHANGELOG.md index 817d8c129..57c9c7196 100644 --- a/crates/matrix-sdk-crypto/CHANGELOG.md +++ b/crates/matrix-sdk-crypto/CHANGELOG.md @@ -8,9 +8,13 @@ All notable changes to this project will be documented in this file. ### Features +- [**breaking**] The `ProcessedToDeviceEvent::Decrypted` variant now also have an `EncryptionInfo` field. + Format changed from `Decrypted(Raw)` to `Decrypted { raw: Raw, encryption_info: EncryptionInfo) }` + ([5074](https://github.com/matrix-org/matrix-rust-sdk/pull/5074)) + - [**breaking**] Move `session_id` from `EncryptionInfo` to `AlgorithmInfo` as it is megolm specific. Use `EncryptionInfo::session_id()` helper for quick access. - ([#4981](https://github.com/matrix-org/matrix-rust-sdk/pull/4775), [#4864](https://github.com/matrix-org/matrix-rust-sdk/pull/4981)) + ([4981](https://github.com/matrix-org/matrix-rust-sdk/pull/4981)) - Send stable identifier `sender_device_keys` for MSC4147 (Including device keys with Olm-encrypted events). diff --git a/crates/matrix-sdk-crypto/src/machine/mod.rs b/crates/matrix-sdk-crypto/src/machine/mod.rs index aade09f2b..c37dc1ee4 100644 --- a/crates/matrix-sdk-crypto/src/machine/mod.rs +++ b/crates/matrix-sdk-crypto/src/machine/mod.rs @@ -52,8 +52,6 @@ use ruma::{ }; use serde_json::{value::to_raw_value, Value}; use tokio::sync::Mutex; -#[cfg(feature = "experimental-send-custom-to-device")] -use tracing::trace; use tracing::{ debug, error, field::{debug, display}, @@ -1453,7 +1451,10 @@ impl OlmMachine { } } - Some(ProcessedToDeviceEvent::Decrypted(raw_event)) + Some(ProcessedToDeviceEvent::Decrypted { + raw: raw_event, + encryption_info: decrypted.result.encryption_info, + }) } e => { diff --git a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs index ef063edd9..e75377ea8 100644 --- a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs +++ b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs @@ -29,17 +29,25 @@ use ruma::{ encryption::OneTimeKey, events::dummy::ToDeviceDummyEventContent, serde::Raw, + to_device::DeviceIdOrAllDevices, user_id, DeviceId, OwnedOneTimeKeyId, TransactionId, UserId, }; -use serde_json::json; +use serde_json::{json, Value}; use tokio::sync::Mutex; use crate::{ + machine::tests, olm::PrivateCrossSigningIdentity, store::{Changes, CryptoStoreWrapper, MemoryStore}, - types::{events::ToDeviceEvent, requests::AnyOutgoingRequest, DeviceKeys}, + types::{ + events::ToDeviceEvent, + requests::{AnyOutgoingRequest, ToDeviceRequest}, + DeviceKeys, ProcessedToDeviceEvent, + }, + utilities::json_convert, verification::VerificationMachine, - Account, CrossSigningBootstrapRequests, Device, DeviceData, OlmMachine, OtherUserIdentityData, + Account, CrossSigningBootstrapRequests, Device, DeviceData, EncryptionSyncChanges, OlmMachine, + OtherUserIdentityData, }; /// These keys need to be periodically uploaded to the server. @@ -174,6 +182,46 @@ pub async fn get_machine_pair_with_session( build_session_for_pair(alice, bob, one_time_keys).await } +pub async fn send_and_receive_encrypted_to_device_test_helper( + sender: &OlmMachine, + recipient: &OlmMachine, + event_type: &str, + content: Value, +) -> ProcessedToDeviceEvent { + let device = + sender.get_device(recipient.user_id(), recipient.device_id(), None).await.unwrap().unwrap(); + + let raw_encrypted = device + .encrypt_event_raw(event_type, &content) + .await + .expect("Should have encrypted the content"); + + let request = ToDeviceRequest::new( + recipient.user_id(), + DeviceIdOrAllDevices::DeviceId(recipient.device_id().to_owned()), + "m.room.encrypted", + raw_encrypted.cast(), + ); + let event = ToDeviceEvent::new( + sender.user_id().to_owned(), + tests::to_device_requests_to_content(vec![request.clone().into()]), + ); + + let event = json_convert(&event).unwrap(); + + let sync_changes = EncryptionSyncChanges { + to_device_events: vec![event], + changed_devices: &Default::default(), + one_time_keys_counts: &Default::default(), + unused_fallback_keys: None, + next_batch_token: None, + }; + + let (decrypted, _) = recipient.receive_sync_changes(sync_changes).await.unwrap(); + assert_eq!(1, decrypted.len()); + decrypted[0].clone() +} + /// Create a session for the two supplied Olm machines to communicate. pub async fn build_session_for_pair( alice: OlmMachine, diff --git a/crates/matrix-sdk-crypto/src/machine/tests/send_encrypted_to_device.rs b/crates/matrix-sdk-crypto/src/machine/tests/send_encrypted_to_device.rs index 87144c773..0994c5e72 100644 --- a/crates/matrix-sdk-crypto/src/machine/tests/send_encrypted_to_device.rs +++ b/crates/matrix-sdk-crypto/src/machine/tests/send_encrypted_to_device.rs @@ -14,14 +14,21 @@ use assert_matches2::{assert_let, assert_matches}; use insta::assert_json_snapshot; +use matrix_sdk_common::deserialized_responses::{ + AlgorithmInfo, VerificationLevel, VerificationState, +}; use matrix_sdk_test::async_test; use ruma::{events::AnyToDeviceEvent, serde::Raw, to_device::DeviceIdOrAllDevices}; use serde_json::{json, value::to_raw_value, Value}; use crate::{ machine::{ - test_helpers::{get_machine_pair, get_machine_pair_with_session}, + test_helpers::{ + build_session_for_pair, get_machine_pair, get_machine_pair_with_session, + get_prepared_machine_test_helper, send_and_receive_encrypted_to_device_test_helper, + }, tests, + tests::decryption_verification_state::mark_alice_identity_as_verified_test_helper, }, types::{ events::{ToDeviceCustomEvent, ToDeviceEvent}, @@ -29,7 +36,8 @@ use crate::{ ProcessedToDeviceEvent, }, utilities::json_convert, - EncryptionSyncChanges, OlmError, + verification::tests::bob_id, + DeviceData, EncryptionSyncChanges, LocalTrust, OlmError, OlmMachine, }; #[async_test] @@ -48,7 +56,7 @@ async fn test_send_encrypted_to_device() { let raw_encrypted = device .encrypt_event_raw(custom_event_type, &custom_content) .await - .expect("Should have encryted the content"); + .expect("Should have encrypted the content"); let request = ToDeviceRequest::new( bob.user_id(), @@ -88,9 +96,9 @@ async fn test_send_encrypted_to_device() { assert_eq!(1, decrypted.len()); let processed_event = &decrypted[0]; - assert_let!(ProcessedToDeviceEvent::Decrypted(decrypted_event) = processed_event); + assert_let!(ProcessedToDeviceEvent::Decrypted { raw, encryption_info } = processed_event); - let decrypted_event = decrypted_event.deserialize().unwrap(); + let decrypted_event = raw.deserialize().unwrap(); assert_eq!(decrypted_event.event_type().to_string(), custom_event_type.to_owned()); @@ -106,6 +114,242 @@ async fn test_send_encrypted_to_device() { decrypted_value.get("content").unwrap().get("rooms").unwrap().as_array().unwrap(), custom_content.get("rooms").unwrap().as_array().unwrap(), ); + + assert_eq!(encryption_info.sender, alice.user_id().to_owned()); + + assert_matches!(&encryption_info.sender_device, Some(sender_device)); + assert_eq!(sender_device.to_owned(), alice.device_id().to_owned()); + + assert_matches!( + &encryption_info.algorithm_info, + AlgorithmInfo::OlmV1Curve25519AesSha2 { curve25519_public_key_base64 } + ); + let alice_device = + alice.get_device(alice.user_id(), alice.device_id(), None).await.unwrap().unwrap(); + assert_eq!( + curve25519_public_key_base64.to_owned(), + alice_device.curve25519_key().unwrap().to_base64() + ); + + assert_matches!( + &encryption_info.verification_state, + VerificationState::Unverified(VerificationLevel::UnsignedDevice) + ); +} + +#[async_test] +async fn test_receive_custom_encrypted_to_device_fails_if_device_unknown() { + // When decrypting a custom to device, we expect the recipient to know the + // sending device. If the device is not known decryption will fail (see + // `EventError(MissingSigningKey)`). The only exception is room keys were + // this check can be delayed. This is a reason why there is no test for + // verification_state `DeviceLinkProblem::MissingDevice` + + let (bob, otk) = get_prepared_machine_test_helper(bob_id(), false).await; + + let alice = OlmMachine::new(tests::alice_id(), tests::alice_device_id()).await; + + let bob_device = DeviceData::from_machine_test_helper(&bob).await.unwrap(); + alice.store().save_device_data(&[bob_device]).await.unwrap(); + + let (alice, bob) = build_session_for_pair(alice, bob, otk).await; + + let custom_event_type = "m.new_device"; + + let custom_content = json!({ + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + }); + + let device = alice.get_device(bob.user_id(), bob.device_id(), None).await.unwrap().unwrap(); + let raw_encrypted = device + .encrypt_event_raw(custom_event_type, &custom_content) + .await + .expect("Should have encrypted the content"); + + let request = ToDeviceRequest::new( + bob.user_id(), + DeviceIdOrAllDevices::DeviceId(tests::bob_device_id().to_owned()), + "m.room.encrypted", + raw_encrypted.cast(), + ); + + let event = ToDeviceEvent::new( + alice.user_id().to_owned(), + tests::to_device_requests_to_content(vec![request.clone().into()]), + ); + + let event = json_convert(&event).unwrap(); + + let sync_changes = EncryptionSyncChanges { + to_device_events: vec![event], + changed_devices: &Default::default(), + one_time_keys_counts: &Default::default(), + unused_fallback_keys: None, + next_batch_token: None, + }; + + let (decrypted, _) = bob.receive_sync_changes(sync_changes).await.unwrap(); + + assert_eq!(1, decrypted.len()); + let processed_event = &decrypted[0]; + + assert_let!(ProcessedToDeviceEvent::UnableToDecrypt(_) = processed_event); +} + +#[async_test] +async fn test_send_olm_encryption_info_unverified_identity() { + let (alice, bob) = + get_machine_pair_with_session(tests::alice_id(), tests::user_id(), false).await; + + // bootstrap cross-signing + // tests::setup_cross_signing_for_machine_test_helper(&alice, &bob).await; + + // sign alice device and let bob knows about it + tests::sign_alice_device_for_machine_test_helper(&alice, &bob).await; + + let custom_event_type = "m.new_device"; + + let custom_content = json!({ + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + }); + + let processed_event = send_and_receive_encrypted_to_device_test_helper( + &alice, + &bob, + custom_event_type, + custom_content, + ) + .await; + + assert_let!(ProcessedToDeviceEvent::Decrypted { encryption_info, .. } = processed_event); + assert_eq!(encryption_info.sender, alice.user_id().to_owned()); + assert_eq!(encryption_info.sender_device, Some(alice.device_id().to_owned())); + assert_eq!(encryption_info.session_id(), None); + + assert_matches!( + &encryption_info.verification_state, + VerificationState::Unverified(VerificationLevel::UnverifiedIdentity) + ); +} + +#[async_test] +async fn test_send_olm_encryption_info_verified_identity() { + let (alice, bob) = + get_machine_pair_with_session(tests::alice_id(), tests::user_id(), false).await; + + // bootstrap cross-signing + tests::setup_cross_signing_for_machine_test_helper(&alice, &bob).await; + + // sign alice device and let bob knows about it + tests::sign_alice_device_for_machine_test_helper(&alice, &bob).await; + + // Given alice is verified + mark_alice_identity_as_verified_test_helper(&alice, &bob).await; + + let custom_event_type = "m.new_device"; + + let custom_content = json!({ + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + }); + + let processed_event = send_and_receive_encrypted_to_device_test_helper( + &alice, + &bob, + custom_event_type, + custom_content, + ) + .await; + + assert_let!(ProcessedToDeviceEvent::Decrypted { encryption_info, .. } = processed_event); + assert_eq!(encryption_info.sender, alice.user_id().to_owned()); + assert_eq!(encryption_info.sender_device, Some(alice.device_id().to_owned())); + assert_eq!(encryption_info.session_id(), None); + + assert_matches!(&encryption_info.verification_state, VerificationState::Verified); +} + +#[async_test] +async fn test_send_olm_encryption_info_verified_locally() { + let (alice, bob) = + get_machine_pair_with_session(tests::alice_id(), tests::user_id(), false).await; + + let custom_event_type = "m.new_device"; + + let custom_content = json!({ + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + }); + + bob.get_device(alice.user_id(), alice.device_id(), None) + .await + .unwrap() + .unwrap() + .set_local_trust(LocalTrust::Verified) + .await + .unwrap(); + + let processed_event = send_and_receive_encrypted_to_device_test_helper( + &alice, + &bob, + custom_event_type, + custom_content, + ) + .await; + + assert_let!(ProcessedToDeviceEvent::Decrypted { encryption_info, .. } = processed_event); + assert_eq!(encryption_info.sender, alice.user_id().to_owned()); + assert_eq!(encryption_info.sender_device, Some(alice.device_id().to_owned())); + assert_eq!(encryption_info.session_id(), None); + + assert_matches!(&encryption_info.verification_state, VerificationState::Verified); +} + +#[async_test] +async fn test_send_olm_encryption_info_verification_violation() { + let (alice, bob) = + get_machine_pair_with_session(tests::alice_id(), tests::user_id(), false).await; + + // bootstrap cross-signing + tests::setup_cross_signing_for_machine_test_helper(&alice, &bob).await; + + // sign alice device and let bob knows about it + tests::sign_alice_device_for_machine_test_helper(&alice, &bob).await; + + // Given alice is verified + mark_alice_identity_as_verified_test_helper(&alice, &bob).await; + + // Reset alice identity + alice.bootstrap_cross_signing(true).await.unwrap(); + tests::setup_cross_signing_for_machine_test_helper(&alice, &bob).await; + tests::sign_alice_device_for_machine_test_helper(&alice, &bob).await; + + let custom_event_type = "m.new_device"; + + let custom_content = json!({ + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + }); + + let processed_event = send_and_receive_encrypted_to_device_test_helper( + &alice, + &bob, + custom_event_type, + custom_content, + ) + .await; + + assert_let!(ProcessedToDeviceEvent::Decrypted { encryption_info, .. } = processed_event); + assert_eq!(encryption_info.sender, alice.user_id().to_owned()); + assert_eq!(encryption_info.sender_device, Some(alice.device_id().to_owned())); + assert_eq!(encryption_info.session_id(), None); + + assert_matches!( + &encryption_info.verification_state, + VerificationState::Unverified(VerificationLevel::VerificationViolation) + ); } #[async_test] @@ -215,7 +459,7 @@ async fn test_processed_to_device_variants() { assert_eq!(4, processed.len()); let processed_event = &processed[0]; - assert_matches!(processed_event, ProcessedToDeviceEvent::Decrypted(_)); + assert_matches!(processed_event, ProcessedToDeviceEvent::Decrypted { .. }); insta::with_settings!({ prepend_module_to_snapshot => false }, { assert_json_snapshot!( diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 7a84b00bc..721907bd3 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -22,6 +22,9 @@ use std::{ use hkdf::Hkdf; use js_option::JsOption; +use matrix_sdk_common::deserialized_responses::{ + AlgorithmInfo, DeviceLinkProblem, EncryptionInfo, VerificationLevel, VerificationState, +}; #[cfg(test)] use ruma::api::client::dehydrated_device::DehydratedDeviceV1; use ruma::{ @@ -78,7 +81,7 @@ use crate::{ requests::UploadSigningKeysRequest, CrossSigningKey, DeviceKeys, EventEncryptionAlgorithm, MasterPubkey, OneTimeKey, SignedKey, }, - OlmError, SignatureError, + Device, OlmError, SignatureError, }; #[derive(Debug)] @@ -127,6 +130,7 @@ pub(crate) struct DecryptionResult { pub event: Box, pub raw_event: Raw, pub sender_key: Curve25519PublicKey, + pub encryption_info: EncryptionInfo, } /// A hash of a successfully decrypted Olm message. @@ -1469,7 +1473,7 @@ impl Account { // valid. The processing of the historic room key bundle depends on this being // here. Self::check_sender_device_keys(event.as_ref(), sender_key)?; - + let mut sender_device: Option = None; if let AnyDecryptedOlmEvent::RoomKey(_) = event.as_ref() { // If this event is an `m.room_key` event, defer the check for // the Ed25519 key of the sender until we decrypt room events. @@ -1502,16 +1506,69 @@ impl Account { ) .into()); } + sender_device = Some(device); } + let encryption_info = Self::get_olm_encryption_info(sender_key, sender, &sender_device); + Ok(DecryptionResult { event, raw_event: Raw::from_json(RawJsonValue::from_string(plaintext)?), sender_key, + encryption_info, }) } } + /// Gets the EncryptionInfo for a successfully decrypted to-device message + /// that have passed the mismatched sender_key/user_id validation. + /// + /// `sender_device` is optional because for some to-device messages we defer + /// the check for the ed25519 key, in that case the + /// `verification_state` will have a `MissingDevice` link problem. + fn get_olm_encryption_info( + sender_key: Curve25519PublicKey, + sender_id: &UserId, + sender_device: &Option, + ) -> EncryptionInfo { + let verification_state = sender_device + .as_ref() + .map(|device| { + if device.is_verified() { + // The device is locally verified or signed by a verified user + VerificationState::Verified + } else if device.is_cross_signed_by_owner() { + // The device is not verified, but it is signed by its owner + if device + .device_owner_identity + .as_ref() + .expect("A device cross-signed by the owner must have an owner identity") + .was_previously_verified() + { + VerificationState::Unverified(VerificationLevel::VerificationViolation) + } else { + VerificationState::Unverified(VerificationLevel::UnverifiedIdentity) + } + } else { + // No identity or not signed + VerificationState::Unverified(VerificationLevel::UnsignedDevice) + } + }) + .unwrap_or(VerificationState::Unverified(VerificationLevel::None( + DeviceLinkProblem::MissingDevice, + ))); + + let encryption_info = EncryptionInfo { + sender: sender_id.to_owned(), + sender_device: sender_device.as_ref().map(|d| d.device_id().to_owned()), + algorithm_info: AlgorithmInfo::OlmV1Curve25519AesSha2 { + curve25519_public_key_base64: sender_key.to_base64(), + }, + verification_state, + }; + encryption_info + } + /// If the plaintext of the decrypted message includes a /// `sender_device_keys` property per [MSC4147], check that it is valid. /// diff --git a/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs b/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs index e66fcb760..549dd71e9 100644 --- a/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs +++ b/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs @@ -1823,10 +1823,10 @@ mod tests { assert_eq!(1, decrypted.len()); use crate::types::events::EventType; assert_let!( - ProcessedToDeviceEvent::Decrypted(decrypted_event) = decrypted.first().unwrap().clone() + ProcessedToDeviceEvent::Decrypted { raw, .. } = decrypted.first().unwrap().clone() ); assert_eq!( - decrypted_event.get_field::("type").unwrap().unwrap(), + raw.get_field::("type").unwrap().unwrap(), RoomKeyBundleContent::EVENT_TYPE, ); } diff --git a/crates/matrix-sdk-crypto/src/types/mod.rs b/crates/matrix-sdk-crypto/src/types/mod.rs index 19aa95c3d..df37e3aef 100644 --- a/crates/matrix-sdk-crypto/src/types/mod.rs +++ b/crates/matrix-sdk-crypto/src/types/mod.rs @@ -34,7 +34,7 @@ use std::{ }; use as_variant::as_variant; -use matrix_sdk_common::deserialized_responses::PrivOwnedStr; +use matrix_sdk_common::deserialized_responses::{EncryptionInfo, PrivOwnedStr}; use ruma::{ events::AnyToDeviceEvent, serde::{Raw, StringEnum}, @@ -630,11 +630,16 @@ mod test { } /// Represents a to-device event after it has been processed by the olm machine. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug)] pub enum ProcessedToDeviceEvent { /// A successfully-decrypted encrypted event. - /// Contains the raw decrypted event . - Decrypted(Raw), + /// Contains the raw decrypted event and encryption info + Decrypted { + /// The raw decrypted event + raw: Raw, + /// The olm encryption info + encryption_info: EncryptionInfo, + }, /// An encrypted event which could not be decrypted. UnableToDecrypt(Raw), @@ -647,13 +652,12 @@ pub enum ProcessedToDeviceEvent { /// example) Invalid(Raw), } - impl ProcessedToDeviceEvent { /// Converts a ProcessedToDeviceEvent to the `Raw` it /// encapsulates pub fn to_raw(&self) -> Raw { match self { - ProcessedToDeviceEvent::Decrypted(decrypted_event) => decrypted_event.clone(), + ProcessedToDeviceEvent::Decrypted { raw, .. } => raw.clone(), ProcessedToDeviceEvent::UnableToDecrypt(event) => event.clone(), ProcessedToDeviceEvent::PlainText(event) => event.clone(), ProcessedToDeviceEvent::Invalid(event) => event.clone(), diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index c4f5d6891..fcc644b1b 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -1786,7 +1786,7 @@ impl Encryption { // TODO: parallelize that? it's already grouping 250 devices per chunk. for request in requests { - let request = RumaToDeviceRequest::new_raw( + let ruma_request = RumaToDeviceRequest::new_raw( request.event_type.clone(), request.txn_id.clone(), request.messages.clone(), @@ -1794,7 +1794,7 @@ impl Encryption { let send_result = self .client - .send_inner(request, Some(RequestConfig::short_retry()), Default::default()) + .send_inner(ruma_request, Some(RequestConfig::short_retry()), Default::default()) .await; // If the sending failed we need to collect the failures to report them