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
Merge pull request #179 from matrix-org/rav/send_megolm_keys
Send out megolm keys when we start a megolm session
This commit is contained in:
@@ -50,12 +50,14 @@ module.exports.DECRYPTION_CLASSES = {};
|
|||||||
* @param {string} params.deviceId The identifier for this device.
|
* @param {string} params.deviceId The identifier for this device.
|
||||||
* @param {module:crypto} params.crypto crypto core
|
* @param {module:crypto} params.crypto crypto core
|
||||||
* @param {module:OlmDevice} params.olmDevice olm.js wrapper
|
* @param {module:OlmDevice} params.olmDevice olm.js wrapper
|
||||||
|
* @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface
|
||||||
* @param {string} params.roomId The ID of the room we will be sending to
|
* @param {string} params.roomId The ID of the room we will be sending to
|
||||||
*/
|
*/
|
||||||
var EncryptionAlgorithm = function(params) {
|
var EncryptionAlgorithm = function(params) {
|
||||||
this._deviceId = params.deviceId;
|
this._deviceId = params.deviceId;
|
||||||
this._crypto = params.crypto;
|
this._crypto = params.crypto;
|
||||||
this._olmDevice = params.olmDevice;
|
this._olmDevice = params.olmDevice;
|
||||||
|
this._baseApis = params.baseApis;
|
||||||
this._roomId = params.roomId;
|
this._roomId = params.roomId;
|
||||||
};
|
};
|
||||||
/** */
|
/** */
|
||||||
@@ -81,7 +83,7 @@ EncryptionAlgorithm.prototype.initRoomEncryption = function(roomMembers) {
|
|||||||
* @method module:crypto-algorithms/base.EncryptionAlgorithm#encryptMessage
|
* @method module:crypto-algorithms/base.EncryptionAlgorithm#encryptMessage
|
||||||
* @abstract
|
* @abstract
|
||||||
*
|
*
|
||||||
* @param {module:models/room?} room
|
* @param {module:models/room} room
|
||||||
* @param {string} eventType
|
* @param {string} eventType
|
||||||
* @param {object} plaintext event content
|
* @param {object} plaintext event content
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -46,10 +46,12 @@ utils.inherits(MegolmEncryption, base.EncryptionAlgorithm);
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*
|
*
|
||||||
|
* @param {module:models/room} room
|
||||||
|
*
|
||||||
* @return {module:client.Promise} Promise which resolves when setup is
|
* @return {module:client.Promise} Promise which resolves when setup is
|
||||||
* complete.
|
* complete.
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._ensureOutboundSession = function() {
|
MegolmEncryption.prototype._ensureOutboundSession = function(room) {
|
||||||
if (this._prepPromise) {
|
if (this._prepPromise) {
|
||||||
// prep already in progress
|
// prep already in progress
|
||||||
return this._prepPromise;
|
return this._prepPromise;
|
||||||
@@ -61,8 +63,6 @@ MegolmEncryption.prototype._ensureOutboundSession = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var session_id = this._olmDevice.createOutboundGroupSession();
|
var session_id = this._olmDevice.createOutboundGroupSession();
|
||||||
this._outboundSessionId = session_id;
|
|
||||||
|
|
||||||
var key = this._olmDevice.getOutboundGroupSessionKey(session_id);
|
var key = this._olmDevice.getOutboundGroupSessionKey(session_id);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
@@ -80,20 +80,94 @@ MegolmEncryption.prototype._ensureOutboundSession = function() {
|
|||||||
key.key, key.chain_index
|
key.key, key.chain_index
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// send the keys to each (unblocked) device in the room.
|
||||||
|
var payload = {
|
||||||
|
type: "m.room_key",
|
||||||
|
content: {
|
||||||
|
algorithm: olmlib.MEGOLM_ALGORITHM,
|
||||||
|
room_id: this._roomId,
|
||||||
|
session_id: session_id,
|
||||||
|
session_key: key.key,
|
||||||
|
chain_index: key.chain_index,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var roomMembers = utils.map(room.getJoinedMembers(), function(u) {
|
||||||
|
return u.userId;
|
||||||
|
});
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
// TODO: initiate key-sharing
|
var txnBase = '' + (new Date().getTime()) + '.';
|
||||||
this._prepPromise = q.delay(3000).then(function() {
|
var txnCtr = 0;
|
||||||
console.log("woop woop, we totally shared the keys");
|
|
||||||
|
// TODO: we need to give the user a chance to block any devices or users
|
||||||
|
// before we send them the keys; it's too late to download them here.
|
||||||
|
this._prepPromise = this._crypto.downloadKeys(
|
||||||
|
roomMembers, false
|
||||||
|
).then(function(res) {
|
||||||
|
return self._crypto.ensureOlmSessionsForUsers(roomMembers);
|
||||||
|
}).then(function(devicemap) {
|
||||||
|
var promises = [];
|
||||||
|
for (var userId in devicemap) {
|
||||||
|
if (!devicemap.hasOwnProperty(userId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var devices = devicemap[userId];
|
||||||
|
|
||||||
|
for (var deviceId in devices) {
|
||||||
|
if (!devices.hasOwnProperty(deviceId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceInfo = devices[deviceId].device;
|
||||||
|
var encryptedContent = olmlib.encryptMessageForDevices(
|
||||||
|
self._deviceId,
|
||||||
|
self._olmDevice,
|
||||||
|
[deviceInfo.getIdentityKey()],
|
||||||
|
payload
|
||||||
|
);
|
||||||
|
|
||||||
|
var txnId = txnBase + (txnCtr++);
|
||||||
|
|
||||||
|
// TODO: send an OOB message. for now, send an in-band message.
|
||||||
|
|
||||||
|
// TODO: aggregate the messages into batches. If we make a
|
||||||
|
// separate request for each message, we will get rate-limited.
|
||||||
|
// On the other hand, we can't just send them in one big batch,
|
||||||
|
// because we'll hit the event size limit.
|
||||||
|
|
||||||
|
var path = utils.encodeUri(
|
||||||
|
"/rooms/$roomId/send/m.room.encrypted/$txnId", {
|
||||||
|
$roomId: self._roomId,
|
||||||
|
$txnId: txnId,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: retries
|
||||||
|
var promise = self._baseApis._http.authedRequest(
|
||||||
|
undefined, "PUT", path, undefined, encryptedContent
|
||||||
|
);
|
||||||
|
|
||||||
|
promises.push(promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return q.all(promises);
|
||||||
|
}).then(function() {
|
||||||
|
// don't set this until the keys are sent successfully; if we get an
|
||||||
|
// error, the user can restart by resending the message.
|
||||||
|
self._outboundSessionId = session_id;
|
||||||
|
}).finally(function() {
|
||||||
self._prepPromise = null;
|
self._prepPromise = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
return this._prepPromise;
|
return this._prepPromise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @param {module:models/room?} room
|
* @param {module:models/room} room
|
||||||
* @param {string} eventType
|
* @param {string} eventType
|
||||||
* @param {object} plaintext event content
|
* @param {object} plaintext event content
|
||||||
*
|
*
|
||||||
@@ -101,7 +175,7 @@ MegolmEncryption.prototype._ensureOutboundSession = function() {
|
|||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
MegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return this._ensureOutboundSession().then(function() {
|
return this._ensureOutboundSession(room).then(function() {
|
||||||
var payloadJson = {
|
var payloadJson = {
|
||||||
room_id: self._roomId,
|
room_id: self._roomId,
|
||||||
type: eventType,
|
type: eventType,
|
||||||
|
|||||||
@@ -56,17 +56,13 @@ OlmEncryption.prototype.initRoomEncryption = function(roomMembers) {
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @param {module:models/room?} room
|
* @param {module:models/room} room
|
||||||
* @param {string} eventType
|
* @param {string} eventType
|
||||||
* @param {object} plaintext event content
|
* @param {object} plaintext event content
|
||||||
*
|
*
|
||||||
* @return {module:client.Promise} Promise which resolves to the new event body
|
* @return {module:client.Promise} Promise which resolves to the new event body
|
||||||
*/
|
*/
|
||||||
OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
||||||
if (!room) {
|
|
||||||
throw new Error("Cannot send encrypted messages in unknown rooms");
|
|
||||||
}
|
|
||||||
|
|
||||||
// pick the list of recipients based on the membership list.
|
// pick the list of recipients based on the membership list.
|
||||||
//
|
//
|
||||||
// TODO: there is a race condition here! What if a new user turns up
|
// TODO: there is a race condition here! What if a new user turns up
|
||||||
|
|||||||
@@ -540,6 +540,7 @@ Crypto.prototype.setRoomEncryption = function(roomId, config, roomMembers) {
|
|||||||
deviceId: this._deviceId,
|
deviceId: this._deviceId,
|
||||||
crypto: this,
|
crypto: this,
|
||||||
olmDevice: this._olmDevice,
|
olmDevice: this._olmDevice,
|
||||||
|
baseApis: this._baseApis,
|
||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
});
|
});
|
||||||
this._roomAlgorithms[roomId] = alg;
|
this._roomAlgorithms[roomId] = alg;
|
||||||
@@ -678,6 +679,10 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!room) {
|
||||||
|
throw new Error("Cannot send encrypted messages in unknown rooms");
|
||||||
|
}
|
||||||
|
|
||||||
var roomId = event.getRoomId();
|
var roomId = event.getRoomId();
|
||||||
|
|
||||||
var alg = this._roomAlgorithms[roomId];
|
var alg = this._roomAlgorithms[roomId];
|
||||||
|
|||||||
Reference in New Issue
Block a user