1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-19 10:22:30 +03:00

persist DecryptionAlgorithm instances

It's useful to be able to keep state between events in the DecryptionAlgorithm,
so store them in a map.
This commit is contained in:
Richard van der Hoff
2016-11-01 10:46:51 +00:00
parent e7dcc06855
commit e623b539c4
2 changed files with 74 additions and 24 deletions

View File

@@ -105,11 +105,16 @@ EncryptionAlgorithm.prototype.onNewDevice = function(userId, deviceId) {};
*
* @param {object} params parameters
* @param {string} params.userId The UserID for the local user
* @param {module:crypto} params.crypto crypto core
* @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper
* @param {string=} params.roomId The ID of the room we will be receiving
* from. Null for to-device events.
*/
var DecryptionAlgorithm = function(params) {
this._userId = params.userId;
this._crypto = params.crypto;
this._olmDevice = params.olmDevice;
this._roomId = params.roomId;
};
/** */
module.exports.DecryptionAlgorithm = DecryptionAlgorithm;

View File

@@ -57,7 +57,10 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
this._olmDevice = new OlmDevice(sessionStore);
// EncryptionAlgorithm instance for each room
this._roomAlgorithms = {};
this._roomEncryptors = {};
// map from algorithm to DecryptionAlgorithm instance, for each room
this._roomDecryptors = {};
this._supportedAlgorithms = utils.keys(
algorithms.DECRYPTION_CLASSES
@@ -705,7 +708,7 @@ Crypto.prototype.setRoomEncryption = function(roomId, config) {
roomId: roomId,
config: config,
});
this._roomAlgorithms[roomId] = alg;
this._roomEncryptors[roomId] = alg;
};
@@ -839,7 +842,7 @@ Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
* @return {bool} whether encryption is enabled.
*/
Crypto.prototype.isRoomEncrypted = function(roomId) {
return Boolean(this._roomAlgorithms[roomId]);
return Boolean(this._roomEncryptors[roomId]);
};
/**
@@ -867,7 +870,7 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
var roomId = event.getRoomId();
var alg = this._roomAlgorithms[roomId];
var alg = this._roomEncryptors[roomId];
if (!alg) {
// not encrypting messages in this room
@@ -922,14 +925,7 @@ Crypto.prototype.encryptEventIfNeeded = function(event, room) {
*/
Crypto.prototype.decryptEvent = function(event) {
var content = event.content;
var AlgClass = algorithms.DECRYPTION_CLASSES[content.algorithm];
if (!AlgClass) {
throw new algorithms.DecryptionError("Unable to decrypt " + content.algorithm);
}
var alg = new AlgClass({
userId: this._userId,
olmDevice: this._olmDevice,
});
var alg = this._getRoomDecryptor(event.room_id, content.algorithm);
var r = alg.decryptEvent(event);
if (r !== null) {
@@ -1054,7 +1050,7 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
var room = rooms[i];
// check for rooms with encryption enabled
var alg = this._roomAlgorithms[room.roomId];
var alg = this._roomEncryptors[room.roomId];
if (!alg) {
continue;
}
@@ -1108,16 +1104,13 @@ Crypto.prototype._onInitialSyncCompleted = function(rooms) {
*/
Crypto.prototype._onRoomKeyEvent = function(event) {
var content = event.getContent();
var AlgClass = algorithms.DECRYPTION_CLASSES[content.algorithm];
if (!AlgClass) {
throw new algorithms.DecryptionError(
"Unable to handle keys for " + content.algorithm
);
if (!content.room_id || !content.algorithm) {
console.error("key event is missing fields");
return;
}
var alg = new AlgClass({
userId: this._userId,
olmDevice: this._olmDevice,
});
var alg = this._getRoomDecryptor(content.room_id, content.algorithm);
alg.onRoomKeyEvent(event);
};
@@ -1141,7 +1134,7 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) {
var roomId = member.roomId;
var alg = this._roomAlgorithms[roomId];
var alg = this._roomEncryptors[roomId];
if (!alg) {
// not encrypting in this room
return;
@@ -1177,7 +1170,7 @@ Crypto.prototype._onNewDeviceEvent = function(event) {
).then(function() {
for (var i = 0; i < rooms.length; i++) {
var roomId = rooms[i];
var alg = self._roomAlgorithms[roomId];
var alg = self._roomEncryptors[roomId];
if (!alg) {
// not encrypting in this room
continue;
@@ -1193,6 +1186,58 @@ Crypto.prototype._onNewDeviceEvent = function(event) {
}).done();
};
/**
* Get a decryptor for a given room and algorithm.
*
* If we already have a decryptor for the given room and algorithm, return
* it. Otherwise try to instantiate it.
*
* @private
*
* @param {string?} roomId room id for decryptor. If undefined, a temporary
* decryptor is instantiated.
*
* @param {string} algorithm crypto algorithm
*
* @return {module:crypto.algorithms.base.DecryptionAlgorithm}
*
* @raises {module:crypto.algorithms.DecryptionError} if the algorithm is
* unknown
*/
Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
var decryptors;
var alg;
roomId = roomId || null;
if (roomId) {
decryptors = this._roomDecryptors[roomId];
if (!decryptors) {
this._roomDecryptors[roomId] = decryptors = {};
}
alg = decryptors[algorithm];
if (alg) {
return alg;
}
}
var AlgClass = algorithms.DECRYPTION_CLASSES[algorithm];
if (!AlgClass) {
throw new algorithms.DecryptionError("Unable to decrypt " + algorithm);
}
alg = new AlgClass({
userId: this._userId,
crypto: this,
olmDevice: this._olmDevice,
roomId: roomId,
});
if (decryptors) {
decryptors[algorithm] = alg;
}
return alg;
};
/**
* sign the given object with our ed25519 key