From d00f140309e8cf62ce4a3b6d43652f4cb2b1f010 Mon Sep 17 00:00:00 2001 From: RMidhunSuresh Date: Tue, 20 Jun 2023 17:45:19 +0530 Subject: [PATCH] Delete secrets when cross-signing is reset --- src/matrix/Session.js | 5 +++++ src/matrix/ssss/SecretSharing.ts | 11 +++++++++++ src/matrix/storage/idb/Store.ts | 15 +++++++++++++++ .../storage/idb/stores/SharedSecretStore.ts | 4 ++++ 4 files changed, 35 insertions(+) diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 94783509..2d9ad66e 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -772,6 +772,7 @@ export class Session { e2eeAccountChanges: null, hasNewRoomKeys: false, deviceMessageDecryptionResults: null, + changedDevices: null, }; const syncToken = syncResponse.next_batch; if (syncToken !== this.syncToken) { @@ -789,6 +790,7 @@ export class Session { const deviceLists = syncResponse.device_lists; if (this._deviceTracker && Array.isArray(deviceLists?.changed) && deviceLists.changed.length) { await log.wrap("deviceLists", log => this._deviceTracker.writeDeviceChanges(deviceLists.changed, txn, log)); + changes.changedDevices = deviceLists.changed; } if (preparation) { @@ -838,6 +840,9 @@ export class Session { if (changes.deviceMessageDecryptionResults) { await this._deviceMessageHandler.afterSyncCompleted(changes.deviceMessageDecryptionResults, this._deviceTracker, this._hsApi, log); } + if (changes.changedDevices?.includes(this.userId)) { + this._secretSharing?.checkSecretValidity(); + } } _tryReplaceRoomBeingCreated(roomId, log) { diff --git a/src/matrix/ssss/SecretSharing.ts b/src/matrix/ssss/SecretSharing.ts index 43c2057d..2ac96d9a 100644 --- a/src/matrix/ssss/SecretSharing.ts +++ b/src/matrix/ssss/SecretSharing.ts @@ -225,6 +225,17 @@ export class SecretSharing { } } + async checkSecretValidity(log: ILogItem): Promise { + const crossSigning = this.crossSigning.get(); + const needsDeleting = !await crossSigning?.areWeVerified(log); + if (needsDeleting) { + // User probably reset their cross-signing keys + // Can't trust the secrets anymore! + const txn = await this.storage.readWriteTxn([this.storage.storeNames.sharedSecrets]); + txn.sharedSecrets.deleteAllSecrets(); + } + } + async getLocallyStoredSecret(name: string): Promise { const txn = await this.storage.readTxn([ this.storage.storeNames.sharedSecrets, diff --git a/src/matrix/storage/idb/Store.ts b/src/matrix/storage/idb/Store.ts index c9df33b2..de7a2733 100644 --- a/src/matrix/storage/idb/Store.ts +++ b/src/matrix/storage/idb/Store.ts @@ -118,6 +118,16 @@ export class QueryTargetWrapper { } } + clear(): IDBRequest { + try { + LOG_REQUESTS && logRequest("clear", [], this._qt); + return this._qtStore.clear(); + } + catch (err) { + throw new IDBRequestAttemptError("delete", this._qt, err, []); + } + } + count(keyRange?: IDBKeyRange): IDBRequest { try { return this._qt.count(keyRange); @@ -195,6 +205,11 @@ export class Store extends QueryTarget { this._prepareErrorLog(request, log, "delete", keyOrKeyRange, undefined); } + clear(log?: ILogItem): void { + const request = this._idbStore.clear(); + this._prepareErrorLog(request, log, "delete", undefined, undefined); + } + private _prepareErrorLog(request: IDBRequest, log: ILogItem | undefined, operationName: string, key: IDBKey | undefined, value: T | undefined) { if (log) { log.ensureRefId(); diff --git a/src/matrix/storage/idb/stores/SharedSecretStore.ts b/src/matrix/storage/idb/stores/SharedSecretStore.ts index 79f9f625..97f1ee74 100644 --- a/src/matrix/storage/idb/stores/SharedSecretStore.ts +++ b/src/matrix/storage/idb/stores/SharedSecretStore.ts @@ -36,4 +36,8 @@ export class SharedSecretStore { remove(name: string): void { this._store.delete(name); } + + deleteAllSecrets(): void { + this._store.clear(); + } }