Skip to content

Commit 3386c66

Browse files
authored
Fix MatrixRTC sender key wrapping (#4441)
1 parent da04482 commit 3386c66

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

spec/unit/matrixrtc/MatrixRTCSession.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,48 @@ describe("MatrixRTCSession", () => {
10101010
}
10111011
});
10121012

1013+
it("Wraps key index around to 0 when it reaches the maximum", async () => {
1014+
// this should give us keys with index [0...255, 0, 1]
1015+
const membersToTest = 258;
1016+
const members: CallMembershipData[] = [];
1017+
for (let i = 0; i < membersToTest; i++) {
1018+
members.push(Object.assign({}, membershipTemplate, { device_id: `DEVICE${i}` }));
1019+
}
1020+
jest.useFakeTimers();
1021+
try {
1022+
// start with a single member
1023+
const mockRoom = makeMockRoom(members.slice(0, 1));
1024+
1025+
for (let i = 0; i < membersToTest; i++) {
1026+
const keysSentPromise = new Promise<EncryptionKeysEventContent>((resolve) => {
1027+
sendEventMock.mockImplementation((_roomId, _evType, payload) => resolve(payload));
1028+
});
1029+
1030+
if (i === 0) {
1031+
// if first time around then set up the session
1032+
sess = MatrixRTCSession.roomSessionForRoom(client, mockRoom);
1033+
sess.joinRoomSession([mockFocus], mockFocus, { manageMediaKeys: true });
1034+
} else {
1035+
// otherwise update the state
1036+
mockRoom.getLiveTimeline().getState = jest
1037+
.fn()
1038+
.mockReturnValue(makeMockRoomState(members.slice(0, i + 1), mockRoom.roomId));
1039+
}
1040+
1041+
sess!.onMembershipUpdate();
1042+
1043+
// advance time to avoid key throttling
1044+
jest.advanceTimersByTime(10000);
1045+
1046+
const keysPayload = await keysSentPromise;
1047+
expect(keysPayload.keys).toHaveLength(1);
1048+
expect(keysPayload.keys[0].index).toEqual(i % 256);
1049+
}
1050+
} finally {
1051+
jest.useRealTimers();
1052+
}
1053+
});
1054+
10131055
it("Doesn't re-send key immediately", async () => {
10141056
const realSetTimeout = setTimeout;
10151057
jest.useFakeTimers();

src/matrixrtc/MatrixRTCSession.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,12 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M
448448
}
449449

450450
private getNewEncryptionKeyIndex(): number {
451-
const userId = this.client.getUserId();
452-
const deviceId = this.client.getDeviceId();
453-
454-
if (!userId) throw new Error("No userId!");
455-
if (!deviceId) throw new Error("No deviceId!");
451+
if (this.currentEncryptionKeyIndex === -1) {
452+
return 0;
453+
}
456454

457-
return (this.getKeysForParticipantInternal(userId, deviceId)?.length ?? 0) % 16;
455+
// maximum key index is 255
456+
return (this.currentEncryptionKeyIndex + 1) % 256;
458457
}
459458

460459
/**

0 commit comments

Comments
 (0)