Skip to content

Commit

Permalink
Element-R: emit VerificationRequestReceived on incoming request (#3762
Browse files Browse the repository at this point in the history
)
  • Loading branch information
richvdh authored Oct 3, 2023
1 parent 6eec2ce commit 6a761af
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 deletions.
50 changes: 40 additions & 10 deletions spec/integ/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -980,12 +980,43 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
});
}

it("Verification request not found", async () => {
// Expect to not find any verification request
const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz");
expect(request).toBeUndefined();
});

it("ignores old verification requests", async () => {
const eventHandler = jest.fn();
aliceClient.on(CryptoEvent.VerificationRequestReceived, eventHandler);

const verificationRequestEvent = createVerificationRequestEvent();
verificationRequestEvent.origin_server_ts -= 1000000;
returnRoomMessageFromSync(TEST_ROOM_ID, verificationRequestEvent);

await syncPromise(aliceClient);

// make sure the event has arrived
const room = aliceClient.getRoom(TEST_ROOM_ID)!;
const matrixEvent = room.getLiveTimeline().getEvents()[0];
expect(matrixEvent.getId()).toEqual(verificationRequestEvent.event_id);

// check that an event has not been raised, and that the request is not found
expect(eventHandler).not.toHaveBeenCalled();
expect(
aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"),
).not.toBeDefined();
});

it("Plaintext verification request from Bob to Alice", async () => {
// Add verification request from Bob to Alice in the DM between them
returnRoomMessageFromSync(TEST_ROOM_ID, createVerificationRequestEvent());

// Wait for the sync response to be processed
await syncPromise(aliceClient);
// Wait for the request to be received
const request1 = await emitPromise(aliceClient, CryptoEvent.VerificationRequestReceived);
expect(request1.roomId).toBe(TEST_ROOM_ID);
expect(request1.isSelfVerification).toBe(false);
expect(request1.otherUserId).toBe("@bob:xyz");

const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz");
// Expect to find the verification request received during the sync
Expand All @@ -994,12 +1025,6 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
expect(request?.otherUserId).toBe("@bob:xyz");
});

it("Verification request not found", async () => {
// Expect to not find any verification request
const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz");
expect(request).not.toBeDefined();
});

it("Encrypted verification request from Bob to Alice", async () => {
const p2pSession = await createOlmSession(testOlmAccount, e2eKeyReceiver);
const groupSession = new Olm.OutboundGroupSession();
Expand All @@ -1021,14 +1046,19 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
await awaitDecryption(matrixEvent);
expect(matrixEvent.getContent().msgtype).toEqual("m.bad.encrypted");

const requestEventPromise = emitPromise(aliceClient, CryptoEvent.VerificationRequestReceived);

// Send Bob the room keys
returnToDeviceMessageFromSync(toDeviceEvent);

// advance the clock, because the devicelist likes to sleep for 5ms during key downloads
await jest.advanceTimersByTimeAsync(10);

// Wait for the message to be decrypted
await awaitDecryption(matrixEvent, { waitOnDecryptionFailure: true });
// Wait for the request to be decrypted
const request1 = await requestEventPromise;
expect(request1.roomId).toBe(TEST_ROOM_ID);
expect(request1.isSelfVerification).toBe(false);
expect(request1.otherUserId).toBe("@bob:xyz");

const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz");
// Expect to find the verification request received during the sync
Expand Down
28 changes: 27 additions & 1 deletion src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import { keyFromPassphrase } from "../crypto/key_passphrase";
import { encodeRecoveryKey } from "../crypto/recoverykey";
import { crypto } from "../crypto/crypto";
import { isVerificationEvent, RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification";
import { EventType } from "../@types/event";
import { EventType, MsgType } from "../@types/event";
import { CryptoEvent } from "../crypto";
import { TypedEventEmitter } from "../models/typed-event-emitter";
import { RustBackupCryptoEventMap, RustBackupCryptoEvents, RustBackupDecryptor, RustBackupManager } from "./backup";
Expand Down Expand Up @@ -1407,6 +1407,32 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
new RustSdkCryptoJs.RoomId(roomId),
);

if (
event.getType() === EventType.RoomMessage &&
event.getContent().msgtype === MsgType.KeyVerificationRequest
) {
const request: RustSdkCryptoJs.VerificationRequest | undefined = this.olmMachine.getVerificationRequest(
new RustSdkCryptoJs.UserId(event.getSender()!),
event.getId()!,
);

if (!request) {
// There are multiple reasons this can happen; probably the most likely is that the event is too old.
logger.info(
`Ignoring just-received verification request ${event.getId()} which did not start a rust-side verification`,
);
} else {
this.emit(
CryptoEvent.VerificationRequestReceived,
new RustVerificationRequest(
request,
this.outgoingRequestProcessor,
this._supportedVerificationMethods,
),
);
}
}

// that may have caused us to queue up outgoing requests, so make sure we send them.
this.outgoingRequestLoop();
}
Expand Down

0 comments on commit 6a761af

Please sign in to comment.