You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-29 16:43:09 +03:00
Factor out a function for doing olm encryption
Make a library file with some constants and a function to pack olm-encrypted events (which we are going to use from megolm)
This commit is contained in:
@@ -294,6 +294,22 @@ OlmDevice.prototype.getSessionIdsForDevice = function(theirDeviceIdentityKey) {
|
|||||||
return utils.keys(sessions);
|
return utils.keys(sessions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the right olm session id for encrypting messages to the given identity key
|
||||||
|
*
|
||||||
|
* @param {string} theirDeviceIdentityKey Curve25519 identity key for the
|
||||||
|
* remote device
|
||||||
|
* @return {string?} session id, or null if no established session
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.getSessionIdForDevice = function(theirDeviceIdentityKey) {
|
||||||
|
var sessionIds = this.getSessionIdsForDevice(theirDeviceIdentityKey);
|
||||||
|
if (sessionIds.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Use the session with the lowest ID.
|
||||||
|
sessionIds.sort();
|
||||||
|
return sessionIds[0];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt an outgoing message using an existing session
|
* Encrypt an outgoing message using an existing session
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ limitations under the License.
|
|||||||
var q = require("q");
|
var q = require("q");
|
||||||
|
|
||||||
var utils = require("../utils");
|
var utils = require("../utils");
|
||||||
|
var olmlib = require("../olmlib");
|
||||||
var base = require("./base");
|
var base = require("./base");
|
||||||
|
|
||||||
var MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Megolm encryption implementation
|
* Megolm encryption implementation
|
||||||
*
|
*
|
||||||
@@ -114,7 +113,7 @@ MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var encryptedContent = {
|
var encryptedContent = {
|
||||||
algorithm: MEGOLM_ALGORITHM,
|
algorithm: olmlib.MEGOLM_ALGORITHM,
|
||||||
sender_key: self._olmDevice.deviceCurve25519Key,
|
sender_key: self._olmDevice.deviceCurve25519Key,
|
||||||
body: ciphertext,
|
body: ciphertext,
|
||||||
session_id: self._outboundSessionId,
|
session_id: self._outboundSessionId,
|
||||||
@@ -171,4 +170,6 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
base.registerAlgorithm(MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption);
|
base.registerAlgorithm(
|
||||||
|
olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption
|
||||||
|
);
|
||||||
|
|||||||
@@ -23,11 +23,10 @@ limitations under the License.
|
|||||||
var q = require('q');
|
var q = require('q');
|
||||||
|
|
||||||
var utils = require("../utils");
|
var utils = require("../utils");
|
||||||
|
var olmlib = require("../olmlib");
|
||||||
|
|
||||||
var base = require("./base");
|
var base = require("./base");
|
||||||
|
|
||||||
var OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Olm encryption implementation
|
* Olm encryption implementation
|
||||||
*
|
*
|
||||||
@@ -89,47 +88,27 @@ OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
|||||||
|
|
||||||
for (var keyId in dev.keys) {
|
for (var keyId in dev.keys) {
|
||||||
if (keyId.indexOf("curve25519:") === 0) {
|
if (keyId.indexOf("curve25519:") === 0) {
|
||||||
participantKeys.push(dev.keys[keyId]);
|
var key = dev.keys[keyId];
|
||||||
|
|
||||||
|
// don't send to ourselves.
|
||||||
|
if (key != this._olmDevice.deviceCurve25519Key) {
|
||||||
|
participantKeys.push(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
participantKeys.sort();
|
|
||||||
var participantHash = ""; // Olm.sha256(participantKeys.join());
|
return q(
|
||||||
var payloadJson = {
|
olmlib.encryptMessageForDevices(
|
||||||
room_id: room.roomId,
|
this._deviceId, this._olmDevice, participantKeys, {
|
||||||
type: eventType,
|
room_id: room.roomId,
|
||||||
fingerprint: participantHash,
|
type: eventType,
|
||||||
sender_device: this._deviceId,
|
content: content,
|
||||||
content: content
|
}
|
||||||
};
|
)
|
||||||
var ciphertext = {};
|
);
|
||||||
var payloadString = JSON.stringify(payloadJson);
|
|
||||||
for (i = 0; i < participantKeys.length; ++i) {
|
|
||||||
var deviceKey = participantKeys[i];
|
|
||||||
if (deviceKey == this._olmDevice.deviceCurve25519Key) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var sessionIds = this._olmDevice.getSessionIdsForDevice(deviceKey);
|
|
||||||
// Use the session with the lowest ID.
|
|
||||||
sessionIds.sort();
|
|
||||||
if (sessionIds.length === 0) {
|
|
||||||
// If we don't have a session for a device then
|
|
||||||
// we can't encrypt a message for it.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var sessionId = sessionIds[0];
|
|
||||||
console.log("Using sessionid " + sessionId + " for device " + deviceKey);
|
|
||||||
ciphertext[deviceKey] = this._olmDevice.encryptMessage(
|
|
||||||
deviceKey, sessionId, payloadString
|
|
||||||
);
|
|
||||||
}
|
|
||||||
var encryptedContent = {
|
|
||||||
algorithm: OLM_ALGORITHM,
|
|
||||||
sender_key: this._olmDevice.deviceCurve25519Key,
|
|
||||||
ciphertext: ciphertext
|
|
||||||
};
|
|
||||||
return q(encryptedContent);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,4 +190,4 @@ OlmDecryption.prototype.decryptEvent = function(event) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
base.registerAlgorithm(OLM_ALGORITHM, OlmEncryption, OlmDecryption);
|
base.registerAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption);
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ var anotherjson = require('another-json');
|
|||||||
var q = require("q");
|
var q = require("q");
|
||||||
|
|
||||||
var OlmDevice = require("./OlmDevice");
|
var OlmDevice = require("./OlmDevice");
|
||||||
|
var olmlib = require("./olmlib");
|
||||||
|
|
||||||
var algorithms = require("./crypto-algorithms");
|
var algorithms = require("./crypto-algorithms");
|
||||||
|
|
||||||
var OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2";
|
|
||||||
|
|
||||||
var DeviceInfo = require("./crypto-deviceinfo");
|
var DeviceInfo = require("./crypto-deviceinfo");
|
||||||
var DeviceVerification = DeviceInfo.DeviceVerification;
|
var DeviceVerification = DeviceInfo.DeviceVerification;
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ function Crypto(baseApis, sessionStore, userId, deviceId) {
|
|||||||
// add our own deviceinfo to the sessionstore
|
// add our own deviceinfo to the sessionstore
|
||||||
var deviceInfo = {
|
var deviceInfo = {
|
||||||
keys: this._deviceKeys,
|
keys: this._deviceKeys,
|
||||||
algorithms: [OLM_ALGORITHM],
|
algorithms: [olmlib.OLM_ALGORITHM],
|
||||||
verified: DeviceVerification.VERIFIED,
|
verified: DeviceVerification.VERIFIED,
|
||||||
};
|
};
|
||||||
var myDevices = this._sessionStore.getEndToEndDevicesForUser(
|
var myDevices = this._sessionStore.getEndToEndDevicesForUser(
|
||||||
@@ -122,7 +121,7 @@ function _uploadDeviceKeys(crypto) {
|
|||||||
var deviceId = crypto._deviceId;
|
var deviceId = crypto._deviceId;
|
||||||
|
|
||||||
var deviceKeys = {
|
var deviceKeys = {
|
||||||
algorithms: [OLM_ALGORITHM],
|
algorithms: [olmlib.OLM_ALGORITHM],
|
||||||
device_id: deviceId,
|
device_id: deviceId,
|
||||||
keys: crypto._deviceKeys,
|
keys: crypto._deviceKeys,
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
@@ -411,7 +410,7 @@ Crypto.prototype.listDeviceKeys = function(userId) {
|
|||||||
* @return {module:crypto-deviceinfo?}
|
* @return {module:crypto-deviceinfo?}
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.getDeviceByIdentityKey = function(userId, algorithm, sender_key) {
|
Crypto.prototype.getDeviceByIdentityKey = function(userId, algorithm, sender_key) {
|
||||||
if (algorithm !== OLM_ALGORITHM) {
|
if (algorithm !== olmlib.OLM_ALGORITHM) {
|
||||||
// we only deal in olm keys
|
// we only deal in olm keys
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
78
lib/olmlib.js
Normal file
78
lib/olmlib.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 OpenMarket Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @module olmlib
|
||||||
|
*
|
||||||
|
* Utilities common to olm encryption algorithms
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require("./utils");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matrix algorithm tag for olm
|
||||||
|
*/
|
||||||
|
module.exports.OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* matrix algorithm tag for megolm
|
||||||
|
*/
|
||||||
|
module.exports.MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an event payload for a list of devices
|
||||||
|
*
|
||||||
|
* @param {string} ourDeviceId
|
||||||
|
* @param {module:OlmDevice} olmDevice olm.js wrapper
|
||||||
|
* @param {string[]} participantKeys list of curve25519 keys to encrypt for
|
||||||
|
* @param {object} payloadFields fields to include in the encrypted payload
|
||||||
|
*
|
||||||
|
* @return {object} content for an m.room.encrypted event
|
||||||
|
*/
|
||||||
|
module.exports.encryptMessageForDevices = function(
|
||||||
|
ourDeviceId, olmDevice, participantKeys, payloadFields
|
||||||
|
) {
|
||||||
|
participantKeys.sort();
|
||||||
|
var participantHash = ""; // Olm.sha256(participantKeys.join());
|
||||||
|
var payloadJson = {
|
||||||
|
fingerprint: participantHash,
|
||||||
|
sender_device: ourDeviceId,
|
||||||
|
};
|
||||||
|
utils.extend(payloadJson, payloadFields);
|
||||||
|
|
||||||
|
var ciphertext = {};
|
||||||
|
var payloadString = JSON.stringify(payloadJson);
|
||||||
|
for (var i = 0; i < participantKeys.length; ++i) {
|
||||||
|
var deviceKey = participantKeys[i];
|
||||||
|
var sessionId = olmDevice.getSessionIdForDevice(deviceKey);
|
||||||
|
if (sessionId === null) {
|
||||||
|
// If we don't have a session for a device then
|
||||||
|
// we can't encrypt a message for it.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console.log("Using sessionid " + sessionId + " for device " + deviceKey);
|
||||||
|
ciphertext[deviceKey] = olmDevice.encryptMessage(
|
||||||
|
deviceKey, sessionId, payloadString
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var encryptedContent = {
|
||||||
|
algorithm: module.exports.OLM_ALGORITHM,
|
||||||
|
sender_key: olmDevice.deviceCurve25519Key,
|
||||||
|
ciphertext: ciphertext
|
||||||
|
};
|
||||||
|
return encryptedContent;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user