Skip to content

Commit

Permalink
share old room keys
Browse files Browse the repository at this point in the history
  • Loading branch information
KevLehman committed Sep 27, 2024
1 parent 60bc3ab commit 6dba1b5
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions apps/meteor/app/e2e/client/rocketchat.e2e.room.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,21 @@ export class E2ERoom extends Emitter {
this.log('decryptOldRoomKeys Done');
}

async exportOldRoomKeys(oldKeys) {
if (!oldKeys || oldKeys.length === 0) {
return;
}

return Promise.all(
oldKeys.map(async (key) => {
return {
...key,
E2EKey: await this.exportSessionKey(key.E2EKey),
};
}),
);
}

async decryptPendingMessages() {
return Messages.find({ rid: this.roomId, t: 'e2e', e2e: 'pending' }).forEach(async ({ _id, ...msg }) => {
Messages.update({ _id }, await this.decryptMessage(msg));
Expand Down Expand Up @@ -287,7 +302,6 @@ export class E2ERoom extends Emitter {
}

async decryptSessionKey(key) {
console.log('Decrypting key: ', key);
key = key.slice(12);
key = Base64.decode(key);

Expand All @@ -300,6 +314,16 @@ export class E2ERoom extends Emitter {
}
}

async exportSessionKey(key) {
try {
const decryptedKey = await decryptRSA(e2e.privateKey, key);
return toString(decryptedKey);
} catch (error) {
this.error('Error decrypting key: ', error);
return null;
}
}

async importGroupKey(groupKey) {
this.log('Importing room key ->', this.roomId);
// Get existing group key
Expand Down Expand Up @@ -357,6 +381,7 @@ export class E2ERoom extends Emitter {
async encryptKeyForOtherParticipants() {
// Encrypt generated session key for every user in room and publish to subscription model.
try {
const mySub = Subscriptions.findOne({ rid: this.roomId });
const users = (await sdk.call('e2e.getUsersOfRoomWithoutKey', this.roomId)).users.filter((user) => user?.e2e?.public_key);

if (!users.length) {
Expand All @@ -366,8 +391,9 @@ export class E2ERoom extends Emitter {
const usersSuggestedGroupKeys = { [this.roomId]: [] };
for await (const user of users) {
const encryptedGroupKey = await this.encryptGroupKeyForParticipant(user.e2e.public_key);
const oldKeys = await this.encryptOldKeysForParticipant(user.e2e.public_key, await this.exportOldRoomKeys(mySub?.oldRoomKeys));

usersSuggestedGroupKeys[this.roomId].push({ _id: user._id, key: encryptedGroupKey });
usersSuggestedGroupKeys[this.roomId].push({ _id: user._id, key: encryptedGroupKey, ...(oldKeys && { oldKeys }) });
}

await sdk.rest.post('/v1/e2e.provideUsersSuggestedGroupKeys', { usersSuggestedGroupKeys });
Expand All @@ -376,6 +402,32 @@ export class E2ERoom extends Emitter {
}
}

async encryptOldKeysForParticipant(public_key, oldRoomKeys) {
if (!oldRoomKeys || oldRoomKeys.length === 0) {
return;
}

let userKey;

try {
userKey = await importRSAKey(JSON.parse(public_key), ['encrypt']);
} catch (error) {
return this.error('Error importing user key: ', error);
}

try {
return await Promise.all(
oldRoomKeys.map(async (key) => {
const encryptedKey = await encryptRSA(userKey, toArrayBuffer(key.E2EKey));
const encryptedKeyToString = key.keyID + Base64.encode(new Uint8Array(encryptedKey));
return { ...key, E2EKey: encryptedKeyToString };
}),
);
} catch (error) {
return this.error('Error encrypting user key: ', error);
}
}

async encryptGroupKeyForParticipant(public_key) {
let userKey;
try {
Expand Down

0 comments on commit 6dba1b5

Please sign in to comment.