Skip to content

Commit

Permalink
Element-R: Wire up globalBlacklistUnverifiedDevices field to rust c…
Browse files Browse the repository at this point in the history
…rypto encryption settings (#3790)

* Wire up `globalBlacklistUnverifiedDevices` rust crypto encrypted settings

* Improve test comment

* Update comments

* Review changes

* Fix lint due to merge
  • Loading branch information
florianduros authored Oct 26, 2023
1 parent 07a9eb3 commit ce7b7bf
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
34 changes: 34 additions & 0 deletions spec/integ/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ import {
establishOlmSession,
getTestOlmAccountKeys,
} from "./olm-utils";
import { ToDevicePayload } from "../../../src/models/ToDeviceMessage";

afterEach(() => {
// reset fake-indexeddb after each test, to make sure we don't leak connections
Expand Down Expand Up @@ -943,6 +944,39 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
aliceClient.sendTextMessage(ROOM_ID, "test"),
]);
});

it("should send a m.unverified code in toDevice messages to an unverified device when globalBlacklistUnverifiedDevices=true", async () => {
aliceClient.getCrypto()!.globalBlacklistUnverifiedDevices = true;

expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} });
await startClientAndAwaitFirstSync();
await establishOlmSession(aliceClient, keyReceiver, syncResponder, testOlmAccount);

// Tell alice we share a room with bob
syncResponder.sendOrQueueSyncResponse(getSyncResponse(["@bob:xyz"]));
await syncPromise(aliceClient);

// Force alice to download bob keys
expectAliceKeyQuery(getTestKeysQueryResponse("@bob:xyz"));

// Wait to receive the toDevice message and return bob device content
const toDevicePromise = new Promise<ToDevicePayload>((resolve) => {
fetchMock.putOnce(new RegExp("/sendToDevice/m.room_key.withheld/"), (url, request) => {
const content = JSON.parse(request.body as string);
resolve(content.messages["@bob:xyz"]["DEVICE_ID"]);
return {};
});
});

// Mock endpoint of message sending
fetchMock.put(new RegExp("/send/"), { event_id: "$event_id" });

await aliceClient.sendTextMessage(ROOM_ID, "test");

// Finally, check that the toDevice message has the m.unverified code
const toDeviceContent = await toDevicePromise;
expect(toDeviceContent.code).toBe("m.unverified");
});
});

describe("Session should rotate according to encryption settings", () => {
Expand Down
18 changes: 14 additions & 4 deletions src/rust-crypto/RoomEncryptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
RoomId,
UserId,
HistoryVisibility as RustHistoryVisibility,
ToDeviceRequest,
} from "@matrix-org/matrix-sdk-crypto-wasm";

import { EventType } from "../@types/event";
Expand All @@ -43,6 +44,7 @@ export class RoomEncryptor {
/**
* @param olmMachine - The rust-sdk's OlmMachine
* @param keyClaimManager - Our KeyClaimManager, which manages the queue of one-time-key claim requests
* @param outgoingRequestProcessor - The OutgoingRequestProcessor, which sends outgoing requests
* @param room - The room we want to encrypt for
* @param encryptionSettings - body of the m.room.encryption event currently in force in this room
*/
Expand Down Expand Up @@ -91,8 +93,10 @@ export class RoomEncryptor {
*
* This ensures that we have a megolm session ready to use and that we have shared its key with all the devices
* in the room.
*
* @param globalBlacklistUnverifiedDevices - When `true`, it will not send encrypted messages to unverified devices
*/
public async ensureEncryptionSession(): Promise<void> {
public async ensureEncryptionSession(globalBlacklistUnverifiedDevices: boolean): Promise<void> {
if (this.encryptionSettings.algorithm !== "m.megolm.v1.aes-sha2") {
throw new Error(
`Cannot encrypt in ${this.room.roomId} for unsupported algorithm '${this.encryptionSettings.algorithm}'`,
Expand Down Expand Up @@ -127,7 +131,12 @@ export class RoomEncryptor {
rustEncryptionSettings.rotationPeriodMessages = BigInt(this.encryptionSettings.rotation_period_msgs);
}

const shareMessages = await this.olmMachine.shareRoomKey(
// When this.room.getBlacklistUnverifiedDevices() === null, the global settings should be used
// See Room#getBlacklistUnverifiedDevices
rustEncryptionSettings.onlyAllowTrustedDevices =
this.room.getBlacklistUnverifiedDevices() ?? globalBlacklistUnverifiedDevices;

const shareMessages: ToDeviceRequest[] = await this.olmMachine.shareRoomKey(
new RoomId(this.room.roomId),
userList,
rustEncryptionSettings,
Expand Down Expand Up @@ -156,9 +165,10 @@ export class RoomEncryptor {
* then encrypt the event using the session.
*
* @param event - Event to be encrypted.
* @param globalBlacklistUnverifiedDevices - When `true`, it will not send encrypted messages to unverified devices
*/
public async encryptEvent(event: MatrixEvent): Promise<void> {
await this.ensureEncryptionSession();
public async encryptEvent(event: MatrixEvent, globalBlacklistUnverifiedDevices: boolean): Promise<void> {
await this.ensureEncryptionSession(globalBlacklistUnverifiedDevices);

const encryptedContent = await this.olmMachine.encryptRoomEvent(
new RoomId(this.room.roomId),
Expand Down
4 changes: 2 additions & 2 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
throw new Error(`Cannot encrypt event in unconfigured room ${roomId}`);
}

await encryptor.encryptEvent(event);
await encryptor.encryptEvent(event, this.globalBlacklistUnverifiedDevices);
}

public async decryptEvent(event: MatrixEvent): Promise<IEventDecryptionResult> {
Expand Down Expand Up @@ -376,7 +376,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
const encryptor = this.roomEncryptors[room.roomId];

if (encryptor) {
encryptor.ensureEncryptionSession();
encryptor.ensureEncryptionSession(this.globalBlacklistUnverifiedDevices);
}
}

Expand Down

0 comments on commit ce7b7bf

Please sign in to comment.