Skip to content

Commit 5be4548

Browse files
Fix an instance of failed to decrypt error when an in flight /keys/query fails. (#3486)
* Fix an instance of failed to decrypt error Specifically, when checking the event sender matches who sent us the session keys we skip waiting for pending device list updates if we already know who owns the session key. * Apply suggestions from code review Co-authored-by: Richard van der Hoff <[email protected]> * Update src/crypto/algorithms/olm.ts Co-authored-by: Richard van der Hoff <[email protected]> * Fix line wrapping * Update src/crypto/algorithms/olm.ts * Fix null check --------- Co-authored-by: Richard van der Hoff <[email protected]>
1 parent 09de76b commit 5be4548

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/crypto/algorithms/olm.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -194,24 +194,37 @@ class OlmDecryption extends DecryptionAlgorithm {
194194

195195
// check that the device that encrypted the event belongs to the user that the event claims it's from.
196196
//
197-
// To do this, we need to make sure that our device list is up-to-date. If the device is unknown, we can only
198-
// assume that the device logged out and accept it anyway. Some event handlers, such as secret sharing, may be
199-
// more strict and reject events that come from unknown devices.
197+
// If the device is unknown then we check that we don't have any pending key-query requests for the sender. If
198+
// after that the device is still unknown, then we can only assume that the device logged out and accept it
199+
// anyway. Some event handlers, such as secret sharing, may be more strict and reject events that come from
200+
// unknown devices.
200201
//
201202
// This is a defence against the following scenario:
202203
//
203204
// * Alice has verified Bob and Mallory.
204205
// * Mallory gets control of Alice's server, and sends a megolm session to Alice using her (Mallory's)
205206
// senderkey, but claiming to be from Bob.
206207
// * Mallory sends more events using that session, claiming to be from Bob.
207-
// * Alice sees that the senderkey is verified (since she verified Mallory) so marks events those
208-
// events as verified even though the sender is forged.
208+
// * Alice sees that the senderkey is verified (since she verified Mallory) so marks events those events as
209+
// verified even though the sender is forged.
209210
//
210211
// In practice, it's not clear that the js-sdk would behave that way, so this may be only a defence in depth.
211212

212-
await this.crypto.deviceList.downloadKeys([event.getSender()!], false);
213-
const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, deviceKey);
214-
if (senderKeyUser !== event.getSender() && senderKeyUser != undefined) {
213+
let senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, deviceKey);
214+
if (senderKeyUser === undefined || senderKeyUser === null) {
215+
// Wait for any pending key query fetches for the user to complete before trying the lookup again.
216+
try {
217+
await this.crypto.deviceList.downloadKeys([event.getSender()!], false);
218+
} catch (e) {
219+
throw new DecryptionError("OLM_BAD_SENDER_CHECK_FAILED", "Could not verify sender identity", {
220+
sender: deviceKey,
221+
err: e as Error,
222+
});
223+
}
224+
225+
senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, deviceKey);
226+
}
227+
if (senderKeyUser !== event.getSender() && senderKeyUser !== undefined && senderKeyUser !== null) {
215228
throw new DecryptionError("OLM_BAD_SENDER", "Message claimed to be from " + event.getSender(), {
216229
real_sender: senderKeyUser,
217230
});

0 commit comments

Comments
 (0)