Merge pull request #1066 from vector-im/fix-sas-issues

Fix some SAS issues
This commit is contained in:
Bruno Windels 2023-03-30 12:52:47 +02:00 committed by GitHub
commit 51c3e3104f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 35 deletions

View File

@ -90,6 +90,13 @@ export class DeviceVerificationViewModel extends ErrorReportViewModel<SegmentTyp
this.emitChange("currentStageViewModel");
}
dispose(): void {
if (!this.sas.finished) {
this.sas.abort().catch(() => {/** ignore */});
}
super.dispose();
}
get currentStageViewModel() {
return this._currentStageViewModel;
}

View File

@ -142,7 +142,7 @@ export function tests() {
await olm.init();
const olmUtil = new Olm.Utility();
const e2eeAccount = {
getDeviceKeysToSignWithCrossSigning: () => {
getUnsignedDeviceKey: () => {
return {
keys: {
[`ed25519:${ourDeviceId}`]:

View File

@ -6,6 +6,7 @@ import {CancelReason, VerificationEventType} from "./types";
import {getKeyEd25519Key} from "../../CrossSigning";
import {getDeviceEd25519Key} from "../../../e2ee/common";
import anotherjson from "another-json";
import {NullLogger} from "../../../../logging/NullLogger";
interface ITestChannel extends IChannel {
setOlmSas(olmSas): void;
@ -82,31 +83,33 @@ export class MockChannel implements ITestChannel {
private async recalculateMAC() {
// We need to replace the mac with calculated mac
const baseInfo =
"MATRIX_KEY_VERIFICATION_MAC" +
this.otherUserId +
this.otherUserDeviceId +
this.ourUserId +
this.ourUserDeviceId +
this.id;
const { content: macContent } = this.receivedMessages.get(VerificationEventType.Mac);
const macMethod = this.acceptMessage.content.message_authentication_code;
const calculateMac = createCalculateMAC(this.olmSas, macMethod);
const input = Object.keys(macContent.mac).sort().join(",");
const properMac = calculateMac(input, baseInfo + "KEY_IDS");
macContent.keys = properMac;
for (const keyId of Object.keys(macContent.mac)) {
const deviceId = keyId.split(":", 2)[1];
const device = await this.deviceTracker.deviceForId(this.otherUserDeviceId, deviceId);
if (device) {
macContent.mac[keyId] = calculateMac(getDeviceEd25519Key(device), baseInfo + keyId);
await new NullLogger().run("log", async (log) => {
const baseInfo =
"MATRIX_KEY_VERIFICATION_MAC" +
this.otherUserId +
this.otherUserDeviceId +
this.ourUserId +
this.ourUserDeviceId +
this.id;
const { content: macContent } = this.receivedMessages.get(VerificationEventType.Mac);
const macMethod = this.acceptMessage.content.message_authentication_code;
const calculateMac = createCalculateMAC(this.olmSas, macMethod);
const input = Object.keys(macContent.mac).sort().join(",");
const properMac = calculateMac(input, baseInfo + "KEY_IDS", log);
macContent.keys = properMac;
for (const keyId of Object.keys(macContent.mac)) {
const deviceId = keyId.split(":", 2)[1];
const device = await this.deviceTracker.deviceForId(this.otherUserDeviceId, deviceId);
if (device) {
macContent.mac[keyId] = calculateMac(getDeviceEd25519Key(device), baseInfo + keyId, log);
}
else {
const key = await this.deviceTracker.getCrossSigningKeyForUser(this.otherUserId);
const masterKey = getKeyEd25519Key(key)!;
macContent.mac[keyId] = calculateMac(masterKey, baseInfo + keyId, log);
}
}
else {
const key = await this.deviceTracker.getCrossSigningKeyForUser(this.otherUserId);
const masterKey = getKeyEd25519Key(key)!;
macContent.mac[keyId] = calculateMac(masterKey, baseInfo + keyId);
}
}
});
}
setStartMessage(event: any): void {

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import type {ILogItem} from "../../../logging/types";
import type {MacMethod} from "./stages/constants";
const macMethods: Record<MacMethod, string> = {
@ -23,8 +24,10 @@ const macMethods: Record<MacMethod, string> = {
};
export function createCalculateMAC(olmSAS: Olm.SAS, method: MacMethod) {
return function (input: string, info: string): string {
const mac = olmSAS[macMethods[method]](input, info);
return mac;
return function (input: string, info: string, log: ILogItem): string {
return log.wrap({ l: "calculate MAC", method}, () => {
const mac = olmSAS[macMethods[method]](input, info);
return mac;
});
};
}

View File

@ -32,7 +32,7 @@ export class SendMacStage extends BaseSASVerificationStage {
});
}
private async sendMAC(calculateMAC: (input: string, info: string) => string, log: ILogItem): Promise<void> {
private async sendMAC(calculateMAC: (input: string, info: string, log: ILogItem) => string, log: ILogItem): Promise<void> {
const mac: Record<string, string> = {};
const keyList: string[] = [];
const baseInfo =
@ -45,7 +45,7 @@ export class SendMacStage extends BaseSASVerificationStage {
const deviceKeyId = `ed25519:${this.ourUserDeviceId}`;
const deviceKeys = this.e2eeAccount.getUnsignedDeviceKey();
mac[deviceKeyId] = calculateMAC(deviceKeys.keys[deviceKeyId], baseInfo + deviceKeyId);
mac[deviceKeyId] = calculateMAC(deviceKeys.keys[deviceKeyId], baseInfo + deviceKeyId, log);
keyList.push(deviceKeyId);
const key = await this.deviceTracker.getCrossSigningKeyForUser(this.ourUserId, KeyUsage.Master, this.hsApi, log);
@ -56,11 +56,11 @@ export class SendMacStage extends BaseSASVerificationStage {
const crossSigningKey = getKeyEd25519Key(key);
if (crossSigningKey) {
const crossSigningKeyId = `ed25519:${crossSigningKey}`;
mac[crossSigningKeyId] = calculateMAC(crossSigningKey, baseInfo + crossSigningKeyId);
mac[crossSigningKeyId] = calculateMAC(crossSigningKey, baseInfo + crossSigningKeyId, log);
keyList.push(crossSigningKeyId);
}
const keys = calculateMAC(keyList.sort().join(","), baseInfo + "KEY_IDS");
const keys = calculateMAC(keyList.sort().join(","), baseInfo + "KEY_IDS", log);
await this.channel.send(VerificationEventType.Mac, { mac, keys }, log);
}
}

View File

@ -35,7 +35,7 @@ export class VerifyMacStage extends BaseSASVerificationStage {
});
}
private async checkMAC(calculateMAC: (input: string, info: string) => string, log: ILogItem): Promise<void> {
private async checkMAC(calculateMAC: (input: string, info: string, log: ILogItem) => string, log: ILogItem): Promise<void> {
const {content} = this.channel.getReceivedMessage(VerificationEventType.Mac);
const baseInfo =
"MATRIX_KEY_VERIFICATION_MAC" +
@ -45,7 +45,7 @@ export class VerifyMacStage extends BaseSASVerificationStage {
this.ourUserDeviceId +
this.channel.id;
const calculatedMAC = calculateMAC(Object.keys(content.mac).sort().join(","), baseInfo + "KEY_IDS");
const calculatedMAC = calculateMAC(Object.keys(content.mac).sort().join(","), baseInfo + "KEY_IDS", log);
if (content.keys !== calculatedMAC) {
log.log({ l: "MAC verification failed for keys field", keys: content.keys, calculated: calculatedMAC });
this.channel.cancelVerification(CancelReason.KeyMismatch);
@ -53,7 +53,7 @@ export class VerifyMacStage extends BaseSASVerificationStage {
}
await this.verifyKeys(content.mac, (keyId, key, keyInfo) => {
const calculatedMAC = calculateMAC(key, baseInfo + keyId);
const calculatedMAC = calculateMAC(key, baseInfo + keyId, log);
if (keyInfo !== calculatedMAC) {
log.log({ l: "Mac verification failed for key", keyMac: keyInfo, calculatedMAC, keyId, key });
this.channel.cancelVerification(CancelReason.KeyMismatch);