You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Support for exporting megolm session data
This commit is contained in:
@@ -193,6 +193,12 @@ module.exports.MockStorageApi = function() {
|
|||||||
this.data = {};
|
this.data = {};
|
||||||
};
|
};
|
||||||
module.exports.MockStorageApi.prototype = {
|
module.exports.MockStorageApi.prototype = {
|
||||||
|
get length() {
|
||||||
|
return Object.keys(this.data).length;
|
||||||
|
},
|
||||||
|
key: function(i) {
|
||||||
|
return Object.keys(this.data)[i];
|
||||||
|
},
|
||||||
setItem: function(k, v) {
|
setItem: function(k, v) {
|
||||||
this.data[k] = v;
|
this.data[k] = v;
|
||||||
},
|
},
|
||||||
|
@@ -461,6 +461,21 @@ MatrixClient.prototype.isRoomEncrypted = function(roomId) {
|
|||||||
return this._crypto.isRoomEncrypted(roomId);
|
return this._crypto.isRoomEncrypted(roomId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list containing all of the room keys
|
||||||
|
*
|
||||||
|
* This should be encrypted before returning it to the user.
|
||||||
|
*
|
||||||
|
* @return {module:client.Promise} a promise which resolves to a list of
|
||||||
|
* session export objects
|
||||||
|
*/
|
||||||
|
MatrixClient.prototype.exportRoomKeys = function() {
|
||||||
|
if (!this._crypto) {
|
||||||
|
return q.reject(new Error("End-to-end encryption disabled"));
|
||||||
|
}
|
||||||
|
return this._crypto.exportRoomKeys();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt a received event according to the algorithm specified in the event.
|
* Decrypt a received event according to the algorithm specified in the event.
|
||||||
*
|
*
|
||||||
|
@@ -739,6 +739,41 @@ OlmDevice.prototype.decryptGroupMessage = function(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export an inbound group session
|
||||||
|
*
|
||||||
|
* @param {string} senderKey base64-encoded curve25519 key of the sender
|
||||||
|
* @param {string} sessionId session identifier
|
||||||
|
* @return {object} exported session data
|
||||||
|
*/
|
||||||
|
OlmDevice.prototype.exportInboundGroupSession = function(senderKey, sessionId) {
|
||||||
|
const s = this._sessionStore.getEndToEndInboundGroupSession(
|
||||||
|
senderKey, sessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (s === null) {
|
||||||
|
throw new Error("Unknown inbound group session [" + senderKey + "," +
|
||||||
|
sessionId + "]");
|
||||||
|
}
|
||||||
|
const r = JSON.parse(s);
|
||||||
|
|
||||||
|
const session = new Olm.InboundGroupSession();
|
||||||
|
try {
|
||||||
|
session.unpickle(this._pickleKey, r.session);
|
||||||
|
|
||||||
|
const messageIndex = session.first_known_index();
|
||||||
|
|
||||||
|
return {
|
||||||
|
"sender_key": senderKey,
|
||||||
|
"sender_claimed_keys": r.keysClaimed,
|
||||||
|
"room_id": r.room_id,
|
||||||
|
"session_id": sessionId,
|
||||||
|
"session_key": session.export_session(messageIndex),
|
||||||
|
};
|
||||||
|
} finally {
|
||||||
|
session.free();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
// =========
|
// =========
|
||||||
|
@@ -897,6 +897,28 @@ Crypto.prototype.isRoomEncrypted = function(roomId) {
|
|||||||
return Boolean(this._roomEncryptors[roomId]);
|
return Boolean(this._roomEncryptors[roomId]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list containing all of the room keys
|
||||||
|
*
|
||||||
|
* @return {module:client.Promise} a promise which resolves to a list of
|
||||||
|
* session export objects
|
||||||
|
*/
|
||||||
|
Crypto.prototype.exportRoomKeys = function() {
|
||||||
|
return q(
|
||||||
|
this._sessionStore.getAllEndToEndInboundGroupSessionKeys().map(
|
||||||
|
(s) => {
|
||||||
|
const sess = this._olmDevice.exportInboundGroupSession(
|
||||||
|
s.senderKey, s.sessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
sess.algorithm = olmlib.MEGOLM_ALGORITHM;
|
||||||
|
return sess;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt an event according to the configuration of the room, if necessary.
|
* Encrypt an event according to the configuration of the room, if necessary.
|
||||||
*
|
*
|
||||||
|
@@ -37,7 +37,10 @@ function WebStorageSessionStore(webStore) {
|
|||||||
this.store = webStore;
|
this.store = webStore;
|
||||||
if (!utils.isFunction(webStore.getItem) ||
|
if (!utils.isFunction(webStore.getItem) ||
|
||||||
!utils.isFunction(webStore.setItem) ||
|
!utils.isFunction(webStore.setItem) ||
|
||||||
!utils.isFunction(webStore.removeItem)) {
|
!utils.isFunction(webStore.removeItem) ||
|
||||||
|
!utils.isFunction(webStore.key) ||
|
||||||
|
typeof(webStore.length) !== 'number'
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Supplied webStore does not meet the WebStorage API interface"
|
"Supplied webStore does not meet the WebStorage API interface"
|
||||||
);
|
);
|
||||||
@@ -120,6 +123,32 @@ WebStorageSessionStore.prototype = {
|
|||||||
return getJsonItem(this.store, keyEndToEndSessions(deviceKey));
|
return getJsonItem(this.store, keyEndToEndSessions(deviceKey));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of all known inbound group sessions
|
||||||
|
*
|
||||||
|
* @return {{senderKey: string, sessionId: string}}
|
||||||
|
*/
|
||||||
|
getAllEndToEndInboundGroupSessionKeys: function() {
|
||||||
|
const prefix = E2E_PREFIX + 'inboundgroupsessions/';
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < this.store.length; i++) {
|
||||||
|
const key = this.store.key(i);
|
||||||
|
if (!key.startsWith(prefix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// we can't use split, as the components we are trying to split out
|
||||||
|
// might themselves contain '/' characters. We rely on the
|
||||||
|
// senderKey being a (32-byte) curve25519 key, base64-encoded
|
||||||
|
// (hence 43 characters long).
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
senderKey: key.substr(prefix.length, 43),
|
||||||
|
sessionId: key.substr(prefix.length + 44),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
getEndToEndInboundGroupSession: function(senderKey, sessionId) {
|
getEndToEndInboundGroupSession: function(senderKey, sessionId) {
|
||||||
let key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
let key = keyEndToEndInboundGroupSession(senderKey, sessionId);
|
||||||
return this.store.getItem(key);
|
return this.store.getItem(key);
|
||||||
|
Reference in New Issue
Block a user