Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub fn make_test_event_with_event_id(
let encryption_info = Arc::new(EncryptionInfo {
sender: (*ALICE).into(),
sender_device: None,
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "1337".to_owned(),
sender_claimed_keys: Default::default(),
Expand Down
2 changes: 2 additions & 0 deletions crates/matrix-sdk-common/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.

### Features

- Add field `forwarder` of type `ForwarderInfo` to `EncryptionInfo`, which which exposes information about the forwarder of the keys with which an event was encrypted if they were shared as part of an [MSC4268](https://github.com/matrix-org/matrix-spec-proposals/pull/4268) room key bundle.
([#5945](https://github.com/matrix-org/matrix-rust-sdk/pull/5945)).
- [**breaking**] Cross-process lock can be dirty. The `CrossProcess::try_lock_once` now returns a new type `CrossProcessResult`, which is an enum with `Clean`, `Dirty` or `Unobtained` variants. When the lock is dirty it means it's been acquired once, then acquired another time from another holder, so the current holder may want to refresh its internal state.
([#5672](https://github.com/matrix-org/matrix-rust-sdk/pull/5672)).

Expand Down
32 changes: 29 additions & 3 deletions crates/matrix-sdk-common/src/deserialized_responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,16 @@ pub enum AlgorithmInfo {
},
}

/// Struct containing information on the forwarder of the keys used to decrypt
/// an event.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ForwarderInfo {
/// The user ID of the forwarder.
pub user_id: OwnedUserId,
/// The device ID of the forwarder.
pub device_id: OwnedDeviceId,
}

/// Struct containing information on how an event was decrypted.
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct EncryptionInfo {
Expand All @@ -328,6 +338,11 @@ pub struct EncryptionInfo {
/// The device ID of the device that sent us the event, note this is
/// untrusted data unless `verification_state` is `Verified` as well.
pub sender_device: Option<OwnedDeviceId>,
/// If the keys for this message were shared-on-invite as part of an
/// [MSC4268] key bundle, information about the forwarder.
///
/// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
pub forwarder: Option<ForwarderInfo>,
/// Information about the algorithm that was used to encrypt the event.
pub algorithm_info: AlgorithmInfo,
/// The verification state of the device that sent us the event, note this
Expand Down Expand Up @@ -361,14 +376,21 @@ impl<'de> Deserialize<'de> for EncryptionInfo {
struct Helper {
pub sender: OwnedUserId,
pub sender_device: Option<OwnedDeviceId>,
pub forwarder: Option<ForwarderInfo>,
pub algorithm_info: AlgorithmInfo,
pub verification_state: VerificationState,
#[serde(rename = "session_id")]
pub old_session_id: Option<String>,
}

let Helper { sender, sender_device, algorithm_info, verification_state, old_session_id } =
Helper::deserialize(deserializer)?;
let Helper {
sender,
sender_device,
forwarder,
algorithm_info,
verification_state,
old_session_id,
} = Helper::deserialize(deserializer)?;

let algorithm_info = match algorithm_info {
AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, session_id } => {
Expand All @@ -382,7 +404,7 @@ impl<'de> Deserialize<'de> for EncryptionInfo {
other => other,
};

Ok(EncryptionInfo { sender, sender_device, algorithm_info, verification_state })
Ok(EncryptionInfo { sender, sender_device, forwarder, algorithm_info, verification_state })
}
}

Expand Down Expand Up @@ -1617,6 +1639,7 @@ mod tests {
encryption_info: Arc::new(EncryptionInfo {
sender: user_id!("@sender:example.com").to_owned(),
sender_device: None,
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "xxx".to_owned(),
sender_claimed_keys: Default::default(),
Expand Down Expand Up @@ -1657,6 +1680,7 @@ mod tests {
"encryption_info": {
"sender": "@sender:example.com",
"sender_device": null,
"forwarder": null,
"algorithm_info": {
"MegolmV1AesSha2": {
"curve25519_key": "xxx",
Expand Down Expand Up @@ -2041,6 +2065,7 @@ mod tests {
let info = EncryptionInfo {
sender: user_id!("@alice:localhost").to_owned(),
sender_device: Some(device_id!("ABCDEFGH").to_owned()),
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "curvecurvecurve".into(),
sender_claimed_keys: Default::default(),
Expand All @@ -2062,6 +2087,7 @@ mod tests {
encryption_info: Arc::new(EncryptionInfo {
sender: user_id!("@sender:example.com").to_owned(),
sender_device: Some(device_id!("ABCDEFGHIJ").to_owned()),
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "xxx".to_owned(),
sender_claimed_keys: BTreeMap::from([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: deserialized
{
"sender": "@alice:localhost",
"sender_device": "ABCDEFGH",
"forwarder": null,
"algorithm_info": {
"MegolmV1AesSha2": {
"curve25519_key": "curvecurvecurve",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ expression: info
{
"sender": "@alice:localhost",
"sender_device": "ABCDEFGH",
"forwarder": null,
"algorithm_info": {
"MegolmV1AesSha2": {
"curve25519_key": "curvecurvecurve",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ expression: "serde_json::to_value(&room_event).unwrap()"
"session_id": "mysessionid112"
}
},
"forwarder": null,
"sender": "@sender:example.com",
"sender_device": "ABCDEFGHIJ",
"verification_state": "Verified"
Expand Down
2 changes: 2 additions & 0 deletions crates/matrix-sdk-crypto/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.

### Features

- Added a new field `forwarder` to `InboundGroupSession` of type `ForwarderData`, which stores information about the forwarder of a session shared in a room key bundle under [MSC4268](https://github.com/matrix-org/matrix-spec-proposals/pull/4268).
([#5980])(https://github.com/matrix-org/matrix-rust-sdk/pull/5980)
- The `OutboundGroupSession` and `OlmMachine` now return the `EncryptionInfo`
used when encrypting raw events.
([#5936](https://github.com/matrix-org/matrix-rust-sdk/pull/5936))
Expand Down
16 changes: 12 additions & 4 deletions crates/matrix-sdk-crypto/src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use matrix_sdk_common::deserialized_responses::WithheldCode;
use matrix_sdk_common::{
BoxFuture,
deserialized_responses::{
AlgorithmInfo, DecryptedRoomEvent, DeviceLinkProblem, EncryptionInfo,
AlgorithmInfo, DecryptedRoomEvent, DeviceLinkProblem, EncryptionInfo, ForwarderInfo,
ProcessedToDeviceEvent, ToDeviceUnableToDecryptInfo, ToDeviceUnableToDecryptReason,
UnableToDecryptInfo, UnableToDecryptReason, UnsignedDecryptionResult,
UnsignedEventLocation, VerificationLevel, VerificationState,
Expand Down Expand Up @@ -1136,6 +1136,7 @@ impl OlmMachine {
EncryptionInfo {
sender: self.inner.user_id.clone(),
sender_device: Some(self.inner.device_id.clone()),
forwarder: None,
algorithm_info,
verification_state: VerificationState::Verified,
}
Expand Down Expand Up @@ -2016,11 +2017,18 @@ impl OlmMachine {
let (verification_state, device_id) =
self.get_room_event_verification_state(session, sender).await?;

let sender = sender.to_owned();

Ok(Arc::new(EncryptionInfo {
sender,
sender: sender.to_owned(),
sender_device: device_id,
forwarder: session.forwarder_data.as_ref().and_then(|data| {
// Per the comment on `KnownSenderData::device_id`, we should never encounter a
// `None` value here, but must still deal with an `Optional` for backwards
// compatibility. The approach below allows us to avoid unwrapping.
data.device_id().map(|device_id| ForwarderInfo {
device_id: device_id.to_owned(),
user_id: data.user_id().to_owned(),
})
}),
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: session.sender_key().to_base64(),
sender_claimed_keys: session
Expand Down
1 change: 1 addition & 0 deletions crates/matrix-sdk-crypto/src/olm/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,7 @@ impl Account {
EncryptionInfo {
sender: sender_id.to_owned(),
sender_device: sender_device.as_ref().map(|d| d.device_id().to_owned()),
forwarder: None,
algorithm_info: AlgorithmInfo::OlmV1Curve25519AesSha2 {
curve25519_public_key_base64: sender_key.to_base64(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ mod tests {
encryption_info: Some(Arc::new(EncryptionInfo {
sender: owned_user_id!("@u:s.co"),
sender_device: None,
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "".to_owned(),
sender_claimed_keys: BTreeMap::new(),
Expand Down
1 change: 1 addition & 0 deletions crates/matrix-sdk-ui/src/timeline/tests/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ async fn test_edit_updates_encryption_info() {
let mut encryption_info = Arc::new(EncryptionInfo {
sender: (*ALICE).into(),
sender_device: None,
forwarder: None,
algorithm_info: AlgorithmInfo::MegolmV1AesSha2 {
curve25519_key: "123".to_owned(),
sender_claimed_keys: BTreeMap::new(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ async fn test_shared_history_out_of_order() {
.await
.expect("Bob should be able to fetch the event Alice has sent");

let encryption_info = event.encryption_info().expect("Event did not have encryption info");

// Check Bob stored information about the key forwarder.
let forwarder_info = encryption_info.forwarder.as_ref().unwrap();
assert_eq!(forwarder_info.user_id, alice_user_id);
assert_eq!(forwarder_info.device_id, alice_device_id);

assert_decrypted_message_eq!(
event,
"It's a secret to everybody",
Expand Down
Loading