UNPKG

matrix-js-sdk

Version:
110 lines 5.71 kB
import { type CallMembershipIdentityParts, type IEncryptionManager } from "./EncryptionManager.ts"; import { type EncryptionConfig, type MembershipConfig } from "./MatrixRTCSession.ts"; import type { CallMembership } from "./CallMembership.ts"; import { type IKeyTransport, type KeyTransportEventListener } from "./IKeyTransport.ts"; import { type Logger } from "../logger.ts"; import { type EncryptionKeyMapKey } from "./types.ts"; /** * RTCEncryptionManager is used to manage the encryption keys for a call. * * It is responsible for distributing the keys to the other participants and rotating the keys if needed. * * This manager when used with to-device transport will share the existing key only to new joiners, and rotate * if there is a leaver. * * XXX In the future we want to distribute a ratcheted key not the current one for new joiners. */ export declare class RTCEncryptionManager implements IEncryptionManager { private readonly ownMembership; private getMemberships; private transport; private onEncryptionKeysChanged; private manageMediaKeys; private useHashedRtcBackendIdentity; private ownRtcBackendIdentityCache; /** * Store the key rings for each participant. * The encryption manager stores the keys because the application layer might not be ready yet to handle the keys. * The keys are stored and can be retrieved later when the application layer is ready {@link RTCEncryptionManager#getEncryptionKeys}. */ private readonly participantKeyRings; private outboundSession; /** * Ensures that there is only one distribute operation at a time for that call. */ private currentKeyDistributionPromise; /** * The time to wait before using the outbound session after it has been distributed. * This is to ensure that the key is delivered to all participants before it is used. * When creating the first key, this is set to 0 so that the key can be used immediately. */ private useKeyDelay; /** * We want to avoid rolling out a new outbound key when the previous one was created less than `keyRotationGracePeriodMs` milliseconds ago. * This is to avoid expensive key rotations when users quickly join the call in a row. * * This must be higher than `useKeyDelay` to have an effect. * If it is lower, the current key will always be older than the grace period. * @private */ private keyRotationGracePeriodMs; /** * If a new key distribution is being requested while one is going on, we will set this flag to true. * This will ensure that a new round is started after the current one. * @private */ private needToEnsureKeyAgain; /** * There is a possibility that keys arrive in the wrong order. * For example, after a quick join/leave/join, there will be 2 keys of index 0 distributed, and * if they are received in the wrong order, the stream won't be decryptable. * For that reason we keep a small buffer of keys for a limited time to disambiguate. * @private */ private keyBuffer; private logger; private readonly rtcIdentityProvider; /** * * @param ownMembership - our own membership info * @param getMemberships - function to get current memberships * @param transport - key transport (room or to-device) * @param statistics - statistics collector * @param onEncryptionKeysChanged - callback to notify the media layer of new keys * @param parentLogger - optional parent logger * @param rtcBackendIdProvider - A function to compute the rtc backend identity, exposed for testing purposes */ constructor(ownMembership: CallMembershipIdentityParts, getMemberships: () => CallMembership[], transport: IKeyTransport, onEncryptionKeysChanged: (keyBin: Uint8Array<ArrayBuffer>, encryptionKeyIndex: number, membership: CallMembershipIdentityParts, rtcBackendIdentity: string) => void, parentLogger?: Logger, rtcBackendIdProvider?: (userId: string, deviceId: string, memberId: string) => Promise<string>); private getOwnRtcBackendIdentity; getEncryptionKeys(): ReadonlyMap<EncryptionKeyMapKey, ReadonlyArray<{ key: Uint8Array<ArrayBuffer>; keyIndex: number; membership: CallMembershipIdentityParts; rtcBackendIdentity: string; }>>; private keysWithoutMatchingRTCMembership; private checkKeysWithoutMatchingRTCMembership; private addKeyToParticipant; private addKeyToParticipantWithBackendIdentity; join(joinConfig: (EncryptionConfig & MembershipConfig) | undefined): void; leave(): void; /** * Will ensure that a new key is distributed and used to encrypt our media. * If there is already a key distribution in progress, it will schedule a new distribution round just after the current one is completed. * If this function is called repeatedly while a distribution is in progress, * the calls will be coalesced to a single new distribution (that will start just after the current one has completed). */ private ensureKeyDistribution; onNewKeyReceived: KeyTransportEventListener; /** * Called when the ownMembership of the call changes. * This encryption manager is very basic, it will rotate the key everytime this is called. * @param oldMemberships - This parameter is not used here, but it is kept for compatibility with the interface. */ onMembershipsUpdate(oldMemberships?: CallMembership[]): void; private rolloutOutboundKey; private createNewOutboundSession; private nextKeyIndex; private generateRandomKey; } //# sourceMappingURL=RTCEncryptionManager.d.ts.map