diff --git a/src/crypto-api.ts b/src/crypto-api.ts index 1c3a3a6356c..3fe084db167 100644 --- a/src/crypto-api.ts +++ b/src/crypto-api.ts @@ -490,6 +490,15 @@ export interface CryptoApi { */ resetKeyBackup(): Promise; + /** + * Update the signature of the backup specified via privateKey and uploaded this change to the server. + * This is an altered copy of {@link @./rust-crypto/rust-crypto.ts#RustCrypto#resetKeyBackup}. + * + * @param privateKey The privat key of the backup which should be updated. + * @param version The version of the backup that should be updated. + */ + resignKeyBackup(privateKey: Uint8Array, version: string): Promise; + /** * Deletes the given key backup. * diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index 5c9c5772e2b..20ae5749abc 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -544,6 +544,47 @@ export class RustBackupManager extends TypedEventEmitter Promise): Promise { + const pubKey = backupDecKey.megolmV1PublicKey; + const authData = { public_key: pubKey.publicKeyBase64 }; + + await signObject(authData); + + // An alternative implementation could be using src\crypto\EncryptionSetup.ts and EncryptionSetupOperation, similar to: + // const setupBuilder = new EncryptionSetupBuilder(); setupBuilder.addSessionBackup(keyBackup); setupBuilder.buildOperation().apply(); + const res = await this.http.authedRequest<{ version: string }>( + Method.Put, + "/room_keys/version/" + version, + undefined, + { + algorithm: pubKey.algorithm, + auth_data: authData, + }, + { + prefix: ClientPrefix.V3, + }, + ); + + await this.saveBackupDecryptionKey(backupDecKey, version); + + return { + version: res.version, + algorithm: pubKey.algorithm, + authData: authData, + decryptionKey: backupDecKey, + }; + } + /** * Deletes all key backups. * diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index fd06d82018b..193da6db5f5 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -1164,6 +1164,20 @@ export class RustCrypto extends TypedEventEmitter { + const backupDecryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(encodeBase64(privateKey!)); + const backupInfo = await this.backupManager.updateBackupSignature(backupDecryptionKey, version, (o) => this.signObject(o)); + + // we want to store the private key in 4S + // need to check if 4S is set up? + if (await this.secretStorageHasAESKey()) { + await this.secretStorage.store("m.megolm_backup.v1", backupInfo.decryptionKey.toBase64()); + } + + // we can check and start async + this.checkKeyBackupAndEnable(); + } + /** * Signs the given object with the current device and current identity (if available). * As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}.