mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-22 06:30:25 +00:00
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
/*
|
|
Copyright 2023, 2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { BaseKeyProvider, createKeyMaterialFromBuffer, importKey, KeyProviderEvent } from "livekit-client";
|
|
import { logger } from "matrix-js-sdk/lib/logger";
|
|
import {
|
|
type MatrixRTCSession,
|
|
MatrixRTCSessionEvent,
|
|
} from "matrix-js-sdk/lib/matrixrtc";
|
|
|
|
export class MatrixKeyProvider extends BaseKeyProvider {
|
|
private rtcSession?: MatrixRTCSession;
|
|
|
|
private readonly onKeyRatchetComplete: (material: ArrayBuffer, keyIndex?: number) => void;
|
|
|
|
public constructor() {
|
|
super({ ratchetWindowSize: 10, keyringSize: 10 });
|
|
|
|
this.onKeyRatchetComplete = (material: ArrayBuffer, keyIndex?: number): void => {
|
|
logger.debug(`key ratcheted event received for index `, keyIndex );
|
|
this.rtcSession?.onOwnKeyRatcheted(material, keyIndex).catch((e) => {
|
|
logger.error(
|
|
`Failed to ratchet key for livekit room=${this.rtcSession?.room.roomId} keyIndex=${keyIndex}`,
|
|
e,
|
|
);
|
|
});
|
|
};
|
|
|
|
this.on(KeyProviderEvent.RatchetRequestCompleted, this.onKeyRatchetComplete);
|
|
}
|
|
|
|
public setRTCSession(rtcSession: MatrixRTCSession): void {
|
|
if (this.rtcSession) {
|
|
this.rtcSession.off(
|
|
MatrixRTCSessionEvent.EncryptionKeyChanged,
|
|
this.onEncryptionKeyChanged,
|
|
);
|
|
this.rtcSession.off(
|
|
MatrixRTCSessionEvent.EncryptionKeyQueryRatchetStep,
|
|
this.doRatchetKey,
|
|
);
|
|
|
|
}
|
|
|
|
this.rtcSession = rtcSession;
|
|
|
|
this.rtcSession.on(
|
|
MatrixRTCSessionEvent.EncryptionKeyChanged,
|
|
this.onEncryptionKeyChanged,
|
|
);
|
|
|
|
this.rtcSession.on(
|
|
MatrixRTCSessionEvent.EncryptionKeyQueryRatchetStep,
|
|
this.doRatchetKey,
|
|
);
|
|
|
|
|
|
// The new session could be aware of keys of which the old session wasn't,
|
|
// so emit key changed events
|
|
this.rtcSession.reemitEncryptionKeys();
|
|
}
|
|
|
|
private doRatchetKey = (participantId:string, keyIndex:number): void => {
|
|
this.ratchetKey(participantId, keyIndex);
|
|
}
|
|
|
|
private onEncryptionKeyChanged = (
|
|
encryptionKey: Uint8Array,
|
|
encryptionKeyIndex: number,
|
|
participantId: string,
|
|
): void => {
|
|
importKey(encryptionKey, "HKDF", 'derive').then(
|
|
(keyMaterial) => {
|
|
this.onSetEncryptionKey(keyMaterial, participantId, encryptionKeyIndex);
|
|
|
|
logger.debug(
|
|
`Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`,
|
|
);
|
|
},
|
|
(e) => {
|
|
logger.error(
|
|
`Failed to create key material from buffer for livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`,
|
|
e,
|
|
);
|
|
},
|
|
);
|
|
};
|
|
}
|