You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Support default keys
This commit is contained in:
@@ -110,6 +110,53 @@ describe("Secrets", function() {
|
||||
}
|
||||
});
|
||||
|
||||
it("should refuse to encrypt with zero keys", async function() {
|
||||
const alice = await makeTestClient(
|
||||
{userId: "@alice:example.com", deviceId: "Osborne2"},
|
||||
);
|
||||
|
||||
try {
|
||||
await alice.storeSecret("foo", "bar", []);
|
||||
expect(true).toBeFalsy();
|
||||
} catch (e) {
|
||||
}
|
||||
});
|
||||
|
||||
it("should encrypt with default key if keys is null", async function() {
|
||||
const alice = await makeTestClient(
|
||||
{userId: "@alice:example.com", deviceId: "Osborne2"},
|
||||
);
|
||||
alice.setAccountData = async function(eventType, contents, callback) {
|
||||
alice.store.storeAccountDataEvents([
|
||||
new MatrixEvent({
|
||||
type: eventType,
|
||||
content: contents,
|
||||
}),
|
||||
]);
|
||||
};
|
||||
|
||||
const newKeyId = await alice.addSecretKey(
|
||||
'm.secret_storage.v1.curve25519-aes-sha2',
|
||||
);
|
||||
await alice.setDefaultKeyId(newKeyId);
|
||||
await alice.storeSecret("foo", "bar");
|
||||
|
||||
const accountData = alice.getAccountData('foo');
|
||||
expect(accountData.getContent().encrypted).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should refuse to encrypt if no keys given and no default key", async function() {
|
||||
const alice = await makeTestClient(
|
||||
{userId: "@alice:example.com", deviceId: "Osborne2"},
|
||||
);
|
||||
|
||||
try {
|
||||
await alice.storeSecret("foo", "bar");
|
||||
expect(true).toBeFalsy();
|
||||
} catch (e) {
|
||||
}
|
||||
});
|
||||
|
||||
it("should request secrets from other clients", async function() {
|
||||
const [osborne2, vax] = await makeTestClients(
|
||||
[
|
||||
|
||||
@@ -1113,6 +1113,8 @@ wrapCryptoFuncs(MatrixClient, [
|
||||
"getSecret",
|
||||
"isSecretStored",
|
||||
"requestSecret",
|
||||
"getDefaultKeyId",
|
||||
"setDefaultKeyId",
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,19 @@ export default class SecretStorage extends EventEmitter {
|
||||
this._cryptoCallbacks = cryptoCallbacks;
|
||||
}
|
||||
|
||||
getDefaultKeyId() {
|
||||
const defaultKeyEvent = this._baseApis.getAccountData('m.secret_storage.default_key');
|
||||
if (!defaultKeyEvent) return null;
|
||||
return defaultKeyEvent.getContent().key;
|
||||
}
|
||||
|
||||
setDefaultKeyId(keyId) {
|
||||
return this._baseApis.setAccountData(
|
||||
'm.secret_storage.default_key',
|
||||
{ key: keyId },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a key for encrypting secrets.
|
||||
*
|
||||
@@ -49,6 +62,8 @@ export default class SecretStorage extends EventEmitter {
|
||||
async addKey(algorithm, opts, keyID) {
|
||||
const keyData = {algorithm};
|
||||
|
||||
if (!opts) opts = {};
|
||||
|
||||
if (opts.name) {
|
||||
keyData.name = opts.name;
|
||||
}
|
||||
@@ -86,7 +101,7 @@ export default class SecretStorage extends EventEmitter {
|
||||
if (!keyID) {
|
||||
do {
|
||||
keyID = randomString(32);
|
||||
} while (!this._baseApis.getAccountData(`m.secret_storage.key.${keyID}`));
|
||||
} while (this._baseApis.getAccountData(`m.secret_storage.key.${keyID}`));
|
||||
}
|
||||
|
||||
// FIXME: sign keyData?
|
||||
@@ -106,10 +121,23 @@ export default class SecretStorage extends EventEmitter {
|
||||
* @param {string} name The name of the secret
|
||||
* @param {string} secret The secret contents.
|
||||
* @param {Array} keys The IDs of the keys to use to encrypt the secret
|
||||
* or null/undefined to use the default key.
|
||||
*/
|
||||
async store(name, secret, keys) {
|
||||
const encrypted = {};
|
||||
|
||||
if (!keys) {
|
||||
const defaultKeyId = this.getDefaultKeyId();
|
||||
if (!defaultKeyId) {
|
||||
throw new Error("No keys specified and no default key present");
|
||||
}
|
||||
keys = [defaultKeyId];
|
||||
}
|
||||
|
||||
if (keys.length === 0) {
|
||||
throw new Error("Zero keys given to encrypt with!");
|
||||
}
|
||||
|
||||
for (const keyName of keys) {
|
||||
// get key information from key storage
|
||||
const keyInfo = this._baseApis.getAccountData(
|
||||
|
||||
@@ -236,6 +236,14 @@ Crypto.prototype.requestSecret = function(name, devices) {
|
||||
return this._secretStorage.request(name, devices);
|
||||
};
|
||||
|
||||
Crypto.prototype.getDefaultKeyId = function() {
|
||||
return this._secretStorage.getDefaultKeyId();
|
||||
};
|
||||
|
||||
Crypto.prototype.setDefaultKeyId = function(k) {
|
||||
return this._secretStorage.setDefaultKeyId(k);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks that a given private key matches a given public key
|
||||
* This can be used by the getCrossSigningKey callback to verify that the
|
||||
|
||||
Reference in New Issue
Block a user