nlcurl 0.7.0 → 0.9.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 +149 -140
- package/dist/cache/groups.d.ts +75 -0
- package/dist/cache/groups.d.ts.map +1 -0
- package/dist/cache/groups.js +118 -0
- package/dist/cache/groups.js.map +1 -0
- package/dist/cache/no-vary-search.d.ts +33 -0
- package/dist/cache/no-vary-search.d.ts.map +1 -0
- package/dist/cache/no-vary-search.js +148 -0
- package/dist/cache/no-vary-search.js.map +1 -0
- package/dist/cache/range.d.ts +120 -0
- package/dist/cache/range.d.ts.map +1 -0
- package/dist/cache/range.js +193 -0
- package/dist/cache/range.js.map +1 -0
- package/dist/cache/store.d.ts +75 -37
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +217 -85
- package/dist/cache/store.js.map +1 -1
- package/dist/cache/types.d.ts +10 -39
- package/dist/cache/types.d.ts.map +1 -1
- package/dist/cli/args.d.ts +4 -37
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/index.d.ts +0 -5
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +14 -20
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +14 -20
- package/dist/cli/output.js.map +1 -1
- package/dist/cookies/jar.d.ts +41 -40
- package/dist/cookies/jar.d.ts.map +1 -1
- package/dist/cookies/jar.js +65 -42
- package/dist/cookies/jar.js.map +1 -1
- package/dist/cookies/parser.d.ts +13 -17
- package/dist/cookies/parser.d.ts.map +1 -1
- package/dist/cookies/parser.js +23 -15
- package/dist/cookies/parser.js.map +1 -1
- package/dist/cookies/psl-data.d.ts +1 -1
- package/dist/cookies/psl-data.js +1 -1
- package/dist/cookies/public-suffix.d.ts +5 -27
- package/dist/cookies/public-suffix.d.ts.map +1 -1
- package/dist/cookies/public-suffix.js +5 -37
- package/dist/cookies/public-suffix.js.map +1 -1
- package/dist/core/auth.d.ts +61 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +159 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/client.d.ts +28 -40
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +31 -41
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.d.ts +64 -88
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +64 -88
- package/dist/core/errors.js.map +1 -1
- package/dist/core/request.d.ts +33 -113
- package/dist/core/request.d.ts.map +1 -1
- package/dist/core/response.d.ts +49 -66
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +45 -59
- package/dist/core/response.js.map +1 -1
- package/dist/core/session.d.ts +66 -78
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +136 -77
- package/dist/core/session.js.map +1 -1
- package/dist/core/validation.d.ts +58 -43
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +141 -56
- package/dist/core/validation.js.map +1 -1
- package/dist/dns/cache.d.ts +65 -0
- package/dist/dns/cache.d.ts.map +1 -0
- package/dist/dns/cache.js +119 -0
- package/dist/dns/cache.js.map +1 -0
- package/dist/dns/codec.d.ts +29 -19
- package/dist/dns/codec.d.ts.map +1 -1
- package/dist/dns/codec.js +73 -39
- package/dist/dns/codec.js.map +1 -1
- package/dist/dns/doh-resolver.d.ts +17 -31
- package/dist/dns/doh-resolver.d.ts.map +1 -1
- package/dist/dns/doh-resolver.js +47 -48
- package/dist/dns/doh-resolver.js.map +1 -1
- package/dist/dns/dot-resolver.d.ts +89 -0
- package/dist/dns/dot-resolver.d.ts.map +1 -0
- package/dist/dns/dot-resolver.js +166 -0
- package/dist/dns/dot-resolver.js.map +1 -0
- package/dist/dns/https-rr.d.ts +19 -30
- package/dist/dns/https-rr.d.ts.map +1 -1
- package/dist/dns/https-rr.js +22 -40
- package/dist/dns/https-rr.js.map +1 -1
- package/dist/dns/types.d.ts +31 -59
- package/dist/dns/types.d.ts.map +1 -1
- package/dist/dns/types.js +3 -14
- package/dist/dns/types.js.map +1 -1
- package/dist/fingerprints/akamai.d.ts +3 -11
- package/dist/fingerprints/akamai.d.ts.map +1 -1
- package/dist/fingerprints/akamai.js +3 -11
- package/dist/fingerprints/akamai.js.map +1 -1
- package/dist/fingerprints/database.d.ts +6 -14
- package/dist/fingerprints/database.d.ts.map +1 -1
- package/dist/fingerprints/database.js +6 -14
- package/dist/fingerprints/database.js.map +1 -1
- package/dist/fingerprints/extensions.d.ts +56 -71
- package/dist/fingerprints/extensions.d.ts.map +1 -1
- package/dist/fingerprints/extensions.js +58 -71
- package/dist/fingerprints/extensions.js.map +1 -1
- package/dist/fingerprints/ja3.d.ts +12 -30
- package/dist/fingerprints/ja3.d.ts.map +1 -1
- package/dist/fingerprints/ja3.js +12 -30
- package/dist/fingerprints/ja3.js.map +1 -1
- package/dist/fingerprints/ja4.d.ts +18 -0
- package/dist/fingerprints/ja4.d.ts.map +1 -0
- package/dist/fingerprints/ja4.js +81 -0
- package/dist/fingerprints/ja4.js.map +1 -0
- package/dist/fingerprints/profiles/chrome.d.ts +18 -21
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -1
- package/dist/fingerprints/profiles/chrome.js +35 -31
- package/dist/fingerprints/profiles/chrome.js.map +1 -1
- package/dist/fingerprints/profiles/edge.d.ts +7 -10
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -1
- package/dist/fingerprints/profiles/edge.js +7 -10
- package/dist/fingerprints/profiles/edge.js.map +1 -1
- package/dist/fingerprints/profiles/firefox.d.ts +8 -11
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -1
- package/dist/fingerprints/profiles/firefox.js +8 -11
- package/dist/fingerprints/profiles/firefox.js.map +1 -1
- package/dist/fingerprints/profiles/safari.d.ts +11 -14
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -1
- package/dist/fingerprints/profiles/safari.js +11 -14
- package/dist/fingerprints/profiles/safari.js.map +1 -1
- package/dist/fingerprints/profiles/tor.d.ts +5 -8
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -1
- package/dist/fingerprints/profiles/tor.js +5 -8
- package/dist/fingerprints/profiles/tor.js.map +1 -1
- package/dist/fingerprints/types.d.ts +42 -73
- package/dist/fingerprints/types.d.ts.map +1 -1
- package/dist/hsts/store.d.ts +19 -21
- package/dist/hsts/store.d.ts.map +1 -1
- package/dist/hsts/store.js +20 -28
- package/dist/hsts/store.js.map +1 -1
- package/dist/hsts/types.d.ts +10 -14
- package/dist/hsts/types.d.ts.map +1 -1
- package/dist/http/alt-svc.d.ts +27 -52
- package/dist/http/alt-svc.d.ts.map +1 -1
- package/dist/http/alt-svc.js +17 -67
- package/dist/http/alt-svc.js.map +1 -1
- package/dist/http/early-hints.d.ts +23 -0
- package/dist/http/early-hints.d.ts.map +1 -0
- package/dist/http/early-hints.js +33 -0
- package/dist/http/early-hints.js.map +1 -0
- package/dist/http/form-data.d.ts +17 -35
- package/dist/http/form-data.d.ts.map +1 -1
- package/dist/http/form-data.js +12 -34
- package/dist/http/form-data.js.map +1 -1
- package/dist/http/h1/client.d.ts +14 -26
- package/dist/http/h1/client.d.ts.map +1 -1
- package/dist/http/h1/client.js +14 -23
- package/dist/http/h1/client.js.map +1 -1
- package/dist/http/h1/encoder.d.ts +21 -17
- package/dist/http/h1/encoder.d.ts.map +1 -1
- package/dist/http/h1/encoder.js +56 -20
- package/dist/http/h1/encoder.js.map +1 -1
- package/dist/http/h1/parser.d.ts +23 -59
- package/dist/http/h1/parser.d.ts.map +1 -1
- package/dist/http/h1/parser.js +61 -55
- package/dist/http/h1/parser.js.map +1 -1
- package/dist/http/h2/client.d.ts +23 -59
- package/dist/http/h2/client.d.ts.map +1 -1
- package/dist/http/h2/client.js +107 -64
- package/dist/http/h2/client.js.map +1 -1
- package/dist/http/h2/frames.d.ts +53 -84
- package/dist/http/h2/frames.d.ts.map +1 -1
- package/dist/http/h2/frames.js +48 -76
- package/dist/http/h2/frames.js.map +1 -1
- package/dist/http/h2/hpack.d.ts +20 -36
- package/dist/http/h2/hpack.d.ts.map +1 -1
- package/dist/http/h2/hpack.js +41 -36
- package/dist/http/h2/hpack.js.map +1 -1
- package/dist/http/negotiator.d.ts +25 -38
- package/dist/http/negotiator.d.ts.map +1 -1
- package/dist/http/negotiator.js +17 -38
- package/dist/http/negotiator.js.map +1 -1
- package/dist/http/pool.d.ts +34 -64
- package/dist/http/pool.d.ts.map +1 -1
- package/dist/http/pool.js +22 -41
- package/dist/http/pool.js.map +1 -1
- package/dist/http/resumable-upload.d.ts +76 -0
- package/dist/http/resumable-upload.d.ts.map +1 -0
- package/dist/http/resumable-upload.js +104 -0
- package/dist/http/resumable-upload.js.map +1 -0
- package/dist/http/trailers.d.ts +29 -0
- package/dist/http/trailers.d.ts.map +1 -0
- package/dist/http/trailers.js +57 -0
- package/dist/http/trailers.js.map +1 -0
- package/dist/index.d.ts +24 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/middleware/circuit-breaker.d.ts +44 -0
- package/dist/middleware/circuit-breaker.d.ts.map +1 -0
- package/dist/middleware/circuit-breaker.js +96 -0
- package/dist/middleware/circuit-breaker.js.map +1 -0
- package/dist/middleware/interceptor.d.ts +13 -32
- package/dist/middleware/interceptor.d.ts.map +1 -1
- package/dist/middleware/interceptor.js +11 -16
- package/dist/middleware/interceptor.js.map +1 -1
- package/dist/middleware/rate-limiter.d.ts +8 -17
- package/dist/middleware/rate-limiter.d.ts.map +1 -1
- package/dist/middleware/rate-limiter.js +11 -12
- package/dist/middleware/rate-limiter.js.map +1 -1
- package/dist/middleware/retry-after.d.ts +15 -0
- package/dist/middleware/retry-after.d.ts.map +1 -0
- package/dist/middleware/retry-after.js +36 -0
- package/dist/middleware/retry-after.js.map +1 -0
- package/dist/middleware/retry.d.ts +9 -18
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +12 -9
- package/dist/middleware/retry.js.map +1 -1
- package/dist/proxy/auth.d.ts +73 -0
- package/dist/proxy/auth.d.ts.map +1 -0
- package/dist/proxy/auth.js +129 -0
- package/dist/proxy/auth.js.map +1 -0
- package/dist/proxy/env-proxy.d.ts +5 -15
- package/dist/proxy/env-proxy.d.ts.map +1 -1
- package/dist/proxy/env-proxy.js +5 -23
- package/dist/proxy/env-proxy.js.map +1 -1
- package/dist/proxy/http-proxy.d.ts +12 -19
- package/dist/proxy/http-proxy.d.ts.map +1 -1
- package/dist/proxy/http-proxy.js +5 -8
- package/dist/proxy/http-proxy.js.map +1 -1
- package/dist/proxy/socks.d.ts +13 -20
- package/dist/proxy/socks.d.ts.map +1 -1
- package/dist/proxy/socks.js +8 -10
- package/dist/proxy/socks.js.map +1 -1
- package/dist/sse/parser.d.ts +16 -37
- package/dist/sse/parser.d.ts.map +1 -1
- package/dist/sse/parser.js +31 -28
- package/dist/sse/parser.js.map +1 -1
- package/dist/tls/constants.d.ts +21 -72
- package/dist/tls/constants.d.ts.map +1 -1
- package/dist/tls/constants.js +21 -72
- package/dist/tls/constants.js.map +1 -1
- package/dist/tls/ct.d.ts +78 -0
- package/dist/tls/ct.d.ts.map +1 -0
- package/dist/tls/ct.js +175 -0
- package/dist/tls/ct.js.map +1 -0
- package/dist/tls/early-data.d.ts +45 -0
- package/dist/tls/early-data.d.ts.map +1 -0
- package/dist/tls/early-data.js +46 -0
- package/dist/tls/early-data.js.map +1 -0
- package/dist/tls/ech.d.ts +68 -85
- package/dist/tls/ech.d.ts.map +1 -1
- package/dist/tls/ech.js +54 -102
- package/dist/tls/ech.js.map +1 -1
- package/dist/tls/keylog.d.ts +34 -0
- package/dist/tls/keylog.d.ts.map +1 -0
- package/dist/tls/keylog.js +64 -0
- package/dist/tls/keylog.js.map +1 -0
- package/dist/tls/node-engine.d.ts +10 -17
- package/dist/tls/node-engine.d.ts.map +1 -1
- package/dist/tls/node-engine.js +41 -18
- package/dist/tls/node-engine.js.map +1 -1
- package/dist/tls/ocsp.d.ts +55 -0
- package/dist/tls/ocsp.d.ts.map +1 -0
- package/dist/tls/ocsp.js +131 -0
- package/dist/tls/ocsp.js.map +1 -0
- package/dist/tls/pin-verification.d.ts +5 -4
- package/dist/tls/pin-verification.d.ts.map +1 -1
- package/dist/tls/pin-verification.js +5 -11
- package/dist/tls/pin-verification.js.map +1 -1
- package/dist/tls/session-cache.d.ts +27 -39
- package/dist/tls/session-cache.d.ts.map +1 -1
- package/dist/tls/session-cache.js +20 -24
- package/dist/tls/session-cache.js.map +1 -1
- package/dist/tls/stealth/client-hello.d.ts +26 -45
- package/dist/tls/stealth/client-hello.d.ts.map +1 -1
- package/dist/tls/stealth/client-hello.js +15 -31
- package/dist/tls/stealth/client-hello.js.map +1 -1
- package/dist/tls/stealth/engine.d.ts +10 -15
- package/dist/tls/stealth/engine.d.ts.map +1 -1
- package/dist/tls/stealth/engine.js +98 -18
- package/dist/tls/stealth/engine.js.map +1 -1
- package/dist/tls/stealth/handshake.d.ts +32 -31
- package/dist/tls/stealth/handshake.d.ts.map +1 -1
- package/dist/tls/stealth/handshake.js +74 -47
- package/dist/tls/stealth/handshake.js.map +1 -1
- package/dist/tls/stealth/key-schedule.d.ts +81 -86
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -1
- package/dist/tls/stealth/key-schedule.js +70 -58
- package/dist/tls/stealth/key-schedule.js.map +1 -1
- package/dist/tls/stealth/record-layer.d.ts +52 -75
- package/dist/tls/stealth/record-layer.d.ts.map +1 -1
- package/dist/tls/stealth/record-layer.js +47 -63
- package/dist/tls/stealth/record-layer.js.map +1 -1
- package/dist/tls/stealth/tls12-handshake.d.ts +16 -0
- package/dist/tls/stealth/tls12-handshake.d.ts.map +1 -1
- package/dist/tls/stealth/tls12-handshake.js +10 -2
- package/dist/tls/stealth/tls12-handshake.js.map +1 -1
- package/dist/tls/types.d.ts +46 -60
- package/dist/tls/types.d.ts.map +1 -1
- package/dist/utils/buffer-reader.d.ts +26 -81
- package/dist/utils/buffer-reader.d.ts.map +1 -1
- package/dist/utils/buffer-reader.js +26 -81
- package/dist/utils/buffer-reader.js.map +1 -1
- package/dist/utils/buffer-writer.d.ts +30 -66
- package/dist/utils/buffer-writer.d.ts.map +1 -1
- package/dist/utils/buffer-writer.js +30 -66
- package/dist/utils/buffer-writer.js.map +1 -1
- package/dist/utils/compression.d.ts +18 -0
- package/dist/utils/compression.d.ts.map +1 -0
- package/dist/utils/compression.js +34 -0
- package/dist/utils/compression.js.map +1 -0
- package/dist/utils/dictionary-transport.d.ts +97 -0
- package/dist/utils/dictionary-transport.d.ts.map +1 -0
- package/dist/utils/dictionary-transport.js +171 -0
- package/dist/utils/dictionary-transport.js.map +1 -0
- package/dist/utils/encoding.d.ts +12 -30
- package/dist/utils/encoding.d.ts.map +1 -1
- package/dist/utils/encoding.js +15 -46
- package/dist/utils/encoding.js.map +1 -1
- package/dist/utils/happy-eyeballs.d.ts +18 -8
- package/dist/utils/happy-eyeballs.d.ts.map +1 -1
- package/dist/utils/happy-eyeballs.js +19 -27
- package/dist/utils/happy-eyeballs.js.map +1 -1
- package/dist/utils/logger.d.ts +54 -81
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +92 -64
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/tcp-fast-open.d.ts +30 -0
- package/dist/utils/tcp-fast-open.d.ts.map +1 -0
- package/dist/utils/tcp-fast-open.js +36 -0
- package/dist/utils/tcp-fast-open.js.map +1 -0
- package/dist/utils/url.d.ts +18 -25
- package/dist/utils/url.d.ts.map +1 -1
- package/dist/utils/url.js +18 -25
- package/dist/utils/url.js.map +1 -1
- package/dist/ws/client.d.ts +35 -53
- package/dist/ws/client.d.ts.map +1 -1
- package/dist/ws/client.js +96 -38
- package/dist/ws/client.js.map +1 -1
- package/dist/ws/frame.d.ts +24 -41
- package/dist/ws/frame.d.ts.map +1 -1
- package/dist/ws/frame.js +26 -33
- package/dist/ws/frame.js.map +1 -1
- package/dist/ws/permessage-deflate.d.ts +23 -28
- package/dist/ws/permessage-deflate.d.ts.map +1 -1
- package/dist/ws/permessage-deflate.js +18 -26
- package/dist/ws/permessage-deflate.js.map +1 -1
- package/package.json +2 -2
- package/dist/http/h3/detection.d.ts +0 -17
- package/dist/http/h3/detection.d.ts.map +0 -1
- package/dist/http/h3/detection.js +0 -59
- package/dist/http/h3/detection.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** OCSP response status codes (RFC 6960). */
|
|
2
|
+
export declare enum OCSPResponseStatus {
|
|
3
|
+
SUCCESSFUL = 0,
|
|
4
|
+
MALFORMED_REQUEST = 1,
|
|
5
|
+
INTERNAL_ERROR = 2,
|
|
6
|
+
TRY_LATER = 3,
|
|
7
|
+
SIG_REQUIRED = 5,
|
|
8
|
+
UNAUTHORIZED = 6
|
|
9
|
+
}
|
|
10
|
+
/** Certificate revocation status from an OCSP response. */
|
|
11
|
+
export declare enum OCSPCertStatus {
|
|
12
|
+
GOOD = 0,
|
|
13
|
+
REVOKED = 1,
|
|
14
|
+
UNKNOWN = 2
|
|
15
|
+
}
|
|
16
|
+
/** Parsed result of an OCSP response. */
|
|
17
|
+
export interface OCSPResult {
|
|
18
|
+
/** Overall OCSP response status. */
|
|
19
|
+
status: OCSPResponseStatus;
|
|
20
|
+
/** Revocation status of the queried certificate. */
|
|
21
|
+
certStatus?: OCSPCertStatus;
|
|
22
|
+
/** Start of the validity window for this response. */
|
|
23
|
+
thisUpdate?: Date;
|
|
24
|
+
/** End of the validity window for this response. */
|
|
25
|
+
nextUpdate?: Date;
|
|
26
|
+
/** Time when the OCSP responder produced this response. */
|
|
27
|
+
producedAt?: Date;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse a DER-encoded OCSP response.
|
|
31
|
+
*
|
|
32
|
+
* @param {Buffer} derResponse - Raw DER bytes.
|
|
33
|
+
* @returns {OCSPResult} Parsed OCSP result.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseOCSPResponse(derResponse: Buffer): OCSPResult;
|
|
36
|
+
/**
|
|
37
|
+
* Check whether an OCSP result indicates the certificate is valid.
|
|
38
|
+
*
|
|
39
|
+
* @param {OCSPResult} result - Parsed OCSP result.
|
|
40
|
+
* @returns {boolean} `false` only if the certificate is explicitly revoked.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isOCSPValid(result: OCSPResult): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Validate OCSP stapling on a TLS socket.
|
|
45
|
+
*
|
|
46
|
+
* @param {{ once(event: string, handler: (...args: any[]) => void): void }} socket - Socket emitter that fires an `"OCSPResponse"` event.
|
|
47
|
+
* @param {{ timeout?: number }} [options] - Optional timeout configuration.
|
|
48
|
+
* @returns {Promise<OCSPResult|undefined>} Parsed OCSP result, or `undefined` if no stapled response.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateOCSPStapling(socket: {
|
|
51
|
+
once(event: string, handler: (...args: any[]) => void): void;
|
|
52
|
+
}, options?: {
|
|
53
|
+
timeout?: number;
|
|
54
|
+
}): Promise<OCSPResult | undefined>;
|
|
55
|
+
//# sourceMappingURL=ocsp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocsp.d.ts","sourceRoot":"","sources":["../../src/tls/ocsp.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,oBAAY,kBAAkB;IAC5B,UAAU,IAAI;IACd,iBAAiB,IAAI;IACrB,cAAc,IAAI;IAClB,SAAS,IAAI;IACb,YAAY,IAAI;IAChB,YAAY,IAAI;CACjB;AAED,2DAA2D;AAC3D,oBAAY,cAAc;IACxB,IAAI,IAAI;IACR,OAAO,IAAI;IACX,OAAO,IAAI;CACZ;AAED,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,oDAAoD;IACpD,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,sDAAsD;IACtD,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,oDAAoD;IACpD,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAuCjE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAQvD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAoB9K"}
|
package/dist/tls/ocsp.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/** OCSP response status codes (RFC 6960). */
|
|
2
|
+
export var OCSPResponseStatus;
|
|
3
|
+
(function (OCSPResponseStatus) {
|
|
4
|
+
OCSPResponseStatus[OCSPResponseStatus["SUCCESSFUL"] = 0] = "SUCCESSFUL";
|
|
5
|
+
OCSPResponseStatus[OCSPResponseStatus["MALFORMED_REQUEST"] = 1] = "MALFORMED_REQUEST";
|
|
6
|
+
OCSPResponseStatus[OCSPResponseStatus["INTERNAL_ERROR"] = 2] = "INTERNAL_ERROR";
|
|
7
|
+
OCSPResponseStatus[OCSPResponseStatus["TRY_LATER"] = 3] = "TRY_LATER";
|
|
8
|
+
OCSPResponseStatus[OCSPResponseStatus["SIG_REQUIRED"] = 5] = "SIG_REQUIRED";
|
|
9
|
+
OCSPResponseStatus[OCSPResponseStatus["UNAUTHORIZED"] = 6] = "UNAUTHORIZED";
|
|
10
|
+
})(OCSPResponseStatus || (OCSPResponseStatus = {}));
|
|
11
|
+
/** Certificate revocation status from an OCSP response. */
|
|
12
|
+
export var OCSPCertStatus;
|
|
13
|
+
(function (OCSPCertStatus) {
|
|
14
|
+
OCSPCertStatus[OCSPCertStatus["GOOD"] = 0] = "GOOD";
|
|
15
|
+
OCSPCertStatus[OCSPCertStatus["REVOKED"] = 1] = "REVOKED";
|
|
16
|
+
OCSPCertStatus[OCSPCertStatus["UNKNOWN"] = 2] = "UNKNOWN";
|
|
17
|
+
})(OCSPCertStatus || (OCSPCertStatus = {}));
|
|
18
|
+
/**
|
|
19
|
+
* Parse a DER-encoded OCSP response.
|
|
20
|
+
*
|
|
21
|
+
* @param {Buffer} derResponse - Raw DER bytes.
|
|
22
|
+
* @returns {OCSPResult} Parsed OCSP result.
|
|
23
|
+
*/
|
|
24
|
+
export function parseOCSPResponse(derResponse) {
|
|
25
|
+
if (!derResponse || derResponse.length < 3) {
|
|
26
|
+
return { status: OCSPResponseStatus.MALFORMED_REQUEST };
|
|
27
|
+
}
|
|
28
|
+
let offset = 0;
|
|
29
|
+
if (derResponse[offset] !== 0x30) {
|
|
30
|
+
return { status: OCSPResponseStatus.MALFORMED_REQUEST };
|
|
31
|
+
}
|
|
32
|
+
offset++;
|
|
33
|
+
const { value: outerLen, bytesRead: outerLenBytes } = readASN1Length(derResponse, offset);
|
|
34
|
+
if (outerLen === -1)
|
|
35
|
+
return { status: OCSPResponseStatus.MALFORMED_REQUEST };
|
|
36
|
+
offset += outerLenBytes;
|
|
37
|
+
if (derResponse[offset] !== 0x0a) {
|
|
38
|
+
return { status: OCSPResponseStatus.MALFORMED_REQUEST };
|
|
39
|
+
}
|
|
40
|
+
offset++;
|
|
41
|
+
const statusLen = derResponse[offset];
|
|
42
|
+
offset++;
|
|
43
|
+
if (statusLen !== 1 || offset >= derResponse.length) {
|
|
44
|
+
return { status: OCSPResponseStatus.MALFORMED_REQUEST };
|
|
45
|
+
}
|
|
46
|
+
const responseStatus = derResponse[offset];
|
|
47
|
+
offset++;
|
|
48
|
+
if (responseStatus !== OCSPResponseStatus.SUCCESSFUL) {
|
|
49
|
+
return { status: responseStatus };
|
|
50
|
+
}
|
|
51
|
+
const result = { status: responseStatus };
|
|
52
|
+
const certStatusResult = findCertStatus(derResponse, offset);
|
|
53
|
+
if (certStatusResult !== undefined) {
|
|
54
|
+
result.certStatus = certStatusResult;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check whether an OCSP result indicates the certificate is valid.
|
|
60
|
+
*
|
|
61
|
+
* @param {OCSPResult} result - Parsed OCSP result.
|
|
62
|
+
* @returns {boolean} `false` only if the certificate is explicitly revoked.
|
|
63
|
+
*/
|
|
64
|
+
export function isOCSPValid(result) {
|
|
65
|
+
if (result.status !== OCSPResponseStatus.SUCCESSFUL) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
if (result.certStatus === OCSPCertStatus.REVOKED) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Validate OCSP stapling on a TLS socket.
|
|
75
|
+
*
|
|
76
|
+
* @param {{ once(event: string, handler: (...args: any[]) => void): void }} socket - Socket emitter that fires an `"OCSPResponse"` event.
|
|
77
|
+
* @param {{ timeout?: number }} [options] - Optional timeout configuration.
|
|
78
|
+
* @returns {Promise<OCSPResult|undefined>} Parsed OCSP result, or `undefined` if no stapled response.
|
|
79
|
+
*/
|
|
80
|
+
export function validateOCSPStapling(socket, options) {
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
const timeout = options?.timeout ?? 5000;
|
|
83
|
+
let timer;
|
|
84
|
+
const onResponse = (response) => {
|
|
85
|
+
if (timer)
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
if (!response || response.length === 0) {
|
|
88
|
+
resolve(undefined);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
resolve(parseOCSPResponse(response));
|
|
92
|
+
};
|
|
93
|
+
socket.once("OCSPResponse", onResponse);
|
|
94
|
+
timer = setTimeout(() => {
|
|
95
|
+
resolve(undefined);
|
|
96
|
+
}, timeout);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function readASN1Length(buf, offset) {
|
|
100
|
+
if (offset >= buf.length)
|
|
101
|
+
return { value: -1, bytesRead: 0 };
|
|
102
|
+
const first = buf[offset];
|
|
103
|
+
if (first < 0x80) {
|
|
104
|
+
return { value: first, bytesRead: 1 };
|
|
105
|
+
}
|
|
106
|
+
const numBytes = first & 0x7f;
|
|
107
|
+
if (numBytes === 0 || numBytes > 4 || offset + numBytes >= buf.length) {
|
|
108
|
+
return { value: -1, bytesRead: 0 };
|
|
109
|
+
}
|
|
110
|
+
let value = 0;
|
|
111
|
+
for (let i = 0; i < numBytes; i++) {
|
|
112
|
+
value = (value << 8) | buf[offset + 1 + i];
|
|
113
|
+
}
|
|
114
|
+
return { value, bytesRead: 1 + numBytes };
|
|
115
|
+
}
|
|
116
|
+
function findCertStatus(buf, startOffset) {
|
|
117
|
+
for (let i = startOffset; i < buf.length - 2; i++) {
|
|
118
|
+
const tag = buf[i];
|
|
119
|
+
if (tag === 0x80 && buf[i + 1] === 0x00) {
|
|
120
|
+
return OCSPCertStatus.GOOD;
|
|
121
|
+
}
|
|
122
|
+
if (tag === 0xa1) {
|
|
123
|
+
return OCSPCertStatus.REVOKED;
|
|
124
|
+
}
|
|
125
|
+
if (tag === 0x82 && buf[i + 1] === 0x00) {
|
|
126
|
+
return OCSPCertStatus.UNKNOWN;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=ocsp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocsp.js","sourceRoot":"","sources":["../../src/tls/ocsp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* one of the supplied pins. Throws {@link TLSError} on mismatch.
|
|
2
|
+
* Verify that a certificate's SPKI hash matches at least one expected pin.
|
|
4
3
|
*
|
|
5
|
-
* @
|
|
6
|
-
*
|
|
4
|
+
* Throws a {@link TLSError} if no pin matches.
|
|
5
|
+
*
|
|
6
|
+
* @param {Buffer} certDer - DER-encoded X.509 certificate.
|
|
7
|
+
* @param {string|string[]} pins - One or more `sha256//` base64-encoded SPKI pins.
|
|
7
8
|
*/
|
|
8
9
|
export declare function verifyPinnedPublicKey(certDer: Buffer, pins: string | string[]): void;
|
|
9
10
|
//# sourceMappingURL=pin-verification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin-verification.d.ts","sourceRoot":"","sources":["../../src/tls/pin-verification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pin-verification.d.ts","sourceRoot":"","sources":["../../src/tls/pin-verification.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiBpF"}
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Certificate public key pinning (RFC 7469 concept, curl-style format).
|
|
3
|
-
*
|
|
4
|
-
* Verifies that a server's leaf certificate matches one of a set of
|
|
5
|
-
* SHA-256 hashes computed over the DER-encoded Subject Public Key Info
|
|
6
|
-
* (SPKI). Pin format: `"sha256//base64hash"` (same as curl `--pinnedpubkey`).
|
|
7
|
-
*/
|
|
8
1
|
import { createHash, X509Certificate } from "node:crypto";
|
|
9
2
|
import { TLSError } from "../core/errors.js";
|
|
10
3
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
4
|
+
* Verify that a certificate's SPKI hash matches at least one expected pin.
|
|
5
|
+
*
|
|
6
|
+
* Throws a {@link TLSError} if no pin matches.
|
|
13
7
|
*
|
|
14
|
-
* @param certDer
|
|
15
|
-
* @param pins
|
|
8
|
+
* @param {Buffer} certDer - DER-encoded X.509 certificate.
|
|
9
|
+
* @param {string|string[]} pins - One or more `sha256//` base64-encoded SPKI pins.
|
|
16
10
|
*/
|
|
17
11
|
export function verifyPinnedPublicKey(certDer, pins) {
|
|
18
12
|
const pinArray = typeof pins === "string" ? [pins] : pins;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pin-verification.js","sourceRoot":"","sources":["../../src/tls/pin-verification.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pin-verification.js","sourceRoot":"","sources":["../../src/tls/pin-verification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,IAAuB;IAC5E,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAElC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,WAAW,IAAI,EAAE,CAAC;IAElC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACpC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAC9C,OAAO,GAAG,KAAK,OAAO,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,QAAQ,CAAC,oDAAoD,OAAO,EAAE,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
|
|
@@ -1,70 +1,58 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TLS session ticket cache for session resumption (RFC 5077 / RFC 8446 §4.6.1).
|
|
3
|
-
* Stores session tickets keyed by origin (`host:port`) and evicts expired
|
|
4
|
-
* entries automatically. Used by both {@link NodeTLSEngine} and
|
|
5
|
-
* {@link StealthTLSEngine} to enable 0-RTT and abbreviated handshakes.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* A cached TLS session ticket with its expiration metadata.
|
|
9
|
-
*
|
|
10
|
-
* @typedef {Object} SessionTicketEntry
|
|
11
|
-
* @property {Buffer} ticket - Opaque session ticket bytes.
|
|
12
|
-
* @property {number} expiresAt - Unix timestamp (ms) at which the ticket is no longer valid.
|
|
13
|
-
* @property {string} [alpn] - ALPN protocol negotiated during the original handshake.
|
|
14
|
-
*/
|
|
1
|
+
/** Cached TLS session ticket with expiry and ALPN metadata. */
|
|
15
2
|
export interface SessionTicketEntry {
|
|
3
|
+
/** Serialized session ticket bytes. */
|
|
16
4
|
ticket: Buffer;
|
|
5
|
+
/** Timestamp (ms since epoch) when this entry expires. */
|
|
17
6
|
expiresAt: number;
|
|
7
|
+
/** ALPN protocol negotiated during the original handshake. */
|
|
18
8
|
alpn?: string;
|
|
19
9
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Options for constructing a {@link TLSSessionCache}.
|
|
22
|
-
*
|
|
23
|
-
* @typedef {Object} SessionCacheOptions
|
|
24
|
-
* @property {number} [maxEntries=256] - Maximum number of tickets to store.
|
|
25
|
-
* @property {number} [defaultLifetimeMs=7200000] - Default ticket lifetime in ms when server doesn't specify.
|
|
26
|
-
*/
|
|
10
|
+
/** Configuration for the TLS session ticket cache. */
|
|
27
11
|
export interface SessionCacheOptions {
|
|
12
|
+
/** Maximum number of cached entries. */
|
|
28
13
|
maxEntries?: number;
|
|
14
|
+
/** Default ticket lifetime in milliseconds. */
|
|
29
15
|
defaultLifetimeMs?: number;
|
|
30
16
|
}
|
|
31
|
-
/**
|
|
32
|
-
* In-memory LRU cache for TLS session tickets. Thread-safe for single-threaded
|
|
33
|
-
* Node.js usage. Keys are `host:port` origin strings. Only valid (non-expired)
|
|
34
|
-
* tickets are returned on lookup.
|
|
35
|
-
*/
|
|
17
|
+
/** LRU cache for TLS session tickets enabling session resumption. */
|
|
36
18
|
export declare class TLSSessionCache {
|
|
37
19
|
private readonly maxEntries;
|
|
38
20
|
private readonly defaultLifetimeMs;
|
|
39
21
|
private readonly entries;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new session cache.
|
|
24
|
+
*
|
|
25
|
+
* @param {SessionCacheOptions} [options] - Cache size and lifetime configuration.
|
|
26
|
+
*/
|
|
40
27
|
constructor(options?: SessionCacheOptions);
|
|
41
28
|
/**
|
|
42
|
-
*
|
|
29
|
+
* Store a session ticket for the given origin.
|
|
43
30
|
*
|
|
44
|
-
* @param {string} origin
|
|
45
|
-
* @param {Buffer} ticket
|
|
46
|
-
* @param {number} [lifetimeMs] -
|
|
47
|
-
* @param {string} [alpn]
|
|
31
|
+
* @param {string} origin - Origin key (e.g. `"example.com:443"`).
|
|
32
|
+
* @param {Buffer} ticket - Serialized session ticket.
|
|
33
|
+
* @param {number} [lifetimeMs] - Optional custom lifetime in milliseconds.
|
|
34
|
+
* @param {string} [alpn] - Negotiated ALPN protocol.
|
|
48
35
|
*/
|
|
49
36
|
set(origin: string, ticket: Buffer, lifetimeMs?: number, alpn?: string): void;
|
|
50
37
|
/**
|
|
51
|
-
*
|
|
52
|
-
* Returns `undefined` if no ticket exists or the ticket has expired.
|
|
38
|
+
* Retrieve a cached session ticket.
|
|
53
39
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
40
|
+
* Expired entries are evicted automatically.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} origin - Origin key.
|
|
43
|
+
* @returns {SessionTicketEntry|undefined} Cached entry, or `undefined` if not found or expired.
|
|
56
44
|
*/
|
|
57
45
|
get(origin: string): SessionTicketEntry | undefined;
|
|
58
46
|
/**
|
|
59
|
-
*
|
|
47
|
+
* Remove a cached entry by origin.
|
|
60
48
|
*
|
|
61
49
|
* @param {string} origin - Origin key.
|
|
62
|
-
* @returns {boolean}
|
|
50
|
+
* @returns {boolean} `true` if an entry was removed.
|
|
63
51
|
*/
|
|
64
52
|
delete(origin: string): boolean;
|
|
65
|
-
/**
|
|
53
|
+
/** Remove all cached session tickets. */
|
|
66
54
|
clear(): void;
|
|
67
|
-
/**
|
|
55
|
+
/** Number of entries currently in the cache. */
|
|
68
56
|
get size(): number;
|
|
69
57
|
}
|
|
70
58
|
//# sourceMappingURL=session-cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cache.d.ts","sourceRoot":"","sources":["../../src/tls/session-cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session-cache.d.ts","sourceRoot":"","sources":["../../src/tls/session-cache.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qEAAqE;AACrE,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE;;;;OAIG;gBACS,OAAO,GAAE,mBAAwB;IAK7C;;;;;;;OAOG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAc7E;;;;;;;OAOG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAcnD;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI/B,yCAAyC;IACzC,KAAK,IAAI,IAAI;IAIb,gDAAgD;IAChD,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TLS session ticket cache for session resumption (RFC 5077 / RFC 8446 §4.6.1).
|
|
3
|
-
* Stores session tickets keyed by origin (`host:port`) and evicts expired
|
|
4
|
-
* entries automatically. Used by both {@link NodeTLSEngine} and
|
|
5
|
-
* {@link StealthTLSEngine} to enable 0-RTT and abbreviated handshakes.
|
|
6
|
-
*/
|
|
7
1
|
const DEFAULT_MAX_ENTRIES = 256;
|
|
8
2
|
const DEFAULT_LIFETIME_MS = 7200_000;
|
|
9
|
-
/**
|
|
10
|
-
* In-memory LRU cache for TLS session tickets. Thread-safe for single-threaded
|
|
11
|
-
* Node.js usage. Keys are `host:port` origin strings. Only valid (non-expired)
|
|
12
|
-
* tickets are returned on lookup.
|
|
13
|
-
*/
|
|
3
|
+
/** LRU cache for TLS session tickets enabling session resumption. */
|
|
14
4
|
export class TLSSessionCache {
|
|
15
5
|
maxEntries;
|
|
16
6
|
defaultLifetimeMs;
|
|
17
7
|
entries = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* Create a new session cache.
|
|
10
|
+
*
|
|
11
|
+
* @param {SessionCacheOptions} [options] - Cache size and lifetime configuration.
|
|
12
|
+
*/
|
|
18
13
|
constructor(options = {}) {
|
|
19
14
|
this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
20
15
|
this.defaultLifetimeMs = options.defaultLifetimeMs ?? DEFAULT_LIFETIME_MS;
|
|
21
16
|
}
|
|
22
17
|
/**
|
|
23
|
-
*
|
|
18
|
+
* Store a session ticket for the given origin.
|
|
24
19
|
*
|
|
25
|
-
* @param {string} origin
|
|
26
|
-
* @param {Buffer} ticket
|
|
27
|
-
* @param {number} [lifetimeMs] -
|
|
28
|
-
* @param {string} [alpn]
|
|
20
|
+
* @param {string} origin - Origin key (e.g. `"example.com:443"`).
|
|
21
|
+
* @param {Buffer} ticket - Serialized session ticket.
|
|
22
|
+
* @param {number} [lifetimeMs] - Optional custom lifetime in milliseconds.
|
|
23
|
+
* @param {string} [alpn] - Negotiated ALPN protocol.
|
|
29
24
|
*/
|
|
30
25
|
set(origin, ticket, lifetimeMs, alpn) {
|
|
31
26
|
if (this.entries.size >= this.maxEntries) {
|
|
@@ -41,11 +36,12 @@ export class TLSSessionCache {
|
|
|
41
36
|
});
|
|
42
37
|
}
|
|
43
38
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Returns `undefined` if no ticket exists or the ticket has expired.
|
|
39
|
+
* Retrieve a cached session ticket.
|
|
46
40
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
41
|
+
* Expired entries are evicted automatically.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} origin - Origin key.
|
|
44
|
+
* @returns {SessionTicketEntry|undefined} Cached entry, or `undefined` if not found or expired.
|
|
49
45
|
*/
|
|
50
46
|
get(origin) {
|
|
51
47
|
const entry = this.entries.get(origin);
|
|
@@ -60,19 +56,19 @@ export class TLSSessionCache {
|
|
|
60
56
|
return entry;
|
|
61
57
|
}
|
|
62
58
|
/**
|
|
63
|
-
*
|
|
59
|
+
* Remove a cached entry by origin.
|
|
64
60
|
*
|
|
65
61
|
* @param {string} origin - Origin key.
|
|
66
|
-
* @returns {boolean}
|
|
62
|
+
* @returns {boolean} `true` if an entry was removed.
|
|
67
63
|
*/
|
|
68
64
|
delete(origin) {
|
|
69
65
|
return this.entries.delete(origin);
|
|
70
66
|
}
|
|
71
|
-
/**
|
|
67
|
+
/** Remove all cached session tickets. */
|
|
72
68
|
clear() {
|
|
73
69
|
this.entries.clear();
|
|
74
70
|
}
|
|
75
|
-
/**
|
|
71
|
+
/** Number of entries currently in the cache. */
|
|
76
72
|
get size() {
|
|
77
73
|
return this.entries.size;
|
|
78
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cache.js","sourceRoot":"","sources":["../../src/tls/session-cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-cache.js","sourceRoot":"","sources":["../../src/tls/session-cache.ts"],"names":[],"mappings":"AAUA,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,mBAAmB,GAAG,QAAQ,CAAC;AAUrC,qEAAqE;AACrE,MAAM,OAAO,eAAe;IACT,UAAU,CAAS;IACnB,iBAAiB,CAAS;IAC1B,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEjE;;;;OAIG;IACH,YAAY,UAA+B,EAAE;QAC3C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAC5D,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,mBAAmB,CAAC;IAC5E,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,UAAmB,EAAE,IAAa;QACpE,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAChD,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;YACvB,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC;YAC9D,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAC,MAAc;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,MAAc;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,yCAAyC;IACzC,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -1,75 +1,56 @@
|
|
|
1
1
|
import type { BrowserProfile } from "../../fingerprints/types.js";
|
|
2
2
|
import type { ECHEncryptionParams } from "../ech.js";
|
|
3
|
-
/**
|
|
4
|
-
* An ephemeral key share generated for a specific named group, used during
|
|
5
|
-
* TLS 1.3 key exchange. Contains both the public key to advertise in the
|
|
6
|
-
* ClientHello and the private key required to compute the shared secret.
|
|
7
|
-
*
|
|
8
|
-
* @typedef {Object} KeyShareEntry
|
|
9
|
-
* @property {number} group - Named group code (e.g. `NamedGroup.X25519`).
|
|
10
|
-
* @property {Buffer} publicKey - Raw public key bytes to include in the key_share extension.
|
|
11
|
-
* @property {Buffer} privateKey - Raw private key bytes used for ECDH computation.
|
|
12
|
-
*/
|
|
3
|
+
/** Key exchange entry containing the group identifier and key material. */
|
|
13
4
|
export interface KeyShareEntry {
|
|
5
|
+
/** Named group identifier. */
|
|
14
6
|
group: number;
|
|
7
|
+
/** Public key bytes. */
|
|
15
8
|
publicKey: Buffer;
|
|
9
|
+
/** Private key bytes. */
|
|
16
10
|
privateKey: Buffer;
|
|
17
11
|
}
|
|
18
12
|
/**
|
|
19
|
-
*
|
|
20
|
-
* X25519, SECP256R1, SECP384R1, and SECP521R1.
|
|
21
|
-
*
|
|
22
|
-
* @param {number} group - Named group code from the {@link NamedGroup} enum.
|
|
23
|
-
* @returns {KeyShareEntry} The generated key pair with group identifier.
|
|
24
|
-
* @throws {Error} If the specified group is not supported.
|
|
25
|
-
*/
|
|
26
|
-
export declare function generateKeyShare(group: number): KeyShareEntry;
|
|
27
|
-
/**
|
|
28
|
-
* Carries the outputs of {@link buildClientHello} that must be retained
|
|
29
|
-
* for subsequent handshake processing.
|
|
13
|
+
* Generate a key pair for the specified TLS named group.
|
|
30
14
|
*
|
|
31
|
-
* @
|
|
32
|
-
* @
|
|
33
|
-
* @property {KeyShareEntry[]} keyShares - Generated key shares (private keys needed for key derivation).
|
|
34
|
-
* @property {Buffer} clientRandom - 32-byte client random included in the ClientHello body.
|
|
35
|
-
* @property {Buffer} sessionId - Legacy session ID bytes (may be empty).
|
|
36
|
-
* @property {Buffer} handshakeMessage - The raw handshake message body (used for transcript hashing).
|
|
15
|
+
* @param {number} group - Named group identifier (e.g. X25519, SECP256R1).
|
|
16
|
+
* @returns {KeyShareEntry} Key share entry with public and private key material.
|
|
37
17
|
*/
|
|
18
|
+
export declare function generateKeyShare(group: number): KeyShareEntry | null;
|
|
19
|
+
/** Result of building a TLS ClientHello message. */
|
|
38
20
|
export interface ClientHelloResult {
|
|
21
|
+
/** Complete TLS record containing the ClientHello. */
|
|
39
22
|
record: Buffer;
|
|
23
|
+
/** Generated key share entries. */
|
|
40
24
|
keyShares: KeyShareEntry[];
|
|
25
|
+
/** Client random bytes. */
|
|
41
26
|
clientRandom: Buffer;
|
|
27
|
+
/** Session ID bytes (may be empty). */
|
|
42
28
|
sessionId: Buffer;
|
|
29
|
+
/** Raw handshake message (without record layer). */
|
|
43
30
|
handshakeMessage: Buffer;
|
|
44
31
|
}
|
|
45
32
|
/**
|
|
46
|
-
*
|
|
47
|
-
* structure produced by the given browser profile, including GREASE injection,
|
|
48
|
-
* key share generation, and extension ordering.
|
|
33
|
+
* Build a TLS ClientHello record matching a browser fingerprint profile.
|
|
49
34
|
*
|
|
50
|
-
* @param {BrowserProfile} profile
|
|
51
|
-
* @param {string}
|
|
52
|
-
* @returns {ClientHelloResult}
|
|
35
|
+
* @param {BrowserProfile} profile - Browser profile with TLS extension ordering and cipher suites.
|
|
36
|
+
* @param {string} hostname - Server hostname for SNI.
|
|
37
|
+
* @returns {ClientHelloResult} ClientHello result with record bytes and key material.
|
|
53
38
|
*/
|
|
54
39
|
export declare function buildClientHello(profile: BrowserProfile, hostname: string): ClientHelloResult;
|
|
55
|
-
/**
|
|
56
|
-
* Result of building an ECH-encrypted ClientHello pair.
|
|
57
|
-
*/
|
|
40
|
+
/** Extended ClientHello result with Encrypted Client Hello inner message. */
|
|
58
41
|
export interface ClientHelloECHResult extends ClientHelloResult {
|
|
59
|
-
/**
|
|
42
|
+
/** Raw inner ClientHello handshake message before encryption. */
|
|
60
43
|
innerHandshakeMessage: Buffer;
|
|
61
|
-
/**
|
|
44
|
+
/** Client random used in the inner ClientHello. */
|
|
62
45
|
innerRandom: Buffer;
|
|
63
46
|
}
|
|
64
47
|
/**
|
|
65
|
-
*
|
|
66
|
-
* (with the encrypted inner ClientHello in the ECH extension) and the
|
|
67
|
-
* inner ClientHello needed for transcript computation upon acceptance.
|
|
48
|
+
* Build a TLS ClientHello with Encrypted Client Hello (ECH) wrapping.
|
|
68
49
|
*
|
|
69
|
-
* @param
|
|
70
|
-
* @param hostname
|
|
71
|
-
* @param echParams
|
|
72
|
-
* @returns
|
|
50
|
+
* @param {BrowserProfile} profile - Browser fingerprint profile.
|
|
51
|
+
* @param {string} hostname - True server hostname (encrypted in the inner ClientHello).
|
|
52
|
+
* @param {ECHEncryptionParams} echParams - ECH encryption parameters.
|
|
53
|
+
* @returns {ClientHelloECHResult} Extended result with both outer and inner handshake data.
|
|
73
54
|
*/
|
|
74
55
|
export declare function buildClientHelloWithECH(profile: BrowserProfile, hostname: string, echParams: ECHEncryptionParams): ClientHelloECHResult;
|
|
75
56
|
//# 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":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client-hello.d.ts","sourceRoot":"","sources":["../../../src/tls/stealth/client-hello.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAOrD,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAyBpE;AAiBD,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CA2E7F;AA6CD,6EAA6E;AAC7E,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,iEAAiE;IACjE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,oBAAoB,CA8DvI"}
|