Path: blob/master/node_modules/@adiwajshing/baileys/WASignalGroup/group_cipher.js
1126 views
const SenderKeyMessage = require('./sender_key_message');1const crypto = require('libsignal/src/crypto');23class GroupCipher {4constructor(senderKeyStore, senderKeyName) {5this.senderKeyStore = senderKeyStore;6this.senderKeyName = senderKeyName;7}89async encrypt(paddedPlaintext) {10try {11const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);12const senderKeyState = record.getSenderKeyState();13const senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey();1415const ciphertext = await this.getCipherText(16senderKey.getIv(),17senderKey.getCipherKey(),18paddedPlaintext19);2021const senderKeyMessage = new SenderKeyMessage(22senderKeyState.getKeyId(),23senderKey.getIteration(),24ciphertext,25senderKeyState.getSigningKeyPrivate()26);27senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext());28await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);29return senderKeyMessage.serialize();30} catch (e) {31//console.log(e.stack);32throw new Error('NoSessionException');33}34}3536async decrypt(senderKeyMessageBytes) {37const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);38if (!record) throw new Error(`No sender key for: ${this.senderKeyName}`);3940const senderKeyMessage = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes);4142const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());43//senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());44const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());45// senderKeyState.senderKeyStateStructure.senderSigningKey.private =4647const plaintext = await this.getPlainText(48senderKey.getIv(),49senderKey.getCipherKey(),50senderKeyMessage.getCipherText()51);5253await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);5455return plaintext;56}5758getSenderKey(senderKeyState, iteration) {59let senderChainKey = senderKeyState.getSenderChainKey();60if (senderChainKey.getIteration() > iteration) {61if (senderKeyState.hasSenderMessageKey(iteration)) {62return senderKeyState.removeSenderMessageKey(iteration);63}64throw new Error(65`Received message with old counter: ${senderChainKey.getIteration()}, ${iteration}`66);67}6869if (senderChainKey.getIteration() - iteration > 2000) {70throw new Error('Over 2000 messages into the future!');71}7273while (senderChainKey.getIteration() < iteration) {74senderKeyState.addSenderMessageKey(senderChainKey.getSenderMessageKey());75senderChainKey = senderChainKey.getNext();76}7778senderKeyState.setSenderChainKey(senderChainKey.getNext());79return senderChainKey.getSenderMessageKey();80}8182getPlainText(iv, key, ciphertext) {83try {84const plaintext = crypto.decrypt(key, ciphertext, iv);85return plaintext;86} catch (e) {87//console.log(e.stack);88throw new Error('InvalidMessageException');89}90}9192getCipherText(iv, key, plaintext) {93try {94iv = typeof iv === 'string' ? Buffer.from(iv, 'base64') : iv;95key = typeof key === 'string' ? Buffer.from(key, 'base64') : key;96const crypted = crypto.encrypt(key, Buffer.from(plaintext), iv);97return crypted;98} catch (e) {99//console.log(e.stack);100throw new Error('InvalidMessageException');101}102}103}104105module.exports = GroupCipher;106107