1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-28 05:03:59 +03:00

don't trust keys megolm received from backup for verifying the sender

This commit is contained in:
Hubert Chathi
2020-06-15 17:47:25 -04:00
parent 1da959ab02
commit bc97e7a5ea
6 changed files with 30 additions and 8 deletions

View File

@@ -517,6 +517,7 @@ describe("MegolmBackup", function() {
return megolmDecryption.decryptEvent(ENCRYPTED_EVENT); return megolmDecryption.decryptEvent(ENCRYPTED_EVENT);
}).then((res) => { }).then((res) => {
expect(res.clearEvent.content).toEqual('testytest'); expect(res.clearEvent.content).toEqual('testytest');
expect(res.untrusted).toBeTruthy(); // keys from backup are untrusted
}); });
}); });

View File

@@ -1978,7 +1978,7 @@ MatrixClient.prototype._restoreKeyBackup = function(
} }
} }
return this.importRoomKeys(keys, { progressCallback }); return this.importRoomKeys(keys, { progressCallback, untrusted: true, source: "backup" });
}).then(() => { }).then(() => {
return this._crypto.setTrustedBackupPubKey(backupPubKey); return this._crypto.setTrustedBackupPubKey(backupPubKey);
}).then(() => { }).then(() => {

View File

@@ -992,12 +992,14 @@ OlmDevice.prototype._getInboundGroupSession = function(
* @param {Object<string, string>} keysClaimed Other keys the sender claims. * @param {Object<string, string>} keysClaimed Other keys the sender claims.
* @param {boolean} exportFormat true if the megolm keys are in export format * @param {boolean} exportFormat true if the megolm keys are in export format
* (ie, they lack an ed25519 signature) * (ie, they lack an ed25519 signature)
* @param {Object} extraSessionData any other data to be include with the session
*/ */
OlmDevice.prototype.addInboundGroupSession = async function( OlmDevice.prototype.addInboundGroupSession = async function(
roomId, senderKey, forwardingCurve25519KeyChain, roomId, senderKey, forwardingCurve25519KeyChain,
sessionId, sessionKey, keysClaimed, sessionId, sessionKey, keysClaimed,
exportFormat, exportFormat, extraSessionData,
) { ) {
extraSessionData = extraSessionData || {};
await this._cryptoStore.doTxn( await this._cryptoStore.doTxn(
'readwrite', [ 'readwrite', [
IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS, IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,
@@ -1043,12 +1045,12 @@ OlmDevice.prototype.addInboundGroupSession = async function(
" with first index " + session.first_known_index(), " with first index " + session.first_known_index(),
); );
const sessionData = { const sessionData = Object.assign({}, extraSessionData, {
room_id: roomId, room_id: roomId,
session: session.pickle(this._pickleKey), session: session.pickle(this._pickleKey),
keysClaimed: keysClaimed, keysClaimed: keysClaimed,
forwardingCurve25519KeyChain: forwardingCurve25519KeyChain, forwardingCurve25519KeyChain: forwardingCurve25519KeyChain,
}; });
this._cryptoStore.storeEndToEndInboundGroupSession( this._cryptoStore.storeEndToEndInboundGroupSession(
senderKey, sessionId, sessionData, txn, senderKey, sessionId, sessionData, txn,
@@ -1224,6 +1226,7 @@ OlmDevice.prototype.decryptGroupMessage = async function(
forwardingCurve25519KeyChain: ( forwardingCurve25519KeyChain: (
sessionData.forwardingCurve25519KeyChain || [] sessionData.forwardingCurve25519KeyChain || []
), ),
untrusted: sessionData.untrusted,
}; };
}, },
); );

View File

@@ -1201,6 +1201,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) {
senderCurve25519Key: res.senderKey, senderCurve25519Key: res.senderKey,
claimedEd25519Key: res.keysClaimed.ed25519, claimedEd25519Key: res.keysClaimed.ed25519,
forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain, forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain,
untrusted: res.untrusted,
}; };
}; };
@@ -1548,8 +1549,10 @@ MegolmDecryption.prototype._buildKeyForwardingMessage = async function(
* @inheritdoc * @inheritdoc
* *
* @param {module:crypto/OlmDevice.MegolmSessionData} session * @param {module:crypto/OlmDevice.MegolmSessionData} session
* @param {string} source where the key comes from
*/ */
MegolmDecryption.prototype.importRoomKey = function(session) { MegolmDecryption.prototype.importRoomKey = function(session, opts) {
opts = opts || {};
return this._olmDevice.addInboundGroupSession( return this._olmDevice.addInboundGroupSession(
session.room_id, session.room_id,
session.sender_key, session.sender_key,
@@ -1558,8 +1561,9 @@ MegolmDecryption.prototype.importRoomKey = function(session) {
session.session_key, session.session_key,
session.sender_claimed_keys, session.sender_claimed_keys,
true, true,
opts.untrusted ? { untrusted: opts.untrusted } : {},
).then(() => { ).then(() => {
if (this._crypto.backupInfo) { if (this._crypto.backupInfo && opts.source !== "backup") {
// don't wait for it to complete // don't wait for it to complete
this._crypto.backupGroupSession( this._crypto.backupGroupSession(
session.room_id, session.room_id,

View File

@@ -2238,11 +2238,16 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) {
const forwardingChain = event.getForwardingCurve25519KeyChain(); const forwardingChain = event.getForwardingCurve25519KeyChain();
if (forwardingChain.length > 0) { if (forwardingChain.length > 0) {
// we got this event from somewhere else // we got the key this event from somewhere else
// TODO: check if we can trust the forwarders. // TODO: check if we can trust the forwarders.
return null; return null;
} }
if (event.isUntrusted()) {
// we got the key for this event from a source that we consider untrusted
return null;
}
// senderKey is the Curve25519 identity key of the device which the event // senderKey is the Curve25519 identity key of the device which the event
// was sent from. In the case of Megolm, it's actually the Curve25519 // was sent from. In the case of Megolm, it's actually the Curve25519
// identity key of the device which set up the Megolm session. // identity key of the device which set up the Megolm session.
@@ -2525,7 +2530,7 @@ Crypto.prototype.importRoomKeys = function(keys, opts = {}) {
} }
const alg = this._getRoomDecryptor(key.room_id, key.algorithm); const alg = this._getRoomDecryptor(key.room_id, key.algorithm);
return alg.importRoomKey(key).finally((r) => { return alg.importRoomKey(key, opts).finally((r) => {
successes++; successes++;
if (opts.progressCallback) { updateProgress(); } if (opts.progressCallback) { updateProgress(); }
}); });

View File

@@ -144,6 +144,10 @@ export const MatrixEvent = function(
*/ */
this._forwardingCurve25519KeyChain = []; this._forwardingCurve25519KeyChain = [];
/* where the decryption key is untrusted
*/
this._untrusted = null;
/* if we have a process decrypting this event, a Promise which resolves /* if we have a process decrypting this event, a Promise which resolves
* when it is finished. Normally null. * when it is finished. Normally null.
*/ */
@@ -599,6 +603,7 @@ utils.extend(MatrixEvent.prototype, {
decryptionResult.claimedEd25519Key || null; decryptionResult.claimedEd25519Key || null;
this._forwardingCurve25519KeyChain = this._forwardingCurve25519KeyChain =
decryptionResult.forwardingCurve25519KeyChain || []; decryptionResult.forwardingCurve25519KeyChain || [];
this._untrusted = decryptionResult.untrusted || false;
}, },
/** /**
@@ -689,6 +694,10 @@ utils.extend(MatrixEvent.prototype, {
return this._forwardingCurve25519KeyChain; return this._forwardingCurve25519KeyChain;
}, },
isUntrusted: function() {
return this._untrusted;
},
getUnsigned: function() { getUnsigned: function() {
return this.event.unsigned || {}; return this.event.unsigned || {};
}, },