Skip to content

Commit 898bc7a

Browse files
committed
wip
1 parent 4319703 commit 898bc7a

File tree

4 files changed

+153
-4
lines changed

4 files changed

+153
-4
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ use crate::{
9595
AnyIncomingResponse, KeysQueryRequest, OutgoingRequest, ToDeviceRequest,
9696
UploadSigningKeysRequest,
9797
},
98+
room_history::RoomKeyBundle,
9899
EventEncryptionAlgorithm, ProcessedToDeviceEvent, Signatures,
99100
},
100101
utilities::timestamp_to_iso8601,
@@ -968,6 +969,43 @@ impl OlmMachine {
968969
Ok(())
969970
}
970971

972+
/// Import the contents of a downloaded and decrypted [MSC4268] key bundle.
973+
///
974+
/// # Arguments
975+
///
976+
/// * `bundle` - The decrypted and deserialized bundle itself.
977+
/// * `room_id` - The room that we expect this bundle to correspond to.
978+
/// * `sender_user` - The user that sent us the to-device message pointing
979+
/// to this data.
980+
/// * `sender_data` - Information on the sending device at the time we
981+
/// received that message.
982+
///
983+
/// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
984+
#[instrument(skip(bundle))]
985+
pub async fn receive_room_key_bundle(
986+
&self,
987+
bundle: &RoomKeyBundle,
988+
room_id: &RoomId,
989+
sender_user: &UserId,
990+
sender_data: &SenderData,
991+
) -> OlmResult<()> {
992+
for key in bundle.room_keys.iter() {
993+
if key.room_id != room_id {
994+
warn!("Ignoring key for incorrect room {} in bundle", key.room_id);
995+
continue;
996+
}
997+
998+
let _session = match InboundGroupSession::try_from(key) {
999+
Ok(session) => session,
1000+
Err(e) => {
1001+
warn!("Ignoring key in bundle with import error: {}", e);
1002+
continue;
1003+
}
1004+
};
1005+
}
1006+
Ok(())
1007+
}
1008+
9711009
fn add_withheld_info(&self, changes: &mut Changes, event: &RoomKeyWithheldEvent) {
9721010
debug!(?event.content, "Processing `m.room_key.withheld` event");
9731011

crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ use crate::{
5555
room::encrypted::{EncryptedEvent, RoomEventEncryptionScheme},
5656
room_key,
5757
},
58+
room_history::HistoricRoomKey,
5859
serialize_curve_key, EventEncryptionAlgorithm, SigningKeys,
5960
},
6061
};
61-
6262
// TODO: add creation times to the inbound group sessions so we can export
6363
// sessions that were created between some time period, this should only be set
6464
// for non-imported sessions.
@@ -672,6 +672,42 @@ fn default_algorithm() -> EventEncryptionAlgorithm {
672672
EventEncryptionAlgorithm::MegolmV1AesSha2
673673
}
674674

675+
impl TryFrom<&HistoricRoomKey> for InboundGroupSession {
676+
type Error = SessionCreationError;
677+
678+
fn try_from(key: &HistoricRoomKey) -> Result<Self, Self::Error> {
679+
let HistoricRoomKey {
680+
algorithm,
681+
room_id,
682+
sender_key,
683+
session_id,
684+
session_key,
685+
sender_claimed_keys,
686+
} = key;
687+
688+
let config = OutboundGroupSession::session_config(algorithm)?;
689+
let session = InnerSession::import(session_key, config);
690+
let first_known_index = session.first_known_index();
691+
692+
Ok(InboundGroupSession {
693+
inner: Mutex::new(session).into(),
694+
session_id: session_id.to_owned().into(),
695+
creator_info: SessionCreatorInfo {
696+
curve25519_key: *sender_key,
697+
signing_keys: sender_claimed_keys.to_owned().into(),
698+
},
699+
sender_data: SenderData::default(),
700+
history_visibility: None.into(),
701+
first_known_index,
702+
room_id: room_id.to_owned(),
703+
imported: true,
704+
algorithm: algorithm.to_owned().into(),
705+
backed_up: AtomicBool::from(false).into(),
706+
shared_history: true,
707+
})
708+
}
709+
}
710+
675711
impl TryFrom<&ExportedRoomKey> for InboundGroupSession {
676712
type Error = SessionCreationError;
677713

crates/matrix-sdk/src/room/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,24 @@ impl Room {
264264
false
265265
});
266266

