From ae61b8fcf7cf0f69a93ceca12e004022808d6388 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 4 Aug 2023 17:21:43 -0400 Subject: [PATCH] Put auth_data signature in correct place Also add/tweak some utility types to help with this --- src/MatrixClient.ts | 14 +++++++++----- src/helpers/Types.ts | 5 +++++ src/models/Crypto.ts | 14 ++++++++++---- src/models/KeyBackup.ts | 29 +++++++++++++++++++---------- 4 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 src/helpers/Types.ts diff --git a/src/MatrixClient.ts b/src/MatrixClient.ts index 68a1d91e..50bf7d66 100644 --- a/src/MatrixClient.ts +++ b/src/MatrixClient.ts @@ -44,7 +44,7 @@ import { DMs } from "./DMs"; import { ServerVersions } from "./models/ServerVersions"; import { RoomCreateOptions } from "./models/CreateRoom"; import { PresenceState } from './models/events/PresenceEvent'; -import { IKeyBackupInfo, IKeyBackupInfoRetrieved, IKeyBackupInfoUpdate, IKeyBackupVersion, KeyBackupVersion } from "./models/KeyBackup"; +import { IKeyBackupInfo, IKeyBackupInfoRetrieved, IKeyBackupInfoUnsigned, IKeyBackupInfoUpdate, IKeyBackupVersion, KeyBackupVersion } from "./models/KeyBackup"; import { MatrixError } from "./models/MatrixError"; const SYNC_BACKOFF_MIN_MS = 5000; @@ -1983,17 +1983,21 @@ export class MatrixClient extends EventEmitter { /** * Create a new room key backup. - * @param {IKeyBackupInfo} info The properties of the key backup to create. + * @param {IKeyBackupInfoUnsigned} info The properties of the key backup to create, + * with its auth_data left unsigned. * @returns {Promise} Resolves to the version id of the new backup. */ - public createKeyBackupVersion(info: IKeyBackupInfo): Promise { + public async signAndCreateKeyBackupVersion(info: IKeyBackupInfoUnsigned): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } - const data = { + const data: IKeyBackupInfo = { ...info, - signatures: this.crypto.sign(info), + auth_data: { + ...info.auth_data, + signatures: await this.crypto.sign(info), + } }; return this.doRequest("POST", "/_matrix/client/v3/room_keys/version", null, data); } diff --git a/src/helpers/Types.ts b/src/helpers/Types.ts new file mode 100644 index 00000000..14a717b5 --- /dev/null +++ b/src/helpers/Types.ts @@ -0,0 +1,5 @@ +export type Json = string | number | boolean | null | undefined | Json[] | { [key: string]: Json }; + +export interface IJsonType { + [key: string]: Json; +} diff --git a/src/models/Crypto.ts b/src/models/Crypto.ts index 9269a95f..af945641 100644 --- a/src/models/Crypto.ts +++ b/src/models/Crypto.ts @@ -23,13 +23,20 @@ export interface Signatures { }; } +/** + * Interface that can be extended by + * any object that needs a signature. + */ +export interface Signed { + signatures: Signatures; +} + /** * A signed_curve25519 one time key. * @category Models */ -export interface SignedCurve25519OTK { +export interface SignedCurve25519OTK extends Signed { key: string; - signatures: Signatures; fallback?: boolean; } @@ -89,12 +96,11 @@ export type DeviceKeyLabel, string>; - signatures: Signatures; unsigned?: { [k: string]: any; device_display_name?: string; diff --git a/src/models/KeyBackup.ts b/src/models/KeyBackup.ts index a8c8eb61..3b946257 100644 --- a/src/models/KeyBackup.ts +++ b/src/models/KeyBackup.ts @@ -1,4 +1,5 @@ -import { Signatures } from "./Crypto"; +import { IJsonType } from "../helpers/Types"; +import { Signed } from "./Crypto"; /** * The kinds of key backup encryption algorithms allowed by the spec. @@ -8,14 +9,28 @@ export enum KeyBackupEncryptionAlgorithm { MegolmBackupV1Curve25519AesSha2 = "m.megolm_backup.v1.curve25519-aes-sha2", } +export interface ICurve25519AuthDataUnsigned { + public_key: string; +} +export type ICurve25519AuthData = ICurve25519AuthDataUnsigned & Signed; + /** - * Information about a server-side key backup. + * Information about a server-side key backup, + * with its auth_data left unsigned. */ -export interface IKeyBackupInfo { +export interface IKeyBackupInfoUnsigned { algorithm: string | KeyBackupEncryptionAlgorithm; - auth_data: object; + auth_data: IJsonType | ICurve25519AuthDataUnsigned; } +/** + * Information about a server-side key backup, + * with its auth_data signed by the entity that created it. + */ +export type IKeyBackupInfo = IKeyBackupInfoUnsigned & { + auth_data: Signed & IKeyBackupInfoUnsigned["auth_data"]; +}; + export type KeyBackupVersion = string; export interface IKeyBackupVersion { @@ -28,9 +43,3 @@ export interface IKeyBackupInfoRetrieved extends IKeyBackupInfo, IKeyBackupVersi } export type IKeyBackupInfoUpdate = IKeyBackupInfo & Partial; - -export interface ICurve25519AuthDataUnsigned { - public_key: string; -} - -export type ICurve25519AuthData = ICurve25519AuthDataUnsigned & Signatures;