Skip to content

Commit

Permalink
v2 of MSC3903 implementation
Browse files Browse the repository at this point in the history
This is a deliberate breaking change on an unstable feature.
  • Loading branch information
hughns committed Feb 13, 2023
1 parent a063ae8 commit c48e819
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 37 deletions.
26 changes: 13 additions & 13 deletions spec/unit/rendezvous/ecdh.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ limitations under the License.

import "../../olm-loader";
import { RendezvousFailureReason, RendezvousIntent } from "../../../src/rendezvous";
import { MSC3903ECDHPayload, MSC3903ECDHv1RendezvousChannel } from "../../../src/rendezvous/channels";
import { MSC3903ECDHPayload, MSC3903ECDHv2RendezvousChannel } from "../../../src/rendezvous/channels";
import { decodeBase64 } from "../../../src/crypto/olmlib";
import { DummyTransport } from "./DummyTransport";

function makeTransport(name: string) {
return new DummyTransport<any, MSC3903ECDHPayload>(name, { type: "dummy" });
}

describe("ECDHv1", function () {
describe("ECDHv2", function () {
beforeAll(async function () {
await global.Olm.init();
});
Expand All @@ -37,9 +37,9 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);
const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));
const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));

const bobChecksum = await bob.connect();
const aliceChecksum = await alice.connect();
Expand All @@ -62,9 +62,9 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);
const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));
const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));

const bobChecksum = await bob.connect();
const aliceChecksum = await alice.connect();
Expand All @@ -87,9 +87,9 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);
const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));
const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));

const bobChecksum = await bob.connect();
const aliceChecksum = await alice.connect();
Expand All @@ -109,9 +109,9 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);
const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));
const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));

const bobChecksum = await bob.connect();
const aliceChecksum = await alice.connect();
Expand All @@ -135,9 +135,9 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);
const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));
const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key));

const bobChecksum = await bob.connect();
const aliceChecksum = await alice.connect();
Expand All @@ -159,7 +159,7 @@ describe("ECDHv1", function () {
bobTransport.otherParty = aliceTransport;

// alice is signing in initiates and generates a code
const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport);
const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport);
await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE);

await bobTransport.send({ iv: "dummy", ciphertext: "dummy" });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Copyright 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,28 +25,28 @@ import {
RendezvousTransport,
RendezvousFailureReason,
} from "..";
import { encodeBase64, decodeBase64 } from "../../crypto/olmlib";
import { encodeUnpaddedBase64, decodeBase64 } from "../../crypto/olmlib";
import { crypto, subtleCrypto, TextEncoder } from "../../crypto/crypto";
import { generateDecimalSas } from "../../crypto/verification/SASDecimal";
import { UnstableValue } from "../../NamespacedValue";

const ECDH_V1 = new UnstableValue(
"m.rendezvous.v1.curve25519-aes-sha256",
"org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256",
const ECDH = new UnstableValue(
"m.rendezvous.v2.curve25519-aes-sha256",
"org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256",
);

export interface ECDHv1RendezvousCode extends RendezvousCode {
export interface ECDHv2RendezvousCode extends RendezvousCode {
rendezvous: {
transport: RendezvousTransportDetails;
algorithm: typeof ECDH_V1.name | typeof ECDH_V1.altName;
algorithm: typeof ECDH.name | typeof ECDH.altName;
key: string;
};
}

export type MSC3903ECDHPayload = PlainTextPayload | EncryptedPayload;

export interface PlainTextPayload {
algorithm: typeof ECDH_V1.name | typeof ECDH_V1.altName;
algorithm: typeof ECDH.name | typeof ECDH.altName;
key?: string;
}

Expand All @@ -70,7 +70,7 @@ async function importKey(key: Uint8Array): Promise<CryptoKey> {
* X25519/ECDH key agreement based secure rendezvous channel.
* Note that this is UNSTABLE and may have breaking changes without notice.
*/
export class MSC3903ECDHv1RendezvousChannel<T> implements RendezvousChannel<T> {
export class MSC3903ECDHv2RendezvousChannel<T> implements RendezvousChannel<T> {
private olmSAS?: SAS;
private ourPublicKey: Uint8Array;
private aesKey?: CryptoKey;
Expand All @@ -85,17 +85,17 @@ export class MSC3903ECDHv1RendezvousChannel<T> implements RendezvousChannel<T> {
this.ourPublicKey = decodeBase64(this.olmSAS.get_pubkey());
}

public async generateCode(intent: RendezvousIntent): Promise<ECDHv1RendezvousCode> {
public async generateCode(intent: RendezvousIntent): Promise<ECDHv2RendezvousCode> {
if (this.transport.ready) {
throw new Error("Code already generated");
}

await this.transport.send({ algorithm: ECDH_V1.name });
await this.transport.send({ algorithm: ECDH.name });

const rendezvous: ECDHv1RendezvousCode = {
const rendezvous: ECDHv2RendezvousCode = {
rendezvous: {
algorithm: ECDH_V1.name,
key: encodeBase64(this.ourPublicKey),
algorithm: ECDH.name,
key: encodeUnpaddedBase64(this.ourPublicKey),
transport: await this.transport.details(),
},
intent,
Expand Down Expand Up @@ -123,7 +123,7 @@ export class MSC3903ECDHv1RendezvousChannel<T> implements RendezvousChannel<T> {
}
const res = rawRes as Partial<PlainTextPayload>;
const { key, algorithm } = res;
if (!algorithm || !ECDH_V1.matches(algorithm) || !key) {
if (!algorithm || !ECDH.matches(algorithm) || !key) {
throw new RendezvousError(
"Unsupported algorithm: " + algorithm,
RendezvousFailureReason.UnsupportedAlgorithm,
Expand All @@ -134,20 +134,20 @@ export class MSC3903ECDHv1RendezvousChannel<T> implements RendezvousChannel<T> {
} else {
// send our public key unencrypted
await this.transport.send({
algorithm: ECDH_V1.name,
key: encodeBase64(this.ourPublicKey),
algorithm: ECDH.name,
key: encodeUnpaddedBase64(this.ourPublicKey),
});
}

this.connected = true;

this.olmSAS.set_their_key(encodeBase64(this.theirPublicKey!));
this.olmSAS.set_their_key(encodeUnpaddedBase64(this.theirPublicKey!));

const initiatorKey = isInitiator ? this.ourPublicKey : this.theirPublicKey!;
const recipientKey = isInitiator ? this.theirPublicKey! : this.ourPublicKey;
let aesInfo = ECDH_V1.name;
aesInfo += `|${encodeBase64(initiatorKey)}`;
aesInfo += `|${encodeBase64(recipientKey)}`;
let aesInfo = ECDH.name;
aesInfo += `|${encodeUnpaddedBase64(initiatorKey)}`;
aesInfo += `|${encodeUnpaddedBase64(recipientKey)}`;

const aesKeyBytes = this.olmSAS.generate_bytes(aesInfo, 32);

Expand Down Expand Up @@ -181,8 +181,8 @@ export class MSC3903ECDHv1RendezvousChannel<T> implements RendezvousChannel<T> {
);

return {
iv: encodeBase64(iv),
ciphertext: encodeBase64(ciphertext),
iv: encodeUnpaddedBase64(iv),
ciphertext: encodeUnpaddedBase64(ciphertext),
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/rendezvous/channels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

export * from "./MSC3903ECDHv1RendezvousChannel";
export * from "./MSC3903ECDHv2RendezvousChannel";

0 comments on commit c48e819

Please sign in to comment.