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 { RustCrypto } from "../../../src/rust-crypto/rust-crypto";
import { initRustCrypto } from "../../../src/rust-crypto"; import { initRustCrypto } from "../../../src/rust-crypto";
import { import {
CryptoEvent,
HttpApiEvent, HttpApiEvent,
HttpApiEventHandlerMap, HttpApiEventHandlerMap,
IHttpOpts, IHttpOpts,
@@ -37,7 +38,7 @@ import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend";
import { IEventDecryptionResult } from "../../../src/@types/crypto"; import { IEventDecryptionResult } from "../../../src/@types/crypto";
import { OutgoingRequest, OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; import { OutgoingRequest, OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { ServerSideSecretStorage } from "../../../src/secret-storage"; 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"; import * as testData from "../../test-utils/test-data";
afterEach(() => { afterEach(() => {
@@ -149,6 +150,27 @@ describe("RustCrypto", () => {
const res = await rustCrypto.preprocessToDeviceMessages(inputs); const res = await rustCrypto.preprocessToDeviceMessages(inputs);
expect(res).toEqual(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 () => { it("getCrossSigningKeyId", async () => {

View File

@@ -2246,6 +2246,9 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// attach the event listeners needed by RustCrypto // attach the event listeners needed by RustCrypto
this.on(RoomMemberEvent.Membership, rustCrypto.onRoomMembership.bind(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 { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto";
import type { IDeviceLists, IToDeviceEvent } from "../sync-accumulator"; import type { IDeviceLists, IToDeviceEvent } from "../sync-accumulator";
import type { IEncryptedEventInfo } from "../crypto/api"; import type { IEncryptedEventInfo } from "../crypto/api";
import { MatrixEvent } from "../models/event"; import { IContent, MatrixEvent } from "../models/event";
import { Room } from "../models/room"; import { Room } from "../models/room";
import { RoomMember } from "../models/room-member"; import { RoomMember } from "../models/room-member";
import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend"; import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
@@ -32,15 +32,15 @@ import { KeyClaimManager } from "./KeyClaimManager";
import { MapWithDefault } from "../utils"; import { MapWithDefault } from "../utils";
import { import {
BootstrapCrossSigningOpts, BootstrapCrossSigningOpts,
CreateSecretStorageOpts,
CrossSigningKey, CrossSigningKey,
CrossSigningStatus, CrossSigningStatus,
CryptoCallbacks,
DeviceVerificationStatus, DeviceVerificationStatus,
GeneratedSecretStorageKey, GeneratedSecretStorageKey,
ImportRoomKeyProgressData, ImportRoomKeyProgressData,
ImportRoomKeysOpts, ImportRoomKeysOpts,
VerificationRequest, VerificationRequest,
CreateSecretStorageOpts,
CryptoCallbacks,
} from "../crypto-api"; } from "../crypto-api";
import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter"; import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter";
import { IDownloadKeyResult, IQueryKeysRequest } from "../client"; import { IDownloadKeyResult, IQueryKeysRequest } from "../client";
@@ -52,11 +52,14 @@ import { keyFromPassphrase } from "../crypto/key_passphrase";
import { encodeRecoveryKey } from "../crypto/recoverykey"; import { encodeRecoveryKey } from "../crypto/recoverykey";
import { crypto } from "../crypto/crypto"; import { crypto } from "../crypto/crypto";
import { RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification"; 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. * 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; public globalErrorOnUnknownDevices = false;
private _trustCrossSignedDevices = true; private _trustCrossSignedDevices = true;
@@ -97,6 +100,7 @@ export class RustCrypto implements CryptoBackend {
/** Crypto callbacks provided by the application */ /** Crypto callbacks provided by the application */
private readonly cryptoCallbacks: CryptoCallbacks, private readonly cryptoCallbacks: CryptoCallbacks,
) { ) {
super();
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http); this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor); this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
this.eventDecryptor = new EventDecryptor(olmMachine); this.eventDecryptor = new EventDecryptor(olmMachine);
@@ -670,10 +674,18 @@ export class RustCrypto implements CryptoBackend {
* @param events - the received to-device messages * @param events - the received to-device messages
* @returns A list of preprocessed 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, // 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. // 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 /** 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(); 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 // 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;
};