267+
#[cfg(all(feature = "experimental-share-history-on-invite", feature = "e2e-encryption"))]
268+
let inviter = if prev_room_state == RoomState::Invited {
269+
self.invite_details().await?.inviter
270+
} else {
271+
None
272+
};
273+
267274
self.client.join_room_by_id(self.room_id()).await?;
268275

269276
if mark_as_direct {
270277
self.set_is_direct(true).await?;
271278
}
272279

280+
#[cfg(all(feature = "experimental-share-history-on-invite", feature = "e2e-encryption"))]
281+
if let Some(inviter) = inviter {
282+
shared_room_history::accept_key_bundle(&self, inviter.user_id()).await?;
283+
}
284+
273285
Ok(())
274286
}
275287

crates/matrix-sdk/src/room/shared_room_history.rs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::iter;
15+
use std::{iter, ops::Deref};
1616

17-
use ruma::OwnedUserId;
17+
use matrix_sdk_base::media::{MediaFormat, MediaRequestParameters};
18+
use ruma::{api::client::authenticated_media, events::room::MediaSource, OwnedUserId, UserId};
1819
use tracing::{info, instrument, warn};
1920

20-
use crate::{crypto::types::events::room_key_bundle::RoomKeyBundleContent, Error, Result, Room};
21+
use crate::{
22+
crypto::types::{events::room_key_bundle::RoomKeyBundleContent, room_history::RoomKeyBundle},
23+
Error, Result, Room,
24+
};
2125

2226
/// Share any shareable E2EE history in the given room with the given recipient,
2327
/// as per [MSC4268].
@@ -86,3 +90,62 @@ pub async fn share_room_history(room: &Room, user_id: OwnedUserId) -> Result<()>
8690
}
8791
Ok(())
8892
}
93+
94+
/// Having accepted an invite for the given room from the given user, download a
95+
/// key bundle and import the room keys, as per [MSC4268].
96+
///
97+
/// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
98+
#[instrument(skip(room), fields(room_id = ?room.room_id()))]
99+
pub async fn accept_key_bundle(room: &Room, user_id: &UserId) -> Result<()> {
100+
// TODO: retry this if it gets interrupted or it fails.
101+
// TODO: do this in the background.
102+
103+
let client = &room.client;
104+
let olm_machine = client.olm_machine().await;
105+
let Some(olm_machine) = olm_machine.deref() else {
106+
warn!("Not fetching room key bundle as the Olm machine is not available");
107+
return Ok(());
108+
};
109+
110+
let Some(bundle) =
111+
olm_machine.store().get_received_room_key_bundle_data(room.room_id(), user_id).await?
112+
else {
113+
// No bundle received (yet).
114+
// TODO: deal with the bundle arriving later (https://github.com/matrix-org/matrix-rust-sdk/issues/4926)
115+
return Ok(());
116+
};
117+
118+
// TODO
119+
// olm_machine.store().clear_received_room_key_bundle_data(room.room_id(),
120+
// user_id).await?;
121+
122+
let bundle_content = client
123+
.media()
124+
.get_media_content(
125+
&MediaRequestParameters {
126+
source: MediaSource::Encrypted(Box::new(bundle.bundle_data.file)),
127+
format: MediaFormat::File,
128+
},
129+
false,
130+
)
131+
.await?;
132+
133+
let bundle_content: RoomKeyBundle = match serde_json::from_slice(&bundle_content) {
134+
Ok(bundle_content) => bundle_content,
135+
Err(err) => {
136+
warn!("Failed to deserialize room key bundle: {}", err);
137+
return Ok(());
138+
}
139+
};
140+
141+
olm_machine
142+
.receive_room_key_bundle(
143+
&bundle_content,
144+
room.room_id(),
145+
&bundle.sender_user,
146+
&bundle.sender_data,
147+
)
148+
.await?;
149+
150+
Ok(())
151+
}

0 commit comments

Comments
 (0)