cache identity pair and add some per measure

This commit is contained in:
Audric Ackermann 2021-07-13 14:18:33 +10:00
parent 92b6e51ac5
commit 399041c5b3
No known key found for this signature in database
GPG key ID: 999F434D76324AD4
5 changed files with 44 additions and 2 deletions

View file

@ -36,6 +36,7 @@ import { getSwarmPollingInstance } from '../session/snode_api';
import { MessageModel } from '../models/message';
import { updateConfirmModal } from '../state/ducks/modalDialog';
import { perfEnd, perfStart } from '../session/utils/Performance';
export const distributingClosedGroupEncryptionKeyPairs = new Map<string, ECKeyPair>();
@ -409,11 +410,14 @@ async function handleClosedGroupEncryptionKeyPair(
}
let plaintext: Uint8Array;
try {
perfStart(`encryptionKeyPair-${envelope.id}`);
const buffer = await decryptWithSessionProtocol(
envelope,
ourWrapper.encryptedKeyPair,
ECKeyPair.fromKeyPair(ourKeyPair)
);
perfEnd(`encryptionKeyPair-${envelope.id}`, 'encryptionKeyPair');
if (!buffer || buffer.byteLength === 0) {
throw new Error();

View file

@ -28,7 +28,10 @@ export async function handleContentMessage(envelope: EnvelopePlus) {
} else if (plaintext instanceof ArrayBuffer && plaintext.byteLength === 0) {
return;
}
perfStart(`innerHandleContentMessage-${envelope.id}`);
await innerHandleContentMessage(envelope, plaintext);
perfEnd(`innerHandleContentMessage-${envelope.id}`, 'innerHandleContentMessage');
} catch (e) {
window?.log?.warn(e);
}
@ -131,6 +134,7 @@ export async function decryptWithSessionProtocol(
x25519KeyPair: ECKeyPair,
isClosedGroup?: boolean
): Promise<ArrayBuffer> {
perfStart(`decryptWithSessionProtocol-${envelope.id}`);
const recipientX25519PrivateKey = x25519KeyPair.privateKeyData;
const hex = toHex(new Uint8Array(x25519KeyPair.publicKeyData));
@ -147,6 +151,8 @@ export async function decryptWithSessionProtocol(
new Uint8Array(recipientX25519PrivateKey)
);
if (plaintextWithMetadata.byteLength <= signatureSize + ed25519PublicKeySize) {
perfEnd(`decryptWithSessionProtocol-${envelope.id}`, 'decryptWithSessionProtocol');
throw new Error('Decryption failed.'); // throw Error.decryptionFailed;
}
@ -167,11 +173,15 @@ export async function decryptWithSessionProtocol(
);
if (!isValid) {
perfEnd(`decryptWithSessionProtocol-${envelope.id}`, 'decryptWithSessionProtocol');
throw new Error('Invalid message signature.'); //throw Error.invalidSignature
}
// 4. ) Get the sender's X25519 public key
const senderX25519PublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(senderED25519PublicKey);
if (!senderX25519PublicKey) {
perfEnd(`decryptWithSessionProtocol-${envelope.id}`, 'decryptWithSessionProtocol');
throw new Error('Decryption failed.'); // Error.decryptionFailed
}
@ -181,6 +191,8 @@ export async function decryptWithSessionProtocol(
} else {
envelope.source = `05${toHex(senderX25519PublicKey)}`;
}
perfEnd(`decryptWithSessionProtocol-${envelope.id}`, 'decryptWithSessionProtocol');
return plaintext;
}
@ -195,16 +207,25 @@ async function decryptUnidentifiedSender(
window?.log?.info('received unidentified sender message');
try {
const userX25519KeyPair = await UserUtils.getIdentityKeyPair();
if (!userX25519KeyPair) {
throw new Error('Failed to find User x25519 keypair from stage'); // noUserX25519KeyPair
}
const ecKeyPair = ECKeyPair.fromArrayBuffer(
userX25519KeyPair.pubKey,
userX25519KeyPair.privKey
);
// keep the await so the try catch works as expected
perfStart(`decryptUnidentifiedSender-${envelope.id}`);
const retSessionProtocol = await decryptWithSessionProtocol(envelope, ciphertext, ecKeyPair);
return removeMessagePadding(retSessionProtocol);
const ret = removeMessagePadding(retSessionProtocol);
perfEnd(`decryptUnidentifiedSender-${envelope.id}`, 'decryptUnidentifiedSender');
return ret;
} catch (e) {
window?.log?.warn('decryptWithSessionProtocol for unidentified message throw:', e);
return null;
@ -241,12 +262,15 @@ async function decrypt(envelope: EnvelopePlus, ciphertext: ArrayBuffer): Promise
return null;
}
perfStart(`updateCache-${envelope.id}`);
await updateCache(envelope, plaintext).catch((error: any) => {
window?.log?.error(
'decrypt failed to save decrypted message contents to cache:',
error && error.stack ? error.stack : error
);
});
perfEnd(`updateCache-${envelope.id}`, 'updateCache');
return plaintext;
} catch (error) {

View file

@ -37,6 +37,7 @@ import { fromBase64ToArray } from '../session/utils/String';
import { removeMessagePadding } from '../session/crypto/BufferPadding';
import { isDuplicateBasedOnHash } from './hashDuplicateFilter';
import { createTaskWithTimeout } from '../session/utils/TaskWithTimeout';
import { perfEnd, perfStart } from '../session/utils/Performance';
// TODO: check if some of these exports no longer needed
@ -141,8 +142,10 @@ async function handleRequestDetail(
// NOTE: Annoyngly we add plaintext to the cache
// after we've already processed some of it (thus the
// need to handle senderIdentity separately)...
perfStart(`addToCache-${envelope.id}`);
await addToCache(envelope, plaintext);
perfEnd(`addToCache-${envelope.id}`, 'addToCache');
// TODO: This is the glue between the first and the last part of the
// receiving pipeline refactor. It is to be implemented in the next PR.

View file

@ -16,6 +16,7 @@ import { StringUtils, UserUtils } from '../../session/utils';
import { ConversationModel } from '../../models/conversation';
import { DURATION, SWARM_POLLING_TIMEOUT } from '../constants';
import { getConversationController } from '../conversations';
import { perfEnd, perfStart } from '../utils/Performance';
type PubkeyToHash = { [key: string]: string };
@ -213,8 +214,12 @@ export class SwarmPolling {
});
}
perfStart(`handleSeenMessages-${pkStr}`);
const newMessages = await this.handleSeenMessages(messages);
perfEnd(`handleSeenMessages-${pkStr}`, 'handleSeenMessages');
newMessages.forEach((m: Message) => {
const options = isGroup ? { conversationId: pkStr } : {};
processMessage(m.data, options);

View file

@ -46,13 +46,19 @@ export function getOurPubKeyFromCache(): PubKey {
return PubKey.cast(ourNumber);
}
let cachedIdentityKeyPair: KeyPair | undefined;
/**
* This return the stored x25519 identity keypair for the current logged in user
*/
export async function getIdentityKeyPair(): Promise<KeyPair | undefined> {
if (cachedIdentityKeyPair) {
return cachedIdentityKeyPair;
}
const item = await getItemById('identityKey');
return item?.value;
cachedIdentityKeyPair = item?.value;
return cachedIdentityKeyPair;
}
export async function getUserED25519KeyPair(): Promise<HexKeyPair | undefined> {