This commit is contained in:
Jiiks 2018-08-12 21:43:59 +03:00
parent b24c0ba2f3
commit 2b833b5141
4 changed files with 48 additions and 16 deletions

View File

@ -18,6 +18,7 @@ import { Utils } from 'common';
import E2EEComponent from './E2EEComponent.vue';
import E2EEMessageButton from './E2EEMessageButton.vue';
import aes256 from 'aes256';
import crypto from 'node-crypto';
let seed = Math.random().toString(36).replace(/[^a-z]+/g, '');
@ -58,6 +59,12 @@ export default new class E2EE extends BuiltinModule {
return aes256.decrypt(key, content.replace(prefix, ''));
}
async createHmac(data) {
const haveKey = this.getKey(DiscordApi.currentChannel.id);
if (!haveKey) return null;
return Security.createHmac(haveKey, data);
}
getKey(channelId) {
const haveKey = this.database.find(kvp => kvp.value.key === channelId);
if (!haveKey) return null;
@ -65,7 +72,6 @@ export default new class E2EE extends BuiltinModule {
}
async enabled(e) {
window.sec = Security;
this.patchMessageContent();
const selector = '.' + WebpackModules.getClassName('channelTextArea', 'emojiButton');
const cta = await ReactComponents.getComponent('ChannelTextArea', { selector });
@ -141,22 +147,32 @@ export default new class E2EE extends BuiltinModule {
component.props.readyState = 'LOADING';
Logger.info('E2EE', 'Decrypting image: ' + src);
request.get(src, { encoding: 'binary' }).then(res => {
const arr = new Uint8Array(new ArrayBuffer(res.length));
for (let i = 0; i < res.length; i++) arr[i] = res.charCodeAt(i);
(async () => {
const arr = new Uint8Array(new ArrayBuffer(res.length));
for (let i = 0; i < res.length; i++) arr[i] = res.charCodeAt(i);
const aobindex = Utils.aobscan(arr, [73, 69, 78, 68]) + 8;
const sliced = arr.slice(aobindex);
const image = new TextDecoder().decode(sliced);
const aobindex = Utils.aobscan(arr, [73, 69, 78, 68]) + 8;
const sliced = arr.slice(aobindex);
const image = new TextDecoder().decode(sliced);
Cache.push('e2ee:images', { src, image });
const hmac = image.slice(-64);
const data = image.slice(0, -64);
const validateHmac = await this.createHmac(data);
if (hmac !== validateHmac) {
console.log('INVALID HMAC!');
return;
}
if (!component || !component.props) {
Logger.warn('E2EE', 'Component seems to be gone');
return;
}
Cache.push('e2ee:images', { src, image: data });
component.props.decrypting = false;
component.forceUpdate();
if (!component || !component.props) {
Logger.warn('E2EE', 'Component seems to be gone');
return;
}
component.props.decrypting = false;
component.forceUpdate();
})();
}).catch(err => {
console.log('request error', err);
});

View File

@ -69,8 +69,9 @@
canvas.height = img.height;
canvas.width = img.width;
const arrBuffer = await Utils.canvasToArrayBuffer(canvas);
const encodedBytes = new TextEncoder().encode(E2EE.encrypt(img.src.replace('data:;base64,', '')));
const encrypted = E2EE.encrypt(img.src.replace('data:;base64,', ''));
const hmac = await E2EE.createHmac(encrypted);
const encodedBytes = new TextEncoder().encode(encrypted + hmac);
Uploader.upload(DiscordApi.currentChannel.id, FileActions.makeFile(new Uint8Array([...new Uint8Array(arrBuffer), ...encodedBytes]), 'bde2ee.png'));
},
toggleEncrypt() {

View File

@ -8,6 +8,7 @@
* LICENSE file in the root directory of this source tree.
*/
import nodecrypto from 'node-crypto';
import aes256 from 'aes256';
export default class Security {
@ -40,4 +41,17 @@ export default class Security {
return decrypt;
}
static async createHmac(key, data, algorithm = 'sha256') {
const hmac = nodecrypto.createHmac(algorithm, key);
return new Promise((resolve, reject) => {
hmac.on('readable', () => {
const data = hmac.read();
if (data) return resolve(data.toString('hex'));
reject(null);
});
hmac.write(data);
hmac.end();
});
}
}

View File

@ -38,7 +38,8 @@ module.exports = {
process: 'require("process")',
net: 'require("net")',
request: 'require(require("path").join(require("electron").remote.app.getAppPath(), "node_modules", "request"))',
sparkplug: 'require("../../core/dist/sparkplug")'
sparkplug: 'require("../../core/dist/sparkplug")',
'node-crypto': 'require("crypto")'
},
resolve: {
alias: {