Skip to content

Commit 0f73ffd

Browse files
authored
feat(crypto): Add the EncryptionInfo to the Decrypted ProcessedToDeviceEvent variant
The `ProcessedToDeviceEvent::Decrypted` variant now also have an `EncryptionInfo` field. The enum variant changed from `Decrypted(Raw<AnyToDeviceEvent>)` to `Decrypted { raw: Raw<AnyToDeviceEvent>, encryption_info: EncryptionInfo) }`
1 parent d3be744 commit 0f73ffd

File tree

12 files changed

+421
-48
lines changed

12 files changed

+421
-48
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindings/matrix-sdk-crypto-ffi/src/machine.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,11 @@ impl OlmMachine {
932932
encryption_info.verification_state.to_shield_state_lax().into()
933933
},
934934
},
935+
AlgorithmInfo::OlmV1Curve25519AesSha2 { .. } => {
936+
// cannot happen because `decrypt_room_event` would have fail to decrypt olm for
937+
// a room (EventError::UnsupportedAlgorithm)
938+
panic!("Unsupported olm algorithm in room")
939+
}
935940
})
936941
}
937942

crates/matrix-sdk-common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ web-sys = { workspace = true, features = ["console"] }
5151

5252
[dev-dependencies]
5353
assert_matches.workspace = true
54+
assert_matches2.workspace = true
5455
insta.workspace = true
5556
matrix-sdk-test-macros = { path = "../../testing/matrix-sdk-test-macros" }
5657
proptest.workspace = true

crates/matrix-sdk-common/src/deserialized_responses.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ pub enum AlgorithmInfo {
290290
#[serde(default, skip_serializing_if = "Option::is_none")]
291291
session_id: Option<String>,
292292
},
293+
294+
/// The info if the event was encrypted using m.olm.v1.curve25519-aes-sha2
295+
OlmV1Curve25519AesSha2 {
296+
// The sender device key, base64 encoded
297+
curve25519_public_key_base64: String,
298+
},
293299
}
294300

295301
/// Struct containing information on how an event was decrypted.
@@ -315,8 +321,11 @@ pub struct EncryptionInfo {
315321
impl EncryptionInfo {
316322
/// Helper to get the megolm session id used to encrypt.
317323
pub fn session_id(&self) -> Option<&str> {
318-
let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = &self.algorithm_info;
319-
session_id.as_deref()
324+
if let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = &self.algorithm_info {
325+
session_id.as_deref()
326+
} else {
327+
None
328+
}
320329
}
321330
}
322331

@@ -337,26 +346,22 @@ impl<'de> Deserialize<'de> for EncryptionInfo {
337346
pub old_session_id: Option<String>,
338347
}
339348

340-
let Helper {
341-
sender,
342-
sender_device,
343-
algorithm_info:
344-
AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, session_id },
345-
verification_state,
346-
old_session_id,
347-
} = Helper::deserialize(deserializer)?;
348-
349-
Ok(EncryptionInfo {
350-
sender,
351-
sender_device,
352-
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
353-
// Migration, merge the old_session_id in algorithm_info
354-
session_id: session_id.or(old_session_id),
355-
curve25519_key,
356-
sender_claimed_keys,
357-
},
358-
verification_state,
359-
})
349+
let Helper { sender, sender_device, algorithm_info, verification_state, old_session_id } =
350+
Helper::deserialize(deserializer)?;
351+
352+
let algorithm_info = match algorithm_info {
353+
AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, session_id } => {
354+
AlgorithmInfo::MegolmV1AesSha2 {
355+
// Migration, merge the old_session_id in algorithm_info
356+
session_id: session_id.or(old_session_id),
357+
curve25519_key,
358+
sender_claimed_keys,
359+
}
360+
}
361+
other => other,
362+
};
363+
364+
Ok(EncryptionInfo { sender, sender_device, algorithm_info, verification_state })
360365
}
361366
}
362367

