Skip to content

Ecryption key ratcheting dev tools #3214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: livekit
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/e2ee/matrixKeyProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/

import { BaseKeyProvider, createKeyMaterialFromBuffer } from "livekit-client";
import {
BaseKeyProvider,
createKeyMaterialFromBuffer,
KeyProviderEvent,
} from "livekit-client";
import { logger } from "matrix-js-sdk/lib/logger";
import {
type MatrixRTCSession,
Expand All @@ -16,7 +20,11 @@ export class MatrixKeyProvider extends BaseKeyProvider {
private rtcSession?: MatrixRTCSession;

public constructor() {
super({ ratchetWindowSize: 0, keyringSize: 256 });
// ratchetWindowSize the amount of ratchets we try consecutively before
// throwing an error log. After those attempts we will still try more retry batches.
// So there can be more than 10 ratchets in total.
super({ ratchetWindowSize: 10, keyringSize: 256 });
this.on(KeyProviderEvent.KeyRatcheted, this.onKeyRatcheted);
}

public setRTCSession(rtcSession: MatrixRTCSession): void {
Expand Down Expand Up @@ -60,4 +68,12 @@ export class MatrixKeyProvider extends BaseKeyProvider {
},
);
};

public onKeyRatcheted = (material: CryptoKey, keyIndex?: number): void => {
logger.debug(
`Key ratcheted event received for livekit room=${this.rtcSession?.room.roomId} keyIndex=${keyIndex}`,
`material:`,
material,
);
};
}
11 changes: 10 additions & 1 deletion src/livekit/useLiveKit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
type RoomOptions,
Track,
} from "livekit-client";
import { useEffect, useMemo, useRef } from "react";
import { useCallback, useEffect, useMemo, useRef } from "react";
import E2EEWorker from "livekit-client/e2ee-worker?worker";
import { logger } from "matrix-js-sdk/lib/logger";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
Expand All @@ -37,6 +37,7 @@ import { type EncryptionSystem } from "../e2ee/sharedKeyManagement";
interface UseLivekitResult {
livekitRoom?: Room;
connState: ECConnectionState;
doKeyRatchet: () => void;
}

export function useLiveKit(
Expand Down Expand Up @@ -331,8 +332,16 @@ export function useLiveKit(
}
}, [room, devices, connectionState]);

const doKeyRatchet = useCallback(() => {
// not providing a key index will default to the current key
e2eeOptions?.keyProvider.ratchetKey(
room.localParticipant.identity,
undefined,
);
}, [e2eeOptions?.keyProvider, room.localParticipant.identity]);
return {
connState: connectionState,
livekitRoom: room,
doKeyRatchet,
};
}
6 changes: 5 additions & 1 deletion src/room/InCallView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export interface ActiveCallProps

export const ActiveCall: FC<ActiveCallProps> = (props) => {
const sfuConfig = useOpenIDSFU(props.client, props.rtcSession);
const { livekitRoom, connState } = useLiveKit(
const { livekitRoom, connState, doKeyRatchet } = useLiveKit(
props.rtcSession,
props.muteStates,
sfuConfig,
Expand Down Expand Up @@ -164,6 +164,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
vm={vm}
livekitRoom={livekitRoom}
connState={connState}
doKeyRatchet={doKeyRatchet}
/>
</ReactionsSenderProvider>
</RoomContext.Provider>
Expand All @@ -184,6 +185,7 @@ export interface InCallViewProps {
otelGroupCallMembership?: OTelGroupCallMembership;
connState: ECConnectionState;
onShareClick: (() => void) | null;
doKeyRatchet?: () => void;
}

export const InCallView: FC<InCallViewProps> = ({
Expand All @@ -198,6 +200,7 @@ export const InCallView: FC<InCallViewProps> = ({
hideHeader,
connState,
onShareClick,
doKeyRatchet,
}) => {
const { supportsReactions, sendReaction, toggleRaisedHand } =
useReactionsSender();
Expand Down Expand Up @@ -710,6 +713,7 @@ export const InCallView: FC<InCallViewProps> = ({
tab={settingsTab}
onTabChange={setSettingsTab}
livekitRoom={livekitRoom}
doKeyRatchet={doKeyRatchet}
/>
</>
)}
Expand Down
16 changes: 14 additions & 2 deletions src/settings/DeveloperSettingsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Please see LICENSE in the repository root for full details.

import { type ChangeEvent, type FC, useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "@vector-im/compound-web";

import { FieldRow, InputField } from "../input/Input";
import {
Expand All @@ -25,9 +26,14 @@ import { useUrlParams } from "../UrlParams";
interface Props {
client: MatrixClient;
livekitRoom?: LivekitRoom;
doKeyRatchet?: () => void;
}

export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRoom }) => {
export const DeveloperSettingsTab: FC<Props> = ({
client,
livekitRoom,
doKeyRatchet,
}) => {
const { t } = useTranslation();
const [duplicateTiles, setDuplicateTiles] = useSetting(duplicateTilesSetting);
const [debugTileLayout, setDebugTileLayout] = useSetting(
Expand Down Expand Up @@ -88,7 +94,13 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRoom }) => {
{t("developer_mode.device_id", {
id: client.getDeviceId() || "unknown",
})}
</p>
</p>{" "}
<FieldRow>
<Button size="sm" onClick={() => doKeyRatchet?.()}>
{" "}
Ratchet current key{" "}
</Button>{" "}
</FieldRow>
<FieldRow>
<InputField
id="duplicateTiles"
Expand Down
10 changes: 9 additions & 1 deletion src/settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface Props {
client: MatrixClient;
roomId?: string;
livekitRoom?: LivekitRoom;
doKeyRatchet?: () => void;
}

export const defaultSettingsTab: SettingsTab = "audio";
Expand All @@ -61,6 +62,7 @@ export const SettingsModal: FC<Props> = ({
client,
roomId,
livekitRoom,
doKeyRatchet,
}) => {
const { t } = useTranslation();

Expand Down Expand Up @@ -144,7 +146,13 @@ export const SettingsModal: FC<Props> = ({
const developerTab: Tab<SettingsTab> = {
key: "developer",
name: t("settings.developer_tab_title"),
content: <DeveloperSettingsTab client={client} livekitRoom={livekitRoom} />,
content: (
<DeveloperSettingsTab
client={client}
livekitRoom={livekitRoom}
doKeyRatchet={doKeyRatchet}
/>
),
};

const tabs = [audioTab, videoTab];
Expand Down