Path: blob/master/node_modules/@adiwajshing/baileys/lib/Utils/signal.js
2593 views
"use strict";1var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {2if (k2 === undefined) k2 = k;3Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });4}) : (function(o, m, k, k2) {5if (k2 === undefined) k2 = k;6o[k2] = m[k];7}));8var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {9Object.defineProperty(o, "default", { enumerable: true, value: v });10}) : function(o, v) {11o["default"] = v;12});13var __importStar = (this && this.__importStar) || function (mod) {14if (mod && mod.__esModule) return mod;15var result = {};16if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);17__setModuleDefault(result, mod);18return result;19};20Object.defineProperty(exports, "__esModule", { value: true });21exports.extractDeviceJids = exports.parseAndInjectE2ESessions = exports.encryptSenderKeyMsgSignalProto = exports.encryptSignalProto = exports.decryptSignalProto = exports.processSenderKeyMessage = exports.decryptGroupSignalProto = exports.signalStorage = exports.xmppPreKey = exports.xmppSignedPreKey = exports.generateOrGetPreKeys = exports.getPreKeys = exports.createSignalIdentity = exports.jidToSignalSenderKeyName = exports.jidToSignalProtocolAddress = exports.generateSignalPubKey = void 0;22const libsignal = __importStar(require("libsignal"));23const WASignalGroup_1 = require("../../WASignalGroup");24const WABinary_1 = require("../WABinary");25const crypto_1 = require("./crypto");26const generics_1 = require("./generics");27const generateSignalPubKey = (pubKey) => {28const newPub = Buffer.alloc(33);29newPub.set([5], 0);30newPub.set(pubKey, 1);31return newPub;32};33exports.generateSignalPubKey = generateSignalPubKey;34const jidToSignalAddress = (jid) => jid.split('@')[0];35const jidToSignalProtocolAddress = (jid) => {36return new libsignal.ProtocolAddress(jidToSignalAddress(jid), 0);37};38exports.jidToSignalProtocolAddress = jidToSignalProtocolAddress;39const jidToSignalSenderKeyName = (group, user) => {40return new WASignalGroup_1.SenderKeyName(group, exports.jidToSignalProtocolAddress(user)).toString();41};42exports.jidToSignalSenderKeyName = jidToSignalSenderKeyName;43const createSignalIdentity = (wid, accountSignatureKey) => {44return {45identifier: { name: wid, deviceId: 0 },46identifierKey: exports.generateSignalPubKey(accountSignatureKey)47};48};49exports.createSignalIdentity = createSignalIdentity;50const getPreKeys = async ({ get }, min, limit) => {51const idList = [];52for (let id = min; id < limit; id++) {53idList.push(id.toString());54}55return get('pre-key', idList);56};57exports.getPreKeys = getPreKeys;58const generateOrGetPreKeys = (creds, range) => {59const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId;60const remaining = range - avaliable;61const lastPreKeyId = creds.nextPreKeyId + remaining - 1;62const newPreKeys = {};63if (remaining > 0) {64for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {65newPreKeys[i] = crypto_1.Curve.generateKeyPair();66}67}68return {69newPreKeys,70lastPreKeyId,71preKeysRange: [creds.firstUnuploadedPreKeyId, range],72};73};74exports.generateOrGetPreKeys = generateOrGetPreKeys;75const xmppSignedPreKey = (key) => ({76tag: 'skey',77attrs: {},78content: [79{ tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(key.keyId, 3) },80{ tag: 'value', attrs: {}, content: key.keyPair.public },81{ tag: 'signature', attrs: {}, content: key.signature }82]83});84exports.xmppSignedPreKey = xmppSignedPreKey;85const xmppPreKey = (pair, id) => ({86tag: 'key',87attrs: {},88content: [89{ tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(id, 3) },90{ tag: 'value', attrs: {}, content: pair.public }91]92});93exports.xmppPreKey = xmppPreKey;94const signalStorage = ({ creds, keys }) => ({95loadSession: async (id) => {96const { [id]: sess } = await keys.get('session', [id]);97if (sess) {98return libsignal.SessionRecord.deserialize(sess);99}100},101storeSession: async (id, session) => {102await keys.set({ 'session': { [id]: session.serialize() } });103},104isTrustedIdentity: () => {105return true;106},107loadPreKey: async (id) => {108const keyId = id.toString();109const { [keyId]: key } = await keys.get('pre-key', [keyId]);110if (key) {111return {112privKey: Buffer.from(key.private),113pubKey: Buffer.from(key.public)114};115}116},117removePreKey: (id) => keys.set({ 'pre-key': { [id]: null } }),118loadSignedPreKey: (keyId) => {119const key = creds.signedPreKey;120return {121privKey: Buffer.from(key.keyPair.private),122pubKey: Buffer.from(key.keyPair.public)123};124},125loadSenderKey: async (keyId) => {126const { [keyId]: key } = await keys.get('sender-key', [keyId]);127if (key) {128return new WASignalGroup_1.SenderKeyRecord(key);129}130},131storeSenderKey: async (keyId, key) => {132await keys.set({ 'sender-key': { [keyId]: key.serialize() } });133},134getOurRegistrationId: () => (creds.registrationId),135getOurIdentity: () => {136const { signedIdentityKey } = creds;137return {138privKey: Buffer.from(signedIdentityKey.private),139pubKey: exports.generateSignalPubKey(signedIdentityKey.public),140};141}142});143exports.signalStorage = signalStorage;144const decryptGroupSignalProto = (group, user, msg, auth) => {145const senderName = exports.jidToSignalSenderKeyName(group, user);146const cipher = new WASignalGroup_1.GroupCipher(exports.signalStorage(auth), senderName);147return cipher.decrypt(Buffer.from(msg));148};149exports.decryptGroupSignalProto = decryptGroupSignalProto;150const processSenderKeyMessage = async (authorJid, item, auth) => {151const builder = new WASignalGroup_1.GroupSessionBuilder(exports.signalStorage(auth));152const senderName = exports.jidToSignalSenderKeyName(item.groupId, authorJid);153const senderMsg = new WASignalGroup_1.SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage);154const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]);155if (!senderKey) {156const record = new WASignalGroup_1.SenderKeyRecord();157await auth.keys.set({ 'sender-key': { [senderName]: record } });158}159await builder.process(senderName, senderMsg);160};161exports.processSenderKeyMessage = processSenderKeyMessage;162const decryptSignalProto = async (user, type, msg, auth) => {163const addr = exports.jidToSignalProtocolAddress(user);164const session = new libsignal.SessionCipher(exports.signalStorage(auth), addr);165let result;166switch (type) {167case 'pkmsg':168result = await session.decryptPreKeyWhisperMessage(msg);169break;170case 'msg':171result = await session.decryptWhisperMessage(msg);172break;173}174return result;175};176exports.decryptSignalProto = decryptSignalProto;177const encryptSignalProto = async (user, buffer, auth) => {178const addr = exports.jidToSignalProtocolAddress(user);179const cipher = new libsignal.SessionCipher(exports.signalStorage(auth), addr);180const { type, body } = await cipher.encrypt(buffer);181return {182type: type === 3 ? 'pkmsg' : 'msg',183ciphertext: Buffer.from(body, 'binary')184};185};186exports.encryptSignalProto = encryptSignalProto;187const encryptSenderKeyMsgSignalProto = async (group, data, meId, auth) => {188const storage = exports.signalStorage(auth);189const senderName = exports.jidToSignalSenderKeyName(group, meId);190const builder = new WASignalGroup_1.GroupSessionBuilder(storage);191const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]);192if (!senderKey) {193const record = new WASignalGroup_1.SenderKeyRecord();194await auth.keys.set({ 'sender-key': { [senderName]: record } });195}196const senderKeyDistributionMessage = await builder.create(senderName);197const session = new WASignalGroup_1.GroupCipher(storage, senderName);198return {199ciphertext: await session.encrypt(data),200senderKeyDistributionMessageKey: senderKeyDistributionMessage.serialize(),201};202};203exports.encryptSenderKeyMsgSignalProto = encryptSenderKeyMsgSignalProto;204const parseAndInjectE2ESessions = async (node, auth) => {205const extractKey = (key) => (key ? ({206keyId: WABinary_1.getBinaryNodeChildUInt(key, 'id', 3),207publicKey: exports.generateSignalPubKey(WABinary_1.getBinaryNodeChildBuffer(key, 'value')),208signature: WABinary_1.getBinaryNodeChildBuffer(key, 'signature'),209}) : undefined);210const nodes = WABinary_1.getBinaryNodeChildren(WABinary_1.getBinaryNodeChild(node, 'list'), 'user');211for (const node of nodes) {212WABinary_1.assertNodeErrorFree(node);213}214await Promise.all(nodes.map(async (node) => {215const signedKey = WABinary_1.getBinaryNodeChild(node, 'skey');216const key = WABinary_1.getBinaryNodeChild(node, 'key');217const identity = WABinary_1.getBinaryNodeChildBuffer(node, 'identity');218const jid = node.attrs.jid;219const registrationId = WABinary_1.getBinaryNodeChildUInt(node, 'registration', 4);220const device = {221registrationId,222identityKey: exports.generateSignalPubKey(identity),223signedPreKey: extractKey(signedKey),224preKey: extractKey(key)225};226const cipher = new libsignal.SessionBuilder(exports.signalStorage(auth), exports.jidToSignalProtocolAddress(jid));227await cipher.initOutgoing(device);228}));229};230exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions;231const extractDeviceJids = (result, myJid, excludeZeroDevices) => {232var _a;233const { user: myUser, device: myDevice } = WABinary_1.jidDecode(myJid);234const extracted = [];235for (const node of result.content) {236const list = (_a = WABinary_1.getBinaryNodeChild(node, 'list')) === null || _a === void 0 ? void 0 : _a.content;237if (list && Array.isArray(list)) {238for (const item of list) {239const { user } = WABinary_1.jidDecode(item.attrs.jid);240const devicesNode = WABinary_1.getBinaryNodeChild(item, 'devices');241const deviceListNode = WABinary_1.getBinaryNodeChild(devicesNode, 'device-list');242if (Array.isArray(deviceListNode === null || deviceListNode === void 0 ? void 0 : deviceListNode.content)) {243for (const { tag, attrs } of deviceListNode.content) {244const device = +attrs.id;245if (tag === 'device' && // ensure the "device" tag246(!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero247(myUser !== user || myDevice !== device) && // either different user or if me user, not this device248(device === 0 || !!attrs['key-index']) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise249) {250extracted.push({ user, device });251}252}253}254}255}256}257return extracted;258};259exports.extractDeviceJids = extractDeviceJids;260261262