visaljs 0.0.10 → 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.
Files changed (221) hide show
  1. package/README.md +12 -4
  2. package/THIRD_PARTY_LICENSES +31 -1
  3. package/cli.js +962 -68
  4. package/node/include/js_node.h +11 -1
  5. package/node/prelude/_http_common.js +29 -0
  6. package/node/prelude/async_hooks.js +50 -11
  7. package/node/prelude/child_process.js +31 -4
  8. package/node/prelude/console.js +311 -143
  9. package/node/prelude/crypto.js +6 -4
  10. package/node/prelude/dgram.js +1169 -0
  11. package/node/prelude/diagnostics_channel.js +3 -1
  12. package/node/prelude/dns.js +250 -45
  13. package/node/prelude/dns_promises.js +8 -2
  14. package/node/prelude/fs_promises.js +9 -1
  15. package/node/prelude/http.js +395 -86
  16. package/node/prelude/https.js +13 -4
  17. package/node/prelude/internal/console_class.js +7 -0
  18. package/node/prelude/internal/console_global.js +25 -0
  19. package/node/prelude/internal/crypto/key_encryption.js +217 -0
  20. package/node/prelude/internal/crypto/keys.js +161 -26
  21. package/node/prelude/internal/crypto/random.js +24 -0
  22. package/node/prelude/internal/crypto/util.js +2 -1
  23. package/node/prelude/internal/crypto_x509.js +161 -0
  24. package/node/prelude/internal/dns_classes.js +6 -0
  25. package/node/prelude/internal/dns_resolver.js +371 -0
  26. package/node/prelude/internal/errors.js +9 -0
  27. package/node/prelude/internal/events_on.js +82 -37
  28. package/node/prelude/internal/features.js +8 -4
  29. package/node/prelude/internal/fs_filehandle.js +10 -4
  30. package/node/prelude/internal/perf_histogram.js +1 -1
  31. package/node/prelude/internal/process_more.js +32 -17
  32. package/node/prelude/internal/process_signals.js +8 -2
  33. package/node/prelude/internal/punycode.ts +163 -0
  34. package/node/prelude/internal/readline.js +648 -274
  35. package/node/prelude/internal/readline_editor.js +1240 -0
  36. package/node/prelude/internal/string_width.js +43 -0
  37. package/node/prelude/internal/tls/common.js +145 -33
  38. package/node/prelude/internal/tls/wrap.js +182 -49
  39. package/node/prelude/internal/tls/x509.js +4 -1
  40. package/node/prelude/internal/udp.js +177 -0
  41. package/node/prelude/net.js +13 -1
  42. package/node/prelude/os.js +24 -6
  43. package/node/prelude/perf_hooks.js +37 -2
  44. package/node/prelude/punycode.js +2 -130
  45. package/node/prelude/readline.js +113 -4
  46. package/node/prelude/readline_promises.js +56 -32
  47. package/node/prelude/tls.js +21 -4
  48. package/node/prelude/util.js +3 -16
  49. package/node/src/host_dns.c +623 -0
  50. package/node/src/host_http.c +12 -0
  51. package/node/src/host_net.c +46 -0
  52. package/node/src/host_os.c +1 -6
  53. package/node/src/host_sys.c +70 -0
  54. package/node/src/host_udp.c +418 -0
  55. package/node/third_party/c-ares/LICENSE.md +24 -0
  56. package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
  57. package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
  58. package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
  59. package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
  60. package/node/third_party/c-ares/include/ares.h +1237 -0
  61. package/node/third_party/c-ares/include/ares_build.h +202 -0
  62. package/node/third_party/c-ares/include/ares_dns.h +127 -0
  63. package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
  64. package/node/third_party/c-ares/include/ares_nameser.h +510 -0
  65. package/node/third_party/c-ares/include/ares_version.h +47 -0
  66. package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
  67. package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
  68. package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
  69. package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
  70. package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
  71. package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
  72. package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
  73. package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
  74. package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
  75. package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
  76. package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
  77. package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
  78. package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
  79. package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
  80. package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
  81. package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
  82. package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
  83. package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
  84. package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
  85. package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
  86. package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
  87. package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
  88. package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
  89. package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
  90. package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
  91. package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
  92. package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
  93. package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
  94. package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
  95. package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
  96. package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
  97. package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
  98. package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
  99. package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
  100. package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
  101. package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
  102. package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
  103. package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
  104. package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
  105. package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
  106. package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
  107. package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
  108. package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
  109. package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
  110. package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
  111. package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
  112. package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
  113. package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
  114. package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
  115. package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
  116. package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
  117. package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
  118. package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
  119. package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
  120. package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
  121. package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
  122. package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
  123. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  124. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  125. package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
  126. package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
  127. package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
  128. package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
  129. package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
  130. package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
  131. package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
  132. package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
  133. package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
  134. package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
  135. package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
  136. package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
  137. package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
  138. package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
  139. package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
  140. package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
  141. package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
  142. package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
  143. package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
  144. package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
  145. package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
  146. package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
  147. package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
  148. package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
  149. package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
  150. package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
  151. package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
  152. package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
  153. package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
  154. package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
  155. package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
  156. package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  157. package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  158. package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  159. package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  160. package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  161. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  162. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  163. package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  164. package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  165. package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  166. package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  167. package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
  168. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
  169. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
  170. package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
  171. package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
  172. package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
  173. package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
  174. package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
  175. package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
  176. package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
  177. package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
  178. package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
  179. package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  180. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
  181. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
  182. package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
  183. package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
  184. package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
  185. package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
  186. package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
  187. package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
  188. package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
  189. package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
  190. package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
  191. package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
  192. package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
  193. package/package.json +1 -1
  194. package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
  195. package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
  196. package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
  197. package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
  198. package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
  199. package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
  200. package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
  201. package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
  202. package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
  203. package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
  204. package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
  205. package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
  206. package/runtime/include/js_builtins.h +5 -0
  207. package/runtime/include/js_crypto.h +11 -0
  208. package/runtime/include/js_gc.h +13 -10
  209. package/runtime/include/js_jobs.h +2 -0
  210. package/runtime/include/js_object.h +58 -0
  211. package/runtime/include/jscontext.h +1 -0
  212. package/runtime/src/crypto_internal.h +1 -0
  213. package/runtime/src/crypto_subtle.c +66 -7
  214. package/runtime/src/crypto_tls.c +265 -19
  215. package/runtime/src/gc.c +73 -92
  216. package/runtime/src/inspect.c +18 -1
  217. package/runtime/src/jobs.c +37 -22
  218. package/runtime/src/object.c +49 -2
  219. package/runtime/src/os.c +16 -6
  220. package/runtime/src/os.h +2 -0
  221. package/runtime/src/process.c +97 -10
