1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

Element-R: implement {get,set}TrustCrossSignedDevices (#3281)

A precursor to https://github.com/vector-im/element-web/issues/25092
This commit is contained in:
Richard van der Hoff
2023-04-18 11:28:47 +01:00
committed by GitHub
parent 95f7d1d347
commit c61d53eed0
6 changed files with 119 additions and 8 deletions

View File

@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import HttpBackend from "matrix-mock-request"; import HttpBackend from "matrix-mock-request";
import { Mocked } from "jest-mock";
import * as utils from "../test-utils/test-utils"; import * as utils from "../test-utils/test-utils";
import { CRYPTO_ENABLED, IStoredClientOpts, MatrixClient } from "../../src/client"; 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 { IFilterDefinition } from "../../src/filter";
import { ISearchResults } from "../../src/@types/search"; import { ISearchResults } from "../../src/@types/search";
import { IStore } from "../../src/store"; import { IStore } from "../../src/store";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
describe("MatrixClient", function () { describe("MatrixClient", function () {
const userId = "@alice:localhost"; const userId = "@alice:localhost";
@@ -1412,6 +1414,42 @@ describe("MatrixClient", function () {
await client!.uploadKeys(); 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 { function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {

View File

@@ -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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -230,4 +230,23 @@ describe("RustCrypto", () => {
expect(res.encrypted).toBeTruthy(); 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);
});
});
}); });

View File

@@ -2764,24 +2764,28 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Default: true * Default: true
* *
* @returns True if trusting cross-signed devices * @returns True if trusting cross-signed devices
*
* @deprecated Prefer {@link CryptoApi.getTrustCrossSignedDevices | `CryptoApi.getTrustCrossSignedDevices`}.
*/ */
public getCryptoTrustCrossSignedDevices(): boolean { public getCryptoTrustCrossSignedDevices(): boolean {
if (!this.crypto) { if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
return this.crypto.getCryptoTrustCrossSignedDevices(); return this.cryptoBackend.getTrustCrossSignedDevices();
} }
/** /**
* See getCryptoTrustCrossSignedDevices * See getCryptoTrustCrossSignedDevices
* *
* @param val - True to trust cross-signed devices * @param val - True to trust cross-signed devices
*
* @deprecated Prefer {@link CryptoApi.setTrustCrossSignedDevices | `CryptoApi.setTrustCrossSignedDevices`}.
*/ */
public setCryptoTrustCrossSignedDevices(val: boolean): void { public setCryptoTrustCrossSignedDevices(val: boolean): void {
if (!this.crypto) { if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
this.crypto.setCryptoTrustCrossSignedDevices(val); this.cryptoBackend.setTrustCrossSignedDevices(val);
} }
/** /**

View File

@@ -72,4 +72,25 @@ export interface CryptoApi {
* session export objects * session export objects
*/ */
exportRoomKeys(): Promise<IMegolmSessionData[]>; 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;
} }

View File

@@ -605,18 +605,23 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
* *
* @returns True if trusting cross-signed devices * @returns True if trusting cross-signed devices
*/ */
public getTrustCrossSignedDevices(): boolean {
return this.trustCrossSignedDevices;
}
/**
* @deprecated Use {@link CryptoApi#getTrustCrossSignedDevices}.
*/
public getCryptoTrustCrossSignedDevices(): boolean { public getCryptoTrustCrossSignedDevices(): boolean {
return this.trustCrossSignedDevices; return this.trustCrossSignedDevices;
} }
/** /**
* See getCryptoTrustCrossSignedDevices * See getCryptoTrustCrossSignedDevices
* This may be set before initCrypto() is called to ensure no races occur.
* *
* @param val - True to trust cross-signed devices * @param val - True to trust cross-signed devices
*/ */
public setCryptoTrustCrossSignedDevices(val: boolean): void { public setTrustCrossSignedDevices(val: boolean): void {
this.trustCrossSignedDevices = val; this.trustCrossSignedDevices = val;
for (const userId of this.deviceList.getKnownUserIds()) { for (const userId of this.deviceList.getKnownUserIds()) {
@@ -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. * Create a recovery key from a user-supplied passphrase.
* *

View File

@@ -36,6 +36,7 @@ import { MapWithDefault } from "../utils";
*/ */
export class RustCrypto implements CryptoBackend { export class RustCrypto implements CryptoBackend {
public globalErrorOnUnknownDevices = false; public globalErrorOnUnknownDevices = false;
private _trustCrossSignedDevices = true;
/** whether {@link stop} has been called */ /** whether {@link stop} has been called */
private stopped = false; private stopped = false;
@@ -165,6 +166,22 @@ export class RustCrypto implements CryptoBackend {
return []; 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 // SyncCryptoCallbacks implementation