feat(crypto): Start using the stable identifier for the sender device keys

This patch updates the sending side of the `sender_device_keys` field
introduced in MSC4147.

Since the MSC got merged, we're switching from the unstable identifier
to the stable one.

A couple of snapshot tests were added modified to make this happen.
This commit is contained in:
Damir Jelić
2025-04-23 13:48:11 +02:00
parent 426a4ff1bf
commit a60e336f85
7 changed files with 98 additions and 25 deletions

View File

@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
### Features
- Send stable identifier `sender_device_keys` for MSC4147 (Including device
keys with Olm-encrypted events).
([#4964](https://github.com/matrix-org/matrix-rust-sdk/pull/4964))
- Add experimental APIs for sharing encrypted room key history with new members, `Store::build_room_key_bundle` and `OlmMachine::share_room_key_bundle_data`.
([#4775](https://github.com/matrix-org/matrix-rust-sdk/pull/4775), [#4864](https://github.com/matrix-org/matrix-rust-sdk/pull/4864))

View File

@@ -222,11 +222,11 @@ async fn test_processed_to_device_variants() {
processed_event.to_raw().deserialize_as::<Value>().unwrap(),
{
".keys.ed25519" => "[sender_ed25519_key]",
r#"["org.matrix.msc4147.device_keys"].device_id"# => "[ABCDEFGH]",
r#"["org.matrix.msc4147.device_keys"].keys"# => "++REDACTED++",
r#"["org.matrix.msc4147.device_keys"].signatures"# => "++REDACTED++",
r#"["sender_device_keys"].device_id"# => "[ABCDEFGH]",
r#"["sender_device_keys"].keys"# => "++REDACTED++",
r#"["sender_device_keys"].signatures"# => "++REDACTED++",
// Redacted because depending on feature flags
r#"["org.matrix.msc4147.device_keys"].algorithms"# => "++REDACTED++",
r#"["sender_device_keys"].algorithms"# => "++REDACTED++",
".recipient_keys.ed25519" => "[recipient_sender_key]",
}
);

View File

@@ -1,6 +1,6 @@
---
source: crates/matrix-sdk-crypto/src/machine/tests/send_encrypted_to_device.rs
expression: "serde_json::from_str::<Value>(processed_event.to_raw().json().get()).unwrap()"
expression: "processed_event.to_raw().deserialize_as::<Value>().unwrap()"
---
{
"content": {
@@ -16,17 +16,17 @@ expression: "serde_json::from_str::<Value>(processed_event.to_raw().json().get()
"keys": {
"ed25519": "[sender_ed25519_key]"
},
"org.matrix.msc4147.device_keys": {
"recipient": "@bob:example.com",
"recipient_keys": {
"ed25519": "[recipient_sender_key]"
},
"sender": "@alice:example.org",
"sender_device_keys": {
"algorithms": "++REDACTED++",
"device_id": "[ABCDEFGH]",
"keys": "++REDACTED++",
"signatures": "++REDACTED++",
"user_id": "@alice:example.org"
},
"recipient": "@bob:example.com",
"recipient_keys": {
"ed25519": "[recipient_sender_key]"
},
"sender": "@alice:example.org",
"type": "rtc.call.encryption_keys"
}

View File

@@ -30,7 +30,7 @@ use crate::{
error::{EventError, OlmResult, SessionUnpickleError},
types::{
events::{
olm_v1::DecryptedOlmV1Event,
olm_v1::{DecryptedOlmV1Event, OlmV1Keys},
room::encrypted::{OlmV1Curve25519AesSha2Content, ToDeviceEncryptedEventContent},
EventType,
},
@@ -192,15 +192,13 @@ impl Session {
let content = DecryptedOlmV1Event {
sender: self.our_device_keys.user_id.clone(),
recipient: recipient_device.user_id().into(),
keys: crate::types::events::olm_v1::OlmV1Keys {
keys: OlmV1Keys {
ed25519: self
.our_device_keys
.ed25519_key()
.expect("Our own device should have an Ed25519 public key"),
},
recipient_keys: crate::types::events::olm_v1::OlmV1Keys {
ed25519: recipient_signing_key,
},
recipient_keys: OlmV1Keys { ed25519: recipient_signing_key },
sender_device_keys: Some(self.our_device_keys.clone()),
content,
};
@@ -408,13 +406,10 @@ mod tests {
)
.unwrap();
// Also ensure that the encrypted payload has the device keys under the unstable
// Also ensure that the encrypted payload has the device keys under the stable
// prefix
let plaintext: Value = serde_json::from_str(&bob_session_result.plaintext).unwrap();
assert_eq!(
plaintext["org.matrix.msc4147.device_keys"]["user_id"].as_str(),
Some("@alice:localhost")
);
assert_eq!(plaintext["sender_device_keys"]["user_id"].as_str(), Some("@alice:localhost"));
// And the serialized object matches the format as specified in
// DecryptedOlmV1Event

View File

@@ -203,10 +203,7 @@ impl<C: EventType + Debug + Sized + Serialize> Serialize for DecryptedOlmV1Event
recipient: &'a UserId,
keys: &'a OlmV1Keys,
recipient_keys: &'a OlmV1Keys,
#[serde(
rename = "org.matrix.msc4147.device_keys",
skip_serializing_if = "Option::is_none"
)]
#[serde(skip_serializing_if = "Option::is_none")]
sender_device_keys: Option<&'a DeviceKeys>,
content: &'a C,
#[serde(rename = "type")]
@@ -326,6 +323,7 @@ mod tests {
use std::collections::BTreeMap;
use assert_matches::assert_matches;
use insta::{assert_json_snapshot, with_settings};
use ruma::{device_id, owned_user_id, KeyId};
use serde_json::{json, Value};
use similar_asserts::assert_eq;
@@ -504,6 +502,17 @@ mod tests {
(sender_device_keys_json, sender_device_keys)
}
#[test]
fn decrypted_to_device_event_snapshot() {
let event_json = room_key_event();
let event: DecryptedRoomKeyEvent = serde_json::from_value(event_json)
.expect("JSON should deserialize to the right event type");
with_settings!({ sort_maps => true, prepend_module_to_snapshot => false }, {
assert_json_snapshot!(event);
})
}
#[test]
fn deserialization() -> Result<(), serde_json::Error> {
macro_rules! assert_deserialization_result {
@@ -571,6 +580,10 @@ mod tests {
// Then it contains the sender_device_keys
assert_eq!(event.sender_device_keys, Some(sender_device_keys));
with_settings!({ sort_maps => true, prepend_module_to_snapshot => false }, {
assert_json_snapshot!(event);
});
}
#[test]

View File

@@ -0,0 +1,22 @@
---
source: crates/matrix-sdk-crypto/src/types/events/olm_v1.rs
expression: event
---
{
"sender": "@alice:example.org",
"recipient": "@bob:example.org",
"keys": {
"ed25519": "aOfOnlaeMb5GW1TxkZ8pXnblkGMgAvps+lAukrdYaZk"
},
"recipient_keys": {
"ed25519": "aOfOnlaeMb5GW1TxkZ8pXnblkGMgAvps+lAukrdYaZk"
},
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"org.matrix.msc3061.shared_history": false,
"room_id": "!Cuyf34gef24t:localhost",
"session_id": "ZFD6+OmV7fVCsJ7Gap8UnORH8EnmiAkes8FAvQuCw/I",
"session_key": "AgAAAADNp1EbxXYOGmJtyX4AkD1bvJvAUyPkbIaKxtnGKjvSQ3E/4mnuqdM4vsmNzpO1EeWzz1rDkUpYhYE9kP7sJhgLXijVv80fMPHfGc49hPdu8A+xnwD4SQiYdFmSWJOIqsxeo/fiHtino//CDQENtcKuEt0I9s0+Kk4YSH310Szse2RQ+vjple31QrCexmqfFJzkR/BJ5ogJHrPBQL0LgsPyglIbMTLg7qygIaYU5Fe2QdKMH7nTZPNIRHh1RaMfHVETAUJBax88EWZBoifk80gdHUwHSgMk77vCc2a5KHKLDA"
},
"type": "m.room_key"
}

View File

@@ -0,0 +1,39 @@
---
source: crates/matrix-sdk-crypto/src/types/events/olm_v1.rs
expression: event
---
{
"sender": "@alice:example.org",
"recipient": "@bob:example.org",
"keys": {
"ed25519": "aOfOnlaeMb5GW1TxkZ8pXnblkGMgAvps+lAukrdYaZk"
},
"recipient_keys": {
"ed25519": "aOfOnlaeMb5GW1TxkZ8pXnblkGMgAvps+lAukrdYaZk"
},
"sender_device_keys": {
"algorithms": [
"m.olm.v1.curve25519-aes-sha2"
],
"device_id": "DEV",
"keys": {
"curve25519:DEV": "c29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28",
"ed25519:DEV": "b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28"
},
"signatures": {
"@u:s.co": {
"ed25519:DEV": "mia28GKixFzOWKJ0h7Bdrdy2fjxiHCsst1qpe467FbW85H61UlshtKBoAXfTLlVfi0FX+/noJ8B3noQPnY+9Cg",
"ed25519:ssk": "mia28GKixFzOWKJ0h7Bdrdy2fjxiHCsst1qpe467FbW85H61UlshtKBoAXfTLlVfi0FX+/noJ8B3noQPnY+9Cg"
}
},
"user_id": "@u:s.co"
},
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"org.matrix.msc3061.shared_history": false,
"room_id": "!Cuyf34gef24t:localhost",
"session_id": "ZFD6+OmV7fVCsJ7Gap8UnORH8EnmiAkes8FAvQuCw/I",
"session_key": "AgAAAADNp1EbxXYOGmJtyX4AkD1bvJvAUyPkbIaKxtnGKjvSQ3E/4mnuqdM4vsmNzpO1EeWzz1rDkUpYhYE9kP7sJhgLXijVv80fMPHfGc49hPdu8A+xnwD4SQiYdFmSWJOIqsxeo/fiHtino//CDQENtcKuEt0I9s0+Kk4YSH310Szse2RQ+vjple31QrCexmqfFJzkR/BJ5ogJHrPBQL0LgsPyglIbMTLg7qygIaYU5Fe2QdKMH7nTZPNIRHh1RaMfHVETAUJBax88EWZBoifk80gdHUwHSgMk77vCc2a5KHKLDA"
},
"type": "m.room_key"
}