nlcurl 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.
Files changed (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/cli/args.d.ts +42 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +262 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/index.d.ts +8 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +114 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/output.d.ts +22 -0
  12. package/dist/cli/output.d.ts.map +1 -0
  13. package/dist/cli/output.js +105 -0
  14. package/dist/cli/output.js.map +1 -0
  15. package/dist/cookies/jar.d.ts +41 -0
  16. package/dist/cookies/jar.d.ts.map +1 -0
  17. package/dist/cookies/jar.js +148 -0
  18. package/dist/cookies/jar.js.map +1 -0
  19. package/dist/cookies/parser.d.ts +24 -0
  20. package/dist/cookies/parser.d.ts.map +1 -0
  21. package/dist/cookies/parser.js +93 -0
  22. package/dist/cookies/parser.js.map +1 -0
  23. package/dist/core/client.d.ts +79 -0
  24. package/dist/core/client.d.ts.map +1 -0
  25. package/dist/core/client.js +106 -0
  26. package/dist/core/client.js.map +1 -0
  27. package/dist/core/errors.d.ts +36 -0
  28. package/dist/core/errors.d.ts.map +1 -0
  29. package/dist/core/errors.js +65 -0
  30. package/dist/core/errors.js.map +1 -0
  31. package/dist/core/request.d.ts +96 -0
  32. package/dist/core/request.d.ts.map +1 -0
  33. package/dist/core/request.js +5 -0
  34. package/dist/core/request.js.map +1 -0
  35. package/dist/core/response.d.ts +48 -0
  36. package/dist/core/response.d.ts.map +1 -0
  37. package/dist/core/response.js +65 -0
  38. package/dist/core/response.js.map +1 -0
  39. package/dist/core/session.d.ts +60 -0
  40. package/dist/core/session.d.ts.map +1 -0
  41. package/dist/core/session.js +305 -0
  42. package/dist/core/session.js.map +1 -0
  43. package/dist/fingerprints/akamai.d.ts +17 -0
  44. package/dist/fingerprints/akamai.d.ts.map +1 -0
  45. package/dist/fingerprints/akamai.js +30 -0
  46. package/dist/fingerprints/akamai.js.map +1 -0
  47. package/dist/fingerprints/database.d.ts +33 -0
  48. package/dist/fingerprints/database.d.ts.map +1 -0
  49. package/dist/fingerprints/database.js +68 -0
  50. package/dist/fingerprints/database.js.map +1 -0
  51. package/dist/fingerprints/extensions.d.ts +49 -0
  52. package/dist/fingerprints/extensions.d.ts.map +1 -0
  53. package/dist/fingerprints/extensions.js +178 -0
  54. package/dist/fingerprints/extensions.js.map +1 -0
  55. package/dist/fingerprints/ja3.d.ts +32 -0
  56. package/dist/fingerprints/ja3.d.ts.map +1 -0
  57. package/dist/fingerprints/ja3.js +64 -0
  58. package/dist/fingerprints/ja3.js.map +1 -0
  59. package/dist/fingerprints/profiles/chrome.d.ts +30 -0
  60. package/dist/fingerprints/profiles/chrome.d.ts.map +1 -0
  61. package/dist/fingerprints/profiles/chrome.js +202 -0
  62. package/dist/fingerprints/profiles/chrome.js.map +1 -0
  63. package/dist/fingerprints/profiles/edge.d.ts +16 -0
  64. package/dist/fingerprints/profiles/edge.d.ts.map +1 -0
  65. package/dist/fingerprints/profiles/edge.js +61 -0
  66. package/dist/fingerprints/profiles/edge.js.map +1 -0
  67. package/dist/fingerprints/profiles/firefox.d.ts +13 -0
  68. package/dist/fingerprints/profiles/firefox.d.ts.map +1 -0
  69. package/dist/fingerprints/profiles/firefox.js +160 -0
  70. package/dist/fingerprints/profiles/firefox.js.map +1 -0
  71. package/dist/fingerprints/profiles/safari.d.ts +16 -0
  72. package/dist/fingerprints/profiles/safari.d.ts.map +1 -0
  73. package/dist/fingerprints/profiles/safari.js +140 -0
  74. package/dist/fingerprints/profiles/safari.js.map +1 -0
  75. package/dist/fingerprints/profiles/tor.d.ts +14 -0
  76. package/dist/fingerprints/profiles/tor.d.ts.map +1 -0
  77. package/dist/fingerprints/profiles/tor.js +136 -0
  78. package/dist/fingerprints/profiles/tor.js.map +1 -0
  79. package/dist/fingerprints/types.d.ts +104 -0
  80. package/dist/fingerprints/types.d.ts.map +1 -0
  81. package/dist/fingerprints/types.js +9 -0
  82. package/dist/fingerprints/types.js.map +1 -0
  83. package/dist/http/h1/client.d.ts +21 -0
  84. package/dist/http/h1/client.d.ts.map +1 -0
  85. package/dist/http/h1/client.js +136 -0
  86. package/dist/http/h1/client.js.map +1 -0
  87. package/dist/http/h1/encoder.d.ts +11 -0
  88. package/dist/http/h1/encoder.d.ts.map +1 -0
  89. package/dist/http/h1/encoder.js +75 -0
  90. package/dist/http/h1/encoder.js.map +1 -0
  91. package/dist/http/h1/parser.d.ts +61 -0
  92. package/dist/http/h1/parser.d.ts.map +1 -0
  93. package/dist/http/h1/parser.js +258 -0
  94. package/dist/http/h1/parser.js.map +1 -0
  95. package/dist/http/h2/client.d.ts +48 -0
  96. package/dist/http/h2/client.d.ts.map +1 -0
  97. package/dist/http/h2/client.js +376 -0
  98. package/dist/http/h2/client.js.map +1 -0
  99. package/dist/http/h2/frames.d.ts +65 -0
  100. package/dist/http/h2/frames.d.ts.map +1 -0
  101. package/dist/http/h2/frames.js +184 -0
  102. package/dist/http/h2/frames.js.map +1 -0
  103. package/dist/http/h2/hpack.d.ts +27 -0
  104. package/dist/http/h2/hpack.d.ts.map +1 -0
  105. package/dist/http/h2/hpack.js +423 -0
  106. package/dist/http/h2/hpack.js.map +1 -0
  107. package/dist/http/negotiator.d.ts +36 -0
  108. package/dist/http/negotiator.d.ts.map +1 -0
  109. package/dist/http/negotiator.js +101 -0
  110. package/dist/http/negotiator.js.map +1 -0
  111. package/dist/http/pool.d.ts +63 -0
  112. package/dist/http/pool.d.ts.map +1 -0
  113. package/dist/http/pool.js +177 -0
  114. package/dist/http/pool.js.map +1 -0
  115. package/dist/index.d.ts +22 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +23 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/middleware/interceptor.d.ts +27 -0
  120. package/dist/middleware/interceptor.d.ts.map +1 -0
  121. package/dist/middleware/interceptor.js +35 -0
  122. package/dist/middleware/interceptor.js.map +1 -0
  123. package/dist/middleware/rate-limiter.d.ts +26 -0
  124. package/dist/middleware/rate-limiter.d.ts.map +1 -0
  125. package/dist/middleware/rate-limiter.js +59 -0
  126. package/dist/middleware/rate-limiter.js.map +1 -0
  127. package/dist/middleware/retry.d.ts +17 -0
  128. package/dist/middleware/retry.d.ts.map +1 -0
  129. package/dist/middleware/retry.js +64 -0
  130. package/dist/middleware/retry.js.map +1 -0
  131. package/dist/proxy/http-proxy.d.ts +23 -0
  132. package/dist/proxy/http-proxy.d.ts.map +1 -0
  133. package/dist/proxy/http-proxy.js +93 -0
  134. package/dist/proxy/http-proxy.js.map +1 -0
  135. package/dist/proxy/socks.d.ts +24 -0
  136. package/dist/proxy/socks.d.ts.map +1 -0
  137. package/dist/proxy/socks.js +196 -0
  138. package/dist/proxy/socks.js.map +1 -0
  139. package/dist/tls/constants.d.ts +142 -0
  140. package/dist/tls/constants.d.ts.map +1 -0
  141. package/dist/tls/constants.js +163 -0
  142. package/dist/tls/constants.js.map +1 -0
  143. package/dist/tls/node-engine.d.ts +22 -0
  144. package/dist/tls/node-engine.d.ts.map +1 -0
  145. package/dist/tls/node-engine.js +190 -0
  146. package/dist/tls/node-engine.js.map +1 -0
  147. package/dist/tls/stealth/client-hello.d.ts +38 -0
  148. package/dist/tls/stealth/client-hello.d.ts.map +1 -0
  149. package/dist/tls/stealth/client-hello.js +197 -0
  150. package/dist/tls/stealth/client-hello.js.map +1 -0
  151. package/dist/tls/stealth/engine.d.ts +16 -0
  152. package/dist/tls/stealth/engine.d.ts.map +1 -0
  153. package/dist/tls/stealth/engine.js +196 -0
  154. package/dist/tls/stealth/engine.js.map +1 -0
  155. package/dist/tls/stealth/handshake.d.ts +45 -0
  156. package/dist/tls/stealth/handshake.d.ts.map +1 -0
  157. package/dist/tls/stealth/handshake.js +403 -0
  158. package/dist/tls/stealth/handshake.js.map +1 -0
  159. package/dist/tls/stealth/key-schedule.d.ts +85 -0
  160. package/dist/tls/stealth/key-schedule.d.ts.map +1 -0
  161. package/dist/tls/stealth/key-schedule.js +141 -0
  162. package/dist/tls/stealth/key-schedule.js.map +1 -0
  163. package/dist/tls/stealth/record-layer.d.ts +74 -0
  164. package/dist/tls/stealth/record-layer.d.ts.map +1 -0
  165. package/dist/tls/stealth/record-layer.js +167 -0
  166. package/dist/tls/stealth/record-layer.js.map +1 -0
  167. package/dist/tls/types.d.ts +58 -0
  168. package/dist/tls/types.d.ts.map +1 -0
  169. package/dist/tls/types.js +6 -0
  170. package/dist/tls/types.js.map +1 -0
  171. package/dist/utils/buffer-reader.d.ts +32 -0
  172. package/dist/utils/buffer-reader.d.ts.map +1 -0
  173. package/dist/utils/buffer-reader.js +99 -0
  174. package/dist/utils/buffer-reader.js.map +1 -0
  175. package/dist/utils/buffer-writer.d.ts +35 -0
  176. package/dist/utils/buffer-writer.d.ts.map +1 -0
  177. package/dist/utils/buffer-writer.js +121 -0
  178. package/dist/utils/buffer-writer.js.map +1 -0
  179. package/dist/utils/encoding.d.ts +19 -0
  180. package/dist/utils/encoding.d.ts.map +1 -0
  181. package/dist/utils/encoding.js +63 -0
  182. package/dist/utils/encoding.js.map +1 -0
  183. package/dist/utils/logger.d.ts +24 -0
  184. package/dist/utils/logger.d.ts.map +1 -0
  185. package/dist/utils/logger.js +56 -0
  186. package/dist/utils/logger.js.map +1 -0
  187. package/dist/utils/url.d.ts +22 -0
  188. package/dist/utils/url.d.ts.map +1 -0
  189. package/dist/utils/url.js +56 -0
  190. package/dist/utils/url.js.map +1 -0
  191. package/dist/ws/client.d.ts +63 -0
  192. package/dist/ws/client.d.ts.map +1 -0
  193. package/dist/ws/client.js +273 -0
  194. package/dist/ws/client.js.map +1 -0
  195. package/dist/ws/frame.d.ts +44 -0
  196. package/dist/ws/frame.d.ts.map +1 -0
  197. package/dist/ws/frame.js +146 -0
  198. package/dist/ws/frame.js.map +1 -0
  199. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-engine.d.ts","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAqB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AA2F/D,qBAAa,aAAc,YAAW,UAAU;IACxC,OAAO,CACX,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,SAAS,CAAC;CAgGtB"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Standard TLS engine.
3
+ *
4
+ * Uses Node.js built-in `node:tls` module with maximum configuration
5
+ * from browser profiles. This engine controls:
6
+ * - Cipher suite order (via the `ciphers` option)
7
+ * - Named groups / ECDH curves (via `ecdhCurve`)
8
+ * - Signature algorithms (via `sigalgs`)
9
+ * - ALPN protocols
10
+ * - Min/max protocol version
11
+ * - Session tickets, SNI
12
+ *
13
+ * Limitations: `node:tls` does not expose extension ordering, GREASE
14
+ * injection, or padding extension control. For full JA3 fingerprint
15
+ * matching use the Stealth engine instead.
16
+ */
17
+ import * as tls from 'node:tls';
18
+ import { CipherSuite, NamedGroup, SignatureScheme } from './constants.js';
19
+ import { TLSError } from '../core/errors.js';
20
+ // ---- Cipher suite name mapping ----
21
+ const CIPHER_NAME = new Map([
22
+ // TLS 1.3 (Node handles these via `ciphersuites` option)
23
+ [CipherSuite.TLS_AES_128_GCM_SHA256, 'TLS_AES_128_GCM_SHA256'],
24
+ [CipherSuite.TLS_AES_256_GCM_SHA384, 'TLS_AES_256_GCM_SHA384'],
25
+ [CipherSuite.TLS_CHACHA20_POLY1305_SHA256, 'TLS_CHACHA20_POLY1305_SHA256'],
26
+ // TLS 1.2
27
+ [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 'ECDHE-ECDSA-AES128-GCM-SHA256'],
28
+ [CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 'ECDHE-RSA-AES128-GCM-SHA256'],
29
+ [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 'ECDHE-ECDSA-AES256-GCM-SHA384'],
30
+ [CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 'ECDHE-RSA-AES256-GCM-SHA384'],
31
+ [CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 'ECDHE-ECDSA-CHACHA20-POLY1305'],
32
+ [CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 'ECDHE-RSA-CHACHA20-POLY1305'],
33
+ [CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 'ECDHE-RSA-AES128-SHA'],
34
+ [CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 'ECDHE-RSA-AES256-SHA'],
35
+ [CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, 'AES128-GCM-SHA256'],
36
+ [CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, 'AES256-GCM-SHA384'],
37
+ [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, 'AES128-SHA'],
38
+ [CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, 'AES256-SHA'],
39
+ [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 'ECDHE-ECDSA-AES256-SHA'],
40
+ [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 'ECDHE-ECDSA-AES128-SHA'],
41
+ [CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, 'AES256-SHA'],
42
+ [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, 'AES128-SHA'],
43
+ ]);
44
+ const GROUP_NAME = new Map([
45
+ [NamedGroup.X25519, 'X25519'],
46
+ [NamedGroup.SECP256R1, 'P-256'],
47
+ [NamedGroup.SECP384R1, 'P-384'],
48
+ [NamedGroup.SECP521R1, 'P-521'],
49
+ [NamedGroup.X448, 'X448'],
50
+ [NamedGroup.FFDHE2048, 'ffdhe2048'],
51
+ [NamedGroup.FFDHE3072, 'ffdhe3072'],
52
+ ]);
53
+ const SIGALG_NAME = new Map([
54
+ [SignatureScheme.ECDSA_SECP256R1_SHA256, 'ecdsa_secp256r1_sha256'],
55
+ [SignatureScheme.ECDSA_SECP384R1_SHA384, 'ecdsa_secp384r1_sha384'],
56
+ [SignatureScheme.ECDSA_SECP521R1_SHA512, 'ecdsa_secp521r1_sha512'],
57
+ [SignatureScheme.RSA_PSS_RSAE_SHA256, 'rsa_pss_rsae_sha256'],
58
+ [SignatureScheme.RSA_PSS_RSAE_SHA384, 'rsa_pss_rsae_sha384'],
59
+ [SignatureScheme.RSA_PSS_RSAE_SHA512, 'rsa_pss_rsae_sha512'],
60
+ [SignatureScheme.RSA_PKCS1_SHA256, 'rsa_pkcs1_sha256'],
61
+ [SignatureScheme.RSA_PKCS1_SHA384, 'rsa_pkcs1_sha384'],
62
+ [SignatureScheme.RSA_PKCS1_SHA512, 'rsa_pkcs1_sha512'],
63
+ [SignatureScheme.RSA_PSS_PSS_SHA256, 'rsa_pss_pss_sha256'],
64
+ [SignatureScheme.RSA_PSS_PSS_SHA384, 'rsa_pss_pss_sha384'],
65
+ [SignatureScheme.RSA_PSS_PSS_SHA512, 'rsa_pss_pss_sha512'],
66
+ ]);
67
+ // ---- Helpers ----
68
+ function buildCipherString(suites) {
69
+ const tls13 = [];
70
+ const tls12 = [];
71
+ for (const s of suites) {
72
+ const name = CIPHER_NAME.get(s);
73
+ if (!name)
74
+ continue;
75
+ if (name.startsWith('TLS_')) {
76
+ tls13.push(name);
77
+ }
78
+ else {
79
+ tls12.push(name);
80
+ }
81
+ }
82
+ return {
83
+ ciphers: tls12.join(':'),
84
+ ciphersuites: tls13.join(':'),
85
+ };
86
+ }
87
+ function buildEcdhCurve(groups) {
88
+ return groups
89
+ .map((g) => GROUP_NAME.get(g))
90
+ .filter((n) => n !== undefined)
91
+ .join(':');
92
+ }
93
+ function buildSigalgs(algs) {
94
+ return algs
95
+ .map((a) => SIGALG_NAME.get(a))
96
+ .filter((n) => n !== undefined)
97
+ .join(':');
98
+ }
99
+ // ---- Engine implementation ----
100
+ export class NodeTLSEngine {
101
+ async connect(options, profile) {
102
+ return new Promise((resolve, reject) => {
103
+ const tlsOpts = {
104
+ host: options.host,
105
+ port: options.port,
106
+ servername: options.servername ?? options.host,
107
+ rejectUnauthorized: !options.insecure,
108
+ ALPNProtocols: options.alpnProtocols,
109
+ minVersion: 'TLSv1.2',
110
+ maxVersion: 'TLSv1.3',
111
+ };
112
+ // Apply profile overrides
113
+ if (profile) {
114
+ const { ciphers, ciphersuites } = buildCipherString(profile.tls.cipherSuites);
115
+ tlsOpts.ciphers = ciphers;
116
+ // ciphersuites is an undocumented but supported option in Node
117
+ tlsOpts['cipherSuites'] = ciphersuites;
118
+ tlsOpts.ecdhCurve = buildEcdhCurve(profile.tls.supportedGroups);
119
+ tlsOpts.sigalgs = buildSigalgs(profile.tls.signatureAlgorithms);
120
+ tlsOpts.ALPNProtocols = profile.tls.alpnProtocols;
121
+ }
122
+ // If a pre-connected socket is provided (e.g. from proxy tunnel),
123
+ // use it as the underlying transport.
124
+ if (options.socket) {
125
+ tlsOpts.socket = options.socket;
126
+ }
127
+ // Timeout
128
+ const timeoutMs = options.timeout ?? 30_000;
129
+ const socket = tls.connect(tlsOpts);
130
+ let settled = false;
131
+ let timer;
132
+ if (timeoutMs > 0) {
133
+ timer = setTimeout(() => {
134
+ if (!settled) {
135
+ settled = true;
136
+ socket.destroy();
137
+ reject(new TLSError('TLS handshake timed out'));
138
+ }
139
+ }, timeoutMs);
140
+ }
141
+ // AbortSignal support
142
+ if (options.signal) {
143
+ const onAbort = () => {
144
+ if (!settled) {
145
+ settled = true;
146
+ if (timer)
147
+ clearTimeout(timer);
148
+ socket.destroy();
149
+ reject(new TLSError('TLS connection aborted'));
150
+ }
151
+ };
152
+ if (options.signal.aborted) {
153
+ onAbort();
154
+ return;
155
+ }
156
+ options.signal.addEventListener('abort', onAbort, { once: true });
157
+ }
158
+ socket.once('secureConnect', () => {
159
+ if (settled)
160
+ return;
161
+ settled = true;
162
+ if (timer)
163
+ clearTimeout(timer);
164
+ const cipher = socket.getCipher();
165
+ const proto = socket.getProtocol();
166
+ const connectionInfo = {
167
+ version: proto ?? 'unknown',
168
+ alpnProtocol: socket.alpnProtocol || null,
169
+ cipher: cipher?.name ?? 'unknown',
170
+ };
171
+ const tlsSocket = Object.assign(socket, {
172
+ connectionInfo,
173
+ destroyTLS() {
174
+ socket.destroy();
175
+ },
176
+ });
177
+ resolve(tlsSocket);
178
+ });
179
+ socket.once('error', (err) => {
180
+ if (settled)
181
+ return;
182
+ settled = true;
183
+ if (timer)
184
+ clearTimeout(timer);
185
+ reject(new TLSError(err.message));
186
+ });
187
+ });
188
+ }
189
+ }
190
+ //# sourceMappingURL=node-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-engine.js","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * ClientHello builder.
3
+ *
4
+ * Constructs a TLS ClientHello message byte-by-byte, giving full
5
+ * control over extension ordering, GREASE placement, cipher suite
6
+ * order, and every other field that contributes to the JA3 fingerprint.
7
+ *
8
+ * The output is a complete TLS record (record header + handshake
9
+ * header + ClientHello body) ready to send over a TCP socket.
10
+ */
11
+ import type { BrowserProfile } from '../../fingerprints/types.js';
12
+ export interface KeyShareEntry {
13
+ group: number;
14
+ publicKey: Buffer;
15
+ privateKey: Buffer;
16
+ }
17
+ /**
18
+ * Generate a key share for the given named group.
19
+ */
20
+ export declare function generateKeyShare(group: number): KeyShareEntry;
21
+ export interface ClientHelloResult {
22
+ /** Complete TLS record bytes to send. */
23
+ record: Buffer;
24
+ /** Generated key shares for use in key exchange. */
25
+ keyShares: KeyShareEntry[];
26
+ /** The client_random value (32 bytes). */
27
+ clientRandom: Buffer;
28
+ /** Session ID (may be empty or 32 bytes). */
29
+ sessionId: Buffer;
30
+ /** The raw ClientHello handshake message (without record header) for
31
+ * transcript hashing. */
32
+ handshakeMessage: Buffer;
33
+ }
34
+ /**
35
+ * Build a complete ClientHello record from a browser profile.
36
+ */
37
+ export declare function buildClientHello(profile: BrowserProfile, hostname: string): ClientHelloResult;
38
+ //# sourceMappingURL=client-hello.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-hello.d.ts","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,6BAA6B,CAAC;AAWnF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAgC7D;AAsBD,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB;8BAC0B;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GACf,iBAAiB,CA+FnB"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * ClientHello builder.
3
+ *
4
+ * Constructs a TLS ClientHello message byte-by-byte, giving full
5
+ * control over extension ordering, GREASE placement, cipher suite
6
+ * order, and every other field that contributes to the JA3 fingerprint.
7
+ *
8
+ * The output is a complete TLS record (record header + handshake
9
+ * header + ClientHello body) ready to send over a TCP socket.
10
+ */
11
+ import { randomBytes, createECDH, generateKeyPairSync } from 'node:crypto';
12
+ import { BufferWriter } from '../../utils/buffer-writer.js';
13
+ import { RecordType, HandshakeType, ExtensionType, GREASE_VALUES, NamedGroup, } from '../constants.js';
14
+ // ---- GREASE ----
15
+ /** Pick a random GREASE value. */
16
+ function randomGrease() {
17
+ return GREASE_VALUES[Math.floor(Math.random() * GREASE_VALUES.length)];
18
+ }
19
+ /**
20
+ * Generate a key share for the given named group.
21
+ */
22
+ export function generateKeyShare(group) {
23
+ switch (group) {
24
+ case NamedGroup.X25519: {
25
+ const kp = generateKeyPairSync('x25519');
26
+ const pub = kp.publicKey.export({ type: 'spki', format: 'der' });
27
+ const priv = kp.privateKey.export({ type: 'pkcs8', format: 'der' });
28
+ // X25519 public key is the last 32 bytes of the SPKI DER
29
+ const publicKey = Buffer.from(pub.subarray(pub.length - 32));
30
+ // X25519 private key is the last 32 bytes of the PKCS8 DER
31
+ const privateKey = Buffer.from(priv.subarray(priv.length - 32));
32
+ return { group, publicKey, privateKey };
33
+ }
34
+ case NamedGroup.SECP256R1:
35
+ case NamedGroup.SECP384R1:
36
+ case NamedGroup.SECP521R1: {
37
+ const curveName = group === NamedGroup.SECP256R1
38
+ ? 'prime256v1'
39
+ : group === NamedGroup.SECP384R1
40
+ ? 'secp384r1'
41
+ : 'secp521r1';
42
+ const ecdh = createECDH(curveName);
43
+ ecdh.generateKeys();
44
+ return {
45
+ group,
46
+ publicKey: Buffer.from(ecdh.getPublicKey()),
47
+ privateKey: Buffer.from(ecdh.getPrivateKey()),
48
+ };
49
+ }
50
+ default:
51
+ throw new Error(`Unsupported key share group: 0x${group.toString(16)}`);
52
+ }
53
+ }
54
+ // ---- Key share extension data builder ----
55
+ function buildKeyShareExtensionData(keyShares) {
56
+ const w = new BufferWriter(256);
57
+ // client_shares length placeholder
58
+ const lenReserve = w.reserve(2);
59
+ const startPos = w.position;
60
+ for (const ks of keyShares) {
61
+ w.writeUInt16(ks.group);
62
+ w.writeUInt16(ks.publicKey.length);
63
+ w.writeBytes(ks.publicKey);
64
+ }
65
+ w.patchUInt16(lenReserve, w.position - startPos);
66
+ return w.toBuffer();
67
+ }
68
+ /**
69
+ * Build a complete ClientHello record from a browser profile.
70
+ */
71
+ export function buildClientHello(profile, hostname) {
72
+ const tlsProfile = profile.tls;
73
+ // Generate cryptographic material
74
+ const clientRandom = randomBytes(32);
75
+ const sessionId = tlsProfile.randomSessionId ? randomBytes(32) : Buffer.alloc(0);
76
+ const keyShares = tlsProfile.keyShareGroups.map(generateKeyShare);
77
+ // Pick GREASE values (reuse same value per category for consistency)
78
+ const greaseCipher = tlsProfile.grease ? randomGrease() : 0;
79
+ const greaseExt = tlsProfile.grease ? randomGrease() : 0;
80
+ const greaseGroup = tlsProfile.grease ? randomGrease() : 0;
81
+ const greaseVersion = tlsProfile.grease ? randomGrease() : 0;
82
+ // ---- Build ClientHello body ----
83
+ const body = new BufferWriter(4096);
84
+ // client_version
85
+ body.writeUInt16(tlsProfile.clientVersion);
86
+ // random (32 bytes)
87
+ body.writeBytes(clientRandom);
88
+ // session_id
89
+ body.writeUInt8(sessionId.length);
90
+ if (sessionId.length > 0)
91
+ body.writeBytes(sessionId);
92
+ // cipher_suites
93
+ const ciphers = tlsProfile.grease
94
+ ? [greaseCipher, ...tlsProfile.cipherSuites]
95
+ : [...tlsProfile.cipherSuites];
96
+ body.writeUInt16(ciphers.length * 2);
97
+ for (const c of ciphers)
98
+ body.writeUInt16(c);
99
+ // compression_methods
100
+ body.writeUInt8(tlsProfile.compressionMethods.length);
101
+ for (const m of tlsProfile.compressionMethods)
102
+ body.writeUInt8(m);
103
+ // ---- Extensions ----
104
+ const extWriter = new BufferWriter(4096);
105
+ // If GREASE is enabled, prepend a GREASE extension
106
+ if (tlsProfile.grease) {
107
+ extWriter.writeUInt16(greaseExt);
108
+ extWriter.writeUInt16(1);
109
+ extWriter.writeUInt8(0);
110
+ }
111
+ // Write each extension from the profile in exact order
112
+ for (const extDef of tlsProfile.extensions) {
113
+ writeExtension(extWriter, extDef, hostname, keyShares, tlsProfile, {
114
+ greaseGroup,
115
+ greaseVersion,
116
+ });
117
+ }
118
+ // If GREASE is enabled, append a GREASE extension at end
119
+ if (tlsProfile.grease) {
120
+ const lastGrease = randomGrease();
121
+ extWriter.writeUInt16(lastGrease);
122
+ extWriter.writeUInt16(1);
123
+ extWriter.writeUInt8(0);
124
+ }
125
+ const extBytes = extWriter.toBuffer();
126
+ body.writeUInt16(extBytes.length);
127
+ body.writeBytes(extBytes);
128
+ const clientHelloBody = body.toBuffer();
129
+ // ---- Wrap in handshake header ----
130
+ const handshake = new BufferWriter(4 + clientHelloBody.length);
131
+ handshake.writeUInt8(HandshakeType.CLIENT_HELLO);
132
+ handshake.writeUInt24(clientHelloBody.length);
133
+ handshake.writeBytes(clientHelloBody);
134
+ const handshakeMessage = handshake.toBuffer();
135
+ // ---- Wrap in record ----
136
+ const record = new BufferWriter(5 + handshakeMessage.length);
137
+ record.writeUInt8(RecordType.HANDSHAKE);
138
+ record.writeUInt16(tlsProfile.recordVersion);
139
+ record.writeUInt16(handshakeMessage.length);
140
+ record.writeBytes(handshakeMessage);
141
+ return {
142
+ record: record.toBuffer(),
143
+ keyShares,
144
+ clientRandom,
145
+ sessionId,
146
+ handshakeMessage,
147
+ };
148
+ }
149
+ // ---- Extension writer ----
150
+ function writeExtension(w, extDef, hostname, keyShares, tlsProfile, grease) {
151
+ // Special handling for key_share -- inject actual key material
152
+ if (extDef.type === ExtensionType.KEY_SHARE) {
153
+ const data = buildKeyShareExtensionData(keyShares);
154
+ w.writeUInt16(ExtensionType.KEY_SHARE);
155
+ w.writeUInt16(data.length);
156
+ w.writeBytes(data);
157
+ return;
158
+ }
159
+ // Special handling for supported_groups with GREASE
160
+ if (extDef.type === ExtensionType.SUPPORTED_GROUPS && tlsProfile.grease) {
161
+ const groups = [grease.greaseGroup, ...tlsProfile.supportedGroups];
162
+ const inner = new BufferWriter(2 + groups.length * 2);
163
+ inner.writeUInt16(groups.length * 2);
164
+ for (const g of groups)
165
+ inner.writeUInt16(g);
166
+ const data = inner.toBuffer();
167
+ w.writeUInt16(ExtensionType.SUPPORTED_GROUPS);
168
+ w.writeUInt16(data.length);
169
+ w.writeBytes(data);
170
+ return;
171
+ }
172
+ // Special handling for supported_versions with GREASE
173
+ if (extDef.type === ExtensionType.SUPPORTED_VERSIONS && tlsProfile.grease) {
174
+ const versions = [grease.greaseVersion, ...tlsProfile.supportedVersions];
175
+ const inner = new BufferWriter(1 + versions.length * 2);
176
+ inner.writeUInt8(versions.length * 2);
177
+ for (const v of versions)
178
+ inner.writeUInt16(v);
179
+ const data = inner.toBuffer();
180
+ w.writeUInt16(ExtensionType.SUPPORTED_VERSIONS);
181
+ w.writeUInt16(data.length);
182
+ w.writeBytes(data);
183
+ return;
184
+ }
185
+ // General case
186
+ w.writeUInt16(extDef.type);
187
+ if (extDef.data) {
188
+ const data = extDef.data(hostname);
189
+ w.writeUInt16(data.length);
190
+ if (data.length > 0)
191
+ w.writeBytes(data);
192
+ }
193
+ else {
194
+ w.writeUInt16(0);
195
+ }
196
+ }
197
+ //# sourceMappingURL=client-hello.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-hello.js","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Stealth TLS engine.
3
+ *
4
+ * Implements ITLSEngine using raw TCP sockets and manual TLS 1.3
5
+ * handshake construction. This gives 100% control over the
6
+ * ClientHello bytes, enabling perfect JA3 fingerprint matching.
7
+ *
8
+ * After the handshake completes, wraps the raw socket in a Duplex
9
+ * stream that transparently encrypts/decrypts application data.
10
+ */
11
+ import type { ITLSEngine, TLSConnectOptions, TLSSocket } from '../types.js';
12
+ import type { BrowserProfile } from '../../fingerprints/types.js';
13
+ export declare class StealthTLSEngine implements ITLSEngine {
14
+ connect(options: TLSConnectOptions, profile?: BrowserProfile): Promise<TLSSocket>;
15
+ }
16
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/tls/stealth/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAyJlE,qBAAa,gBAAiB,YAAW,UAAU;IAC3C,OAAO,CACX,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,SAAS,CAAC;CA2BtB"}