1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-05 17:02:07 +03:00

Create key backup with secret storage

When secret storage is enable, create a random key for encrypting key backups
and store it in SSSS.
This commit is contained in:
J. Ryan Stinnett
2019-12-11 16:28:58 +00:00
parent a626b44bbe
commit 3f448df1d3
2 changed files with 22 additions and 22 deletions

View File

@@ -53,6 +53,7 @@ import { isCryptoAvailable } from './crypto';
import { decodeRecoveryKey } from './crypto/recoverykey'; import { decodeRecoveryKey } from './crypto/recoverykey';
import { keyFromAuthData } from './crypto/key_passphrase'; import { keyFromAuthData } from './crypto/key_passphrase';
import { randomString } from './randomstring'; import { randomString } from './randomstring';
import { encodeBase64 } from '../lib/crypto/olmlib';
const SCROLLBACK_DELAY_MS = 3000; const SCROLLBACK_DELAY_MS = 3000;
const CRYPTO_ENABLED = isCryptoAvailable(); const CRYPTO_ENABLED = isCryptoAvailable();
@@ -1437,7 +1438,7 @@ MatrixClient.prototype.disableKeyBackup = function() {
* when restoring the backup as an alternative to entering the recovery key. * when restoring the backup as an alternative to entering the recovery key.
* Optional. * Optional.
* @param {boolean} [opts.secureSecretStorage = false] Whether to use Secure * @param {boolean} [opts.secureSecretStorage = false] Whether to use Secure
* Secret Storage (MSC1946) to store the key encrypting key backups. * Secret Storage to store the key encrypting key backups.
* Optional, defaults to false. * Optional, defaults to false.
* *
* @returns {Promise<object>} Object that can be passed to createKeyBackupVersion and * @returns {Promise<object>} Object that can be passed to createKeyBackupVersion and
@@ -1451,28 +1452,25 @@ MatrixClient.prototype.prepareKeyBackupVersion = async function(
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
if (secureSecretStorage) { const [keyInfo, encodedPrivateKey, privateKey] =
logger.log("Preparing key backup version with Secure Secret Storage");
// Ensure Secure Secret Storage is ready for use
if (!this.hasSecretStorageKey()) {
throw new Error("Secure Secret Storage has no keys, needs bootstrapping");
}
throw new Error("Not yet implemented");
}
const [keyInfo, encodedPrivateKey] =
await this.createRecoveryKeyFromPassphrase(password); await this.createRecoveryKeyFromPassphrase(password);
if (secureSecretStorage) {
await this.storeSecret("m.megolm_backup.v1", encodeBase64(privateKey));
logger.info("Key backup private key stored in secret storage");
}
// Reshape objects into form expected for key backup // Reshape objects into form expected for key backup
const authData = {
public_key: keyInfo.pubkey,
};
if (keyInfo.passphrase) {
authData.private_key_salt = keyInfo.passphrase.salt;
authData.private_key_iterations = keyInfo.passphrase.iterations;
}
return { return {
algorithm: olmlib.MEGOLM_BACKUP_ALGORITHM, algorithm: olmlib.MEGOLM_BACKUP_ALGORITHM,
auth_data: { auth_data: authData,
public_key: keyInfo.pubkey,
private_key_salt: keyInfo.passphrase.salt,
private_key_iterations: keyInfo.passphrase.iterations,
},
recovery_key: encodedPrivateKey, recovery_key: encodedPrivateKey,
}; };
}; };

View File

@@ -296,8 +296,9 @@ Crypto.prototype.init = async function() {
* @param {string} password Passphrase string that can be entered by the user * @param {string} password Passphrase string that can be entered by the user
* when restoring the backup as an alternative to entering the recovery key. * when restoring the backup as an alternative to entering the recovery key.
* Optional. * Optional.
* @returns {Promise<Array>} Array with public key metadata and encoded private * @returns {Promise<Array>} Array with public key metadata, encoded private
* recovery key which should be disposed of after displaying to the user. * recovery key which should be disposed of after displaying to the user,
* and raw private key to avoid round tripping if needed.
*/ */
Crypto.prototype.createRecoveryKeyFromPassphrase = async function(password) { Crypto.prototype.createRecoveryKeyFromPassphrase = async function(password) {
const decryption = new global.Olm.PkDecryption(); const decryption = new global.Olm.PkDecryption();
@@ -314,8 +315,9 @@ Crypto.prototype.createRecoveryKeyFromPassphrase = async function(password) {
} else { } else {
keyInfo.pubkey = decryption.generate_key(); keyInfo.pubkey = decryption.generate_key();
} }
const encodedPrivateKey = encodeRecoveryKey(decryption.get_private_key()); const privateKey = decryption.get_private_key();
return [keyInfo, encodedPrivateKey]; const encodedPrivateKey = encodeRecoveryKey(privateKey);
return [keyInfo, encodedPrivateKey, privateKey];
} finally { } finally {
decryption.free(); decryption.free();
} }