diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index e03460fe0..34766b871 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -27,6 +27,7 @@ import {MockStorageApi} from "../../MockStorageApi"; import * as testUtils from "../../test-utils"; import {OlmDevice} from "../../../src/crypto/OlmDevice"; import {Crypto} from "../../../src/crypto"; +import {resetCrossSigningKeys} from "./crypto-utils"; const Olm = global.Olm; @@ -332,7 +333,7 @@ describe("MegolmBackup", function() { client.on("crossSigning.getKey", function(e) { e.done(privateKeys[e.type]); }); - await client.resetCrossSigningKeys(); + await resetCrossSigningKeys(client); let numCalls = 0; await new Promise((resolve, reject) => { client._http.authedRequest = function( diff --git a/spec/unit/crypto/cross-signing.spec.js b/spec/unit/crypto/cross-signing.spec.js index ccdbef0bc..a15239a0c 100644 --- a/spec/unit/crypto/cross-signing.spec.js +++ b/spec/unit/crypto/cross-signing.spec.js @@ -20,6 +20,7 @@ import anotherjson from 'another-json'; import * as olmlib from "../../../src/crypto/olmlib"; import {TestClient} from '../../TestClient'; import {HttpResponse, setHttpResponses} from '../../test-utils'; +import {resetCrossSigningKeys, createSecretStorageKey} from "./crypto-utils"; async function makeTestClient(userInfo, options, keys) { if (!keys) keys = {}; @@ -66,8 +67,10 @@ describe("Cross Signing", function() { ); }); alice.uploadKeySignatures = async () => {}; + alice.setAccountData = async () => {}; + alice.getAccountDataFromServer = async () => {}; // set Alice's cross-signing key - await alice.resetCrossSigningKeys(); + await alice.bootstrapSecretStorage({createSecretStorageKey}); expect(alice.uploadDeviceSigningKeys).toHaveBeenCalled(); }); @@ -78,7 +81,7 @@ describe("Cross Signing", function() { alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; // set Alice's cross-signing key - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); // Alice downloads Bob's device key alice._crypto._deviceList.storeCrossSigningForUser("@bob:example.com", { keys: { @@ -273,7 +276,7 @@ describe("Cross Signing", function() { alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; // set Alice's cross-signing key - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); // Alice downloads Bob's ssk and device key const bobMasterSigning = new global.Olm.PkSigning(); const bobMasterPrivkey = bobMasterSigning.generate_seed(); @@ -363,7 +366,7 @@ describe("Cross Signing", function() { alice.uploadKeySignatures = async () => {}; // set Alice's cross-signing key - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); const selfSigningKey = new Uint8Array([ 0x1e, 0xf4, 0x01, 0x6d, 0x4f, 0xa1, 0x73, 0x66, @@ -520,7 +523,7 @@ describe("Cross Signing", function() { alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; // set Alice's cross-signing key - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); // Alice downloads Bob's ssk and device key // (NOTE: device key is not signed by ssk) const bobMasterSigning = new global.Olm.PkSigning(); @@ -588,7 +591,7 @@ describe("Cross Signing", function() { ); alice.uploadDeviceSigningKeys = async () => {}; alice.uploadKeySignatures = async () => {}; - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); // Alice downloads Bob's keys const bobMasterSigning = new global.Olm.PkSigning(); const bobMasterPrivkey = bobMasterSigning.generate_seed(); @@ -740,7 +743,7 @@ describe("Cross Signing", function() { bob.uploadDeviceSigningKeys = async () => {}; bob.uploadKeySignatures = async () => {}; // set Bob's cross-signing key - await bob.resetCrossSigningKeys(); + await resetCrossSigningKeys(bob); alice._crypto._deviceList.storeDevicesForUser("@bob:example.com", { Dynabook: { algorithms: ["m.olm.curve25519-aes-sha256", "m.megolm.v1.aes-sha"], @@ -766,7 +769,7 @@ describe("Cross Signing", function() { let upgradePromise = new Promise((resolve) => { upgradeResolveFunc = resolve; }); - await alice.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice); await upgradePromise; const bobTrust = alice.checkUserTrust("@bob:example.com"); diff --git a/spec/unit/crypto/crypto-utils.js b/spec/unit/crypto/crypto-utils.js new file mode 100644 index 000000000..b54802b05 --- /dev/null +++ b/spec/unit/crypto/crypto-utils.js @@ -0,0 +1,44 @@ +import {IndexedDBCryptoStore} from '../../../src/crypto/store/indexeddb-crypto-store'; + + +// needs to be phased out and replaced with bootstrapSecretStorage, +// but that is doing too much extra stuff for it to be an easy transition. +export async function resetCrossSigningKeys(client, { + level, + authUploadDeviceSigningKeys = async func => await func(), +} = {}) { + const crypto = client._crypto; + + const oldKeys = Object.assign({}, crypto._crossSigningInfo.keys); + try { + await crypto._crossSigningInfo.resetKeys(level); + await crypto._signObject(crypto._crossSigningInfo.keys.master); + // write a copy locally so we know these are trusted keys + await crypto._cryptoStore.doTxn( + 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], + (txn) => { + crypto._cryptoStore.storeCrossSigningKeys( + txn, crypto._crossSigningInfo.keys); + }, + ); + } catch (e) { + // If anything failed here, revert the keys so we know to try again from the start + // next time. + crypto._crossSigningInfo.keys = oldKeys; + throw e; + } + crypto._baseApis.emit("crossSigning.keysChanged", {}); + await crypto._afterCrossSigningLocalKeyChange(); +} + +export async function createSecretStorageKey() { + const decryption = new global.Olm.PkDecryption(); + const storagePublicKey = decryption.generate_key(); + const storagePrivateKey = decryption.get_private_key(); + decryption.free(); + return { + // `pubkey` not used anymore with symmetric 4S + keyInfo: { pubkey: storagePublicKey }, + privateKey: storagePrivateKey, + }; +} diff --git a/spec/unit/crypto/secrets.spec.js b/spec/unit/crypto/secrets.spec.js index d60ca1ba5..74748667f 100644 --- a/spec/unit/crypto/secrets.spec.js +++ b/spec/unit/crypto/secrets.spec.js @@ -21,6 +21,7 @@ import {MatrixEvent} from "../../../src/models/event"; import {TestClient} from '../../TestClient'; import {makeTestClients} from './verification/util'; import {encryptAES} from "../../../src/crypto/aes"; +import {resetCrossSigningKeys, createSecretStorageKey} from "./crypto-utils"; import * as utils from "../../../src/utils"; @@ -190,7 +191,7 @@ describe("Secrets", function() { }), ]); }; - alice.resetCrossSigningKeys(); + resetCrossSigningKeys(alice); const newKeyId = await alice.addSecretStorageKey( SECRET_STORAGE_ALGORITHM_V1_AES, @@ -325,7 +326,7 @@ describe("Secrets", function() { this.emit("accountData", event); }; - await bob.bootstrapSecretStorage(); + await bob.bootstrapSecretStorage({createSecretStorageKey}); const crossSigning = bob._crypto._crossSigningInfo; const secretStorage = bob._crypto._secretStorage; diff --git a/spec/unit/crypto/verification/sas.spec.js b/spec/unit/crypto/verification/sas.spec.js index 88f424fe8..607712318 100644 --- a/spec/unit/crypto/verification/sas.spec.js +++ b/spec/unit/crypto/verification/sas.spec.js @@ -22,6 +22,7 @@ import {DeviceInfo} from "../../../../src/crypto/deviceinfo"; import {verificationMethods} from "../../../../src/crypto"; import * as olmlib from "../../../../src/crypto/olmlib"; import {logger} from "../../../../src/logger"; +import {resetCrossSigningKeys} from "../crypto-utils"; const Olm = global.Olm; @@ -288,12 +289,12 @@ describe("SAS verification", function() { ); alice.httpBackend.when('POST', '/keys/signatures/upload').respond(200, {}); alice.httpBackend.flush(undefined, 2); - await alice.client.resetCrossSigningKeys(); + await resetCrossSigningKeys(alice.client); bob.httpBackend.when('POST', '/keys/device_signing/upload').respond(200, {}); bob.httpBackend.when('POST', '/keys/signatures/upload').respond(200, {}); bob.httpBackend.flush(undefined, 2); - await bob.client.resetCrossSigningKeys(); + await resetCrossSigningKeys(bob.client); bob.client._crypto._deviceList.storeCrossSigningForUser( "@alice:example.com", {