Skip to content

Commit

Permalink
Pass SecretStorage into RustCrypto (#3353)
Browse files Browse the repository at this point in the history
* Pass SecretStorage into RustCrypto

* Update src/rust-crypto/rust-crypto.ts
  • Loading branch information
richvdh authored May 12, 2023
1 parent ceb2a57 commit 40f2579
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
45 changes: 39 additions & 6 deletions spec/unit/rust-crypto/rust-crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { mkEvent } from "../../test-utils/test-utils";
import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend";
import { IEventDecryptionResult } from "../../../src/@types/crypto";
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { ServerSideSecretStorage } from "../../../src/secret-storage";

afterEach(() => {
// reset fake-indexeddb after each test, to make sure we don't leak connections
Expand All @@ -44,7 +45,12 @@ describe("RustCrypto", () => {

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

it("should return a list", async () => {
Expand All @@ -58,7 +64,12 @@ describe("RustCrypto", () => {

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

it("should pass through unencrypted to-device messages", async () => {
Expand Down Expand Up @@ -141,7 +152,13 @@ describe("RustCrypto", () => {
makeOutgoingRequest: jest.fn(),
} as unknown as Mocked<OutgoingRequestProcessor>;

rustCrypto = new RustCrypto(olmMachine, {} as MatrixHttpApi<any>, TEST_USER, TEST_DEVICE_ID);
rustCrypto = new RustCrypto(
olmMachine,
{} as MatrixHttpApi<any>,
TEST_USER,
TEST_DEVICE_ID,
{} as ServerSideSecretStorage,
);
rustCrypto["outgoingRequestProcessor"] = outgoingRequestProcessor;
});

Expand Down Expand Up @@ -207,7 +224,12 @@ describe("RustCrypto", () => {

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

it("should handle unencrypted events", () => {
Expand Down Expand Up @@ -235,7 +257,12 @@ describe("RustCrypto", () => {
let rustCrypto: RustCrypto;

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

it("should be true by default", () => {
Expand All @@ -258,7 +285,13 @@ describe("RustCrypto", () => {
olmMachine = {
getDevice: jest.fn(),
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
rustCrypto = new RustCrypto(olmMachine, {} as MatrixClient["http"], TEST_USER, TEST_DEVICE_ID);
rustCrypto = new RustCrypto(
olmMachine,
{} as MatrixClient["http"],
TEST_USER,
TEST_DEVICE_ID,
{} as ServerSideSecretStorage,
);
});

it("should call getDevice", async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2227,7 +2227,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// importing rust-crypto will download the webassembly, so we delay it until we know it will be
// needed.
const RustCrypto = await import("./rust-crypto");
const rustCrypto = await RustCrypto.initRustCrypto(this.http, userId, deviceId);
const rustCrypto = await RustCrypto.initRustCrypto(this.http, userId, deviceId, this.secretStorage);
this.cryptoBackend = rustCrypto;

// attach the event listeners needed by RustCrypto
Expand Down
15 changes: 13 additions & 2 deletions src/rust-crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ import { RustCrypto } from "./rust-crypto";
import { logger } from "../logger";
import { RUST_SDK_STORE_PREFIX } from "./constants";
import { IHttpOpts, MatrixHttpApi } from "../http-api";

import { ServerSideSecretStorage } from "../secret-storage";

/**
* Create a new `RustCrypto` implementation
*
* @param http - Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
* We expect it to set the access token, etc.
* @param userId - The local user's User ID.
* @param deviceId - The local user's Device ID.
* @param secretStorage - Interface to server-side secret storage.
*/
export async function initRustCrypto(
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
userId: string,
deviceId: string,
secretStorage: ServerSideSecretStorage,
): Promise<RustCrypto> {
// initialise the rust matrix-sdk-crypto-js, if it hasn't already been done
await RustSdkCryptoJs.initAsync();
Expand All @@ -38,7 +49,7 @@ export async function initRustCrypto(

// TODO: use the pickle key for the passphrase
const olmMachine = await RustSdkCryptoJs.OlmMachine.initialize(u, d, RUST_SDK_STORE_PREFIX, "test pass");
const rustCrypto = new RustCrypto(olmMachine, http, userId, deviceId);
const rustCrypto = new RustCrypto(olmMachine, http, userId, deviceId, secretStorage);
await olmMachine.registerRoomKeyUpdatedCallback((sessions: RustSdkCryptoJs.RoomKeyInfo[]) =>
rustCrypto.onRoomKeysUpdated(sessions),
);
Expand Down
15 changes: 15 additions & 0 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { DeviceVerificationStatus } from "../crypto-api";
import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter";
import { IDownloadKeyResult, IQueryKeysRequest } from "../client";
import { Device, DeviceMap } from "../models/device";
import { ServerSideSecretStorage } from "../secret-storage";

/**
* An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto.
Expand All @@ -56,10 +57,24 @@ export class RustCrypto implements CryptoBackend {
private outgoingRequestProcessor: OutgoingRequestProcessor;

public constructor(
/** The `OlmMachine` from the underlying rust crypto sdk. */
private readonly olmMachine: RustSdkCryptoJs.OlmMachine,

/**
* Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
*
* We expect it to set the access token, etc.
*/
private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,

/** The local user's User ID. */
_userId: string,

/** The local user's Device ID. */
_deviceId: string,

/** Interface to server-side secret storage */
_secretStorage: ServerSideSecretStorage,
) {
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
Expand Down

0 comments on commit 40f2579

Please sign in to comment.