From aacdfdea8533aaa8361797971444b3439c67c2d2 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 24 May 2024 11:13:20 +0100 Subject: [PATCH 1/4] Pass backup version into `CryptoBackend.importBackedUpRoomKeys` --- spec/unit/rust-crypto/rust-crypto.spec.ts | 10 ++++++---- src/client.ts | 12 +++++++----- src/common-crypto/CryptoBackend.ts | 3 ++- src/crypto/index.ts | 6 +++++- src/rust-crypto/backup.ts | 6 +++++- src/rust-crypto/rust-crypto.ts | 8 ++++++-- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index c6507a0d145..f2ce1fff222 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -1396,14 +1396,15 @@ describe("RustCrypto", () => { const rustCrypto = await makeTestRustCrypto(); const olmMachine: OlmMachine = rustCrypto["olmMachine"]; + const backupVersion = testData.SIGNED_BACKUP_DATA.version!; await olmMachine.enableBackupV1( (testData.SIGNED_BACKUP_DATA.auth_data as Curve25519AuthData).public_key, - testData.SIGNED_BACKUP_DATA.version!, + backupVersion, ); // we import two keys: one "from backup", and one "from export" const [backedUpRoomKey, exportedRoomKey] = testData.MEGOLM_SESSION_DATA_ARRAY; - await rustCrypto.importBackedUpRoomKeys([backedUpRoomKey]); + await rustCrypto.importBackedUpRoomKeys([backedUpRoomKey], backupVersion); await rustCrypto.importRoomKeys([exportedRoomKey]); // we ask for the keys that should be backed up @@ -1438,16 +1439,17 @@ describe("RustCrypto", () => { const rustCrypto = await makeTestRustCrypto(); const olmMachine: OlmMachine = rustCrypto["olmMachine"]; + const backupVersion = testData.SIGNED_BACKUP_DATA.version!; await olmMachine.enableBackupV1( (testData.SIGNED_BACKUP_DATA.auth_data as Curve25519AuthData).public_key, - testData.SIGNED_BACKUP_DATA.version!, + backupVersion, ); const backup = Array.from(testData.MEGOLM_SESSION_DATA_ARRAY); // in addition to correct keys, we restore an invalid key backup.push({ room_id: "!roomid", session_id: "sessionid" } as IMegolmSessionData); const progressCallback = jest.fn(); - await rustCrypto.importBackedUpRoomKeys(backup, { progressCallback }); + await rustCrypto.importBackedUpRoomKeys(backup, backupVersion, { progressCallback }); expect(progressCallback).toHaveBeenCalledWith({ total: 3, successes: 0, diff --git a/src/client.ts b/src/client.ts index 27485d076f8..9f859a0469b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3852,12 +3852,13 @@ export class MatrixClient extends TypedEventEmitter { this.logger.warn("Error caching session backup key:", e); }) @@ -3911,7 +3912,8 @@ export class MatrixClient extends TypedEventEmitter { // We have a chunk of decrypted keys: import them try { - await this.cryptoBackend!.importBackedUpRoomKeys(chunk, { + const backupVersion = backupInfo.version!; + await this.cryptoBackend!.importBackedUpRoomKeys(chunk, backupVersion, { untrusted, }); totalImported += chunk.length; @@ -3941,7 +3943,7 @@ export class MatrixClient extends TypedEventEmitter; + importBackedUpRoomKeys(keys: IMegolmSessionData[], backupVersion: string, opts?: ImportRoomKeysOpts): Promise; } /** The methods which crypto implementations should expose to the Sync api diff --git a/src/crypto/index.ts b/src/crypto/index.ts index ff62c429c9f..bf8af76e380 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1888,7 +1888,11 @@ export class Crypto extends TypedEventEmitter { + public importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts: ImportRoomKeysOpts = {}, + ): Promise { opts.source = "backup"; return this.importRoomKeys(keys, opts); } diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index 5c9c5772e2b..758f40c038b 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -239,7 +239,11 @@ export class RustBackupManager extends TypedEventEmitter { + public async importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts?: ImportRoomKeysOpts, + ): Promise { const keysByRoom: Map> = new Map(); for (const key of keys) { const roomId = new RustSdkCryptoJs.RoomId(key.room_id); diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 29373fe3b48..555ada8b354 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -1217,8 +1217,12 @@ export class RustCrypto extends TypedEventEmitter { - return await this.backupManager.importBackedUpRoomKeys(keys, opts); + public async importBackedUpRoomKeys( + keys: IMegolmSessionData[], + backupVersion: string, + opts?: ImportRoomKeysOpts, + ): Promise { + return await this.backupManager.importBackedUpRoomKeys(keys, backupVersion, opts); } /** From ab633daf9bb28e8da31bbb50be6e520d40b4b36f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 24 May 2024 10:53:36 +0100 Subject: [PATCH 2/4] Update matrix-rust-sdk-crypto-wasm to 5.0.0 --- package.json | 2 +- src/rust-crypto/backup.ts | 1 + yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a55e2ee3ea5..9bec27646fb 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-wasm": "^4.9.0", + "@matrix-org/matrix-sdk-crypto-wasm": "^5.0.0", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index 758f40c038b..8eb84887448 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -263,6 +263,7 @@ export class RustBackupManager extends TypedEventEmitter Date: Fri, 24 May 2024 11:14:33 +0100 Subject: [PATCH 3/4] Re-enable test that was disabled for rust-sdk 4.10.0 --- spec/unit/rust-crypto/rust-crypto.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index f2ce1fff222..a87519af363 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -1391,8 +1391,7 @@ describe("RustCrypto", () => { expect(await keyBackupStatusPromise).toBe(true); }); - // XXX: disabled until https://github.com/matrix-org/matrix-rust-sdk/issues/3447 is fixed - it.skip("does not back up keys that came from backup", async () => { + it("does not back up keys that came from backup", async () => { const rustCrypto = await makeTestRustCrypto(); const olmMachine: OlmMachine = rustCrypto["olmMachine"]; From 7afa451446b472d3f3b8173683277d2f8dbe30d8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 24 May 2024 11:44:29 +0100 Subject: [PATCH 4/4] Pass backup version in from `PerSessionKEyBackupDownloader` too missed this one. --- src/rust-crypto/PerSessionKeyBackupDownloader.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/rust-crypto/PerSessionKeyBackupDownloader.ts b/src/rust-crypto/PerSessionKeyBackupDownloader.ts index 7642d52f9d9..ad5a649c51f 100644 --- a/src/rust-crypto/PerSessionKeyBackupDownloader.ts +++ b/src/rust-crypto/PerSessionKeyBackupDownloader.ts @@ -57,10 +57,14 @@ class KeyDownloadRateLimitError extends Error { /** Details of a megolm session whose key we are trying to fetch. */ type SessionInfo = { roomId: string; megolmSessionId: string }; -/** Holds the current backup decryptor and version that should be used. */ +/** Holds the current backup decryptor and version that should be used. + * + * This is intended to be used as an immutable object (a new instance should be created if the configuration changes), + * and some of the logic relies on that, so the properties are marked as `readonly`. + */ type Configuration = { - backupVersion: string; - decryptor: BackupDecryptor; + readonly backupVersion: string; + readonly decryptor: BackupDecryptor; }; /** @@ -392,7 +396,7 @@ export class PerSessionKeyBackupDownloader { for (const k of keys) { k.room_id = sessionInfo.roomId; } - await this.backupManager.importBackedUpRoomKeys(keys); + await this.backupManager.importBackedUpRoomKeys(keys, configuration.backupVersion); } /**