You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
cleanups and a lot more docs
This commit is contained in:
221
src/client.js
221
src/client.js
@@ -560,8 +560,8 @@ MatrixClient.prototype.initCrypto = async function() {
|
|||||||
"crypto.roomKeyRequestCancellation",
|
"crypto.roomKeyRequestCancellation",
|
||||||
"crypto.warning",
|
"crypto.warning",
|
||||||
"crypto.devicesUpdated",
|
"crypto.devicesUpdated",
|
||||||
"cross-signing:savePrivateKeys",
|
"cross-signing.savePrivateKeys",
|
||||||
"cross-signing:getKey",
|
"cross-signing.getKey",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
logger.log("Crypto: initialising crypto object...");
|
logger.log("Crypto: initialising crypto object...");
|
||||||
@@ -815,12 +815,149 @@ function wrapCryptoFuncs(MatrixClient, names) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate new cross-signing keys.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#resetCrossSigningKeys
|
||||||
|
* @param {object} authDict Auth data to supply for User-Interactive auth.
|
||||||
|
* @param {CrossSigningLevel} [level] the level of cross-signing to reset. New
|
||||||
|
* keys will be created for the given level and below. Defaults to
|
||||||
|
* regenerating all keys.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user's cross-signing key ID.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#getCrossSigningId
|
||||||
|
* @param {string} [type=master] The type of key to get the ID of. One of
|
||||||
|
* "master", "self_signing", or "user_signing". Defaults to "master".
|
||||||
|
*
|
||||||
|
* @returns {string} the key ID
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cross signing information for a given user.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#getStoredCrossSigningForUser
|
||||||
|
* @param {string} userId the user ID to get the cross-signing info for.
|
||||||
|
*
|
||||||
|
* @returns {CrossSigningInfo} the cross signing informmation for the user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given user is trusted.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#checkUserTrust
|
||||||
|
* @param {string} userId The ID of the user to check.
|
||||||
|
*
|
||||||
|
* @returns {integer} a bit mask indicating how the user is trusted (if at all)
|
||||||
|
* - returnValue & 1: unused
|
||||||
|
* - returnValue & 2: trust-on-first-use cross-signing key
|
||||||
|
* - returnValue & 4: user's cross-signing key is verified
|
||||||
|
*
|
||||||
|
* TODO: is this a good way of representing it? Or we could return an object
|
||||||
|
* with different keys, or a set? The advantage of doing it this way is that
|
||||||
|
* you can define which methods you want to use, "&" with the appopriate mask,
|
||||||
|
* then test for truthiness. Or if you want to just trust everything, then use
|
||||||
|
* the value alone. However, I wonder if bit masks are too obscure...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given device is trusted.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#checkDeviceTrust
|
||||||
|
* @param {string} userId The ID of the user whose devices is to be checked.
|
||||||
|
* @param {string} deviceId The ID of the device to check
|
||||||
|
*
|
||||||
|
* @returns {integer} a bit mask indicating how the user is trusted (if at all)
|
||||||
|
* - returnValue & 1: device marked as verified
|
||||||
|
* - returnValue & 2: trust-on-first-use cross-signing key
|
||||||
|
* - returnValue & 4: user's cross-signing key is verified and device is signed
|
||||||
|
*
|
||||||
|
* TODO: see checkUserTrust
|
||||||
|
*/
|
||||||
|
|
||||||
wrapCryptoFuncs(MatrixClient, [
|
wrapCryptoFuncs(MatrixClient, [
|
||||||
|
"resetCrossSigningKeys",
|
||||||
|
"getCrossSigningId",
|
||||||
|
"getStoredCrossSigningForUser",
|
||||||
"checkUserTrust",
|
"checkUserTrust",
|
||||||
"checkDeviceTrust",
|
"checkDeviceTrust",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the sender of an event is verified
|
||||||
|
*
|
||||||
|
* @param {MatrixEvent} event event to be checked
|
||||||
|
*
|
||||||
|
* @returns {integer} a bit mask indicating how the user is trusted (if at all)
|
||||||
|
* - returnValue & 1: device marked as verified
|
||||||
|
* - returnValue & 2: trust-on-first-use cross-signing key
|
||||||
|
* - returnValue & 4: user's cross-signing key is verified
|
||||||
|
*/
|
||||||
|
MatrixClient.prototype.checkEventSenderTrust = async function(event) {
|
||||||
|
const device = await this.getEventSenderDeviceInfo(event);
|
||||||
|
if (!device) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return await this._crypto.checkDeviceTrust(event.getSender(), device.deviceId);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a key for encrypting secrets.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#addSecretKey
|
||||||
|
* @param {string} algorithm the algorithm used by the key
|
||||||
|
* @param {object} opts the options for the algorithm. The properties used
|
||||||
|
* depend on the algorithm given. This object may be modified to pass
|
||||||
|
* information back about the key.
|
||||||
|
* @param {string} [keyName] the name of the key. If not given, a random
|
||||||
|
* name will be generated.
|
||||||
|
*
|
||||||
|
* @return {string} the name of the key
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an encrypted secret on the server
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#storeSecret
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a secret from storage.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#getSecret
|
||||||
|
* @param {string} name the name of the secret
|
||||||
|
*
|
||||||
|
* @return {string} the contents of the secret
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a secret is stored on the server.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#isSecretStored
|
||||||
|
* @param {string} name the name of the secret
|
||||||
|
* @param {boolean} checkKey check if the secret is encrypted by a trusted
|
||||||
|
* key (currently unimplemented)
|
||||||
|
*
|
||||||
|
* @return {boolean} whether or not the secret is stored
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a secret from another device.
|
||||||
|
*
|
||||||
|
* @function module:client~MatrixClient#requestSecret
|
||||||
|
* @param {string} name the name of the secret to request
|
||||||
|
* @param {string[]} devices the devices to request the secret from
|
||||||
|
*
|
||||||
|
* @return {string} the contents of the secret
|
||||||
|
*/
|
||||||
|
|
||||||
wrapCryptoFuncs(MatrixClient, [
|
wrapCryptoFuncs(MatrixClient, [
|
||||||
|
"addSecretKey",
|
||||||
"storeSecret",
|
"storeSecret",
|
||||||
"getSecret",
|
"getSecret",
|
||||||
"isSecretStored",
|
"isSecretStored",
|
||||||
@@ -858,12 +995,6 @@ MatrixClient.prototype.isEventSenderVerified = async function(event) {
|
|||||||
return device.isVerified();
|
return device.isVerified();
|
||||||
};
|
};
|
||||||
|
|
||||||
wrapCryptoFuncs(MatrixClient, [
|
|
||||||
"resetCrossSigningKeys",
|
|
||||||
"getCrossSigningId",
|
|
||||||
"getStoredCrossSigningForUser",
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel a room key request for this event if one is ongoing and resend the
|
* Cancel a room key request for this event if one is ongoing and resend the
|
||||||
* request.
|
* request.
|
||||||
@@ -4712,6 +4843,80 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
|
|||||||
* perform the key verification
|
* perform the key verification
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires when private keys for cross-signing need to be saved.
|
||||||
|
* @event module:client~MatrixClient#"cross-signing.savePrivateKeys"
|
||||||
|
* @param {object} keys the private keys to save.
|
||||||
|
* @param {UInt8Array} [keys.master] the private master key
|
||||||
|
* @param {UInt8Array} [keys.self_signing] the private user-signing key
|
||||||
|
* @param {UInt8Array} [keys.user_signing] the private self-signing key
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires when a private key is needed.
|
||||||
|
* @event module:client~MatrixClient#"cross-signing.getKey"
|
||||||
|
* @param {object} data
|
||||||
|
* @param {string} data.type the type of key needed. Will be one of "master",
|
||||||
|
* "self_signing", or "user_signing"
|
||||||
|
* @param {Function} data.done a function to call with the private key as a
|
||||||
|
* `UInt8Array`
|
||||||
|
* @param {Function} data.cancel a function to call if the private key cannot
|
||||||
|
* be provided
|
||||||
|
* @param {string} [data.error] Error string to display to the user. Normally
|
||||||
|
* provided if a previously provided key was invalid, to re-prompt the
|
||||||
|
* user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires when a new cross-signing key is provided from the server. The handler
|
||||||
|
* must verify the key by providing the private key for the given public key.
|
||||||
|
* @event module:client~MatrixClient#"cross-signing.newKey"
|
||||||
|
* @param {object} data
|
||||||
|
* @param {string} data.publicKey the public key received from the server
|
||||||
|
* @param {string} data.type the type of key that was received. Currently will
|
||||||
|
* only be "master".
|
||||||
|
* @param {Function} data.done a function to call with the private key
|
||||||
|
* corresponding to the given public key.
|
||||||
|
* @param {Function} data.cancel a function to call if the private key cannot be
|
||||||
|
* provided, indicating that the client does not accept the cross-signing key.
|
||||||
|
* @param {string} [data.error] Error string to display to the user. Normally
|
||||||
|
* provided if a previously provided key was invalid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires when a secret has been requested by another client. Clients should
|
||||||
|
* ensure that the requesting device is allowed to have the secret. For
|
||||||
|
* example, if the device is not already trusted, a verification should be
|
||||||
|
* performed before sharing the secret. The client may also wish to prompt the
|
||||||
|
* user before sharing the secret.
|
||||||
|
* @event module:client~MatrixClient#"crypto.secrets.request"
|
||||||
|
* @param {object} data
|
||||||
|
* @param {string} data.name The name of the secret being requested.
|
||||||
|
* @param {string} data.user_id (string) The user ID of the client requesting
|
||||||
|
* the secret. In most cases, this shoud be the same as the client's user.
|
||||||
|
* @param {string} data.device_id The device ID of the client requesting the secret.
|
||||||
|
* @param {string} data.request_id The ID of the request. Used to match a
|
||||||
|
* corresponding `crypto.secrets.request_cancelled`. The request ID will be
|
||||||
|
* unique per sender, device pair.
|
||||||
|
* @param {int} data.device_trust: The trust status of the device requesting
|
||||||
|
* the secret. Will be a bit mask in the same form as returned by {@link
|
||||||
|
* module:client~MatrixClient#checkDeviceTrust}.
|
||||||
|
* @param {Function} data.send A function to call to send the secret to the
|
||||||
|
* requester
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires when a secret request has been cancelled. If the client is prompting
|
||||||
|
* the user to ask whether they want to share a secret, the prompt can be
|
||||||
|
* dismissed.
|
||||||
|
* @event module:client~MatrixClient#"crypto.secrets.request_cancelled"
|
||||||
|
* @param {object} data
|
||||||
|
* @param {string} data.user_id The user ID of the client that had requested the secret.
|
||||||
|
* @param {string} data.device_id The device ID of the client that had requested the
|
||||||
|
* secret.
|
||||||
|
* @param {string} data.request_id The ID of the original request.
|
||||||
|
*/
|
||||||
|
|
||||||
// EventEmitter JSDocs
|
// EventEmitter JSDocs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ async function getPrivateKey(self, type, check) {
|
|||||||
let signing;
|
let signing;
|
||||||
do {
|
do {
|
||||||
[pubkey, signing] = await new Promise((resolve, reject) => {
|
[pubkey, signing] = await new Promise((resolve, reject) => {
|
||||||
self.emit("cross-signing:getKey", {
|
self.emit("cross-signing.getKey", {
|
||||||
type: type,
|
type: type,
|
||||||
error,
|
error,
|
||||||
done: (key) => {
|
done: (key) => {
|
||||||
@@ -178,7 +178,7 @@ export class CrossSigningInfo extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(this.keys, keys);
|
Object.assign(this.keys, keys);
|
||||||
this.emit("cross-signing:savePrivateKeys", privateKeys);
|
this.emit("cross-signing.savePrivateKeys", privateKeys);
|
||||||
} finally {
|
} finally {
|
||||||
if (masterSigning) {
|
if (masterSigning) {
|
||||||
masterSigning.free();
|
masterSigning.free();
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import { randomString } from '../randomstring';
|
|||||||
import { keyForNewBackup } from './backup_password';
|
import { keyForNewBackup } from './backup_password';
|
||||||
import { encodeRecoveryKey, decodeRecoveryKey } from './recoverykey';
|
import { encodeRecoveryKey, decodeRecoveryKey } from './recoverykey';
|
||||||
|
|
||||||
/** Implements MSC-1946
|
/**
|
||||||
|
* Implements secret storage and sharing (MSC-1946)
|
||||||
|
* @module crypto/Secrets
|
||||||
*/
|
*/
|
||||||
export default class SecretStorage extends EventEmitter {
|
export default class SecretStorage extends EventEmitter {
|
||||||
constructor(baseApis) {
|
constructor(baseApis) {
|
||||||
@@ -31,12 +33,26 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
this._incomingRequests = {};
|
this._incomingRequests = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
async addKey(type, opts) {
|
/**
|
||||||
const keyData = {
|
* Add a key for encrypting secrets.
|
||||||
algorithm: opts.algorithm,
|
*
|
||||||
};
|
* @param {string} algorithm the algorithm used by the key.
|
||||||
|
* @param {object} opts the options for the algorithm. The properties used
|
||||||
|
* depend on the algorithm given. This object may be modified to pass
|
||||||
|
* information back about the key.
|
||||||
|
* @param {string} [keyID] the ID of the key. If not given, a random
|
||||||
|
* ID will be generated.
|
||||||
|
*
|
||||||
|
* @return {string} the ID of the key
|
||||||
|
*/
|
||||||
|
async addKey(algorithm, opts, keyID) {
|
||||||
|
const keyData = {algorithm};
|
||||||
|
|
||||||
switch (opts.algorithm) {
|
if (opts.name) {
|
||||||
|
keyData.name = opts.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (algorithm) {
|
||||||
case "m.secret_storage.v1.curve25519-aes-sha2":
|
case "m.secret_storage.v1.curve25519-aes-sha2":
|
||||||
{
|
{
|
||||||
const decryption = new global.Olm.PkDecryption();
|
const decryption = new global.Olm.PkDecryption();
|
||||||
@@ -66,22 +82,25 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
throw new Error(`Unknown key algorithm ${opts.algorithm}`);
|
throw new Error(`Unknown key algorithm ${opts.algorithm}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyName;
|
if (!keyID) {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
keyName = randomString(32);
|
keyID = randomString(32);
|
||||||
} while (!this._baseApis.getAccountData(`m.secret_storage.key.${keyName}`));
|
} while (!this._baseApis.getAccountData(`m.secret_storage.key.${keyID}`));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: sign keyData?
|
// FIXME: sign keyData?
|
||||||
|
|
||||||
await this._baseApis.setAccountData(
|
await this._baseApis.setAccountData(
|
||||||
`m.secret_storage.key.${keyName}`, keyData,
|
`m.secret_storage.key.${keyID}`, keyData,
|
||||||
);
|
);
|
||||||
|
|
||||||
return keyName;
|
return keyID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** store an encrypted secret on the server
|
// TODO: need a function to get all the secret keys
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an encrypted secret on the server
|
||||||
*
|
*
|
||||||
* @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.
|
||||||
@@ -124,6 +143,13 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
await this._baseApis.setAccountData(name, {encrypted});
|
await this._baseApis.setAccountData(name, {encrypted});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a secret from storage.
|
||||||
|
*
|
||||||
|
* @param {string} name the name of the secret
|
||||||
|
*
|
||||||
|
* @return {string} the contents of the secret
|
||||||
|
*/
|
||||||
async get(name) {
|
async get(name) {
|
||||||
const secretInfo = this._baseApis.getAccountData(name);
|
const secretInfo = this._baseApis.getAccountData(name);
|
||||||
if (!secretInfo) {
|
if (!secretInfo) {
|
||||||
@@ -225,6 +251,15 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a secret is stored on the server.
|
||||||
|
*
|
||||||
|
* @param {string} name the name of the secret
|
||||||
|
* @param {boolean} checkKey check if the secret is encrypted by a trusted
|
||||||
|
* key (currently unimplemented)
|
||||||
|
*
|
||||||
|
* @return {boolean} whether or not the secret is stored
|
||||||
|
*/
|
||||||
isStored(name, checkKey) {
|
isStored(name, checkKey) {
|
||||||
// check if secret exists
|
// check if secret exists
|
||||||
const secretInfo = this._baseApis.getAccountData(name);
|
const secretInfo = this._baseApis.getAccountData(name);
|
||||||
@@ -263,6 +298,14 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a secret from another device
|
||||||
|
*
|
||||||
|
* @param {string} name the name of the secret to request
|
||||||
|
* @param {string[]} devices the devices to request the secret from
|
||||||
|
*
|
||||||
|
* @return {string} the contents of the secret
|
||||||
|
*/
|
||||||
request(name, devices) {
|
request(name, devices) {
|
||||||
const requestId = this._baseApis.makeTxnId();
|
const requestId = this._baseApis.makeTxnId();
|
||||||
|
|
||||||
@@ -347,7 +390,7 @@ export default class SecretStorage extends EventEmitter {
|
|||||||
logger.info("received request for secret (" + sender
|
logger.info("received request for secret (" + sender
|
||||||
+ ", " + deviceId + ", " + content.request_id + ")");
|
+ ", " + deviceId + ", " + content.request_id + ")");
|
||||||
this._baseApis.emit("crypto.secrets.request", {
|
this._baseApis.emit("crypto.secrets.request", {
|
||||||
sender: sender,
|
user_id: sender,
|
||||||
device_id: deviceId,
|
device_id: deviceId,
|
||||||
request_id: content.request_id,
|
request_id: content.request_id,
|
||||||
name: content.name,
|
name: content.name,
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ export default function Crypto(baseApis, sessionStore, userId, deviceId,
|
|||||||
|
|
||||||
this._crossSigningInfo = new CrossSigningInfo(userId);
|
this._crossSigningInfo = new CrossSigningInfo(userId);
|
||||||
this._reEmitter.reEmit(this._crossSigningInfo, [
|
this._reEmitter.reEmit(this._crossSigningInfo, [
|
||||||
"cross-signing:savePrivateKeys",
|
"cross-signing.savePrivateKeys",
|
||||||
"cross-signing:getKey",
|
"cross-signing.getKey",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this._secretStorage = new SecretStorage(baseApis);
|
this._secretStorage = new SecretStorage(baseApis);
|
||||||
@@ -213,6 +213,10 @@ export default function Crypto(baseApis, sessionStore, userId, deviceId,
|
|||||||
}
|
}
|
||||||
utils.inherits(Crypto, EventEmitter);
|
utils.inherits(Crypto, EventEmitter);
|
||||||
|
|
||||||
|
Crypto.prototype.addSecretKey = function(algorithm, opts, keyID) {
|
||||||
|
return this._secretStorage.store(algorithm, opts, keyID);
|
||||||
|
};
|
||||||
|
|
||||||
Crypto.prototype.storeSecret = function(name, secret, keys) {
|
Crypto.prototype.storeSecret = function(name, secret, keys) {
|
||||||
return this._secretStorage.store(name, secret, keys);
|
return this._secretStorage.store(name, secret, keys);
|
||||||
};
|
};
|
||||||
@@ -287,7 +291,8 @@ Crypto.prototype.init = async function() {
|
|||||||
/**
|
/**
|
||||||
* Generate new cross-signing keys.
|
* Generate new cross-signing keys.
|
||||||
*
|
*
|
||||||
* @param {CrossSigningLevel} level the level of cross-signing to reset. New
|
* @param {object} authDict Auth data to supply for User-Interactive auth.
|
||||||
|
* @param {CrossSigningLevel} [level] the level of cross-signing to reset. New
|
||||||
* keys will be created for the given level and below. Defaults to
|
* keys will be created for the given level and below. Defaults to
|
||||||
* regenerating all keys.
|
* regenerating all keys.
|
||||||
*/
|
*/
|
||||||
@@ -298,7 +303,7 @@ Crypto.prototype.resetCrossSigningKeys = async function(authDict, level) {
|
|||||||
keys[name + "_key"] = key;
|
keys[name + "_key"] = key;
|
||||||
}
|
}
|
||||||
await this._baseApis.uploadDeviceSigningKeys(authDict || {}, keys);
|
await this._baseApis.uploadDeviceSigningKeys(authDict || {}, keys);
|
||||||
this._baseApis.emit("cross-signing:keysChanged", {});
|
this._baseApis.emit("cross-signing.keysChanged", {});
|
||||||
|
|
||||||
const device = this._deviceList.getStoredDevice(this._userId, this._deviceId);
|
const device = this._deviceList.getStoredDevice(this._userId, this._deviceId);
|
||||||
const signedDevice = await this._crossSigningInfo.signDevice(this._userId, device);
|
const signedDevice = await this._crossSigningInfo.signDevice(this._userId, device);
|
||||||
@@ -312,8 +317,8 @@ Crypto.prototype.resetCrossSigningKeys = async function(authDict, level) {
|
|||||||
/**
|
/**
|
||||||
* Get the user's cross-signing key ID.
|
* Get the user's cross-signing key ID.
|
||||||
*
|
*
|
||||||
* @param {string} type The type of key to get the ID of. One of "master",
|
* @param {string} [type=master] The type of key to get the ID of. One of
|
||||||
* "self_signing", or "user_signing". Defaults to "master".
|
* "master", "self_signing", or "user_signing". Defaults to "master".
|
||||||
*
|
*
|
||||||
* @returns {string} the key ID
|
* @returns {string} the key ID
|
||||||
*/
|
*/
|
||||||
@@ -321,6 +326,13 @@ Crypto.prototype.getCrossSigningId = function(type) {
|
|||||||
return this._crossSigningInfo.getId(type);
|
return this._crossSigningInfo.getId(type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cross signing information for a given user.
|
||||||
|
*
|
||||||
|
* @param {string} userId the user ID to get the cross-signing info for.
|
||||||
|
*
|
||||||
|
* @returns {CrossSigningInfo} the cross signing informmation for the user.
|
||||||
|
*/
|
||||||
Crypto.prototype.getStoredCrossSigningForUser = function(userId) {
|
Crypto.prototype.getStoredCrossSigningForUser = function(userId) {
|
||||||
return this._deviceList.getStoredCrossSigningForUser(userId);
|
return this._deviceList.getStoredCrossSigningForUser(userId);
|
||||||
};
|
};
|
||||||
@@ -415,7 +427,7 @@ Crypto.prototype.checkOwnCrossSigningTrust = async function() {
|
|||||||
let error;
|
let error;
|
||||||
do {
|
do {
|
||||||
privkey = await new Promise((resolve, reject) => {
|
privkey = await new Promise((resolve, reject) => {
|
||||||
this._baseApis.emit("cross-signing:newKey", {
|
this._baseApis.emit("cross-signing.newKey", {
|
||||||
publicKey: seenPubkey,
|
publicKey: seenPubkey,
|
||||||
type: "master",
|
type: "master",
|
||||||
error,
|
error,
|
||||||
@@ -436,18 +448,21 @@ Crypto.prototype.checkOwnCrossSigningTrust = async function() {
|
|||||||
resolve(key);
|
resolve(key);
|
||||||
},
|
},
|
||||||
cancel: (error) => {
|
cancel: (error) => {
|
||||||
|
// FIXME: should we forcibly push our copy of the key
|
||||||
|
// to the server if the client rejects the server's
|
||||||
|
// key?
|
||||||
reject(error || new Error("Cancelled by user"));
|
reject(error || new Error("Cancelled by user"));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} while (!privkey);
|
} while (!privkey);
|
||||||
this._baseApis.emit("cross-signing:savePrivateKeys", {master: privkey});
|
this._baseApis.emit("cross-signing.savePrivateKeys", {master: privkey});
|
||||||
|
|
||||||
logger.info("Got private key");
|
logger.info("Got private key");
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldSelfSigningId = this._crossSigningInfo.getId("self_signing");
|
const oldSelfSigningId = this._crossSigningInfo.getId("self_signing");
|
||||||
const oldUserSigningId = this._crossSigningInfo.getId("user_signing")
|
const oldUserSigningId = this._crossSigningInfo.getId("user_signing");
|
||||||
|
|
||||||
this._crossSigningInfo.setKeys(newCrossSigning.keys);
|
this._crossSigningInfo.setKeys(newCrossSigning.keys);
|
||||||
// FIXME: save it ... somewhere?
|
// FIXME: save it ... somewhere?
|
||||||
@@ -470,7 +485,7 @@ Crypto.prototype.checkOwnCrossSigningTrust = async function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this._baseApis.emit("cross-signing:keysChanged", {});
|
this._baseApis.emit("cross-signing.keysChanged", {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
|
|||||||
Reference in New Issue
Block a user