1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

move shared secret to QRCodeData

This commit is contained in:
Bruno Windels
2020-03-31 15:47:58 +02:00
parent d7a7100912
commit 2c7ea0606b
2 changed files with 19 additions and 24 deletions

View File

@@ -24,7 +24,7 @@ import {VerificationBase as Base} from "./Base";
import { import {
newKeyMismatchError, newKeyMismatchError,
} from './Error'; } from './Error';
import {decodeBase64} from "../olmlib"; import olmlib from "../olmlib";
export const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1"; export const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1";
export const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1"; export const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1";
@@ -49,8 +49,9 @@ export class ReciprocateQRCode extends Base {
"with this method yet."); "with this method yet.");
} }
const {qrCodeData} = this.request;
// 1. check the secret // 1. check the secret
if (this.startEvent.getContent()['secret'] !== this.request.encodedSharedSecret) { if (this.startEvent.getContent()['secret'] !== qrCodeData.encodedSharedSecret) {
throw newKeyMismatchError(); throw newKeyMismatchError();
} }
@@ -64,7 +65,6 @@ export class ReciprocateQRCode extends Base {
}); });
const keys = {}; const keys = {};
const {qrCodeData} = this.request;
if (qrCodeData.mode === MODE_VERIFY_OTHER_USER) { if (qrCodeData.mode === MODE_VERIFY_OTHER_USER) {
// add master key to keys to be signed, only if we're not doing self-verification // add master key to keys to be signed, only if we're not doing self-verification
const masterKey = qrCodeData.otherUserMasterKey; const masterKey = qrCodeData.otherUserMasterKey;
@@ -107,6 +107,7 @@ const MODE_VERIFY_SELF_UNTRUSTED = 0x02; // We do not trust the master key
export class QRCodeData { export class QRCodeData {
constructor(request, client) { constructor(request, client) {
this._sharedSecret = QRCodeData._generateSharedSecret();
this._mode = QRCodeData._determineMode(request, client); this._mode = QRCodeData._determineMode(request, client);
this._otherUserMasterKey = null; this._otherUserMasterKey = null;
this._otherDeviceKey = null; this._otherDeviceKey = null;
@@ -137,6 +138,19 @@ export class QRCodeData {
return this._otherUserMasterKey; return this._otherUserMasterKey;
} }
/**
* The unpadded base64 encoded shared secret.
*/
get encodedSharedSecret() {
return this._sharedSecret;
}
static _generateSharedSecret() {
const secretBytes = new Uint8Array(8);
global.crypto.getRandomValues(secretBytes);
this._sharedSecret = olmlib.encodeUnpaddedBase64(secretBytes);
}
static _getOtherDeviceKey(request, client) { static _getOtherDeviceKey(request, client) {
const myUserId = client.getUserId(); const myUserId = client.getUserId();
const myDevices = client.getStoredDevicesForUser(myUserId) || []; const myDevices = client.getStoredDevicesForUser(myUserId) || [];
@@ -173,7 +187,7 @@ export class QRCodeData {
transactionId, transactionId,
firstKeyB64: '', // worked out shortly firstKeyB64: '', // worked out shortly
secondKeyB64: '', // worked out shortly secondKeyB64: '', // worked out shortly
secretB64: request.encodedSharedSecret, secretB64: this.encodedSharedSecret,
}; };
const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId); const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);
@@ -216,7 +230,7 @@ export class QRCodeData {
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);
}; };
const appendEncBase64 = (b64: string) => { const appendEncBase64 = (b64: string) => {
const b = decodeBase64(b64); const b = olmlib.decodeBase64(b64);
const tmpBuf = Buffer.from(b); const tmpBuf = Buffer.from(b);
buf = Buffer.concat([buf, tmpBuf]); buf = Buffer.concat([buf, tmpBuf]);
}; };

View File

@@ -23,7 +23,6 @@ import {
newUnexpectedMessageError, newUnexpectedMessageError,
newUnknownMethodError, newUnknownMethodError,
} from "../Error"; } from "../Error";
import * as olmlib from "../../olmlib";
import {QRCodeData, SCAN_QR_CODE_METHOD} from "../QRCode"; import {QRCodeData, SCAN_QR_CODE_METHOD} from "../QRCode";
// the recommended amount of time before a verification request // the recommended amount of time before a verification request
@@ -71,7 +70,6 @@ export class VerificationRequest extends EventEmitter {
this._eventsByThem = new Map(); this._eventsByThem = new Map();
this._observeOnly = false; this._observeOnly = false;
this._timeoutTimer = null; this._timeoutTimer = null;
this._sharedSecret = null; // used for QR codes
this._accepting = false; this._accepting = false;
this._declining = false; this._declining = false;
this._verifierHasFinished = false; this._verifierHasFinished = false;
@@ -209,7 +207,6 @@ export class VerificationRequest extends EventEmitter {
/** Only set after a .ready if the other party can scan a QR code */ /** Only set after a .ready if the other party can scan a QR code */
get qrCodeData() { get qrCodeData() {
// TODO, merge encodedSharedSecret in here as well
return this._qrCodeData; return this._qrCodeData;
} }
@@ -327,14 +324,6 @@ export class VerificationRequest extends EventEmitter {
return this._observeOnly; return this._observeOnly;
} }
/**
* The unpadded base64 encoded shared secret. Primarily used for QR code
* verification.
*/
get encodedSharedSecret() {
if (!this._sharedSecret) this._generateSharedSecret();
return this._sharedSecret;
}
/** /**
* Gets which device the verification should be started with * Gets which device the verification should be started with
@@ -394,7 +383,6 @@ export class VerificationRequest extends EventEmitter {
if (!this.observeOnly && this._phase === PHASE_UNSENT) { if (!this.observeOnly && this._phase === PHASE_UNSENT) {
const methods = [...this._verificationMethods.keys()]; const methods = [...this._verificationMethods.keys()];
await this.channel.send(REQUEST_TYPE, {methods}); await this.channel.send(REQUEST_TYPE, {methods});
this._generateSharedSecret();
} }
} }
@@ -427,16 +415,9 @@ export class VerificationRequest extends EventEmitter {
this._accepting = true; this._accepting = true;
this.emit("change"); this.emit("change");
await this.channel.send(READY_TYPE, {methods}); await this.channel.send(READY_TYPE, {methods});
this._generateSharedSecret();
} }
} }
_generateSharedSecret() {
const secretBytes = new Uint8Array(8);
global.crypto.getRandomValues(secretBytes);
this._sharedSecret = olmlib.encodeUnpaddedBase64(secretBytes);
}
/** /**
* Can be used to listen for state changes until the callback returns true. * Can be used to listen for state changes until the callback returns true.
* @param {Function} fn callback to evaluate whether the request is in the desired state. * @param {Function} fn callback to evaluate whether the request is in the desired state.