You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Element-R: implement {get,store}SessionBackupPrivateKey
(#3622)
This commit is contained in:
committed by
GitHub
parent
29b815b678
commit
0e95df5dba
@ -55,7 +55,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@matrix-org/matrix-sdk-crypto-wasm": "^1.0.1",
|
||||
"@matrix-org/matrix-sdk-crypto-wasm": "^1.1.0",
|
||||
"another-json": "^0.2.0",
|
||||
"bs58": "^5.0.0",
|
||||
"content-type": "^1.0.4",
|
||||
|
@ -503,6 +503,16 @@ describe("RustCrypto", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("get|storeSessionBackupPrivateKey", () => {
|
||||
it("can save and restore a key", async () => {
|
||||
const key = "testtesttesttesttesttesttesttest";
|
||||
const rustCrypto = await makeTestRustCrypto();
|
||||
await rustCrypto.storeSessionBackupPrivateKey(new TextEncoder().encode(key));
|
||||
const fetched = await rustCrypto.getSessionBackupPrivateKey();
|
||||
expect(new TextDecoder().decode(fetched!)).toEqual(key);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/** build a basic RustCrypto instance for testing
|
||||
|
@ -3726,10 +3726,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
backupInfo: IKeyBackupInfo,
|
||||
opts?: IKeyBackupRestoreOpts,
|
||||
): Promise<IKeyBackupRestoreResult> {
|
||||
if (!this.crypto) {
|
||||
if (!this.cryptoBackend) {
|
||||
throw new Error("End-to-end encryption disabled");
|
||||
}
|
||||
const privKey = await this.crypto.getSessionBackupPrivateKey();
|
||||
const privKey = await this.cryptoBackend.getSessionBackupPrivateKey();
|
||||
if (!privKey) {
|
||||
throw new Error("Couldn't get key");
|
||||
}
|
||||
@ -3767,7 +3767,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
const cacheCompleteCallback = opts?.cacheCompleteCallback;
|
||||
const progressCallback = opts?.progressCallback;
|
||||
|
||||
if (!this.crypto) {
|
||||
if (!this.cryptoBackend) {
|
||||
throw new Error("End-to-end encryption disabled");
|
||||
}
|
||||
|
||||
@ -3790,9 +3790,13 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
return Promise.reject(new MatrixError({ errcode: MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY }));
|
||||
}
|
||||
|
||||
if (!(privKey instanceof Uint8Array)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||
throw new Error(`restoreKeyBackup expects Uint8Array, got ${privKey}`);
|
||||
}
|
||||
// Cache the key, if possible.
|
||||
// This is async.
|
||||
this.crypto
|
||||
this.cryptoBackend
|
||||
.storeSessionBackupPrivateKey(privKey)
|
||||
.catch((e) => {
|
||||
logger.warn("Error caching session backup key:", e);
|
||||
@ -3849,7 +3853,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
algorithm.free();
|
||||
}
|
||||
|
||||
await this.getCrypto()?.importRoomKeys(keys, {
|
||||
await this.cryptoBackend.importRoomKeys(keys, {
|
||||
progressCallback,
|
||||
untrusted,
|
||||
source: "backup",
|
||||
|
@ -284,6 +284,30 @@ export interface CryptoApi {
|
||||
* @returns a VerificationRequest when the request has been sent to the other party.
|
||||
*/
|
||||
requestDeviceVerification(userId: string, deviceId: string): Promise<VerificationRequest>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Secure key backup
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Fetch the backup decryption key we have saved in our store.
|
||||
*
|
||||
* This can be used for gossiping the key to other devices.
|
||||
*
|
||||
* @returns the key, if any, or null
|
||||
*/
|
||||
getSessionBackupPrivateKey(): Promise<Uint8Array | null>;
|
||||
|
||||
/**
|
||||
* Store the backup decryption key.
|
||||
*
|
||||
* This should be called if the client has received the key from another device via secret sharing (gossiping).
|
||||
*
|
||||
* @param key - the backup decryption key
|
||||
*/
|
||||
storeSessionBackupPrivateKey(key: Uint8Array): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -698,6 +698,33 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
||||
return new RustVerificationRequest(request, this.outgoingRequestProcessor, this._supportedVerificationMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the backup decryption key we have saved in our store.
|
||||
*
|
||||
* Implementation of {@link CryptoApi#getSessionBackupPrivateKey}.
|
||||
*
|
||||
* @returns the key, if any, or null
|
||||
*/
|
||||
public async getSessionBackupPrivateKey(): Promise<Uint8Array | null> {
|
||||
const backupKeys: RustSdkCryptoJs.BackupKeys = await this.olmMachine.getBackupKeys();
|
||||
if (!backupKeys.decryptionKeyBase64) return null;
|
||||
return Buffer.from(backupKeys.decryptionKeyBase64, "base64");
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the backup decryption key.
|
||||
*
|
||||
* Implementation of {@link CryptoApi#storeSessionBackupPrivateKey}.
|
||||
*
|
||||
* @param key - the backup decryption key
|
||||
*/
|
||||
public async storeSessionBackupPrivateKey(key: Uint8Array): Promise<void> {
|
||||
const base64Key = Buffer.from(key).toString("base64");
|
||||
|
||||
// TODO get version from backupManager
|
||||
await this.olmMachine.saveBackupDecryptionKey(RustSdkCryptoJs.BackupDecryptionKey.fromBase64(base64Key), "");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SyncCryptoCallbacks implementation
|
||||
|
@ -1482,10 +1482,10 @@
|
||||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-1.0.1.tgz#21a0557a7bb3f60b37c6d412be8906c056fe79b8"
|
||||
integrity sha512-VTwV5IowvhhLXwAsDDAv02bC5/qBQbG2YtpYAije11253sQ3MePIoSR+dS40Ih3lAlEzqQ00GU3O+i45jMzIRQ==
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-1.1.0.tgz#43996a2c5fc8786999eeaaf6df51007244f6b3c4"
|
||||
integrity sha512-BSMYqXRgQOHG3N18z8b05x3UQcdLL3XDrxjtjjA88t9PadZ7RwNowLm1Sx3ESzdzRX+r1SEVAWs2JnTTs0rv3Q==
|
||||
|
||||
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz":
|
||||
version "3.2.14"
|
||||
|
Reference in New Issue
Block a user