diff --git a/spec/unit/crypto/DeviceList.spec.js b/spec/unit/crypto/DeviceList.spec.js index 5a442d81b..fcca8c963 100644 --- a/spec/unit/crypto/DeviceList.spec.js +++ b/spec/unit/crypto/DeviceList.spec.js @@ -1,6 +1,6 @@ /* Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd +Copyright 2018, 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ limitations under the License. */ import DeviceList from '../../../lib/crypto/DeviceList'; -import MockStorageApi from '../../MockStorageApi'; -import WebStorageSessionStore from '../../../lib/store/session/webstorage'; import MemoryCryptoStore from '../../../lib/crypto/store/memory-crypto-store.js'; import testUtils from '../../test-utils'; import utils from '../../../lib/utils'; @@ -57,7 +55,6 @@ const signedDeviceList = { describe('DeviceList', function() { let downloadSpy; - let sessionStore; let cryptoStore; let deviceLists = []; @@ -67,8 +64,6 @@ describe('DeviceList', function() { deviceLists = []; downloadSpy = expect.createSpy(); - const mockStorage = new MockStorageApi(); - sessionStore = new WebStorageSessionStore(mockStorage); cryptoStore = new MemoryCryptoStore(); }); @@ -85,7 +80,7 @@ describe('DeviceList', function() { const mockOlm = { verifySignature: function(key, message, signature) {}, }; - const dl = new DeviceList(baseApis, cryptoStore, sessionStore, mockOlm); + const dl = new DeviceList(baseApis, cryptoStore, mockOlm); deviceLists.push(dl); return dl; } diff --git a/spec/unit/crypto/algorithms/megolm.spec.js b/spec/unit/crypto/algorithms/megolm.spec.js index 164158e90..5d98f033e 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.js +++ b/spec/unit/crypto/algorithms/megolm.spec.js @@ -5,7 +5,6 @@ import Promise from 'bluebird'; import sdk from '../../../..'; import algorithms from '../../../../lib/crypto/algorithms'; -import WebStorageSessionStore from '../../../../lib/store/session/webstorage'; import MemoryCryptoStore from '../../../../lib/crypto/store/memory-crypto-store.js'; import MockStorageApi from '../../../MockStorageApi'; import testUtils from '../../../test-utils'; @@ -40,10 +39,9 @@ describe("MegolmDecryption", function() { mockBaseApis = {}; const mockStorage = new MockStorageApi(); - const sessionStore = new WebStorageSessionStore(mockStorage); const cryptoStore = new MemoryCryptoStore(mockStorage); - const olmDevice = new OlmDevice(sessionStore, cryptoStore); + const olmDevice = new OlmDevice(cryptoStore); megolmDecryption = new MegolmDecryption({ userId: '@user:id', @@ -264,10 +262,9 @@ describe("MegolmDecryption", function() { it("re-uses sessions for sequential messages", async function() { const mockStorage = new MockStorageApi(); - const sessionStore = new WebStorageSessionStore(mockStorage); const cryptoStore = new MemoryCryptoStore(mockStorage); - const olmDevice = new OlmDevice(sessionStore, cryptoStore); + const olmDevice = new OlmDevice(cryptoStore); olmDevice.verifySignature = expect.createSpy(); await olmDevice.init(); diff --git a/spec/unit/crypto/algorithms/olm.spec.js b/spec/unit/crypto/algorithms/olm.spec.js index 493c0eba2..d8c211918 100644 --- a/spec/unit/crypto/algorithms/olm.spec.js +++ b/spec/unit/crypto/algorithms/olm.spec.js @@ -17,7 +17,6 @@ limitations under the License. import '../../../olm-loader'; import expect from 'expect'; -import WebStorageSessionStore from '../../../../lib/store/session/webstorage'; import MemoryCryptoStore from '../../../../lib/crypto/store/memory-crypto-store.js'; import MockStorageApi from '../../../MockStorageApi'; import testUtils from '../../../test-utils'; @@ -28,9 +27,8 @@ import DeviceInfo from '../../../../lib/crypto/deviceinfo'; function makeOlmDevice() { const mockStorage = new MockStorageApi(); - const sessionStore = new WebStorageSessionStore(mockStorage); const cryptoStore = new MemoryCryptoStore(mockStorage); - const olmDevice = new OlmDevice(sessionStore, cryptoStore); + const olmDevice = new OlmDevice(cryptoStore); return olmDevice; } diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index 29503e4a2..1b613c945 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -138,7 +138,7 @@ describe("MegolmBackup", function() { sessionStore = new WebStorageSessionStore(mockStorage); cryptoStore = new MemoryCryptoStore(mockStorage); - olmDevice = new OlmDevice(sessionStore, cryptoStore); + olmDevice = new OlmDevice(cryptoStore); // we stub out the olm encryption bits mockOlmLib = {}; diff --git a/src/client.js b/src/client.js index 12e5ad674..a71a20e05 100644 --- a/src/client.js +++ b/src/client.js @@ -220,7 +220,7 @@ function MatrixClient(opts) { // List of which rooms have encryption enabled: separate from crypto because // we still want to know which rooms are encrypted even if crypto is disabled: // we don't want to start sending unencrypted events to them. - this._roomList = new RoomList(this._cryptoStore, this._sessionStore); + this._roomList = new RoomList(this._cryptoStore); // The pushprocessor caches useful things, so keep one and re-use it this._pushProcessor = new PushProcessor(this); diff --git a/src/crypto/DeviceList.js b/src/crypto/DeviceList.js index d234cab17..5e50189e4 100644 --- a/src/crypto/DeviceList.js +++ b/src/crypto/DeviceList.js @@ -1,6 +1,6 @@ /* Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd +Copyright 2018, 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -61,9 +61,8 @@ const TRACKING_STATUS_UP_TO_DATE = 3; * @alias module:crypto/DeviceList */ export default class DeviceList { - constructor(baseApis, cryptoStore, sessionStore, olmDevice) { + constructor(baseApis, cryptoStore, olmDevice) { this._cryptoStore = cryptoStore; - this._sessionStore = sessionStore; // userId -> { // deviceId -> { @@ -108,30 +107,13 @@ export default class DeviceList { * Load the device tracking state from storage */ async load() { - let shouldDeleteSessionStore = false; await this._cryptoStore.doTxn( - // migrate from session store if there's data there and not here - 'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => { + 'readonly', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => { this._cryptoStore.getEndToEndDeviceData(txn, (deviceData) => { - if (deviceData === null) { - logger.log("Migrating e2e device data..."); - this._devices = this._sessionStore.getAllEndToEndDevices() || {}; - this._deviceTrackingStatus = ( - this._sessionStore.getEndToEndDeviceTrackingStatus() || {} - ); - this._syncToken = this._sessionStore.getEndToEndDeviceSyncToken(); - this._cryptoStore.storeEndToEndDeviceData({ - devices: this._devices, - trackingStatus: this._deviceTrackingStatus, - syncToken: this._syncToken, - }, txn); - shouldDeleteSessionStore = true; - } else { - this._devices = deviceData ? deviceData.devices : {}, - this._deviceTrackingStatus = deviceData ? - deviceData.trackingStatus : {}; - this._syncToken = deviceData ? deviceData.syncToken : null; - } + this._devices = deviceData ? deviceData.devices : {}, + this._deviceTrackingStatus = deviceData ? + deviceData.trackingStatus : {}; + this._syncToken = deviceData ? deviceData.syncToken : null; this._userByIdentityKey = {}; for (const user of Object.keys(this._devices)) { const userDevices = this._devices[user]; @@ -146,11 +128,6 @@ export default class DeviceList { }, ); - if (shouldDeleteSessionStore) { - // migrated data is now safely persisted: remove from old store - this._sessionStore.removeEndToEndDeviceData(); - } - for (const u of Object.keys(this._deviceTrackingStatus)) { // if a download was in progress when we got shut down, it isn't any more. if (this._deviceTrackingStatus[u] == TRACKING_STATUS_DOWNLOAD_IN_PROGRESS) { diff --git a/src/crypto/OlmDevice.js b/src/crypto/OlmDevice.js index 77257bf52..77c8f17c1 100644 --- a/src/crypto/OlmDevice.js +++ b/src/crypto/OlmDevice.js @@ -59,20 +59,17 @@ function checkPayloadLength(payloadString) { * Manages the olm cryptography functions. Each OlmDevice has a single * OlmAccount and a number of OlmSessions. * - * Accounts and sessions are kept pickled in a sessionStore. + * Accounts and sessions are kept pickled in the cryptoStore. * * @constructor * @alias module:crypto/OlmDevice * - * @param {Object} sessionStore A store to be used for data in end-to-end - * crypto. This is deprecated and being replaced by cryptoStore. * @param {Object} cryptoStore A store for crypto data * * @property {string} deviceCurve25519Key Curve25519 key for the account * @property {string} deviceEd25519Key Ed25519 key for the account */ -function OlmDevice(sessionStore, cryptoStore) { - this._sessionStore = sessionStore; +function OlmDevice(cryptoStore) { this._cryptoStore = cryptoStore; this._pickleKey = "DEFAULT_KEY"; @@ -81,7 +78,7 @@ function OlmDevice(sessionStore, cryptoStore) { this.deviceEd25519Key = null; this._maxOneTimeKeys = null; - // we don't bother stashing outboundgroupsessions in the sessionstore - + // we don't bother stashing outboundgroupsessions in the cryptoStore - // instead we keep them here. this._outboundGroupSessionStore = {}; @@ -118,14 +115,10 @@ function OlmDevice(sessionStore, cryptoStore) { * Reads the device keys from the OlmAccount object. */ OlmDevice.prototype.init = async function() { - await this._migrateFromSessionStore(); - let e2eKeys; const account = new global.Olm.Account(); try { - await _initialiseAccount( - this._sessionStore, this._cryptoStore, this._pickleKey, account, - ); + await _initialiseAccount(this._cryptoStore, this._pickleKey, account); e2eKeys = JSON.parse(account.identity_keys()); this._maxOneTimeKeys = account.max_number_of_one_time_keys(); @@ -137,7 +130,7 @@ OlmDevice.prototype.init = async function() { this.deviceEd25519Key = e2eKeys.ed25519; }; -async function _initialiseAccount(sessionStore, cryptoStore, pickleKey, account) { +async function _initialiseAccount(cryptoStore, pickleKey, account) { await cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { cryptoStore.getAccount(txn, (pickledAccount) => { if (pickledAccount !== null) { @@ -158,95 +151,6 @@ OlmDevice.getOlmVersion = function() { return global.Olm.get_library_version(); }; -OlmDevice.prototype._migrateFromSessionStore = async function() { - // account - await this._cryptoStore.doTxn( - 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { - this._cryptoStore.getAccount(txn, (pickledAccount) => { - if (pickledAccount === null) { - // Migrate from sessionStore - pickledAccount = this._sessionStore.getEndToEndAccount(); - if (pickledAccount !== null) { - logger.log("Migrating account from session store"); - this._cryptoStore.storeAccount(txn, pickledAccount); - } - } - }); - }, - ); - - // remove the old account now the transaction has completed. Either we've - // migrated it or decided not to, either way we want to blow away the old data. - this._sessionStore.removeEndToEndAccount(); - - // sessions - const sessions = this._sessionStore.getAllEndToEndSessions(); - if (Object.keys(sessions).length > 0) { - await this._cryptoStore.doTxn( - 'readwrite', [IndexedDBCryptoStore.STORE_SESSIONS], (txn) => { - // Don't migrate sessions from localstorage if we already have sessions - // in indexeddb, since this means we've already migrated and an old version - // has run against the same localstorage and created some spurious sessions. - this._cryptoStore.countEndToEndSessions(txn, (count) => { - if (count) { - logger.log("Crypto store already has sessions: not migrating"); - return; - } - let numSessions = 0; - for (const deviceKey of Object.keys(sessions)) { - for (const sessionId of Object.keys(sessions[deviceKey])) { - numSessions++; - this._cryptoStore.storeEndToEndSession( - deviceKey, sessionId, sessions[deviceKey][sessionId], txn, - ); - } - } - logger.log( - "Migrating " + numSessions + " sessions from session store", - ); - }); - }, - ); - - this._sessionStore.removeAllEndToEndSessions(); - } - - // inbound group sessions - const ibGroupSessions = this._sessionStore.getAllEndToEndInboundGroupSessionKeys(); - if (Object.keys(ibGroupSessions).length > 0) { - let numIbSessions = 0; - await this._cryptoStore.doTxn( - 'readwrite', [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS], (txn) => { - // We always migrate inbound group sessions, even if we already have some - // in the new store. They should be be safe to migrate. - for (const s of ibGroupSessions) { - try { - this._cryptoStore.addEndToEndInboundGroupSession( - s.senderKey, s.sessionId, - JSON.parse( - this._sessionStore.getEndToEndInboundGroupSession( - s.senderKey, s.sessionId, - ), - ), txn, - ); - } catch (e) { - logger.warn( - "Failed to migrate session " + s.senderKey + "/" + - s.sessionId + ": " + e.stack || e, - ); - } - ++numIbSessions; - } - logger.log( - "Migrated " + numIbSessions + - " inbound group sessions from session store", - ); - }, - ); - this._sessionStore.removeAllEndToEndInboundGroupSessions(); - } -}; - /** * extract our OlmAccount from the crypto store and call the given function * with the account object diff --git a/src/crypto/RoomList.js b/src/crypto/RoomList.js index 1f0234548..b8c87dd1f 100644 --- a/src/crypto/RoomList.js +++ b/src/crypto/RoomList.js @@ -1,5 +1,5 @@ /* -Copyright 2018 New Vector Ltd +Copyright 2018, 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,40 +26,21 @@ import IndexedDBCryptoStore from './store/indexeddb-crypto-store'; * @alias module:crypto/RoomList */ export default class RoomList { - constructor(cryptoStore, sessionStore) { + constructor(cryptoStore) { this._cryptoStore = cryptoStore; - this._sessionStore = sessionStore; // Object of roomId -> room e2e info object (body of the m.room.encryption event) this._roomEncryption = {}; } async init() { - let removeSessionStoreRooms = false; await this._cryptoStore.doTxn( 'readwrite', [IndexedDBCryptoStore.STORE_ROOMS], (txn) => { this._cryptoStore.getEndToEndRooms(txn, (result) => { - if (result === null || Object.keys(result).length === 0) { - // migrate from session store, if there's data there - const sessStoreRooms = this._sessionStore.getAllEndToEndRooms(); - if (sessStoreRooms !== null) { - for (const roomId of Object.keys(sessStoreRooms)) { - this._cryptoStore.storeEndToEndRoom( - roomId, sessStoreRooms[roomId], txn, - ); - } - } - this._roomEncryption = sessStoreRooms; - removeSessionStoreRooms = true; - } else { - this._roomEncryption = result; - } + this._roomEncryption = result; }); }, ); - if (removeSessionStoreRooms) { - this._sessionStore.removeAllEndToEndRooms(); - } } getRoomEncryption(roomId) { diff --git a/src/crypto/index.js b/src/crypto/index.js index 4b39141e3..b1ae7f3d3 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -134,9 +134,9 @@ export default function Crypto(baseApis, sessionStore, userId, deviceId, this._checkedForBackup = false; // Have we checked the server for a backup we can use? this._sendingBackups = false; // Are we currently sending backups? - this._olmDevice = new OlmDevice(sessionStore, cryptoStore); + this._olmDevice = new OlmDevice(cryptoStore); this._deviceList = new DeviceList( - baseApis, cryptoStore, sessionStore, this._olmDevice, + baseApis, cryptoStore, this._olmDevice, ); // the last time we did a check for the number of one-time-keys on the @@ -198,25 +198,6 @@ utils.inherits(Crypto, EventEmitter); */ Crypto.prototype.init = async function() { await global.Olm.init(); - - const sessionStoreHasAccount = Boolean(this._sessionStore.getEndToEndAccount()); - let cryptoStoreHasAccount; - await this._cryptoStore.doTxn( - 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { - this._cryptoStore.getAccount(txn, (pickledAccount) => { - cryptoStoreHasAccount = Boolean(pickledAccount); - }); - }, - ); - if (sessionStoreHasAccount && !cryptoStoreHasAccount) { - // we're about to migrate to the crypto store - this.emit("crypto.warning", 'CRYPTO_WARNING_ACCOUNT_MIGRATED'); - } else if (sessionStoreHasAccount && cryptoStoreHasAccount) { - // There's an account in both stores: an old version of - // the code has been run against this store. - this.emit("crypto.warning", 'CRYPTO_WARNING_OLD_VERSION_DETECTED'); - } - await this._olmDevice.init(); await this._deviceList.load(); @@ -235,7 +216,7 @@ Crypto.prototype.init = async function() { } if (!myDevices[this._deviceId]) { - // add our own deviceinfo to the sessionstore + // add our own deviceinfo to the cryptoStore const deviceInfo = { keys: this._deviceKeys, algorithms: this._supportedAlgorithms, @@ -942,7 +923,7 @@ Crypto.prototype.forceDiscardSession = function(roomId) { }; /** - * Configure a room to use encryption (ie, save a flag in the sessionstore). + * Configure a room to use encryption (ie, save a flag in the cryptoStore). * * @param {string} roomId The room ID to enable encryption in. * @@ -2358,17 +2339,6 @@ class IncomingRoomKeyRequestCancellation { * Fires when the app may wish to warn the user about something related * the end-to-end crypto. * - * Comes with a type which is one of: - * * CRYPTO_WARNING_ACCOUNT_MIGRATED: Account data has been migrated from an older - * version of the store in such a way that older clients will no longer be - * able to read it. The app may wish to warn the user against going back to - * an older version of the app. - * * CRYPTO_WARNING_OLD_VERSION_DETECTED: js-sdk has detected that an older version - * of js-sdk has been run against the same store after a migration has been - * performed. This is likely have caused unexpected behaviour in the old - * version. For example, the old version and the new version may have two - * different identity keys. - * * @event module:client~MatrixClient#"crypto.warning" * @param {string} type One of the strings listed above */