From 74fe7427af784caa9c3976ed3fcd96f4b2ac70ed Mon Sep 17 00:00:00 2001 From: Bruno Windels <274386+bwindels@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:39:39 +0200 Subject: [PATCH] sign device or user when mac check out during sas --- src/matrix/verification/CrossSigning.ts | 1 + .../verification/SAS/SASVerification.ts | 4 +++- .../SAS/stages/BaseSASVerificationStage.ts | 2 ++ .../verification/SAS/stages/VerifyMacStage.ts | 23 +++++++++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/matrix/verification/CrossSigning.ts b/src/matrix/verification/CrossSigning.ts index a6fb3091..d9725c9a 100644 --- a/src/matrix/verification/CrossSigning.ts +++ b/src/matrix/verification/CrossSigning.ts @@ -202,6 +202,7 @@ export class CrossSigning { deviceTracker: this.deviceTracker, hsApi: this.hsApi, clock: this.platform.clock, + crossSigning: this, }); return this.sasVerificationInProgress; } diff --git a/src/matrix/verification/SAS/SASVerification.ts b/src/matrix/verification/SAS/SASVerification.ts index fff697f2..14e52007 100644 --- a/src/matrix/verification/SAS/SASVerification.ts +++ b/src/matrix/verification/SAS/SASVerification.ts @@ -29,6 +29,7 @@ import {SelectVerificationMethodStage} from "./stages/SelectVerificationMethodSt import {VerificationCancelledError} from "./VerificationCancelledError"; import {EventEmitter} from "../../../utils/EventEmitter"; import {SASProgressEvents} from "./types"; +import type {CrossSigning} from "../CrossSigning"; type Olm = typeof OlmNamespace; @@ -44,6 +45,7 @@ type Options = { deviceTracker: DeviceTracker; hsApi: HomeServerApi; clock: Clock; + crossSigning: CrossSigning } export class SASVerification extends EventEmitter { @@ -60,7 +62,7 @@ export class SASVerification extends EventEmitter { this.olmSas = olmSas; this.channel = channel; this.setupCancelAfterTimeout(clock); - const stageOptions = {...options, olmSas, eventEmitter: this}; + const stageOptions = {...options, olmSas, eventEmitter: this, crossSigning: options.crossSigning}; if (channel.getReceivedMessage(VerificationEventType.Start)) { this.startStage = new SelectVerificationMethodStage(stageOptions); } diff --git a/src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts b/src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts index 0eb26a02..1c2506e0 100644 --- a/src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts +++ b/src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts @@ -16,6 +16,7 @@ limitations under the License. import type {ILogItem} from "../../../../logging/types"; import type {Account} from "../../../e2ee/Account.js"; import type {DeviceTracker} from "../../../e2ee/DeviceTracker.js"; +import type {CrossSigning} from "../../CrossSigning"; import {IChannel} from "../channel/Channel"; import {HomeServerApi} from "../../../net/HomeServerApi"; import {SASProgressEvents} from "../types"; @@ -33,6 +34,7 @@ export type Options = { deviceTracker: DeviceTracker; hsApi: HomeServerApi; eventEmitter: EventEmitter + crossSigning: CrossSigning } export abstract class BaseSASVerificationStage { diff --git a/src/matrix/verification/SAS/stages/VerifyMacStage.ts b/src/matrix/verification/SAS/stages/VerifyMacStage.ts index 6d635cce..7fa66cc5 100644 --- a/src/matrix/verification/SAS/stages/VerifyMacStage.ts +++ b/src/matrix/verification/SAS/stages/VerifyMacStage.ts @@ -21,7 +21,7 @@ import {SendDoneStage} from "./SendDoneStage"; import {KeyUsage, getKeyEd25519Key} from "../../CrossSigning"; import {getDeviceEd25519Key} from "../../../e2ee/common"; -export type KeyVerifier = (keyId: string, device: any, keyInfo: string) => void; +export type KeyVerifier = (keyId: string, publicKey: string, keyInfo: string) => boolean; export class VerifyMacStage extends BaseSASVerificationStage { async completeStage() { @@ -54,11 +54,12 @@ export class VerifyMacStage extends BaseSASVerificationStage { await this.verifyKeys(content.mac, (keyId, key, keyInfo) => { const calculatedMAC = calculateMAC(key, baseInfo + keyId, log); - if (keyInfo !== calculatedMAC) { + const matches = keyInfo === calculatedMAC; + if (!matches) { log.log({ l: "Mac verification failed for key", keyMac: keyInfo, calculatedMAC, keyId, key }); this.channel.cancelVerification(CancelReason.KeyMismatch); - return; } + return matches; }, log); } @@ -68,8 +69,12 @@ export class VerifyMacStage extends BaseSASVerificationStage { const deviceIdOrMSK = keyId.split(":", 2)[1]; const device = await this.deviceTracker.deviceForId(userId, deviceIdOrMSK, this.hsApi, log); if (device) { - verifier(keyId, getDeviceEd25519Key(device), keyInfo); - // todo: mark device as verified here + if (verifier(keyId, getDeviceEd25519Key(device), keyInfo)) { + await log.wrap("signing device", async log => { + const signedKey = await this.options.crossSigning.signDevice(device.device_id, log); + log.set("success", !!signedKey); + }); + } } else { // If we were not able to find the device, then deviceIdOrMSK is actually the MSK! const key = await this.deviceTracker.getCrossSigningKeyForUser(userId, KeyUsage.Master, this.hsApi, log); @@ -78,8 +83,12 @@ export class VerifyMacStage extends BaseSASVerificationStage { throw new Error("Fetching MSK for user failed!"); } const masterKey = getKeyEd25519Key(key); - verifier(keyId, masterKey, keyInfo); - // todo: mark user as verified here + if(masterKey && verifier(keyId, masterKey, keyInfo)) { + await log.wrap("signing user", async log => { + const signedKey = await this.options.crossSigning.signUser(userId, log); + log.set("success", !!signedKey); + }); + } } } }