From be3fb0f917da9a5ff76e1c9d020266da81598a2e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 20 Jun 2017 11:41:52 +0100 Subject: [PATCH] Make a start on a unit test for megolm alg impl not much here yet, but it's a start at least. --- spec/unit/crypto/algorithms/megolm.spec.js | 109 +++++++++++++++++++++ src/crypto/algorithms/megolm.js | 7 +- 2 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 spec/unit/crypto/algorithms/megolm.spec.js diff --git a/spec/unit/crypto/algorithms/megolm.spec.js b/spec/unit/crypto/algorithms/megolm.spec.js new file mode 100644 index 000000000..d712cc7ba --- /dev/null +++ b/spec/unit/crypto/algorithms/megolm.spec.js @@ -0,0 +1,109 @@ +try { + global.Olm = require('olm'); +} catch (e) { + console.warn("unable to run megolm tests: libolm not available"); +} + +import expect from 'expect'; + +import sdk from '../../../..'; +import algorithms from '../../../../lib/crypto/algorithms'; +import WebStorageSessionStore from '../../../../lib/store/session/webstorage'; +import MockStorageApi from '../../../MockStorageApi'; +import testUtils from '../../../test-utils'; + +// Crypto and OlmDevice won't import unless we have global.Olm +let OlmDevice; +let Crypto; +if (global.Olm) { + OlmDevice = require('../../../../lib/crypto/OlmDevice'); + Crypto = require('../../../../lib/crypto'); +} + +const MatrixEvent = sdk.MatrixEvent; +const MegolmDecryption = algorithms.DECRYPTION_CLASSES['m.megolm.v1.aes-sha2']; + +const ROOM_ID = '!ROOM:ID'; + +describe("MegolmDecryption", function() { + if (!global.Olm) { + console.warn('Not running megolm unit tests: libolm not present'); + return; + } + + let megolmDecryption; + let mockOlmLib; + let mockCrypto; + let mockBaseApis; + + beforeEach(function() { + testUtils.beforeEach(this); // eslint-disable-line no-invalid-this + + mockCrypto = testUtils.mock(Crypto, 'Crypto'); + mockBaseApis = {}; + + const mockStorage = new MockStorageApi(); + const sessionStore = new WebStorageSessionStore(mockStorage); + + const olmDevice = new OlmDevice(sessionStore); + + megolmDecryption = new MegolmDecryption({ + userId: '@user:id', + crypto: mockCrypto, + olmDevice: olmDevice, + baseApis: mockBaseApis, + roomId: ROOM_ID, + }); + + + // we stub out the olm encryption bits + mockOlmLib = {}; + mockOlmLib.ensureOlmSessionsForDevices = expect.createSpy(); + mockOlmLib.encryptMessageForDevice = expect.createSpy(); + megolmDecryption.olmlib = mockOlmLib; + }); + + describe('receives some keys:', function() { + let groupSession; + beforeEach(function() { + groupSession = new global.Olm.OutboundGroupSession(); + groupSession.create(); + + const event = new MatrixEvent({}); + event.setClearData( + { + type: 'm.room_key', + content: { + algorithm: 'm.megolm.v1.aes-sha2', + room_id: ROOM_ID, + session_id: groupSession.session_id(), + session_key: groupSession.session_key(), + }, + }, + "SENDER_CURVE25519", + "SENDER_ED25519", + ); + + megolmDecryption.onRoomKeyEvent(event); + }); + + it('can decrypt an event', function() { + const event = new MatrixEvent({ + type: 'm.room.encrypted', + room_id: ROOM_ID, + content: { + algorithm: 'm.megolm.v1.aes-sha2', + sender_key: "SENDER_CURVE25519", + session_id: groupSession.session_id(), + ciphertext: groupSession.encrypt(JSON.stringify({ + room_id: ROOM_ID, + content: 'testytest', + })), + }, + }); + + megolmDecryption.decryptEvent(event); + expect(event.getContent()).toEqual('testytest'); + }); + }); +}); diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 15bb07d59..9e83f9d9c 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -520,6 +520,9 @@ function MegolmDecryption(params) { // events which we couldn't decrypt due to unknown sessions / indexes: map from // senderKey|sessionId to list of MatrixEvents this._pendingEvents = {}; + + // this gets stubbed out by the unit tests. + this.olmlib = olmlib; } utils.inherits(MegolmDecryption, base.DecryptionAlgorithm); @@ -698,7 +701,7 @@ MegolmDecryption.prototype.shareKeysWithDevice = function(keyRequest) { const deviceInfo = this._crypto.getStoredDevice(userId, deviceId); const body = keyRequest.requestBody; - olmlib.ensureOlmSessionsForDevices( + this.olmlib.ensureOlmSessionsForDevices( this._olmDevice, this._baseApis, { [userId]: [deviceInfo], }, @@ -741,7 +744,7 @@ MegolmDecryption.prototype.shareKeysWithDevice = function(keyRequest) { ciphertext: {}, }; - olmlib.encryptMessageForDevice( + this.olmlib.encryptMessageForDevice( encryptedContent.ciphertext, this._userId, this._deviceId,