matrix-js-sdk
Version:
Matrix Client-Server SDK for Javascript
110 lines • 5.71 kB
TypeScript
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