From e1ed22de862458522eecd3da2c1043e8ddf355b8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 13 Apr 2023 11:18:22 +0100 Subject: [PATCH] Element-R: implement `{get,set}TrustCrossSignedDevices` A precursor to https://github.com/vector-im/element-web/issues/25092 --- spec/integ/matrix-client-methods.spec.ts | 38 +++++++++++++++++++++++ spec/unit/rust-crypto/rust-crypto.spec.ts | 21 ++++++++++++- src/client.ts | 12 ++++--- src/crypto-api.ts | 21 +++++++++++++ src/crypto/index.ts | 18 +++++++++-- src/rust-crypto/rust-crypto.ts | 17 ++++++++++ 6 files changed, 119 insertions(+), 8 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index 33b5e1ad9eb..8bf57124d83 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -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"; @@ -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"; @@ -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; + 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; + 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 { diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 7a66de7057a..3eea4ba12b7 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -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. @@ -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); + }); + }); }); diff --git a/src/client.ts b/src/client.ts index 309817f879a..635464ac45b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2748,24 +2748,28 @@ export class MatrixClient extends TypedEventEmitter; + + /** + * 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; } diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 6d860c6d290..0b36347867a 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -605,18 +605,23 @@ export class Crypto extends TypedEventEmitter