Skip to content

Commit

Permalink
Element-R: implement {get,set}TrustCrossSignedDevices
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Apr 13, 2023
1 parent f400a7b commit e1ed22d
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 8 deletions.
38 changes: 38 additions & 0 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import HttpBackend from "matrix-mock-request";
import { Mocked } from "jest-mock";

import * as utils from "../test-utils/test-utils";
import { CRYPTO_ENABLED, IStoredClientOpts, MatrixClient } from "../../src/client";
Expand All @@ -24,6 +25,7 @@ import { THREAD_RELATION_TYPE } from "../../src/models/thread";
import { IFilterDefinition } from "../../src/filter";
import { ISearchResults } from "../../src/@types/search";
import { IStore } from "../../src/store";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";

describe("MatrixClient", function () {
const userId = "@alice:localhost";
Expand Down Expand Up @@ -1412,6 +1414,42 @@ describe("MatrixClient", function () {
await client!.uploadKeys();
});
});

describe("getCryptoTrustCrossSignedDevices", () => {
it("should throw if e2e is disabled", () => {
expect(() => client!.getCryptoTrustCrossSignedDevices()).toThrow("End-to-end encryption disabled");
});

it("should proxy to the crypto backend", async () => {
const mockBackend = {
getTrustCrossSignedDevices: jest.fn().mockReturnValue(true),
} as unknown as Mocked<CryptoBackend>;
client!["cryptoBackend"] = mockBackend;

expect(client!.getCryptoTrustCrossSignedDevices()).toBe(true);
mockBackend.getTrustCrossSignedDevices.mockReturnValue(false);
expect(client!.getCryptoTrustCrossSignedDevices()).toBe(false);
});
});

describe("setCryptoTrustCrossSignedDevices", () => {
it("should throw if e2e is disabled", () => {
expect(() => client!.setCryptoTrustCrossSignedDevices(false)).toThrow("End-to-end encryption disabled");
});

it("should proxy to the crypto backend", async () => {
const mockBackend = {
setTrustCrossSignedDevices: jest.fn(),
} as unknown as Mocked<CryptoBackend>;
client!["cryptoBackend"] = mockBackend;

client!.setCryptoTrustCrossSignedDevices(true);
expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(true);

client!.setCryptoTrustCrossSignedDevices(false);
expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(false);
});
});
});

function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {
Expand Down
21 changes: 20 additions & 1 deletion spec/unit/rust-crypto/rust-crypto.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Copyright 2022-2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -230,4 +230,23 @@ describe("RustCrypto", () => {
expect(res.encrypted).toBeTruthy();
});
});

describe("get|setTrustCrossSignedDevices", () => {
let rustCrypto: RustCrypto;

beforeEach(async () => {
rustCrypto = await initRustCrypto({} as MatrixClient["http"], TEST_USER, TEST_DEVICE_ID);
});

it("should be true by default", () => {
expect(rustCrypto.getTrustCrossSignedDevices()).toBe(true);
});

it("should be easily turn-off-and-on-able", () => {
rustCrypto.setTrustCrossSignedDevices(false);
expect(rustCrypto.getTrustCrossSignedDevices()).toBe(false);
rustCrypto.setTrustCrossSignedDevices(true);
expect(rustCrypto.getTrustCrossSignedDevices()).toBe(true);
});
});
});
12 changes: 8 additions & 4 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2748,24 +2748,28 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Default: true
*
* @returns True if trusting cross-signed devices
*
* @deprecated Prefer {@link CryptoApi.getTrustCrossSignedDevices | `CryptoApi.getTrustCrossSignedDevices`}.
*/
public getCryptoTrustCrossSignedDevices(): boolean {
if (!this.crypto) {
if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled");
}
return this.crypto.getCryptoTrustCrossSignedDevices();
return this.cryptoBackend.getTrustCrossSignedDevices();
}

/**
* See getCryptoTrustCrossSignedDevices
*
* @param val - True to trust cross-signed devices
*
* @deprecated Prefer {@link CryptoApi.setTrustCrossSignedDevices | `CryptoApi.setTrustCrossSignedDevices`}.
*/
public setCryptoTrustCrossSignedDevices(val: boolean): void {
if (!this.crypto) {
if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled");
}
this.crypto.setCryptoTrustCrossSignedDevices(val);
this.cryptoBackend.setTrustCrossSignedDevices(val);
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/crypto-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,25 @@ export interface CryptoApi {
* session export objects
*/
exportRoomKeys(): Promise<IMegolmSessionData[]>;

/**
* Set whether to trust other user's signatures of their devices.
*
* If false, devices will only be considered 'verified' if we have
* verified that device individually (effectively disabling cross-signing).
*
* `true` by default.
*
* @param val - the new value
*/
setTrustCrossSignedDevices(val: boolean): void;

/**
* Return whether we trust other user's signatures of their devices.
*
* @see {@link CryptoApi#setTrustCrossSignedDevices}
*
* @returns `true` if we trust cross-signed devices, otherwise `false`.
*/
getTrustCrossSignedDevices(): boolean;
}
18 changes: 15 additions & 3 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,18 +605,23 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
*
* @returns True if trusting cross-signed devices
*/
public getTrustCrossSignedDevices(): boolean {
return this.trustCrossSignedDevices;
}

/**
* @deprecated Use {@link CryptoApi#getTrustCrossSignedDevices}.
*/
public getCryptoTrustCrossSignedDevices(): boolean {
return this.trustCrossSignedDevices;
}

/**
* See getCryptoTrustCrossSignedDevices
* This may be set before initCrypto() is called to ensure no races occur.
*
* @param val - True to trust cross-signed devices
*/
public setCryptoTrustCrossSignedDevices(val: boolean): void {
public setTrustCrossSignedDevices(val: boolean): void {
this.trustCrossSignedDevices = val;

for (const userId of this.deviceList.getKnownUserIds()) {
Expand All @@ -634,6 +639,13 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
}
}

/**
* @deprecated Use {@link CryptoApi#setTrustCrossSignedDevices}.
*/
public setCryptoTrustCrossSignedDevices(val: boolean): void {
this.setTrustCrossSignedDevices(val);
}

/**
* Create a recovery key from a user-supplied passphrase.
*
Expand Down
17 changes: 17 additions & 0 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { MapWithDefault } from "../utils";
*/
export class RustCrypto implements CryptoBackend {
public globalErrorOnUnknownDevices = false;
private _trustCrossSignedDevices = true;

/** whether {@link stop} has been called */
private stopped = false;
Expand Down Expand Up @@ -165,6 +166,22 @@ export class RustCrypto implements CryptoBackend {
return [];
}

/**
* Implementation of {@link CryptoApi#getTrustCrossSignedDevices}.
*/
public getTrustCrossSignedDevices(): boolean {
return this._trustCrossSignedDevices;
}

/**
* Implementation of {@link CryptoApi#setTrustCrossSignedDevices}.
*/
public setTrustCrossSignedDevices(val: boolean): void {
this._trustCrossSignedDevices = val;
// TODO: legacy crypto goes through the list of known devices and emits DeviceVerificationChanged
// events. Maybe we need to do the same?
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// SyncCryptoCallbacks implementation
Expand Down

0 comments on commit e1ed22d

Please sign in to comment.