@mtcute/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/base-client.js +4 -1
- package/cjs/base-client.js.map +1 -1
- package/cjs/network/auth-key.d.ts +3 -3
- package/cjs/network/auth-key.js +12 -12
- package/cjs/network/auth-key.js.map +1 -1
- package/cjs/network/authorization.js +62 -57
- package/cjs/network/authorization.js.map +1 -1
- package/cjs/network/mtproto-session.d.ts +2 -2
- package/cjs/network/mtproto-session.js +2 -2
- package/cjs/network/mtproto-session.js.map +1 -1
- package/cjs/network/multi-session-connection.d.ts +1 -1
- package/cjs/network/multi-session-connection.js +2 -2
- package/cjs/network/multi-session-connection.js.map +1 -1
- package/cjs/network/network-manager.d.ts +1 -0
- package/cjs/network/network-manager.js +21 -27
- package/cjs/network/network-manager.js.map +1 -1
- package/cjs/network/session-connection.d.ts +2 -1
- package/cjs/network/session-connection.js +48 -35
- package/cjs/network/session-connection.js.map +1 -1
- package/cjs/network/transports/intermediate.d.ts +3 -0
- package/cjs/network/transports/intermediate.js +5 -3
- package/cjs/network/transports/intermediate.js.map +1 -1
- package/cjs/network/transports/obfuscated.js +14 -18
- package/cjs/network/transports/obfuscated.js.map +1 -1
- package/cjs/storage/abstract.d.ts +23 -2
- package/cjs/storage/abstract.js.map +1 -1
- package/cjs/storage/json.js +8 -9
- package/cjs/storage/json.js.map +1 -1
- package/cjs/storage/localstorage.js +5 -2
- package/cjs/storage/localstorage.js.map +1 -1
- package/cjs/storage/memory.d.ts +7 -8
- package/cjs/storage/memory.js +7 -7
- package/cjs/storage/memory.js.map +1 -1
- package/cjs/utils/bigint-utils.d.ts +18 -11
- package/cjs/utils/bigint-utils.js +148 -47
- package/cjs/utils/bigint-utils.js.map +1 -1
- package/cjs/utils/buffer-utils.d.ts +7 -1
- package/cjs/utils/buffer-utils.js +16 -3
- package/cjs/utils/buffer-utils.js.map +1 -1
- package/cjs/utils/crypto/abstract.d.ts +16 -9
- package/cjs/utils/crypto/abstract.js +6 -9
- package/cjs/utils/crypto/abstract.js.map +1 -1
- package/cjs/utils/crypto/factorization.d.ts +2 -1
- package/cjs/utils/crypto/factorization.js +28 -36
- package/cjs/utils/crypto/factorization.js.map +1 -1
- package/cjs/utils/crypto/index.d.ts +4 -0
- package/cjs/utils/crypto/index.js +4 -0
- package/cjs/utils/crypto/index.js.map +1 -1
- package/cjs/utils/crypto/keys.d.ts +2 -2
- package/cjs/utils/crypto/keys.js +4 -4
- package/cjs/utils/crypto/keys.js.map +1 -1
- package/cjs/utils/crypto/miller-rabin.d.ts +2 -2
- package/cjs/utils/crypto/miller-rabin.js +20 -22
- package/cjs/utils/crypto/miller-rabin.js.map +1 -1
- package/cjs/utils/crypto/mtproto.d.ts +3 -3
- package/cjs/utils/crypto/mtproto.js +12 -12
- package/cjs/utils/crypto/mtproto.js.map +1 -1
- package/cjs/utils/crypto/node.d.ts +21 -0
- package/cjs/utils/crypto/node.js +74 -0
- package/cjs/utils/crypto/node.js.map +1 -0
- package/cjs/utils/crypto/password.js +22 -33
- package/cjs/utils/crypto/password.js.map +1 -1
- package/cjs/utils/crypto/wasm.d.ts +22 -0
- package/cjs/utils/crypto/wasm.js +41 -0
- package/cjs/utils/crypto/wasm.js.map +1 -0
- package/cjs/utils/crypto/web.d.ts +11 -0
- package/cjs/utils/crypto/web.js +40 -0
- package/cjs/utils/crypto/web.js.map +1 -0
- package/cjs/utils/deque.d.ts +1 -1
- package/cjs/utils/deque.js +9 -3
- package/cjs/utils/deque.js.map +1 -1
- package/cjs/utils/function-utils.d.ts +4 -1
- package/cjs/utils/function-utils.js +8 -1
- package/cjs/utils/function-utils.js.map +1 -1
- package/cjs/utils/index.d.ts +0 -1
- package/cjs/utils/index.js +0 -1
- package/cjs/utils/index.js.map +1 -1
- package/cjs/utils/logger.d.ts +0 -1
- package/cjs/utils/logger.js +3 -4
- package/cjs/utils/logger.js.map +1 -1
- package/cjs/utils/lru-map.d.ts +1 -0
- package/cjs/utils/lru-map.js +6 -0
- package/cjs/utils/lru-map.js.map +1 -1
- package/cjs/utils/peer-utils.js +5 -1
- package/cjs/utils/peer-utils.js.map +1 -1
- package/cjs/utils/platform/crypto.js +2 -2
- package/cjs/utils/platform/crypto.js.map +1 -1
- package/cjs/utils/platform/crypto.web.js +2 -2
- package/cjs/utils/platform/crypto.web.js.map +1 -1
- package/cjs/utils/string-session.js +4 -2
- package/cjs/utils/string-session.js.map +1 -1
- package/esm/base-client.js +4 -1
- package/esm/base-client.js.map +1 -1
- package/esm/network/auth-key.d.ts +3 -3
- package/esm/network/auth-key.js +13 -13
- package/esm/network/auth-key.js.map +1 -1
- package/esm/network/authorization.js +64 -59
- package/esm/network/authorization.js.map +1 -1
- package/esm/network/mtproto-session.d.ts +2 -2
- package/esm/network/mtproto-session.js +2 -2
- package/esm/network/mtproto-session.js.map +1 -1
- package/esm/network/multi-session-connection.d.ts +1 -1
- package/esm/network/multi-session-connection.js +2 -2
- package/esm/network/multi-session-connection.js.map +1 -1
- package/esm/network/network-manager.d.ts +1 -0
- package/esm/network/network-manager.js +21 -27
- package/esm/network/network-manager.js.map +1 -1
- package/esm/network/session-connection.d.ts +2 -1
- package/esm/network/session-connection.js +50 -37
- package/esm/network/session-connection.js.map +1 -1
- package/esm/network/transports/intermediate.d.ts +3 -0
- package/esm/network/transports/intermediate.js +6 -4
- package/esm/network/transports/intermediate.js.map +1 -1
- package/esm/network/transports/obfuscated.js +15 -19
- package/esm/network/transports/obfuscated.js.map +1 -1
- package/esm/storage/abstract.d.ts +23 -2
- package/esm/storage/abstract.js.map +1 -1
- package/esm/storage/json.js +8 -9
- package/esm/storage/json.js.map +1 -1
- package/esm/storage/localstorage.js +5 -2
- package/esm/storage/localstorage.js.map +1 -1
- package/esm/storage/memory.d.ts +7 -8
- package/esm/storage/memory.js +7 -7
- package/esm/storage/memory.js.map +1 -1
- package/esm/utils/bigint-utils.d.ts +18 -11
- package/esm/utils/bigint-utils.js +142 -44
- package/esm/utils/bigint-utils.js.map +1 -1
- package/esm/utils/buffer-utils.d.ts +7 -1
- package/esm/utils/buffer-utils.js +14 -1
- package/esm/utils/buffer-utils.js.map +1 -1
- package/esm/utils/crypto/abstract.d.ts +16 -9
- package/esm/utils/crypto/abstract.js +6 -9
- package/esm/utils/crypto/abstract.js.map +1 -1
- package/esm/utils/crypto/factorization.d.ts +2 -1
- package/esm/utils/crypto/factorization.js +29 -34
- package/esm/utils/crypto/factorization.js.map +1 -1
- package/esm/utils/crypto/index.d.ts +4 -0
- package/esm/utils/crypto/index.js +4 -0
- package/esm/utils/crypto/index.js.map +1 -1
- package/esm/utils/crypto/keys.d.ts +2 -2
- package/esm/utils/crypto/keys.js +4 -4
- package/esm/utils/crypto/keys.js.map +1 -1
- package/esm/utils/crypto/miller-rabin.d.ts +2 -2
- package/esm/utils/crypto/miller-rabin.js +21 -20
- package/esm/utils/crypto/miller-rabin.js.map +1 -1
- package/esm/utils/crypto/mtproto.d.ts +3 -3
- package/esm/utils/crypto/mtproto.js +12 -12
- package/esm/utils/crypto/mtproto.js.map +1 -1
- package/esm/utils/crypto/node.d.ts +21 -0
- package/esm/utils/crypto/node.js +69 -0
- package/esm/utils/crypto/node.js.map +1 -0
- package/esm/utils/crypto/password.js +24 -32
- package/esm/utils/crypto/password.js.map +1 -1
- package/esm/utils/crypto/wasm.d.ts +22 -0
- package/esm/utils/crypto/wasm.js +37 -0
- package/esm/utils/crypto/wasm.js.map +1 -0
- package/esm/utils/crypto/web.d.ts +11 -0
- package/esm/utils/crypto/web.js +36 -0
- package/esm/utils/crypto/web.js.map +1 -0
- package/esm/utils/deque.d.ts +1 -1
- package/esm/utils/deque.js +9 -3
- package/esm/utils/deque.js.map +1 -1
- package/esm/utils/function-utils.d.ts +4 -1
- package/esm/utils/function-utils.js +8 -1
- package/esm/utils/function-utils.js.map +1 -1
- package/esm/utils/index.d.ts +0 -1
- package/esm/utils/index.js +0 -1
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/logger.d.ts +0 -1
- package/esm/utils/logger.js +3 -4
- package/esm/utils/logger.js.map +1 -1
- package/esm/utils/lru-map.d.ts +1 -0
- package/esm/utils/lru-map.js +6 -0
- package/esm/utils/lru-map.js.map +1 -1
- package/esm/utils/peer-utils.js +5 -1
- package/esm/utils/peer-utils.js.map +1 -1
- package/esm/utils/platform/crypto.js +1 -1
- package/esm/utils/platform/crypto.js.map +1 -1
- package/esm/utils/platform/crypto.web.js +2 -2
- package/esm/utils/platform/crypto.web.js.map +1 -1
- package/esm/utils/string-session.js +4 -2
- package/esm/utils/string-session.js.map +1 -1
- package/package.json +4 -5
- package/cjs/utils/crypto/common.d.ts +0 -12
- package/cjs/utils/crypto/common.js +0 -54
- package/cjs/utils/crypto/common.js.map +0 -1
- package/cjs/utils/crypto/node-crypto.d.ts +0 -10
- package/cjs/utils/crypto/node-crypto.js +0 -46
- package/cjs/utils/crypto/node-crypto.js.map +0 -1
- package/cjs/utils/crypto/subtle.d.ts +0 -12
- package/cjs/utils/crypto/subtle.js +0 -86
- package/cjs/utils/crypto/subtle.js.map +0 -1
- package/cjs/utils/flood-control.d.ts +0 -14
- package/cjs/utils/flood-control.js +0 -65
- package/cjs/utils/flood-control.js.map +0 -1
- package/cjs/utils/platform/random.d.ts +0 -1
- package/cjs/utils/platform/random.js +0 -7
- package/cjs/utils/platform/random.js.map +0 -1
- package/cjs/utils/platform/random.web.d.ts +0 -1
- package/cjs/utils/platform/random.web.js +0 -10
- package/cjs/utils/platform/random.web.js.map +0 -1
- package/esm/utils/crypto/common.d.ts +0 -12
- package/esm/utils/crypto/common.js +0 -50
- package/esm/utils/crypto/common.js.map +0 -1
- package/esm/utils/crypto/node-crypto.d.ts +0 -10
- package/esm/utils/crypto/node-crypto.js +0 -42
- package/esm/utils/crypto/node-crypto.js.map +0 -1
- package/esm/utils/crypto/subtle.d.ts +0 -12
- package/esm/utils/crypto/subtle.js +0 -59
- package/esm/utils/crypto/subtle.js.map +0 -1
- package/esm/utils/flood-control.d.ts +0 -14
- package/esm/utils/flood-control.js +0 -61
- package/esm/utils/flood-control.js.map +0 -1
- package/esm/utils/platform/random.d.ts +0 -1
- package/esm/utils/platform/random.js +0 -4
- package/esm/utils/platform/random.js.map +0 -1
- package/esm/utils/platform/random.web.d.ts +0 -1
- package/esm/utils/platform/random.web.js +0 -6
- package/esm/utils/platform/random.web.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/network/authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import bigInt from 'big-integer'\nimport Long from 'long'\n\nimport { mtp } from '@mtcute/tl'\nimport { TlPublicKey } from '@mtcute/tl/binary/rsa-keys.js'\nimport { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime'\n\nimport { MtArgumentError, MtSecurityError, MtTypeAssertionError } from '../types/index.js'\nimport { buffersEqual, concatBuffers, dataViewFromBuffer, randomBytes } from '../utils/buffer-utils.js'\nimport { findKeyByFingerprints } from '../utils/crypto/keys.js'\nimport { millerRabin } from '../utils/crypto/miller-rabin.js'\nimport { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto.js'\nimport { xorBuffer, xorBufferInPlace } from '../utils/crypto/utils.js'\nimport { bigIntToBuffer, bufferToBigInt, ICryptoProvider, Logger } from '../utils/index.js'\nimport { mtpAssertTypeIs } from '../utils/type-assertions.js'\nimport { SessionConnection } from './session-connection.js'\n\n// Heavily based on code from https://github.com/LonamiWebs/Telethon/blob/master/telethon/network/authenticator.py\n\n// see https://core.telegram.org/mtproto/security_guidelines\nconst DH_SAFETY_RANGE = bigInt[2].pow(2048 - 64)\nconst KNOWN_DH_PRIME = bigInt(\n 'C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B',\n 16,\n)\nconst TWO_POW_2047 = bigInt[2].pow(2047)\nconst TWO_POW_2048 = bigInt[2].pow(2048)\n\ninterface CheckedPrime {\n prime: bigInt.BigInteger\n generators: number[]\n}\nconst checkedPrimesCache: CheckedPrime[] = []\n\nfunction checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) {\n if (KNOWN_DH_PRIME.eq(dhPrime)) {\n log.debug('server is using known dh prime, skipping validation')\n\n return\n }\n\n let checkedPrime = checkedPrimesCache.find((x) => x.prime.eq(dhPrime))\n\n if (!checkedPrime) {\n if (dhPrime.lesserOrEquals(TWO_POW_2047) || dhPrime.greaterOrEquals(TWO_POW_2048)) {\n throw new MtSecurityError('Step 3: dh_prime is not in the 2048-bit range')\n }\n\n if (!millerRabin(dhPrime)) {\n throw new MtSecurityError('Step 3: dh_prime is not prime')\n }\n if (!millerRabin(dhPrime.minus(1).divide(2))) {\n throw new MtSecurityError('Step 3: dh_prime is not a safe prime - (dh_prime-1)/2 is not prime')\n }\n\n log.debug('dh_prime is probably prime')\n\n checkedPrime = {\n prime: dhPrime,\n generators: [],\n }\n checkedPrimesCache.push(checkedPrime)\n } else {\n log.debug('dh_prime is probably prime (cached)')\n }\n\n const generatorChecked = checkedPrime.generators.includes(g)\n\n if (generatorChecked) {\n log.debug('g = %d is already checked for dh_prime', g)\n\n return\n }\n\n switch (g) {\n case 2:\n if (dhPrime.mod(8).notEquals(7)) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 8 != 7')\n }\n break\n case 3:\n if (dhPrime.mod(3).notEquals(2)) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 3 != 2')\n }\n break\n case 4:\n break\n case 5: {\n const mod = dhPrime.mod(5)\n\n if (mod.notEquals(1) && mod.notEquals(4)) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 5 != 1 && dh_prime mod 5 != 4')\n }\n break\n }\n case 6: {\n const mod = dhPrime.mod(24)\n\n if (mod.notEquals(19) && mod.notEquals(23)) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 24 != 19 && dh_prime mod 24 != 23')\n }\n break\n }\n case 7: {\n const mod = dhPrime.mod(7)\n\n if (mod.notEquals(3) && mod.notEquals(5) && mod.notEquals(6)) {\n throw new MtSecurityError(\n 'Step 3: ivalid g - dh_prime mod 7 != 3 && dh_prime mod 7 != 5 && dh_prime mod 7 != 6',\n )\n }\n break\n }\n default:\n throw new MtSecurityError(`Step 3: ivalid g - unknown g = ${g}`)\n }\n\n checkedPrime.generators.push(g)\n\n log.debug('g = %d is safe to use with dh_prime', g)\n}\n\nasync function rsaPad(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Promise<Uint8Array> {\n // since Summer 2021, they use \"version of RSA with a variant of OAEP+ padding explained below\"\n\n const keyModulus = bigInt(key.modulus, 16)\n const keyExponent = bigInt(key.exponent, 16)\n\n if (data.length > 144) {\n throw new MtArgumentError('Failed to pad: too big data')\n }\n\n data = concatBuffers([data, randomBytes(192 - data.length)])\n\n for (;;) {\n const aesIv = new Uint8Array(32)\n\n const aesKey = randomBytes(32)\n\n const dataWithHash = concatBuffers([data, await crypto.sha256(concatBuffers([aesKey, data]))])\n // we only need to reverse the data\n dataWithHash.subarray(0, 192).reverse()\n\n const aes = await crypto.createAesIge(aesKey, aesIv)\n const encrypted = await aes.encrypt(dataWithHash)\n const encryptedHash = await crypto.sha256(encrypted)\n\n xorBufferInPlace(aesKey, encryptedHash)\n const decryptedData = concatBuffers([aesKey, encrypted])\n\n const decryptedDataBigint = bufferToBigInt(decryptedData)\n\n if (decryptedDataBigint.geq(keyModulus)) {\n continue\n }\n\n const encryptedBigint = decryptedDataBigint.modPow(keyExponent, keyModulus)\n\n return bigIntToBuffer(encryptedBigint, 256)\n }\n}\n\nasync function rsaEncrypt(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Promise<Uint8Array> {\n const toEncrypt = concatBuffers([\n await crypto.sha1(data),\n data,\n // sha1 is always 20 bytes, so we're left with 255 - 20 - x padding\n randomBytes(235 - data.length),\n ])\n\n const encryptedBigInt = bufferToBigInt(toEncrypt).modPow(bigInt(key.exponent, 16), bigInt(key.modulus, 16))\n\n return bigIntToBuffer(encryptedBigInt)\n}\n\n/**\n * Execute authorization flow on `connection` using `crypto`.\n *\n * @returns tuple: [authKey, serverSalt, timeOffset]\n */\nexport async function doAuthorization(\n connection: SessionConnection,\n crypto: ICryptoProvider,\n expiresIn?: number,\n): Promise<[Uint8Array, Long, number]> {\n // eslint-disable-next-line dot-notation\n const session = connection['_session']\n const readerMap = session._readerMap\n const writerMap = session._writerMap\n const log = connection.log.create('auth')\n\n function sendPlainMessage(message: mtp.TlObject): Promise<void> {\n const length = TlSerializationCounter.countNeededBytes(writerMap, message)\n const writer = TlBinaryWriter.alloc(writerMap, length + 20) // 20 bytes for mtproto header\n\n const messageId = session.getMessageId()\n\n log.verbose('[PLAIN] >>> %j', message)\n writer.long(Long.ZERO)\n writer.long(messageId)\n writer.uint(length)\n writer.object(message)\n\n return connection.send(writer.result())\n }\n\n async function readNext(): Promise<mtp.TlObject> {\n const res = TlBinaryReader.deserializeObject<mtp.TlObject>(\n readerMap,\n await connection.waitForUnencryptedMessage(),\n 20, // skip mtproto header\n )\n\n log.verbose('[PLAIN] <<< %j', res)\n\n return res\n }\n\n if (expiresIn) log.prefix = '[PFS] '\n\n const nonce = randomBytes(16)\n // Step 1: PQ request\n log.debug('starting PQ handshake (temp = %b), nonce = %h', expiresIn, nonce)\n\n await sendPlainMessage({ _: 'mt_req_pq_multi', nonce })\n const resPq = await readNext()\n\n mtpAssertTypeIs('auth step 1', resPq, 'mt_resPQ')\n\n if (!buffersEqual(resPq.nonce, nonce)) {\n throw new MtSecurityError('Step 1: invalid nonce from server')\n }\n\n const serverKeys = resPq.serverPublicKeyFingerprints.map((it) => it.toUnsigned().toString(16))\n log.debug('received PQ, keys: %j', serverKeys)\n\n // Step 2: DH exchange\n const publicKey = findKeyByFingerprints(serverKeys)\n\n if (!publicKey) {\n throw new MtSecurityError(\n 'Step 2: Could not find server public key with any of these fingerprints: ' + serverKeys.join(', '),\n )\n }\n log.debug('found server key, fp = %s, old = %s', publicKey.fingerprint, publicKey.old)\n\n const [p, q] = await crypto.factorizePQ(resPq.pq)\n log.debug('factorized PQ: PQ = %h, P = %h, Q = %h', resPq.pq, p, q)\n\n const newNonce = randomBytes(32)\n\n let dcId = connection.params.dc.id\n if (connection.params.testMode) dcId += 10000\n if (connection.params.dc.mediaOnly) dcId = -dcId\n\n const _pqInnerData: mtp.TypeP_Q_inner_data = {\n _: expiresIn ? 'mt_p_q_inner_data_temp_dc' : 'mt_p_q_inner_data_dc',\n pq: resPq.pq,\n p,\n q,\n nonce,\n newNonce,\n serverNonce: resPq.serverNonce,\n dc: dcId,\n expiresIn: expiresIn!, // whatever\n }\n const pqInnerData = TlBinaryWriter.serializeObject(writerMap, _pqInnerData)\n\n const encryptedData = publicKey.old ?\n await rsaEncrypt(pqInnerData, crypto, publicKey) :\n await rsaPad(pqInnerData, crypto, publicKey)\n\n log.debug('requesting DH params')\n\n await sendPlainMessage({\n _: 'mt_req_DH_params',\n nonce,\n serverNonce: resPq.serverNonce,\n p,\n q,\n publicKeyFingerprint: Long.fromString(publicKey.fingerprint, true, 16),\n encryptedData,\n })\n const serverDhParams = await readNext()\n\n mtpAssertTypeIs('auth step 2', serverDhParams, 'mt_server_DH_params_ok')\n\n if (!buffersEqual(serverDhParams.nonce, nonce)) {\n throw new MtSecurityError('Step 2: invalid nonce from server')\n }\n if (!buffersEqual(serverDhParams.serverNonce, resPq.serverNonce)) {\n throw new MtSecurityError('Step 2: invalid server nonce from server')\n }\n\n log.debug('server DH ok')\n\n if (serverDhParams.encryptedAnswer.length % 16 !== 0) {\n throw new MtSecurityError('Step 2: AES block size is invalid')\n }\n\n // Step 3: complete DH exchange\n const [key, iv] = await generateKeyAndIvFromNonce(crypto, resPq.serverNonce, newNonce)\n const ige = await crypto.createAesIge(key, iv)\n\n const plainTextAnswer = await ige.decrypt(serverDhParams.encryptedAnswer)\n const innerDataHash = plainTextAnswer.subarray(0, 20)\n const serverDhInnerReader = new TlBinaryReader(readerMap, plainTextAnswer, 20)\n const serverDhInner = serverDhInnerReader.object() as mtp.TlObject\n\n if (!buffersEqual(innerDataHash, await crypto.sha1(plainTextAnswer.subarray(20, serverDhInnerReader.pos)))) {\n throw new MtSecurityError('Step 3: invalid inner data hash')\n }\n\n mtpAssertTypeIs('auth step 3', serverDhInner, 'mt_server_DH_inner_data')\n\n if (!buffersEqual(serverDhInner.nonce, nonce)) {\n throw Error('Step 3: invalid nonce from server')\n }\n if (!buffersEqual(serverDhInner.serverNonce, resPq.serverNonce)) {\n throw Error('Step 3: invalid server nonce from server')\n }\n\n const dhPrime = bufferToBigInt(serverDhInner.dhPrime)\n const timeOffset = Math.floor(Date.now() / 1000) - serverDhInner.serverTime\n\n const g = bigInt(serverDhInner.g)\n const gA = bufferToBigInt(serverDhInner.gA)\n\n checkDhPrime(log, dhPrime, serverDhInner.g)\n\n let retryId = Long.ZERO\n const serverSalt = xorBuffer(newNonce.subarray(0, 8), resPq.serverNonce.subarray(0, 8))\n\n for (;;) {\n const b = bufferToBigInt(randomBytes(256))\n const gB = g.modPow(b, dhPrime)\n\n const authKey = bigIntToBuffer(gA.modPow(b, dhPrime))\n const authKeyAuxHash = (await crypto.sha1(authKey)).subarray(0, 8)\n\n // validate DH params\n if (g.lesserOrEquals(1) || g.greaterOrEquals(dhPrime.minus(bigInt.one))) {\n throw new MtSecurityError('g is not within (1, dh_prime - 1)')\n }\n if (gA.lesserOrEquals(1) || gA.greaterOrEquals(dhPrime.minus(bigInt.one))) {\n throw new MtSecurityError('g_a is not within (1, dh_prime - 1)')\n }\n if (gB.lesserOrEquals(1) || gB.greaterOrEquals(dhPrime.minus(bigInt.one))) {\n throw new MtSecurityError('g_b is not within (1, dh_prime - 1)')\n }\n\n if (gA.lt(DH_SAFETY_RANGE) || gA.gt(dhPrime.minus(DH_SAFETY_RANGE))) {\n throw new MtSecurityError('g_a is not within (2^{2048-64}, dh_prime - 2^{2048-64})')\n }\n if (gB.lt(DH_SAFETY_RANGE) || gB.gt(dhPrime.minus(DH_SAFETY_RANGE))) {\n throw new MtSecurityError('g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64})')\n }\n\n const gB_ = bigIntToBuffer(gB, 0, false)\n\n // Step 4: send client DH\n const clientDhInner: mtp.RawMt_client_DH_inner_data = {\n _: 'mt_client_DH_inner_data',\n nonce,\n serverNonce: resPq.serverNonce,\n retryId,\n gB: gB_,\n }\n let innerLength = TlSerializationCounter.countNeededBytes(writerMap, clientDhInner) + 20 // for hash\n const innerPaddingLength = innerLength % 16\n if (innerPaddingLength > 0) innerLength += 16 - innerPaddingLength\n\n const clientDhInnerWriter = TlBinaryWriter.alloc(writerMap, innerLength)\n clientDhInnerWriter.pos = 20\n clientDhInnerWriter.object(clientDhInner)\n const clientDhInnerHash = await crypto.sha1(clientDhInnerWriter.uint8View.subarray(20, clientDhInnerWriter.pos))\n clientDhInnerWriter.pos = 0\n clientDhInnerWriter.raw(clientDhInnerHash)\n\n log.debug('sending client DH (timeOffset = %d)', timeOffset)\n\n const clientDhEncrypted = await ige.encrypt(clientDhInnerWriter.uint8View)\n await sendPlainMessage({\n _: 'mt_set_client_DH_params',\n nonce,\n serverNonce: resPq.serverNonce,\n encryptedData: clientDhEncrypted,\n })\n\n const dhGen = await readNext()\n\n if (!mtp.isAnySet_client_DH_params_answer(dhGen)) {\n throw new MtTypeAssertionError('auth step 4', 'set_client_DH_params_answer', dhGen._)\n }\n\n if (!buffersEqual(dhGen.nonce, nonce)) {\n throw Error('Step 4: invalid nonce from server')\n }\n if (!buffersEqual(dhGen.serverNonce, resPq.serverNonce)) {\n throw Error('Step 4: invalid server nonce from server')\n }\n\n log.debug('DH result: %s', dhGen._)\n\n if (dhGen._ === 'mt_dh_gen_fail') {\n // in theory i would be supposed to calculate newNonceHash, but why, we are failing anyway\n throw new MtTypeAssertionError('auth step 4', '!mt_dh_gen_fail', dhGen._)\n }\n\n if (dhGen._ === 'mt_dh_gen_retry') {\n const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([2]), authKeyAuxHash]))\n\n if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash2)) {\n throw Error('Step 4: invalid retry nonce hash from server')\n }\n retryId = Long.fromBytesLE(authKeyAuxHash as unknown as number[])\n continue\n }\n\n if (dhGen._ !== 'mt_dh_gen_ok') throw new Error() // unreachable\n\n const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([1]), authKeyAuxHash]))\n\n if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash1)) {\n throw Error('Step 4: invalid nonce hash from server')\n }\n\n log.info('authorization successful')\n\n const dv = dataViewFromBuffer(serverSalt)\n\n return [authKey, new Long(dv.getInt32(0, true), dv.getInt32(4, true)), timeOffset]\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/network/authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\n\nimport { mtp } from '@mtcute/tl'\nimport { TlPublicKey } from '@mtcute/tl/binary/rsa-keys.js'\nimport { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime'\n\nimport { MtArgumentError, MtSecurityError, MtTypeAssertionError } from '../types/index.js'\nimport { buffersEqual, concatBuffers, dataViewFromBuffer } from '../utils/buffer-utils.js'\nimport { findKeyByFingerprints } from '../utils/crypto/keys.js'\nimport { millerRabin } from '../utils/crypto/miller-rabin.js'\nimport { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto.js'\nimport { xorBuffer, xorBufferInPlace } from '../utils/crypto/utils.js'\nimport { bigIntModPow, bigIntToBuffer, bufferToBigInt, ICryptoProvider, Logger } from '../utils/index.js'\nimport { mtpAssertTypeIs } from '../utils/type-assertions.js'\nimport { SessionConnection } from './session-connection.js'\n\n// Heavily based on code from https://github.com/LonamiWebs/Telethon/blob/master/telethon/network/authenticator.py\n\n// see https://core.telegram.org/mtproto/security_guidelines\n// const DH_SAFETY_RANGE = bigInt[2].pow(2048 - 64)\nconst DH_SAFETY_RANGE = 2n ** (2048n - 64n)\nconst KNOWN_DH_PRIME =\n // eslint-disable-next-line max-len\n 0xc71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5bn\nconst TWO_POW_2047 = 2n ** 2047n\nconst TWO_POW_2048 = 2n ** 2048n\n\ninterface CheckedPrime {\n prime: bigint\n generators: number[]\n}\n\nconst checkedPrimesCache: CheckedPrime[] = []\n\nfunction checkDhPrime(crypto: ICryptoProvider, log: Logger, dhPrime: bigint, g: number) {\n if (KNOWN_DH_PRIME === dhPrime) {\n log.debug('server is using known dh prime, skipping validation')\n\n return\n }\n\n let checkedPrime = checkedPrimesCache.find((x) => x.prime === dhPrime)\n\n if (!checkedPrime) {\n if (dhPrime <= TWO_POW_2047 || dhPrime >= TWO_POW_2048) {\n throw new MtSecurityError('Step 3: dh_prime is not in the 2048-bit range')\n }\n\n if (!millerRabin(crypto, dhPrime)) {\n throw new MtSecurityError('Step 3: dh_prime is not prime')\n }\n if (!millerRabin(crypto, (dhPrime - 1n) / 2n)) {\n throw new MtSecurityError('Step 3: dh_prime is not a safe prime - (dh_prime-1)/2 is not prime')\n }\n\n log.debug('dh_prime is probably prime')\n\n checkedPrime = {\n prime: dhPrime,\n generators: [],\n }\n checkedPrimesCache.push(checkedPrime)\n } else {\n log.debug('dh_prime is probably prime (cached)')\n }\n\n const generatorChecked = checkedPrime.generators.includes(g)\n\n if (generatorChecked) {\n log.debug('g = %d is already checked for dh_prime', g)\n\n return\n }\n\n switch (g) {\n case 2:\n if (dhPrime % 8n !== 7n) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 8 != 7')\n }\n break\n case 3:\n if (dhPrime % 3n !== 2n) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 3 != 2')\n }\n break\n case 4:\n break\n case 5: {\n const mod = dhPrime % 5n\n\n if (mod !== 1n && mod !== 4n) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 5 != 1 && dh_prime mod 5 != 4')\n }\n break\n }\n case 6: {\n const mod = dhPrime % 24n\n\n if (mod !== 19n && mod !== 23n) {\n throw new MtSecurityError('Step 3: ivalid g - dh_prime mod 24 != 19 && dh_prime mod 24 != 23')\n }\n break\n }\n case 7: {\n const mod = dhPrime % 7n\n\n if (mod !== 3n && mod !== 5n && mod !== 6n) {\n throw new MtSecurityError(\n 'Step 3: ivalid g - dh_prime mod 7 != 3 && dh_prime mod 7 != 5 && dh_prime mod 7 != 6',\n )\n }\n break\n }\n default:\n throw new MtSecurityError(`Step 3: ivalid g - unknown g = ${g}`)\n }\n\n checkedPrime.generators.push(g)\n\n log.debug('g = %d is safe to use with dh_prime', g)\n}\n\nfunction rsaPad(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Uint8Array {\n // since Summer 2021, they use \"version of RSA with a variant of OAEP+ padding explained below\"\n\n const keyModulus = BigInt(`0x${key.modulus}`)\n const keyExponent = BigInt(`0x${key.exponent}`)\n\n if (data.length > 144) {\n throw new MtArgumentError('Failed to pad: too big data')\n }\n\n const dataPadded = new Uint8Array(192)\n dataPadded.set(data, 0)\n crypto.randomFill(dataPadded.subarray(data.length))\n data = dataPadded\n\n for (;;) {\n const aesIv = new Uint8Array(32)\n\n const aesKey = crypto.randomBytes(32)\n\n const dataWithHash = concatBuffers([data, crypto.sha256(concatBuffers([aesKey, data]))])\n // we only need to reverse the data\n dataWithHash.subarray(0, 192).reverse()\n\n const aes = crypto.createAesIge(aesKey, aesIv)\n const encrypted = aes.encrypt(dataWithHash)\n const encryptedHash = crypto.sha256(encrypted)\n\n xorBufferInPlace(aesKey, encryptedHash)\n const decryptedData = concatBuffers([aesKey, encrypted])\n\n const decryptedDataBigint = bufferToBigInt(decryptedData)\n\n if (decryptedDataBigint >= keyModulus) {\n continue\n }\n\n const encryptedBigint = bigIntModPow(decryptedDataBigint, keyExponent, keyModulus)\n\n return bigIntToBuffer(encryptedBigint, 256)\n }\n}\n\nfunction rsaEncrypt(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Uint8Array {\n const toEncrypt = concatBuffers([\n crypto.sha1(data),\n data,\n // sha1 is always 20 bytes, so we're left with 255 - 20 - x padding\n crypto.randomBytes(235 - data.length),\n ])\n\n const encryptedBigInt = bigIntModPow(\n bufferToBigInt(toEncrypt),\n BigInt(`0x${key.exponent}`),\n BigInt(`0x${key.modulus}`),\n )\n\n return bigIntToBuffer(encryptedBigInt)\n}\n\n/**\n * Execute authorization flow on `connection` using `crypto`.\n *\n * @returns tuple: [authKey, serverSalt, timeOffset]\n */\nexport async function doAuthorization(\n connection: SessionConnection,\n crypto: ICryptoProvider,\n expiresIn?: number,\n): Promise<[Uint8Array, Long, number]> {\n // eslint-disable-next-line dot-notation\n const session = connection['_session']\n const readerMap = session._readerMap\n const writerMap = session._writerMap\n const log = connection.log.create('auth')\n\n function sendPlainMessage(message: mtp.TlObject): Promise<void> {\n const length = TlSerializationCounter.countNeededBytes(writerMap, message)\n const writer = TlBinaryWriter.alloc(writerMap, length + 20) // 20 bytes for mtproto header\n\n const messageId = session.getMessageId()\n\n log.verbose('[PLAIN] >>> %j', message)\n writer.long(Long.ZERO)\n writer.long(messageId)\n writer.uint(length)\n writer.object(message)\n\n return connection.send(writer.result())\n }\n\n async function readNext(): Promise<mtp.TlObject> {\n const res = TlBinaryReader.deserializeObject<mtp.TlObject>(\n readerMap,\n await connection.waitForUnencryptedMessage(),\n 20, // skip mtproto header\n )\n\n log.verbose('[PLAIN] <<< %j', res)\n\n return res\n }\n\n if (expiresIn) log.prefix = '[PFS] '\n\n const nonce = crypto.randomBytes(16)\n // Step 1: PQ request\n log.debug('starting PQ handshake (temp = %b), nonce = %h', expiresIn, nonce)\n\n await sendPlainMessage({ _: 'mt_req_pq_multi', nonce })\n const resPq = await readNext()\n\n mtpAssertTypeIs('auth step 1', resPq, 'mt_resPQ')\n\n if (!buffersEqual(resPq.nonce, nonce)) {\n throw new MtSecurityError('Step 1: invalid nonce from server')\n }\n\n const serverKeys = resPq.serverPublicKeyFingerprints.map((it) => it.toUnsigned().toString(16))\n log.debug('received PQ, keys: %j', serverKeys)\n\n // Step 2: DH exchange\n const publicKey = findKeyByFingerprints(serverKeys)\n\n if (!publicKey) {\n throw new MtSecurityError(\n 'Step 2: Could not find server public key with any of these fingerprints: ' + serverKeys.join(', '),\n )\n }\n log.debug('found server key, fp = %s, old = %s', publicKey.fingerprint, publicKey.old)\n\n const [p, q] = await crypto.factorizePQ(resPq.pq)\n log.debug('factorized PQ: PQ = %h, P = %h, Q = %h', resPq.pq, p, q)\n\n const newNonce = crypto.randomBytes(32)\n\n let dcId = connection.params.dc.id\n if (connection.params.testMode) dcId += 10000\n if (connection.params.dc.mediaOnly) dcId = -dcId\n\n const _pqInnerData: mtp.TypeP_Q_inner_data = {\n _: expiresIn ? 'mt_p_q_inner_data_temp_dc' : 'mt_p_q_inner_data_dc',\n pq: resPq.pq,\n p,\n q,\n nonce,\n newNonce,\n serverNonce: resPq.serverNonce,\n dc: dcId,\n expiresIn: expiresIn!, // whatever\n }\n const pqInnerData = TlBinaryWriter.serializeObject(writerMap, _pqInnerData)\n\n const encryptedData = publicKey.old ?\n rsaEncrypt(pqInnerData, crypto, publicKey) :\n rsaPad(pqInnerData, crypto, publicKey)\n\n log.debug('requesting DH params')\n\n await sendPlainMessage({\n _: 'mt_req_DH_params',\n nonce,\n serverNonce: resPq.serverNonce,\n p,\n q,\n publicKeyFingerprint: Long.fromString(publicKey.fingerprint, true, 16),\n encryptedData,\n })\n const serverDhParams = await readNext()\n\n mtpAssertTypeIs('auth step 2', serverDhParams, 'mt_server_DH_params_ok')\n\n if (!buffersEqual(serverDhParams.nonce, nonce)) {\n throw new MtSecurityError('Step 2: invalid nonce from server')\n }\n if (!buffersEqual(serverDhParams.serverNonce, resPq.serverNonce)) {\n throw new MtSecurityError('Step 2: invalid server nonce from server')\n }\n\n log.debug('server DH ok')\n\n if (serverDhParams.encryptedAnswer.length % 16 !== 0) {\n throw new MtSecurityError('Step 2: AES block size is invalid')\n }\n\n // Step 3: complete DH exchange\n const [key, iv] = generateKeyAndIvFromNonce(crypto, resPq.serverNonce, newNonce)\n const ige = crypto.createAesIge(key, iv)\n\n const plainTextAnswer = ige.decrypt(serverDhParams.encryptedAnswer)\n const innerDataHash = plainTextAnswer.subarray(0, 20)\n const serverDhInnerReader = new TlBinaryReader(readerMap, plainTextAnswer, 20)\n const serverDhInner = serverDhInnerReader.object() as mtp.TlObject\n\n if (!buffersEqual(innerDataHash, crypto.sha1(plainTextAnswer.subarray(20, serverDhInnerReader.pos)))) {\n throw new MtSecurityError('Step 3: invalid inner data hash')\n }\n\n mtpAssertTypeIs('auth step 3', serverDhInner, 'mt_server_DH_inner_data')\n\n if (!buffersEqual(serverDhInner.nonce, nonce)) {\n throw Error('Step 3: invalid nonce from server')\n }\n if (!buffersEqual(serverDhInner.serverNonce, resPq.serverNonce)) {\n throw Error('Step 3: invalid server nonce from server')\n }\n\n const dhPrime = bufferToBigInt(serverDhInner.dhPrime)\n const timeOffset = Math.floor(Date.now() / 1000) - serverDhInner.serverTime\n\n const g = BigInt(serverDhInner.g)\n const gA = bufferToBigInt(serverDhInner.gA)\n\n checkDhPrime(crypto, log, dhPrime, serverDhInner.g)\n\n let retryId = Long.ZERO\n const serverSalt = xorBuffer(newNonce.subarray(0, 8), resPq.serverNonce.subarray(0, 8))\n\n for (;;) {\n const b = bufferToBigInt(crypto.randomBytes(256))\n const gB = bigIntModPow(g, b, dhPrime)\n\n const authKey = bigIntToBuffer(bigIntModPow(gA, b, dhPrime))\n const authKeyAuxHash = crypto.sha1(authKey).subarray(0, 8)\n\n // validate DH params\n if (g <= 1 || g >= dhPrime - 1n) {\n throw new MtSecurityError('g is not within (1, dh_prime - 1)')\n }\n if (gA <= 1 || gA >= dhPrime - 1n) {\n throw new MtSecurityError('g_a is not within (1, dh_prime - 1)')\n }\n if (gB <= 1 || gB >= dhPrime - 1n) {\n throw new MtSecurityError('g_b is not within (1, dh_prime - 1)')\n }\n\n if (gA <= DH_SAFETY_RANGE || gA >= dhPrime - DH_SAFETY_RANGE) {\n throw new MtSecurityError('g_a is not within (2^{2048-64}, dh_prime - 2^{2048-64})')\n }\n if (gB <= DH_SAFETY_RANGE || gB >= dhPrime - DH_SAFETY_RANGE) {\n throw new MtSecurityError('g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64})')\n }\n\n const gB_ = bigIntToBuffer(gB, 0, false)\n\n // Step 4: send client DH\n const clientDhInner: mtp.RawMt_client_DH_inner_data = {\n _: 'mt_client_DH_inner_data',\n nonce,\n serverNonce: resPq.serverNonce,\n retryId,\n gB: gB_,\n }\n let innerLength = TlSerializationCounter.countNeededBytes(writerMap, clientDhInner) + 20 // for hash\n const innerPaddingLength = innerLength % 16\n if (innerPaddingLength > 0) innerLength += 16 - innerPaddingLength\n\n const clientDhInnerWriter = TlBinaryWriter.alloc(writerMap, innerLength)\n clientDhInnerWriter.pos = 20\n clientDhInnerWriter.object(clientDhInner)\n const clientDhInnerHash = crypto.sha1(clientDhInnerWriter.uint8View.subarray(20, clientDhInnerWriter.pos))\n clientDhInnerWriter.pos = 0\n clientDhInnerWriter.raw(clientDhInnerHash)\n\n log.debug('sending client DH (timeOffset = %d)', timeOffset)\n\n const clientDhEncrypted = ige.encrypt(clientDhInnerWriter.uint8View)\n await sendPlainMessage({\n _: 'mt_set_client_DH_params',\n nonce,\n serverNonce: resPq.serverNonce,\n encryptedData: clientDhEncrypted,\n })\n\n const dhGen = await readNext()\n\n if (!mtp.isAnySet_client_DH_params_answer(dhGen)) {\n throw new MtTypeAssertionError('auth step 4', 'set_client_DH_params_answer', dhGen._)\n }\n\n if (!buffersEqual(dhGen.nonce, nonce)) {\n throw Error('Step 4: invalid nonce from server')\n }\n if (!buffersEqual(dhGen.serverNonce, resPq.serverNonce)) {\n throw Error('Step 4: invalid server nonce from server')\n }\n\n log.debug('DH result: %s', dhGen._)\n\n if (dhGen._ === 'mt_dh_gen_fail') {\n // in theory i would be supposed to calculate newNonceHash, but why, we are failing anyway\n throw new MtTypeAssertionError('auth step 4', '!mt_dh_gen_fail', dhGen._)\n }\n\n if (dhGen._ === 'mt_dh_gen_retry') {\n const expectedHash = crypto.sha1(concatBuffers([newNonce, new Uint8Array([2]), authKeyAuxHash]))\n\n if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash2)) {\n throw Error('Step 4: invalid retry nonce hash from server')\n }\n retryId = Long.fromBytesLE(authKeyAuxHash as unknown as number[])\n continue\n }\n\n if (dhGen._ !== 'mt_dh_gen_ok') throw new Error() // unreachable\n\n const expectedHash = crypto.sha1(concatBuffers([newNonce, new Uint8Array([1]), authKeyAuxHash]))\n\n if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash1)) {\n throw Error('Step 4: invalid nonce hash from server')\n }\n\n log.info('authorization successful')\n\n const dv = dataViewFromBuffer(serverSalt)\n\n return [authKey, new Long(dv.getInt32(0, true), dv.getInt32(4, true)), timeOffset]\n }\n}\n"]}
|
|
@@ -107,9 +107,9 @@ export declare class MtprotoSession {
|
|
|
107
107
|
getMessageId(): Long;
|
|
108
108
|
getSeqNo(isContentRelated?: boolean): number;
|
|
109
109
|
/** Encrypt a single MTProto message using session's keys */
|
|
110
|
-
encryptMessage(message: Uint8Array):
|
|
110
|
+
encryptMessage(message: Uint8Array): Uint8Array;
|
|
111
111
|
/** Decrypt a single MTProto message using session's keys */
|
|
112
|
-
decryptMessage(data: Uint8Array, callback: Parameters<AuthKey['decryptMessage']>[2]):
|
|
112
|
+
decryptMessage(data: Uint8Array, callback: Parameters<AuthKey['decryptMessage']>[2]): void;
|
|
113
113
|
writeMessage(writer: TlBinaryWriter, content: tl.TlObject | mtp.TlObject | Uint8Array, isContentRelated?: boolean): Long;
|
|
114
114
|
onTransportFlood(callback: () => void): number | undefined;
|
|
115
115
|
resetLastPing(withTime?: boolean): void;
|
|
@@ -136,12 +136,12 @@ class MtprotoSession {
|
|
|
136
136
|
return seqNo;
|
|
137
137
|
}
|
|
138
138
|
/** Encrypt a single MTProto message using session's keys */
|
|
139
|
-
|
|
139
|
+
encryptMessage(message) {
|
|
140
140
|
const key = this._authKeyTemp.ready ? this._authKeyTemp : this._authKey;
|
|
141
141
|
return key.encryptMessage(message, this.serverSalt, this._sessionId);
|
|
142
142
|
}
|
|
143
143
|
/** Decrypt a single MTProto message using session's keys */
|
|
144
|
-
|
|
144
|
+
decryptMessage(data, callback) {
|
|
145
145
|
if (!this._authKey.ready)
|
|
146
146
|
throw new index_js_1.MtcuteError('Keys are not set up!');
|
|
147
147
|
const authKeyId = data.subarray(0, 8);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mtproto-session.js","sourceRoot":"","sources":["../../../src/network/mtproto-session.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\n\nimport { mtp, tl } from '@mtcute/tl'\nimport { TlBinaryWriter, TlReaderMap, TlSerializationCounter, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { MtcuteError } from '../types/index.js'\nimport {\n ControllablePromise,\n Deque,\n getRandomInt,\n ICryptoProvider,\n Logger,\n LongMap,\n LruSet,\n randomLong,\n SortedArray,\n} from '../utils/index.js'\nimport { AuthKey } from './auth-key.js'\n\nexport interface PendingRpc {\n method: string\n data: Uint8Array\n promise: ControllablePromise\n stack?: string\n gzipOverhead?: number\n\n sent?: boolean\n done?: boolean\n msgId?: Long\n seqNo?: number\n containerId?: Long\n acked?: boolean\n initConn?: boolean\n getState?: number\n cancelled?: boolean\n timeout?: NodeJS.Timeout\n}\n\nexport type PendingMessage =\n | {\n _: 'rpc'\n rpc: PendingRpc\n }\n | {\n _: 'container'\n msgIds: Long[]\n }\n | {\n _: 'state'\n msgIds: Long[]\n containerId: Long\n }\n | {\n _: 'resend'\n msgIds: Long[]\n containerId: Long\n }\n | {\n _: 'ping'\n pingId: Long\n containerId: Long\n }\n | {\n _: 'destroy_session'\n sessionId: Long\n containerId: Long\n }\n | {\n _: 'cancel'\n msgId: Long\n containerId: Long\n }\n | {\n _: 'future_salts'\n containerId: Long\n }\n | {\n _: 'bind'\n promise: ControllablePromise\n }\n\n/**\n * Class encapsulating a single MTProto session and storing\n * all the relevant state\n */\nexport class MtprotoSession {\n _sessionId = randomLong()\n\n _authKey = new AuthKey(this._crypto, this.log, this._readerMap)\n _authKeyTemp = new AuthKey(this._crypto, this.log, this._readerMap)\n _authKeyTempSecondary = new AuthKey(this._crypto, this.log, this._readerMap)\n\n _timeOffset = 0\n _lastMessageId = Long.ZERO\n _seqNo = 0\n\n serverSalt = Long.ZERO\n\n /// state ///\n // recent msg ids\n recentOutgoingMsgIds = new LruSet<Long>(1000, true)\n recentIncomingMsgIds = new LruSet<Long>(1000, true)\n\n // queues\n queuedRpc = new Deque<PendingRpc>()\n queuedAcks: Long[] = []\n queuedStateReq: Long[] = []\n queuedResendReq: Long[] = []\n queuedCancelReq: Long[] = []\n getStateSchedule = new SortedArray<PendingRpc>([], (a, b) => a.getState! - b.getState!)\n\n // requests info\n pendingMessages = new LongMap<PendingMessage>()\n destroySessionIdToMsgId = new LongMap<Long>()\n\n lastPingRtt = NaN\n lastPingTime = 0\n lastPingMsgId = Long.ZERO\n lastSessionCreatedUid = Long.ZERO\n\n initConnectionCalled = false\n authorizationPending = false\n\n next429Timeout = 1000\n current429Timeout?: NodeJS.Timeout\n next429ResetTimeout?: NodeJS.Timeout\n\n constructor(\n readonly _crypto: ICryptoProvider,\n readonly log: Logger,\n readonly _readerMap: TlReaderMap,\n readonly _writerMap: TlWriterMap,\n ) {\n this.log.prefix = `[SESSION ${this._sessionId.toString(16)}] `\n }\n\n get hasPendingMessages(): boolean {\n return Boolean(\n this.queuedRpc.length ||\n this.queuedAcks.length ||\n this.queuedStateReq.length ||\n this.queuedResendReq.length,\n )\n }\n\n /**\n * Reset session by resetting auth key(s) and session state\n */\n reset(withAuthKey = false): void {\n if (withAuthKey) {\n this._authKey.reset()\n this._authKeyTemp.reset()\n this._authKeyTempSecondary.reset()\n }\n\n clearTimeout(this.current429Timeout)\n this.resetState()\n this.resetLastPing(true)\n }\n\n /**\n * Reset session state and generate a new session ID.\n *\n * By default, also cancels any pending RPC requests.\n * If `keepPending` is set to `true`, pending requests will be kept\n */\n resetState(keepPending = false): void {\n this._lastMessageId = Long.ZERO\n this._seqNo = 0\n\n this._sessionId = randomLong()\n this.log.debug('session reset, new sid = %h', this._sessionId)\n this.log.prefix = `[SESSION ${this._sessionId.toString(16)}] `\n\n // reset session state\n\n if (!keepPending) {\n for (const info of this.pendingMessages.values()) {\n if (info._ === 'rpc') {\n info.rpc.promise.reject(new MtcuteError('Session is reset'))\n }\n }\n this.pendingMessages.clear()\n }\n\n this.recentOutgoingMsgIds.clear()\n this.recentIncomingMsgIds.clear()\n\n if (!keepPending) {\n while (this.queuedRpc.length) {\n const rpc = this.queuedRpc.popFront()!\n\n if (rpc.sent === false) {\n rpc.promise.reject(new MtcuteError('Session is reset'))\n }\n }\n }\n\n this.queuedAcks.length = 0\n this.queuedStateReq.length = 0\n this.queuedResendReq.length = 0\n this.getStateSchedule.clear()\n }\n\n enqueueRpc(rpc: PendingRpc, force?: boolean): boolean {\n // already queued or cancelled\n if ((!force && !rpc.sent) || rpc.cancelled) return false\n\n rpc.sent = false\n rpc.containerId = undefined\n this.log.debug('enqueued %s for sending (msg_id = %s)', rpc.method, rpc.msgId || 'n/a')\n this.queuedRpc.pushBack(rpc)\n\n return true\n }\n\n getMessageId(): Long {\n const timeTicks = Date.now()\n const timeSec = Math.floor(timeTicks / 1000) + this._timeOffset\n const timeMSec = timeTicks % 1000\n const random = getRandomInt(0xffff)\n\n let messageId = new Long((timeMSec << 21) | (random << 3) | 4, timeSec)\n\n if (this._lastMessageId.gt(messageId)) {\n messageId = this._lastMessageId.add(4)\n }\n\n this._lastMessageId = messageId\n\n return messageId\n }\n\n getSeqNo(isContentRelated = true): number {\n let seqNo = this._seqNo\n\n if (isContentRelated) {\n seqNo += 1\n this._seqNo += 2\n }\n\n return seqNo\n }\n\n /** Encrypt a single MTProto message using session's keys */\n async encryptMessage(message: Uint8Array): Promise<Uint8Array> {\n const key = this._authKeyTemp.ready ? this._authKeyTemp : this._authKey\n\n return key.encryptMessage(message, this.serverSalt, this._sessionId)\n }\n\n /** Decrypt a single MTProto message using session's keys */\n async decryptMessage(data: Uint8Array, callback: Parameters<AuthKey['decryptMessage']>[2]): Promise<void> {\n if (!this._authKey.ready) throw new MtcuteError('Keys are not set up!')\n\n const authKeyId = data.subarray(0, 8)\n\n let key: AuthKey\n\n if (this._authKey.match(authKeyId)) {\n key = this._authKey\n } else if (this._authKeyTemp.match(authKeyId)) {\n key = this._authKeyTemp\n } else if (this._authKeyTempSecondary.match(authKeyId)) {\n key = this._authKeyTempSecondary\n } else {\n this.log.warn(\n 'received message with unknown authKey = %h (expected %h or %h or %h)',\n authKeyId,\n this._authKey.id,\n this._authKeyTemp.id,\n this._authKeyTempSecondary.id,\n )\n\n return\n }\n\n return key.decryptMessage(data, this._sessionId, callback)\n }\n\n writeMessage(\n writer: TlBinaryWriter,\n content: tl.TlObject | mtp.TlObject | Uint8Array,\n isContentRelated = true,\n ): Long {\n const messageId = this.getMessageId()\n const seqNo = this.getSeqNo(isContentRelated)\n\n const length = ArrayBuffer.isView(content) ?\n content.length :\n TlSerializationCounter.countNeededBytes(writer.objectMap!, content)\n\n writer.long(messageId)\n writer.int(seqNo)\n writer.uint(length)\n if (ArrayBuffer.isView(content)) writer.raw(content)\n else writer.object(content as tl.TlObject)\n\n return messageId\n }\n\n onTransportFlood(callback: () => void) {\n if (this.current429Timeout) return // already waiting\n\n // all active queries must be resent after a timeout\n this.resetLastPing(true)\n\n const timeout = this.next429Timeout\n\n this.next429Timeout = Math.min(this.next429Timeout * 2, 32000)\n clearTimeout(this.current429Timeout)\n clearTimeout(this.next429ResetTimeout)\n\n this.current429Timeout = setTimeout(() => {\n this.current429Timeout = undefined\n callback()\n }, timeout)\n this.next429ResetTimeout = setTimeout(() => {\n this.next429ResetTimeout = undefined\n this.next429Timeout = 1000\n }, 60000)\n\n this.log.debug('transport flood, waiting for %d ms before proceeding', timeout)\n\n return Date.now() + timeout\n }\n\n resetLastPing(withTime = false): void {\n if (withTime) this.lastPingTime = 0\n\n if (!this.lastPingMsgId.isZero()) {\n this.pendingMessages.delete(this.lastPingMsgId)\n }\n\n this.lastPingMsgId = Long.ZERO\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mtproto-session.js","sourceRoot":"","sources":["../../../src/network/mtproto-session.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\n\nimport { mtp, tl } from '@mtcute/tl'\nimport { TlBinaryWriter, TlReaderMap, TlSerializationCounter, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { MtcuteError } from '../types/index.js'\nimport {\n ControllablePromise,\n Deque,\n getRandomInt,\n ICryptoProvider,\n Logger,\n LongMap,\n LruSet,\n randomLong,\n SortedArray,\n} from '../utils/index.js'\nimport { AuthKey } from './auth-key.js'\n\nexport interface PendingRpc {\n method: string\n data: Uint8Array\n promise: ControllablePromise\n stack?: string\n gzipOverhead?: number\n\n sent?: boolean\n done?: boolean\n msgId?: Long\n seqNo?: number\n containerId?: Long\n acked?: boolean\n initConn?: boolean\n getState?: number\n cancelled?: boolean\n timeout?: NodeJS.Timeout\n}\n\nexport type PendingMessage =\n | {\n _: 'rpc'\n rpc: PendingRpc\n }\n | {\n _: 'container'\n msgIds: Long[]\n }\n | {\n _: 'state'\n msgIds: Long[]\n containerId: Long\n }\n | {\n _: 'resend'\n msgIds: Long[]\n containerId: Long\n }\n | {\n _: 'ping'\n pingId: Long\n containerId: Long\n }\n | {\n _: 'destroy_session'\n sessionId: Long\n containerId: Long\n }\n | {\n _: 'cancel'\n msgId: Long\n containerId: Long\n }\n | {\n _: 'future_salts'\n containerId: Long\n }\n | {\n _: 'bind'\n promise: ControllablePromise\n }\n\n/**\n * Class encapsulating a single MTProto session and storing\n * all the relevant state\n */\nexport class MtprotoSession {\n _sessionId = randomLong()\n\n _authKey = new AuthKey(this._crypto, this.log, this._readerMap)\n _authKeyTemp = new AuthKey(this._crypto, this.log, this._readerMap)\n _authKeyTempSecondary = new AuthKey(this._crypto, this.log, this._readerMap)\n\n _timeOffset = 0\n _lastMessageId = Long.ZERO\n _seqNo = 0\n\n serverSalt = Long.ZERO\n\n /// state ///\n // recent msg ids\n recentOutgoingMsgIds = new LruSet<Long>(1000, true)\n recentIncomingMsgIds = new LruSet<Long>(1000, true)\n\n // queues\n queuedRpc = new Deque<PendingRpc>()\n queuedAcks: Long[] = []\n queuedStateReq: Long[] = []\n queuedResendReq: Long[] = []\n queuedCancelReq: Long[] = []\n getStateSchedule = new SortedArray<PendingRpc>([], (a, b) => a.getState! - b.getState!)\n\n // requests info\n pendingMessages = new LongMap<PendingMessage>()\n destroySessionIdToMsgId = new LongMap<Long>()\n\n lastPingRtt = NaN\n lastPingTime = 0\n lastPingMsgId = Long.ZERO\n lastSessionCreatedUid = Long.ZERO\n\n initConnectionCalled = false\n authorizationPending = false\n\n next429Timeout = 1000\n current429Timeout?: NodeJS.Timeout\n next429ResetTimeout?: NodeJS.Timeout\n\n constructor(\n readonly _crypto: ICryptoProvider,\n readonly log: Logger,\n readonly _readerMap: TlReaderMap,\n readonly _writerMap: TlWriterMap,\n ) {\n this.log.prefix = `[SESSION ${this._sessionId.toString(16)}] `\n }\n\n get hasPendingMessages(): boolean {\n return Boolean(\n this.queuedRpc.length ||\n this.queuedAcks.length ||\n this.queuedStateReq.length ||\n this.queuedResendReq.length,\n )\n }\n\n /**\n * Reset session by resetting auth key(s) and session state\n */\n reset(withAuthKey = false): void {\n if (withAuthKey) {\n this._authKey.reset()\n this._authKeyTemp.reset()\n this._authKeyTempSecondary.reset()\n }\n\n clearTimeout(this.current429Timeout)\n this.resetState()\n this.resetLastPing(true)\n }\n\n /**\n * Reset session state and generate a new session ID.\n *\n * By default, also cancels any pending RPC requests.\n * If `keepPending` is set to `true`, pending requests will be kept\n */\n resetState(keepPending = false): void {\n this._lastMessageId = Long.ZERO\n this._seqNo = 0\n\n this._sessionId = randomLong()\n this.log.debug('session reset, new sid = %h', this._sessionId)\n this.log.prefix = `[SESSION ${this._sessionId.toString(16)}] `\n\n // reset session state\n\n if (!keepPending) {\n for (const info of this.pendingMessages.values()) {\n if (info._ === 'rpc') {\n info.rpc.promise.reject(new MtcuteError('Session is reset'))\n }\n }\n this.pendingMessages.clear()\n }\n\n this.recentOutgoingMsgIds.clear()\n this.recentIncomingMsgIds.clear()\n\n if (!keepPending) {\n while (this.queuedRpc.length) {\n const rpc = this.queuedRpc.popFront()!\n\n if (rpc.sent === false) {\n rpc.promise.reject(new MtcuteError('Session is reset'))\n }\n }\n }\n\n this.queuedAcks.length = 0\n this.queuedStateReq.length = 0\n this.queuedResendReq.length = 0\n this.getStateSchedule.clear()\n }\n\n enqueueRpc(rpc: PendingRpc, force?: boolean): boolean {\n // already queued or cancelled\n if ((!force && !rpc.sent) || rpc.cancelled) return false\n\n rpc.sent = false\n rpc.containerId = undefined\n this.log.debug('enqueued %s for sending (msg_id = %s)', rpc.method, rpc.msgId || 'n/a')\n this.queuedRpc.pushBack(rpc)\n\n return true\n }\n\n getMessageId(): Long {\n const timeTicks = Date.now()\n const timeSec = Math.floor(timeTicks / 1000) + this._timeOffset\n const timeMSec = timeTicks % 1000\n const random = getRandomInt(0xffff)\n\n let messageId = new Long((timeMSec << 21) | (random << 3) | 4, timeSec)\n\n if (this._lastMessageId.gt(messageId)) {\n messageId = this._lastMessageId.add(4)\n }\n\n this._lastMessageId = messageId\n\n return messageId\n }\n\n getSeqNo(isContentRelated = true): number {\n let seqNo = this._seqNo\n\n if (isContentRelated) {\n seqNo += 1\n this._seqNo += 2\n }\n\n return seqNo\n }\n\n /** Encrypt a single MTProto message using session's keys */\n encryptMessage(message: Uint8Array): Uint8Array {\n const key = this._authKeyTemp.ready ? this._authKeyTemp : this._authKey\n\n return key.encryptMessage(message, this.serverSalt, this._sessionId)\n }\n\n /** Decrypt a single MTProto message using session's keys */\n decryptMessage(data: Uint8Array, callback: Parameters<AuthKey['decryptMessage']>[2]): void {\n if (!this._authKey.ready) throw new MtcuteError('Keys are not set up!')\n\n const authKeyId = data.subarray(0, 8)\n\n let key: AuthKey\n\n if (this._authKey.match(authKeyId)) {\n key = this._authKey\n } else if (this._authKeyTemp.match(authKeyId)) {\n key = this._authKeyTemp\n } else if (this._authKeyTempSecondary.match(authKeyId)) {\n key = this._authKeyTempSecondary\n } else {\n this.log.warn(\n 'received message with unknown authKey = %h (expected %h or %h or %h)',\n authKeyId,\n this._authKey.id,\n this._authKeyTemp.id,\n this._authKeyTempSecondary.id,\n )\n\n return\n }\n\n return key.decryptMessage(data, this._sessionId, callback)\n }\n\n writeMessage(\n writer: TlBinaryWriter,\n content: tl.TlObject | mtp.TlObject | Uint8Array,\n isContentRelated = true,\n ): Long {\n const messageId = this.getMessageId()\n const seqNo = this.getSeqNo(isContentRelated)\n\n const length = ArrayBuffer.isView(content) ?\n content.length :\n TlSerializationCounter.countNeededBytes(writer.objectMap!, content)\n\n writer.long(messageId)\n writer.int(seqNo)\n writer.uint(length)\n if (ArrayBuffer.isView(content)) writer.raw(content)\n else writer.object(content as tl.TlObject)\n\n return messageId\n }\n\n onTransportFlood(callback: () => void) {\n if (this.current429Timeout) return // already waiting\n\n // all active queries must be resent after a timeout\n this.resetLastPing(true)\n\n const timeout = this.next429Timeout\n\n this.next429Timeout = Math.min(this.next429Timeout * 2, 32000)\n clearTimeout(this.current429Timeout)\n clearTimeout(this.next429ResetTimeout)\n\n this.current429Timeout = setTimeout(() => {\n this.current429Timeout = undefined\n callback()\n }, timeout)\n this.next429ResetTimeout = setTimeout(() => {\n this.next429ResetTimeout = undefined\n this.next429Timeout = 1000\n }, 60000)\n\n this.log.debug('transport flood, waiting for %d ms before proceeding', timeout)\n\n return Date.now() + timeout\n }\n\n resetLastPing(withTime = false): void {\n if (withTime) this.lastPingTime = 0\n\n if (!this.lastPingMsgId.isZero()) {\n this.pendingMessages.delete(this.lastPingMsgId)\n }\n\n this.lastPingMsgId = Long.ZERO\n }\n}\n"]}
|
|
@@ -22,7 +22,7 @@ export declare class MultiSessionConnection extends EventEmitter {
|
|
|
22
22
|
sendRpc<T extends tl.RpcMethod>(request: T, stack?: string, timeout?: number, abortSignal?: AbortSignal): Promise<tl.RpcCallReturn[T['_']]>;
|
|
23
23
|
connect(): void;
|
|
24
24
|
ensureConnected(): void;
|
|
25
|
-
setAuthKey(authKey: Uint8Array | null, temp?: boolean, idx?: number):
|
|
25
|
+
setAuthKey(authKey: Uint8Array | null, temp?: boolean, idx?: number): void;
|
|
26
26
|
resetAuthKeys(): void;
|
|
27
27
|
setInactivityTimeout(timeout?: number): void;
|
|
28
28
|
notifyKeyChange(): void;
|
|
@@ -185,10 +185,10 @@ class MultiSessionConnection extends events_1.default {
|
|
|
185
185
|
return;
|
|
186
186
|
this.connect();
|
|
187
187
|
}
|
|
188
|
-
|
|
188
|
+
setAuthKey(authKey, temp = false, idx = 0) {
|
|
189
189
|
const session = this._sessions[idx];
|
|
190
190
|
const key = temp ? session._authKeyTemp : session._authKey;
|
|
191
|
-
|
|
191
|
+
key.setup(authKey);
|
|
192
192
|
}
|
|
193
193
|
resetAuthKeys() {
|
|
194
194
|
for (const session of this._sessions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-session-connection.js","sourceRoot":"","sources":["../../../src/network/multi-session-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events'\n\nimport { tl } from '@mtcute/tl'\n\nimport { Logger } from '../utils/index.js'\nimport { MtprotoSession } from './mtproto-session.js'\nimport { SessionConnection, SessionConnectionParams } from './session-connection.js'\nimport { TransportFactory } from './transports/index.js'\n\nexport class MultiSessionConnection extends EventEmitter {\n private _log: Logger\n readonly _sessions: MtprotoSession[]\n private _enforcePfs = false\n\n constructor(\n readonly params: SessionConnectionParams,\n private _count: number,\n log: Logger,\n logPrefix = '',\n ) {\n super()\n this._log = log.create('multi')\n if (logPrefix) this._log.prefix = `[${logPrefix}] `\n this._enforcePfs = _count > 1 && params.isMainConnection\n\n this._sessions = []\n this._updateConnections()\n }\n\n protected _connections: SessionConnection[] = []\n\n setCount(count: number, connect = this.params.isMainConnection): void {\n this._count = count\n\n this._updateConnections(connect)\n }\n\n private _updateSessions(): void {\n // there are two cases\n // 1. this msc is main, in which case every connection should have its own session\n // 2. this msc is not main, in which case all connections should share the same session\n // if (!this.params.isMainConnection) {\n // // case 2\n // this._log.debug(\n // 'updating sessions count: %d -> 1',\n // this._sessions.length,\n // )\n //\n // if (this._sessions.length === 0) {\n // this._sessions.push(\n // new MtprotoSession(\n // this.params.crypto,\n // this._log.create('session'),\n // this.params.readerMap,\n // this.params.writerMap,\n // ),\n // )\n // }\n //\n // // shouldn't happen, but just in case\n // while (this._sessions.length > 1) {\n // this._sessions.pop()!.reset()\n // }\n //\n // return\n // }\n\n this._log.debug('updating sessions count: %d -> %d', this._sessions.length, this._count)\n\n // case 1\n if (this._sessions.length === this._count) return\n\n if (this._sessions.length > this._count) {\n // destroy extra sessions\n for (let i = this._sessions.length - 1; i >= this._count; i--) {\n this._sessions[i].reset()\n }\n\n this._sessions.splice(this._count)\n\n return\n }\n\n while (this._sessions.length < this._count) {\n const idx = this._sessions.length\n const session = new MtprotoSession(\n this.params.crypto,\n this._log.create('session'),\n this.params.readerMap,\n this.params.writerMap,\n )\n\n // brvh\n if (idx !== 0) session._authKey = this._sessions[0]._authKey\n\n this._sessions.push(session)\n }\n }\n\n private _updateConnections(connect = false): void {\n this._updateSessions()\n if (this._connections.length === this._count) return\n\n this._log.debug('updating connections count: %d -> %d', this._connections.length, this._count)\n\n const newEnforcePfs = this._count > 1 && this.params.isMainConnection\n const enforcePfsChanged = newEnforcePfs !== this._enforcePfs\n\n if (enforcePfsChanged) {\n this._log.debug('enforcePfs changed: %s -> %s', this._enforcePfs, newEnforcePfs)\n this._enforcePfs = newEnforcePfs\n }\n\n if (this._connections.length > this._count) {\n // destroy extra connections\n for (let i = this._connections.length - 1; i >= this._count; i--) {\n this._connections[i].removeAllListeners()\n this._connections[i].destroy()\n }\n\n this._connections.splice(this._count)\n\n return\n }\n\n if (enforcePfsChanged) {\n this._connections.forEach((conn) => {\n conn.setUsePfs(this.params.usePfs || this._enforcePfs)\n })\n }\n\n // create new connections\n for (let i = this._connections.length; i < this._count; i++) {\n const session = this._sessions[i] // this.params.isMainConnection ? // :\n // this._sessions[0]\n const conn = new SessionConnection(\n {\n ...this.params,\n usePfs: this.params.usePfs || this._enforcePfs,\n isMainConnection: this.params.isMainConnection && i === 0,\n withUpdates:\n this.params.isMainConnection && this.params.isMainDcConnection && !this.params.disableUpdates,\n },\n session,\n )\n\n if (this.params.isMainConnection) {\n conn.on('update', (update) => this.emit('update', update))\n }\n conn.on('error', (err) => this.emit('error', err, conn))\n conn.on('key-change', (key) => {\n this.emit('key-change', i, key)\n\n // notify other connections\n for (const conn_ of this._connections) {\n if (conn_ === conn) continue\n conn_.onConnected()\n }\n })\n conn.on('tmp-key-change', (key, expires) => this.emit('tmp-key-change', i, key, expires))\n conn.on('auth-begin', () => {\n this._log.debug('received auth-begin from connection %d', i)\n this.emit('auth-begin', i)\n\n // we need to reset temp auth keys if there are any left\n\n this._connections.forEach((conn_) => {\n conn_._session._authKeyTemp.reset()\n if (conn_ !== conn) conn_.reconnect()\n })\n })\n conn.on('usable', () => this.emit('usable', i))\n conn.on('request-auth', () => this.emit('request-auth', i))\n conn.on('flood-done', () => {\n this._log.debug('received flood-done from connection %d', i)\n\n this._connections.forEach((it) => it.flushWhenIdle())\n })\n\n this._connections.push(conn)\n if (connect) conn.connect()\n }\n }\n\n _destroyed = false\n destroy(): void {\n this._connections.forEach((conn) => conn.destroy())\n this._sessions.forEach((sess) => sess.reset())\n this.removeAllListeners()\n\n this._destroyed = true\n }\n\n private _nextConnection = 0\n\n sendRpc<T extends tl.RpcMethod>(\n request: T,\n stack?: string,\n timeout?: number,\n abortSignal?: AbortSignal,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n // if (this.params.isMainConnection) {\n // find the least loaded connection\n let min = Infinity\n let minIdx = 0\n\n for (let i = 0; i < this._connections.length; i++) {\n const conn = this._connections[i]\n const total = conn._session.queuedRpc.length + conn._session.pendingMessages.size()\n\n if (total < min) {\n min = total\n minIdx = i\n }\n }\n\n return this._connections[minIdx].sendRpc(request, stack, timeout, abortSignal)\n // }\n\n // round-robin connections\n // since they all share the same session, it doesn't matter which one we use\n // the connection chosen here will only affect the first attempt at sending\n // return this._connections[\n // this._nextConnection++ % this._connections.length\n // ].sendRpc(request, stack, timeout)\n }\n\n connect(): void {\n for (const conn of this._connections) {\n conn.connect()\n }\n }\n\n ensureConnected(): void {\n if (this._connections[0].isConnected) return\n\n this.connect()\n }\n\n async setAuthKey(authKey: Uint8Array | null, temp = false, idx = 0): Promise<void> {\n const session = this._sessions[idx]\n const key = temp ? session._authKeyTemp : session._authKey\n await key.setup(authKey)\n }\n\n resetAuthKeys(): void {\n for (const session of this._sessions) {\n session.reset(true)\n }\n this.notifyKeyChange()\n }\n\n setInactivityTimeout(timeout?: number): void {\n this._log.debug('setting inactivity timeout to %s', timeout)\n\n // for future connections (if any)\n this.params.inactivityTimeout = timeout\n\n // for current connections\n for (const conn of this._connections) {\n conn.setInactivityTimeout(timeout)\n }\n }\n\n notifyKeyChange(): void {\n // only expected to be called on non-main connections\n const session = this._sessions[0]\n\n if (this.params.usePfs && !session._authKeyTemp.ready) {\n this._log.debug('temp auth key needed but not ready, ignoring key change')\n\n return\n }\n\n if (this._sessions[0].queuedRpc.length) {\n // there are pending requests, we need to reconnect.\n this._log.debug('notifying key change on the connection due to queued rpc')\n this._connections[0].onConnected()\n }\n\n // connection is idle, we don't need to notify it\n }\n\n requestAuth(): void {\n this._connections[0]._authorize()\n }\n\n resetSessions(): void {\n if (this.params.isMainConnection) {\n for (const conn of this._connections) {\n conn._resetSession()\n }\n } else {\n this._connections[0]._resetSession()\n }\n }\n\n changeTransport(factory: TransportFactory): void {\n this._connections.forEach((conn) => conn.changeTransport(factory))\n }\n\n getPoolSize(): number {\n return this._connections.length\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"multi-session-connection.js","sourceRoot":"","sources":["../../../src/network/multi-session-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events'\n\nimport { tl } from '@mtcute/tl'\n\nimport { Logger } from '../utils/index.js'\nimport { MtprotoSession } from './mtproto-session.js'\nimport { SessionConnection, SessionConnectionParams } from './session-connection.js'\nimport { TransportFactory } from './transports/index.js'\n\nexport class MultiSessionConnection extends EventEmitter {\n private _log: Logger\n readonly _sessions: MtprotoSession[]\n private _enforcePfs = false\n\n constructor(\n readonly params: SessionConnectionParams,\n private _count: number,\n log: Logger,\n logPrefix = '',\n ) {\n super()\n this._log = log.create('multi')\n if (logPrefix) this._log.prefix = `[${logPrefix}] `\n this._enforcePfs = _count > 1 && params.isMainConnection\n\n this._sessions = []\n this._updateConnections()\n }\n\n protected _connections: SessionConnection[] = []\n\n setCount(count: number, connect = this.params.isMainConnection): void {\n this._count = count\n\n this._updateConnections(connect)\n }\n\n private _updateSessions(): void {\n // there are two cases\n // 1. this msc is main, in which case every connection should have its own session\n // 2. this msc is not main, in which case all connections should share the same session\n // if (!this.params.isMainConnection) {\n // // case 2\n // this._log.debug(\n // 'updating sessions count: %d -> 1',\n // this._sessions.length,\n // )\n //\n // if (this._sessions.length === 0) {\n // this._sessions.push(\n // new MtprotoSession(\n // this.params.crypto,\n // this._log.create('session'),\n // this.params.readerMap,\n // this.params.writerMap,\n // ),\n // )\n // }\n //\n // // shouldn't happen, but just in case\n // while (this._sessions.length > 1) {\n // this._sessions.pop()!.reset()\n // }\n //\n // return\n // }\n\n this._log.debug('updating sessions count: %d -> %d', this._sessions.length, this._count)\n\n // case 1\n if (this._sessions.length === this._count) return\n\n if (this._sessions.length > this._count) {\n // destroy extra sessions\n for (let i = this._sessions.length - 1; i >= this._count; i--) {\n this._sessions[i].reset()\n }\n\n this._sessions.splice(this._count)\n\n return\n }\n\n while (this._sessions.length < this._count) {\n const idx = this._sessions.length\n const session = new MtprotoSession(\n this.params.crypto,\n this._log.create('session'),\n this.params.readerMap,\n this.params.writerMap,\n )\n\n // brvh\n if (idx !== 0) session._authKey = this._sessions[0]._authKey\n\n this._sessions.push(session)\n }\n }\n\n private _updateConnections(connect = false): void {\n this._updateSessions()\n if (this._connections.length === this._count) return\n\n this._log.debug('updating connections count: %d -> %d', this._connections.length, this._count)\n\n const newEnforcePfs = this._count > 1 && this.params.isMainConnection\n const enforcePfsChanged = newEnforcePfs !== this._enforcePfs\n\n if (enforcePfsChanged) {\n this._log.debug('enforcePfs changed: %s -> %s', this._enforcePfs, newEnforcePfs)\n this._enforcePfs = newEnforcePfs\n }\n\n if (this._connections.length > this._count) {\n // destroy extra connections\n for (let i = this._connections.length - 1; i >= this._count; i--) {\n this._connections[i].removeAllListeners()\n this._connections[i].destroy()\n }\n\n this._connections.splice(this._count)\n\n return\n }\n\n if (enforcePfsChanged) {\n this._connections.forEach((conn) => {\n conn.setUsePfs(this.params.usePfs || this._enforcePfs)\n })\n }\n\n // create new connections\n for (let i = this._connections.length; i < this._count; i++) {\n const session = this._sessions[i] // this.params.isMainConnection ? // :\n // this._sessions[0]\n const conn = new SessionConnection(\n {\n ...this.params,\n usePfs: this.params.usePfs || this._enforcePfs,\n isMainConnection: this.params.isMainConnection && i === 0,\n withUpdates:\n this.params.isMainConnection && this.params.isMainDcConnection && !this.params.disableUpdates,\n },\n session,\n )\n\n if (this.params.isMainConnection) {\n conn.on('update', (update) => this.emit('update', update))\n }\n conn.on('error', (err) => this.emit('error', err, conn))\n conn.on('key-change', (key) => {\n this.emit('key-change', i, key)\n\n // notify other connections\n for (const conn_ of this._connections) {\n if (conn_ === conn) continue\n conn_.onConnected()\n }\n })\n conn.on('tmp-key-change', (key, expires) => this.emit('tmp-key-change', i, key, expires))\n conn.on('auth-begin', () => {\n this._log.debug('received auth-begin from connection %d', i)\n this.emit('auth-begin', i)\n\n // we need to reset temp auth keys if there are any left\n\n this._connections.forEach((conn_) => {\n conn_._session._authKeyTemp.reset()\n if (conn_ !== conn) conn_.reconnect()\n })\n })\n conn.on('usable', () => this.emit('usable', i))\n conn.on('request-auth', () => this.emit('request-auth', i))\n conn.on('flood-done', () => {\n this._log.debug('received flood-done from connection %d', i)\n\n this._connections.forEach((it) => it.flushWhenIdle())\n })\n\n this._connections.push(conn)\n if (connect) conn.connect()\n }\n }\n\n _destroyed = false\n destroy(): void {\n this._connections.forEach((conn) => conn.destroy())\n this._sessions.forEach((sess) => sess.reset())\n this.removeAllListeners()\n\n this._destroyed = true\n }\n\n private _nextConnection = 0\n\n sendRpc<T extends tl.RpcMethod>(\n request: T,\n stack?: string,\n timeout?: number,\n abortSignal?: AbortSignal,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n // if (this.params.isMainConnection) {\n // find the least loaded connection\n let min = Infinity\n let minIdx = 0\n\n for (let i = 0; i < this._connections.length; i++) {\n const conn = this._connections[i]\n const total = conn._session.queuedRpc.length + conn._session.pendingMessages.size()\n\n if (total < min) {\n min = total\n minIdx = i\n }\n }\n\n return this._connections[minIdx].sendRpc(request, stack, timeout, abortSignal)\n // }\n\n // round-robin connections\n // since they all share the same session, it doesn't matter which one we use\n // the connection chosen here will only affect the first attempt at sending\n // return this._connections[\n // this._nextConnection++ % this._connections.length\n // ].sendRpc(request, stack, timeout)\n }\n\n connect(): void {\n for (const conn of this._connections) {\n conn.connect()\n }\n }\n\n ensureConnected(): void {\n if (this._connections[0].isConnected) return\n\n this.connect()\n }\n\n setAuthKey(authKey: Uint8Array | null, temp = false, idx = 0): void {\n const session = this._sessions[idx]\n const key = temp ? session._authKeyTemp : session._authKey\n key.setup(authKey)\n }\n\n resetAuthKeys(): void {\n for (const session of this._sessions) {\n session.reset(true)\n }\n this.notifyKeyChange()\n }\n\n setInactivityTimeout(timeout?: number): void {\n this._log.debug('setting inactivity timeout to %s', timeout)\n\n // for future connections (if any)\n this.params.inactivityTimeout = timeout\n\n // for current connections\n for (const conn of this._connections) {\n conn.setInactivityTimeout(timeout)\n }\n }\n\n notifyKeyChange(): void {\n // only expected to be called on non-main connections\n const session = this._sessions[0]\n\n if (this.params.usePfs && !session._authKeyTemp.ready) {\n this._log.debug('temp auth key needed but not ready, ignoring key change')\n\n return\n }\n\n if (this._sessions[0].queuedRpc.length) {\n // there are pending requests, we need to reconnect.\n this._log.debug('notifying key change on the connection due to queued rpc')\n this._connections[0].onConnected()\n }\n\n // connection is idle, we don't need to notify it\n }\n\n requestAuth(): void {\n this._connections[0]._authorize()\n }\n\n resetSessions(): void {\n if (this.params.isMainConnection) {\n for (const conn of this._connections) {\n conn._resetSession()\n }\n } else {\n this._connections[0]._resetSession()\n }\n }\n\n changeTransport(factory: TransportFactory): void {\n this._connections.forEach((conn) => conn.changeTransport(factory))\n }\n\n getPoolSize(): number {\n return this._connections.length\n }\n}\n"]}
|
|
@@ -33,6 +33,7 @@ export interface NetworkManagerParams {
|
|
|
33
33
|
isPremium: boolean;
|
|
34
34
|
_emitError: (err: Error, connection?: SessionConnection) => void;
|
|
35
35
|
keepAliveAction: () => void;
|
|
36
|
+
onUsable: () => void;
|
|
36
37
|
}
|
|
37
38
|
export type ConnectionCountDelegate = (kind: ConnectionKind, dcId: number, isPremium: boolean) => number;
|
|
38
39
|
/**
|
|
@@ -99,12 +99,10 @@ class DcConnectionManager {
|
|
|
99
99
|
}
|
|
100
100
|
this.manager._log.debug('key change for dc %d from connection %d', this.dcId, idx);
|
|
101
101
|
// send key to other connections
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.downloadSmall.setAuthKey(key),
|
|
107
|
-
])
|
|
102
|
+
this.upload.setAuthKey(key);
|
|
103
|
+
this.download.setAuthKey(key);
|
|
104
|
+
this.downloadSmall.setAuthKey(key);
|
|
105
|
+
Promise.resolve(this.manager._storage.setAuthKeyFor(this.dcId, key))
|
|
108
106
|
.then(() => {
|
|
109
107
|
this.upload.notifyKeyChange();
|
|
110
108
|
this.download.notifyKeyChange();
|
|
@@ -119,12 +117,10 @@ class DcConnectionManager {
|
|
|
119
117
|
}
|
|
120
118
|
this.manager._log.debug('temp key change for dc %d from connection %d', this.dcId, idx);
|
|
121
119
|
// send key to other connections
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this.downloadSmall.setAuthKey(key, true),
|
|
127
|
-
])
|
|
120
|
+
this.upload.setAuthKey(key, true);
|
|
121
|
+
this.download.setAuthKey(key, true);
|
|
122
|
+
this.downloadSmall.setAuthKey(key, true);
|
|
123
|
+
Promise.resolve(this.manager._storage.setTempAuthKeyFor(this.dcId, idx, key, expires * 1000))
|
|
128
124
|
.then(() => {
|
|
129
125
|
this.upload.notifyKeyChange();
|
|
130
126
|
this.download.notifyKeyChange();
|
|
@@ -170,25 +166,21 @@ class DcConnectionManager {
|
|
|
170
166
|
}
|
|
171
167
|
async loadKeys() {
|
|
172
168
|
const permanent = await this.manager._storage.getAuthKeyFor(this.dcId);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
this.downloadSmall.setAuthKey(permanent),
|
|
178
|
-
]);
|
|
169
|
+
this.main.setAuthKey(permanent);
|
|
170
|
+
this.upload.setAuthKey(permanent);
|
|
171
|
+
this.download.setAuthKey(permanent);
|
|
172
|
+
this.downloadSmall.setAuthKey(permanent);
|
|
179
173
|
if (!permanent) {
|
|
180
174
|
return false;
|
|
181
175
|
}
|
|
182
176
|
if (this.manager.params.usePfs) {
|
|
183
177
|
await Promise.all(this.main._sessions.map(async (_, i) => {
|
|
184
178
|
const temp = await this.manager._storage.getAuthKeyFor(this.dcId, i);
|
|
185
|
-
|
|
179
|
+
this.main.setAuthKey(temp, true, i);
|
|
186
180
|
if (i === 0) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.downloadSmall.setAuthKey(temp, true),
|
|
191
|
-
]);
|
|
181
|
+
this.upload.setAuthKey(temp, true);
|
|
182
|
+
this.download.setAuthKey(temp, true);
|
|
183
|
+
this.downloadSmall.setAuthKey(temp, true);
|
|
192
184
|
}
|
|
193
185
|
}));
|
|
194
186
|
}
|
|
@@ -227,7 +219,7 @@ class NetworkManager {
|
|
|
227
219
|
_: 'initConnection',
|
|
228
220
|
deviceModel,
|
|
229
221
|
systemVersion: '1.0',
|
|
230
|
-
appVersion: '0.1.
|
|
222
|
+
appVersion: '0.1.1',
|
|
231
223
|
systemLangCode: 'en',
|
|
232
224
|
langPack: '',
|
|
233
225
|
langCode: 'en',
|
|
@@ -271,6 +263,7 @@ class NetworkManager {
|
|
|
271
263
|
dc.setIsPrimary(true);
|
|
272
264
|
dc.main.on('usable', () => {
|
|
273
265
|
this._lastUpdateTime = Date.now();
|
|
266
|
+
this.params.onUsable();
|
|
274
267
|
if (this._keepAliveInterval)
|
|
275
268
|
clearInterval(this._keepAliveInterval);
|
|
276
269
|
this._keepAliveInterval = setInterval(() => {
|
|
@@ -454,8 +447,9 @@ class NetworkManager {
|
|
|
454
447
|
}
|
|
455
448
|
catch (e) {
|
|
456
449
|
lastError = e;
|
|
457
|
-
if (!tl_1.tl.RpcError.is(e))
|
|
458
|
-
|
|
450
|
+
if (!tl_1.tl.RpcError.is(e)) {
|
|
451
|
+
throw e;
|
|
452
|
+
}
|
|
459
453
|
if (!(e.code in CLIENT_ERRORS)) {
|
|
460
454
|
this._log.warn('Telegram is having internal issues: %d %s, retrying', e.code, e.message);
|
|
461
455
|
if (e.text === 'WORKER_BUSY_TOO_LONG_RETRY') {
|