diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index a16901afb5..35b6d491ab 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -38,6 +38,7 @@ import { sleep } from "../utils.ts"; import { BackupDecryptor } from "../common-crypto/CryptoBackend.ts"; import { ImportRoomKeyProgressData, ImportRoomKeysOpts, CryptoEvent } from "../crypto-api/index.ts"; import { AESEncryptedSecretStoragePayload } from "../@types/AESEncryptedSecretStoragePayload.ts"; +import { encodeBase64 } from "../base64.ts"; /** Authentification of the backup info, depends on algorithm */ type AuthData = KeyBackupInfo["auth_data"]; @@ -813,6 +814,18 @@ export async function requestKeyBackupVersion( } } +/** + * Checks if the provided decryption key matches the public key of the key backup info. + * @param decryptionKey - The decryption key to check. + * @param keyBackupInfo - The key backup info to check against. + * @returns `true` if the decryption key matches the key backup info, `false` otherwise. + */ +export function decryptionKeyMatchKeyBackupInfo(decryptionKey: Uint8Array, keyBackupInfo: KeyBackupInfo): boolean { + const backupDecryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(encodeBase64(decryptionKey)); + const authData = keyBackupInfo.auth_data; + return authData.public_key === backupDecryptionKey.megolmV1PublicKey.publicKeyBase64; +} + /** * Counts the total number of keys present in a key backup. * @param keyBackup - The key backup to count the keys from. diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 8cc338b8e0..6725e44feb 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -46,7 +46,6 @@ import { CrossSigningStatus, CryptoApi, CryptoCallbacks, - Curve25519AuthData, DecryptionFailureCode, DeviceVerificationStatus, EventEncryptionInfo, @@ -78,7 +77,7 @@ import { secretStorageCanAccessSecrets, secretStorageContainsCrossSigningKeys } import { isVerificationEvent, RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification.ts"; import { EventType, MsgType } from "../@types/event.ts"; import { TypedEventEmitter } from "../models/typed-event-emitter.ts"; -import { RustBackupManager } from "./backup.ts"; +import { decryptionKeyMatchKeyBackupInfo, RustBackupManager } from "./backup.ts"; import { TypedReEmitter } from "../ReEmitter.ts"; import { randomString } from "../randomstring.ts"; import { ClientStoppedError } from "../errors.ts"; @@ -339,13 +338,11 @@ export class RustCrypto extends TypedEventEmitterbackupInfo.auth_data; - if (authData.public_key != backupDecryptionKey.megolmV1PublicKey.publicKeyBase64) { + if (!decryptionKeyMatchKeyBackupInfo(privKey, backupInfo)) { throw new Error(`getBackupDecryptor: key backup on server does not match the decryption key`); } + const backupDecryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(encodeBase64(privKey)); return this.backupManager.createBackupDecryptor(backupDecryptionKey); } @@ -1220,6 +1217,10 @@ export class RustCrypto extends TypedEventEmitter