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
|
||||
*
|
||||
|
||||
@@ -89,12 +89,11 @@ export {EncryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272
|
||||
/**
|
||||
* base type for decryption implementations
|
||||
*
|
||||
* @alias module:crypto/algorithms/base.DecryptionAlgorithm
|
||||
*
|
||||
* @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 {module:base-apis~MatrixBaseApis} baseApis base matrix api interface
|
||||
* @param {string=} params.roomId The ID of the room we will be receiving
|
||||
* from. Null for to-device events.
|
||||
*/
|
||||
@@ -103,6 +102,7 @@ class DecryptionAlgorithm {
|
||||
this._userId = params.userId;
|
||||
this._crypto = params.crypto;
|
||||
this._olmDevice = params.olmDevice;
|
||||
this._baseApis = params.baseApis;
|
||||
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
|
||||
*
|
||||
|
||||
@@ -1238,6 +1238,7 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
|
||||
userId: this._userId,
|
||||
crypto: this,
|
||||
olmDevice: this._olmDevice,
|
||||
baseApis: this._baseApis,
|
||||
roomId: roomId,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user