Skip to content

Commit 5237c47

Browse files
author
Erika Perugachi
authored
Merge pull request #336 from JulianAdams4/fix-session
Fix external session
2 parents aef3880 + 56b9e63 commit 5237c47

File tree

3 files changed

+87
-23
lines changed

3 files changed

+87
-23
lines changed

email_composer/src/containers/Composer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class ComposerWrapper extends Component {
134134
: Status.DISABLED;
135135
state = { ...composerData, status };
136136
}
137-
const { key, iv } = generateKeyAndIv(null, 8, null);
137+
const { key, iv } = generateKeyAndIv(null, 8);
138138
state = { ...state, key, iv };
139139
fileManager.on(FILE_PROGRESS, this.handleUploadProgress);
140140
fileManager.on(FILE_FINISH, this.handleUploadSuccess);

email_composer/src/libs/signal.js

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ import {
99
import SignalProtocolStore from './store';
1010
import { CustomError } from './../utils/CustomError';
1111
import {
12-
AesEncryptToBase64,
12+
AesEncrypt,
1313
generateKeyAndIv,
14-
base64ToWordArray
14+
base64ToWordArray,
15+
wordArrayToByteArray,
16+
wordArrayToBase64,
17+
byteArrayToWordArray
1518
} from '../utils/AESUtils';
1619

1720
const KeyHelper = libsignal.KeyHelper;
@@ -199,6 +202,7 @@ const encryptPostEmail = async ({
199202
peer,
200203
fileKeyParams
201204
);
205+
const fileKey = criptextEmails[0] ? criptextEmails[0].fileKey : null;
202206

203207
const allExternalRecipients = [
204208
...externalRecipients.to,
@@ -207,7 +211,7 @@ const encryptPostEmail = async ({
207211
];
208212
const hasExternalRecipients = allExternalRecipients.length > 0;
209213
const { session, encryptedBody } = externalEmailPassword.length
210-
? await encryptExternalEmail(body, externalEmailPassword)
214+
? await encryptExternalEmail(body, externalEmailPassword, fileKey)
211215
: { session: null, encryptedBody: null };
212216

213217
const guestEmail = hasExternalRecipients
@@ -235,7 +239,7 @@ const encryptPostEmail = async ({
235239
return res;
236240
};
237241

238-
const createDummyKeyBundle = async () => {
242+
const createDummyKeyBundle = async fileKey => {
239243
const preKeyId = 1;
240244
const signedPreKeyId = 1;
241245
const { identityKey, registrationId } = await generateIdentity();
@@ -252,6 +256,7 @@ const createDummyKeyBundle = async () => {
252256
signedPreKey
253257
};
254258
const dummySession = {
259+
fileKey,
255260
identityKey: {
256261
publicKey: util.toBase64(identityKey.pubKey),
257262
privateKey: util.toBase64(identityKey.privKey)
@@ -295,10 +300,10 @@ const generatePreKeyBundle = async ({
295300
return { preKey, signedPreKey };
296301
};
297302

298-
const encryptExternalEmail = async (body, password) => {
303+
const encryptExternalEmail = async (body, password, fileKey) => {
299304
const recipient = password;
300305
const deviceId = 1;
301-
const { dummySession, sessionParams } = await createDummyKeyBundle();
306+
const { dummySession, sessionParams } = await createDummyKeyBundle(fileKey);
302307
const keys = {
303308
preKey: {
304309
id: sessionParams.preKey.keyId,
@@ -319,12 +324,26 @@ const encryptExternalEmail = async (body, password) => {
319324
);
320325

321326
const saltLength = 8;
322-
const keyLength = 128 / 32;
323-
const { key, iv } = generateKeyAndIv(password, saltLength, keyLength);
324-
const keyArray = base64ToWordArray(key);
325-
const ivArray = base64ToWordArray(iv);
326-
const sessionString = JSON.stringify(dummySession);
327-
const session = AesEncryptToBase64(sessionString, keyArray, ivArray);
327+
const { key, iv, salt } = generateKeyAndIv(password, saltLength);
328+
const saltWArray = base64ToWordArray(salt);
329+
const ivWArray = base64ToWordArray(iv);
330+
const keyWArray = base64ToWordArray(key);
331+
332+
const dummySessionString = JSON.stringify(dummySession);
333+
const encryptedSessionWArray = AesEncrypt(
334+
dummySessionString,
335+
keyWArray,
336+
ivWArray
337+
);
338+
const saltBArray = wordArrayToByteArray(saltWArray);
339+
const ivBArray = wordArrayToByteArray(ivWArray);
340+
const encryptedSessionBArray = wordArrayToByteArray(encryptedSessionWArray);
341+
const sessionByteArray = saltBArray.concat(
342+
ivBArray.concat(encryptedSessionBArray)
343+
);
344+
345+
const sessionWordArray = byteArrayToWordArray(sessionByteArray);
346+
const session = wordArrayToBase64(sessionWordArray);
328347
return {
329348
session,
330349
encryptedBody: encryptedBody.body
Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,71 @@
11
import CryptoJS from 'crypto-js';
22

3-
export const generateKeyAndIv = (phrase, saltsize, keysize) => {
3+
export const generateKeyAndIv = (phrase, saltsize) => {
44
const passphrase = phrase || CryptoJS.lib.WordArray.random(saltsize);
5-
const keySalt = CryptoJS.lib.WordArray.random(saltsize);
6-
const ivSalt = CryptoJS.lib.WordArray.random(saltsize);
5+
const salt = CryptoJS.lib.WordArray.random(saltsize);
76
const keyParams = {
8-
keySize: keysize || 128 / 32,
9-
iterations: 1000
7+
keySize: 128 / 32,
8+
iterations: 10000,
9+
hasher: CryptoJS.algo.SHA256
1010
};
11-
const keyArray = CryptoJS.PBKDF2(passphrase, keySalt, keyParams);
12-
const ivArray = CryptoJS.PBKDF2(passphrase, ivSalt, keyParams);
11+
const keyArray = CryptoJS.PBKDF2(passphrase, salt, keyParams);
12+
const ivArray = CryptoJS.lib.WordArray.random(16);
1313
return {
1414
key: keyArray.toString(CryptoJS.enc.Base64),
15-
iv: ivArray.toString(CryptoJS.enc.Base64)
15+
iv: ivArray.toString(CryptoJS.enc.Base64),
16+
salt: salt.toString(CryptoJS.enc.Base64)
1617
};
1718
};
1819

19-
export const AesEncryptToBase64 = (data, keyArray, ivArray) => {
20+
export const AesEncrypt = (data, keyArray, ivArray) => {
2021
const encrypted = CryptoJS.AES.encrypt(data, keyArray, { iv: ivArray });
21-
return encrypted.toString();
22+
const based64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
23+
return base64ToWordArray(based64);
2224
};
2325

2426
export const base64ToWordArray = base64String => {
2527
return CryptoJS.enc.Base64.parse(base64String);
2628
};
29+
30+
export const wordArrayToBase64 = wordArray => {
31+
return CryptoJS.enc.Base64.stringify(wordArray);
32+
};
33+
34+
export const byteArrayToWordArray = bytearray => {
35+
const wa = [];
36+
let i;
37+
for (i = 0; i < bytearray.length; i++) {
38+
wa[(i / 4) | 0] |= bytearray[i] << (24 - 8 * i);
39+
}
40+
return CryptoJS.lib.WordArray.create(wa, bytearray.length);
41+
};
42+
43+
const wordToByteArray = (word, length) => {
44+
const ba = [];
45+
const xFF = 0xff;
46+
if (length > 0) ba.push(word >>> 24);
47+
if (length > 1) ba.push((word >>> 16) & xFF);
48+
if (length > 2) ba.push((word >>> 8) & xFF);
49+
if (length > 3) ba.push(word & xFF);
50+
return ba;
51+
};
52+
53+
export const wordArrayToByteArray = (wordarray, length) => {
54+
if (
55+
wordarray.hasOwnProperty('sigBytes') &&
56+
wordarray.hasOwnProperty('words')
57+
) {
58+
length = wordarray.sigBytes;
59+
wordarray = wordarray.words;
60+
}
61+
const result = [];
62+
let i = 0;
63+
let bytes;
64+
while (length > 0) {
65+
bytes = wordToByteArray(wordarray[i], Math.min(4, length));
66+
length -= bytes.length;
67+
result.push(bytes);
68+
i++;
69+
}
70+
return [].concat.apply([], result);
71+
};

0 commit comments

Comments
 (0)