You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
Groundwork for supporting migration from libolm to rust crypto. (#3977)
* `getOwnDeviceKeys`: use `olmMachine.identityKeys` This is simpler, and doesn't rely on us having done a device query to work. * Factor out `requestKeyBackupVersion` utility * Factor out `makeMatrixHttpApi` function * Convert `initRustCrypto` to take a params object * Improve logging in startup ... to help figure out what is taking so long.
This commit is contained in:
committed by
GitHub
parent
c115e055c6
commit
d030c83cee
@ -398,17 +398,11 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
|
|||||||
expect(aliceClient.getCrypto()).toHaveProperty("globalBlacklistUnverifiedDevices");
|
expect(aliceClient.getCrypto()).toHaveProperty("globalBlacklistUnverifiedDevices");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("CryptoAPI.getOwnedDeviceKeys returns the correct values", async () => {
|
it("CryptoAPI.getOwnDeviceKeys returns plausible values", async () => {
|
||||||
const homeserverUrl = aliceClient.getHomeserverUrl();
|
|
||||||
|
|
||||||
keyResponder = new E2EKeyResponder(homeserverUrl);
|
|
||||||
await startClientAndAwaitFirstSync();
|
|
||||||
keyResponder.addKeyReceiver("@alice:localhost", keyReceiver);
|
|
||||||
|
|
||||||
const deviceKeys = await aliceClient.getCrypto()!.getOwnDeviceKeys();
|
const deviceKeys = await aliceClient.getCrypto()!.getOwnDeviceKeys();
|
||||||
|
// We just check for a 43-character base64 string
|
||||||
expect(deviceKeys.curve25519).toEqual(keyReceiver.getDeviceKey());
|
expect(deviceKeys.curve25519).toMatch(/^[A-Za-z0-9+/]{43}$/);
|
||||||
expect(deviceKeys.ed25519).toEqual(keyReceiver.getSigningKey());
|
expect(deviceKeys.ed25519).toMatch(/^[A-Za-z0-9+/]{43}$/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Alice receives a megolm message", async () => {
|
it("Alice receives a megolm message", async () => {
|
||||||
|
@ -84,16 +84,16 @@ describe("initRustCrypto", () => {
|
|||||||
const testOlmMachine = makeTestOlmMachine();
|
const testOlmMachine = makeTestOlmMachine();
|
||||||
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
||||||
|
|
||||||
await initRustCrypto(
|
await initRustCrypto({
|
||||||
logger,
|
logger,
|
||||||
{} as MatrixClient["http"],
|
http: {} as MatrixClient["http"],
|
||||||
TEST_USER,
|
userId: TEST_USER,
|
||||||
TEST_DEVICE_ID,
|
deviceId: TEST_DEVICE_ID,
|
||||||
{} as ServerSideSecretStorage,
|
secretStorage: {} as ServerSideSecretStorage,
|
||||||
{} as CryptoCallbacks,
|
cryptoCallbacks: {} as CryptoCallbacks,
|
||||||
"storePrefix",
|
storePrefix: "storePrefix",
|
||||||
"storePassphrase",
|
storePassphrase: "storePassphrase",
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(OlmMachine.initialize).toHaveBeenCalledWith(
|
expect(OlmMachine.initialize).toHaveBeenCalledWith(
|
||||||
expect.anything(),
|
expect.anything(),
|
||||||
@ -107,16 +107,16 @@ describe("initRustCrypto", () => {
|
|||||||
const testOlmMachine = makeTestOlmMachine();
|
const testOlmMachine = makeTestOlmMachine();
|
||||||
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
||||||
|
|
||||||
await initRustCrypto(
|
await initRustCrypto({
|
||||||
logger,
|
logger,
|
||||||
{} as MatrixClient["http"],
|
http: {} as MatrixClient["http"],
|
||||||
TEST_USER,
|
userId: TEST_USER,
|
||||||
TEST_DEVICE_ID,
|
deviceId: TEST_DEVICE_ID,
|
||||||
{} as ServerSideSecretStorage,
|
secretStorage: {} as ServerSideSecretStorage,
|
||||||
{} as CryptoCallbacks,
|
cryptoCallbacks: {} as CryptoCallbacks,
|
||||||
null,
|
storePrefix: null,
|
||||||
"storePassphrase",
|
storePassphrase: "storePassphrase",
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(OlmMachine.initialize).toHaveBeenCalledWith(expect.anything(), expect.anything(), undefined, undefined);
|
expect(OlmMachine.initialize).toHaveBeenCalledWith(expect.anything(), expect.anything(), undefined, undefined);
|
||||||
});
|
});
|
||||||
@ -125,16 +125,16 @@ describe("initRustCrypto", () => {
|
|||||||
const testOlmMachine = makeTestOlmMachine() as OlmMachine;
|
const testOlmMachine = makeTestOlmMachine() as OlmMachine;
|
||||||
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
||||||
|
|
||||||
await initRustCrypto(
|
await initRustCrypto({
|
||||||
logger,
|
logger,
|
||||||
{} as MatrixClient["http"],
|
http: {} as MatrixClient["http"],
|
||||||
TEST_USER,
|
userId: TEST_USER,
|
||||||
TEST_DEVICE_ID,
|
deviceId: TEST_DEVICE_ID,
|
||||||
{} as ServerSideSecretStorage,
|
secretStorage: {} as ServerSideSecretStorage,
|
||||||
{} as CryptoCallbacks,
|
cryptoCallbacks: {} as CryptoCallbacks,
|
||||||
"storePrefix",
|
storePrefix: "storePrefix",
|
||||||
"storePassphrase",
|
storePassphrase: "storePassphrase",
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(testOlmMachine.getSecretsFromInbox).toHaveBeenCalledWith("m.megolm_backup.v1");
|
expect(testOlmMachine.getSecretsFromInbox).toHaveBeenCalledWith("m.megolm_backup.v1");
|
||||||
});
|
});
|
||||||
@ -823,11 +823,6 @@ describe("RustCrypto", () => {
|
|||||||
it("should wait for a keys/query before returning devices", async () => {
|
it("should wait for a keys/query before returning devices", async () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const mockHttpApi = new MatrixHttpApi(new TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>(), {
|
|
||||||
baseUrl: "http://server/",
|
|
||||||
prefix: "",
|
|
||||||
onlyData: true,
|
|
||||||
});
|
|
||||||
fetchMock.post("path:/_matrix/client/v3/keys/upload", { one_time_key_counts: {} });
|
fetchMock.post("path:/_matrix/client/v3/keys/upload", { one_time_key_counts: {} });
|
||||||
fetchMock.post("path:/_matrix/client/v3/keys/query", {
|
fetchMock.post("path:/_matrix/client/v3/keys/query", {
|
||||||
device_keys: {
|
device_keys: {
|
||||||
@ -837,7 +832,7 @@ describe("RustCrypto", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const rustCrypto = await makeTestRustCrypto(mockHttpApi, testData.TEST_USER_ID);
|
const rustCrypto = await makeTestRustCrypto(makeMatrixHttpApi(), testData.TEST_USER_ID);
|
||||||
|
|
||||||
// an attempt to fetch the device list should block
|
// an attempt to fetch the device list should block
|
||||||
const devicesPromise = rustCrypto.getUserDeviceInfo([testData.TEST_USER_ID]);
|
const devicesPromise = rustCrypto.getUserDeviceInfo([testData.TEST_USER_ID]);
|
||||||
@ -963,12 +958,6 @@ describe("RustCrypto", () => {
|
|||||||
// Return the key backup
|
// Return the key backup
|
||||||
fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA);
|
fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA);
|
||||||
|
|
||||||
const mockHttpApi = new MatrixHttpApi(new TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>(), {
|
|
||||||
baseUrl: "http://server/",
|
|
||||||
prefix: "",
|
|
||||||
onlyData: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const olmMachine = {
|
const olmMachine = {
|
||||||
getIdentity: jest.fn(),
|
getIdentity: jest.fn(),
|
||||||
// Force the backup to be trusted by the olmMachine
|
// Force the backup to be trusted by the olmMachine
|
||||||
@ -981,7 +970,7 @@ describe("RustCrypto", () => {
|
|||||||
const rustCrypto = new RustCrypto(
|
const rustCrypto = new RustCrypto(
|
||||||
logger,
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
mockHttpApi,
|
makeMatrixHttpApi(),
|
||||||
testData.TEST_USER_ID,
|
testData.TEST_USER_ID,
|
||||||
testData.TEST_DEVICE_ID,
|
testData.TEST_DEVICE_ID,
|
||||||
{} as ServerSideSecretStorage,
|
{} as ServerSideSecretStorage,
|
||||||
@ -1040,6 +1029,15 @@ describe("RustCrypto", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** Build a MatrixHttpApi instance */
|
||||||
|
function makeMatrixHttpApi(): MatrixHttpApi<IHttpOpts & { onlyData: true }> {
|
||||||
|
return new MatrixHttpApi(new TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>(), {
|
||||||
|
baseUrl: "http://server/",
|
||||||
|
prefix: "",
|
||||||
|
onlyData: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** build a basic RustCrypto instance for testing
|
/** build a basic RustCrypto instance for testing
|
||||||
*
|
*
|
||||||
* just provides default arguments for initRustCrypto()
|
* just provides default arguments for initRustCrypto()
|
||||||
@ -1051,7 +1049,16 @@ async function makeTestRustCrypto(
|
|||||||
secretStorage: ServerSideSecretStorage = {} as ServerSideSecretStorage,
|
secretStorage: ServerSideSecretStorage = {} as ServerSideSecretStorage,
|
||||||
cryptoCallbacks: CryptoCallbacks = {} as CryptoCallbacks,
|
cryptoCallbacks: CryptoCallbacks = {} as CryptoCallbacks,
|
||||||
): Promise<RustCrypto> {
|
): Promise<RustCrypto> {
|
||||||
return await initRustCrypto(logger, http, userId, deviceId, secretStorage, cryptoCallbacks, null, undefined);
|
return await initRustCrypto({
|
||||||
|
logger,
|
||||||
|
http,
|
||||||
|
userId,
|
||||||
|
deviceId,
|
||||||
|
secretStorage,
|
||||||
|
cryptoCallbacks,
|
||||||
|
storePrefix: null,
|
||||||
|
storePassphrase: undefined,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** emulate account data, storing in memory
|
/** emulate account data, storing in memory
|
||||||
|
@ -2316,17 +2316,19 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
// importing rust-crypto will download the webassembly, so we delay it until we know it will be
|
// importing rust-crypto will download the webassembly, so we delay it until we know it will be
|
||||||
// needed.
|
// needed.
|
||||||
|
this.logger.debug("Downloading Rust crypto library");
|
||||||
const RustCrypto = await import("./rust-crypto");
|
const RustCrypto = await import("./rust-crypto");
|
||||||
const rustCrypto = await RustCrypto.initRustCrypto(
|
|
||||||
this.logger,
|
const rustCrypto = await RustCrypto.initRustCrypto({
|
||||||
this.http,
|
logger: this.logger,
|
||||||
userId,
|
http: this.http,
|
||||||
deviceId,
|
userId: userId,
|
||||||
this.secretStorage,
|
deviceId: deviceId,
|
||||||
this.cryptoCallbacks,
|
secretStorage: this.secretStorage,
|
||||||
useIndexedDB ? RUST_SDK_STORE_PREFIX : null,
|
cryptoCallbacks: this.cryptoCallbacks,
|
||||||
this.pickleKey,
|
storePrefix: useIndexedDB ? RUST_SDK_STORE_PREFIX : null,
|
||||||
);
|
storePassphrase: this.pickleKey,
|
||||||
|
});
|
||||||
rustCrypto.setSupportedVerificationMethods(this.verificationMethods);
|
rustCrypto.setSupportedVerificationMethods(this.verificationMethods);
|
||||||
|
|
||||||
this.cryptoBackend = rustCrypto;
|
this.cryptoBackend = rustCrypto;
|
||||||
|
@ -35,6 +35,7 @@ import { sleep } from "../utils";
|
|||||||
import { BackupDecryptor } from "../common-crypto/CryptoBackend";
|
import { BackupDecryptor } from "../common-crypto/CryptoBackend";
|
||||||
import { IEncryptedPayload } from "../crypto/aes";
|
import { IEncryptedPayload } from "../crypto/aes";
|
||||||
import { ImportRoomKeyProgressData, ImportRoomKeysOpts } from "../crypto-api";
|
import { ImportRoomKeyProgressData, ImportRoomKeysOpts } from "../crypto-api";
|
||||||
|
import { IKeyBackupInfo } from "../crypto/keybackup";
|
||||||
|
|
||||||
/** Authentification of the backup info, depends on algorithm */
|
/** Authentification of the backup info, depends on algorithm */
|
||||||
type AuthData = KeyBackupInfo["auth_data"];
|
type AuthData = KeyBackupInfo["auth_data"];
|
||||||
@ -399,23 +400,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
|
|||||||
* @returns Information object from API or null if there is no active backup.
|
* @returns Information object from API or null if there is no active backup.
|
||||||
*/
|
*/
|
||||||
public async requestKeyBackupVersion(): Promise<KeyBackupInfo | null> {
|
public async requestKeyBackupVersion(): Promise<KeyBackupInfo | null> {
|
||||||
try {
|
return await requestKeyBackupVersion(this.http);
|
||||||
return await this.http.authedRequest<KeyBackupInfo>(
|
|
||||||
Method.Get,
|
|
||||||
"/room_keys/version",
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
{
|
|
||||||
prefix: ClientPrefix.V3,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
if ((<MatrixError>e).errcode === "M_NOT_FOUND") {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -567,6 +552,22 @@ export class RustBackupDecryptor implements BackupDecryptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function requestKeyBackupVersion(
|
||||||
|
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
|
||||||
|
): Promise<IKeyBackupInfo | null> {
|
||||||
|
try {
|
||||||
|
return await http.authedRequest<KeyBackupInfo>(Method.Get, "/room_keys/version", undefined, undefined, {
|
||||||
|
prefix: ClientPrefix.V3,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if ((<MatrixError>e).errcode === "M_NOT_FOUND") {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type RustBackupCryptoEvents =
|
export type RustBackupCryptoEvents =
|
||||||
| CryptoEvent.KeyBackupStatus
|
| CryptoEvent.KeyBackupStatus
|
||||||
| CryptoEvent.KeyBackupSessionsRemaining
|
| CryptoEvent.KeyBackupSessionsRemaining
|
||||||
|
@ -25,22 +25,70 @@ import { Logger } from "../logger";
|
|||||||
/**
|
/**
|
||||||
* Create a new `RustCrypto` implementation
|
* Create a new `RustCrypto` implementation
|
||||||
*
|
*
|
||||||
* @param logger - A `Logger` instance that will be used for debug output.
|
* @param args - Parameter object
|
||||||
* @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.
|
|
||||||
* @param cryptoCallbacks - Crypto callbacks provided by the application
|
|
||||||
* @param storePrefix - the prefix to use on the indexeddbs created by rust-crypto.
|
|
||||||
* If `null`, a memory store will be used.
|
|
||||||
* @param storePassphrase - a passphrase to use to encrypt the indexeddbs created by rust-crypto.
|
|
||||||
* Ignored if `storePrefix` is null. If this is `undefined` (and `storePrefix` is not null), the indexeddbs
|
|
||||||
* will be unencrypted.
|
|
||||||
*
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function initRustCrypto(
|
export async function initRustCrypto(args: {
|
||||||
|
/** A `Logger` instance that will be used for debug output. */
|
||||||
|
logger: Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
|
||||||
|
* We expect it to set the access token, etc.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
/** Crypto callbacks provided by the application. */
|
||||||
|
cryptoCallbacks: ICryptoCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix to use on the indexeddbs created by rust-crypto.
|
||||||
|
* If `null`, a memory store will be used.
|
||||||
|
*/
|
||||||
|
storePrefix: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A passphrase to use to encrypt the indexeddbs created by rust-crypto.
|
||||||
|
*
|
||||||
|
* Ignored if `storePrefix` is null. If this is `undefined` (and `storePrefix` is not null), the indexeddbs
|
||||||
|
* will be unencrypted.
|
||||||
|
*/
|
||||||
|
storePassphrase?: string;
|
||||||
|
}): Promise<RustCrypto> {
|
||||||
|
const { logger } = args;
|
||||||
|
|
||||||
|
// initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done
|
||||||
|
logger.debug("Initialising Rust crypto-sdk WASM artifact");
|
||||||
|
await RustSdkCryptoJs.initAsync();
|
||||||
|
|
||||||
|
// enable tracing in the rust-sdk
|
||||||
|
new RustSdkCryptoJs.Tracing(RustSdkCryptoJs.LoggerLevel.Debug).turnOn();
|
||||||
|
|
||||||
|
const rustCrypto = await initOlmMachine(
|
||||||
|
logger,
|
||||||
|
args.http,
|
||||||
|
args.userId,
|
||||||
|
args.deviceId,
|
||||||
|
args.secretStorage,
|
||||||
|
args.cryptoCallbacks,
|
||||||
|
args.storePrefix,
|
||||||
|
args.storePassphrase,
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.debug("Completed rust crypto-sdk setup");
|
||||||
|
return rustCrypto;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initOlmMachine(
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
|
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
|
||||||
userId: string,
|
userId: string,
|
||||||
@ -50,20 +98,10 @@ export async function initRustCrypto(
|
|||||||
storePrefix: string | null,
|
storePrefix: string | null,
|
||||||
storePassphrase: string | undefined,
|
storePassphrase: string | undefined,
|
||||||
): Promise<RustCrypto> {
|
): Promise<RustCrypto> {
|
||||||
// initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done
|
logger.debug("Init OlmMachine");
|
||||||
await RustSdkCryptoJs.initAsync();
|
|
||||||
|
|
||||||
// enable tracing in the rust-sdk
|
|
||||||
new RustSdkCryptoJs.Tracing(RustSdkCryptoJs.LoggerLevel.Debug).turnOn();
|
|
||||||
|
|
||||||
const u = new RustSdkCryptoJs.UserId(userId);
|
|
||||||
const d = new RustSdkCryptoJs.DeviceId(deviceId);
|
|
||||||
logger.info("Init OlmMachine");
|
|
||||||
|
|
||||||
// TODO: use the pickle key for the passphrase
|
|
||||||
const olmMachine = await RustSdkCryptoJs.OlmMachine.initialize(
|
const olmMachine = await RustSdkCryptoJs.OlmMachine.initialize(
|
||||||
u,
|
new RustSdkCryptoJs.UserId(userId),
|
||||||
d,
|
new RustSdkCryptoJs.DeviceId(deviceId),
|
||||||
storePrefix ?? undefined,
|
storePrefix ?? undefined,
|
||||||
(storePrefix && storePassphrase) ?? undefined,
|
(storePrefix && storePassphrase) ?? undefined,
|
||||||
);
|
);
|
||||||
@ -101,6 +139,5 @@ export async function initRustCrypto(
|
|||||||
// XXX: find a less hacky way to do this.
|
// XXX: find a less hacky way to do this.
|
||||||
await olmMachine.outgoingRequests();
|
await olmMachine.outgoingRequests();
|
||||||
|
|
||||||
logger.info("Completed rust crypto-sdk setup");
|
|
||||||
return rustCrypto;
|
return rustCrypto;
|
||||||
}
|
}
|
||||||
|
@ -315,18 +315,8 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
* Implementation of {@link CryptoApi#getOwnDeviceKeys}.
|
* Implementation of {@link CryptoApi#getOwnDeviceKeys}.
|
||||||
*/
|
*/
|
||||||
public async getOwnDeviceKeys(): Promise<OwnDeviceKeys> {
|
public async getOwnDeviceKeys(): Promise<OwnDeviceKeys> {
|
||||||
const device: RustSdkCryptoJs.Device = await this.olmMachine.getDevice(
|
const keys = this.olmMachine.identityKeys;
|
||||||
this.olmMachine.userId,
|
return { ed25519: keys.ed25519.toBase64(), curve25519: keys.curve25519.toBase64() };
|
||||||
this.olmMachine.deviceId,
|
|
||||||
);
|
|
||||||
// could be undefined if there is no such algorithm for that device.
|
|
||||||
if (device.curve25519Key && device.ed25519Key) {
|
|
||||||
return {
|
|
||||||
ed25519: device.ed25519Key.toBase64(),
|
|
||||||
curve25519: device.curve25519Key.toBase64(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw new Error("Device keys not found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareToEncrypt(room: Room): void {
|
public prepareToEncrypt(room: Room): void {
|
||||||
|
Reference in New Issue
Block a user