UNPKG

@tgsnake/core

Version:

Pure Telegram MTProto library for nodejs

141 lines (140 loc) 6.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TCPAbridgedO = void 0; const tcp_js_1 = require("./tcp.js"); const helpers_js_1 = require("../../helpers.js"); const platform_node_js_1 = require("../../platform.node.js"); const Aes_js_1 = require("../../crypto/Aes.js"); class TCPAbridgedO extends tcp_js_1.TCP { _reserved; _encryptor; _decryptor; constructor() { super(); this._reserved = [ platform_node_js_1.Buffer.from('HEAD'), platform_node_js_1.Buffer.from('POST'), platform_node_js_1.Buffer.from('GET'), platform_node_js_1.Buffer.from('OPTI'), platform_node_js_1.Buffer.from('eeeeeeee', 'hex'), ]; } async connect(ip, port, proxy, dcId) { await super.connect(ip, port, proxy, dcId); let nonce; if (proxy && 'secret' in proxy && 'port' in proxy && 'server' in proxy && dcId) { let secret = typeof proxy.secret === 'string' ? (0, helpers_js_1.normalizeSecretString)(proxy.secret) : platform_node_js_1.Buffer.from(proxy.secret); secret = platform_node_js_1.Buffer.byteLength(secret) === 17 && secret[0] === 0xdd ? secret.subarray(1) : secret; while (true) { nonce = platform_node_js_1.crypto.randomBytes(64); if (!platform_node_js_1.Buffer.from([nonce[0]]).equals(platform_node_js_1.Buffer.from('ef', 'hex')) && !(0, helpers_js_1.includesBuffer)(this._reserved, nonce) && !nonce.subarray(4, 8).equals(platform_node_js_1.Buffer.alloc(4))) { nonce[56] = nonce[57] = nonce[58] = nonce[59] = 0xef; break; } } const temp = (0, helpers_js_1.sliceBuffer)(nonce, 55, 7, -1); const encryptionKey = sha256(platform_node_js_1.Buffer.concat([ nonce.subarray(8, 40), secret, ])); const encryptionIv = nonce.subarray(40, 56); const decryptionKey = sha256(platform_node_js_1.Buffer.concat([ temp.subarray(0, 32), secret, ])); const decryptionIv = temp.subarray(32, 48); this._encryptor = (0, Aes_js_1.ctr256Cipher)(encryptionKey, encryptionIv); this._decryptor = (0, Aes_js_1.ctr256Cipher)(decryptionKey, decryptionIv); const _dcId = platform_node_js_1.Buffer.alloc(2); _dcId.writeInt8(dcId, 0); nonce = platform_node_js_1.Buffer.concat([ nonce.subarray(0, 60), _dcId, nonce.subarray(62), ]); nonce = platform_node_js_1.Buffer.concat([ nonce.subarray(0, 56), this._encryptor(nonce).subarray(56, 64), ]); } else { while (true) { nonce = platform_node_js_1.crypto.randomBytes(64); if (!platform_node_js_1.Buffer.from([nonce[0]]).equals(platform_node_js_1.Buffer.from('ef', 'hex')) && !(0, helpers_js_1.includesBuffer)(this._reserved, nonce) && !nonce.subarray(4, 8).equals(platform_node_js_1.Buffer.alloc(4))) { nonce[56] = nonce[57] = nonce[58] = nonce[59] = 0xef; break; } } const temp = (0, helpers_js_1.sliceBuffer)(nonce, 55, 7, -1); const encryptionKey = nonce.subarray(8, 40); const encryptionIv = nonce.subarray(40, 56); const decryptionKey = temp.subarray(0, 32); const decryptionIv = temp.subarray(32, 48); this._encryptor = (0, Aes_js_1.ctr256Cipher)(encryptionKey, encryptionIv); this._decryptor = (0, Aes_js_1.ctr256Cipher)(decryptionKey, decryptionIv); nonce = platform_node_js_1.Buffer.concat([ nonce.subarray(0, 56), this._encryptor(nonce).subarray(56, 64), ]); } await super.send(nonce); } async send(data) { const length = Math.round(platform_node_js_1.Buffer.byteLength(data) / 4); if (length <= 126) { return await super.send(this._encryptor(platform_node_js_1.Buffer.concat([ platform_node_js_1.Buffer.from([length]), data, ]))); } else { return await super.send(this._encryptor(platform_node_js_1.Buffer.concat([ platform_node_js_1.Buffer.concat([ platform_node_js_1.Buffer.from('7f', 'hex'), (0, helpers_js_1.bigintToBuffer)(BigInt(length), 3), ]), data, ]))); } } async recv(_length = 0) { let length = await super.recv(1); if (!length) return; length = platform_node_js_1.Buffer.from(this._decryptor(length)); if (length.equals(platform_node_js_1.Buffer.from('7f', 'hex'))) { length = await super.recv(3); if (!length) return; length = platform_node_js_1.Buffer.from(this._decryptor(length)); return platform_node_js_1.Buffer.from(this._decryptor((await super.recv(platform_node_js_1.Buffer.concat([ length, platform_node_js_1.Buffer.alloc(1), ]).readInt32LE(0) * 4)))); } return platform_node_js_1.Buffer.from(this._decryptor((await super.recv(length[0] * 4)))); } } exports.TCPAbridgedO = TCPAbridgedO; function sha256(data) { const hash = platform_node_js_1.crypto.createHash('sha256'); hash.update(data); return hash.digest(); }