@@ -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 > 255) throw outOfRange(`The byte length of the protocol at index ${i} exceeds the maximum length.`, "<= 255", 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
- if (Array.isArray(protocols)) out.ALPNProtocols = convertProtocols(protocols);
77
- else if (protocols instanceof Uint8Array) out.ALPNProtocols = Buffer.from(protocols);
78
- else if (ArrayBuffer.isView(protocols)) out.ALPNProtocols = Buffer.from(protocols.buffer.slice(protocols.byteOffset, protocols.byteOffset + protocols.byteLength));
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
- this._peerEnded();
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
- finish(context ? (context instanceof SecureContext ? context : context.context instanceof SecureContext ? context.context : context) : null);
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); OpenSSL 3
632
- * refuses one in TLS 1.3 too */
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
- if (typeof size !== "number" || !Number.isInteger(size)) throw invalidArgType("size", "of type number", size);
651
- return size >= 512 && size <= 16384;
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
- if (typeof session === "string") session = Buffer.from(session, "latin1");
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 ? new X509Certificate(chain[0].der) : undefined;
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 ? new X509Certificate(ctx._certs[0]) : undefined;
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 ? null : tlsFinished(this._conn, false);
909
+ return this._conn === null ? undefined : tlsFinished(this._conn, false);
805
910
  }
806
911
 
807
912
  getPeerFinished() {
808
- return this._conn === null ? null : tlsFinished(this._conn, true);
913
+ return this._conn === null ? undefined : tlsFinished(this._conn, true);
809
914
  }
810
915
 
811
916
  getTLSTicket() {
812
- return this._conn === null ? null : undefined;
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
- export class Server extends NetServer {
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, ca: this.ca, ciphers: this.ciphers,
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 Buffer.alloc(48);
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
- if (this.listenerCount("session") > 0) {
992
- const session = this.getSession();
993
- if (session) this.emit("session", session);
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: process.env.NODE_TLS_REJECT_UNAUTHORIZED !== "0",
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(hostname);
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] === "TRUSTED CERTIFICATE")) out.push(Buffer.from(m[2], "base64"));
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