@honeybbq/teamspeak-client 0.0.0 → 0.1.0
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/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/api.d.ts +17 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/client.d.ts +39 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/command/command.d.ts +12 -0
- package/dist/command/command.d.ts.map +1 -0
- package/dist/command/command.test.d.ts +2 -0
- package/dist/command/command.test.d.ts.map +1 -0
- package/dist/command/index.cjs +1 -0
- package/dist/command/index.d.ts +4 -0
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.mjs +3 -0
- package/dist/command/parser.d.ts +3 -0
- package/dist/command/parser.d.ts.map +1 -0
- package/dist/command-Cu2v-5-K.cjs +4 -0
- package/dist/command-Cu2v-5-K.cjs.map +1 -0
- package/dist/command-caXc4h0n.js +76 -0
- package/dist/command-caXc4h0n.js.map +1 -0
- package/dist/commands.d.ts +48 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/crypt-handshake-CHmvZ2qs.js +55 -0
- package/dist/crypt-handshake-CHmvZ2qs.js.map +1 -0
- package/dist/crypt-handshake-Dbj2cSBZ.cjs +2 -0
- package/dist/crypt-handshake-Dbj2cSBZ.cjs.map +1 -0
- package/dist/crypt-init2-BIbQ7TN0.cjs +2 -0
- package/dist/crypt-init2-BIbQ7TN0.cjs.map +1 -0
- package/dist/crypt-init2-C63eypta.js +165 -0
- package/dist/crypt-init2-C63eypta.js.map +1 -0
- package/dist/crypto/crypt-ops.d.ts +7 -0
- package/dist/crypto/crypt-ops.d.ts.map +1 -0
- package/dist/crypto/crypt.d.ts +22 -0
- package/dist/crypto/crypt.d.ts.map +1 -0
- package/dist/crypto/eax.d.ts +12 -0
- package/dist/crypto/eax.d.ts.map +1 -0
- package/dist/crypto/eax.test.d.ts +2 -0
- package/dist/crypto/eax.test.d.ts.map +1 -0
- package/dist/crypto/identity.d.ts +18 -0
- package/dist/crypto/identity.d.ts.map +1 -0
- package/dist/crypto/identity.test.d.ts +2 -0
- package/dist/crypto/identity.test.d.ts.map +1 -0
- package/dist/crypto/index.cjs +1 -0
- package/dist/crypto/index.d.ts +6 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.mjs +3 -0
- package/dist/crypto/primitives.d.ts +28 -0
- package/dist/crypto/primitives.d.ts.map +1 -0
- package/dist/crypto-C3gBJkh2.cjs +2 -0
- package/dist/crypto-C3gBJkh2.cjs.map +1 -0
- package/dist/crypto-IGJlkTAl.js +165 -0
- package/dist/crypto-IGJlkTAl.js.map +1 -0
- package/dist/discovery/index.cjs +1 -0
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.mjs +2 -0
- package/dist/discovery/resolver.d.ts +8 -0
- package/dist/discovery/resolver.d.ts.map +1 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/events.d.ts +10 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/handler-C2vxlHYC.js +458 -0
- package/dist/handler-C2vxlHYC.js.map +1 -0
- package/dist/handler-DQteUMKT.cjs +2 -0
- package/dist/handler-DQteUMKT.cjs.map +1 -0
- package/dist/handshake/crypt-handshake.d.ts +8 -0
- package/dist/handshake/crypt-handshake.d.ts.map +1 -0
- package/dist/handshake/crypt-init2.d.ts +7 -0
- package/dist/handshake/crypt-init2.d.ts.map +1 -0
- package/dist/handshake/index.cjs +1 -0
- package/dist/handshake/index.d.ts +4 -0
- package/dist/handshake/index.d.ts.map +1 -0
- package/dist/handshake/index.mjs +3 -0
- package/dist/handshake/license.d.ts +28 -0
- package/dist/handshake/license.d.ts.map +1 -0
- package/dist/handshake.d.ts +9 -0
- package/dist/handshake.d.ts.map +1 -0
- package/dist/helpers.d.ts +14 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.test.d.ts +2 -0
- package/dist/helpers.test.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +761 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integration.test.d.ts +12 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/notifications.d.ts +32 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.test.d.ts +2 -0
- package/dist/notifications.test.d.ts.map +1 -0
- package/dist/parser-CJjP3LlO.js +33 -0
- package/dist/parser-CJjP3LlO.js.map +1 -0
- package/dist/parser-DhAWj-TI.cjs +2 -0
- package/dist/parser-DhAWj-TI.cjs.map +1 -0
- package/dist/primitives-BxtDMP7x.cjs +2 -0
- package/dist/primitives-BxtDMP7x.cjs.map +1 -0
- package/dist/primitives-CmIK1O7L.js +1836 -0
- package/dist/primitives-CmIK1O7L.js.map +1 -0
- package/dist/resolver-DDZWomrF.js +165 -0
- package/dist/resolver-DDZWomrF.js.map +1 -0
- package/dist/resolver-Dey6omBe.cjs +4 -0
- package/dist/resolver-Dey6omBe.cjs.map +1 -0
- package/dist/throttle.d.ts +11 -0
- package/dist/throttle.d.ts.map +1 -0
- package/dist/throttle.test.d.ts +2 -0
- package/dist/throttle.test.d.ts.map +1 -0
- package/dist/transfer.d.ts +34 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transport/generation-window.d.ts +15 -0
- package/dist/transport/generation-window.d.ts.map +1 -0
- package/dist/transport/generation-window.test.d.ts +2 -0
- package/dist/transport/generation-window.test.d.ts.map +1 -0
- package/dist/transport/handler.d.ts +18 -0
- package/dist/transport/handler.d.ts.map +1 -0
- package/dist/transport/index.cjs +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.mjs +2 -0
- package/dist/transport/packet.d.ts +36 -0
- package/dist/transport/packet.d.ts.map +1 -0
- package/dist/transport/packet.test.d.ts +2 -0
- package/dist/transport/packet.test.d.ts.map +1 -0
- package/dist/transport/quicklz.d.ts +5 -0
- package/dist/transport/quicklz.d.ts.map +1 -0
- package/dist/transport/quicklz.test.d.ts +2 -0
- package/dist/transport/quicklz.test.d.ts.map +1 -0
- package/dist/types-CGKgXvpG.js +18 -0
- package/dist/types-CGKgXvpG.js.map +1 -0
- package/dist/types-DrnoCdSW.cjs +2 -0
- package/dist/types-DrnoCdSW.cjs.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +87 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypt-init2-BIbQ7TN0.cjs","names":[],"sources":["../src/handshake/license.ts","../src/handshake/crypt-init2.ts"],"sourcesContent":["import { hash512 } from \"../crypto/identity.js\";\nimport { clampScalar } from \"../crypto/primitives.js\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\n\n// The root key is a 33-byte Ed25519 point\nconst LICENSE_ROOT_KEY = new Uint8Array([\n 0xcd, 0x0d, 0xe2, 0xae, 0xd4, 0x63, 0x45, 0x50, 0x9a, 0x7e, 0x3c, 0xfd, 0x8f, 0x68, 0xb3, 0xdc,\n 0x75, 0x55, 0xb2, 0x9d, 0xcc, 0xec, 0x73, 0xcd, 0x18, 0x75, 0x0f, 0x99, 0x38, 0x12, 0x40, 0x8a,\n]);\n\nconst enum LicenseBlockType {\n Intermediate = 0,\n Server = 2,\n Ts5Server = 8,\n Ephemeral = 32,\n}\n\ninterface LicenseBlock {\n readonly key: Uint8Array; // 32-byte Ed25519 point\n readonly hash: Uint8Array; // SHA-512 truncated to 32 bytes\n properties: Uint8Array[];\n issuer: string;\n notValidBefore: Date;\n notValidAfter: Date;\n blockType: LicenseBlockType;\n serverType: number;\n}\n\nexport class LicenseChain {\n readonly blocks: LicenseBlock[];\n\n constructor(blocks: LicenseBlock[]) {\n this.blocks = blocks;\n }\n\n /**\n * Derive the session key by chaining Ed25519 point arithmetic starting from\n * the root key through each license block.\n */\n deriveKey(): Uint8Array<ArrayBuffer> {\n let round: Uint8Array<ArrayBuffer> = Uint8Array.from(LICENSE_ROOT_KEY);\n for (const block of this.blocks) {\n round = deriveKeyFromBlock(block, round);\n }\n return round;\n }\n}\n\nexport function parseLicenses(data: Uint8Array): LicenseChain {\n if (data.length < 1) throw new Error(\"license too short\");\n if (data[0] !== 1) throw new Error(\"unsupported license version\");\n\n let remaining = data.slice(1);\n const blocks: LicenseBlock[] = [];\n\n while (remaining.length > 0) {\n const { block, consumed } = parseLicenseBlock(remaining);\n blocks.push(block);\n remaining = remaining.slice(consumed);\n }\n\n return new LicenseChain(blocks);\n}\n\nfunction parseLicenseBlock(data: Uint8Array): { block: LicenseBlock; consumed: number } {\n const MIN_BLOCK_LEN = 42;\n if (data.length < MIN_BLOCK_LEN) throw new Error(\"license too short\");\n if (data[0] !== 0) throw new Error(`wrong key kind in license: ${data[0]}`);\n\n const blockType = data[33] as LicenseBlockType;\n\n // Timestamps are seconds since Unix epoch offset by 0x50e22700\n const UNIX_OFFSET = 0x50e22700;\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const notValidBefore = new Date((view.getUint32(34, false) + UNIX_OFFSET) * 1000);\n const notValidAfter = new Date((view.getUint32(38, false) + UNIX_OFFSET) * 1000);\n\n if (notValidAfter < notValidBefore) {\n throw new Error(\"license times are invalid\");\n }\n\n const key = Uint8Array.from(data.slice(1, 33));\n\n const { payload, payloadRead } = parseBlockPayload(blockType, data, MIN_BLOCK_LEN);\n\n const allLen = MIN_BLOCK_LEN + payloadRead;\n const hashInput = data.slice(1, allLen);\n const hashFull = hash512(Uint8Array.from(hashInput));\n const hash = Uint8Array.from(hashFull.slice(0, 32));\n\n return {\n block: {\n key,\n hash,\n properties: payload.properties,\n issuer: payload.issuer,\n notValidBefore,\n notValidAfter,\n blockType,\n serverType: payload.serverType,\n },\n consumed: allLen,\n };\n}\n\ninterface BlockPayload {\n issuer: string;\n serverType: number;\n properties: Uint8Array[];\n read: number;\n}\n\nfunction parseBlockPayload(\n blockType: LicenseBlockType,\n data: Uint8Array,\n minBlockLen: number,\n): { payload: BlockPayload; payloadRead: number } {\n switch (blockType) {\n case LicenseBlockType.Intermediate: {\n const { str, read } = readNullString(data.slice(46));\n return {\n payload: { issuer: str, serverType: 0, properties: [], read: 5 + read },\n payloadRead: 5 + read,\n };\n }\n case LicenseBlockType.Server: {\n const { str, read } = readNullString(data.slice(47));\n return {\n payload: { issuer: str, serverType: data[42] ?? 0, properties: [], read: 6 + read },\n payloadRead: 6 + read,\n };\n }\n case LicenseBlockType.Ts5Server: {\n const propCount = data[43] !== undefined ? data[43] : 0;\n let pos = 44;\n const properties: Uint8Array[] = [];\n for (let i = 0; i < propCount; i++) {\n if (pos >= data.length) throw new Error(\"license too short\");\n const propLen = data[pos++]!;\n if (pos + propLen > data.length) throw new Error(\"license too short\");\n properties.push(Uint8Array.from(data.slice(pos, pos + propLen)));\n pos += propLen;\n }\n return {\n payload: { issuer: \"\", serverType: data[42] ?? 0, properties, read: pos - minBlockLen },\n payloadRead: pos - minBlockLen,\n };\n }\n case LicenseBlockType.Ephemeral:\n return { payload: { issuer: \"\", serverType: 0, properties: [], read: 0 }, payloadRead: 0 };\n default:\n throw new Error(`invalid license block type: ${blockType}`);\n }\n}\n\n/**\n * Scan for a null-terminated string and return its content and the index\n * of the null byte (NOT including it in the count, matching Go behaviour).\n * The parent formulas (`5 + read`, `6 + read`) already add 1 for the null.\n */\nfunction readNullString(data: Uint8Array): { str: string; read: number } {\n for (let i = 0; i < data.length; i++) {\n if (data[i] === 0) {\n return { str: new TextDecoder().decode(data.slice(0, i)), read: i };\n }\n }\n throw new Error(\"non-null-terminated issuer string\");\n}\n\n/**\n * Derive the next key given a parent key and a license block.\n * Mirrors Go's licenseBlock.deriveKey.\n */\nfunction deriveKeyFromBlock(block: LicenseBlock, parent: Uint8Array): Uint8Array<ArrayBuffer> {\n const scalarBytes = Uint8Array.from(block.hash);\n clampScalar(scalarBytes);\n\n // Reduce mod curve order — matches Go's scalar.NewFromBits behaviour\n const scalar = bytesToBigIntLE(scalarBytes) % ed25519.Point.CURVE().n;\n\n const pub = ed25519.Point.fromBytes(block.key);\n const negPub = pub.negate();\n\n const par = ed25519.Point.fromBytes(parent);\n const negPar = par.negate();\n\n const res = negPub.multiply(scalar).add(negPar);\n const raw = res.toBytes();\n const final = new Uint8Array(raw.length) as Uint8Array<ArrayBuffer>;\n final.set(raw);\n final[31] = (final[31] !== undefined ? final[31] : 0) ^ 0x80;\n\n return final;\n}\n\nfunction bytesToBigIntLE(bytes: Uint8Array): bigint {\n let result = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n result = (result << 8n) | BigInt(bytes[i]!);\n }\n return result;\n}\n","import type { Crypt } from \"../crypto/crypt.js\";\nimport { importPublicKey } from \"../crypto/identity.js\";\nimport { verifySign, getSharedSecret2 } from \"../crypto/primitives.js\";\nimport { parseLicenses } from \"./license.js\";\n\n/**\n * CryptoInit2 performs the second stage of crypto initialization (Ed25519 ECDH).\n * Mirrors Go's handshake.CryptoInit2.\n */\nexport function cryptoInit2(\n crypt: Crypt,\n license: string,\n omega: string,\n proof: string,\n beta: string,\n privateKey: Uint8Array,\n): void {\n if (crypt.alphaTmp.length === 0) {\n throw new Error(\"alpha is not initialized\");\n }\n\n const licenseBytes = Buffer.from(license, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n const proofBytes = Buffer.from(proof, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n if (!verifySign(serverPubKey, licenseBytes, proofBytes)) {\n throw new Error(\"init proof is not valid\");\n }\n\n const licenses = parseLicenses(licenseBytes);\n const key = licenses.deriveKey();\n\n const sharedSecret = getSharedSecret2(key, privateKey);\n\n crypt.setSharedSecret(crypt.alphaTmp, betaBytes, sharedSecret);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { a as e, f as t, o as n, r, t as i, u as a } from "./primitives-CmIK1O7L.js";
|
|
2
|
+
//#region src/handshake/license.ts
|
|
3
|
+
var o = new Uint8Array([
|
|
4
|
+
205,
|
|
5
|
+
13,
|
|
6
|
+
226,
|
|
7
|
+
174,
|
|
8
|
+
212,
|
|
9
|
+
99,
|
|
10
|
+
69,
|
|
11
|
+
80,
|
|
12
|
+
154,
|
|
13
|
+
126,
|
|
14
|
+
60,
|
|
15
|
+
253,
|
|
16
|
+
143,
|
|
17
|
+
104,
|
|
18
|
+
179,
|
|
19
|
+
220,
|
|
20
|
+
117,
|
|
21
|
+
85,
|
|
22
|
+
178,
|
|
23
|
+
157,
|
|
24
|
+
204,
|
|
25
|
+
236,
|
|
26
|
+
115,
|
|
27
|
+
205,
|
|
28
|
+
24,
|
|
29
|
+
117,
|
|
30
|
+
15,
|
|
31
|
+
153,
|
|
32
|
+
56,
|
|
33
|
+
18,
|
|
34
|
+
64,
|
|
35
|
+
138
|
|
36
|
+
]), s = /* @__PURE__ */ function(e) {
|
|
37
|
+
return e[e.Intermediate = 0] = "Intermediate", e[e.Server = 2] = "Server", e[e.Ts5Server = 8] = "Ts5Server", e[e.Ephemeral = 32] = "Ephemeral", e;
|
|
38
|
+
}(s || {}), c = class {
|
|
39
|
+
blocks;
|
|
40
|
+
constructor(e) {
|
|
41
|
+
this.blocks = e;
|
|
42
|
+
}
|
|
43
|
+
deriveKey() {
|
|
44
|
+
let e = Uint8Array.from(o);
|
|
45
|
+
for (let t of this.blocks) e = p(t, e);
|
|
46
|
+
return e;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function l(e) {
|
|
50
|
+
if (e.length < 1) throw Error("license too short");
|
|
51
|
+
if (e[0] !== 1) throw Error("unsupported license version");
|
|
52
|
+
let t = e.slice(1), n = [];
|
|
53
|
+
for (; t.length > 0;) {
|
|
54
|
+
let { block: e, consumed: r } = u(t);
|
|
55
|
+
n.push(e), t = t.slice(r);
|
|
56
|
+
}
|
|
57
|
+
return new c(n);
|
|
58
|
+
}
|
|
59
|
+
function u(e) {
|
|
60
|
+
if (e.length < 42) throw Error("license too short");
|
|
61
|
+
if (e[0] !== 0) throw Error(`wrong key kind in license: ${e[0]}`);
|
|
62
|
+
let t = e[33], n = 1356998400, r = new DataView(e.buffer, e.byteOffset, e.byteLength), i = /* @__PURE__ */ new Date((r.getUint32(34, !1) + n) * 1e3), o = /* @__PURE__ */ new Date((r.getUint32(38, !1) + n) * 1e3);
|
|
63
|
+
if (o < i) throw Error("license times are invalid");
|
|
64
|
+
let s = Uint8Array.from(e.slice(1, 33)), { payload: c, payloadRead: l } = d(t, e, 42), u = 42 + l, f = e.slice(1, u), p = a(Uint8Array.from(f));
|
|
65
|
+
return {
|
|
66
|
+
block: {
|
|
67
|
+
key: s,
|
|
68
|
+
hash: Uint8Array.from(p.slice(0, 32)),
|
|
69
|
+
properties: c.properties,
|
|
70
|
+
issuer: c.issuer,
|
|
71
|
+
notValidBefore: i,
|
|
72
|
+
notValidAfter: o,
|
|
73
|
+
blockType: t,
|
|
74
|
+
serverType: c.serverType
|
|
75
|
+
},
|
|
76
|
+
consumed: u
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function d(e, t, n) {
|
|
80
|
+
switch (e) {
|
|
81
|
+
case s.Intermediate: {
|
|
82
|
+
let { str: e, read: n } = f(t.slice(46));
|
|
83
|
+
return {
|
|
84
|
+
payload: {
|
|
85
|
+
issuer: e,
|
|
86
|
+
serverType: 0,
|
|
87
|
+
properties: [],
|
|
88
|
+
read: 5 + n
|
|
89
|
+
},
|
|
90
|
+
payloadRead: 5 + n
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
case s.Server: {
|
|
94
|
+
let { str: e, read: n } = f(t.slice(47));
|
|
95
|
+
return {
|
|
96
|
+
payload: {
|
|
97
|
+
issuer: e,
|
|
98
|
+
serverType: t[42] ?? 0,
|
|
99
|
+
properties: [],
|
|
100
|
+
read: 6 + n
|
|
101
|
+
},
|
|
102
|
+
payloadRead: 6 + n
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
case s.Ts5Server: {
|
|
106
|
+
let e = t[43] === void 0 ? 0 : t[43], r = 44, i = [];
|
|
107
|
+
for (let n = 0; n < e; n++) {
|
|
108
|
+
if (r >= t.length) throw Error("license too short");
|
|
109
|
+
let e = t[r++];
|
|
110
|
+
if (r + e > t.length) throw Error("license too short");
|
|
111
|
+
i.push(Uint8Array.from(t.slice(r, r + e))), r += e;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
payload: {
|
|
115
|
+
issuer: "",
|
|
116
|
+
serverType: t[42] ?? 0,
|
|
117
|
+
properties: i,
|
|
118
|
+
read: r - n
|
|
119
|
+
},
|
|
120
|
+
payloadRead: r - n
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
case s.Ephemeral: return {
|
|
124
|
+
payload: {
|
|
125
|
+
issuer: "",
|
|
126
|
+
serverType: 0,
|
|
127
|
+
properties: [],
|
|
128
|
+
read: 0
|
|
129
|
+
},
|
|
130
|
+
payloadRead: 0
|
|
131
|
+
};
|
|
132
|
+
default: throw Error(`invalid license block type: ${e}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function f(e) {
|
|
136
|
+
for (let t = 0; t < e.length; t++) if (e[t] === 0) return {
|
|
137
|
+
str: new TextDecoder().decode(e.slice(0, t)),
|
|
138
|
+
read: t
|
|
139
|
+
};
|
|
140
|
+
throw Error("non-null-terminated issuer string");
|
|
141
|
+
}
|
|
142
|
+
function p(e, t) {
|
|
143
|
+
let r = Uint8Array.from(e.hash);
|
|
144
|
+
i(r);
|
|
145
|
+
let a = m(r) % n.Point.CURVE().n, o = n.Point.fromBytes(e.key).negate(), s = n.Point.fromBytes(t).negate(), c = o.multiply(a).add(s).toBytes(), l = new Uint8Array(c.length);
|
|
146
|
+
return l.set(c), l[31] = (l[31] === void 0 ? 0 : l[31]) ^ 128, l;
|
|
147
|
+
}
|
|
148
|
+
function m(e) {
|
|
149
|
+
let t = 0n;
|
|
150
|
+
for (let n = e.length - 1; n >= 0; n--) t = t << 8n | BigInt(e[n]);
|
|
151
|
+
return t;
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/handshake/crypt-init2.ts
|
|
155
|
+
function h(n, i, a, o, s, c) {
|
|
156
|
+
if (n.alphaTmp.length === 0) throw Error("alpha is not initialized");
|
|
157
|
+
let u = Buffer.from(i, "base64"), d = Buffer.from(a, "base64"), f = Buffer.from(o, "base64"), p = Buffer.from(s, "base64");
|
|
158
|
+
if (!e(t(d), u, f)) throw Error("init proof is not valid");
|
|
159
|
+
let m = r(l(u).deriveKey(), c);
|
|
160
|
+
n.setSharedSecret(n.alphaTmp, p, m);
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { c as n, l as r, h as t };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=crypt-init2-C63eypta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypt-init2-C63eypta.js","names":[],"sources":["../src/handshake/license.ts","../src/handshake/crypt-init2.ts"],"sourcesContent":["import { hash512 } from \"../crypto/identity.js\";\nimport { clampScalar } from \"../crypto/primitives.js\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\n\n// The root key is a 33-byte Ed25519 point\nconst LICENSE_ROOT_KEY = new Uint8Array([\n 0xcd, 0x0d, 0xe2, 0xae, 0xd4, 0x63, 0x45, 0x50, 0x9a, 0x7e, 0x3c, 0xfd, 0x8f, 0x68, 0xb3, 0xdc,\n 0x75, 0x55, 0xb2, 0x9d, 0xcc, 0xec, 0x73, 0xcd, 0x18, 0x75, 0x0f, 0x99, 0x38, 0x12, 0x40, 0x8a,\n]);\n\nconst enum LicenseBlockType {\n Intermediate = 0,\n Server = 2,\n Ts5Server = 8,\n Ephemeral = 32,\n}\n\ninterface LicenseBlock {\n readonly key: Uint8Array; // 32-byte Ed25519 point\n readonly hash: Uint8Array; // SHA-512 truncated to 32 bytes\n properties: Uint8Array[];\n issuer: string;\n notValidBefore: Date;\n notValidAfter: Date;\n blockType: LicenseBlockType;\n serverType: number;\n}\n\nexport class LicenseChain {\n readonly blocks: LicenseBlock[];\n\n constructor(blocks: LicenseBlock[]) {\n this.blocks = blocks;\n }\n\n /**\n * Derive the session key by chaining Ed25519 point arithmetic starting from\n * the root key through each license block.\n */\n deriveKey(): Uint8Array<ArrayBuffer> {\n let round: Uint8Array<ArrayBuffer> = Uint8Array.from(LICENSE_ROOT_KEY);\n for (const block of this.blocks) {\n round = deriveKeyFromBlock(block, round);\n }\n return round;\n }\n}\n\nexport function parseLicenses(data: Uint8Array): LicenseChain {\n if (data.length < 1) throw new Error(\"license too short\");\n if (data[0] !== 1) throw new Error(\"unsupported license version\");\n\n let remaining = data.slice(1);\n const blocks: LicenseBlock[] = [];\n\n while (remaining.length > 0) {\n const { block, consumed } = parseLicenseBlock(remaining);\n blocks.push(block);\n remaining = remaining.slice(consumed);\n }\n\n return new LicenseChain(blocks);\n}\n\nfunction parseLicenseBlock(data: Uint8Array): { block: LicenseBlock; consumed: number } {\n const MIN_BLOCK_LEN = 42;\n if (data.length < MIN_BLOCK_LEN) throw new Error(\"license too short\");\n if (data[0] !== 0) throw new Error(`wrong key kind in license: ${data[0]}`);\n\n const blockType = data[33] as LicenseBlockType;\n\n // Timestamps are seconds since Unix epoch offset by 0x50e22700\n const UNIX_OFFSET = 0x50e22700;\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const notValidBefore = new Date((view.getUint32(34, false) + UNIX_OFFSET) * 1000);\n const notValidAfter = new Date((view.getUint32(38, false) + UNIX_OFFSET) * 1000);\n\n if (notValidAfter < notValidBefore) {\n throw new Error(\"license times are invalid\");\n }\n\n const key = Uint8Array.from(data.slice(1, 33));\n\n const { payload, payloadRead } = parseBlockPayload(blockType, data, MIN_BLOCK_LEN);\n\n const allLen = MIN_BLOCK_LEN + payloadRead;\n const hashInput = data.slice(1, allLen);\n const hashFull = hash512(Uint8Array.from(hashInput));\n const hash = Uint8Array.from(hashFull.slice(0, 32));\n\n return {\n block: {\n key,\n hash,\n properties: payload.properties,\n issuer: payload.issuer,\n notValidBefore,\n notValidAfter,\n blockType,\n serverType: payload.serverType,\n },\n consumed: allLen,\n };\n}\n\ninterface BlockPayload {\n issuer: string;\n serverType: number;\n properties: Uint8Array[];\n read: number;\n}\n\nfunction parseBlockPayload(\n blockType: LicenseBlockType,\n data: Uint8Array,\n minBlockLen: number,\n): { payload: BlockPayload; payloadRead: number } {\n switch (blockType) {\n case LicenseBlockType.Intermediate: {\n const { str, read } = readNullString(data.slice(46));\n return {\n payload: { issuer: str, serverType: 0, properties: [], read: 5 + read },\n payloadRead: 5 + read,\n };\n }\n case LicenseBlockType.Server: {\n const { str, read } = readNullString(data.slice(47));\n return {\n payload: { issuer: str, serverType: data[42] ?? 0, properties: [], read: 6 + read },\n payloadRead: 6 + read,\n };\n }\n case LicenseBlockType.Ts5Server: {\n const propCount = data[43] !== undefined ? data[43] : 0;\n let pos = 44;\n const properties: Uint8Array[] = [];\n for (let i = 0; i < propCount; i++) {\n if (pos >= data.length) throw new Error(\"license too short\");\n const propLen = data[pos++]!;\n if (pos + propLen > data.length) throw new Error(\"license too short\");\n properties.push(Uint8Array.from(data.slice(pos, pos + propLen)));\n pos += propLen;\n }\n return {\n payload: { issuer: \"\", serverType: data[42] ?? 0, properties, read: pos - minBlockLen },\n payloadRead: pos - minBlockLen,\n };\n }\n case LicenseBlockType.Ephemeral:\n return { payload: { issuer: \"\", serverType: 0, properties: [], read: 0 }, payloadRead: 0 };\n default:\n throw new Error(`invalid license block type: ${blockType}`);\n }\n}\n\n/**\n * Scan for a null-terminated string and return its content and the index\n * of the null byte (NOT including it in the count, matching Go behaviour).\n * The parent formulas (`5 + read`, `6 + read`) already add 1 for the null.\n */\nfunction readNullString(data: Uint8Array): { str: string; read: number } {\n for (let i = 0; i < data.length; i++) {\n if (data[i] === 0) {\n return { str: new TextDecoder().decode(data.slice(0, i)), read: i };\n }\n }\n throw new Error(\"non-null-terminated issuer string\");\n}\n\n/**\n * Derive the next key given a parent key and a license block.\n * Mirrors Go's licenseBlock.deriveKey.\n */\nfunction deriveKeyFromBlock(block: LicenseBlock, parent: Uint8Array): Uint8Array<ArrayBuffer> {\n const scalarBytes = Uint8Array.from(block.hash);\n clampScalar(scalarBytes);\n\n // Reduce mod curve order — matches Go's scalar.NewFromBits behaviour\n const scalar = bytesToBigIntLE(scalarBytes) % ed25519.Point.CURVE().n;\n\n const pub = ed25519.Point.fromBytes(block.key);\n const negPub = pub.negate();\n\n const par = ed25519.Point.fromBytes(parent);\n const negPar = par.negate();\n\n const res = negPub.multiply(scalar).add(negPar);\n const raw = res.toBytes();\n const final = new Uint8Array(raw.length) as Uint8Array<ArrayBuffer>;\n final.set(raw);\n final[31] = (final[31] !== undefined ? final[31] : 0) ^ 0x80;\n\n return final;\n}\n\nfunction bytesToBigIntLE(bytes: Uint8Array): bigint {\n let result = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n result = (result << 8n) | BigInt(bytes[i]!);\n }\n return result;\n}\n","import type { Crypt } from \"../crypto/crypt.js\";\nimport { importPublicKey } from \"../crypto/identity.js\";\nimport { verifySign, getSharedSecret2 } from \"../crypto/primitives.js\";\nimport { parseLicenses } from \"./license.js\";\n\n/**\n * CryptoInit2 performs the second stage of crypto initialization (Ed25519 ECDH).\n * Mirrors Go's handshake.CryptoInit2.\n */\nexport function cryptoInit2(\n crypt: Crypt,\n license: string,\n omega: string,\n proof: string,\n beta: string,\n privateKey: Uint8Array,\n): void {\n if (crypt.alphaTmp.length === 0) {\n throw new Error(\"alpha is not initialized\");\n }\n\n const licenseBytes = Buffer.from(license, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n const proofBytes = Buffer.from(proof, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n if (!verifySign(serverPubKey, licenseBytes, proofBytes)) {\n throw new Error(\"init proof is not valid\");\n }\n\n const licenses = parseLicenses(licenseBytes);\n const key = licenses.deriveKey();\n\n const sharedSecret = getSharedSecret2(key, privateKey);\n\n crypt.setSharedSecret(crypt.alphaTmp, betaBytes, sharedSecret);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports the key/nonce derivation and encrypt/decrypt from Crypt.
|
|
3
|
+
* This file exists to mirror the Go crypt_ops.go structure.
|
|
4
|
+
*/
|
|
5
|
+
export type { KeyNonce } from "./crypt.js";
|
|
6
|
+
export { Crypt } from "./crypt.js";
|
|
7
|
+
//# sourceMappingURL=crypt-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypt-ops.d.ts","sourceRoot":"","sources":["../../src/crypto/crypt-ops.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Identity } from "./identity.js";
|
|
2
|
+
export interface KeyNonce {
|
|
3
|
+
key: Uint8Array;
|
|
4
|
+
nonce: Uint8Array;
|
|
5
|
+
gen: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class Crypt {
|
|
8
|
+
#private;
|
|
9
|
+
readonly identity: Identity;
|
|
10
|
+
ivStruct: Uint8Array;
|
|
11
|
+
fakeSignature: Uint8Array;
|
|
12
|
+
alphaTmp: Uint8Array;
|
|
13
|
+
cryptoInitComplete: boolean;
|
|
14
|
+
constructor(identity: Identity);
|
|
15
|
+
solveRsaChallenge(data: Uint8Array, offset: number, level: number): Uint8Array;
|
|
16
|
+
initCrypto(alpha: string, beta: string, omega: string): void;
|
|
17
|
+
setSharedSecret(alpha: Uint8Array, beta: Uint8Array, sharedKey: Uint8Array): void;
|
|
18
|
+
getKeyNonce(fromServer: boolean, packetID: number, generationID: number, packetType: number, dummy: boolean): [key: Uint8Array, nonce: Uint8Array];
|
|
19
|
+
encrypt(packetType: number, packetID: number, generationID: number, header: Uint8Array, plaintext: Uint8Array, dummy: boolean, unencrypted: boolean): [ciphertext: Uint8Array, mac: Uint8Array];
|
|
20
|
+
decrypt(packetType: number, packetID: number, generationID: number, header: Uint8Array, ciphertext: Uint8Array, tag: Uint8Array, dummy: boolean, unencrypted: boolean): Uint8Array;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=crypt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypt.d.ts","sourceRoot":"","sources":["../../src/crypto/crypt.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAW9C,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAMD,qBAAa,KAAK;;IAChB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,QAAQ,EAAE,UAAU,CAAqB;IACzC,aAAa,EAAE,UAAU,CAAuC;IAChE,QAAQ,EAAE,UAAU,CAAqB;IACzC,kBAAkB,UAAS;gBAIf,QAAQ,EAAE,QAAQ;IAI9B,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU;IAkB9E,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAW5D,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI;IAmBjF,WAAW,CACT,UAAU,EAAE,OAAO,EACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,GACb,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC;IA+BvC,OAAO,CACL,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,OAAO,GACnB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC;IAa5C,OAAO,CACL,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,OAAO,GACnB,UAAU;CAwCd"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).
|
|
3
|
+
* Uses AES-CMAC for authentication and AES-CTR for encryption.
|
|
4
|
+
*/
|
|
5
|
+
export declare class EAX {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(key: Uint8Array);
|
|
8
|
+
encrypt(nonce: Uint8Array, header: Uint8Array, plaintext: Uint8Array): [ciphertext: Uint8Array, tag: Uint8Array];
|
|
9
|
+
decrypt(nonce: Uint8Array, header: Uint8Array, ciphertext: Uint8Array, tag: Uint8Array): Uint8Array;
|
|
10
|
+
}
|
|
11
|
+
export declare function aesCmac(key: Uint8Array, message: Uint8Array): Uint8Array;
|
|
12
|
+
//# sourceMappingURL=eax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eax.d.ts","sourceRoot":"","sources":["../../src/crypto/eax.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qBAAa,GAAG;;gBAGF,GAAG,EAAE,UAAU;IAK3B,OAAO,CACL,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,GACpB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC;IAgB5C,OAAO,CACL,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,GACd,UAAU;CA6Bd;AAoDD,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,CA2BxE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eax.test.d.ts","sourceRoot":"","sources":["../../src/crypto/eax.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type KeyObject } from "node:crypto";
|
|
2
|
+
export declare class Identity {
|
|
3
|
+
readonly privateKey: KeyObject;
|
|
4
|
+
offset: bigint;
|
|
5
|
+
constructor(privateKey: KeyObject, offset: bigint);
|
|
6
|
+
publicKeyBase64(): string;
|
|
7
|
+
toString(): string;
|
|
8
|
+
securityLevel(): number;
|
|
9
|
+
upgradeToLevel(targetLevel: number, signal?: AbortSignal): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare function identityFromString(s: string): Identity;
|
|
12
|
+
export declare function generateIdentity(targetLevel: number): Identity;
|
|
13
|
+
export declare function getUidFromPublicKey(publicKey: string): string;
|
|
14
|
+
export declare function hash512(data: Uint8Array): Uint8Array;
|
|
15
|
+
/** Import a TS3 public key (canonical or legacy ASN.1 DER) and return the
|
|
16
|
+
* uncompressed 65-byte point [0x04 || x || y]. */
|
|
17
|
+
export declare function importPublicKey(data: Uint8Array): KeyObject;
|
|
18
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/crypto/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,aAAa,CAAC;AAOrB,qBAAa,QAAQ;IACnB,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;gBAEH,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;IAKjD,eAAe,IAAI,MAAM;IAoBzB,QAAQ,IAAI,MAAM;IAUlB,aAAa,IAAI,MAAM;IAOjB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAe/E;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CA+BtD;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAc9D;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEpD;AA8BD;mDACmD;AACnD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAS3D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../../src/crypto/identity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../primitives-BxtDMP7x.cjs`),t=require(`../crypto-C3gBJkh2.cjs`);exports.Crypt=t.t,exports.EAX=t.n,exports.Identity=e.s,exports.aesCmac=t.r,exports.clampScalar=e.t,exports.generateIdentity=e.c,exports.generateTemporaryKey=e.n,exports.getSharedSecret2=e.r,exports.getUidFromPublicKey=e.l,exports.hash512=e.u,exports.identityFromString=e.d,exports.importPublicKey=e.f,exports.sign=e.i,exports.verifySign=e.a;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Identity, identityFromString, generateIdentity, getUidFromPublicKey, hash512, importPublicKey, } from "./identity.js";
|
|
2
|
+
export { Crypt } from "./crypt.js";
|
|
3
|
+
export type { KeyNonce } from "./crypt.js";
|
|
4
|
+
export { EAX, aesCmac } from "./eax.js";
|
|
5
|
+
export { generateTemporaryKey, sign, verifySign, getSharedSecret2, clampScalar, } from "./primitives.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,IAAI,EACJ,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as e, c as t, d as n, f as r, i, l as a, n as o, r as s, s as c, t as l, u } from "../primitives-CmIK1O7L.js";
|
|
2
|
+
import { n as d, r as f, t as p } from "../crypto-IGJlkTAl.js";
|
|
3
|
+
export { p as Crypt, d as EAX, c as Identity, f as aesCmac, l as clampScalar, t as generateIdentity, o as generateTemporaryKey, s as getSharedSecret2, a as getUidFromPublicKey, u as hash512, n as identityFromString, r as importPublicKey, i as sign, e as verifySign };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type KeyObject } from "node:crypto";
|
|
2
|
+
/** Clamp a Curve25519 scalar in-place (required before scalar multiplication). */
|
|
3
|
+
export declare function clampScalar(key: Uint8Array): void;
|
|
4
|
+
/**
|
|
5
|
+
* Generate an ephemeral Ed25519 key pair for the TS3 handshake.
|
|
6
|
+
* Returns [publicKey (32 bytes, RFC-8032 encoded), privateKey (32 bytes)].
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateTemporaryKey(): [Uint8Array, Uint8Array];
|
|
9
|
+
/**
|
|
10
|
+
* Sign data with a P-256 private key (SHA-256 hash, ASN.1 DER encoded).
|
|
11
|
+
*/
|
|
12
|
+
export declare function sign(privateKey: KeyObject, data: Uint8Array): Uint8Array;
|
|
13
|
+
/**
|
|
14
|
+
* Verify a P-256 ECDSA signature (SHA-256 hash, ASN.1 DER encoded).
|
|
15
|
+
*/
|
|
16
|
+
export declare function verifySign(publicKey: KeyObject, data: Uint8Array, sig: Uint8Array): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* TS3-specific shared secret derivation using Ed25519 point arithmetic.
|
|
19
|
+
* Mirrors Go's `GetSharedSecret2`:
|
|
20
|
+
* 1. Negate the public point
|
|
21
|
+
* 2. Scalar-multiply by clamped private key (top bit cleared)
|
|
22
|
+
* 3. Flip sign bit of result
|
|
23
|
+
* 4. SHA-512 the resulting point bytes
|
|
24
|
+
*/
|
|
25
|
+
export declare function getSharedSecret2(publicKeyBytes: Uint8Array, privateKeyBytes: Uint8Array): Uint8Array;
|
|
26
|
+
/** Interpret a little-endian byte array as an unsigned BigInt. */
|
|
27
|
+
export declare function bytesToBigIntLE(bytes: Uint8Array): bigint;
|
|
28
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/crypto/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAUhG,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAKjD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAU/D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAIxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAQ3F;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,UAAU,EAC1B,eAAe,EAAE,UAAU,GAC1B,UAAU,CAyBZ;AAID,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./primitives-BxtDMP7x.cjs`);let t=require(`node:crypto`);var n=8,r=16,i=class{#e;constructor(e){if(e.length!==16)throw Error(`EAX requires a 16-byte key`);this.#e=e}encrypt(e,t,r){let i=this.#t(0,e),o=this.#t(1,t),s=a(this.#e,i,r),c=this.#t(2,s),l=new Uint8Array(n);for(let e=0;e<n;e++)l[e]=i[e]^o[e]^c[e];return[s,l]}decrypt(r,i,o,s){let c=this.#t(0,r),l=this.#t(1,i),u=this.#t(2,o),d=new Uint8Array(n);for(let e=0;e<n;e++)d[e]=c[e]^l[e]^u[e];if(!(0,t.timingSafeEqual)(Buffer.from(d),Buffer.from(s.slice(0,n))))throw new e.g;return a(this.#e,c,o)}#t(e,t){let n=new Uint8Array(r+t.length);return n[r-1]=e,n.set(t,r),d(this.#e,n)}};function a(e,n,r){let i=(0,t.createCipheriv)(`aes-128-ctr`,Buffer.from(e),Buffer.from(n));return Buffer.concat([i.update(Buffer.from(r)),i.final()])}function o(e,n){let r=(0,t.createCipheriv)(`aes-128-ecb`,Buffer.from(e),null);return r.setAutoPadding(!1),Buffer.concat([r.update(Buffer.from(n)),r.final()])}function s(e,t){let n=new Uint8Array(r);for(let i=0;i<r;i++)n[i]=e[i]^t[i];return n}function c(e){let t=new Uint8Array(r),n=0;for(let i=r-1;i>=0;i--){let r=(e[i]<<1|n)&255;n=e[i]>>7,t[i]=r}return t}var l=new Uint8Array(r);l[r-1]=135;function u(e){let t=o(e,new Uint8Array(r)),n=c(t);t[0]&128&&(n=s(n,l));let i=c(n);return n[0]&128&&(i=s(i,l)),[n,i]}function d(e,t){let[n,i]=u(e),a=Math.max(1,Math.ceil(t.length/r)),c=t.length>0&&t.length%r===0,l=new Uint8Array(r);for(let n=0;n<a-1;n++){let i=t.slice(n*r,(n+1)*r);l=Uint8Array.from(o(e,s(l,i)))}let d=new Uint8Array(r),f=(a-1)*r,p=t.slice(f);d.set(p);let m;return c?m=s(d,n):(p.length<r&&(d[p.length]=128),m=s(d,i)),Uint8Array.from(o(e,s(l,m)))}var f=8,p=10,m=8,h=15,g=Buffer.from(`TS3INIT1`),_=Buffer.from(`c:\\windows\\syste`),v=Buffer.from(`m\\firewall32.cpl`),y=class{identity;ivStruct=new Uint8Array;fakeSignature=new Uint8Array(f);alphaTmp=new Uint8Array;cryptoInitComplete=!1;#e=new Map;constructor(e){this.identity=e}solveRsaChallenge(e,t,n){if(n<0||n>1e6)throw Error(`RSA challenge level out of range`);let r=e.slice(t,t+64),i=e.slice(t+64,t+128),a=x(r),o=x(i);for(let e=0;e<n;e++)a=a*a%o;return S(a,64)}initCrypto(t,n,r){let i=Buffer.from(t,`base64`),a=Buffer.from(n,`base64`),o=e.f(Buffer.from(r,`base64`)),s=this.#t(o);this.setSharedSecret(i,a,s)}setSharedSecret(e,n,r){this.ivStruct=new Uint8Array(p+n.length);for(let t=0;t<p;t++){let n=r[t],i=e[t];this.ivStruct[t]=((n===void 0?0:n)^(i===void 0?0:i))&255}for(let e=0;e<n.length;e++){let t=r[p+e],i=n[e];this.ivStruct[p+e]=((t===void 0?0:t)^(i===void 0?0:i))&255}let i=(0,t.createHash)(`sha1`).update(this.ivStruct).digest();this.fakeSignature=new Uint8Array(i.buffer,i.byteOffset,f),this.cryptoInitComplete=!0}getKeyNonce(e,n,r,i,a){if(a)return[Uint8Array.from(_),Uint8Array.from(v)];let o=b(e,i,r),s=this.#e.get(o);if(s===void 0){let n=new Uint8Array(6+this.ivStruct.length);n[0]=e?48:49,n[1]=i&h,new DataView(n.buffer).setUint32(2,r,!1),n.set(this.ivStruct,6);let a=(0,t.createHash)(`sha256`).update(n).digest();s={key:Uint8Array.from(a.slice(0,16)),nonce:Uint8Array.from(a.slice(16,32)),gen:r},this.#e.set(o,s)}let c=Uint8Array.from(s.key);return c[0]=(c[0]===void 0?0:c[0])^n>>8&255,c[1]=(c[1]===void 0?0:c[1])^n&255,[c,s.nonce]}encrypt(e,t,n,r,a,o,s){if(e===m)return[a,g];if(s)return[a,this.fakeSignature];let[c,l]=this.getKeyNonce(!1,t,n,e,o);return new i(c).encrypt(l,r,a)}decrypt(t,n,r,a,o,s,c,l){if(t===m)return o;if(l){let t=s.slice(0,f);if(!Buffer.from(t).equals(Buffer.from(this.fakeSignature)))throw new e._;return o}let[u,d]=this.getKeyNonce(!0,n,r,t,c);return new i(u).decrypt(d,a,o,s)}#t(e){let n=this.identity.privateKey.export({format:`jwk`}),r=e.export({format:`jwk`}),i=(0,t.createECDH)(`prime256v1`),a=Buffer.from(n.d,`base64url`);i.setPrivateKey(a);let o=C(r.x,32),s=C(r.y,32),c=Buffer.alloc(65);c[0]=4,o.copy(c,1),s.copy(c,33);let l=i.computeSecret(c);return(0,t.createHash)(`sha1`).update(l).digest()}};function b(e,t,n){let r=0n;return e&&(r|=1n<<40n),r|=BigInt(t&h)<<32n,r|=BigInt(n),r}function x(e){let t=0n;for(let n of e)t=t<<8n|BigInt(n);return t}function S(e,t){let n=new Uint8Array(t),r=e;for(let e=t-1;e>=0;e--)n[e]=Number(r&255n),r>>=8n;return n}function C(e,t){let n=Buffer.from(e,`base64url`);if(n.length===t)return n;let r=Buffer.alloc(t);return n.copy(r,t-n.length),r}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return y}});
|
|
2
|
+
//# sourceMappingURL=crypto-C3gBJkh2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-C3gBJkh2.cjs","names":["#key","#cmac","#cachedKeys","#getSharedSecret"],"sources":["../src/crypto/eax.ts","../src/crypto/crypt.ts"],"sourcesContent":["import { createCipheriv, timingSafeEqual } from \"node:crypto\";\nimport { EAXTagMismatchError } from \"../errors.js\";\n\nconst EAX_TAG_SIZE = 8;\nconst EAX_BLOCK_SIZE = 16;\n\n/**\n * AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).\n * Uses AES-CMAC for authentication and AES-CTR for encryption.\n */\nexport class EAX {\n readonly #key: Uint8Array;\n\n constructor(key: Uint8Array) {\n if (key.length !== 16) throw new Error(\"EAX requires a 16-byte key\");\n this.#key = key;\n }\n\n encrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n plaintext: Uint8Array,\n ): [ciphertext: Uint8Array, tag: Uint8Array] {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n\n const ciphertext = aesCtr(this.#key, nStar, plaintext);\n\n const cStar = this.#cmac(2, ciphertext);\n\n const tag = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n tag[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n return [ciphertext, tag];\n }\n\n decrypt(\n nonce: Uint8Array,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n ): Uint8Array {\n const nStar = this.#cmac(0, nonce);\n const hStar = this.#cmac(1, header);\n const cStar = this.#cmac(2, ciphertext);\n\n const expected = new Uint8Array(EAX_TAG_SIZE);\n for (let i = 0; i < EAX_TAG_SIZE; i++) {\n expected[i] = nStar[i]! ^ hStar[i]! ^ cStar[i]!;\n }\n\n if (!timingSafeEqual(Buffer.from(expected), Buffer.from(tag.slice(0, EAX_TAG_SIZE)))) {\n throw new EAXTagMismatchError();\n }\n\n return aesCtr(this.#key, nStar, ciphertext);\n }\n\n /**\n * AES-CMAC per RFC 4493:\n * input = [0…0 tag] ++ data (one block prefix)\n */\n #cmac(tagByte: number, data: Uint8Array): Uint8Array {\n const input = new Uint8Array(EAX_BLOCK_SIZE + data.length);\n // first block: zeros then tag byte at the last position\n input[EAX_BLOCK_SIZE - 1] = tagByte;\n input.set(data, EAX_BLOCK_SIZE);\n\n return aesCmac(this.#key, input);\n }\n}\n\n// ---- AES-CTR ----------------------------------------------------------------\n\nfunction aesCtr(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Uint8Array {\n const cipher = createCipheriv(\"aes-128-ctr\", Buffer.from(key), Buffer.from(iv));\n return Buffer.concat([cipher.update(Buffer.from(data)), cipher.final()]);\n}\n\n// ---- AES-CMAC (RFC 4493) ----------------------------------------------------\n\nfunction aesEcb(key: Uint8Array, block: Uint8Array): Uint8Array {\n // Node.js does not expose ECB directly; simulate via CTR with zero IV and\n // a zero-input (CTR of 0-block XOR with input = ECB)\n const cipher = createCipheriv(\"aes-128-ecb\", Buffer.from(key), null);\n cipher.setAutoPadding(false);\n return Buffer.concat([cipher.update(Buffer.from(block)), cipher.final()]);\n}\n\nfunction xorBlock(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n for (let i = 0; i < EAX_BLOCK_SIZE; i++) out[i] = a[i]! ^ b[i]!;\n return out;\n}\n\nfunction shiftLeft1(b: Uint8Array): Uint8Array {\n const out = new Uint8Array(EAX_BLOCK_SIZE);\n let carry = 0;\n for (let i = EAX_BLOCK_SIZE - 1; i >= 0; i--) {\n const shifted = ((b[i]! << 1) | carry) & 0xff;\n carry = b[i]! >> 7;\n out[i] = shifted;\n }\n return out;\n}\n\nconst RB = new Uint8Array(EAX_BLOCK_SIZE);\nRB[EAX_BLOCK_SIZE - 1] = 0x87;\n\nfunction generateSubkeys(key: Uint8Array): [Uint8Array, Uint8Array] {\n const zero = new Uint8Array(EAX_BLOCK_SIZE);\n const L = aesEcb(key, zero);\n\n let K1 = shiftLeft1(L);\n if ((L[0]! & 0x80) !== 0) K1 = xorBlock(K1, RB);\n\n let K2 = shiftLeft1(K1);\n if ((K1[0]! & 0x80) !== 0) K2 = xorBlock(K2, RB);\n\n return [K1, K2];\n}\n\nexport function aesCmac(key: Uint8Array, message: Uint8Array): Uint8Array {\n const [K1, K2] = generateSubkeys(key);\n\n const n = Math.max(1, Math.ceil(message.length / EAX_BLOCK_SIZE));\n const lastBlockComplete = message.length > 0 && message.length % EAX_BLOCK_SIZE === 0;\n\n let X: Uint8Array = new Uint8Array(EAX_BLOCK_SIZE);\n\n for (let i = 0; i < n - 1; i++) {\n const block = message.slice(i * EAX_BLOCK_SIZE, (i + 1) * EAX_BLOCK_SIZE);\n X = Uint8Array.from(aesEcb(key, xorBlock(X, block)));\n }\n\n const lastBlock = new Uint8Array(EAX_BLOCK_SIZE);\n const lastStart = (n - 1) * EAX_BLOCK_SIZE;\n const lastSlice = message.slice(lastStart);\n lastBlock.set(lastSlice);\n\n let Mn: Uint8Array;\n if (lastBlockComplete) {\n Mn = xorBlock(lastBlock, K1);\n } else {\n if (lastSlice.length < EAX_BLOCK_SIZE) lastBlock[lastSlice.length] = 0x80;\n Mn = xorBlock(lastBlock, K2);\n }\n\n return Uint8Array.from(aesEcb(key, xorBlock(X, Mn)));\n}\n","import { createHash, createECDH } from \"node:crypto\";\nimport { FakeSignatureMismatchError } from \"../errors.js\";\nimport type { Identity } from \"./identity.js\";\nimport { importPublicKey } from \"./identity.js\";\nimport { EAX } from \"./eax.js\";\n\nconst FAKE_SIGNATURE_SIZE = 8;\nconst IV_ALPHA_SIZE = 10;\nconst INIT1_PACKET_TYPE = 8;\nconst PACKET_TYPE_MASK = 0x0f;\n\nconst INIT1_MAC = Buffer.from(\"TS3INIT1\");\n\nexport interface KeyNonce {\n key: Uint8Array;\n nonce: Uint8Array;\n gen: number;\n}\n\n/** Precomputed dummy key/nonce matching the TS3 client pre-crypto placeholder. */\nconst DUMMY_KEY = Buffer.from(\"c:\\\\windows\\\\syste\");\nconst DUMMY_NONCE = Buffer.from(\"m\\\\firewall32.cpl\");\n\nexport class Crypt {\n readonly identity: Identity;\n\n ivStruct: Uint8Array = new Uint8Array(0);\n fakeSignature: Uint8Array = new Uint8Array(FAKE_SIGNATURE_SIZE);\n alphaTmp: Uint8Array = new Uint8Array(0);\n cryptoInitComplete = false;\n\n readonly #cachedKeys = new Map<bigint, KeyNonce>();\n\n constructor(identity: Identity) {\n this.identity = identity;\n }\n\n solveRsaChallenge(data: Uint8Array, offset: number, level: number): Uint8Array {\n if (level < 0 || level > 1_000_000) {\n throw new Error(\"RSA challenge level out of range\");\n }\n\n const xBytes = data.slice(offset, offset + 64);\n const nBytes = data.slice(offset + 64, offset + 128);\n\n let y = bytesToBigInt(xBytes);\n const n = bytesToBigInt(nBytes);\n\n for (let i = 0; i < level; i++) {\n y = (y * y) % n;\n }\n\n return bigIntToBytes(y, 64);\n }\n\n initCrypto(alpha: string, beta: string, omega: string): void {\n const alphaBytes = Buffer.from(alpha, \"base64\");\n const betaBytes = Buffer.from(beta, \"base64\");\n const omegaBytes = Buffer.from(omega, \"base64\");\n\n const serverPubKey = importPublicKey(omegaBytes);\n const sharedSecret = this.#getSharedSecret(serverPubKey);\n\n this.setSharedSecret(alphaBytes, betaBytes, sharedSecret);\n }\n\n setSharedSecret(alpha: Uint8Array, beta: Uint8Array, sharedKey: Uint8Array): void {\n this.ivStruct = new Uint8Array(IV_ALPHA_SIZE + beta.length);\n for (let i = 0; i < IV_ALPHA_SIZE; i++) {\n const a = sharedKey[i];\n const b = alpha[i];\n this.ivStruct[i] = ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n for (let i = 0; i < beta.length; i++) {\n const a = sharedKey[IV_ALPHA_SIZE + i];\n const b = beta[i];\n this.ivStruct[IV_ALPHA_SIZE + i] =\n ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;\n }\n\n const digest = createHash(\"sha1\").update(this.ivStruct).digest();\n this.fakeSignature = new Uint8Array(digest.buffer, digest.byteOffset, FAKE_SIGNATURE_SIZE);\n this.cryptoInitComplete = true;\n }\n\n getKeyNonce(\n fromServer: boolean,\n packetID: number,\n generationID: number,\n packetType: number,\n dummy: boolean,\n ): [key: Uint8Array, nonce: Uint8Array] {\n if (dummy) {\n return [Uint8Array.from(DUMMY_KEY), Uint8Array.from(DUMMY_NONCE)];\n }\n\n const cacheKey = makeCacheKey(fromServer, packetType, generationID);\n let kn = this.#cachedKeys.get(cacheKey);\n\n if (kn === undefined) {\n const tmpToHash = new Uint8Array(6 + this.ivStruct.length);\n tmpToHash[0] = fromServer ? 0x30 : 0x31;\n tmpToHash[1] = packetType & PACKET_TYPE_MASK;\n new DataView(tmpToHash.buffer).setUint32(2, generationID, false);\n tmpToHash.set(this.ivStruct, 6);\n\n const hash = createHash(\"sha256\").update(tmpToHash).digest();\n kn = {\n key: Uint8Array.from(hash.slice(0, 16)),\n nonce: Uint8Array.from(hash.slice(16, 32)),\n gen: generationID,\n };\n this.#cachedKeys.set(cacheKey, kn);\n }\n\n const key = Uint8Array.from(kn.key);\n key[0] = (key[0] !== undefined ? key[0] : 0) ^ ((packetID >> 8) & 0xff);\n key[1] = (key[1] !== undefined ? key[1] : 0) ^ (packetID & 0xff);\n\n return [key, kn.nonce];\n }\n\n encrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n plaintext: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): [ciphertext: Uint8Array, mac: Uint8Array] {\n if (packetType === INIT1_PACKET_TYPE) {\n return [plaintext, INIT1_MAC];\n }\n if (unencrypted) {\n return [plaintext, this.fakeSignature];\n }\n\n const [key, nonce] = this.getKeyNonce(false, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.encrypt(nonce, header, plaintext);\n }\n\n decrypt(\n packetType: number,\n packetID: number,\n generationID: number,\n header: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n dummy: boolean,\n unencrypted: boolean,\n ): Uint8Array {\n if (packetType === INIT1_PACKET_TYPE) {\n return ciphertext;\n }\n if (unencrypted) {\n const fsSub = tag.slice(0, FAKE_SIGNATURE_SIZE);\n if (!Buffer.from(fsSub).equals(Buffer.from(this.fakeSignature))) {\n throw new FakeSignatureMismatchError();\n }\n return ciphertext;\n }\n\n const [key, nonce] = this.getKeyNonce(true, packetID, generationID, packetType, dummy);\n const eax = new EAX(key);\n return eax.decrypt(nonce, header, ciphertext, tag);\n }\n\n #getSharedSecret(serverPubKey: import(\"node:crypto\").KeyObject): Uint8Array {\n const privJwk = this.identity.privateKey.export({ format: \"jwk\" }) as {\n d: string;\n };\n const pubJwk = serverPubKey.export({ format: \"jwk\" }) as {\n x: string;\n y: string;\n };\n\n const ecdh = createECDH(\"prime256v1\");\n const dBytes = Buffer.from(privJwk.d, \"base64url\");\n ecdh.setPrivateKey(dBytes);\n\n const xBytes = base64UrlToBytes(pubJwk.x, 32);\n const yBytes = base64UrlToBytes(pubJwk.y, 32);\n const uncompressed = Buffer.alloc(65);\n uncompressed[0] = 0x04;\n xBytes.copy(uncompressed, 1);\n yBytes.copy(uncompressed, 33);\n\n const rawSecret = ecdh.computeSecret(uncompressed);\n return createHash(\"sha1\").update(rawSecret).digest();\n }\n}\n\n// ---- Helpers ----------------------------------------------------------------\n\nfunction makeCacheKey(fromServer: boolean, packetType: number, generationID: number): bigint {\n let key = 0n;\n if (fromServer) key |= 1n << 40n;\n key |= BigInt(packetType & PACKET_TYPE_MASK) << 32n;\n key |= BigInt(generationID);\n return key;\n}\n\nfunction bytesToBigInt(bytes: Uint8Array): bigint {\n let result = 0n;\n for (const b of bytes) result = (result << 8n) | BigInt(b);\n return result;\n}\n\nfunction bigIntToBytes(value: bigint, size: number): Uint8Array {\n const result = new Uint8Array(size);\n let v = value;\n for (let i = size - 1; i >= 0; i--) {\n result[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return result;\n}\n\nfunction base64UrlToBytes(b64url: string, size: number): Buffer {\n const buf = Buffer.from(b64url, \"base64url\");\n if (buf.length === size) return buf;\n const padded = Buffer.alloc(size);\n buf.copy(padded, size - buf.length);\n return padded;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { _ as e, f as t, g as n } from "./primitives-CmIK1O7L.js";
|
|
2
|
+
import { createCipheriv as r, createECDH as i, createHash as a, timingSafeEqual as o } from "node:crypto";
|
|
3
|
+
//#region src/crypto/eax.ts
|
|
4
|
+
var s = 8, c = 16, l = class {
|
|
5
|
+
#e;
|
|
6
|
+
constructor(e) {
|
|
7
|
+
if (e.length !== 16) throw Error("EAX requires a 16-byte key");
|
|
8
|
+
this.#e = e;
|
|
9
|
+
}
|
|
10
|
+
encrypt(e, t, n) {
|
|
11
|
+
let r = this.#t(0, e), i = this.#t(1, t), a = u(this.#e, r, n), o = this.#t(2, a), c = new Uint8Array(s);
|
|
12
|
+
for (let e = 0; e < s; e++) c[e] = r[e] ^ i[e] ^ o[e];
|
|
13
|
+
return [a, c];
|
|
14
|
+
}
|
|
15
|
+
decrypt(e, t, r, i) {
|
|
16
|
+
let a = this.#t(0, e), c = this.#t(1, t), l = this.#t(2, r), d = new Uint8Array(s);
|
|
17
|
+
for (let e = 0; e < s; e++) d[e] = a[e] ^ c[e] ^ l[e];
|
|
18
|
+
if (!o(Buffer.from(d), Buffer.from(i.slice(0, s)))) throw new n();
|
|
19
|
+
return u(this.#e, a, r);
|
|
20
|
+
}
|
|
21
|
+
#t(e, t) {
|
|
22
|
+
let n = new Uint8Array(c + t.length);
|
|
23
|
+
return n[c - 1] = e, n.set(t, c), g(this.#e, n);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function u(e, t, n) {
|
|
27
|
+
let i = r("aes-128-ctr", Buffer.from(e), Buffer.from(t));
|
|
28
|
+
return Buffer.concat([i.update(Buffer.from(n)), i.final()]);
|
|
29
|
+
}
|
|
30
|
+
function d(e, t) {
|
|
31
|
+
let n = r("aes-128-ecb", Buffer.from(e), null);
|
|
32
|
+
return n.setAutoPadding(!1), Buffer.concat([n.update(Buffer.from(t)), n.final()]);
|
|
33
|
+
}
|
|
34
|
+
function f(e, t) {
|
|
35
|
+
let n = new Uint8Array(c);
|
|
36
|
+
for (let r = 0; r < c; r++) n[r] = e[r] ^ t[r];
|
|
37
|
+
return n;
|
|
38
|
+
}
|
|
39
|
+
function p(e) {
|
|
40
|
+
let t = new Uint8Array(c), n = 0;
|
|
41
|
+
for (let r = c - 1; r >= 0; r--) {
|
|
42
|
+
let i = (e[r] << 1 | n) & 255;
|
|
43
|
+
n = e[r] >> 7, t[r] = i;
|
|
44
|
+
}
|
|
45
|
+
return t;
|
|
46
|
+
}
|
|
47
|
+
var m = new Uint8Array(c);
|
|
48
|
+
m[c - 1] = 135;
|
|
49
|
+
function h(e) {
|
|
50
|
+
let t = d(e, new Uint8Array(c)), n = p(t);
|
|
51
|
+
t[0] & 128 && (n = f(n, m));
|
|
52
|
+
let r = p(n);
|
|
53
|
+
return n[0] & 128 && (r = f(r, m)), [n, r];
|
|
54
|
+
}
|
|
55
|
+
function g(e, t) {
|
|
56
|
+
let [n, r] = h(e), i = Math.max(1, Math.ceil(t.length / c)), a = t.length > 0 && t.length % c === 0, o = new Uint8Array(c);
|
|
57
|
+
for (let n = 0; n < i - 1; n++) {
|
|
58
|
+
let r = t.slice(n * c, (n + 1) * c);
|
|
59
|
+
o = Uint8Array.from(d(e, f(o, r)));
|
|
60
|
+
}
|
|
61
|
+
let s = new Uint8Array(c), l = (i - 1) * c, u = t.slice(l);
|
|
62
|
+
s.set(u);
|
|
63
|
+
let p;
|
|
64
|
+
return a ? p = f(s, n) : (u.length < c && (s[u.length] = 128), p = f(s, r)), Uint8Array.from(d(e, f(o, p)));
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/crypto/crypt.ts
|
|
68
|
+
var _ = 8, v = 10, y = 8, b = 15, x = Buffer.from("TS3INIT1"), S = Buffer.from("c:\\windows\\syste"), C = Buffer.from("m\\firewall32.cpl"), w = class {
|
|
69
|
+
identity;
|
|
70
|
+
ivStruct = new Uint8Array();
|
|
71
|
+
fakeSignature = new Uint8Array(_);
|
|
72
|
+
alphaTmp = new Uint8Array();
|
|
73
|
+
cryptoInitComplete = !1;
|
|
74
|
+
#e = /* @__PURE__ */ new Map();
|
|
75
|
+
constructor(e) {
|
|
76
|
+
this.identity = e;
|
|
77
|
+
}
|
|
78
|
+
solveRsaChallenge(e, t, n) {
|
|
79
|
+
if (n < 0 || n > 1e6) throw Error("RSA challenge level out of range");
|
|
80
|
+
let r = e.slice(t, t + 64), i = e.slice(t + 64, t + 128), a = E(r), o = E(i);
|
|
81
|
+
for (let e = 0; e < n; e++) a = a * a % o;
|
|
82
|
+
return D(a, 64);
|
|
83
|
+
}
|
|
84
|
+
initCrypto(e, n, r) {
|
|
85
|
+
let i = Buffer.from(e, "base64"), a = Buffer.from(n, "base64"), o = t(Buffer.from(r, "base64")), s = this.#t(o);
|
|
86
|
+
this.setSharedSecret(i, a, s);
|
|
87
|
+
}
|
|
88
|
+
setSharedSecret(e, t, n) {
|
|
89
|
+
this.ivStruct = new Uint8Array(v + t.length);
|
|
90
|
+
for (let t = 0; t < v; t++) {
|
|
91
|
+
let r = n[t], i = e[t];
|
|
92
|
+
this.ivStruct[t] = ((r === void 0 ? 0 : r) ^ (i === void 0 ? 0 : i)) & 255;
|
|
93
|
+
}
|
|
94
|
+
for (let e = 0; e < t.length; e++) {
|
|
95
|
+
let r = n[v + e], i = t[e];
|
|
96
|
+
this.ivStruct[v + e] = ((r === void 0 ? 0 : r) ^ (i === void 0 ? 0 : i)) & 255;
|
|
97
|
+
}
|
|
98
|
+
let r = a("sha1").update(this.ivStruct).digest();
|
|
99
|
+
this.fakeSignature = new Uint8Array(r.buffer, r.byteOffset, _), this.cryptoInitComplete = !0;
|
|
100
|
+
}
|
|
101
|
+
getKeyNonce(e, t, n, r, i) {
|
|
102
|
+
if (i) return [Uint8Array.from(S), Uint8Array.from(C)];
|
|
103
|
+
let o = T(e, r, n), s = this.#e.get(o);
|
|
104
|
+
if (s === void 0) {
|
|
105
|
+
let t = new Uint8Array(6 + this.ivStruct.length);
|
|
106
|
+
t[0] = e ? 48 : 49, t[1] = r & b, new DataView(t.buffer).setUint32(2, n, !1), t.set(this.ivStruct, 6);
|
|
107
|
+
let i = a("sha256").update(t).digest();
|
|
108
|
+
s = {
|
|
109
|
+
key: Uint8Array.from(i.slice(0, 16)),
|
|
110
|
+
nonce: Uint8Array.from(i.slice(16, 32)),
|
|
111
|
+
gen: n
|
|
112
|
+
}, this.#e.set(o, s);
|
|
113
|
+
}
|
|
114
|
+
let c = Uint8Array.from(s.key);
|
|
115
|
+
return c[0] = (c[0] === void 0 ? 0 : c[0]) ^ t >> 8 & 255, c[1] = (c[1] === void 0 ? 0 : c[1]) ^ t & 255, [c, s.nonce];
|
|
116
|
+
}
|
|
117
|
+
encrypt(e, t, n, r, i, a, o) {
|
|
118
|
+
if (e === y) return [i, x];
|
|
119
|
+
if (o) return [i, this.fakeSignature];
|
|
120
|
+
let [s, c] = this.getKeyNonce(!1, t, n, e, a);
|
|
121
|
+
return new l(s).encrypt(c, r, i);
|
|
122
|
+
}
|
|
123
|
+
decrypt(t, n, r, i, a, o, s, c) {
|
|
124
|
+
if (t === y) return a;
|
|
125
|
+
if (c) {
|
|
126
|
+
let t = o.slice(0, _);
|
|
127
|
+
if (!Buffer.from(t).equals(Buffer.from(this.fakeSignature))) throw new e();
|
|
128
|
+
return a;
|
|
129
|
+
}
|
|
130
|
+
let [u, d] = this.getKeyNonce(!0, n, r, t, s);
|
|
131
|
+
return new l(u).decrypt(d, i, a, o);
|
|
132
|
+
}
|
|
133
|
+
#t(e) {
|
|
134
|
+
let t = this.identity.privateKey.export({ format: "jwk" }), n = e.export({ format: "jwk" }), r = i("prime256v1"), o = Buffer.from(t.d, "base64url");
|
|
135
|
+
r.setPrivateKey(o);
|
|
136
|
+
let s = O(n.x, 32), c = O(n.y, 32), l = Buffer.alloc(65);
|
|
137
|
+
l[0] = 4, s.copy(l, 1), c.copy(l, 33);
|
|
138
|
+
let u = r.computeSecret(l);
|
|
139
|
+
return a("sha1").update(u).digest();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
function T(e, t, n) {
|
|
143
|
+
let r = 0n;
|
|
144
|
+
return e && (r |= 1n << 40n), r |= BigInt(t & b) << 32n, r |= BigInt(n), r;
|
|
145
|
+
}
|
|
146
|
+
function E(e) {
|
|
147
|
+
let t = 0n;
|
|
148
|
+
for (let n of e) t = t << 8n | BigInt(n);
|
|
149
|
+
return t;
|
|
150
|
+
}
|
|
151
|
+
function D(e, t) {
|
|
152
|
+
let n = new Uint8Array(t), r = e;
|
|
153
|
+
for (let e = t - 1; e >= 0; e--) n[e] = Number(r & 255n), r >>= 8n;
|
|
154
|
+
return n;
|
|
155
|
+
}
|
|
156
|
+
function O(e, t) {
|
|
157
|
+
let n = Buffer.from(e, "base64url");
|
|
158
|
+
if (n.length === t) return n;
|
|
159
|
+
let r = Buffer.alloc(t);
|
|
160
|
+
return n.copy(r, t - n.length), r;
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { l as n, g as r, w as t };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=crypto-IGJlkTAl.js.map
|