From 7446bcdedb1ab40cb433496b6e0c2aad3e51a914 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 5 Dec 2019 15:20:30 +0000 Subject: [PATCH] Extract callbacks to a new module --- src/CrossSigningManager.js | 62 ++++++++++++++++++++++++++++++++++++++ src/MatrixClientPeg.js | 49 +++--------------------------- 2 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 src/CrossSigningManager.js diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js new file mode 100644 index 0000000000..56feadd5d7 --- /dev/null +++ b/src/CrossSigningManager.js @@ -0,0 +1,62 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import Modal from './Modal'; +import sdk from './index'; +import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase'; +import { decodeRecoveryKey } from 'matrix-js-sdk/lib/crypto/recoverykey'; + +// This stores the cross-signing private keys in memory for the JS SDK. They are +// also persisted to Secure Secret Storage in account data by the JS SDK when +// created. +const crossSigningKeys = {}; + +// XXX: On desktop platforms, we plan to store only the SSSS default key in a +// secure enclave, while the cross-signing private keys will still be retrieved +// from SSSS, so it's unclear that we actually need these cross-signing +// application callbacks for Riot. Should the JS SDK default to in-memory +// storage of these itself? +export const getCrossSigningKey = k => crossSigningKeys[k]; +export const saveCrossSigningKeys = newKeys => Object.assign(crossSigningKeys, newKeys); + +// XXX: This flow should maybe be reworked to allow retries in case of typos, +// etc. +export const getSecretStorageKey = async keyInfos => { + const keyInfoEntries = Object.entries(keyInfos); + if (keyInfoEntries.length > 1) { + throw new Error("Multiple storage key requests not implemented"); + } + const [name, info] = keyInfoEntries[0]; + const AccessSecretStorageDialog = + sdk.getComponent("dialogs.secretstorage.AccessSecretStorageDialog"); + const { finished } = Modal.createTrackedDialog("Access Secret Storage dialog", "", + AccessSecretStorageDialog, { + keyInfo: info, + }, + ); + const [input] = await finished; + if (!input) { + throw new Error("Secret storage access canceled"); + } + let key; + const { passphrase } = info; + if (passphrase) { + key = await deriveKey(input, passphrase.salt, passphrase.iterations); + } else { + key = decodeRecoveryKey(input); + } + return [name, key]; +}; diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index d73931f57b..a3a0588bfc 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -1,7 +1,8 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd. -Copyright 2017 New Vector Ltd +Copyright 2017, 2018, 2019 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,8 +31,7 @@ import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; import MatrixClientBackedSettingsHandler from "./settings/handlers/MatrixClientBackedSettingsHandler"; import * as StorageManager from './utils/StorageManager'; import IdentityAuthClient from './IdentityAuthClient'; -import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase'; -import { decodeRecoveryKey } from 'matrix-js-sdk/lib/crypto/recoverykey'; +import * as CrossSigningManager from './CrossSigningManager'; interface MatrixClientCreds { homeserverUrl: string, @@ -222,48 +222,9 @@ class MatrixClientPeg { identityServer: new IdentityAuthClient(), }; + opts.cryptoCallbacks = {}; if (SettingsStore.isFeatureEnabled("feature_cross_signing")) { - // This stores the cross-signing private keys in memory for the JS SDK. They - // are also persisted to Secure Secret Storage in account data by - // the JS SDK when created. - const keys = {}; - opts.cryptoCallbacks = { - // XXX: This flow should maybe be reworked to allow retries in - // case of typos, etc. - getSecretStorageKey: async keyInfos => { - const keyInfoEntries = Object.entries(keyInfos); - if (keyInfoEntries.length > 1) { - throw new Error("Multiple storage key requests not implemented"); - } - const [name, info] = keyInfoEntries[0]; - const AccessSecretStorageDialog = - sdk.getComponent("dialogs.secretstorage.AccessSecretStorageDialog"); - const { finished } = Modal.createTrackedDialog("Access Secret Storage dialog", "", - AccessSecretStorageDialog, { - keyInfo: info, - }, - ); - const [input] = await finished; - if (!input) { - throw new Error("Secret storage access canceled"); - } - let key; - const { passphrase } = info; - if (passphrase) { - key = await deriveKey(input, passphrase.salt, passphrase.iterations); - } else { - key = decodeRecoveryKey(input); - } - return [name, key]; - }, - // XXX: On desktop platforms, we plan to store only the SSSS default - // key in a secure enclave, while the cross-signing private keys - // will still be retrieved from SSSS, so it's unclear that we - // actually need these cross-signing application callbacks for Riot. - // Should the JS SDK default to in-memory storage of these itself? - getCrossSigningKey: k => keys[k], - saveCrossSigningKeys: newKeys => Object.assign(keys, newKeys), - }; + Object.assign(opts.cryptoCallbacks, CrossSigningManager); } this.matrixClient = createMatrixClient(opts);