You've already forked matrix-js-sdk
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:
@@ -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
|
* Download device keys
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1070,8 +1070,10 @@ MatrixClient.prototype.createKeyBackupVersion = function(info, auth, replacesSsk
|
|||||||
};
|
};
|
||||||
|
|
||||||
return this._cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
|
return this._cryptoStore.doTxn('readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
|
||||||
|
// store the newly generated account keys
|
||||||
this._cryptoStore.storeAccountKeys(txn, info.accountKeys);
|
this._cryptoStore.storeAccountKeys(txn, info.accountKeys);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
// upload the public part of the account keys
|
||||||
return this.uploadDeviceSigningKeys(keys);
|
return this.uploadDeviceSigningKeys(keys);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return this._crypto._signObject(data.auth_data);
|
return this._crypto._signObject(data.auth_data);
|
||||||
@@ -1086,6 +1088,9 @@ MatrixClient.prototype.createKeyBackupVersion = function(info, auth, replacesSsk
|
|||||||
version: res.version,
|
version: res.version,
|
||||||
});
|
});
|
||||||
return res;
|
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 totalKeyCount = 0;
|
||||||
let keys = [];
|
let keys = [];
|
||||||
|
|
||||||
const path = this._makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version);
|
|
||||||
|
|
||||||
const decryption = new global.Olm.PkDecryption();
|
const decryption = new global.Olm.PkDecryption();
|
||||||
try {
|
try {
|
||||||
decryption.init_with_private_key(privKey);
|
decryption.init_with_private_key(privKey);
|
||||||
@@ -1237,9 +1240,14 @@ MatrixClient.prototype._restoreKeyBackup = async function(
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._http.authedRequest(
|
// start by signing this device from the SSK now we have it
|
||||||
undefined, "GET", path.path, path.queryData,
|
return this._crypto.uploadDeviceKeySignatures().then(() => {
|
||||||
).then((res) => {
|
// 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) => {
|
||||||
if (res.rooms) {
|
if (res.rooms) {
|
||||||
for (const [roomId, roomData] of Object.entries(res.rooms)) {
|
for (const [roomId, roomData] of Object.entries(res.rooms)) {
|
||||||
if (!roomData.sessions) continue;
|
if (!roomData.sessions) continue;
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ import {
|
|||||||
newUnknownMethodError,
|
newUnknownMethodError,
|
||||||
} from './verification/Error';
|
} from './verification/Error';
|
||||||
|
|
||||||
|
import { pkSign } from './PkSigning';
|
||||||
|
|
||||||
const defaultVerificationMethods = {
|
const defaultVerificationMethods = {
|
||||||
[ScanQRCode.NAME]: ScanQRCode,
|
[ScanQRCode.NAME]: ScanQRCode,
|
||||||
[ShowQRCode.NAME]: ShowQRCode,
|
[ShowQRCode.NAME]: ShowQRCode,
|
||||||
@@ -457,8 +459,20 @@ Crypto.prototype.uploadDeviceKeys = function() {
|
|||||||
user_id: userId,
|
user_id: userId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let accountKeys;
|
||||||
return crypto._signObject(deviceKeys).then(() => {
|
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,
|
device_keys: deviceKeys,
|
||||||
}, {
|
}, {
|
||||||
// for now, we set the device id explicitly, as we may not be using the
|
// 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
|
* 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.
|
* onSyncCompleted). The count is e.g. coming from a /sync response.
|
||||||
|
|||||||
Reference in New Issue
Block a user