Add a config flag to enable the rust crypto-sdk (#9759)

This PR adds an option to `config.json` which will make the js-sdk use the rust crypto sdk, instead of the libolm implementation.

To use it, you need to add something like this to `config.json`:

```
    "features": {
        "feature_rust_crypto": true
    },
```

We don't (yet) have any way to migrate a device between implementations, so the setting that was in use when you log in is persisted to the device; it is *visible* via the labs section but cannot currently be changed.

This is part of https://github.com/vector-im/element-web/issues/21972, and enables the functionality added to the js-sdk in https://github.com/matrix-org/matrix-js-sdk/pull/2969.
This commit is contained in:
Richard van der Hoff 2022-12-16 17:10:26 +00:00 committed by GitHub
parent bfaced2172
commit 6ec6d44c96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 157 additions and 19 deletions

View file

@ -39,6 +39,7 @@ import SecurityCustomisations from "./customisations/Security";
import { SlidingSyncManager } from "./SlidingSyncManager";
import CryptoStoreTooNewDialog from "./components/views/dialogs/CryptoStoreTooNewDialog";
import { _t } from "./languageHandler";
import { SettingLevel } from "./settings/SettingLevel";
export interface IMatrixClientCreds {
homeserverUrl: string;
@ -208,24 +209,8 @@ class MatrixClientPegClass implements IMatrixClientPeg {
}
// try to initialise e2e on the new client
try {
// check that we have a version of the js-sdk which includes initCrypto
if (!SettingsStore.getValue("lowBandwidth") && this.matrixClient.initCrypto) {
await this.matrixClient.initCrypto();
this.matrixClient.setCryptoTrustCrossSignedDevices(
!SettingsStore.getValue("e2ee.manuallyVerifyAllSessions"),
);
await tryToUnlockSecretStorageWithDehydrationKey(this.matrixClient);
StorageManager.setCryptoInitialised(true);
}
} catch (e) {
if (e && e.name === "InvalidCryptoStoreError") {
// The js-sdk found a crypto DB too new for it to use
Modal.createDialog(CryptoStoreTooNewDialog);
}
// this can happen for a number of reasons, the most likely being
// that the olm library was missing. It's not fatal.
logger.warn("Unable to initialise e2e", e);
if (!SettingsStore.getValue("lowBandwidth")) {
await this.initClientCrypto();
}
const opts = utils.deepCopy(this.opts);
@ -256,6 +241,48 @@ class MatrixClientPegClass implements IMatrixClientPeg {
return opts;
}
/**
* Attempt to initialize the crypto layer on a newly-created MatrixClient
*/
private async initClientCrypto(): Promise<void> {
const useRustCrypto = SettingsStore.getValue("feature_rust_crypto");
// we want to make sure that the same crypto implementation is used throughout the lifetime of a device,
// so persist the setting at the device layer
// (At some point, we'll allow the user to *enable* the setting via labs, which will migrate their existing
// device to the rust-sdk implementation, but that won't change anything here).
await SettingsStore.setValue("feature_rust_crypto", null, SettingLevel.DEVICE, useRustCrypto);
// Now we can initialise the right crypto impl.
if (useRustCrypto) {
await this.matrixClient.initRustCrypto();
// TODO: device dehydration and whathaveyou
return;
}
// fall back to the libolm layer.
try {
// check that we have a version of the js-sdk which includes initCrypto
if (this.matrixClient.initCrypto) {
await this.matrixClient.initCrypto();
this.matrixClient.setCryptoTrustCrossSignedDevices(
!SettingsStore.getValue("e2ee.manuallyVerifyAllSessions"),
);
await tryToUnlockSecretStorageWithDehydrationKey(this.matrixClient);
StorageManager.setCryptoInitialised(true);
}
} catch (e) {
if (e instanceof Error && e.name === "InvalidCryptoStoreError") {
// The js-sdk found a crypto DB too new for it to use
Modal.createDialog(CryptoStoreTooNewDialog);
}
// this can happen for a number of reasons, the most likely being
// that the olm library was missing. It's not fatal.
logger.warn("Unable to initialise e2e", e);
}
}
public async start(): Promise<any> {
const opts = await this.assign();