1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00
or at least the rules that are consistent with the rest of our
codebase
This commit is contained in:
David Baker
2019-02-01 18:12:27 +00:00
parent 7195365188
commit 7dedcb82b2
5 changed files with 82 additions and 42 deletions

View File

@@ -1596,7 +1596,8 @@ MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
MatrixBaseApis.prototype.uploadKeySignatures = function(content) { MatrixBaseApis.prototype.uploadKeySignatures = function(content) {
return this._http.authedRequestWithPrefix( return this._http.authedRequestWithPrefix(
undefined, "POST", '/keys/signatures/upload', undefined, content, httpApi.PREFIX_UNSTABLE, undefined, "POST", '/keys/signatures/upload', undefined,
content, httpApi.PREFIX_UNSTABLE,
); );
}; };

View File

@@ -958,7 +958,9 @@ MatrixClient.prototype.prepareKeyBackupVersion = async function(password) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
let decryption, encryption, signing; let decryption;
let encryption;
let signing;
try { try {
decryption = new global.Olm.PkDecryption(); decryption = new global.Olm.PkDecryption();
encryption = new global.Olm.PkEncryption(); encryption = new global.Olm.PkEncryption();
@@ -988,32 +990,43 @@ MatrixClient.prototype.prepareKeyBackupVersion = async function(password) {
}; };
if (signing) { if (signing) {
await this._cryptoStore.doTxn('readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { await this._cryptoStore.doTxn(
this._cryptoStore.getAccountKeys(txn, keys => { 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT],
returnInfo.accountKeys = keys; (txn) => {
}); this._cryptoStore.getAccountKeys(txn, (keys) => {
}); returnInfo.accountKeys = keys;
});
},
);
if (!returnInfo.accountKeys) { if (!returnInfo.accountKeys) {
const ssk_seed = signing.generate_seed(); const sskSeed = signing.generate_seed();
const usk_seed = signing.generate_seed(); const uskSeed = signing.generate_seed();
returnInfo.accountKeys = { returnInfo.accountKeys = {
self_signing_key_seed: Buffer.from(ssk_seed).toString('base64'), self_signing_key_seed: Buffer.from(sskSeed).toString('base64'),
user_signing_key_seed: Buffer.from(usk_seed).toString('base64'), user_signing_key_seed: Buffer.from(uskSeed).toString('base64'),
} };
} }
// put the encrypted version of the seed in the auth data to upload // put the encrypted version of the seed in the auth data to upload
// XXX: our encryption really should support encrypting binary data. // XXX: our encryption really should support encrypting binary data.
authData.self_signing_key_seed = encryption.encrypt(returnInfo.accountKeys.self_signing_key_seed); authData.self_signing_key_seed = encryption.encrypt(
returnInfo.accountKeys.self_signing_key_seed,
);
// also keep the public part there // also keep the public part there
returnInfo.ssk_public = signing.init_with_seed(Buffer.from(returnInfo.accountKeys.self_signing_key_seed, 'base64')); returnInfo.ssk_public = signing.init_with_seed(
Buffer.from(returnInfo.accountKeys.self_signing_key_seed, 'base64'),
);
signing.free(); signing.free();
// same for the USK // same for the USK
authData.user_signing_key_seed = encryption.encrypt(returnInfo.accountKeys.user_signing_key_seed); authData.user_signing_key_seed = encryption.encrypt(
returnInfo.usk_public = signing.init_with_seed(Buffer.from(returnInfo.accountKeys.user_signing_key_seed, 'base64')); returnInfo.accountKeys.user_signing_key_seed,
);
returnInfo.usk_public = signing.init_with_seed(
Buffer.from(returnInfo.accountKeys.user_signing_key_seed, 'base64'),
);
signing.free(); signing.free();
// we don't save these keys back to the store yet: we'll do that when (if) we // we don't save these keys back to the store yet: we'll do that when (if) we
@@ -1033,6 +1046,8 @@ MatrixClient.prototype.prepareKeyBackupVersion = async function(password) {
* from prepareKeyBackupVersion. * from prepareKeyBackupVersion.
* *
* @param {object} info Info object from prepareKeyBackupVersion * @param {object} info Info object from prepareKeyBackupVersion
* @param {object} auth Auth object for UI auth
* @param {string} replacesSsk If the SSK is being replaced, the ID of the old key
* @returns {Promise<object>} Object with 'version' param indicating the version created * @returns {Promise<object>} Object with 'version' param indicating the version created
*/ */
MatrixClient.prototype.createKeyBackupVersion = async function(info, auth, replacesSsk) { MatrixClient.prototype.createKeyBackupVersion = async function(info, auth, replacesSsk) {
@@ -1054,7 +1069,11 @@ MatrixClient.prototype.createKeyBackupVersion = async function(info, auth, repla
}; };
// sign the USK with the SSK // sign the USK with the SSK
pkSign(uskInfo, Buffer.from(info.accountKeys.self_signing_key_seed, 'base64'), this.credentials.userId); pkSign(
uskInfo,
Buffer.from(info.accountKeys.self_signing_key_seed, 'base64'),
this.credentials.userId,
);
// Now sig the backup auth data. Do it as this device first because crypto._signObject // Now sig the backup auth data. Do it as this device first because crypto._signObject
// is dumb and bluntly replaces the whole signatures block... // is dumb and bluntly replaces the whole signatures block...
@@ -1062,7 +1081,11 @@ MatrixClient.prototype.createKeyBackupVersion = async function(info, auth, repla
await this._crypto._signObject(data.auth_data); await this._crypto._signObject(data.auth_data);
// now also sign the auth data with the SSK // now also sign the auth data with the SSK
pkSign(data.auth_data, Buffer.from(info.accountKeys.self_signing_key_seed, 'base64'), this.credentials.userId); pkSign(
data.auth_data,
Buffer.from(info.accountKeys.self_signing_key_seed, 'base64'),
this.credentials.userId,
);
const keys = { const keys = {
self_signing_key: { self_signing_key: {
@@ -1077,10 +1100,13 @@ MatrixClient.prototype.createKeyBackupVersion = async function(info, auth, repla
auth, auth,
}; };
return this._cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { return this._cryptoStore.doTxn(
// store the newly generated account keys 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT],
this._cryptoStore.storeAccountKeys(txn, info.accountKeys); (txn) => {
}).then(() => { // store the newly generated account keys
this._cryptoStore.storeAccountKeys(txn, info.accountKeys);
},
).then(() => {
// re-check the SSK in the device store if necessary // re-check the SSK in the device store if necessary
return this._crypto.checkOwnSskTrust(); return this._crypto.checkOwnSskTrust();
}).then(() => { }).then(() => {
@@ -1220,11 +1246,14 @@ MatrixClient.prototype._restoreKeyBackup = async function(
// decrypt the account keys from the backup info if there are any // decrypt the account keys from the backup info if there are any
// fetch the old ones first so we don't lose info if only one of them is in the backup // fetch the old ones first so we don't lose info if only one of them is in the backup
let accountKeys; let accountKeys;
await this._cryptoStore.doTxn('readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { await this._cryptoStore.doTxn(
this._cryptoStore.getAccountKeys(txn, keys => { 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT],
accountKeys = keys || {}; (txn) => {
}); this._cryptoStore.getAccountKeys(txn, (keys) => {
}); accountKeys = keys || {};
});
},
);
if (backupInfo.auth_data.self_signing_key_seed) { if (backupInfo.auth_data.self_signing_key_seed) {
accountKeys.self_signing_key_seed = decryption.decrypt( accountKeys.self_signing_key_seed = decryption.decrypt(
@@ -1241,9 +1270,12 @@ MatrixClient.prototype._restoreKeyBackup = async function(
); );
} }
await this._cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { await this._cryptoStore.doTxn(
this._cryptoStore.storeAccountKeys(txn, accountKeys); 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT],
}); (txn) => {
this._cryptoStore.storeAccountKeys(txn, accountKeys);
},
);
await this._crypto.checkOwnSskTrust(); await this._crypto.checkOwnSskTrust();
} catch(e) { } catch(e) {
@@ -1254,7 +1286,9 @@ MatrixClient.prototype._restoreKeyBackup = async function(
// start by signing this device from the SSK now we have it // start by signing this device from the SSK now we have it
return this._crypto.uploadDeviceKeySignatures().then(() => { return this._crypto.uploadDeviceKeySignatures().then(() => {
// Now fetch the encrypted keys // Now fetch the encrypted keys
const path = this._makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version); const path = this._makeKeyBackupPath(
targetRoomId, targetSessionId, backupInfo.version,
);
return this._http.authedRequest( return this._http.authedRequest(
undefined, "GET", path.path, path.queryData, undefined, "GET", path.path, path.queryData,
); );

View File

@@ -788,7 +788,9 @@ class DeviceListUpdateSerialiser {
let prom = Promise.resolve(); let prom = Promise.resolve();
for (const userId of downloadUsers) { for (const userId of downloadUsers) {
prom = prom.delay(5).then(() => { prom = prom.delay(5).then(() => {
return this._processQueryResponseForUser(userId, dk[userId], ssks[userId]); return this._processQueryResponseForUser(
userId, dk[userId], ssks[userId],
);
}); });
} }
@@ -812,9 +814,9 @@ class DeviceListUpdateSerialiser {
return deferred.promise; return deferred.promise;
} }
async _processQueryResponseForUser(userId, dk_response, ssk_response) { async _processQueryResponseForUser(userId, dkResponse, sskResponse) {
logger.log('got device keys for ' + userId + ':', dk_response); logger.log('got device keys for ' + userId + ':', dkResponse);
logger.log('got self-signing keys for ' + userId + ':', ssk_response); logger.log('got self-signing keys for ' + userId + ':', sskResponse);
{ {
// map from deviceid -> deviceinfo for this user // map from deviceid -> deviceinfo for this user
@@ -828,7 +830,7 @@ class DeviceListUpdateSerialiser {
} }
await _updateStoredDeviceKeysForUser( await _updateStoredDeviceKeysForUser(
this._olmDevice, userId, userStore, dk_response || {}, this._olmDevice, userId, userStore, dkResponse || {},
); );
// put the updates into the object that will be returned as our results // put the updates into the object that will be returned as our results
@@ -845,7 +847,7 @@ class DeviceListUpdateSerialiser {
const ssk = this._deviceList.getRawStoredSskForUser(userId) || {}; const ssk = this._deviceList.getRawStoredSskForUser(userId) || {};
const updated = await _updateStoredSelfSigningKeyForUser( const updated = await _updateStoredSelfSigningKeyForUser(
this._olmDevice, userId, ssk, ssk_response || {}, this._olmDevice, userId, ssk, sskResponse || {},
); );
this._deviceList.setRawStoredSskForUser(userId, ssk); this._deviceList.setRawStoredSskForUser(userId, ssk);

View File

@@ -18,6 +18,9 @@ const anotherjson = require('another-json');
/** /**
* Higher level wrapper around olm.PkSigning that signs JSON objects * Higher level wrapper around olm.PkSigning that signs JSON objects
* @param obj {Object} Object to sign
* @param seed {Uint8Array} The private key seed (32 bytes)
* @param userId {string} The user ID who owns the signing key
*/ */
export function pkSign(obj, seed, userId) { export function pkSign(obj, seed, userId) {
const signing = new global.Olm.PkSigning(); const signing = new global.Olm.PkSigning();

View File

@@ -268,7 +268,7 @@ Crypto.prototype._onDeviceListUserSskUpdated = async function(userId) {
if (userId === this._userId) { if (userId === this._userId) {
this.checkOwnSskTrust(); this.checkOwnSskTrust();
} }
} };
/* /*
* Check the copy of our SSK that we have in the device list and see if it * Check the copy of our SSK that we have in the device list and see if it
@@ -303,7 +303,7 @@ Crypto.prototype.checkOwnSskTrust = async function() {
let localPubkey; let localPubkey;
try { try {
signing = new global.Olm.PkSigning(); signing = new global.Olm.PkSigning();
localPubkey = signing.init_with_seed(Buffer.from(accountKeys.self_signing_key_seed, 'base64')) localPubkey = signing.init_with_seed(Buffer.from(accountKeys.self_signing_key_seed, 'base64'));
} finally { } finally {
if (signing) signing.free(); if (signing) signing.free();
signing = null; signing = null;
@@ -467,7 +467,7 @@ Crypto.prototype.isKeyBackupTrusted = async function(backupInfo) {
s.valid && ( s.valid && (
(s.device && s.device.isVerified()) || (s.self_signing_key && s.self_signing_key.isVerified()) (s.device && s.device.isVerified()) || (s.self_signing_key && s.self_signing_key.isVerified())
) )
) );
}); });
return ret; return ret;
}; };
@@ -622,7 +622,7 @@ Crypto.prototype.uploadDeviceKeySignatures = async function() {
}; };
await crypto._baseApis.uploadKeySignatures(content); await crypto._baseApis.uploadKeySignatures(content);
return true return true;
}; };
/** /**
@@ -829,7 +829,7 @@ Crypto.prototype.setSskVerification = async function(userId, verified) {
throw new Error("No self-signing key found for user " + userId); throw new Error("No self-signing key found for user " + userId);
} }
ssk.verified = verified; ssk.verified = verified;
this._deviceList.storeSskForUser(userId, ssk) this._deviceList.storeSskForUser(userId, ssk);
this._deviceList.saveIfDirty(); this._deviceList.saveIfDirty();
}; };