visaljs 0.0.9 → 0.0.11
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 +12 -4
- package/THIRD_PARTY_LICENSES +31 -1
- package/cli.js +3745 -890
- package/node/include/js_node.h +12 -1
- package/node/prelude/_http_common.js +29 -0
- package/node/prelude/async_hooks.js +50 -11
- package/node/prelude/child_process.js +31 -4
- package/node/prelude/console.js +311 -143
- package/node/prelude/crypto.js +6 -4
- package/node/prelude/dgram.js +1169 -0
- package/node/prelude/diagnostics_channel.js +3 -1
- package/node/prelude/dns.js +250 -45
- package/node/prelude/dns_promises.js +8 -2
- package/node/prelude/fs_promises.js +9 -1
- package/node/prelude/http.js +405 -94
- package/node/prelude/https.js +13 -4
- package/node/prelude/internal/console_class.js +7 -0
- package/node/prelude/internal/console_global.js +25 -0
- package/node/prelude/internal/crypto/key_encryption.js +217 -0
- package/node/prelude/internal/crypto/keys.js +161 -26
- package/node/prelude/internal/crypto/random.js +24 -0
- package/node/prelude/internal/crypto/util.js +2 -1
- package/node/prelude/internal/crypto_x509.js +161 -0
- package/node/prelude/internal/dns_classes.js +6 -0
- package/node/prelude/internal/dns_resolver.js +371 -0
- package/node/prelude/internal/errors.js +9 -0
- package/node/prelude/internal/events_on.js +82 -37
- package/node/prelude/internal/features.js +8 -4
- package/node/prelude/internal/fs_filehandle.js +10 -4
- package/node/prelude/internal/http_chars.ts +22 -0
- package/node/prelude/internal/perf_histogram.js +1 -1
- package/node/prelude/internal/process_more.js +32 -17
- package/node/prelude/internal/process_signals.js +8 -2
- package/node/prelude/internal/punycode.ts +163 -0
- package/node/prelude/internal/readline.js +648 -274
- package/node/prelude/internal/readline_editor.js +1240 -0
- package/node/prelude/internal/string_width.js +43 -0
- package/node/prelude/internal/tls/common.js +145 -33
- package/node/prelude/internal/tls/wrap.js +182 -49
- package/node/prelude/internal/tls/x509.js +4 -1
- package/node/prelude/internal/udp.js +177 -0
- package/node/prelude/net.js +30 -14
- package/node/prelude/os.js +24 -6
- package/node/prelude/perf_hooks.js +37 -2
- package/node/prelude/punycode.js +2 -130
- package/node/prelude/readline.js +113 -4
- package/node/prelude/readline_promises.js +56 -32
- package/node/prelude/tls.js +21 -4
- package/node/prelude/util.js +3 -16
- package/node/src/host_dns.c +623 -0
- package/node/src/host_http.c +12 -0
- package/node/src/host_net.c +46 -0
- package/node/src/host_os.c +1 -6
- package/node/src/host_sys.c +79 -0
- package/node/src/host_udp.c +418 -0
- package/node/third_party/c-ares/LICENSE.md +24 -0
- package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
- package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
- package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
- package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
- package/node/third_party/c-ares/include/ares.h +1237 -0
- package/node/third_party/c-ares/include/ares_build.h +202 -0
- package/node/third_party/c-ares/include/ares_dns.h +127 -0
- package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
- package/node/third_party/c-ares/include/ares_nameser.h +510 -0
- package/node/third_party/c-ares/include/ares_version.h +47 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
- package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
- package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
- package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
- package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
- package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
- package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
- package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
- package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
- package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
- package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
- package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
- package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
- package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
- package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
- package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
- package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
- package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
- package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
- package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
- package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
- package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
- package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
- package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
- package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
- package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
- package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
- package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
- package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
- package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
- package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
- package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
- package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
- package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
- package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
- package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
- package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
- package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
- package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
- package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
- package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
- package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
- package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
- package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
- package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
- package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
- package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
- package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
- package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
- package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
- package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
- package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
- package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
- package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
- package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
- package/package.json +1 -1
- package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
- package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
- package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
- package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
- package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
- package/runtime/include/js_buffer.h +185 -0
- package/runtime/include/js_builtins.h +58 -0
- package/runtime/include/js_crypto.h +11 -0
- package/runtime/include/js_exception.h +3 -0
- package/runtime/include/js_function.h +1 -1
- package/runtime/include/js_gc.h +13 -10
- package/runtime/include/js_jobs.h +2 -0
- package/runtime/include/js_object.h +79 -3
- package/runtime/include/js_ops.h +27 -0
- package/runtime/include/js_runtime.h +1 -0
- package/runtime/include/js_web.h +0 -3
- package/runtime/include/jscontext.h +8 -0
- package/runtime/src/builtins.c +17 -4
- package/runtime/src/crypto_internal.h +1 -0
- package/runtime/src/crypto_subtle.c +66 -7
- package/runtime/src/crypto_tls.c +265 -19
- package/runtime/src/function.c +37 -10
- package/runtime/src/gc.c +76 -93
- package/runtime/src/inspect.c +18 -1
- package/runtime/src/iterator.c +5 -1
- package/runtime/src/jobs.c +37 -22
- package/runtime/src/object.c +91 -8
- package/runtime/src/os.c +16 -6
- package/runtime/src/os.h +2 -0
- package/runtime/src/process.c +97 -10
- package/runtime/src/typedarray.c +23 -0
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
// Ported from Node.js (Copyright Node.js contributors, MIT): node/third_party/nodejs/LICENSE.
|
|
10
10
|
import {
|
|
11
11
|
errnoName, netReadStart, netReadStop, netShutdown, netWrite, tlsExportKeyingMaterial, tlsFinished, tlsInfo, tlsNew, tlsPeerCerts,
|
|
12
|
-
tlsRootCertificates, tlsRun, tlsSession, tlsSetNoRenegotiation, tlsShutdown, tlsVerifyError,
|
|
12
|
+
tlsContextTicketKeys, tlsEnableKeylog, tlsRootCertificates, tlsRun, tlsSession, tlsSetMaxSendFragment, tlsSetNoRenegotiation, tlsShutdown, tlsTicket, tlsVerifyError,
|
|
13
13
|
} from "visaljs:host";
|
|
14
|
-
import { codeError, invalidArgType, outOfRange, validateFunction, validateString } from "../errors.js";
|
|
15
|
-
import { features } from "../features.js";
|
|
14
|
+
import { codeError, invalidArgType, invalidArgValue, outOfRange, validateFunction, validateInteger, validateString } from "../errors.js";
|
|
15
|
+
import { callableClass, feature, features } from "../features.js";
|
|
16
16
|
import { isIP } from "../net.js";
|
|
17
17
|
import { Server as NetServer, Socket } from "../../net.js";
|
|
18
|
+
import { domainToASCII } from "../../url.js";
|
|
18
19
|
import { createSecureContext, SecureContext, sslError, tlsFailure, VERSION_NAMES, verifyError } from "./common.js";
|
|
19
20
|
import { certificatesOf, legacyObject, parseCertificate } from "./x509.js";
|
|
20
21
|
|
|
@@ -30,6 +31,7 @@ const kSNICallback = Symbol("snicallback");
|
|
|
30
31
|
const kALPNCallback = Symbol("alpncallback");
|
|
31
32
|
const kIsVerified = Symbol("verified");
|
|
32
33
|
const kPendingSession = Symbol("pendingSession");
|
|
34
|
+
const kMaxSendFragment = Symbol("maxSendFragment");
|
|
33
35
|
|
|
34
36
|
const connReset = (message) => codeError(Error, "ECONNRESET", message);
|
|
35
37
|
|
|
@@ -59,7 +61,10 @@ function alpnNames(buf) {
|
|
|
59
61
|
function convertProtocols(protocols) {
|
|
60
62
|
const parts = protocols.map((p, i) => {
|
|
61
63
|
const b = Buffer.from(p);
|
|
62
|
-
if (b.length
|
|
64
|
+
if (b.length === 0) throw invalidArgValue(`protocols[${i}]`, "must be a non-empty string", p);
|
|
65
|
+
if (b.length > 255) {
|
|
66
|
+
throw codeError(RangeError, "ERR_OUT_OF_RANGE", `The byte length of the protocol at index ${i} exceeds the maximum length. It must be <= 255. Received ${b.length}`);
|
|
67
|
+
}
|
|
63
68
|
return b;
|
|
64
69
|
});
|
|
65
70
|
const out = Buffer.allocUnsafe(parts.reduce((n, b) => n + 1 + b.length, 0));
|
|
@@ -72,10 +77,57 @@ function convertProtocols(protocols) {
|
|
|
72
77
|
return out;
|
|
73
78
|
}
|
|
74
79
|
|
|
80
|
+
/* the wire format: <len><protocol>…, each 1–255 bytes, nothing after (empty: no ALPN) */
|
|
81
|
+
function validateALPNBuffer(buffer) {
|
|
82
|
+
for (let at = 0; at < buffer.length; at += 1 + buffer[at]) {
|
|
83
|
+
if (buffer[at] === 0) throw invalidArgValue("ALPNProtocols", "must not contain zero-length protocol", buffer);
|
|
84
|
+
if (at + 1 + buffer[at] > buffer.length) throw invalidArgValue("ALPNProtocols", "contains truncated protocol", buffer);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
75
88
|
export function convertALPNProtocols(protocols, out) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
89
|
+
let buf;
|
|
90
|
+
if (Array.isArray(protocols)) {
|
|
91
|
+
out.ALPNProtocols = convertProtocols(protocols);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (protocols instanceof Uint8Array) buf = Buffer.from(protocols);
|
|
95
|
+
else if (ArrayBuffer.isView(protocols)) buf = Buffer.from(protocols.buffer.slice(protocols.byteOffset, protocols.byteOffset + protocols.byteLength));
|
|
96
|
+
else return;
|
|
97
|
+
validateALPNBuffer(buf);
|
|
98
|
+
out.ALPNProtocols = buf;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* ---- Sessions: a client's carry the server name they were verified for (Node 24.21) ------------ */
|
|
102
|
+
|
|
103
|
+
const kSessionStatePrefix = Buffer.from("\0nodejs:tls:session:1\0");
|
|
104
|
+
|
|
105
|
+
const sessionServerIdentity = (options) => options?.servername || options?.host || options?.socket?._host || "localhost";
|
|
106
|
+
|
|
107
|
+
function wrapSessionState(session, options) {
|
|
108
|
+
if (!Buffer.isBuffer(session) || options?.isServer) return session;
|
|
109
|
+
const servername = Buffer.from(sessionServerIdentity(options), "utf8");
|
|
110
|
+
const length = Buffer.allocUnsafe(2);
|
|
111
|
+
length.writeUInt16BE(servername.length, 0);
|
|
112
|
+
return Buffer.concat([kSessionStatePrefix, length, servername, session]);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function unwrapSessionState(session) {
|
|
116
|
+
const start = kSessionStatePrefix.length;
|
|
117
|
+
if (!Buffer.isBuffer(session) || session.length < start + 2 || Buffer.compare(session.subarray(0, start), kSessionStatePrefix) !== 0) return;
|
|
118
|
+
const end = start + 2 + session.readUInt16BE(start);
|
|
119
|
+
if (session.length < end) return;
|
|
120
|
+
return { servername: session.toString("utf8", start + 2, end), session: session.subarray(end) };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* a session another server name was verified for isn't resumed; nor a raw one, by a client that verifies */
|
|
124
|
+
function sessionForReuse(session, options) {
|
|
125
|
+
if (typeof session === "string") session = Buffer.from(session, "latin1");
|
|
126
|
+
if (options?.isServer) return session;
|
|
127
|
+
const wrapped = unwrapSessionState(session);
|
|
128
|
+
if (wrapped !== undefined) return wrapped.servername === sessionServerIdentity(options) ? wrapped.session : undefined;
|
|
129
|
+
if (Buffer.isBuffer(session) && options?.rejectUnauthorized !== false) return;
|
|
130
|
+
return session;
|
|
79
131
|
}
|
|
80
132
|
|
|
81
133
|
/* ---- The ClientHello: what a server needs before it can choose a context --------------------- */
|
|
@@ -151,6 +203,7 @@ export class TLSSocket extends Socket {
|
|
|
151
203
|
manualStart: true,
|
|
152
204
|
highWaterMark: tlsOptions.highWaterMark,
|
|
153
205
|
onread: !socket ? tlsOptions.onread : null,
|
|
206
|
+
signal: tlsOptions.signal,
|
|
154
207
|
});
|
|
155
208
|
this._tlsOptions = tlsOptions;
|
|
156
209
|
this._secureEstablished = false;
|
|
@@ -170,6 +223,7 @@ export class TLSSocket extends Socket {
|
|
|
170
223
|
this._conn = null; /* the engine, once started */
|
|
171
224
|
this._handshakes = 0;
|
|
172
225
|
this._tlsClosed = false; /* the engine closed (close_notify, or an error) */
|
|
226
|
+
this._inSecureHandlers = false; /* in _onHandshakeDone, inside a _run */
|
|
173
227
|
this._pendingWrites = []; /* written before the handshake: [bytes, cb] */
|
|
174
228
|
this._hello = null; /* a server's first bytes, until the ClientHello is read */
|
|
175
229
|
this._servernameOut = null; /* a client's SNI */
|
|
@@ -197,6 +251,8 @@ export class TLSSocket extends Socket {
|
|
|
197
251
|
|
|
198
252
|
/* a Duplex (or a net.Socket not connected yet): records travel through its write() and 'data' */
|
|
199
253
|
_wrapStream(socket) {
|
|
254
|
+
/* as Node's JSStreamSocket: paused until the engine reads (_startReading); not a stream, a TypeError */
|
|
255
|
+
if (!(socket instanceof Socket)) socket.pause();
|
|
200
256
|
this._stream = socket;
|
|
201
257
|
this._parent = socket instanceof Socket ? socket : null;
|
|
202
258
|
socket.on("data", (chunk) => this._onCipher(chunk));
|
|
@@ -273,6 +329,12 @@ export class TLSSocket extends Socket {
|
|
|
273
329
|
return;
|
|
274
330
|
}
|
|
275
331
|
if (this.destroyed || this._conn !== null) return;
|
|
332
|
+
/* a net.Socket wrapped before its connect(): the ClientHello goes once it is connected */
|
|
333
|
+
const stream = this._stream;
|
|
334
|
+
if (stream instanceof Socket && stream._handle === null && !stream.destroyed) {
|
|
335
|
+
stream.once("connect", () => this._start());
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
276
338
|
this._createEngine(this._secureContext, this._servernameOut, alpnNames(this._tlsOptions.ALPNProtocols), false);
|
|
277
339
|
if (this._conn === null) return;
|
|
278
340
|
this._run(null, null);
|
|
@@ -291,27 +353,43 @@ export class TLSSocket extends Socket {
|
|
|
291
353
|
this._conn = conn;
|
|
292
354
|
this.ssl = conn;
|
|
293
355
|
this._activeContext = context;
|
|
356
|
+
if (this.listenerCount("keylog") > 0) tlsEnableKeylog(conn);
|
|
357
|
+
else this.on("newListener", keylogNewListener);
|
|
358
|
+
if (this[kMaxSendFragment] !== undefined) tlsSetMaxSendFragment(conn, this[kMaxSendFragment]);
|
|
294
359
|
if (this[kDisableRenegotiation]) tlsSetNoRenegotiation(conn);
|
|
295
360
|
}
|
|
296
361
|
|
|
297
362
|
/** Runs the engine with records received and data to send: sends the records it makes (`cb`
|
|
298
363
|
* when the last of `plain`'s are written), pushes the data it decrypts, and reports handshakes,
|
|
299
364
|
* sessions, the peer's close_notify and failures. Returns how much of `plain` it took. */
|
|
365
|
+
/* each line (with its \n), as Node's onkeylog */
|
|
366
|
+
_emitKeylog(lines) {
|
|
367
|
+
for (let at = 0; at < lines.length;) {
|
|
368
|
+
const end = lines.indexOf(0x0a, at) + 1;
|
|
369
|
+
this.emit("keylog", lines.subarray(at, end));
|
|
370
|
+
at = end;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
300
374
|
_run(cipher, plain, cb) {
|
|
301
375
|
if (this._conn === null || this._tlsClosed) {
|
|
302
376
|
if (cb) cb();
|
|
303
377
|
return plain ? plain.length : 0;
|
|
304
378
|
}
|
|
305
|
-
const [out, app, taken, state, err, handshakes] = tlsRun(this._conn, cipher, plain);
|
|
379
|
+
const [out, app, taken, state, err, handshakes, keylog] = tlsRun(this._conn, cipher, plain);
|
|
380
|
+
if (keylog) this._emitKeylog(keylog);
|
|
306
381
|
/* the callback goes with the last record of the data, once the engine took all of it */
|
|
307
382
|
const all = !plain || taken === plain.length;
|
|
308
383
|
if (handshakes > this._handshakes) {
|
|
309
384
|
/* As Node's TLSWrap: the handshake's last flight goes out after 'secure' is handled, so a
|
|
310
385
|
* side that rejects the peer's certificate there never sends it (the peer sees the end);
|
|
311
|
-
* whatever the handlers write goes after it.
|
|
386
|
+
* whatever the handlers write goes after it. The handlers' runs leave the peer's end to
|
|
387
|
+
* this one, which has the data before it (`app`). */
|
|
312
388
|
this._handshakes = handshakes;
|
|
313
389
|
this._flight = out;
|
|
390
|
+
this._inSecureHandlers = true;
|
|
314
391
|
this._onHandshakeDone();
|
|
392
|
+
this._inSecureHandlers = false;
|
|
315
393
|
const flight = this._flight;
|
|
316
394
|
this._flight = null;
|
|
317
395
|
if (flight && !this.destroyed) this._sendCipher(flight);
|
|
@@ -326,8 +404,11 @@ export class TLSSocket extends Socket {
|
|
|
326
404
|
if (state & TLS_FAILED && !this._tlsClosed) {
|
|
327
405
|
this._tlsClosed = true;
|
|
328
406
|
this._onTlsError(tlsFailure(err));
|
|
329
|
-
} else if (state & TLS_PEER_CLOSED) {
|
|
330
|
-
|
|
407
|
+
} else if (state & TLS_PEER_CLOSED && !this._inSecureHandlers) {
|
|
408
|
+
/* libuv reads data and the end apart, Node's ticks and promise jobs between them: the end
|
|
409
|
+
* of what came with data, a turn of the loop later */
|
|
410
|
+
if (app) setImmediate(() => this._peerEnded());
|
|
411
|
+
else this._peerEnded();
|
|
331
412
|
}
|
|
332
413
|
return taken;
|
|
333
414
|
}
|
|
@@ -335,7 +416,7 @@ export class TLSSocket extends Socket {
|
|
|
335
416
|
/* a session the server gave (a TLS 1.3 ticket comes after the handshake): 'session', once the
|
|
336
417
|
* server is verified (Node's onnewsessionclient) */
|
|
337
418
|
_onNewSession() {
|
|
338
|
-
const session = tlsSession(this._conn);
|
|
419
|
+
const session = wrapSessionState(tlsSession(this._conn), this[kConnectOptions] || this._tlsOptions);
|
|
339
420
|
if (!session) return;
|
|
340
421
|
if (this[kIsVerified]) this.emit("session", session);
|
|
341
422
|
else this[kPendingSession] = session;
|
|
@@ -384,8 +465,9 @@ export class TLSSocket extends Socket {
|
|
|
384
465
|
this.destroy(errnoException(r, "write"));
|
|
385
466
|
return;
|
|
386
467
|
}
|
|
468
|
+
/* written at once, but a TLS write completes later, as Node's TLSWrap's (bufferSize counts it till then) */
|
|
387
469
|
if (r === 0) {
|
|
388
|
-
if (cb) cb
|
|
470
|
+
if (cb) process.nextTick(cb);
|
|
389
471
|
return;
|
|
390
472
|
}
|
|
391
473
|
this._writeCallbacks.push((status) => {
|
|
@@ -477,12 +559,12 @@ export class TLSSocket extends Socket {
|
|
|
477
559
|
alpn = [selected === undefined ? "\u0000" : selected];
|
|
478
560
|
strict = true;
|
|
479
561
|
}
|
|
480
|
-
this.servername = hello.servername ?? false;
|
|
481
562
|
this._createEngine(context ?? this._secureContext, null, alpn, strict);
|
|
482
563
|
const buffered = this._hello;
|
|
483
564
|
this._hello = null;
|
|
484
565
|
if (this._conn !== null) this._run(buffered, null);
|
|
485
566
|
};
|
|
567
|
+
this.servername = hello.servername ?? false;
|
|
486
568
|
if (!hello.servername || !this._SNICallback) {
|
|
487
569
|
finish(null);
|
|
488
570
|
return;
|
|
@@ -493,7 +575,10 @@ export class TLSSocket extends Socket {
|
|
|
493
575
|
if (once) return this.destroy(codeError(Error, "ERR_MULTIPLE_CALLBACK", "Callback called multiple times"));
|
|
494
576
|
once = true;
|
|
495
577
|
if (err) return this.destroy(err);
|
|
496
|
-
|
|
578
|
+
const secureContext = !context ? null : context instanceof SecureContext ? context : context.context instanceof SecureContext ? context.context : undefined;
|
|
579
|
+
/* Node's TLSWrap: the handshake fails, as a TLS error the server reports */
|
|
580
|
+
if (secureContext === undefined) return this._onTlsError(new TypeError("Invalid SNI context"));
|
|
581
|
+
finish(secureContext);
|
|
497
582
|
});
|
|
498
583
|
} catch (err) {
|
|
499
584
|
this.destroy(err);
|
|
@@ -617,6 +702,21 @@ export class TLSSocket extends Socket {
|
|
|
617
702
|
|
|
618
703
|
/* ---- Node's TLSSocket API ---- */
|
|
619
704
|
|
|
705
|
+
/* Node's TLSWrap is the socket's handle from the start, over a stream too; it goes with destroy() */
|
|
706
|
+
get bufferSize() {
|
|
707
|
+
return this.destroyed ? undefined : this.writableLength;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* the engine goes; the transport stays (Node frees the SSL) */
|
|
711
|
+
_destroySSL() {
|
|
712
|
+
if (this._conn === null) return;
|
|
713
|
+
this._conn = null;
|
|
714
|
+
this.ssl = null;
|
|
715
|
+
this._tlsClosed = true;
|
|
716
|
+
this[kPendingSession] = null;
|
|
717
|
+
this[kIsVerified] = false;
|
|
718
|
+
}
|
|
719
|
+
|
|
620
720
|
disableRenegotiation() {
|
|
621
721
|
this[kDisableRenegotiation] = true;
|
|
622
722
|
if (this._conn !== null) tlsSetNoRenegotiation(this._conn);
|
|
@@ -628,9 +728,9 @@ export class TLSSocket extends Socket {
|
|
|
628
728
|
if (this.destroyed) return;
|
|
629
729
|
if (options.requestCert !== undefined) this._requestCert = !!options.requestCert;
|
|
630
730
|
if (options.rejectUnauthorized !== undefined) this._rejectUnauthorized = !!options.rejectUnauthorized;
|
|
631
|
-
/* BoringSSL never starts a renegotiation (a client follows a server's request);
|
|
632
|
-
*
|
|
633
|
-
const err = sslError(0x0A000153, "no renegotiation");
|
|
731
|
+
/* BoringSSL never starts a renegotiation (a client follows a server's request); TLS 1.3 has
|
|
732
|
+
* none, which OpenSSL 3 reports as its wrong version */
|
|
733
|
+
const err = this.getProtocol() === "TLSv1.3" ? sslError(0x0A00010A, "wrong ssl version") : sslError(0x0A000153, "no renegotiation");
|
|
634
734
|
if (callback) process.nextTick(callback, err);
|
|
635
735
|
return false;
|
|
636
736
|
}
|
|
@@ -647,8 +747,13 @@ export class TLSSocket extends Socket {
|
|
|
647
747
|
}
|
|
648
748
|
|
|
649
749
|
setMaxSendFragment(size) {
|
|
650
|
-
|
|
651
|
-
|
|
750
|
+
validateInteger(size, "size");
|
|
751
|
+
if (size < -(2 ** 31) || size > 2 ** 31 - 1) throw outOfRange("size", `>= ${-(2 ** 31)} && <= ${2 ** 31 - 1}`, size);
|
|
752
|
+
/* OpenSSL's range: BoringSSL would clamp what's outside it, and report success */
|
|
753
|
+
if (size < 512 || size > 16384) return false;
|
|
754
|
+
if (this._conn) tlsSetMaxSendFragment(this._conn, size);
|
|
755
|
+
else this[kMaxSendFragment] = size;
|
|
756
|
+
return true;
|
|
652
757
|
}
|
|
653
758
|
|
|
654
759
|
_handleTimeout() {
|
|
@@ -692,12 +797,12 @@ export class TLSSocket extends Socket {
|
|
|
692
797
|
/* a session is BoringSSL's (i2d_SSL_SESSION's), with the server's chain and verification as
|
|
693
798
|
* OpenSSL's has them */
|
|
694
799
|
setSession(session) {
|
|
695
|
-
|
|
800
|
+
session = sessionForReuse(session, this[kConnectOptions] || this._tlsOptions);
|
|
696
801
|
if (ArrayBuffer.isView(session)) this._sessionIn = session;
|
|
697
802
|
}
|
|
698
803
|
|
|
699
804
|
getSession() {
|
|
700
|
-
return this._conn === null ? null : tlsSession(this._conn);
|
|
805
|
+
return this._conn === null ? null : wrapSessionState(tlsSession(this._conn), this[kConnectOptions] || this._tlsOptions);
|
|
701
806
|
}
|
|
702
807
|
|
|
703
808
|
/** The peer's chain, parsed: the leaf, then each certificate's issuer among the rest */
|
|
@@ -769,12 +874,12 @@ export class TLSSocket extends Socket {
|
|
|
769
874
|
|
|
770
875
|
getPeerX509Certificate() {
|
|
771
876
|
const chain = this._peerChain();
|
|
772
|
-
return chain.length ?
|
|
877
|
+
return chain.length ? feature("x509CertificateChain")(chain.map((c) => c.der)) : undefined;
|
|
773
878
|
}
|
|
774
879
|
|
|
775
880
|
getX509Certificate() {
|
|
776
881
|
const ctx = this._activeContext ?? this._secureContext;
|
|
777
|
-
return ctx._certs.length ?
|
|
882
|
+
return ctx._certs.length ? feature("x509CertificateChain")([ctx._certs[0]]) : undefined;
|
|
778
883
|
}
|
|
779
884
|
|
|
780
885
|
setKeyCert(context) {
|
|
@@ -801,15 +906,15 @@ export class TLSSocket extends Socket {
|
|
|
801
906
|
}
|
|
802
907
|
|
|
803
908
|
getFinished() {
|
|
804
|
-
return this._conn === null ?
|
|
909
|
+
return this._conn === null ? undefined : tlsFinished(this._conn, false);
|
|
805
910
|
}
|
|
806
911
|
|
|
807
912
|
getPeerFinished() {
|
|
808
|
-
return this._conn === null ?
|
|
913
|
+
return this._conn === null ? undefined : tlsFinished(this._conn, true);
|
|
809
914
|
}
|
|
810
915
|
|
|
811
916
|
getTLSTicket() {
|
|
812
|
-
return this._conn === null ?
|
|
917
|
+
return this._conn === null ? undefined : tlsTicket(this._conn);
|
|
813
918
|
}
|
|
814
919
|
|
|
815
920
|
getSharedSigalgs() {
|
|
@@ -823,16 +928,6 @@ export class TLSSocket extends Socket {
|
|
|
823
928
|
enableTrace() {}
|
|
824
929
|
}
|
|
825
930
|
|
|
826
|
-
/* crypto.X509Certificate, which getPeerX509Certificate returns: set by node:crypto's module */
|
|
827
|
-
let X509Certificate = class {
|
|
828
|
-
constructor() {
|
|
829
|
-
throw codeError(Error, "ERR_VISALJS_UNSUPPORTED", "X509Certificate is not supported by visaljs yet");
|
|
830
|
-
}
|
|
831
|
-
};
|
|
832
|
-
export function setX509Certificate(cls) {
|
|
833
|
-
X509Certificate = cls;
|
|
834
|
-
}
|
|
835
|
-
|
|
836
931
|
/* ---- Server ------------------------------------------------------------------------------------- */
|
|
837
932
|
|
|
838
933
|
function onServerSocketSecure() {
|
|
@@ -866,6 +961,16 @@ function onSocketClose(err) {
|
|
|
866
961
|
}
|
|
867
962
|
}
|
|
868
963
|
|
|
964
|
+
function keylogNewListener(event) {
|
|
965
|
+
if (event !== "keylog") return;
|
|
966
|
+
if (this._conn !== null) tlsEnableKeylog(this._conn);
|
|
967
|
+
this.removeListener("newListener", keylogNewListener);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
function onSocketKeylog(line) {
|
|
971
|
+
this._tlsOptions.server.emit("keylog", line, this);
|
|
972
|
+
}
|
|
973
|
+
|
|
869
974
|
function tlsConnectionListener(rawSocket) {
|
|
870
975
|
const socket = new TLSSocket(rawSocket, {
|
|
871
976
|
secureContext: this._sharedCreds,
|
|
@@ -884,6 +989,7 @@ function tlsConnectionListener(rawSocket) {
|
|
|
884
989
|
socket.on("close", onSocketClose);
|
|
885
990
|
socket.on("_tlsError", onSocketTLSError);
|
|
886
991
|
socket.on("error", onSocketTLSError);
|
|
992
|
+
if (this.listenerCount("keylog") > 0) socket.on("keylog", onSocketKeylog);
|
|
887
993
|
}
|
|
888
994
|
|
|
889
995
|
function SNICallback(servername, callback) {
|
|
@@ -897,7 +1003,7 @@ function SNICallback(servername, callback) {
|
|
|
897
1003
|
callback(null, undefined);
|
|
898
1004
|
}
|
|
899
1005
|
|
|
900
|
-
|
|
1006
|
+
class ServerClass extends NetServer {
|
|
901
1007
|
constructor(options, listener) {
|
|
902
1008
|
if (typeof options === "function") {
|
|
903
1009
|
listener = options;
|
|
@@ -937,30 +1043,44 @@ export class Server extends NetServer {
|
|
|
937
1043
|
this.honorCipherOrder = options.honorCipherOrder !== undefined ? !!options.honorCipherOrder : true;
|
|
938
1044
|
this.secureOptions = options.secureOptions || undefined;
|
|
939
1045
|
this.sessionIdContext = options.sessionIdContext || undefined;
|
|
1046
|
+
if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
|
|
1047
|
+
if (options.ticketKeys) this.ticketKeys = options.ticketKeys;
|
|
1048
|
+
this.privateKeyIdentifier = options.privateKeyIdentifier;
|
|
1049
|
+
this.privateKeyEngine = options.privateKeyEngine;
|
|
1050
|
+
this.certificateCompression = options.certificateCompression;
|
|
940
1051
|
this._sharedCreds = createSecureContext({
|
|
941
|
-
pfx: this.pfx, key: this.key, passphrase: this.passphrase, cert: this.cert,
|
|
942
|
-
sigalgs: this.sigalgs, ecdhCurve: this.ecdhCurve, dhparam: this.dhparam, minVersion: this.minVersion,
|
|
1052
|
+
pfx: this.pfx, key: this.key, passphrase: this.passphrase, cert: this.cert, clientCertEngine: this.clientCertEngine, ca: this.ca,
|
|
1053
|
+
ciphers: this.ciphers, sigalgs: this.sigalgs, ecdhCurve: this.ecdhCurve, dhparam: this.dhparam, minVersion: this.minVersion,
|
|
943
1054
|
maxVersion: this.maxVersion, secureProtocol: this.secureProtocol, secureOptions: this.secureOptions,
|
|
944
|
-
honorCipherOrder: this.honorCipherOrder, crl: this.crl, sessionIdContext: this.sessionIdContext,
|
|
1055
|
+
honorCipherOrder: this.honorCipherOrder, crl: this.crl, sessionIdContext: this.sessionIdContext, ticketKeys: this.ticketKeys,
|
|
1056
|
+
sessionTimeout: this.sessionTimeout, privateKeyIdentifier: this.privateKeyIdentifier, privateKeyEngine: this.privateKeyEngine,
|
|
1057
|
+
certificateCompression: this.certificateCompression,
|
|
945
1058
|
});
|
|
946
1059
|
}
|
|
947
1060
|
|
|
948
1061
|
addContext(servername, context) {
|
|
949
1062
|
if (!servername) throw codeError(Error, "ERR_TLS_REQUIRED_SERVER_NAME", '"servername" is required parameter for Server.addContext');
|
|
950
|
-
const re = new RegExp(`^${servername.replace(/([.^$+?\-\\[\]{}])/g, "\\$1").replaceAll("*", "[^.]*")}
|
|
1063
|
+
const re = new RegExp(`^${servername.replace(/([.^$+?\-\\[\]{}])/g, "\\$1").replaceAll("*", "[^.]*")}$`, "i");
|
|
951
1064
|
const secureContext = context instanceof SecureContext ? context : createSecureContext(context);
|
|
952
1065
|
this._contexts.push([re, secureContext]);
|
|
953
1066
|
}
|
|
954
1067
|
|
|
955
1068
|
getTicketKeys() {
|
|
956
|
-
return
|
|
1069
|
+
return tlsContextTicketKeys(this._sharedCreds.context, null);
|
|
957
1070
|
}
|
|
958
1071
|
|
|
959
1072
|
setTicketKeys(keys) {
|
|
960
1073
|
if (!ArrayBuffer.isView(keys)) throw invalidArgType("buffer", "an instance of Buffer, TypedArray, or DataView", keys);
|
|
1074
|
+
if (keys.byteLength !== 48) {
|
|
1075
|
+
throw codeError(Error, "ERR_INTERNAL_ASSERTION", "Session ticket keys must be a 48-byte buffer\nThis is caused by either a bug in Node.js " +
|
|
1076
|
+
"or incorrect usage of Node.js internals.\nPlease open an issue with this stack trace at https://github.com/nodejs/node/issues\n");
|
|
1077
|
+
}
|
|
1078
|
+
tlsContextTicketKeys(this._sharedCreds.context, keys);
|
|
961
1079
|
}
|
|
962
1080
|
}
|
|
963
1081
|
|
|
1082
|
+
export const Server = callableClass(ServerClass, "Server"); /* Server(…) without new, as Node's */
|
|
1083
|
+
|
|
964
1084
|
export function createServer(options, listener) {
|
|
965
1085
|
return new Server(options, listener);
|
|
966
1086
|
}
|
|
@@ -988,10 +1108,9 @@ function onConnectSecure() {
|
|
|
988
1108
|
this.secureConnecting = false;
|
|
989
1109
|
this.emit("secureConnect");
|
|
990
1110
|
this[kIsVerified] = true;
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
}
|
|
1111
|
+
const session = this[kPendingSession];
|
|
1112
|
+
this[kPendingSession] = null;
|
|
1113
|
+
if (session) this.emit("session", session);
|
|
995
1114
|
this.removeListener("end", onConnectEnd);
|
|
996
1115
|
}
|
|
997
1116
|
|
|
@@ -1026,10 +1145,22 @@ function normalizeConnectArgs(listArgs) {
|
|
|
1026
1145
|
|
|
1027
1146
|
let ipServernameWarned = false;
|
|
1028
1147
|
|
|
1148
|
+
let warnOnAllowUnauthorized = true;
|
|
1149
|
+
/* Node's getAllowUnauthorized: NODE_TLS_REJECT_UNAUTHORIZED=0, with a warning the first time */
|
|
1150
|
+
function allowUnauthorized() {
|
|
1151
|
+
const allow = process.env.NODE_TLS_REJECT_UNAUTHORIZED === "0";
|
|
1152
|
+
if (allow && warnOnAllowUnauthorized) {
|
|
1153
|
+
warnOnAllowUnauthorized = false;
|
|
1154
|
+
process.emitWarning("Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests " +
|
|
1155
|
+
"insecure by disabling certificate verification.");
|
|
1156
|
+
}
|
|
1157
|
+
return allow;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1029
1160
|
export function connect(...args) {
|
|
1030
1161
|
let [options, cb] = normalizeConnectArgs(args);
|
|
1031
1162
|
options = {
|
|
1032
|
-
rejectUnauthorized:
|
|
1163
|
+
rejectUnauthorized: !allowUnauthorized(),
|
|
1033
1164
|
ciphers: undefined,
|
|
1034
1165
|
checkServerIdentity,
|
|
1035
1166
|
minDHSize: 1024,
|
|
@@ -1052,6 +1183,7 @@ export function connect(...args) {
|
|
|
1052
1183
|
ALPNProtocols: options.ALPNProtocols,
|
|
1053
1184
|
highWaterMark: options.highWaterMark,
|
|
1054
1185
|
onread: options.onread,
|
|
1186
|
+
signal: options.signal,
|
|
1055
1187
|
});
|
|
1056
1188
|
options.rejectUnauthorized = options.rejectUnauthorized !== false;
|
|
1057
1189
|
tlssock[kConnectOptions] = options;
|
|
@@ -1171,6 +1303,7 @@ export function checkServerIdentity(hostname, cert) {
|
|
|
1171
1303
|
const dnsNames = [];
|
|
1172
1304
|
const ips = [];
|
|
1173
1305
|
hostname = "" + hostname;
|
|
1306
|
+
const hostnameASCII = unfqdn(domainToASCII(hostname));
|
|
1174
1307
|
if (altNames) {
|
|
1175
1308
|
const splitAltNames = altNames.includes('"') ? splitEscapedAltNames(altNames) : altNames.split(", ");
|
|
1176
1309
|
splitAltNames.forEach((name) => {
|
|
@@ -1185,7 +1318,7 @@ export function checkServerIdentity(hostname, cert) {
|
|
|
1185
1318
|
valid = ips.includes(canonicalizeIP(hostname));
|
|
1186
1319
|
if (!valid) reason = `IP: ${hostname} is not in the cert's list: ` + ips.join(", ");
|
|
1187
1320
|
} else if (dnsNames.length > 0 || subject?.CN) {
|
|
1188
|
-
const hostParts = splitHost(
|
|
1321
|
+
const hostParts = splitHost(hostnameASCII);
|
|
1189
1322
|
const wildcard = (pattern) => check(hostParts, pattern, true);
|
|
1190
1323
|
if (dnsNames.length > 0) {
|
|
1191
1324
|
valid = dnsNames.some(wildcard);
|
|
@@ -373,11 +373,14 @@ export const issuedBy = (cert, issuer) => Buffer.compare(cert.issuerRaw, issuer.
|
|
|
373
373
|
|
|
374
374
|
/* ---- PEM ---------------------------------------------------------------------------------------- */
|
|
375
375
|
|
|
376
|
+
/* what OpenSSL's PEM reader takes as a certificate */
|
|
377
|
+
const CERTIFICATE_LABELS = new Set(["TRUSTED CERTIFICATE", "X509 CERTIFICATE"]);
|
|
378
|
+
|
|
376
379
|
/** Every block of a label in PEM text, as DER Buffers */
|
|
377
380
|
export function pemBlocks(text, label) {
|
|
378
381
|
const out = [];
|
|
379
382
|
const re = /-----BEGIN ([A-Z0-9 ]+)-----\r?\n([\s\S]*?)-----END \1-----/g;
|
|
380
|
-
for (let m; (m = re.exec(text)) !== null;) if (label === undefined || m[1] === label || (label === "CERTIFICATE" && m[1]
|
|
383
|
+
for (let m; (m = re.exec(text)) !== null;) if (label === undefined || m[1] === label || (label === "CERTIFICATE" && CERTIFICATE_LABELS.has(m[1]))) out.push(Buffer.from(m[2], "base64"));
|
|
381
384
|
return out;
|
|
382
385
|
}
|
|
383
386
|
|