add a cache of the keypairs for a closed group

pull/1783/head
Audric Ackermann 4 years ago
parent 7cc7db5d4a
commit 9a302fb5ff
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -103,7 +103,6 @@ module.exports = {
getAllEncryptionKeyPairsForGroup,
getLatestClosedGroupEncryptionKeyPair,
addClosedGroupEncryptionKeyPair,
isKeyPairAlreadySaved,
removeAllClosedGroupEncryptionKeyPairs,
// open group v2
@ -1804,8 +1803,6 @@ function saveMessage(data) {
unread,
};
console.warn('payload: ', payload);
globalInstance
.prepare(
`INSERT OR REPLACE INTO ${MESSAGES_TABLE} (
@ -2692,16 +2689,6 @@ function addClosedGroupEncryptionKeyPair(groupPublicKey, keypair, instance) {
});
}
function isKeyPairAlreadySaved(
groupPublicKey,
newKeyPairInHex // : HexKeyPair
) {
const allKeyPairs = getAllEncryptionKeyPairsForGroup(groupPublicKey);
return (allKeyPairs || []).some(
k => newKeyPairInHex.publicHex === k.publicHex && newKeyPairInHex.privateHex === k.privateHex
);
}
function removeAllClosedGroupEncryptionKeyPairs(groupPublicKey) {
globalInstance
.prepare(

@ -6,7 +6,7 @@ import { Emojify } from './Emojify';
type Props = {
phoneNumber: string;
name?: string | null;
profileName?: string;
profileName?: string | null;
module?: string;
boldProfileName?: Boolean;
compact?: Boolean;

@ -154,7 +154,6 @@ const channelsToMake = {
getAllEncryptionKeyPairsForGroup,
getLatestClosedGroupEncryptionKeyPair,
addClosedGroupEncryptionKeyPair,
isKeyPairAlreadySaved,
removeAllClosedGroupEncryptionKeyPairs,
removeOneOpenGroupV1Message,
@ -497,13 +496,6 @@ export async function addClosedGroupEncryptionKeyPair(
await channels.addClosedGroupEncryptionKeyPair(groupPublicKey, keypair);
}
export async function isKeyPairAlreadySaved(
groupPublicKey: string,
keypair: HexKeyPair
): Promise<boolean> {
return channels.isKeyPairAlreadySaved(groupPublicKey, keypair);
}
export async function removeAllClosedGroupEncryptionKeyPairs(
groupPublicKey: string
): Promise<void> {

@ -193,9 +193,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
trailing: true,
leading: true,
});
this.triggerUIRefresh = _.throttle(this.triggerUIRefresh, 1000, {
this.triggerUIRefresh = _.throttle(this.triggerUIRefresh, 300, {
trailing: true,
leading: true,
});
this.throttledNotify = _.debounce(this.notify, 500, { maxWait: 1000, trailing: true });
//start right away the function is called, and wait 1sec before calling it again
@ -484,7 +483,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return unreadCount;
}
public queueJob(callback: any) {
public queueJob(callback: () => Promise<void>) {
// tslint:disable-next-line: no-promise-as-boolean
const previous = this.pending || Promise.resolve();

@ -16,7 +16,6 @@ import {
addClosedGroupEncryptionKeyPair,
getAllEncryptionKeyPairsForGroup,
getLatestClosedGroupEncryptionKeyPair,
isKeyPairAlreadySaved,
removeAllClosedGroupEncryptionKeyPairs,
} from '../../ts/data/data';
import {
@ -40,6 +39,52 @@ import { updateConfirmModal } from '../state/ducks/modalDialog';
export const distributingClosedGroupEncryptionKeyPairs = new Map<string, ECKeyPair>();
// this is a cache of the keypairs stored in the db.
const cacheOfClosedGroupKeyPairs: Map<string, Array<HexKeyPair>> = new Map();
export async function getAllCachedECKeyPair(groupPubKey: string) {
let keyPairsFound = cacheOfClosedGroupKeyPairs.get(groupPubKey);
if (!keyPairsFound) {
keyPairsFound = (await getAllEncryptionKeyPairsForGroup(groupPubKey)) || [];
cacheOfClosedGroupKeyPairs.set(groupPubKey, keyPairsFound);
}
return keyPairsFound;
}
/**
*
* @returns true if this keypair was not already saved for this publickey
*/
export async function addKeyPairToCacheAndDBIfNeeded(
groupPubKey: string,
keyPair: HexKeyPair
): Promise<boolean> {
const existingKeyPairs = await getAllCachedECKeyPair(groupPubKey);
const alreadySaved = existingKeyPairs.some(k => {
return k.privateHex === keyPair.privateHex && k.publicHex === keyPair.publicHex;
});
if (alreadySaved) {
return false;
}
await addClosedGroupEncryptionKeyPair(groupPubKey, keyPair);
if (!cacheOfClosedGroupKeyPairs.has(groupPubKey)) {
cacheOfClosedGroupKeyPairs.set(groupPubKey, []);
}
cacheOfClosedGroupKeyPairs.get(groupPubKey)?.push(keyPair);
return true;
}
export async function innerRemoveAllClosedGroupEncryptionKeyPairs(groupPubKey: string) {
cacheOfClosedGroupKeyPairs.set(groupPubKey, []);
await removeAllClosedGroupEncryptionKeyPairs(groupPubKey);
}
export async function handleClosedGroupControlMessage(
envelope: EnvelopePlus,
groupUpdate: SignalService.DataMessage.ClosedGroupControlMessage
@ -199,7 +244,7 @@ export async function handleNewClosedGroup(
encryptionKeyPair!.publicKey,
encryptionKeyPair!.privateKey
);
const isKeyPairAlreadyHere = await isKeyPairAlreadySaved(
const isKeyPairAlreadyHere = await addKeyPairToCacheAndDBIfNeeded(
groupId,
ecKeyPairAlreadyExistingConvo.toHexKeyPair()
);
@ -207,15 +252,12 @@ export async function handleNewClosedGroup(
await maybeConvo.updateExpirationTimer(expireTimer, sender, Date.now());
if (isKeyPairAlreadyHere) {
await getAllEncryptionKeyPairsForGroup(groupId);
window.log.info('Dropping already saved keypair for group', groupId);
await removeFromCache(envelope);
return;
}
window.log.info(`Received the encryptionKeyPair for new group ${groupId}`);
await addClosedGroupEncryptionKeyPair(groupId, ecKeyPairAlreadyExistingConvo.toHexKeyPair());
await removeFromCache(envelope);
window.log.warn(
'Closed group message of type NEW: the conversation already exists, but we saved the new encryption keypair'
@ -272,7 +314,7 @@ export async function handleNewClosedGroup(
const ecKeyPair = new ECKeyPair(encryptionKeyPair!.publicKey, encryptionKeyPair!.privateKey);
window?.log?.info(`Received the encryptionKeyPair for new group ${groupId}`);
await addClosedGroupEncryptionKeyPair(groupId, ecKeyPair.toHexKeyPair());
await addKeyPairToCacheAndDBIfNeeded(groupId, ecKeyPair.toHexKeyPair());
// start polling for this new group
getSwarmPollingInstance().addGroupId(PubKey.cast(groupId));
@ -291,7 +333,7 @@ export async function markGroupAsLeftOrKicked(
groupConvo: ConversationModel,
isKicked: boolean
) {
await removeAllClosedGroupEncryptionKeyPairs(groupPublicKey);
await innerRemoveAllClosedGroupEncryptionKeyPairs(groupPublicKey);
if (isKicked) {
groupConvo.set('isKickedFromGroup', true);
@ -408,17 +450,17 @@ async function handleClosedGroupEncryptionKeyPair(
// Store it if needed
const newKeyPairInHex = keyPair.toHexKeyPair();
const isKeyPairAlreadyHere = await isKeyPairAlreadySaved(groupPublicKey, newKeyPairInHex);
const isKeyPairAlreadyHere = await addKeyPairToCacheAndDBIfNeeded(
groupPublicKey,
newKeyPairInHex
);
if (isKeyPairAlreadyHere) {
const existingKeyPairs = await getAllEncryptionKeyPairsForGroup(groupPublicKey);
window?.log?.info('Dropping already saved keypair for group', groupPublicKey);
await removeFromCache(envelope);
return;
}
window?.log?.info('Got a new encryption keypair for group', groupPublicKey);
await addClosedGroupEncryptionKeyPair(groupPublicKey, keyPair.toHexKeyPair());
await removeFromCache(envelope);
// trigger decrypting of all this group messages we did not decrypt successfully yet.
await queueAllCachedFromSource(groupPublicKey);
@ -893,12 +935,9 @@ export async function createClosedGroup(groupName: string, members: Array<string
if (allInvitesSent) {
const newHexKeypair = encryptionKeyPair.toHexKeyPair();
const isHexKeyPairSaved = await isKeyPairAlreadySaved(groupPublicKey, newHexKeypair);
const isHexKeyPairSaved = await addKeyPairToCacheAndDBIfNeeded(groupPublicKey, newHexKeypair);
if (!isHexKeyPairSaved) {
// tslint:disable-next-line: no-non-null-assertion
await addClosedGroupEncryptionKeyPair(groupPublicKey, encryptionKeyPair.toHexKeyPair());
} else {
if (isHexKeyPairSaved) {
window?.log?.info('Dropping already saved keypair for group', groupPublicKey);
}

@ -11,12 +11,12 @@ import { GroupUtils, UserUtils } from '../session/utils';
import { fromHexToArray, toHex } from '../session/utils/String';
import { concatUInt8Array, getSodium } from '../session/crypto';
import { getConversationController } from '../session/conversations';
import { getAllEncryptionKeyPairsForGroup } from '../../ts/data/data';
import { ECKeyPair } from './keypairs';
import { ECKeyPair, HexKeyPair } from './keypairs';
import { handleConfigurationMessage } from './configMessage';
import { ConversationTypeEnum } from '../models/conversation';
import { removeMessagePadding } from '../session/crypto/BufferPadding';
import { perfEnd, perfStart } from '../session/utils/Performance';
import { getAllCachedECKeyPair } from './closedGroups';
export async function handleContentMessage(envelope: EnvelopePlus) {
try {
@ -43,7 +43,11 @@ async function decryptForClosedGroup(envelope: EnvelopePlus, ciphertext: ArrayBu
window?.log?.warn('received medium group message but not for an existing medium group');
throw new Error('Invalid group public key'); // invalidGroupPublicKey
}
const encryptionKeyPairs = await getAllEncryptionKeyPairsForGroup(hexEncodedGroupPublicKey);
console.time('getAllEncryptionKeyPairsForGroup');
const encryptionKeyPairs = await getAllCachedECKeyPair(hexEncodedGroupPublicKey);
console.timeEnd('getAllEncryptionKeyPairsForGroup');
const encryptionKeyPairsCount = encryptionKeyPairs?.length;
if (!encryptionKeyPairs?.length) {
throw new Error(`No group keypairs for group ${hexEncodedGroupPublicKey}`); // noGroupKeyPair

@ -590,8 +590,6 @@ export async function handleMessageEvent(event: MessageEvent): Promise<void> {
// if the message is `sent` (from secondary device) we have to set the sender manually... (at least for now)
source = source || msg.get('source');
const isOurDevice = UserUtils.isUsFromCache(source);
// Conversation Id is:
// - primarySource if it is an incoming DM message,
// - destination if it is an outgoing message,

@ -21,6 +21,7 @@ import { MessageModel } from '../../models/message';
import { MessageModelType } from '../../models/messageType';
import { getMessageController } from '../messages';
import {
addKeyPairToCacheAndDBIfNeeded,
distributingClosedGroupEncryptionKeyPairs,
markGroupAsLeftOrKicked,
} from '../../receiver/closedGroups';
@ -504,7 +505,7 @@ async function generateAndSendNewEncryptionKeyPair(
distributingClosedGroupEncryptionKeyPairs.delete(toHex(groupId));
await addClosedGroupEncryptionKeyPair(toHex(groupId), newKeyPair.toHexKeyPair());
await addKeyPairToCacheAndDBIfNeeded(toHex(groupId), newKeyPair.toHexKeyPair());
};
// this is to be sent to the group pubkey adress
await getMessageQueue().sendToGroup(keypairsMessage, messageSentCallback);

@ -35,7 +35,7 @@ export async function send(
encryption
);
const envelope = await buildEnvelope(envelopeType, device.key, timestamp, cipherText);
window?.log?.debug('Sending envelope', envelope, ' to ', device.key);
window?.log?.debug('Sending envelope with timestamp: ', envelope.timestamp, ' to ', device.key);
const data = wrapEnvelope(envelope);
return pRetry(

Loading…
Cancel
Save