You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Implement sharing of megolm keys
This commit is contained in:
@@ -796,6 +796,62 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if we have the keys for a given megolm session
|
||||||
|
*
|
||||||
|
* @param {string} roomId room in which the message was received
|
||||||
|
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||||
|
* @param {sring} sessionId session identifier
|
||||||
|
*
|
||||||
|
* @returns {boolean} true if we have the keys to this session
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.hasInboundSessionKeys = function(roomId, senderKey, sessionId) {
|
||||||
|
const s = this._sessionStore.getEndToEndInboundGroupSession(
|
||||||
|
senderKey, sessionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (s === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = JSON.parse(s);
|
||||||
|
if (roomId !== r.room_id) {
|
||||||
|
console.warn(
|
||||||
|
`requested keys for inbound group session ${senderKey}|` +
|
||||||
|
`${sessionId}, with incorrect room_id (expected ${r.room_id}, ` +
|
||||||
|
`was ${roomId})`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the keys to a given megolm session, for sharing
|
||||||
|
*
|
||||||
|
* @param {string} roomId room in which the message was received
|
||||||
|
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||||
|
* @param {string} sessionId session identifier
|
||||||
|
*
|
||||||
|
* @returns {{chain_index: number, key: string}} details of the session key. The
|
||||||
|
* key is a base64-encoded megolm key in export format.
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.getInboundGroupSessionKey = function(roomId, senderKey, sessionId) {
|
||||||
|
function getKey(session, keysClaimed) {
|
||||||
|
const messageIndex = session.first_known_index();
|
||||||
|
|
||||||
|
return {
|
||||||
|
"chain_index": messageIndex,
|
||||||
|
"key": session.export_session(messageIndex),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._getInboundGroupSession(
|
||||||
|
roomId, senderKey, sessionId, getKey,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export an inbound group session
|
* Export an inbound group session
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -89,12 +89,11 @@ export {EncryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272
|
|||||||
/**
|
/**
|
||||||
* base type for decryption implementations
|
* base type for decryption implementations
|
||||||
*
|
*
|
||||||
* @alias module:crypto/algorithms/base.DecryptionAlgorithm
|
|
||||||
*
|
|
||||||
* @param {object} params parameters
|
* @param {object} params parameters
|
||||||
* @param {string} params.userId The UserID for the local user
|
* @param {string} params.userId The UserID for the local user
|
||||||
* @param {module:crypto} params.crypto crypto core
|
* @param {module:crypto} params.crypto crypto core
|
||||||
* @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper
|
* @param {module:crypto/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 receiving
|
* @param {string=} params.roomId The ID of the room we will be receiving
|
||||||
* from. Null for to-device events.
|
* from. Null for to-device events.
|
||||||
*/
|
*/
|
||||||
@@ -103,6 +102,7 @@ class DecryptionAlgorithm {
|
|||||||
this._userId = params.userId;
|
this._userId = params.userId;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -663,6 +663,89 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MegolmDecryption.prototype.hasKeysForKeyRequest = function(keyRequest) {
|
||||||
|
const body = keyRequest.requestBody;
|
||||||
|
|
||||||
|
return this._olmDevice.hasInboundSessionKeys(
|
||||||
|
body.room_id,
|
||||||
|
body.sender_key,
|
||||||
|
body.session_id,
|
||||||
|
// TODO: ratchet index
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MegolmDecryption.prototype.shareKeysWithDevice = function(keyRequest) {
|
||||||
|
const userId = keyRequest.userId;
|
||||||
|
const deviceId = keyRequest.deviceId;
|
||||||
|
const deviceInfo = this._crypto.getStoredDevice(userId, deviceId);
|
||||||
|
const body = keyRequest.requestBody;
|
||||||
|
|
||||||
|
olmlib.ensureOlmSessionsForDevices(
|
||||||
|
this._olmDevice, this._baseApis, {
|
||||||
|
[userId]: [deviceInfo],
|
||||||
|
},
|
||||||
|
).then((devicemap) => {
|
||||||
|
const olmSessionResult = devicemap[userId][deviceId];
|
||||||
|
if (!olmSessionResult.sessionId) {
|
||||||
|
// no session with this device, probably because there
|
||||||
|
// were no one-time keys.
|
||||||
|
//
|
||||||
|
// ensureOlmSessionsForUsers has already done the logging,
|
||||||
|
// so just skip it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"sharing keys for session " + body.sender_key + "|"
|
||||||
|
+ body.session_id + " with device "
|
||||||
|
+ userId + ":" + deviceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const key = this._olmDevice.getInboundGroupSessionKey(
|
||||||
|
body.room_id, body.sender_key, body.session_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
type: "m.forwarded_room_key",
|
||||||
|
content: {
|
||||||
|
algorithm: olmlib.MEGOLM_ALGORITHM,
|
||||||
|
room_id: body.room_id,
|
||||||
|
sender_key: body.sender_key,
|
||||||
|
session_id: body.session_id,
|
||||||
|
session_key: key.key,
|
||||||
|
chain_index: key.chain_index,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const encryptedContent = {
|
||||||
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
|
sender_key: this._olmDevice.deviceCurve25519Key,
|
||||||
|
ciphertext: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
olmlib.encryptMessageForDevice(
|
||||||
|
encryptedContent.ciphertext,
|
||||||
|
this._userId,
|
||||||
|
this._deviceId,
|
||||||
|
this._olmDevice,
|
||||||
|
userId,
|
||||||
|
deviceInfo,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
|
||||||
|
const contentMap = {
|
||||||
|
[userId]: {
|
||||||
|
[deviceId]: encryptedContent,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: retries
|
||||||
|
return this._baseApis.sendToDevice("m.room.encrypted", contentMap);
|
||||||
|
}).done();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1238,6 +1238,7 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
|
|||||||
userId: this._userId,
|
userId: this._userId,
|
||||||
crypto: this,
|
crypto: this,
|
||||||
olmDevice: this._olmDevice,
|
olmDevice: this._olmDevice,
|
||||||
|
baseApis: this._baseApis,
|
||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user