1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-08 19:08:34 +03:00

Cross sign the current device with the SSK

whenever we get the SSK, ie. when creating or restoring a backup
This commit is contained in:
David Baker
2019-01-31 21:13:01 +00:00
parent 02d4dcb128
commit 1f77cc6d1a
3 changed files with 73 additions and 6 deletions

View File

@@ -1594,6 +1594,12 @@ MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
);
};
MatrixBaseApis.prototype.uploadKeySignatures = function(content) {
return this._http.authedRequestWithPrefix(
undefined, "POST", '/keys/signatures/upload', undefined, content, httpApi.PREFIX_UNSTABLE,
);
};
/**
* Download device keys
*

View File

@@ -1070,8 +1070,10 @@ MatrixClient.prototype.createKeyBackupVersion = function(info, auth, replacesSsk
};
return this._cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
// store the newly generated account keys
this._cryptoStore.storeAccountKeys(txn, info.accountKeys);
}).then(() => {
// upload the public part of the account keys
return this.uploadDeviceSigningKeys(keys);
}).then(() => {
return this._crypto._signObject(data.auth_data);
@@ -1086,6 +1088,9 @@ MatrixClient.prototype.createKeyBackupVersion = function(info, auth, replacesSsk
version: res.version,
});
return res;
}).then(() => {
// upload signatures between the SSK & this device
return this._crypto.uploadDeviceKeySignatures();
});
};
@@ -1199,8 +1204,6 @@ MatrixClient.prototype._restoreKeyBackup = async function(
let totalKeyCount = 0;
let keys = [];
const path = this._makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version);
const decryption = new global.Olm.PkDecryption();
try {
decryption.init_with_private_key(privKey);
@@ -1237,9 +1240,14 @@ MatrixClient.prototype._restoreKeyBackup = async function(
throw e;
}
// start by signing this device from the SSK now we have it
return this._crypto.uploadDeviceKeySignatures().then(() => {
// Now fetch the encrypted keys
const path = this._makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version);
return this._http.authedRequest(
undefined, "GET", path.path, path.queryData,
).then((res) => {
);
}).then((res) => {
if (res.rooms) {
for (const [roomId, roomData] of Object.entries(res.rooms)) {
if (!roomData.sessions) continue;

View File

@@ -46,6 +46,8 @@ import {
newUnknownMethodError,
} from './verification/Error';
import { pkSign } from './PkSigning';
const defaultVerificationMethods = {
[ScanQRCode.NAME]: ScanQRCode,
[ShowQRCode.NAME]: ShowQRCode,
@@ -457,8 +459,20 @@ Crypto.prototype.uploadDeviceKeys = function() {
user_id: userId,
};
let accountKeys;
return crypto._signObject(deviceKeys).then(() => {
crypto._baseApis.uploadKeysRequest({
return this._cryptoStore.doTxn('readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
this._cryptoStore.getAccountKeys(txn, keys => {
accountKeys = keys;
});
});
}).then(() => {
if (accountKeys && accountKeys.self_signing_key_seed) {
// if we have an SSK, sign the key with the SSK too
pkSign(deviceKeys, Buffer.from(accountKeys.self_signing_key_seed, 'base64'), userId);
}
return crypto._baseApis.uploadKeysRequest({
device_keys: deviceKeys,
}, {
// for now, we set the device id explicitly, as we may not be using the
@@ -468,6 +482,45 @@ Crypto.prototype.uploadDeviceKeys = function() {
});
};
/**
* If a self-signing key is available, uploads the signature of this device from
* the self-signing key
*
* @return {bool} Promise: True if signatures were uploaded or otherwise false
* (eg. if no account keys were available)
*/
Crypto.prototype.uploadDeviceKeySignatures = async function() {
const crypto = this;
const userId = crypto._userId;
const deviceId = crypto._deviceId;
const thisDeviceKey = {
algorithms: crypto._supportedAlgorithms,
device_id: deviceId,
keys: crypto._deviceKeys,
user_id: userId,
};
let accountKeys;
await this._cryptoStore.doTxn('readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
this._cryptoStore.getAccountKeys(txn, keys => {
accountKeys = keys;
});
});
if (!accountKeys || !accountKeys.self_signing_key_seed) return false;
// Sign this device with the SSK
pkSign(thisDeviceKey, Buffer.from(accountKeys.self_signing_key_seed, 'base64'), userId);
const content = {
[userId]: {
[deviceId]: thisDeviceKey,
},
};
await crypto._baseApis.uploadKeySignatures(content);
return true
};
/**
* Stores the current one_time_key count which will be handled later (in a call of
* onSyncCompleted). The count is e.g. coming from a /sync response.