Skip to content

Commit

Permalink
Verify target device key on reshare
Browse files Browse the repository at this point in the history
  • Loading branch information
RiotRobot committed Sep 13, 2021
1 parent f8186ad commit 894c248
Showing 1 changed file with 29 additions and 9 deletions.
38 changes: 29 additions & 9 deletions src/crypto/algorithms/megolm.ts
Expand Up @@ -101,6 +101,13 @@ interface IPayload extends Partial<IMessage> {
}
/* eslint-enable camelcase */

interface SharedWithData {
// The identity key of the device we shared with
deviceKey: string;
// The message index of the ratchet we shared with that device
messageIndex: number;
}

/**
* @private
* @constructor
Expand All @@ -115,12 +122,12 @@ interface IPayload extends Partial<IMessage> {
*
* @property {object} sharedWithDevices
* devices with which we have shared the session key
* userId -> {deviceId -> msgindex}
* userId -> {deviceId -> SharedWithData}
*/
class OutboundSessionInfo {
public useCount = 0;
public creationTime: number;
public sharedWithDevices: Record<string, Record<string, number>> = {};
public sharedWithDevices: Record<string, Record<string, SharedWithData>> = {};
public blockedDevicesNotified: Record<string, Record<string, boolean>> = {};

constructor(public readonly sessionId: string, public readonly sharedHistory = false) {
Expand Down Expand Up @@ -150,11 +157,11 @@ class OutboundSessionInfo {
return false;
}

public markSharedWithDevice(userId: string, deviceId: string, chainIndex: number): void {
public markSharedWithDevice(userId: string, deviceId: string, deviceKey: string, chainIndex: number): void {
if (!this.sharedWithDevices[userId]) {
this.sharedWithDevices[userId] = {};
}
this.sharedWithDevices[userId][deviceId] = chainIndex;
this.sharedWithDevices[userId][deviceId] = { deviceKey, messageIndex: chainIndex };
}

public markNotifiedBlockedDevice(userId: string, deviceId: string): void {
Expand Down Expand Up @@ -572,6 +579,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
payload: IPayload,
): Promise<void> {
const contentMap = {};
const deviceInfoByDeviceId = new Map<string, DeviceInfo>();

const promises = [];
for (let i = 0; i < userDeviceMap.length; i++) {
Expand All @@ -584,6 +592,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
const userId = val.userId;
const deviceInfo = val.deviceInfo;
const deviceId = deviceInfo.deviceId;
deviceInfoByDeviceId.set(deviceId, deviceInfo);

if (!contentMap[userId]) {
contentMap[userId] = {};
Expand Down Expand Up @@ -636,7 +645,10 @@ class MegolmEncryption extends EncryptionAlgorithm {
for (const userId of Object.keys(contentMap)) {
for (const deviceId of Object.keys(contentMap[userId])) {
session.markSharedWithDevice(
userId, deviceId, chainIndex,
userId,
deviceId,
deviceInfoByDeviceId.get(deviceId).getIdentityKey(),
chainIndex,
);
}
}
Expand Down Expand Up @@ -719,19 +731,27 @@ class MegolmEncryption extends EncryptionAlgorithm {
logger.debug(`megolm session ${sessionId} never shared with user ${userId}`);
return;
}
const sentChainIndex = obSessionInfo.sharedWithDevices[userId][device.deviceId];
if (sentChainIndex === undefined) {
const sessionSharedData = obSessionInfo.sharedWithDevices[userId][device.deviceId];
if (sessionSharedData === undefined) {
logger.debug(
"megolm session ID " + sessionId + " never shared with device " +
userId + ":" + device.deviceId,
);
return;
}

if (sessionSharedData.deviceKey !== device.getIdentityKey()) {
logger.warn(
`Session has been shared with device ${device.deviceId} but with identity ` +
`key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`,
);
return;
}

// get the key from the inbound session: the outbound one will already
// have been ratcheted to the next chain index.
const key = await this.olmDevice.getInboundGroupSessionKey(
this.roomId, senderKey, sessionId, sentChainIndex,
this.roomId, senderKey, sessionId, sessionSharedData.messageIndex,
);

if (!key) {
Expand Down Expand Up @@ -882,7 +902,7 @@ class MegolmEncryption extends EncryptionAlgorithm {
const deviceId = deviceInfo.deviceId;

session.markSharedWithDevice(
userId, deviceId, key.chain_index,
userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index,
);
}

Expand Down

0 comments on commit 894c248

Please sign in to comment.