1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Rust crypto: emit VerificationRequestReceived events (#3525)

This commit is contained in:
Richard van der Hoff
2023-06-28 15:32:27 +01:00
committed by GitHub
parent e645af1fc5
commit 24cee68fa2
3 changed files with 79 additions and 7 deletions

View File

@@ -24,6 +24,7 @@ import fetchMock from "fetch-mock-jest";
import { RustCrypto } from "../../../src/rust-crypto/rust-crypto";
import { initRustCrypto } from "../../../src/rust-crypto";
import {
CryptoEvent,
HttpApiEvent,
HttpApiEventHandlerMap,
IHttpOpts,
@@ -37,7 +38,7 @@ import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend";
import { IEventDecryptionResult } from "../../../src/@types/crypto";
import { OutgoingRequest, OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { ServerSideSecretStorage } from "../../../src/secret-storage";
import { CryptoCallbacks, ImportRoomKeysOpts } from "../../../src/crypto-api";
import { CryptoCallbacks, ImportRoomKeysOpts, VerificationRequest } from "../../../src/crypto-api";
import * as testData from "../../test-utils/test-data";
afterEach(() => {
@@ -149,6 +150,27 @@ describe("RustCrypto", () => {
const res = await rustCrypto.preprocessToDeviceMessages(inputs);
expect(res).toEqual(inputs);
});
it("emits VerificationRequestReceived on incoming m.key.verification.request", async () => {
const toDeviceEvent = {
type: "m.key.verification.request",
content: {
from_device: "testDeviceId",
methods: ["m.sas.v1"],
transaction_id: "testTxn",
timestamp: Date.now() - 1000,
},
sender: "@user:id",
};
const onEvent = jest.fn();
rustCrypto.on(CryptoEvent.VerificationRequestReceived, onEvent);
await rustCrypto.preprocessToDeviceMessages([toDeviceEvent]);
expect(onEvent).toHaveBeenCalledTimes(1);
const [req]: [VerificationRequest] = onEvent.mock.lastCall;
expect(req.transactionId).toEqual("testTxn");
});
});
it("getCrossSigningKeyId", async () => {

View File

@@ -2246,6 +2246,9 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// attach the event listeners needed by RustCrypto
this.on(RoomMemberEvent.Membership, rustCrypto.onRoomMembership.bind(rustCrypto));
// re-emit the events emitted by the crypto impl
this.reEmitter.reEmit(rustCrypto, [CryptoEvent.VerificationRequestReceived]);
}
/**

View File

@@ -19,7 +19,7 @@ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js";
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 { IContent, MatrixEvent } from "../models/event";
import { Room } from "../models/room";
import { RoomMember } from "../models/room-member";
import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
@@ -32,15 +32,15 @@ import { KeyClaimManager } from "./KeyClaimManager";
import { MapWithDefault } from "../utils";
import {
BootstrapCrossSigningOpts,
CreateSecretStorageOpts,
CrossSigningKey,
CrossSigningStatus,
CryptoCallbacks,
DeviceVerificationStatus,
GeneratedSecretStorageKey,
ImportRoomKeyProgressData,
ImportRoomKeysOpts,
VerificationRequest,
CreateSecretStorageOpts,
CryptoCallbacks,
} from "../crypto-api";
import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter";
import { IDownloadKeyResult, IQueryKeysRequest } from "../client";
@@ -52,11 +52,14 @@ import { keyFromPassphrase } from "../crypto/key_passphrase";
import { encodeRecoveryKey } from "../crypto/recoverykey";
import { crypto } from "../crypto/crypto";
import { RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification";
import { EventType } from "../@types/event";
import { CryptoEvent } from "../crypto";
import { TypedEventEmitter } from "../models/typed-event-emitter";
/**
* An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto.
*/
export class RustCrypto implements CryptoBackend {
export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEventMap> implements CryptoBackend {
public globalErrorOnUnknownDevices = false;
private _trustCrossSignedDevices = true;
@@ -97,6 +100,7 @@ export class RustCrypto implements CryptoBackend {
/** Crypto callbacks provided by the application */
private readonly cryptoCallbacks: CryptoCallbacks,
) {
super();
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
this.eventDecryptor = new EventDecryptor(olmMachine);
@@ -670,10 +674,18 @@ export class RustCrypto implements CryptoBackend {
* @param events - the received to-device messages
* @returns A list of preprocessed to-device messages.
*/
public preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]> {
public async preprocessToDeviceMessages(events: IToDeviceEvent[]): Promise<IToDeviceEvent[]> {
// send the received to-device messages into receiveSyncChanges. We have no info on device-list changes,
// one-time-keys, or fallback keys, so just pass empty data.
return this.receiveSyncChanges({ events });
const processed = await this.receiveSyncChanges({ events });
// look for interesting to-device messages
for (const message of processed) {
if (message.type === EventType.KeyVerificationRequest) {
this.onIncomingKeyVerificationRequest(message.sender, message.content);
}
}
return processed;
}
/** called by the sync loop to process one time key counts and unused fallback keys
@@ -751,6 +763,32 @@ export class RustCrypto implements CryptoBackend {
this.outgoingRequestLoop();
}
/**
* Handle an incoming m.key.verification request event
*
* @param sender - the sender of the event
* @param content - the content of the event
*/
private onIncomingKeyVerificationRequest(sender: string, content: IContent): void {
const transactionId = content.transaction_id;
if (!transactionId || !sender) {
// not a valid request: ignore
return;
}
const request: RustSdkCryptoJs.VerificationRequest | undefined = this.olmMachine.getVerificationRequest(
new RustSdkCryptoJs.UserId(sender),
transactionId,
);
if (request) {
this.emit(
CryptoEvent.VerificationRequestReceived,
new RustVerificationRequest(request, this.outgoingRequestProcessor),
);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Other public functions
@@ -939,3 +977,12 @@ class EventDecryptor {
}
}
}
type RustCryptoEvents = CryptoEvent.VerificationRequestReceived;
type RustCryptoEventMap = {
/**
* Fires when a key verification request is received.
*/
[CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void;
};