From 48d9d9b4c9c34f7921120b5e6e233225d5faead3 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 29 Nov 2023 18:54:06 +0100 Subject: [PATCH] move get device key API from client to crypto (#3899) MatrixClient API was exposing two methods that only worked for legacy crypto: - getDeviceEd25519Key - getDeviceCurve25519Key => These are used in the react-sdk for some functionality (rageshake, sentry, rendez-vous). I have deprecated those calls from MatrixClient and created a new API in CryptoApi (where it belongs): getOwnDeviceKeys(): Promise --- spec/integ/crypto/crypto.spec.ts | 13 +++++++++++++ src/client.ts | 4 ++++ src/crypto-api.ts | 15 +++++++++++++++ src/crypto/index.ts | 21 +++++++++++++++++++++ src/rust-crypto/rust-crypto.ts | 19 +++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/spec/integ/crypto/crypto.spec.ts b/spec/integ/crypto/crypto.spec.ts index 09cf2ebfe..1ef22bf57 100644 --- a/spec/integ/crypto/crypto.spec.ts +++ b/spec/integ/crypto/crypto.spec.ts @@ -397,6 +397,19 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string, expect(aliceClient.getCrypto()).toHaveProperty("globalBlacklistUnverifiedDevices"); }); + it("CryptoAPI.getOwnedDeviceKeys returns the correct values", async () => { + const homeserverUrl = aliceClient.getHomeserverUrl(); + + keyResponder = new E2EKeyResponder(homeserverUrl); + await startClientAndAwaitFirstSync(); + keyResponder.addKeyReceiver("@alice:localhost", keyReceiver); + + const deviceKeys = await aliceClient.getCrypto()!.getOwnDeviceKeys(); + + expect(deviceKeys.curve25519).toEqual(keyReceiver.getDeviceKey()); + expect(deviceKeys.ed25519).toEqual(keyReceiver.getSigningKey()); + }); + it("Alice receives a megolm message", async () => { expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} }); await startClientAndAwaitFirstSync(); diff --git a/src/client.ts b/src/client.ts index 5d436a1fc..4121314ec 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2393,6 +2393,8 @@ export class MatrixClient extends TypedEventEmitter; + /** * Perform any background tasks that can be done before a message is ready to * send, in order to speed up sending of the message. @@ -764,5 +771,13 @@ export enum EventShieldReason { MISMATCHED_SENDER_KEY, } +/** The result of a call to {@link CryptoApi.getOwnDeviceKeys} */ +export interface OwnDeviceKeys { + /** Public part of the Ed25519 fingerprint key for the current device, base64 encoded. */ + ed25519: string; + /** Public part of the Curve25519 identity key for the current device, base64 encoded. */ + curve25519: string; +} + export * from "./crypto-api/verification"; export * from "./crypto-api/keybackup"; diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 7bf98139d..1d3dc855f 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -98,6 +98,7 @@ import { KeyBackupCheck, KeyBackupInfo, VerificationRequest as CryptoApiVerificationRequest, + OwnDeviceKeys, } from "../crypto-api"; import { Device, DeviceMap } from "../models/device"; import { deviceInfoToDevice } from "./device-converter"; @@ -1968,6 +1969,8 @@ export class Crypto extends TypedEventEmitter { + if (!this.olmDevice.deviceCurve25519Key) { + throw new Error("Curve25519 key not yet created"); + } + if (!this.olmDevice.deviceEd25519Key) { + throw new Error("Ed25519 key not yet created"); + } + return { + ed25519: this.olmDevice.deviceEd25519Key, + curve25519: this.olmDevice.deviceCurve25519Key, + }; + } + /** * Set the global override for whether the client should ever send encrypted * messages to unverified devices. This provides the default for rooms which diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index f4952df73..b16c0c51a 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -49,6 +49,7 @@ import { KeyBackupCheck, KeyBackupInfo, KeyBackupSession, + OwnDeviceKeys, UserVerificationStatus, VerificationRequest, } from "../crypto-api"; @@ -371,6 +372,24 @@ export class RustCrypto extends TypedEventEmitter { + const device: RustSdkCryptoJs.Device = await this.olmMachine.getDevice( + this.olmMachine.userId, + 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 { const encryptor = this.roomEncryptors[room.roomId];