diff --git a/crates/matrix-sdk-crypto/src/machine/mod.rs b/crates/matrix-sdk-crypto/src/machine/mod.rs index ee6f0cda0..f44540510 100644 --- a/crates/matrix-sdk-crypto/src/machine/mod.rs +++ b/crates/matrix-sdk-crypto/src/machine/mod.rs @@ -939,6 +939,26 @@ impl OlmMachine { } } + #[instrument()] + async fn receive_room_key_bundle( + &self, + sender_key: Curve25519PublicKey, + event: &DecryptedRoomKeyBundleEvent, + changes: &mut Changes, + ) -> OlmResult<()> { + let Some(sender_device_keys) = &event.sender_device_keys else { + warn!("Received a room key bundle with no sender device keys: ignoring"); + return Ok(()); + }; + + changes.received_room_key_bundles.push(StoredRoomKeyBundleData { + sender_user: event.sender.clone(), + sender_data: SenderData::device_info(sender_device_keys.clone()), + bundle_data: event.content.clone(), + }); + Ok(()) + } + fn add_withheld_info(&self, changes: &mut Changes, event: &RoomKeyWithheldEvent) { debug!(?event.content, "Processing `m.room_key.withheld` event"); @@ -1186,6 +1206,7 @@ impl OlmMachine { } AnyDecryptedOlmEvent::RoomKeyBundle(e) => { debug!("Received a room key bundle event {:?}", e); + self.receive_room_key_bundle(decrypted.result.sender_key, e, changes).await?; } AnyDecryptedOlmEvent::Custom(_) => { warn!("Received an unexpected encrypted to-device event"); diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index f5dc8c58b..6e2fd251b 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -70,7 +70,7 @@ use crate::{ identities::{user::UserIdentity, Device, DeviceData, UserDevices, UserIdentityData}, olm::{ Account, ExportedRoomKey, InboundGroupSession, OlmMessageHash, OutboundGroupSession, - PrivateCrossSigningIdentity, Session, StaticAccountData, + PrivateCrossSigningIdentity, SenderData, Session, StaticAccountData, }, types::{ events::room_key_withheld::RoomKeyWithheldEvent, BackupSecrets, CrossSigningSecrets, @@ -101,7 +101,8 @@ pub use memorystore::MemoryStore; pub use traits::{CryptoStore, DynCryptoStore, IntoCryptoStore}; use crate::types::{ - events::room_key_withheld::RoomKeyWithheldContent, room_history::RoomKeyBundle, + events::{room_key_bundle::RoomKeyBundleContent, room_key_withheld::RoomKeyWithheldContent}, + room_history::RoomKeyBundle, }; pub use crate::{ dehydrated_devices::DehydrationError, @@ -541,6 +542,26 @@ pub struct Changes { pub room_settings: HashMap, pub secrets: Vec, pub next_batch_token: Option, + + /// Historical room key history bundles that we have received and should + /// store. + pub received_room_key_bundles: Vec, +} + +/// Information about an [MSC4268] room key bundle. +/// +/// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268 +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct StoredRoomKeyBundleData { + /// The user that sent us this data. + pub sender_user: OwnedUserId, + + /// Information about the sender of this data and how much we trust that + /// information. + pub sender_data: SenderData, + + /// The room key bundle data itself. + pub bundle_data: RoomKeyBundleContent, } /// A user for which we are tracking the list of devices. @@ -573,6 +594,7 @@ impl Changes { && self.room_settings.is_empty() && self.secrets.is_empty() && self.next_batch_token.is_none() + && self.received_room_key_bundles.is_empty() } }