nlcurl 0.1.0 → 0.2.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/README.md +5 -13
- package/dist/cli/args.d.ts +37 -5
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +6 -17
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +25 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +24 -7
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +24 -12
- package/dist/cli/output.js.map +1 -1
- package/dist/cookies/jar.d.ts +45 -13
- package/dist/cookies/jar.d.ts.map +1 -1
- package/dist/cookies/jar.js +88 -29
- package/dist/cookies/jar.js.map +1 -1
- package/dist/cookies/parser.d.ts +25 -3
- package/dist/cookies/parser.d.ts.map +1 -1
- package/dist/cookies/parser.js +12 -7
- package/dist/cookies/parser.js.map +1 -1
- package/dist/core/client.d.ts +49 -33
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +64 -38
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.d.ts +94 -6
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +95 -6
- package/dist/core/errors.js.map +1 -1
- package/dist/core/request.d.ts +96 -30
- package/dist/core/request.d.ts.map +1 -1
- package/dist/core/request.js +0 -3
- package/dist/core/request.js.map +1 -1
- package/dist/core/response.d.ts +92 -8
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +92 -7
- package/dist/core/response.js.map +1 -1
- package/dist/core/session.d.ts +109 -14
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +124 -46
- package/dist/core/session.js.map +1 -1
- package/dist/fingerprints/akamai.d.ts +11 -11
- package/dist/fingerprints/akamai.d.ts.map +1 -1
- package/dist/fingerprints/akamai.js +10 -14
- package/dist/fingerprints/akamai.js.map +1 -1
- package/dist/fingerprints/database.d.ts +14 -15
- package/dist/fingerprints/database.d.ts.map +1 -1
- package/dist/fingerprints/database.js +14 -19
- package/dist/fingerprints/database.js.map +1 -1
- package/dist/fingerprints/extensions.d.ts +121 -27
- package/dist/fingerprints/extensions.d.ts.map +1 -1
- package/dist/fingerprints/extensions.js +132 -49
- package/dist/fingerprints/extensions.js.map +1 -1
- package/dist/fingerprints/ja3.d.ts +34 -18
- package/dist/fingerprints/ja3.d.ts.map +1 -1
- package/dist/fingerprints/ja3.js +34 -18
- package/dist/fingerprints/ja3.js.map +1 -1
- package/dist/fingerprints/profiles/chrome.d.ts +21 -10
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -1
- package/dist/fingerprints/profiles/chrome.js +25 -22
- package/dist/fingerprints/profiles/chrome.js.map +1 -1
- package/dist/fingerprints/profiles/edge.d.ts +10 -7
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -1
- package/dist/fingerprints/profiles/edge.js +10 -10
- package/dist/fingerprints/profiles/edge.js.map +1 -1
- package/dist/fingerprints/profiles/firefox.d.ts +11 -3
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -1
- package/dist/fingerprints/profiles/firefox.js +15 -14
- package/dist/fingerprints/profiles/firefox.js.map +1 -1
- package/dist/fingerprints/profiles/safari.d.ts +14 -3
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -1
- package/dist/fingerprints/profiles/safari.js +16 -13
- package/dist/fingerprints/profiles/safari.js.map +1 -1
- package/dist/fingerprints/profiles/tor.d.ts +8 -7
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -1
- package/dist/fingerprints/profiles/tor.js +8 -14
- package/dist/fingerprints/profiles/tor.js.map +1 -1
- package/dist/fingerprints/types.d.ts +70 -47
- package/dist/fingerprints/types.d.ts.map +1 -1
- package/dist/fingerprints/types.js +0 -7
- package/dist/fingerprints/types.js.map +1 -1
- package/dist/http/h1/client.d.ts +30 -9
- package/dist/http/h1/client.d.ts.map +1 -1
- package/dist/http/h1/client.js +152 -15
- package/dist/http/h1/client.js.map +1 -1
- package/dist/http/h1/encoder.d.ts +9 -6
- package/dist/http/h1/encoder.d.ts.map +1 -1
- package/dist/http/h1/encoder.js +8 -12
- package/dist/http/h1/encoder.js.map +1 -1
- package/dist/http/h1/parser.d.ts +68 -14
- package/dist/http/h1/parser.d.ts.map +1 -1
- package/dist/http/h1/parser.js +92 -37
- package/dist/http/h1/parser.js.map +1 -1
- package/dist/http/h2/client.d.ts +81 -14
- package/dist/http/h2/client.d.ts.map +1 -1
- package/dist/http/h2/client.js +465 -63
- package/dist/http/h2/client.js.map +1 -1
- package/dist/http/h2/frames.d.ts +103 -6
- package/dist/http/h2/frames.d.ts.map +1 -1
- package/dist/http/h2/frames.js +96 -17
- package/dist/http/h2/frames.js.map +1 -1
- package/dist/http/h2/hpack.d.ts +30 -5
- package/dist/http/h2/hpack.d.ts.map +1 -1
- package/dist/http/h2/hpack.js +39 -35
- package/dist/http/h2/hpack.js.map +1 -1
- package/dist/http/negotiator.d.ts +35 -12
- package/dist/http/negotiator.d.ts.map +1 -1
- package/dist/http/negotiator.js +89 -24
- package/dist/http/negotiator.js.map +1 -1
- package/dist/http/pool.d.ts +66 -17
- package/dist/http/pool.d.ts.map +1 -1
- package/dist/http/pool.js +47 -20
- package/dist/http/pool.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -13
- package/dist/index.js.map +1 -1
- package/dist/middleware/interceptor.d.ts +40 -8
- package/dist/middleware/interceptor.d.ts.map +1 -1
- package/dist/middleware/interceptor.js +28 -6
- package/dist/middleware/interceptor.js.map +1 -1
- package/dist/middleware/rate-limiter.d.ts +18 -5
- package/dist/middleware/rate-limiter.d.ts.map +1 -1
- package/dist/middleware/rate-limiter.js +12 -7
- package/dist/middleware/rate-limiter.js.map +1 -1
- package/dist/middleware/retry.d.ts +17 -5
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +13 -11
- package/dist/middleware/retry.js.map +1 -1
- package/dist/proxy/http-proxy.d.ts +17 -9
- package/dist/proxy/http-proxy.d.ts.map +1 -1
- package/dist/proxy/http-proxy.js +9 -13
- package/dist/proxy/http-proxy.js.map +1 -1
- package/dist/proxy/socks.d.ts +20 -9
- package/dist/proxy/socks.d.ts.map +1 -1
- package/dist/proxy/socks.js +20 -31
- package/dist/proxy/socks.js.map +1 -1
- package/dist/tls/constants.d.ts +74 -4
- package/dist/tls/constants.d.ts.map +1 -1
- package/dist/tls/constants.js +75 -21
- package/dist/tls/constants.js.map +1 -1
- package/dist/tls/node-engine.d.ts +17 -16
- package/dist/tls/node-engine.d.ts.map +1 -1
- package/dist/tls/node-engine.js +20 -27
- package/dist/tls/node-engine.js.map +1 -1
- package/dist/tls/stealth/client-hello.d.ts +32 -16
- package/dist/tls/stealth/client-hello.d.ts.map +1 -1
- package/dist/tls/stealth/client-hello.js +13 -37
- package/dist/tls/stealth/client-hello.js.map +1 -1
- package/dist/tls/stealth/engine.d.ts +18 -10
- package/dist/tls/stealth/engine.d.ts.map +1 -1
- package/dist/tls/stealth/engine.js +18 -24
- package/dist/tls/stealth/engine.js.map +1 -1
- package/dist/tls/stealth/handshake.d.ts +31 -17
- package/dist/tls/stealth/handshake.d.ts.map +1 -1
- package/dist/tls/stealth/handshake.js +173 -74
- package/dist/tls/stealth/handshake.js.map +1 -1
- package/dist/tls/stealth/key-schedule.d.ts +89 -32
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -1
- package/dist/tls/stealth/key-schedule.js +62 -42
- package/dist/tls/stealth/key-schedule.js.map +1 -1
- package/dist/tls/stealth/record-layer.d.ts +76 -25
- package/dist/tls/stealth/record-layer.d.ts.map +1 -1
- package/dist/tls/stealth/record-layer.js +66 -36
- package/dist/tls/stealth/record-layer.js.map +1 -1
- package/dist/tls/types.d.ts +33 -25
- package/dist/tls/types.d.ts.map +1 -1
- package/dist/tls/types.js +0 -4
- package/dist/tls/types.js.map +1 -1
- package/dist/utils/buffer-reader.d.ts +99 -7
- package/dist/utils/buffer-reader.d.ts.map +1 -1
- package/dist/utils/buffer-reader.js +99 -7
- package/dist/utils/buffer-reader.js.map +1 -1
- package/dist/utils/buffer-writer.d.ts +99 -10
- package/dist/utils/buffer-writer.d.ts.map +1 -1
- package/dist/utils/buffer-writer.js +101 -12
- package/dist/utils/buffer-writer.js.map +1 -1
- package/dist/utils/encoding.d.ts +33 -8
- package/dist/utils/encoding.d.ts.map +1 -1
- package/dist/utils/encoding.js +58 -13
- package/dist/utils/encoding.js.map +1 -1
- package/dist/utils/logger.d.ts +61 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +52 -4
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/url.d.ts +47 -7
- package/dist/utils/url.d.ts.map +1 -1
- package/dist/utils/url.js +47 -7
- package/dist/utils/url.js.map +1 -1
- package/dist/ws/client.d.ts +59 -15
- package/dist/ws/client.d.ts.map +1 -1
- package/dist/ws/client.js +34 -27
- package/dist/ws/client.js.map +1 -1
- package/dist/ws/frame.d.ts +43 -9
- package/dist/ws/frame.d.ts.map +1 -1
- package/dist/ws/frame.js +35 -19
- package/dist/ws/frame.js.map +1 -1
- package/package.json +2 -2
package/dist/tls/constants.js
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TLS
|
|
2
|
+
* TLS record content type codes (RFC 8446 §5.1).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* (RFC 8446 for TLS 1.3, RFC 5246 for TLS 1.2).
|
|
4
|
+
* @enum {number}
|
|
6
5
|
*/
|
|
7
|
-
// ---- Record types ----
|
|
8
6
|
export const RecordType = {
|
|
9
7
|
CHANGE_CIPHER_SPEC: 20,
|
|
10
8
|
ALERT: 21,
|
|
11
9
|
HANDSHAKE: 22,
|
|
12
10
|
APPLICATION_DATA: 23,
|
|
13
11
|
};
|
|
14
|
-
|
|
12
|
+
/**
|
|
13
|
+
* TLS protocol version codes as used in the record layer and handshake
|
|
14
|
+
* (RFC 8446 Appendix B.3.1).
|
|
15
|
+
*
|
|
16
|
+
* @enum {number}
|
|
17
|
+
*/
|
|
15
18
|
export const ProtocolVersion = {
|
|
16
19
|
TLS_1_0: 0x0301,
|
|
17
20
|
TLS_1_1: 0x0302,
|
|
18
21
|
TLS_1_2: 0x0303,
|
|
19
22
|
TLS_1_3: 0x0304,
|
|
20
23
|
};
|
|
21
|
-
|
|
24
|
+
/**
|
|
25
|
+
* TLS handshake message type codes (RFC 8446 ¥4).
|
|
26
|
+
*
|
|
27
|
+
* @enum {number}
|
|
28
|
+
*/
|
|
22
29
|
export const HandshakeType = {
|
|
23
30
|
CLIENT_HELLO: 1,
|
|
24
31
|
SERVER_HELLO: 2,
|
|
@@ -32,14 +39,16 @@ export const HandshakeType = {
|
|
|
32
39
|
KEY_UPDATE: 24,
|
|
33
40
|
MESSAGE_HASH: 254,
|
|
34
41
|
};
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
/**
|
|
43
|
+
* IANA TLS cipher suite codes supported by the stealth engine and used to
|
|
44
|
+
* construct JA3 fingerprints (RFC 8446, RFC 5246).
|
|
45
|
+
*
|
|
46
|
+
* @enum {number}
|
|
47
|
+
*/
|
|
37
48
|
export const CipherSuite = {
|
|
38
|
-
// TLS 1.3
|
|
39
49
|
TLS_AES_128_GCM_SHA256: 0x1301,
|
|
40
50
|
TLS_AES_256_GCM_SHA384: 0x1302,
|
|
41
51
|
TLS_CHACHA20_POLY1305_SHA256: 0x1303,
|
|
42
|
-
// TLS 1.2 (Chrome / Edge)
|
|
43
52
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 0xc02b,
|
|
44
53
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: 0xc02f,
|
|
45
54
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 0xc02c,
|
|
@@ -52,11 +61,14 @@ export const CipherSuite = {
|
|
|
52
61
|
TLS_RSA_WITH_AES_256_GCM_SHA384: 0x009d,
|
|
53
62
|
TLS_RSA_WITH_AES_128_CBC_SHA: 0x002f,
|
|
54
63
|
TLS_RSA_WITH_AES_256_CBC_SHA: 0x0035,
|
|
55
|
-
// Firefox additional
|
|
56
64
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: 0xc009,
|
|
57
65
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: 0xc00a,
|
|
58
66
|
};
|
|
59
|
-
|
|
67
|
+
/**
|
|
68
|
+
* IANA TLS extension type codes (RFC 8446 Appendix B.3.1 and related RFCs).
|
|
69
|
+
*
|
|
70
|
+
* @enum {number}
|
|
71
|
+
*/
|
|
60
72
|
export const ExtensionType = {
|
|
61
73
|
SERVER_NAME: 0x0000,
|
|
62
74
|
EC_POINT_FORMATS: 0x000b,
|
|
@@ -74,7 +86,7 @@ export const ExtensionType = {
|
|
|
74
86
|
APPLICATION_LAYER_PROTOCOL_NEGOTIATION: 0x0010,
|
|
75
87
|
COMPRESS_CERTIFICATE: 0x001b,
|
|
76
88
|
TOKEN_BINDING: 0x0018,
|
|
77
|
-
APPLICATION_SETTINGS: 0x4469,
|
|
89
|
+
APPLICATION_SETTINGS: 0x4469,
|
|
78
90
|
DELEGATED_CREDENTIALS: 0x0022,
|
|
79
91
|
RECORD_SIZE_LIMIT: 0x001c,
|
|
80
92
|
PADDING: 0x0015,
|
|
@@ -83,7 +95,12 @@ export const ExtensionType = {
|
|
|
83
95
|
ENCRYPTED_CLIENT_HELLO: 0xfe0d,
|
|
84
96
|
POST_HANDSHAKE_AUTH: 0x0031,
|
|
85
97
|
};
|
|
86
|
-
|
|
98
|
+
/**
|
|
99
|
+
* IANA named group codes for elliptic curves and finite-field DH groups
|
|
100
|
+
* used in TLS key exchange (RFC 8422, RFC 7748).
|
|
101
|
+
*
|
|
102
|
+
* @enum {number}
|
|
103
|
+
*/
|
|
87
104
|
export const NamedGroup = {
|
|
88
105
|
X25519: 0x001d,
|
|
89
106
|
SECP256R1: 0x0017,
|
|
@@ -95,7 +112,12 @@ export const NamedGroup = {
|
|
|
95
112
|
X25519_KYBER768: 0x6399,
|
|
96
113
|
X25519_MLKEM768: 0x4588,
|
|
97
114
|
};
|
|
98
|
-
|
|
115
|
+
/**
|
|
116
|
+
* IANA TLS signature scheme codes used in the `signature_algorithms` extension
|
|
117
|
+
* and in `CertificateVerify` messages (RFC 8446 Appendix B.3.1.3).
|
|
118
|
+
*
|
|
119
|
+
* @enum {number}
|
|
120
|
+
*/
|
|
99
121
|
export const SignatureScheme = {
|
|
100
122
|
ECDSA_SECP256R1_SHA256: 0x0403,
|
|
101
123
|
ECDSA_SECP384R1_SHA384: 0x0503,
|
|
@@ -114,31 +136,63 @@ export const SignatureScheme = {
|
|
|
114
136
|
RSA_PKCS1_SHA1: 0x0201,
|
|
115
137
|
ECDSA_SHA1: 0x0203,
|
|
116
138
|
};
|
|
117
|
-
|
|
139
|
+
/**
|
|
140
|
+
* EC point format codes used in the `ec_point_formats` TLS extension
|
|
141
|
+
* (RFC 8422 §5.1.2). Only `UNCOMPRESSED` (`0`) is used in practice.
|
|
142
|
+
*
|
|
143
|
+
* @enum {number}
|
|
144
|
+
*/
|
|
118
145
|
export const ECPointFormat = {
|
|
119
146
|
UNCOMPRESSED: 0,
|
|
120
147
|
};
|
|
121
|
-
|
|
148
|
+
/**
|
|
149
|
+
* PSK key exchange mode codes used in the `psk_key_exchange_modes` extension
|
|
150
|
+
* (RFC 8446 ¥4.2.9).
|
|
151
|
+
*
|
|
152
|
+
* @enum {number}
|
|
153
|
+
*/
|
|
122
154
|
export const PskKeyExchangeMode = {
|
|
123
155
|
PSK_KE: 0,
|
|
124
156
|
PSK_DHE_KE: 1,
|
|
125
157
|
};
|
|
126
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Certificate compression algorithm codes used in the `compress_certificate`
|
|
160
|
+
* extension (RFC 8879).
|
|
161
|
+
*
|
|
162
|
+
* @enum {number}
|
|
163
|
+
*/
|
|
127
164
|
export const CertCompressAlg = {
|
|
128
165
|
ZLIB: 1,
|
|
129
166
|
BROTLI: 2,
|
|
130
167
|
ZSTD: 3,
|
|
131
168
|
};
|
|
132
|
-
|
|
169
|
+
/**
|
|
170
|
+
* The 16 GREASE values defined in RFC 8701. These are injected into cipher
|
|
171
|
+
* suite lists, extension type lists, and named group lists to encourage
|
|
172
|
+
* servers to be tolerant of unknown values.
|
|
173
|
+
*
|
|
174
|
+
* @type {readonly number[]}
|
|
175
|
+
*/
|
|
133
176
|
export const GREASE_VALUES = [
|
|
134
177
|
0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a,
|
|
135
178
|
0x8a8a, 0x9a9a, 0xaaaa, 0xbaba, 0xcaca, 0xdada, 0xeaea, 0xfafa,
|
|
136
179
|
];
|
|
137
|
-
/**
|
|
180
|
+
/**
|
|
181
|
+
* Returns a deterministic GREASE value selected by `seed`, cycling through
|
|
182
|
+
* the 16 GREASE values defined in RFC 8701.
|
|
183
|
+
*
|
|
184
|
+
* @param {number} seed - Arbitrary integer used to select the GREASE value.
|
|
185
|
+
* @returns {number} A GREASE value from the GREASE_VALUES array.
|
|
186
|
+
*/
|
|
138
187
|
export function greaseValue(seed) {
|
|
139
188
|
return GREASE_VALUES[seed % GREASE_VALUES.length];
|
|
140
189
|
}
|
|
141
|
-
|
|
190
|
+
/**
|
|
191
|
+
* TLS alert description codes (RFC 8446 Appendix B.2). Used to interpret
|
|
192
|
+
* alert records received from the server during or after the handshake.
|
|
193
|
+
*
|
|
194
|
+
* @enum {number}
|
|
195
|
+
*/
|
|
142
196
|
export const AlertDescription = {
|
|
143
197
|
CLOSE_NOTIFY: 0,
|
|
144
198
|
UNEXPECTED_MESSAGE: 10,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/tls/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/tls/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,23 @@
|
|
|
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
1
|
import type { ITLSEngine, TLSConnectOptions, TLSSocket } from './types.js';
|
|
18
2
|
import type { BrowserProfile } from '../fingerprints/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* TLS engine that delegates to Node.js’s built-in `tls` module. Provides
|
|
5
|
+
* standard TLS connectivity with optional browser-profile cipher and curve
|
|
6
|
+
* configuration, but does not reproduce the exact ClientHello byte sequence
|
|
7
|
+
* of a real browser. Use {@link StealthTLSEngine} when full fingerprint
|
|
8
|
+
* fidelity is required.
|
|
9
|
+
*/
|
|
19
10
|
export declare class NodeTLSEngine implements ITLSEngine {
|
|
11
|
+
/**
|
|
12
|
+
* Establishes a TLS connection to the given host and port using Node.js’s
|
|
13
|
+
* native `tls.connect()`. When a `profile` is supplied the cipher list,
|
|
14
|
+
* ECDH curves, and signature algorithms are overridden to match that profile.
|
|
15
|
+
*
|
|
16
|
+
* @param {TLSConnectOptions} options - Connection parameters.
|
|
17
|
+
* @param {BrowserProfile} [profile] - Optional browser profile to apply cipher/curve overrides.
|
|
18
|
+
* @returns {Promise<TLSSocket>} Resolves with the connected TLS duplex stream.
|
|
19
|
+
* @throws {TLSError} If the handshake fails, times out, or the connection is aborted.
|
|
20
|
+
*/
|
|
20
21
|
connect(options: TLSConnectOptions, profile?: BrowserProfile): Promise<TLSSocket>;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=node-engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-engine.d.ts","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node-engine.d.ts","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAqB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAmF/D;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C;;;;;;;;;OASG;IACG,OAAO,CACX,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,SAAS,CAAC;CA8FtB"}
|
package/dist/tls/node-engine.js
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
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
1
|
import * as tls from 'node:tls';
|
|
18
2
|
import { CipherSuite, NamedGroup, SignatureScheme } from './constants.js';
|
|
19
3
|
import { TLSError } from '../core/errors.js';
|
|
20
|
-
// ---- Cipher suite name mapping ----
|
|
21
4
|
const CIPHER_NAME = new Map([
|
|
22
|
-
// TLS 1.3 (Node handles these via `ciphersuites` option)
|
|
23
5
|
[CipherSuite.TLS_AES_128_GCM_SHA256, 'TLS_AES_128_GCM_SHA256'],
|
|
24
6
|
[CipherSuite.TLS_AES_256_GCM_SHA384, 'TLS_AES_256_GCM_SHA384'],
|
|
25
7
|
[CipherSuite.TLS_CHACHA20_POLY1305_SHA256, 'TLS_CHACHA20_POLY1305_SHA256'],
|
|
26
|
-
// TLS 1.2
|
|
27
8
|
[CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 'ECDHE-ECDSA-AES128-GCM-SHA256'],
|
|
28
9
|
[CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 'ECDHE-RSA-AES128-GCM-SHA256'],
|
|
29
10
|
[CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 'ECDHE-ECDSA-AES256-GCM-SHA384'],
|
|
@@ -64,7 +45,6 @@ const SIGALG_NAME = new Map([
|
|
|
64
45
|
[SignatureScheme.RSA_PSS_PSS_SHA384, 'rsa_pss_pss_sha384'],
|
|
65
46
|
[SignatureScheme.RSA_PSS_PSS_SHA512, 'rsa_pss_pss_sha512'],
|
|
66
47
|
]);
|
|
67
|
-
// ---- Helpers ----
|
|
68
48
|
function buildCipherString(suites) {
|
|
69
49
|
const tls13 = [];
|
|
70
50
|
const tls12 = [];
|
|
@@ -96,8 +76,24 @@ function buildSigalgs(algs) {
|
|
|
96
76
|
.filter((n) => n !== undefined)
|
|
97
77
|
.join(':');
|
|
98
78
|
}
|
|
99
|
-
|
|
79
|
+
/**
|
|
80
|
+
* TLS engine that delegates to Node.js’s built-in `tls` module. Provides
|
|
81
|
+
* standard TLS connectivity with optional browser-profile cipher and curve
|
|
82
|
+
* configuration, but does not reproduce the exact ClientHello byte sequence
|
|
83
|
+
* of a real browser. Use {@link StealthTLSEngine} when full fingerprint
|
|
84
|
+
* fidelity is required.
|
|
85
|
+
*/
|
|
100
86
|
export class NodeTLSEngine {
|
|
87
|
+
/**
|
|
88
|
+
* Establishes a TLS connection to the given host and port using Node.js’s
|
|
89
|
+
* native `tls.connect()`. When a `profile` is supplied the cipher list,
|
|
90
|
+
* ECDH curves, and signature algorithms are overridden to match that profile.
|
|
91
|
+
*
|
|
92
|
+
* @param {TLSConnectOptions} options - Connection parameters.
|
|
93
|
+
* @param {BrowserProfile} [profile] - Optional browser profile to apply cipher/curve overrides.
|
|
94
|
+
* @returns {Promise<TLSSocket>} Resolves with the connected TLS duplex stream.
|
|
95
|
+
* @throws {TLSError} If the handshake fails, times out, or the connection is aborted.
|
|
96
|
+
*/
|
|
101
97
|
async connect(options, profile) {
|
|
102
98
|
return new Promise((resolve, reject) => {
|
|
103
99
|
const tlsOpts = {
|
|
@@ -109,22 +105,20 @@ export class NodeTLSEngine {
|
|
|
109
105
|
minVersion: 'TLSv1.2',
|
|
110
106
|
maxVersion: 'TLSv1.3',
|
|
111
107
|
};
|
|
112
|
-
|
|
108
|
+
if (options.family !== undefined) {
|
|
109
|
+
tlsOpts['family'] = options.family;
|
|
110
|
+
}
|
|
113
111
|
if (profile) {
|
|
114
112
|
const { ciphers, ciphersuites } = buildCipherString(profile.tls.cipherSuites);
|
|
115
113
|
tlsOpts.ciphers = ciphers;
|
|
116
|
-
// ciphersuites is an undocumented but supported option in Node
|
|
117
114
|
tlsOpts['cipherSuites'] = ciphersuites;
|
|
118
115
|
tlsOpts.ecdhCurve = buildEcdhCurve(profile.tls.supportedGroups);
|
|
119
116
|
tlsOpts.sigalgs = buildSigalgs(profile.tls.signatureAlgorithms);
|
|
120
117
|
tlsOpts.ALPNProtocols = profile.tls.alpnProtocols;
|
|
121
118
|
}
|
|
122
|
-
// If a pre-connected socket is provided (e.g. from proxy tunnel),
|
|
123
|
-
// use it as the underlying transport.
|
|
124
119
|
if (options.socket) {
|
|
125
120
|
tlsOpts.socket = options.socket;
|
|
126
121
|
}
|
|
127
|
-
// Timeout
|
|
128
122
|
const timeoutMs = options.timeout ?? 30_000;
|
|
129
123
|
const socket = tls.connect(tlsOpts);
|
|
130
124
|
let settled = false;
|
|
@@ -138,7 +132,6 @@ export class NodeTLSEngine {
|
|
|
138
132
|
}
|
|
139
133
|
}, timeoutMs);
|
|
140
134
|
}
|
|
141
|
-
// AbortSignal support
|
|
142
135
|
if (options.signal) {
|
|
143
136
|
const onAbort = () => {
|
|
144
137
|
if (!settled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-engine.js","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node-engine.js","sourceRoot":"","sources":["../../src/tls/node-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,38 +1,54 @@
|
|
|
1
|
+
import type { BrowserProfile } from '../../fingerprints/types.js';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* control over extension ordering, GREASE placement, cipher suite
|
|
6
|
-
* order, and every other field that contributes to the JA3 fingerprint.
|
|
3
|
+
* An ephemeral key share generated for a specific named group, used during
|
|
4
|
+
* TLS 1.3 key exchange. Contains both the public key to advertise in the
|
|
5
|
+
* ClientHello and the private key required to compute the shared secret.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* @typedef {Object} KeyShareEntry
|
|
8
|
+
* @property {number} group - Named group code (e.g. `NamedGroup.X25519`).
|
|
9
|
+
* @property {Buffer} publicKey - Raw public key bytes to include in the key_share extension.
|
|
10
|
+
* @property {Buffer} privateKey - Raw private key bytes used for ECDH computation.
|
|
10
11
|
*/
|
|
11
|
-
import type { BrowserProfile } from '../../fingerprints/types.js';
|
|
12
12
|
export interface KeyShareEntry {
|
|
13
13
|
group: number;
|
|
14
14
|
publicKey: Buffer;
|
|
15
15
|
privateKey: Buffer;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Generates an ephemeral key pair for the specified named group. Supports
|
|
19
|
+
* X25519, SECP256R1, SECP384R1, and SECP521R1.
|
|
20
|
+
*
|
|
21
|
+
* @param {number} group - Named group code from the {@link NamedGroup} enum.
|
|
22
|
+
* @returns {KeyShareEntry} The generated key pair with group identifier.
|
|
23
|
+
* @throws {Error} If the specified group is not supported.
|
|
19
24
|
*/
|
|
20
25
|
export declare function generateKeyShare(group: number): KeyShareEntry;
|
|
26
|
+
/**
|
|
27
|
+
* Carries the outputs of {@link buildClientHello} that must be retained
|
|
28
|
+
* for subsequent handshake processing.
|
|
29
|
+
*
|
|
30
|
+
* @typedef {Object} ClientHelloResult
|
|
31
|
+
* @property {Buffer} record - The complete TLS record containing the ClientHello.
|
|
32
|
+
* @property {KeyShareEntry[]} keyShares - Generated key shares (private keys needed for key derivation).
|
|
33
|
+
* @property {Buffer} clientRandom - 32-byte client random included in the ClientHello body.
|
|
34
|
+
* @property {Buffer} sessionId - Legacy session ID bytes (may be empty).
|
|
35
|
+
* @property {Buffer} handshakeMessage - The raw handshake message body (used for transcript hashing).
|
|
36
|
+
*/
|
|
21
37
|
export interface ClientHelloResult {
|
|
22
|
-
/** Complete TLS record bytes to send. */
|
|
23
38
|
record: Buffer;
|
|
24
|
-
/** Generated key shares for use in key exchange. */
|
|
25
39
|
keyShares: KeyShareEntry[];
|
|
26
|
-
/** The client_random value (32 bytes). */
|
|
27
40
|
clientRandom: Buffer;
|
|
28
|
-
/** Session ID (may be empty or 32 bytes). */
|
|
29
41
|
sessionId: Buffer;
|
|
30
|
-
/** The raw ClientHello handshake message (without record header) for
|
|
31
|
-
* transcript hashing. */
|
|
32
42
|
handshakeMessage: Buffer;
|
|
33
43
|
}
|
|
34
44
|
/**
|
|
35
|
-
*
|
|
45
|
+
* Constructs a binary TLS 1.3 ClientHello record that mirrors the exact byte
|
|
46
|
+
* structure produced by the given browser profile, including GREASE injection,
|
|
47
|
+
* key share generation, and extension ordering.
|
|
48
|
+
*
|
|
49
|
+
* @param {BrowserProfile} profile - The browser profile whose TLS fingerprint to replicate.
|
|
50
|
+
* @param {string} hostname - The SNI hostname to include in the server_name extension.
|
|
51
|
+
* @returns {ClientHelloResult} The encoded record alongside key material needed for the handshake.
|
|
36
52
|
*/
|
|
37
53
|
export declare function buildClientHello(profile: BrowserProfile, hostname: string): ClientHelloResult;
|
|
38
54
|
//# sourceMappingURL=client-hello.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-hello.d.ts","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client-hello.d.ts","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,6BAA6B,CAAC;AAMnF;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CA8B7D;AAiBD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GACf,iBAAiB,CA6EnB"}
|
|
@@ -1,23 +1,16 @@
|
|
|
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
1
|
import { randomBytes, createECDH, generateKeyPairSync } from 'node:crypto';
|
|
12
2
|
import { BufferWriter } from '../../utils/buffer-writer.js';
|
|
13
3
|
import { RecordType, HandshakeType, ExtensionType, GREASE_VALUES, NamedGroup, } from '../constants.js';
|
|
14
|
-
// ---- GREASE ----
|
|
15
|
-
/** Pick a random GREASE value. */
|
|
16
4
|
function randomGrease() {
|
|
17
5
|
return GREASE_VALUES[Math.floor(Math.random() * GREASE_VALUES.length)];
|
|
18
6
|
}
|
|
19
7
|
/**
|
|
20
|
-
*
|
|
8
|
+
* Generates an ephemeral key pair for the specified named group. Supports
|
|
9
|
+
* X25519, SECP256R1, SECP384R1, and SECP521R1.
|
|
10
|
+
*
|
|
11
|
+
* @param {number} group - Named group code from the {@link NamedGroup} enum.
|
|
12
|
+
* @returns {KeyShareEntry} The generated key pair with group identifier.
|
|
13
|
+
* @throws {Error} If the specified group is not supported.
|
|
21
14
|
*/
|
|
22
15
|
export function generateKeyShare(group) {
|
|
23
16
|
switch (group) {
|
|
@@ -25,9 +18,7 @@ export function generateKeyShare(group) {
|
|
|
25
18
|
const kp = generateKeyPairSync('x25519');
|
|
26
19
|
const pub = kp.publicKey.export({ type: 'spki', format: 'der' });
|
|
27
20
|
const priv = kp.privateKey.export({ type: 'pkcs8', format: 'der' });
|
|
28
|
-
// X25519 public key is the last 32 bytes of the SPKI DER
|
|
29
21
|
const publicKey = Buffer.from(pub.subarray(pub.length - 32));
|
|
30
|
-
// X25519 private key is the last 32 bytes of the PKCS8 DER
|
|
31
22
|
const privateKey = Buffer.from(priv.subarray(priv.length - 32));
|
|
32
23
|
return { group, publicKey, privateKey };
|
|
33
24
|
}
|
|
@@ -51,10 +42,8 @@ export function generateKeyShare(group) {
|
|
|
51
42
|
throw new Error(`Unsupported key share group: 0x${group.toString(16)}`);
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
|
-
// ---- Key share extension data builder ----
|
|
55
45
|
function buildKeyShareExtensionData(keyShares) {
|
|
56
46
|
const w = new BufferWriter(256);
|
|
57
|
-
// client_shares length placeholder
|
|
58
47
|
const lenReserve = w.reserve(2);
|
|
59
48
|
const startPos = w.position;
|
|
60
49
|
for (const ks of keyShares) {
|
|
@@ -66,56 +55,50 @@ function buildKeyShareExtensionData(keyShares) {
|
|
|
66
55
|
return w.toBuffer();
|
|
67
56
|
}
|
|
68
57
|
/**
|
|
69
|
-
*
|
|
58
|
+
* Constructs a binary TLS 1.3 ClientHello record that mirrors the exact byte
|
|
59
|
+
* structure produced by the given browser profile, including GREASE injection,
|
|
60
|
+
* key share generation, and extension ordering.
|
|
61
|
+
*
|
|
62
|
+
* @param {BrowserProfile} profile - The browser profile whose TLS fingerprint to replicate.
|
|
63
|
+
* @param {string} hostname - The SNI hostname to include in the server_name extension.
|
|
64
|
+
* @returns {ClientHelloResult} The encoded record alongside key material needed for the handshake.
|
|
70
65
|
*/
|
|
71
66
|
export function buildClientHello(profile, hostname) {
|
|
72
67
|
const tlsProfile = profile.tls;
|
|
73
|
-
// Generate cryptographic material
|
|
74
68
|
const clientRandom = randomBytes(32);
|
|
75
69
|
const sessionId = tlsProfile.randomSessionId ? randomBytes(32) : Buffer.alloc(0);
|
|
76
70
|
const keyShares = tlsProfile.keyShareGroups.map(generateKeyShare);
|
|
77
|
-
// Pick GREASE values (reuse same value per category for consistency)
|
|
78
71
|
const greaseCipher = tlsProfile.grease ? randomGrease() : 0;
|
|
79
72
|
const greaseExt = tlsProfile.grease ? randomGrease() : 0;
|
|
80
73
|
const greaseGroup = tlsProfile.grease ? randomGrease() : 0;
|
|
81
74
|
const greaseVersion = tlsProfile.grease ? randomGrease() : 0;
|
|
82
|
-
// ---- Build ClientHello body ----
|
|
83
75
|
const body = new BufferWriter(4096);
|
|
84
|
-
// client_version
|
|
85
76
|
body.writeUInt16(tlsProfile.clientVersion);
|
|
86
|
-
// random (32 bytes)
|
|
87
77
|
body.writeBytes(clientRandom);
|
|
88
|
-
// session_id
|
|
89
78
|
body.writeUInt8(sessionId.length);
|
|
90
79
|
if (sessionId.length > 0)
|
|
91
80
|
body.writeBytes(sessionId);
|
|
92
|
-
// cipher_suites
|
|
93
81
|
const ciphers = tlsProfile.grease
|
|
94
82
|
? [greaseCipher, ...tlsProfile.cipherSuites]
|
|
95
83
|
: [...tlsProfile.cipherSuites];
|
|
96
84
|
body.writeUInt16(ciphers.length * 2);
|
|
97
85
|
for (const c of ciphers)
|
|
98
86
|
body.writeUInt16(c);
|
|
99
|
-
// compression_methods
|
|
100
87
|
body.writeUInt8(tlsProfile.compressionMethods.length);
|
|
101
88
|
for (const m of tlsProfile.compressionMethods)
|
|
102
89
|
body.writeUInt8(m);
|
|
103
|
-
// ---- Extensions ----
|
|
104
90
|
const extWriter = new BufferWriter(4096);
|
|
105
|
-
// If GREASE is enabled, prepend a GREASE extension
|
|
106
91
|
if (tlsProfile.grease) {
|
|
107
92
|
extWriter.writeUInt16(greaseExt);
|
|
108
93
|
extWriter.writeUInt16(1);
|
|
109
94
|
extWriter.writeUInt8(0);
|
|
110
95
|
}
|
|
111
|
-
// Write each extension from the profile in exact order
|
|
112
96
|
for (const extDef of tlsProfile.extensions) {
|
|
113
97
|
writeExtension(extWriter, extDef, hostname, keyShares, tlsProfile, {
|
|
114
98
|
greaseGroup,
|
|
115
99
|
greaseVersion,
|
|
116
100
|
});
|
|
117
101
|
}
|
|
118
|
-
// If GREASE is enabled, append a GREASE extension at end
|
|
119
102
|
if (tlsProfile.grease) {
|
|
120
103
|
const lastGrease = randomGrease();
|
|
121
104
|
extWriter.writeUInt16(lastGrease);
|
|
@@ -126,13 +109,11 @@ export function buildClientHello(profile, hostname) {
|
|
|
126
109
|
body.writeUInt16(extBytes.length);
|
|
127
110
|
body.writeBytes(extBytes);
|
|
128
111
|
const clientHelloBody = body.toBuffer();
|
|
129
|
-
// ---- Wrap in handshake header ----
|
|
130
112
|
const handshake = new BufferWriter(4 + clientHelloBody.length);
|
|
131
113
|
handshake.writeUInt8(HandshakeType.CLIENT_HELLO);
|
|
132
114
|
handshake.writeUInt24(clientHelloBody.length);
|
|
133
115
|
handshake.writeBytes(clientHelloBody);
|
|
134
116
|
const handshakeMessage = handshake.toBuffer();
|
|
135
|
-
// ---- Wrap in record ----
|
|
136
117
|
const record = new BufferWriter(5 + handshakeMessage.length);
|
|
137
118
|
record.writeUInt8(RecordType.HANDSHAKE);
|
|
138
119
|
record.writeUInt16(tlsProfile.recordVersion);
|
|
@@ -146,9 +127,7 @@ export function buildClientHello(profile, hostname) {
|
|
|
146
127
|
handshakeMessage,
|
|
147
128
|
};
|
|
148
129
|
}
|
|
149
|
-
// ---- Extension writer ----
|
|
150
130
|
function writeExtension(w, extDef, hostname, keyShares, tlsProfile, grease) {
|
|
151
|
-
// Special handling for key_share -- inject actual key material
|
|
152
131
|
if (extDef.type === ExtensionType.KEY_SHARE) {
|
|
153
132
|
const data = buildKeyShareExtensionData(keyShares);
|
|
154
133
|
w.writeUInt16(ExtensionType.KEY_SHARE);
|
|
@@ -156,7 +135,6 @@ function writeExtension(w, extDef, hostname, keyShares, tlsProfile, grease) {
|
|
|
156
135
|
w.writeBytes(data);
|
|
157
136
|
return;
|
|
158
137
|
}
|
|
159
|
-
// Special handling for supported_groups with GREASE
|
|
160
138
|
if (extDef.type === ExtensionType.SUPPORTED_GROUPS && tlsProfile.grease) {
|
|
161
139
|
const groups = [grease.greaseGroup, ...tlsProfile.supportedGroups];
|
|
162
140
|
const inner = new BufferWriter(2 + groups.length * 2);
|
|
@@ -169,7 +147,6 @@ function writeExtension(w, extDef, hostname, keyShares, tlsProfile, grease) {
|
|
|
169
147
|
w.writeBytes(data);
|
|
170
148
|
return;
|
|
171
149
|
}
|
|
172
|
-
// Special handling for supported_versions with GREASE
|
|
173
150
|
if (extDef.type === ExtensionType.SUPPORTED_VERSIONS && tlsProfile.grease) {
|
|
174
151
|
const versions = [grease.greaseVersion, ...tlsProfile.supportedVersions];
|
|
175
152
|
const inner = new BufferWriter(1 + versions.length * 2);
|
|
@@ -182,7 +159,6 @@ function writeExtension(w, extDef, hostname, keyShares, tlsProfile, grease) {
|
|
|
182
159
|
w.writeBytes(data);
|
|
183
160
|
return;
|
|
184
161
|
}
|
|
185
|
-
// General case
|
|
186
162
|
w.writeUInt16(extDef.type);
|
|
187
163
|
if (extDef.data) {
|
|
188
164
|
const data = extDef.data(hostname);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-hello.js","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client-hello.js","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AAGzB,SAAS,YAAY;IACnB,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAE,CAAC;AAC1E,CAAC;AAkBD;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACjE,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;YAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;YAChE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;QAC1C,CAAC;QACD,KAAK,UAAU,CAAC,SAAS,CAAC;QAC1B,KAAK,UAAU,CAAC,SAAS,CAAC;QAC1B,KAAK,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;YAC1B,MAAM,SAAS,GACb,KAAK,KAAK,UAAU,CAAC,SAAS;gBAC5B,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,SAAS;oBAC9B,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,WAAW,CAAC;YACpB,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YACnC,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO;gBACL,KAAK;gBACL,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC3C,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;aAC9C,CAAC;QACJ,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,SAA0B;IAC5D,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IAE5B,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAED,CAAC,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACjD,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;AACtB,CAAC;AAqBD;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAuB,EACvB,QAAgB;IAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAE/B,MAAM,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAElE,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7D,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAE9B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAErD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM;QAC/B,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC;QAC5C,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACjC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,kBAAkB;QAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAEzC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC3C,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE;YACjE,WAAW;YACX,aAAa;SACd,CAAC,CAAC;IACL,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;QAClC,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAClC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IACtC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAE1B,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC/D,SAAS,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACjD,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9C,SAAS,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IACtC,MAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAE9C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEpC,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;QACzB,SAAS;QACT,YAAY;QACZ,SAAS;QACT,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,CAAe,EACf,MAAuB,EACvB,QAAgB,EAChB,SAA0B,EAC1B,UAA4D,EAC5D,MAAsD;IAEtD,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,SAAS,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,gBAAgB,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtD,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC9C,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,kBAAkB,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAC1E,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAChD,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;AACH,CAAC"}
|