@@ -1047,6 +1052,7 @@ mod tests {
10471052
use std::{collections::BTreeMap, sync::Arc};
10481053

10491054
use assert_matches::assert_matches;
1055+
use assert_matches2::assert_let;
10501056
use insta::{assert_json_snapshot, with_settings};
10511057
use ruma::{
10521058
device_id, event_id, events::room::message::RoomMessageEventContent, serde::Raw, user_id,
@@ -1598,7 +1604,9 @@ mod tests {
15981604
let deserialized = serde_json::from_value::<EncryptionInfo>(old_format).unwrap();
15991605
let expected_session_id = Some("mysessionid76".to_owned());
16001606

1601-
let AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = deserialized.algorithm_info.clone();
1607+
assert_let!(
1608+
AlgorithmInfo::MegolmV1AesSha2 { session_id, .. } = deserialized.algorithm_info.clone()
1609+
);
16021610
assert_eq!(session_id, expected_session_id);
16031611

16041612
assert_json_snapshot!(deserialized);

crates/matrix-sdk-crypto/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- [**breaking**] The `ProcessedToDeviceEvent::Decrypted` variant now also have an `EncryptionInfo` field.
12+
Format changed from `Decrypted(Raw<AnyToDeviceEvent>)` to `Decrypted { raw: Raw<AnyToDeviceEvent>, encryption_info: EncryptionInfo) }`
13+
([5074](https://github.com/matrix-org/matrix-rust-sdk/pull/5074))
14+
1115
- [**breaking**] Move `session_id` from `EncryptionInfo` to `AlgorithmInfo` as it is megolm specific.
1216
Use `EncryptionInfo::session_id()` helper for quick access.
13-
([#4981](https://github.com/matrix-org/matrix-rust-sdk/pull/4775), [#4864](https://github.com/matrix-org/matrix-rust-sdk/pull/4981))
17+
([4981](https://github.com/matrix-org/matrix-rust-sdk/pull/4981))
1418

1519
- Send stable identifier `sender_device_keys` for MSC4147 (Including device
1620
keys with Olm-encrypted events).

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ use ruma::{
5252
};
5353
use serde_json::{value::to_raw_value, Value};
5454
use tokio::sync::Mutex;
55-
#[cfg(feature = "experimental-send-custom-to-device")]
56-
use tracing::trace;
5755
use tracing::{
5856
debug, error,
5957
field::{debug, display},
@@ -1453,7 +1451,10 @@ impl OlmMachine {
14531451
}
14541452
}
14551453

1456-
Some(ProcessedToDeviceEvent::Decrypted(raw_event))
1454+
Some(ProcessedToDeviceEvent::Decrypted {
1455+
raw: raw_event,
1456+
encryption_info: decrypted.result.encryption_info,
1457+
})
14571458
}
14581459

14591460
e => {

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

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,25 @@ use ruma::{
2929
encryption::OneTimeKey,
3030
events::dummy::ToDeviceDummyEventContent,
3131
serde::Raw,
32+
to_device::DeviceIdOrAllDevices,
3233
user_id, DeviceId, OwnedOneTimeKeyId, TransactionId, UserId,
3334
};
34-
use serde_json::json;
35+
use serde_json::{json, Value};
3536
use tokio::sync::Mutex;
3637

3738
use crate::{
39+
machine::tests,
3840
olm::PrivateCrossSigningIdentity,
3941
store::{Changes, CryptoStoreWrapper, MemoryStore},
40-
types::{events::ToDeviceEvent, requests::AnyOutgoingRequest, DeviceKeys},
42+
types::{
43+
events::ToDeviceEvent,
44+
requests::{AnyOutgoingRequest, ToDeviceRequest},
45+
DeviceKeys, ProcessedToDeviceEvent,
46+
},
47+
utilities::json_convert,
4148
verification::VerificationMachine,
42-
Account, CrossSigningBootstrapRequests, Device, DeviceData, OlmMachine, OtherUserIdentityData,
49+
Account, CrossSigningBootstrapRequests, Device, DeviceData, EncryptionSyncChanges, OlmMachine,
50+
OtherUserIdentityData,
4351
};
4452

4553
/// These keys need to be periodically uploaded to the server.
@@ -174,6 +182,46 @@ pub async fn get_machine_pair_with_session(
174182
build_session_for_pair(alice, bob, one_time_keys).await
175183
}
176184

185+
pub async fn send_and_receive_encrypted_to_device_test_helper(
186+
sender: &OlmMachine,
187+
recipient: &OlmMachine,
188+
event_type: &str,
189+
content: Value,
190+
) -> ProcessedToDeviceEvent {
191+
let device =
192+
sender.get_device(recipient.user_id(), recipient.device_id(), None).await.unwrap().unwrap();
193+
194+
let raw_encrypted = device
195+
.encrypt_event_raw(event_type, &content)
196+
.await
197+
.expect("Should have encrypted the content");
198+
199+
let request = ToDeviceRequest::new(
200+
recipient.user_id(),
201+
DeviceIdOrAllDevices::DeviceId(recipient.device_id().to_owned()),
202+
"m.room.encrypted",
203+
raw_encrypted.cast(),
204+
);
205+
let event = ToDeviceEvent::new(
206+
sender.user_id().to_owned(),
207+
tests::to_device_requests_to_content(vec![request.clone().into()]),
208+
);
209+
210+
let event = json_convert(&event).unwrap();
211+
212+
let sync_changes = EncryptionSyncChanges {
213+
to_device_events: vec![event],
214+
changed_devices: &Default::default(),
215+
one_time_keys_counts: &Default::default(),
216+
unused_fallback_keys: None,
217+
next_batch_token: None,
218+
};
219+
220+
let (decrypted, _) = recipient.receive_sync_changes(sync_changes).await.unwrap();
221+
assert_eq!(1, decrypted.len());
222+
decrypted[0].clone()
223+
}
224+
177225
/// Create a session for the two supplied Olm machines to communicate.
178226
pub async fn build_session_for_pair(
179227
alice: OlmMachine,

0 commit comments

Comments
 (0)