Skip to content

Commit 3c0d818

Browse files
authored
Add option to enable to-device-encryption (#3167)
* enable to-device-encryption * add logging for key provider * make rooms encrypted * add dev setting to choose to-device or room encryption * add indicator when to-device is used.
1 parent 1702b15 commit 3c0d818

File tree

10 files changed

+74
-42
lines changed

10 files changed

+74
-42
lines changed

locales/en/app.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@
7373
"show_connection_stats": "Show connection statistics",
7474
"show_non_member_tiles": "Show tiles for non-member media",
7575
"url_params": "URL parameters",
76-
"use_new_membership_manager": "Use the new implementation of the call MembershipManager"
76+
"use_new_membership_manager": "Use the new implementation of the call MembershipManager",
77+
"use_to_device_key_transport": "Use to device messages to distribute keys for matrixRTC media"
7778
},
7879
"disconnected_banner": "Connectivity to the server has been lost.",
7980
"error": {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"livekit-client": "2.11.1",
101101
"lodash-es": "^4.17.21",
102102
"loglevel": "^1.9.1",
103-
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#8395919f0fd1af7cab1e793d736f2cdf18ef7686",
103+
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#e3a3a52f2a56cb5cc52b57b36e9a915faed0b5db",
104104
"matrix-widget-api": "1.11.0",
105105
"normalize.css": "^8.0.1",
106106
"observable-hooks": "^4.2.3",

src/livekit/useLiveKit.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,14 @@ export function useLiveKit(
4949
if (e2eeSystem.kind === E2eeType.NONE) return undefined;
5050

5151
if (e2eeSystem.kind === E2eeType.PER_PARTICIPANT) {
52+
logger.info("Created MatrixKeyProvider (per participant)");
5253
return {
5354
keyProvider: new MatrixKeyProvider(),
5455
worker: new E2EEWorker(),
5556
};
5657
} else if (e2eeSystem.kind === E2eeType.SHARED_KEY && e2eeSystem.secret) {
58+
logger.info("Created ExternalE2EEKeyProvider (shared key)");
59+
5760
return {
5861
keyProvider: new ExternalE2EEKeyProvider(),
5962
worker: new E2EEWorker(),

src/room/GroupCallView.tsx

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import {
6262
} from "../utils/errors.ts";
6363
import { GroupCallErrorBoundary } from "./GroupCallErrorBoundary.tsx";
6464
import {
65+
useExperimentalToDeviceTransportSetting,
6566
useNewMembershipManagerSetting as useNewMembershipManagerSetting,
6667
useSetting,
6768
} from "../settings/settings";
@@ -151,6 +152,9 @@ export const GroupCallView: FC<Props> = ({
151152
const { perParticipantE2EE, returnToLobby } = useUrlParams();
152153
const e2eeSystem = useRoomEncryptionSystem(room.roomId);
153154
const [useNewMembershipManager] = useSetting(useNewMembershipManagerSetting);
155+
const [useExperimentalToDeviceTransport] = useSetting(
156+
useExperimentalToDeviceTransportSetting,
157+
);
154158

155159
usePageTitle(roomName);
156160

@@ -178,16 +182,13 @@ export const GroupCallView: FC<Props> = ({
178182
const latestMuteStates = useLatest(muteStates);
179183

180184
const enterRTCSessionOrError = useCallback(
181-
async (
182-
rtcSession: MatrixRTCSession,
183-
perParticipantE2EE: boolean,
184-
newMembershipManager: boolean,
185-
): Promise<void> => {
185+
async (rtcSession: MatrixRTCSession): Promise<void> => {
186186
try {
187187
await enterRTCSession(
188188
rtcSession,
189189
perParticipantE2EE,
190-
newMembershipManager,
190+
useNewMembershipManager,
191+
useExperimentalToDeviceTransport,
191192
);
192193
} catch (e) {
193194
if (e instanceof ElementCallError) {
@@ -201,7 +202,11 @@ export const GroupCallView: FC<Props> = ({
201202
}
202203
}
203204
},
204-
[setExternalError],
205+
[
206+
perParticipantE2EE,
207+
useExperimentalToDeviceTransport,
208+
useNewMembershipManager,
209+
],
205210
);
206211

207212
useEffect(() => {
@@ -253,11 +258,7 @@ export const GroupCallView: FC<Props> = ({
253258
await defaultDeviceSetup(
254259
ev.detail.data as unknown as JoinCallData,
255260
);
256-
await enterRTCSessionOrError(
257-
rtcSession,
258-
perParticipantE2EE,
259-
useNewMembershipManager,
260-
);
261+
await enterRTCSessionOrError(rtcSession);
261262
widget.api.transport.reply(ev.detail, {});
262263
})().catch((e) => {
263264
logger.error("Error joining RTC session", e);
@@ -270,21 +271,13 @@ export const GroupCallView: FC<Props> = ({
270271
} else {
271272
// No lobby and no preload: we enter the rtc session right away
272273
(async (): Promise<void> => {
273-
await enterRTCSessionOrError(
274-
rtcSession,
275-
perParticipantE2EE,
276-
useNewMembershipManager,
277-
);
274+
await enterRTCSessionOrError(rtcSession);
278275
})().catch((e) => {
279276
logger.error("Error joining RTC session", e);
280277
});
281278
}
282279
} else {
283-
void enterRTCSessionOrError(
284-
rtcSession,
285-
perParticipantE2EE,
286-
useNewMembershipManager,
287-
);
280+
void enterRTCSessionOrError(rtcSession);
288281
}
289282
}
290283
}, [
@@ -407,13 +400,7 @@ export const GroupCallView: FC<Props> = ({
407400
client={client}
408401
matrixInfo={matrixInfo}
409402
muteStates={muteStates}
410-
onEnter={() =>
411-
void enterRTCSessionOrError(
412-
rtcSession,
413-
perParticipantE2EE,
414-
useNewMembershipManager,
415-
)
416-
}
403+
onEnter={() => void enterRTCSessionOrError(rtcSession)}
417404
confineToRoom={confineToRoom}
418405
hideHeader={hideHeader}
419406
participantCount={participantCount}
@@ -491,11 +478,7 @@ export const GroupCallView: FC<Props> = ({
491478
recoveryActionHandler={(action) => {
492479
if (action == "reconnect") {
493480
setLeft(false);
494-
enterRTCSessionOrError(
495-
rtcSession,
496-
perParticipantE2EE,
497-
useNewMembershipManager,
498-
).catch((e) => {
481+
enterRTCSessionOrError(rtcSession).catch((e) => {
499482
logger.error("Error re-entering RTC session", e);
500483
});
501484
}

src/room/InCallView.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
RoomContext,
1111
useLocalParticipant,
1212
} from "@livekit/components-react";
13+
import { Text } from "@vector-im/compound-web";
1314
import { ConnectionState, type Room } from "livekit-client";
1415
import { type MatrixClient } from "matrix-js-sdk";
1516
import {
@@ -94,11 +95,11 @@ import { ReactionsOverlay } from "./ReactionsOverlay";
9495
import { CallEventAudioRenderer } from "./CallEventAudioRenderer";
9596
import {
9697
debugTileLayout as debugTileLayoutSetting,
98+
useExperimentalToDeviceTransportSetting,
9799
useSetting,
98100
} from "../settings/settings";
99101
import { ReactionsReader } from "../reactions/ReactionsReader";
100102
import { ConnectionLostError } from "../utils/errors.ts";
101-
102103
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
103104

104105
const maxTapDurationMs = 400;
@@ -216,6 +217,10 @@ export const InCallView: FC<InCallViewProps> = ({
216217
room: livekitRoom,
217218
});
218219

220+
const [toDeviceEncryption] = useSetting(
221+
useExperimentalToDeviceTransportSetting,
222+
);
223+
219224
const toggleMicrophone = useCallback(
220225
() => muteStates.audio.setEnabled?.((e) => !e),
221226
[muteStates],
@@ -662,6 +667,18 @@ export const InCallView: FC<InCallViewProps> = ({
662667
</RightNav>
663668
</Header>
664669
))}
670+
{
671+
// TODO: remove this once we remove the developer flag
672+
// and find a better way to device what key transport to use.
673+
toDeviceEncryption && (
674+
<Text
675+
style={{ height: 0, zIndex: 1, alignSelf: "center", margin: 0 }}
676+
size="sm"
677+
>
678+
using to Device key transport
679+
</Text>
680+
)
681+
}
665682
<RoomAudioRenderer />
666683
{renderContent()}
667684
<CallEventAudioRenderer vm={vm} />

src/rtcSessionHelpers.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ test("It joins the correct Session", async () => {
112112
manageMediaKeys: false,
113113
useLegacyMemberEvents: false,
114114
useNewMembershipManager: true,
115+
useExperimentalToDeviceTransport: false,
115116
},
116117
);
117118
});

src/rtcSessionHelpers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export async function enterRTCSession(
9898
rtcSession: MatrixRTCSession,
9999
encryptMedia: boolean,
100100
useNewMembershipManager = true,
101+
useExperimentalToDeviceTransport = false,
101102
): Promise<void> {
102103
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
103104
PosthogAnalytics.instance.eventCallStarted.track(rtcSession.room.roomId);
@@ -125,6 +126,7 @@ export async function enterRTCSession(
125126
membershipKeepAlivePeriod:
126127
matrixRtcSessionConfig?.membership_keep_alive_period,
127128
makeKeyDelay: matrixRtcSessionConfig?.key_rotation_on_leave_delay,
129+
useExperimentalToDeviceTransport,
128130
},
129131
);
130132
if (widget) {

src/settings/DeveloperSettingsTab.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
showNonMemberTiles as showNonMemberTilesSetting,
1717
showConnectionStats as showConnectionStatsSetting,
1818
useNewMembershipManagerSetting,
19+
useExperimentalToDeviceTransportSetting,
1920
} from "./settings";
2021
import type { MatrixClient } from "matrix-js-sdk";
2122
import type { Room as LivekitRoom } from "livekit-client";
@@ -44,6 +45,10 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRoom }) => {
4445
useNewMembershipManagerSetting,
4546
);
4647

48+
const [
49+
useExperimentalToDeviceTransport,
50+
setUseExperimentalToDeviceTransport,
51+
] = useSetting(useExperimentalToDeviceTransportSetting);
4752
const urlParams = useUrlParams();
4853

4954
const sfuUrl = useMemo((): URL | null => {
@@ -156,6 +161,20 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRoom }) => {
156161
)}
157162
/>
158163
</FieldRow>
164+
<FieldRow>
165+
<InputField
166+
id="useToDeviceKeyTransport"
167+
type="checkbox"
168+
label={t("developer_mode.use_to_device_key_transport")}
169+
checked={!!useExperimentalToDeviceTransport}
170+
onChange={useCallback(
171+
(event: ChangeEvent<HTMLInputElement>): void => {
172+
setUseExperimentalToDeviceTransport(event.target.checked);
173+
},
174+
[setUseExperimentalToDeviceTransport],
175+
)}
176+
/>
177+
</FieldRow>
159178
{livekitRoom ? (
160179
<>
161180
<p>

src/settings/settings.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,10 @@ export const useNewMembershipManagerSetting = new Setting<boolean>(
117117
"new-membership-manager",
118118
true,
119119
);
120+
121+
export const useExperimentalToDeviceTransportSetting = new Setting<boolean>(
122+
"experimental-to-device-transport",
123+
false,
124+
);
125+
120126
export const alwaysShowSelf = new Setting<boolean>("always-show-self", true);

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6913,7 +6913,7 @@ __metadata:
69136913
livekit-client: "npm:2.11.1"
69146914
lodash-es: "npm:^4.17.21"
69156915
loglevel: "npm:^1.9.1"
6916-
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#8395919f0fd1af7cab1e793d736f2cdf18ef7686"
6916+
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#e3a3a52f2a56cb5cc52b57b36e9a915faed0b5db"
69176917
matrix-widget-api: "npm:1.11.0"
69186918
normalize.css: "npm:^8.0.1"
69196919
observable-hooks: "npm:^4.2.3"
@@ -9504,9 +9504,9 @@ __metadata:
95049504
languageName: node
95059505
linkType: hard
95069506

9507-
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#8395919f0fd1af7cab1e793d736f2cdf18ef7686":
9508-
version: 37.1.0
9509-
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=8395919f0fd1af7cab1e793d736f2cdf18ef7686"
9507+
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#e3a3a52f2a56cb5cc52b57b36e9a915faed0b5db":
9508+
version: 37.3.0
9509+
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=e3a3a52f2a56cb5cc52b57b36e9a915faed0b5db"
95109510
dependencies:
95119511
"@babel/runtime": "npm:^7.12.5"
95129512
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^14.0.1"
@@ -9523,7 +9523,7 @@ __metadata:
95239523
sdp-transform: "npm:^2.14.1"
95249524
unhomoglyph: "npm:^1.0.6"
95259525
uuid: "npm:11"
9526-
checksum: 10c0/a0eb3be822e07cfe53965f6ca4f0c3cdf8ba3728d03a15f2322a463a7543206583e0c2f34d6b6d45089ce36eec60d77d9e90eb0635d3c65a343f77728908fe57
9526+
checksum: 10c0/1baf50f93576a6fdf46d76c7a84cf43adeb0b04e692165f749f15c56e8e3fd0f5f354a1702b9f9de1688cebbdee176f7056b71e8a526ef9b0fbbe23405c2aee2
95279527
languageName: node
95289528
linkType: hard
95299529

0 commit comments

Comments
 (0)