index : matrix-js-sdk

My fork of matrix-js-sdk

diff options
context:
space:
mode:
authorBruno Windels <[email protected]>2020-06-17 15:06:41 +0200
committerBruno Windels <[email protected]>2020-06-17 15:06:41 +0200
commitd4b4bc5031654437a687a04014c0f78276c714bd (patch)
tree01a530ba8f9e69ef851680702a7435b017ed4237
parent9bcf33b6d3bcf6cb5f0bfc11fae182a96ed69638 (diff)
downloadmatrix-js-sdk-d4b4bc5031654437a687a04014c0f78276c714bd.tar.gz
move 4S creation to operation
-rw-r--r--src/crypto/EncryptionSetup.js63
-rw-r--r--src/crypto/index.js36
2 files changed, 72 insertions, 27 deletions
diff --git a/src/crypto/EncryptionSetup.js b/src/crypto/EncryptionSetup.js
index 16422eef..e706af55 100644
--- a/src/crypto/EncryptionSetup.js
+++ b/src/crypto/EncryptionSetup.js
@@ -18,6 +18,69 @@ export class EncryptionSetupBuilder {
this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);
this.crossSigningCallbacks = new CrossSigningCallbacks();
this.ssssCryptoCallbacks = new SSSSCryptoCallbacks();
+
+ this._crossSigningKeys = null;
+ this._keySignatures = null;
+ this._keyBackupInfo = null;
+ }
+
+
+ /**
+ * @param {String} type
+ * @param {Object} content
+ * @return {Promise}
+ */
+ setAccountData(type, content) {
+ return this.accountDataClientAdapter.setAccountData(type, content);
+ }
+
+ /**
+ * builds the operation containing all the parts that have been added to the builder
+ * @return {EncryptionSetupOperation}
+ */
+ buildOperation() {
+ const accountData = this.accountDataClientAdapter._values;
+ return new EncryptionSetupOperation(
+ accountData,
+ this._crossSigningKeys,
+ this._keyBackupInfo,
+ this._keySignatures,
+ );
+ }
+
+/**
+ * Can be created from EncryptionSetupBuilder, or
+ * (in a follow-up PR, not implemented yet) restored from storage, to retry.
+ *
+ * It does not have knowledge of any private keys, unlike the builder.
+ */
+export class EncryptionSetupOperation {
+ /**
+ * @param {Map<String, Object>} accountData
+ * @param {Object} crossSigningKeys
+ * @param {Object} keyBackupInfo
+ * @param {Object} keySignatures
+ */
+ constructor(accountData, crossSigningKeys, keyBackupInfo, keySignatures) {
+ this._accountData = accountData;
+ this._crossSigningKeys = crossSigningKeys;
+ this._keyBackupInfo = keyBackupInfo;
+ this._keySignatures = keySignatures;
+ }
+
+ /**
+ * Runs the (remaining part of, in the future) operation by sending requests to the server.
+ * @param {Crypto} crypto
+ */
+ async apply(crypto) {
+ const baseApis = crypto._baseApis;
+ // set account data
+ if (this._accountData) {
+ for (const [type, content] of this._accountData) {
+ await baseApis.setAccountData(type, content);
+ }
+ }
+ }
}
}
diff --git a/src/crypto/index.js b/src/crypto/index.js
index 035286fe..261203b8 100644
--- a/src/crypto/index.js
+++ b/src/crypto/index.js
@@ -507,27 +507,6 @@ Crypto.prototype.bootstrapSecretStorage = async function({
// the ID of the new SSSS key, if we create one
let newKeyId = null;
- // cache SSSS keys so that we don't need to constantly pester the user about it
- const ssssKeys = {};
-
- this._baseApis._cryptoCallbacks.getSecretStorageKey =
- async ({keys}, name) => {
- // if we already have a key that works, return it
- for (const keyId of Object.keys(keys)) {
- if (ssssKeys[keyId]) {
- return [keyId, ssssKeys[keyId]];
- }
- }
-
- // otherwise, prompt the user and cache it
- const key = await appCallbacks.getSecretStorageKey({keys}, name);
- if (key) {
- const [keyId, keyData] = key;
- ssssKeys[keyId] = keyData;
- }
- return key;
- };
-
// create a new SSSS key and set it as default
const createSSSS = async (opts, privateKey) => {
opts = opts || {};
@@ -535,15 +514,16 @@ Crypto.prototype.bootstrapSecretStorage = async function({
opts.key = privateKey;
}
- const keyId = await this.addSecretStorageKey(
+ const keyId = await secretStorage.addKey(
SECRET_STORAGE_ALGORITHM_V1_AES, opts,
);
- await this.setDefaultSecretStorageKeyId(keyId);
if (privateKey) {
- // cache the private key so that we can access it again
- ssssKeys[keyId] = privateKey;
+ // make the private key available to encrypt 4S secrets
+ builder.ssssCryptoCallbacks.addPrivateKey(keyId, privateKey);
}
+
+ await secretStorage.setDefaultKeyId(keyId);
return keyId;
};
@@ -566,12 +546,12 @@ Crypto.prototype.bootstrapSecretStorage = async function({
);
if (key) {
const keyData = key[1];
- ssssKeys[keyId] = keyData;
+ builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyData);
const {iv, mac} = await SecretStorage._calculateKeyCheck(keyData);
keyInfo.iv = iv;
keyInfo.mac = mac;
- await this._baseApis.setAccountData(
+ await builder.setAccountData(
`m.secret_storage.key.${keyId}`, keyInfo,
);
}
@@ -746,6 +726,8 @@ Crypto.prototype.bootstrapSecretStorage = async function({
Object.assign(this._baseApis._cryptoCallbacks, appCallbacks);
}
+ const operation = builder.buildOperation();
+ await operation.apply(this);
logger.log("Secure Secret Storage ready");
};