1
0
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:
David Baker
2019-11-13 14:09:40 +00:00
parent c97a87d1f6
commit 26aa3d3ce7
4 changed files with 86 additions and 1 deletions

View File

@@ -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() { it("should request secrets from other clients", async function() {
const [osborne2, vax] = await makeTestClients( const [osborne2, vax] = await makeTestClients(
[ [

View File

@@ -1113,6 +1113,8 @@ wrapCryptoFuncs(MatrixClient, [
"getSecret", "getSecret",
"isSecretStored", "isSecretStored",
"requestSecret", "requestSecret",
"getDefaultKeyId",
"setDefaultKeyId",
]); ]);
/** /**

View File

@@ -34,6 +34,19 @@ export default class SecretStorage extends EventEmitter {
this._cryptoCallbacks = cryptoCallbacks; 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. * Add a key for encrypting secrets.
* *
@@ -49,6 +62,8 @@ export default class SecretStorage extends EventEmitter {
async addKey(algorithm, opts, keyID) { async addKey(algorithm, opts, keyID) {
const keyData = {algorithm}; const keyData = {algorithm};
if (!opts) opts = {};
if (opts.name) { if (opts.name) {
keyData.name = opts.name; keyData.name = opts.name;
} }
@@ -86,7 +101,7 @@ export default class SecretStorage extends EventEmitter {
if (!keyID) { if (!keyID) {
do { do {
keyID = randomString(32); keyID = randomString(32);
} while (!this._baseApis.getAccountData(`m.secret_storage.key.${keyID}`)); } while (this._baseApis.getAccountData(`m.secret_storage.key.${keyID}`));
} }
// FIXME: sign keyData? // FIXME: sign keyData?
@@ -106,10 +121,23 @@ export default class SecretStorage extends EventEmitter {
* @param {string} name The name of the secret * @param {string} name The name of the secret
* @param {string} secret The secret contents. * @param {string} secret The secret contents.
* @param {Array} keys The IDs of the keys to use to encrypt the secret * @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) { async store(name, secret, keys) {
const encrypted = {}; 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) { for (const keyName of keys) {
// get key information from key storage // get key information from key storage
const keyInfo = this._baseApis.getAccountData( const keyInfo = this._baseApis.getAccountData(

View File

@@ -236,6 +236,14 @@ Crypto.prototype.requestSecret = function(name, devices) {
return this._secretStorage.request(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 * Checks that a given private key matches a given public key
* This can be used by the getCrossSigningKey callback to verify that the * This can be used by the getCrossSigningKey callback to verify that the