Skip to content

Commit 1396738

Browse files
authored
Remember the public Curve25519 key of the sender of the historic room key bundle
1 parent 669ebf2 commit 1396738

File tree

10 files changed

+98
-9
lines changed

10 files changed

+98
-9
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ impl OlmMachine {
967967
#[instrument()]
968968
async fn receive_room_key_bundle_data(
969969
&self,
970+
sender_key: Curve25519PublicKey,
970971
event: &DecryptedRoomKeyBundleEvent,
971972
changes: &mut Changes,
972973
) -> OlmResult<()> {
@@ -975,8 +976,8 @@ impl OlmMachine {
975976
return Ok(());
976977
};
977978

978-
// We already checked that `sender_device_keys` matches the actual sender of the
979-
// message when we decrypted the message, which included doing
979+
// NOTE: We already checked that `sender_device_keys` matches the actual sender
980+
// of the message when we decrypted the message, which included doing
980981
// `DeviceData::try_from` on it, so it can't fail.
981982

982983
let sender_device_data =
@@ -986,6 +987,7 @@ impl OlmMachine {
986987
changes.received_room_key_bundles.push(StoredRoomKeyBundleData {
987988
sender_user: event.sender.clone(),
988989
sender_data: SenderData::from_device(&sender_device),
990+
sender_key,
989991
bundle_data: event.content.clone(),
990992
});
991993
Ok(())
@@ -1287,7 +1289,7 @@ impl OlmMachine {
12871289
}
12881290
AnyDecryptedOlmEvent::RoomKeyBundle(e) => {
12891291
debug!("Received a room key bundle event {:?}", e);
1290-
self.receive_room_key_bundle_data(e, changes).await?;
1292+
self.receive_room_key_bundle_data(decrypted.result.sender_key, e, changes).await?;
12911293
}
12921294
AnyDecryptedOlmEvent::Custom(_) => {
12931295
warn!("Received an unexpected encrypted to-device event");

crates/matrix-sdk-crypto/src/store/integration_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,7 @@ macro_rules! cryptostore_integration_tests {
13041304

13051305
StoredRoomKeyBundleData {
13061306
sender_user: sender_user.to_owned(),
1307+
sender_key: Curve25519PublicKey::from_bytes([0u8; 32]),
13071308
sender_data: SenderData::unknown(),
13081309
bundle_data: RoomKeyBundleContent {
13091310
room_id: room_id!("!room:example.org").to_owned(),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,7 @@ impl Store {
13421342
/// while let Some(bundle_info) = bundle_stream.next().await {
13431343
/// // Try to find the bundle content in the store and if it's valid accept it.
13441344
/// if let Some(bundle_content) = machine.store().get_received_room_key_bundle_data(&bundle_info.room_id, &bundle_info.sender).await? {
1345-
/// let StoredRoomKeyBundleData { sender_user, sender_data, bundle_data } = bundle_content;
1345+
/// let StoredRoomKeyBundleData { sender_user, sender_data, bundle_data, .. } = bundle_content;
13461346
/// // Download the bundle now and import it.
13471347
/// let bundle: RoomKeyBundle = todo!("Download the bundle");
13481348
/// machine.store().receive_room_key_bundle(

crates/matrix-sdk-crypto/src/store/types.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ pub struct StoredRoomKeyBundleData {
9393
/// The user that sent us this data.
9494
pub sender_user: OwnedUserId,
9595

96+
/// The [`Curve25519PublicKey`] of the device that sent us this data.
97+
pub sender_key: Curve25519PublicKey,
98+
9699
/// Information about the sender of this data and how much we trust that
97100
/// information.
98101
pub sender_data: SenderData,
@@ -491,13 +494,19 @@ pub struct RoomKeyBundleInfo {
491494
/// The user ID of the person that sent us the historic room key bundle.
492495
pub sender: OwnedUserId,
493496

497+
/// The [`Curve25519PublicKey`] of the device that sent us this data.
498+
pub sender_key: Curve25519PublicKey,
499+
494500
/// The ID of the room the bundle should be used in.
495501
pub room_id: OwnedRoomId,
496502
}
497503

498504
impl From<&StoredRoomKeyBundleData> for RoomKeyBundleInfo {
499505
fn from(value: &StoredRoomKeyBundleData) -> Self {
500-
let StoredRoomKeyBundleData { sender_user, sender_data: _, bundle_data } = value;
501-
Self { sender: sender_user.clone(), room_id: bundle_data.room_id.clone() }
506+
let StoredRoomKeyBundleData { sender_user, sender_data: _, bundle_data, sender_key } =
507+
value;
508+
let sender_key = *sender_key;
509+
510+
Self { sender: sender_user.clone(), room_id: bundle_data.room_id.clone(), sender_key }
502511
}
503512
}

crates/matrix-sdk-indexeddb/src/crypto_store/migrations/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod v0_to_v5;
2525
mod v10_to_v11;
2626
mod v11_to_v12;
2727
mod v12_to_v13;
28+
mod v13_to_v14;
2829
mod v5_to_v7;
2930
mod v7;
3031
mod v7_to_v8;
@@ -163,6 +164,11 @@ pub async fn open_and_upgrade_db(
163164
v12_to_v13::schema_add(name).await?;
164165
}
165166

167+
if old_version < 14 {
168+
v13_to_v14::data_migrate(name, serializer).await?;
169+
v13_to_v14::schema_bump(name).await?;
170+
}
171+
166172
// If you add more migrations here, you'll need to update
167173
// `tests::EXPECTED_SCHEMA_VERSION`.
168174

@@ -267,7 +273,7 @@ mod tests {
267273
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
268274

269275
/// The schema version we expect after we open the store.
270-
const EXPECTED_SCHEMA_VERSION: u32 = 13;
276+
const EXPECTED_SCHEMA_VERSION: u32 = 14;
271277

272278
/// Adjust this to test do a more comprehensive perf test
273279
const NUM_RECORDS_FOR_PERF: usize = 2_000;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2025 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
use web_sys::{DomException, IdbTransactionMode};
18+
19+
use super::MigrationDb;
20+
use crate::{
21+
crypto_store::{keys, migrations::do_schema_upgrade, Result},
22+
serializer::IndexeddbSerializer,
23+
};
24+
25+
pub(crate) async fn data_migrate(name: &str, _: &IndexeddbSerializer) -> Result<()> {
26+
let db = MigrationDb::new(name, 14).await?;
27+
let transaction = db.transaction_on_one_with_mode(
28+
keys::RECEIVED_ROOM_KEY_BUNDLES,
29+
IdbTransactionMode::Readwrite,
30+
)?;
31+
let store = transaction.object_store(keys::RECEIVED_ROOM_KEY_BUNDLES)?;
32+
33+
// The schema didn't actually change, we just changed the objects that are
34+
// stored. So let us remove them.
35+
store.clear()?;
36+
37+
transaction.await.into_result()?;
38+
39+
Ok(())
40+
}
41+
42+
/// Perform the schema upgrade v13 to v14, just bumping the schema version since
43+
/// the schema didn't actually change.
44+
pub(crate) async fn schema_bump(name: &str) -> Result<(), DomException> {
45+
// Just bump the version number to 14 to demonstrate that we have run the data
46+
// changes from data_migrate.
47+
do_schema_upgrade(name, 14, |_, _, _| Ok(())).await
48+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
DROP TABLE "received_room_key_bundle";
2+
3+
CREATE TABLE "received_room_key_bundle"
4+
(
5+
"room_id" BLOB NOT NULL,
6+
"sender_user_id" BLOB NOT NULL,
7+
"bundle_data" BLOB NOT NULL
8+
);
9+
10+
CREATE UNIQUE INDEX "received_room_key_bundle_room_id_user_id_idx"
11+
ON "received_room_key_bundle" ("room_id", "sender_user_id");

crates/matrix-sdk-sqlite/src/crypto_store.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl SqliteCryptoStore {
167167
}
168168
}
169169

170-
const DATABASE_VERSION: u8 = 10;
170+
const DATABASE_VERSION: u8 = 11;
171171

172172
/// key for the dehydrated device pickle key in the key/value table.
173173
const DEHYDRATED_DEVICE_PICKLE_KEY: &str = "dehydrated_device_pickle_key";
@@ -273,6 +273,16 @@ async fn run_migrations(conn: &SqliteAsyncConn, version: u8) -> Result<()> {
273273
.await?;
274274
}
275275

276+
if version < 11 {
277+
conn.with_transaction(|txn| {
278+
txn.execute_batch(include_str!(
279+
"../migrations/crypto_store/011_received_room_key_bundles_with_curve_key.sql"
280+
))?;
281+
txn.set_db_version(11)
282+
})
283+
.await?;
284+
}
285+
276286
Ok(())
277287
}
278288

crates/matrix-sdk/src/encryption/tasks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ mod test {
479479
};
480480
use ruma::{event_id, room_id, user_id};
481481
use serde_json::json;
482+
use vodozemac::Curve25519PublicKey;
482483
use wiremock::MockServer;
483484

484485
use super::*;
@@ -584,6 +585,7 @@ mod test {
584585

585586
let bundle_info = RoomKeyBundleInfo {
586587
sender: bob_user_id.to_owned(),
588+
sender_key: Curve25519PublicKey::from_bytes([0u8; 32]),
587589
room_id: joined_room_id.to_owned(),
588590
};
589591

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub(crate) async fn maybe_accept_key_bundle(room: &Room, inviter: &UserId) -> Re
124124
return Ok(());
125125
};
126126

127-
let Some(StoredRoomKeyBundleData { sender_user, sender_data, bundle_data }) =
127+
let Some(StoredRoomKeyBundleData { sender_user, sender_data, bundle_data, .. }) =
128128
olm_machine.store().get_received_room_key_bundle_data(room.room_id(), inviter).await?
129129
else {
130130
// No bundle received (yet).

0 commit comments

Comments
 (0)