sign device or user when mac check out during sas

This commit is contained in:
Bruno Windels 2023-03-30 14:39:39 +02:00
parent 51c3e3104f
commit 74fe7427af
4 changed files with 22 additions and 8 deletions

View File

@ -202,6 +202,7 @@ export class CrossSigning {
deviceTracker: this.deviceTracker, deviceTracker: this.deviceTracker,
hsApi: this.hsApi, hsApi: this.hsApi,
clock: this.platform.clock, clock: this.platform.clock,
crossSigning: this,
}); });
return this.sasVerificationInProgress; return this.sasVerificationInProgress;
} }

View File

@ -29,6 +29,7 @@ import {SelectVerificationMethodStage} from "./stages/SelectVerificationMethodSt
import {VerificationCancelledError} from "./VerificationCancelledError"; import {VerificationCancelledError} from "./VerificationCancelledError";
import {EventEmitter} from "../../../utils/EventEmitter"; import {EventEmitter} from "../../../utils/EventEmitter";
import {SASProgressEvents} from "./types"; import {SASProgressEvents} from "./types";
import type {CrossSigning} from "../CrossSigning";
type Olm = typeof OlmNamespace; type Olm = typeof OlmNamespace;
@ -44,6 +45,7 @@ type Options = {
deviceTracker: DeviceTracker; deviceTracker: DeviceTracker;
hsApi: HomeServerApi; hsApi: HomeServerApi;
clock: Clock; clock: Clock;
crossSigning: CrossSigning
} }
export class SASVerification extends EventEmitter<SASProgressEvents> { export class SASVerification extends EventEmitter<SASProgressEvents> {
@ -60,7 +62,7 @@ export class SASVerification extends EventEmitter<SASProgressEvents> {
this.olmSas = olmSas; this.olmSas = olmSas;
this.channel = channel; this.channel = channel;
this.setupCancelAfterTimeout(clock); this.setupCancelAfterTimeout(clock);
const stageOptions = {...options, olmSas, eventEmitter: this}; const stageOptions = {...options, olmSas, eventEmitter: this, crossSigning: options.crossSigning};
if (channel.getReceivedMessage(VerificationEventType.Start)) { if (channel.getReceivedMessage(VerificationEventType.Start)) {
this.startStage = new SelectVerificationMethodStage(stageOptions); this.startStage = new SelectVerificationMethodStage(stageOptions);
} }

View File

@ -16,6 +16,7 @@ limitations under the License.
import type {ILogItem} from "../../../../logging/types"; import type {ILogItem} from "../../../../logging/types";
import type {Account} from "../../../e2ee/Account.js"; import type {Account} from "../../../e2ee/Account.js";
import type {DeviceTracker} from "../../../e2ee/DeviceTracker.js"; import type {DeviceTracker} from "../../../e2ee/DeviceTracker.js";
import type {CrossSigning} from "../../CrossSigning";
import {IChannel} from "../channel/Channel"; import {IChannel} from "../channel/Channel";
import {HomeServerApi} from "../../../net/HomeServerApi"; import {HomeServerApi} from "../../../net/HomeServerApi";
import {SASProgressEvents} from "../types"; import {SASProgressEvents} from "../types";
@ -33,6 +34,7 @@ export type Options = {
deviceTracker: DeviceTracker; deviceTracker: DeviceTracker;
hsApi: HomeServerApi; hsApi: HomeServerApi;
eventEmitter: EventEmitter<SASProgressEvents> eventEmitter: EventEmitter<SASProgressEvents>
crossSigning: CrossSigning
} }
export abstract class BaseSASVerificationStage { export abstract class BaseSASVerificationStage {

View File

@ -21,7 +21,7 @@ import {SendDoneStage} from "./SendDoneStage";
import {KeyUsage, getKeyEd25519Key} from "../../CrossSigning"; import {KeyUsage, getKeyEd25519Key} from "../../CrossSigning";
import {getDeviceEd25519Key} from "../../../e2ee/common"; 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 { export class VerifyMacStage extends BaseSASVerificationStage {
async completeStage() { async completeStage() {
@ -54,11 +54,12 @@ export class VerifyMacStage extends BaseSASVerificationStage {
await this.verifyKeys(content.mac, (keyId, key, keyInfo) => { await this.verifyKeys(content.mac, (keyId, key, keyInfo) => {
const calculatedMAC = calculateMAC(key, baseInfo + keyId, log); 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 }); log.log({ l: "Mac verification failed for key", keyMac: keyInfo, calculatedMAC, keyId, key });
this.channel.cancelVerification(CancelReason.KeyMismatch); this.channel.cancelVerification(CancelReason.KeyMismatch);
return;
} }
return matches;
}, log); }, log);
} }
@ -68,8 +69,12 @@ export class VerifyMacStage extends BaseSASVerificationStage {
const deviceIdOrMSK = keyId.split(":", 2)[1]; const deviceIdOrMSK = keyId.split(":", 2)[1];
const device = await this.deviceTracker.deviceForId(userId, deviceIdOrMSK, this.hsApi, log); const device = await this.deviceTracker.deviceForId(userId, deviceIdOrMSK, this.hsApi, log);
if (device) { if (device) {
verifier(keyId, getDeviceEd25519Key(device), keyInfo); if (verifier(keyId, getDeviceEd25519Key(device), keyInfo)) {
// todo: mark device as verified here await log.wrap("signing device", async log => {
const signedKey = await this.options.crossSigning.signDevice(device.device_id, log);
log.set("success", !!signedKey);
});
}
} else { } else {
// If we were not able to find the device, then deviceIdOrMSK is actually the MSK! // 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); 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!"); throw new Error("Fetching MSK for user failed!");
} }
const masterKey = getKeyEd25519Key(key); const masterKey = getKeyEd25519Key(key);
verifier(keyId, masterKey, keyInfo); if(masterKey && verifier(keyId, masterKey, keyInfo)) {
// todo: mark user as verified here await log.wrap("signing user", async log => {
const signedKey = await this.options.crossSigning.signUser(userId, log);
log.set("success", !!signedKey);
});
}
} }
} }
} }