From 4356603665e16e9c01cce7d863fc234059bc9ed5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 27 Jun 2019 23:37:57 -0400 Subject: [PATCH] save public part of cross-signing keys --- src/crypto/index.js | 45 +++++++++++-------- .../store/indexeddb-crypto-store-backend.js | 8 ++-- src/crypto/store/indexeddb-crypto-store.js | 14 +++--- src/crypto/store/localStorage-crypto-store.js | 10 ++--- src/crypto/store/memory-crypto-store.js | 10 ++--- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/crypto/index.js b/src/crypto/index.js index b29e77053..845a7d1bc 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -280,6 +280,17 @@ Crypto.prototype.init = async function() { ); this._deviceList.saveIfDirty(); } + + await this._cryptoStore.doTxn( + 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], + (txn) => { + this._cryptoStore.getCrossSigningKeys(txn, (keys) => { + if (keys) { + this._crossSigningInfo.setKeys(keys); + } + }); + }, + ); // make sure we are keeping track of our own devices // (this is important for key backups & things) this._deviceList.startTrackingDeviceList(this._userId); @@ -298,6 +309,14 @@ Crypto.prototype.init = async function() { */ Crypto.prototype.resetCrossSigningKeys = async function(authDict, level) { await this._crossSigningInfo.resetKeys(level); + await this._cryptoStore.doTxn( + 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], + (txn) => { + this._cryptoStore.storeCrossSigningKeys(txn, this._crossSigningInfo.keys); + }, + ); + + // send keys to server const keys = {}; for (const [name, key] of Object.entries(this._crossSigningInfo.keys)) { keys[name + "_key"] = key; @@ -305,6 +324,7 @@ Crypto.prototype.resetCrossSigningKeys = async function(authDict, level) { await this._baseApis.uploadDeviceSigningKeys(authDict || {}, keys); this._baseApis.emit("cross-signing.keysChanged", {}); + // sign the current device with the new key, and upload to the server const device = this._deviceList.getStoredDevice(this._userId, this._deviceId); const signedDevice = await this._crossSigningInfo.signDevice(this._userId, device); await this._baseApis.uploadKeySignatures({ @@ -465,7 +485,12 @@ Crypto.prototype.checkOwnCrossSigningTrust = async function() { const oldUserSigningId = this._crossSigningInfo.getId("user_signing"); this._crossSigningInfo.setKeys(newCrossSigning.keys); - // FIXME: save it ... somewhere? + await this._cryptoStore.doTxn( + 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], + (txn) => { + this._cryptoStore.storeCrossSigningKeys(txn, this._crossSigningInfo.keys); + }, + ); if (oldSelfSigningId !== newCrossSigning.getId("self_signing")) { logger.info("Got new self-signing key", newCrossSigning.getId("self_signing")); @@ -820,24 +845,6 @@ Crypto.prototype.uploadDeviceKeys = function() { let accountKeys; return crypto._signObject(deviceKeys).then(() => { - return this._cryptoStore.doTxn( - 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], - (txn) => { - this._cryptoStore.getAccountKeys(txn, keys => { - accountKeys = keys; - }); - }, - ); - }).then(() => { - if (accountKeys && accountKeys.self_signing_key_seed) { - // if we have an SSK, sign the key with the SSK too - pkSign( - deviceKeys, - Buffer.from(accountKeys.self_signing_key_seed, 'base64'), - userId, - ); - } - return crypto._baseApis.uploadKeysRequest({ device_keys: deviceKeys, }, { diff --git a/src/crypto/store/indexeddb-crypto-store-backend.js b/src/crypto/store/indexeddb-crypto-store-backend.js index f6b4774c8..76f066887 100644 --- a/src/crypto/store/indexeddb-crypto-store-backend.js +++ b/src/crypto/store/indexeddb-crypto-store-backend.js @@ -332,9 +332,9 @@ export class Backend { objectStore.put(newData, "-"); } - getAccountKeys(txn, func) { + getCrossSigningKeys(txn, func) { const objectStore = txn.objectStore("account"); - const getReq = objectStore.get("keys"); + const getReq = objectStore.get("crossSigningKeys"); getReq.onsuccess = function() { try { func(getReq.result || null); @@ -344,9 +344,9 @@ export class Backend { }; } - storeAccountKeys(txn, keys) { + storeCrossSigningKeys(txn, keys) { const objectStore = txn.objectStore("account"); - objectStore.put(keys, "keys"); + objectStore.put(keys, "crossSigningKeys"); } // Olm Sessions diff --git a/src/crypto/store/indexeddb-crypto-store.js b/src/crypto/store/indexeddb-crypto-store.js index 3a1c77912..15492204f 100644 --- a/src/crypto/store/indexeddb-crypto-store.js +++ b/src/crypto/store/indexeddb-crypto-store.js @@ -302,25 +302,25 @@ export default class IndexedDBCryptoStore { } /** - * Get the account keys for cross-signing (eg. self-signing key, + * Get the public part of the cross-signing keys (eg. self-signing key, * user signing key). * * @param {*} txn An active transaction. See doTxn(). * @param {function(string)} func Called with the account keys object: * { key_type: base64 encoded seed } where key type = user_signing_key_seed or self_signing_key_seed */ - getAccountKeys(txn, func) { - this._backendPromise.value().getAccountKeys(txn, func); + getCrossSigningKeys(txn, func) { + this._backendPromise.value().getCrossSigningKeys(txn, func); } /** - * Write the account keys back to the store + * Write the cross-siging keys back to the store * * @param {*} txn An active transaction. See doTxn(). - * @param {string} keys Account keys object as getAccountKeys() + * @param {string} keys keys object as getCrossSigningKeys() */ - storeAccountKeys(txn, keys) { - this._backendPromise.value().storeAccountKeys(txn, keys); + storeCrossSigningKeys(txn, keys) { + this._backendPromise.value().storeCrossSigningKeys(txn, keys); } // Olm sessions diff --git a/src/crypto/store/localStorage-crypto-store.js b/src/crypto/store/localStorage-crypto-store.js index 0163c0c95..fd7934bb1 100644 --- a/src/crypto/store/localStorage-crypto-store.js +++ b/src/crypto/store/localStorage-crypto-store.js @@ -31,7 +31,7 @@ import MemoryCryptoStore from './memory-crypto-store.js'; const E2E_PREFIX = "crypto."; const KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account"; -const KEY_END_TO_END_ACCOUNT_KEYS = E2E_PREFIX + "account_keys"; +const KEY_CROSS_SIGNING_KEYS = E2E_PREFIX + "cross_signing_keys"; const KEY_DEVICE_DATA = E2E_PREFIX + "device_data"; const KEY_INBOUND_SESSION_PREFIX = E2E_PREFIX + "inboundgroupsessions/"; const KEY_ROOMS_PREFIX = E2E_PREFIX + "rooms/"; @@ -285,14 +285,14 @@ export default class LocalStorageCryptoStore extends MemoryCryptoStore { ); } - getAccountKeys(txn, func) { - const keys = getJsonItem(this.store, KEY_END_TO_END_ACCOUNT_KEYS); + getCrossSigningKeys(txn, func) { + const keys = getJsonItem(this.store, KEY_CROSS_SIGNING_KEYS); func(keys); } - storeAccountKeys(txn, keys) { + storeCrossSigningKeys(txn, keys) { setJsonItem( - this.store, KEY_END_TO_END_ACCOUNT_KEYS, keys, + this.store, KEY_CROSS_SIGNING_KEYS, keys, ); } diff --git a/src/crypto/store/memory-crypto-store.js b/src/crypto/store/memory-crypto-store.js index fd2205c9f..2897be81e 100644 --- a/src/crypto/store/memory-crypto-store.js +++ b/src/crypto/store/memory-crypto-store.js @@ -33,7 +33,7 @@ export default class MemoryCryptoStore { constructor() { this._outgoingRoomKeyRequests = []; this._account = null; - this._accountKeys = null; + this._crossSigningKeys = null; // Map of {devicekey -> {sessionId -> session pickle}} this._sessions = {}; @@ -235,12 +235,12 @@ export default class MemoryCryptoStore { this._account = newData; } - getAccountKeys(txn, func) { - func(this._accountKeys); + getCrossSigningKeys(txn, func) { + func(this._crossSigningKeys); } - storeAccountKeys(txn, keys) { - this._accountKeys = keys; + storeCrossSigningKeys(txn, keys) { + this._crossSigningKeys = keys; } // Olm Sessions