UNPKG

matrix-js-sdk

Version:
538 lines 22.7 kB
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto"; import type { IDeviceLists, IToDeviceEvent } from "../sync-accumulator"; import type { IEncryptedEventInfo } from "../crypto/api"; import { MatrixEvent } from "../models/event"; import { Room } from "../models/room"; import { RoomMember } from "../models/room-member"; import { BackupDecryptor, CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend"; import { Logger } from "../logger"; import { IHttpOpts, MatrixHttpApi } from "../http-api"; import { BackupTrustInfo, BootstrapCrossSigningOpts, CreateSecretStorageOpts, CrossSigningKey, CrossSigningStatus, CryptoCallbacks, DeviceVerificationStatus, EventEncryptionInfo, GeneratedSecretStorageKey, ImportRoomKeysOpts, KeyBackupCheck, KeyBackupInfo, OwnDeviceKeys, UserVerificationStatus, VerificationRequest } from "../crypto-api"; import { DeviceMap } from "../models/device"; import { ServerSideSecretStorage } from "../secret-storage"; import { CryptoEvent } from "../crypto"; import { TypedEventEmitter } from "../models/typed-event-emitter"; import { RustBackupCryptoEventMap, RustBackupCryptoEvents } from "./backup"; /** * An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto. * * @internal */ export declare class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEventMap> implements CryptoBackend { private readonly logger; /** The `OlmMachine` from the underlying rust crypto sdk. */ private readonly olmMachine; /** * Low-level HTTP interface: used to make outgoing requests required by the rust SDK. * * We expect it to set the access token, etc. */ private readonly http; /** The local user's User ID. */ private readonly userId; /** Interface to server-side secret storage */ private readonly secretStorage; /** Crypto callbacks provided by the application */ private readonly cryptoCallbacks; private _trustCrossSignedDevices; /** whether {@link stop} has been called */ private stopped; /** mapping of roomId → encryptor class */ private roomEncryptors; private eventDecryptor; private keyClaimManager; private outgoingRequestProcessor; private crossSigningIdentity; private readonly backupManager; private outgoingRequestsManager; private readonly perSessionBackupDownloader; private readonly dehydratedDeviceManager; private readonly reemitter; constructor(logger: Logger, /** The `OlmMachine` from the underlying rust crypto sdk. */ olmMachine: RustSdkCryptoJs.OlmMachine, /** * Low-level HTTP interface: used to make outgoing requests required by the rust SDK. * * We expect it to set the access token, etc. */ http: MatrixHttpApi<IHttpOpts & { onlyData: true; }>, /** The local user's User ID. */ userId: string, /** The local user's Device ID. */ _deviceId: string, /** Interface to server-side secret storage */ secretStorage: ServerSideSecretStorage, /** Crypto callbacks provided by the application */ cryptoCallbacks: CryptoCallbacks); /** * Return the OlmMachine only if {@link RustCrypto#stop} has not been called. * * This allows us to better handle race conditions where the client is stopped before or during a crypto API call. * * @throws ClientStoppedError if {@link RustCrypto#stop} has been called. */ private getOlmMachineOrThrow; set globalErrorOnUnknownDevices(_v: boolean); get globalErrorOnUnknownDevices(): boolean; stop(): void; encryptEvent(event: MatrixEvent, _room: Room): Promise<void>; decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult>; /** * Implementation of (deprecated) {@link MatrixClient#getEventEncryptionInfo}. * * @param event - event to inspect */ getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo; /** * Implementation of {@link CryptoBackend#checkUserTrust}. * * Stub for backwards compatibility. * */ checkUserTrust(userId: string): UserVerificationStatus; /** * Get the cross signing information for a given user. * * The cross-signing API is currently UNSTABLE and may change without notice. * * @param userId - the user ID to get the cross-signing info for. * * @returns the cross signing information for the user. */ getStoredCrossSigningForUser(userId: string): null; /** * This function is unneeded for the rust-crypto. * The cross signing key import and the device verification are done in {@link CryptoApi#bootstrapCrossSigning} * * The function is stub to keep the compatibility with the old crypto. * More information: https://github.com/vector-im/element-web/issues/25648 * * Implementation of {@link CryptoBackend#checkOwnCrossSigningTrust} */ checkOwnCrossSigningTrust(): Promise<void>; globalBlacklistUnverifiedDevices: boolean; /** * Implementation of {@link CryptoApi#getVersion}. */ getVersion(): string; /** * Implementation of {@link CryptoApi#isEncryptionEnabledInRoom}. */ isEncryptionEnabledInRoom(roomId: string): Promise<boolean>; /** * Implementation of {@link CryptoApi#getOwnDeviceKeys}. */ getOwnDeviceKeys(): Promise<OwnDeviceKeys>; prepareToEncrypt(room: Room): void; forceDiscardSession(roomId: string): Promise<void>; exportRoomKeys(): Promise<IMegolmSessionData[]>; exportRoomKeysAsJson(): Promise<string>; importRoomKeys(keys: IMegolmSessionData[], opts?: ImportRoomKeysOpts): Promise<void>; importRoomKeysAsJson(keys: string, opts?: ImportRoomKeysOpts): Promise<void>; /** * Implementation of {@link CryptoApi.userHasCrossSigningKeys}. */ userHasCrossSigningKeys(userId?: string, downloadUncached?: boolean): Promise<boolean>; /** * Get the device information for the given list of users. * * @param userIds - The users to fetch. * @param downloadUncached - If true, download the device list for users whose device list we are not * currently tracking. Defaults to false, in which case such users will not appear at all in the result map. * * @returns A map `{@link DeviceMap}`. */ getUserDeviceInfo(userIds: string[], downloadUncached?: boolean): Promise<DeviceMap>; /** * Get the device list for the given user from the olm machine * @param userId - Rust SDK UserId */ private getUserDevices; /** * Download the given user keys by calling `/keys/query` request * @param untrackedUsers - download keys of these users */ private downloadDeviceList; /** * Implementation of {@link CryptoApi#getTrustCrossSignedDevices}. */ getTrustCrossSignedDevices(): boolean; /** * Implementation of {@link CryptoApi#setTrustCrossSignedDevices}. */ setTrustCrossSignedDevices(val: boolean): void; /** * Mark the given device as locally verified. * * Implementation of {@link CryptoApi#setDeviceVerified}. */ setDeviceVerified(userId: string, deviceId: string, verified?: boolean): Promise<void>; /** * Blindly cross-sign one of our other devices. * * Implementation of {@link CryptoApi#crossSignDevice}. */ crossSignDevice(deviceId: string): Promise<void>; /** * Implementation of {@link CryptoApi#getDeviceVerificationStatus}. */ getDeviceVerificationStatus(userId: string, deviceId: string): Promise<DeviceVerificationStatus | null>; /** * Implementation of {@link CryptoApi#getUserVerificationStatus}. */ getUserVerificationStatus(userId: string): Promise<UserVerificationStatus>; /** * Implementation of {@link CryptoApi#isCrossSigningReady} */ isCrossSigningReady(): Promise<boolean>; /** * Implementation of {@link CryptoApi#getCrossSigningKeyId} */ getCrossSigningKeyId(type?: CrossSigningKey): Promise<string | null>; /** * Implementation of {@link CryptoApi#boostrapCrossSigning} */ bootstrapCrossSigning(opts: BootstrapCrossSigningOpts): Promise<void>; /** * Implementation of {@link CryptoApi#isSecretStorageReady} */ isSecretStorageReady(): Promise<boolean>; /** * Implementation of {@link CryptoApi#bootstrapSecretStorage} */ bootstrapSecretStorage({ createSecretStorageKey, setupNewSecretStorage, setupNewKeyBackup, }?: CreateSecretStorageOpts): Promise<void>; /** * Add the secretStorage key to the secret storage * - The secret storage key must have the `keyInfo` field filled * - The secret storage key is set as the default key of the secret storage * - Call `cryptoCallbacks.cacheSecretStorageKey` when done * * @param secretStorageKey - The secret storage key to add in the secret storage. */ private addSecretStorageKeyToSecretStorage; /** * Check if a secret storage AES Key is already added in secret storage * * @returns True if an AES key is in the secret storage */ private secretStorageHasAESKey; /** * Implementation of {@link CryptoApi#getCrossSigningStatus} */ getCrossSigningStatus(): Promise<CrossSigningStatus>; /** * Implementation of {@link CryptoApi#createRecoveryKeyFromPassphrase} */ createRecoveryKeyFromPassphrase(password?: string): Promise<GeneratedSecretStorageKey>; /** * Implementation of {@link CryptoApi.getEncryptionInfoForEvent}. */ getEncryptionInfoForEvent(event: MatrixEvent): Promise<EventEncryptionInfo | null>; /** * Returns to-device verification requests that are already in progress for the given user id. * * Implementation of {@link CryptoApi#getVerificationRequestsToDeviceInProgress} * * @param userId - the ID of the user to query * * @returns the VerificationRequests that are in progress */ getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[]; /** * Finds a DM verification request that is already in progress for the given room id * * Implementation of {@link CryptoApi#findVerificationRequestDMInProgress} * * @param roomId - the room to use for verification * @param userId - search the verification request for the given user * * @returns the VerificationRequest that is in progress, if any * */ findVerificationRequestDMInProgress(roomId: string, userId?: string): VerificationRequest | undefined; /** * Implementation of {@link CryptoApi#requestVerificationDM} */ requestVerificationDM(userId: string, roomId: string): Promise<VerificationRequest>; /** * Send the verification content to a room * See https://spec.matrix.org/v1.7/client-server-api/#put_matrixclientv3roomsroomidsendeventtypetxnid * * Prefer to use {@link OutgoingRequestProcessor.makeOutgoingRequest} when dealing with {@link RustSdkCryptoJs.RoomMessageRequest} * * @param roomId - the targeted room * @param verificationEventContent - the request body. * * @returns the event id */ private sendVerificationRequestContent; /** * The verification methods we offer to the other side during an interactive verification. */ private _supportedVerificationMethods; /** * Set the verification methods we offer to the other side during an interactive verification. * * If `undefined`, we will offer all the methods supported by the Rust SDK. */ setSupportedVerificationMethods(methods: string[] | undefined): void; /** * Send a verification request to our other devices. * * If a verification is already in flight, returns it. Otherwise, initiates a new one. * * Implementation of {@link CryptoApi#requestOwnUserVerification}. * * @returns a VerificationRequest when the request has been sent to the other party. */ requestOwnUserVerification(): Promise<VerificationRequest>; /** * Request an interactive verification with the given device. * * If a verification is already in flight, returns it. Otherwise, initiates a new one. * * Implementation of {@link CryptoApi#requestDeviceVerification}. * * @param userId - ID of the owner of the device to verify * @param deviceId - ID of the device to verify * * @returns a VerificationRequest when the request has been sent to the other party. */ requestDeviceVerification(userId: string, deviceId: string): Promise<VerificationRequest>; /** * Fetch the backup decryption key we have saved in our store. * * Implementation of {@link CryptoApi#getSessionBackupPrivateKey}. * * @returns the key, if any, or null */ getSessionBackupPrivateKey(): Promise<Uint8Array | null>; /** * Store the backup decryption key. * * Implementation of {@link CryptoApi#storeSessionBackupPrivateKey}. * * @param key - the backup decryption key * @param version - the backup version for this key. */ storeSessionBackupPrivateKey(key: Uint8Array, version?: string): Promise<void>; /** * Get the current status of key backup. * * Implementation of {@link CryptoApi#getActiveSessionBackupVersion}. */ getActiveSessionBackupVersion(): Promise<string | null>; /** * Determine if a key backup can be trusted. * * Implementation of {@link Crypto.CryptoApi.isKeyBackupTrusted}. */ isKeyBackupTrusted(info: KeyBackupInfo): Promise<BackupTrustInfo>; /** * Force a re-check of the key backup and enable/disable it as appropriate. * * Implementation of {@link Crypto.CryptoApi.checkKeyBackupAndEnable}. */ checkKeyBackupAndEnable(): Promise<KeyBackupCheck | null>; /** * Implementation of {@link CryptoApi#deleteKeyBackupVersion}. */ deleteKeyBackupVersion(version: string): Promise<void>; /** * Implementation of {@link CryptoApi#resetKeyBackup}. */ resetKeyBackup(): Promise<void>; /** * Signs the given object with the current device and current identity (if available). * As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}. * * @param obj - The object to sign */ private signObject; /** * Implementation of {@link CryptoBackend#getBackupDecryptor}. */ getBackupDecryptor(backupInfo: KeyBackupInfo, privKey: ArrayLike<number>): Promise<BackupDecryptor>; /** * Implementation of {@link CryptoBackend#importBackedUpRoomKeys}. */ importBackedUpRoomKeys(keys: IMegolmSessionData[], opts?: ImportRoomKeysOpts): Promise<void>; /** * Implementation of {@link CryptoBackend#isDehydrationSupported}. */ isDehydrationSupported(): Promise<boolean>; /** * Implementation of {@link CryptoBackend#startDehydration}. */ startDehydration(createNewKey?: boolean): Promise<void>; /** * Apply sync changes to the olm machine * @param events - the received to-device messages * @param oneTimeKeysCounts - the received one time key counts * @param unusedFallbackKeys - the received unused fallback keys * @param devices - the received device list updates * @returns A list of preprocessed to-device messages. */ private receiveSyncChanges; /** called by the sync loop to preprocess incoming to-device messages * * @param events - the received to-device messages * @returns A list of preprocessed to-device messages. */ preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]>; /** called by the sync loop to process one time key counts and unused fallback keys * * @param oneTimeKeysCounts - the received one time key counts * @param unusedFallbackKeys - the received unused fallback keys */ processKeyCounts(oneTimeKeysCounts?: Record<string, number>, unusedFallbackKeys?: string[]): Promise<void>; /** called by the sync loop to process the notification that device lists have * been changed. * * @param deviceLists - device_lists field from /sync */ processDeviceLists(deviceLists: IDeviceLists): Promise<void>; /** called by the sync loop on m.room.encrypted events * * @param room - in which the event was received * @param event - encryption event to be processed */ onCryptoEvent(room: Room, event: MatrixEvent): Promise<void>; /** called by the sync loop after processing each sync. * * TODO: figure out something equivalent for sliding sync. * * @param syncState - information on the completed sync. */ onSyncCompleted(syncState: OnSyncCompletedData): void; /** * Handle an incoming m.key.verification request event * * @param sender - the sender of the event * @param content - the content of the event */ private onIncomingKeyVerificationRequest; /** called by the MatrixClient on a room membership event * * @param event - The matrix event which caused this event to fire. * @param member - The member whose RoomMember.membership changed. * @param oldMembership - The previous membership state. Null if it's a new member. */ onRoomMembership(event: MatrixEvent, member: RoomMember, oldMembership?: string): void; /** Callback for OlmMachine.registerRoomKeyUpdatedCallback * * Called by the rust-sdk whenever there is an update to (megolm) room keys. We * check if we have any events waiting for the given keys, and schedule them for * a decryption retry if so. * * @param keys - details of the updated keys */ onRoomKeysUpdated(keys: RustSdkCryptoJs.RoomKeyInfo[]): Promise<void>; private onRoomKeyUpdated; /** * Callback for `OlmMachine.registerUserIdentityUpdatedCallback` * * Called by the rust-sdk whenever there is an update to any user's cross-signing status. We re-check their trust * status and emit a `UserTrustStatusChanged` event, as well as a `KeysChanged` if it is our own identity that changed. * * @param userId - the user with the updated identity */ onUserIdentityUpdated(userId: RustSdkCryptoJs.UserId): Promise<void>; /** * Callback for `OlmMachine.registerDevicesUpdatedCallback` * * Called when users' devices have updated. Emits `WillUpdateDevices` and `DevicesUpdated`. In the JavaScript * crypto backend, these events are called at separate times, with `WillUpdateDevices` being emitted just before * the devices are saved, and `DevicesUpdated` being emitted just after. But the OlmMachine only gives us * one event, so we emit both events here. * * @param userIds - an array of user IDs of users whose devices have updated. */ onDevicesUpdated(userIds: string[]): Promise<void>; /** * Handles secret received from the rust secret inbox. * * The gossipped secrets are received using the `m.secret.send` event type * and are guaranteed to have been received over a 1-to-1 Olm * Session from a verified device. * * The only secret currently handled in this way is `m.megolm_backup.v1`. * * @param name - the secret name * @param value - the secret value */ private handleSecretReceived; /** * Called when a new secret is received in the rust secret inbox. * * Will poll the secret inbox and handle the secrets received. * * @param name - The name of the secret received. */ checkSecrets(name: string): Promise<void>; /** * Handle a live event received via /sync. * See {@link ClientEventHandlerMap#event} * * @param event - live event */ onLiveEventFromSync(event: MatrixEvent): Promise<void>; /** * Handle key verification request. * * @param event - a key validation request event. */ private onKeyVerificationRequest; /** * Returns the cross-signing user identity of the current user. * * Not part of the public crypto-api interface. * Used during migration from legacy js-crypto to update local trust if needed. */ getOwnIdentity(): Promise<RustSdkCryptoJs.OwnUserIdentity | undefined>; } type RustCryptoEvents = CryptoEvent.VerificationRequestReceived | CryptoEvent.UserTrustStatusChanged | CryptoEvent.KeysChanged | CryptoEvent.WillUpdateDevices | CryptoEvent.DevicesUpdated | RustBackupCryptoEvents; type RustCryptoEventMap = { /** * Fires when a key verification request is received. */ [CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void; /** * Fires when the trust status of a user changes. */ [CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserVerificationStatus) => void; [CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void; /** * Fires when the user's cross-signing keys have changed or cross-signing * has been enabled/disabled. The client can use getStoredCrossSigningForUser * with the user ID of the logged in user to check if cross-signing is * enabled on the account. If enabled, it can test whether the current key * is trusted using with checkUserTrust with the user ID of the logged * in user. The checkOwnCrossSigningTrust function may be used to reconcile * the trust in the account key. * * The cross-signing API is currently UNSTABLE and may change without notice. * @experimental */ [CryptoEvent.KeysChanged]: (data: {}) => void; /** * Fires whenever the stored devices for a user will be updated * @param users - A list of user IDs that will be updated * @param initialFetch - If true, the store is empty (apart * from our own device) and is being seeded. */ [CryptoEvent.WillUpdateDevices]: (users: string[], initialFetch: boolean) => void; /** * Fires whenever the stored devices for a user have changed * @param users - A list of user IDs that were updated * @param initialFetch - If true, the store was empty (apart * from our own device) and has been seeded. */ [CryptoEvent.DevicesUpdated]: (users: string[], initialFetch: boolean) => void; } & RustBackupCryptoEventMap; export {}; //# sourceMappingURL=rust-crypto.d.ts.map