@encharm/cws 4.5.3 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/CLAUDE.md +83 -0
  3. package/README.md +20 -4
  4. package/binding.gyp +8 -2
  5. package/dist/bindings/cws_darwin_arm64_node115.node +0 -0
  6. package/dist/bindings/cws_darwin_arm64_node127.node +0 -0
  7. package/dist/bindings/cws_darwin_arm64_node137.node +0 -0
  8. package/dist/bindings/cws_darwin_arm64_node147.node +0 -0
  9. package/dist/bindings/cws_linux_arm64_node115.node +0 -0
  10. package/dist/bindings/cws_linux_arm64_node127.node +0 -0
  11. package/dist/bindings/cws_linux_arm64_node137.node +0 -0
  12. package/dist/bindings/cws_linux_arm64_node147.node +0 -0
  13. package/dist/bindings/cws_linux_x64_node115.node +0 -0
  14. package/dist/bindings/cws_linux_x64_node127.node +0 -0
  15. package/dist/bindings/cws_linux_x64_node137.node +0 -0
  16. package/dist/bindings/cws_linux_x64_node147.node +0 -0
  17. package/dist/bindings/cws_win32_x64_node115.node +0 -0
  18. package/dist/bindings/cws_win32_x64_node127.node +0 -0
  19. package/dist/bindings/cws_win32_x64_node137.node +0 -0
  20. package/dist/bindings/cws_win32_x64_node147.node +0 -0
  21. package/dist/client.d.ts +1 -0
  22. package/dist/client.js +15 -1
  23. package/dist/index.d.ts +6 -1
  24. package/dist/index.js +2 -0
  25. package/dist/server.d.ts +1 -0
  26. package/dist/server.js +16 -2
  27. package/dist/shared.d.ts +1 -0
  28. package/dist/shared.js +3 -2
  29. package/package.json +1 -1
  30. package/src/Addon.cpp +4 -1
  31. package/src/Addon.h +80 -15
  32. package/src/Extensions.cpp +7 -1
  33. package/src/Extensions.h +2 -1
  34. package/src/Group.cpp +1 -1
  35. package/src/Group.h +4 -1
  36. package/src/HTTPSocket.cpp +1 -1
  37. package/src/Hub.cpp +11 -76
  38. package/src/Hub.h +12 -10
  39. package/src/Networking.h +11 -0
  40. package/src/Socket.h +201 -6
  41. package/src/WebSocket.cpp +8 -5
  42. package/src/Zlib.cpp +138 -0
  43. package/src/Zlib.h +38 -0
  44. package/src/cSNode.cpp +2 -0
  45. package/src/cSNode.h +4 -0
  46. package/src/headers/26/acorn_version.h +6 -0
  47. package/src/headers/26/aliased_buffer-inl.h +264 -0
  48. package/src/headers/26/aliased_buffer.h +205 -0
  49. package/src/headers/26/aliased_struct-inl.h +143 -0
  50. package/src/headers/26/aliased_struct.h +248 -0
  51. package/src/headers/26/amaro_version.h +6 -0
  52. package/src/headers/26/async_context_frame.h +33 -0
  53. package/src/headers/26/async_wrap-inl.h +123 -0
  54. package/src/headers/26/async_wrap.h +254 -0
  55. package/src/headers/26/base_object-inl.h +333 -0
  56. package/src/headers/26/base_object.h +339 -0
  57. package/src/headers/26/base_object_types.h +76 -0
  58. package/src/headers/26/blob_serializer_deserializer-inl.h +385 -0
  59. package/src/headers/26/blob_serializer_deserializer.h +142 -0
  60. package/src/headers/26/builtin_info.h +57 -0
  61. package/src/headers/26/callback_queue-inl.h +97 -0
  62. package/src/headers/26/callback_queue.h +79 -0
  63. package/src/headers/26/cares_wrap.h +475 -0
  64. package/src/headers/26/cleanup_queue-inl.h +36 -0
  65. package/src/headers/26/cleanup_queue.h +79 -0
  66. package/src/headers/26/compile_cache.h +134 -0
  67. package/src/headers/26/connect_wrap.h +26 -0
  68. package/src/headers/26/connection_wrap.h +30 -0
  69. package/src/headers/26/cppgc_helpers-inl.h +69 -0
  70. package/src/headers/26/cppgc_helpers.h +162 -0
  71. package/src/headers/26/crypto/crypto_aes.h +107 -0
  72. package/src/headers/26/crypto/crypto_argon2.h +88 -0
  73. package/src/headers/26/crypto/crypto_bio.h +193 -0
  74. package/src/headers/26/crypto/crypto_chacha20_poly1305.h +62 -0
  75. package/src/headers/26/crypto/crypto_cipher.h +291 -0
  76. package/src/headers/26/crypto/crypto_common.h +48 -0
  77. package/src/headers/26/crypto/crypto_context.h +219 -0
  78. package/src/headers/26/crypto/crypto_dh.h +104 -0
  79. package/src/headers/26/crypto/crypto_dsa.h +50 -0
  80. package/src/headers/26/crypto/crypto_ec.h +102 -0
  81. package/src/headers/26/crypto/crypto_hash.h +157 -0
  82. package/src/headers/26/crypto/crypto_hkdf.h +62 -0
  83. package/src/headers/26/crypto/crypto_hmac.h +92 -0
  84. package/src/headers/26/crypto/crypto_kem.h +131 -0
  85. package/src/headers/26/crypto/crypto_keygen.h +382 -0
  86. package/src/headers/26/crypto/crypto_keys.h +366 -0
  87. package/src/headers/26/crypto/crypto_kmac.h +79 -0
  88. package/src/headers/26/crypto/crypto_pbkdf2.h +76 -0
  89. package/src/headers/26/crypto/crypto_pqc.h +39 -0
  90. package/src/headers/26/crypto/crypto_random.h +127 -0
  91. package/src/headers/26/crypto/crypto_rsa.h +108 -0
  92. package/src/headers/26/crypto/crypto_scrypt.h +85 -0
  93. package/src/headers/26/crypto/crypto_sig.h +159 -0
  94. package/src/headers/26/crypto/crypto_spkac.h +21 -0
  95. package/src/headers/26/crypto/crypto_timing.h +20 -0
  96. package/src/headers/26/crypto/crypto_tls.h +342 -0
  97. package/src/headers/26/crypto/crypto_turboshake.h +105 -0
  98. package/src/headers/26/crypto/crypto_util.h +775 -0
  99. package/src/headers/26/crypto/crypto_x509.h +140 -0
  100. package/src/headers/26/dataqueue/queue.h +311 -0
  101. package/src/headers/26/debug_utils-inl.h +291 -0
  102. package/src/headers/26/debug_utils.h +200 -0
  103. package/src/headers/26/diagnosticfilename-inl.h +33 -0
  104. package/src/headers/26/embedded_data.h +17 -0
  105. package/src/headers/26/encoding_binding.h +59 -0
  106. package/src/headers/26/env-inl.h +956 -0
  107. package/src/headers/26/env.h +1294 -0
  108. package/src/headers/26/env_properties.h +562 -0
  109. package/src/headers/26/ffi/data.h +30 -0
  110. package/src/headers/26/ffi/fast.h +96 -0
  111. package/src/headers/26/ffi/jit_memory.h +26 -0
  112. package/src/headers/26/ffi/types.h +99 -0
  113. package/src/headers/26/handle_wrap.h +123 -0
  114. package/src/headers/26/histogram-inl.h +211 -0
  115. package/src/headers/26/histogram.h +474 -0
  116. package/src/headers/26/inspector/dom_storage_agent.h +68 -0
  117. package/src/headers/26/inspector/inspector_object_utils.h +38 -0
  118. package/src/headers/26/inspector/io_agent.h +30 -0
  119. package/src/headers/26/inspector/main_thread_interface.h +116 -0
  120. package/src/headers/26/inspector/network_agent.h +110 -0
  121. package/src/headers/26/inspector/network_inspector.h +45 -0
  122. package/src/headers/26/inspector/network_requests_buffer.h +195 -0
  123. package/src/headers/26/inspector/network_resource_manager.h +29 -0
  124. package/src/headers/26/inspector/node_json.h +24 -0
  125. package/src/headers/26/inspector/node_string.h +101 -0
  126. package/src/headers/26/inspector/notification_emitter.h +38 -0
  127. package/src/headers/26/inspector/protocol_helper.h +27 -0
  128. package/src/headers/26/inspector/runtime_agent.h +41 -0
  129. package/src/headers/26/inspector/storage_agent.h +33 -0
  130. package/src/headers/26/inspector/target_agent.h +59 -0
  131. package/src/headers/26/inspector/target_manager.h +70 -0
  132. package/src/headers/26/inspector/tracing_agent.h +43 -0
  133. package/src/headers/26/inspector/worker_agent.h +40 -0
  134. package/src/headers/26/inspector/worker_inspector.h +124 -0
  135. package/src/headers/26/inspector_agent.h +168 -0
  136. package/src/headers/26/inspector_io.h +78 -0
  137. package/src/headers/26/inspector_profiler.h +149 -0
  138. package/src/headers/26/inspector_socket.h +60 -0
  139. package/src/headers/26/inspector_socket_server.h +110 -0
  140. package/src/headers/26/js_native_api.h +634 -0
  141. package/src/headers/26/js_native_api_types.h +244 -0
  142. package/src/headers/26/js_native_api_v8.h +485 -0
  143. package/src/headers/26/js_native_api_v8_internals.h +45 -0
  144. package/src/headers/26/js_stream.h +57 -0
  145. package/src/headers/26/json_utils.h +172 -0
  146. package/src/headers/26/large_pages/node_large_page.h +34 -0
  147. package/src/headers/26/lru_cache-inl.h +69 -0
  148. package/src/headers/26/memory_tracker-inl.h +461 -0
  149. package/src/headers/26/memory_tracker.h +341 -0
  150. package/src/headers/26/module_wrap.h +231 -0
  151. package/src/headers/26/ncrypto.h +2008 -0
  152. package/src/headers/26/node.h +1693 -0
  153. package/src/headers/26/node_api.h +265 -0
  154. package/src/headers/26/node_api_internals.h +48 -0
  155. package/src/headers/26/node_api_types.h +58 -0
  156. package/src/headers/26/node_binding.h +170 -0
  157. package/src/headers/26/node_blob.h +160 -0
  158. package/src/headers/26/node_bob-inl.h +36 -0
  159. package/src/headers/26/node_bob.h +107 -0
  160. package/src/headers/26/node_buffer.h +92 -0
  161. package/src/headers/26/node_builtins.h +239 -0
  162. package/src/headers/26/node_concepts.h +46 -0
  163. package/src/headers/26/node_config_file.h +77 -0
  164. package/src/headers/26/node_constants.h +82 -0
  165. package/src/headers/26/node_context_data.h +171 -0
  166. package/src/headers/26/node_contextify.h +261 -0
  167. package/src/headers/26/node_crypto.h +66 -0
  168. package/src/headers/26/node_debug.h +30 -0
  169. package/src/headers/26/node_diagnostics_channel.h +121 -0
  170. package/src/headers/26/node_dir.h +52 -0
  171. package/src/headers/26/node_dotenv.h +45 -0
  172. package/src/headers/26/node_errors.h +378 -0
  173. package/src/headers/26/node_exit_code.h +54 -0
  174. package/src/headers/26/node_external_reference.h +171 -0
  175. package/src/headers/26/node_ffi.h +212 -0
  176. package/src/headers/26/node_file-inl.h +421 -0
  177. package/src/headers/26/node_file.h +561 -0
  178. package/src/headers/26/node_file_utils.h +39 -0
  179. package/src/headers/26/node_hash.h +212 -0
  180. package/src/headers/26/node_http2.h +1202 -0
  181. package/src/headers/26/node_http2_state.h +159 -0
  182. package/src/headers/26/node_http_common-inl.h +199 -0
  183. package/src/headers/26/node_http_common.h +535 -0
  184. package/src/headers/26/node_i18n.h +132 -0
  185. package/src/headers/26/node_internals.h +485 -0
  186. package/src/headers/26/node_locks.h +184 -0
  187. package/src/headers/26/node_main_instance.h +67 -0
  188. package/src/headers/26/node_mem-inl.h +113 -0
  189. package/src/headers/26/node_mem.h +45 -0
  190. package/src/headers/26/node_messaging.h +389 -0
  191. package/src/headers/26/node_metadata.h +172 -0
  192. package/src/headers/26/node_modules.h +102 -0
  193. package/src/headers/26/node_mutex.h +323 -0
  194. package/src/headers/26/node_object_wrap.h +145 -0
  195. package/src/headers/26/node_options-inl.h +524 -0
  196. package/src/headers/26/node_options.h +710 -0
  197. package/src/headers/26/node_perf.h +167 -0
  198. package/src/headers/26/node_perf_common.h +103 -0
  199. package/src/headers/26/node_platform.h +290 -0
  200. package/src/headers/26/node_process-inl.h +26 -0
  201. package/src/headers/26/node_process.h +112 -0
  202. package/src/headers/26/node_profiling.h +38 -0
  203. package/src/headers/26/node_realm-inl.h +156 -0
  204. package/src/headers/26/node_realm.h +236 -0
  205. package/src/headers/26/node_report.h +43 -0
  206. package/src/headers/26/node_revert.h +82 -0
  207. package/src/headers/26/node_root_certs.h +2937 -0
  208. package/src/headers/26/node_sea.h +101 -0
  209. package/src/headers/26/node_shadow_realm.h +46 -0
  210. package/src/headers/26/node_snapshot_builder.h +57 -0
  211. package/src/headers/26/node_snapshotable.h +167 -0
  212. package/src/headers/26/node_sockaddr-inl.h +248 -0
  213. package/src/headers/26/node_sockaddr.h +459 -0
  214. package/src/headers/26/node_sqlite.h +607 -0
  215. package/src/headers/26/node_stat_watcher.h +73 -0
  216. package/src/headers/26/node_task_runner.h +92 -0
  217. package/src/headers/26/node_threadsafe_cow-inl.h +54 -0
  218. package/src/headers/26/node_threadsafe_cow.h +105 -0
  219. package/src/headers/26/node_union_bytes.h +81 -0
  220. package/src/headers/26/node_url.h +101 -0
  221. package/src/headers/26/node_url_pattern.h +118 -0
  222. package/src/headers/26/node_v8.h +78 -0
  223. package/src/headers/26/node_v8_embedder.h +26 -0
  224. package/src/headers/26/node_v8_platform-inl.h +96 -0
  225. package/src/headers/26/node_version.h +116 -0
  226. package/src/headers/26/node_wasi.h +184 -0
  227. package/src/headers/26/node_wasm_web_api.h +55 -0
  228. package/src/headers/26/node_watchdog.h +164 -0
  229. package/src/headers/26/node_webstorage.h +62 -0
  230. package/src/headers/26/node_worker.h +162 -0
  231. package/src/headers/26/path.h +36 -0
  232. package/src/headers/26/permission/boolean_permission.h +50 -0
  233. package/src/headers/26/permission/fs_permission.h +192 -0
  234. package/src/headers/26/permission/permission.h +155 -0
  235. package/src/headers/26/permission/permission_base.h +79 -0
  236. package/src/headers/26/pipe_wrap.h +80 -0
  237. package/src/headers/26/quic/application.h +279 -0
  238. package/src/headers/26/quic/arena.h +373 -0
  239. package/src/headers/26/quic/bindingdata.h +440 -0
  240. package/src/headers/26/quic/cid.h +127 -0
  241. package/src/headers/26/quic/data.h +358 -0
  242. package/src/headers/26/quic/defs.h +417 -0
  243. package/src/headers/26/quic/endpoint.h +519 -0
  244. package/src/headers/26/quic/guard.h +5 -0
  245. package/src/headers/26/quic/http3.h +25 -0
  246. package/src/headers/26/quic/packet.h +166 -0
  247. package/src/headers/26/quic/preferredaddress.h +72 -0
  248. package/src/headers/26/quic/session.h +770 -0
  249. package/src/headers/26/quic/session_manager.h +107 -0
  250. package/src/headers/26/quic/sessionticket.h +110 -0
  251. package/src/headers/26/quic/streams.h +518 -0
  252. package/src/headers/26/quic/tlscontext.h +353 -0
  253. package/src/headers/26/quic/tokens.h +263 -0
  254. package/src/headers/26/quic/transportparams.h +184 -0
  255. package/src/headers/26/req_wrap-inl.h +175 -0
  256. package/src/headers/26/req_wrap.h +79 -0
  257. package/src/headers/26/spawn_sync.h +243 -0
  258. package/src/headers/26/stream_base-inl.h +170 -0
  259. package/src/headers/26/stream_base.h +487 -0
  260. package/src/headers/26/stream_pipe.h +76 -0
  261. package/src/headers/26/stream_wrap.h +137 -0
  262. package/src/headers/26/string_bytes.h +114 -0
  263. package/src/headers/26/string_decoder-inl.h +31 -0
  264. package/src/headers/26/string_decoder.h +49 -0
  265. package/src/headers/26/tcp_wrap.h +138 -0
  266. package/src/headers/26/threadpoolwork-inl.h +70 -0
  267. package/src/headers/26/timer_wrap-inl.h +32 -0
  268. package/src/headers/26/timer_wrap.h +87 -0
  269. package/src/headers/26/timers.h +70 -0
  270. package/src/headers/26/tracing/agent.h +125 -0
  271. package/src/headers/26/tracing/agent_legacy.h +146 -0
  272. package/src/headers/26/tracing/agent_perfetto.h +145 -0
  273. package/src/headers/26/tracing/node_trace_buffer.h +91 -0
  274. package/src/headers/26/tracing/node_trace_writer.h +79 -0
  275. package/src/headers/26/tracing/trace_event.h +27 -0
  276. package/src/headers/26/tracing/trace_event_helper.h +40 -0
  277. package/src/headers/26/tracing/trace_event_legacy.h +1113 -0
  278. package/src/headers/26/tracing/trace_event_legacy_inl.h +711 -0
  279. package/src/headers/26/tracing/trace_event_perfetto.h +47 -0
  280. package/src/headers/26/tracing/traced_value.h +167 -0
  281. package/src/headers/26/tty_wrap.h +65 -0
  282. package/src/headers/26/udp_wrap.h +231 -0
  283. package/src/headers/26/undici_version.h +6 -0
  284. package/src/headers/26/util-inl.h +788 -0
  285. package/src/headers/26/util.h +1207 -0
  286. package/src/headers/26/v8-cpp-heap-external.h +56 -0
  287. package/src/headers/26/v8-external-memory-accounter.h +60 -0
  288. package/src/headers/26/v8-fast-api-calls.h +784 -0
  289. package/src/headers/26/v8-inspector-protocol.h +13 -0
  290. package/src/headers/26/v8-inspector.h +458 -0
  291. package/src/headers/26/v8-metrics.h +273 -0
  292. package/src/headers/26/v8-trace-categories.h +28 -0
  293. package/src/headers/26/v8-unwinder-state.h +30 -0
  294. package/src/headers/26/v8-util.h +549 -0
  295. package/src/headers/26/v8-value-serializer-version.h +24 -0
  296. package/src/headers/26/v8-version-string.h +38 -0
  297. package/src/headers/26/v8-wasm-trap-handler-posix.h +31 -0
  298. package/src/headers/26/v8-wasm-trap-handler-win.h +28 -0
  299. package/src/headers/26/zlib_version.h +6 -0
  300. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Info.plist +0 -20
  301. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Resources/DWARF/cws_darwin_arm64_node115.node +0 -0
  302. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Resources/Relocations/aarch64/cws_darwin_arm64_node115.node.yml +0 -931
  303. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Info.plist +0 -20
  304. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Resources/DWARF/cws_darwin_arm64_node127.node +0 -0
  305. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Resources/Relocations/aarch64/cws_darwin_arm64_node127.node.yml +0 -931
@@ -0,0 +1,775 @@
1
+ #ifndef SRC_CRYPTO_CRYPTO_UTIL_H_
2
+ #define SRC_CRYPTO_CRYPTO_UTIL_H_
3
+
4
+ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
+
6
+ #include "async_wrap.h"
7
+ #include "env.h"
8
+ #include "node_errors.h"
9
+ #include "node_external_reference.h"
10
+ #include "node_internals.h"
11
+ #include "string_bytes.h"
12
+ #include "util.h"
13
+ #include "v8.h"
14
+
15
+ #include "ncrypto.h"
16
+
17
+ #include <algorithm>
18
+ #include <climits>
19
+ #include <cstdio>
20
+ #include <memory>
21
+ #include <optional>
22
+ #include <string>
23
+ #include <vector>
24
+
25
+ #if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(OPENSSL_NO_COMP_ALG)
26
+ #define NODE_OPENSSL_HAS_CERT_COMP 1
27
+ #endif
28
+
29
+ namespace node {
30
+ namespace crypto {
31
+ class ByteSource;
32
+ }
33
+
34
+ template <>
35
+ struct MemoryRetainerTraits<crypto::ByteSource> {
36
+ static void MemoryInfo(MemoryTracker* tracker,
37
+ const crypto::ByteSource& value);
38
+ static const char* MemoryInfoName(const crypto::ByteSource& value);
39
+ static size_t SelfSize(const crypto::ByteSource& value);
40
+ };
41
+ } // namespace node
42
+
43
+ namespace node::crypto {
44
+ // Currently known sizes of commonly used OpenSSL struct sizes.
45
+ // OpenSSL considers it's various structs to be opaque and the
46
+ // sizes may change from one version of OpenSSL to another, so
47
+ // these values should not be trusted to remain static. These
48
+ // are provided to allow for some close to reasonable memory
49
+ // tracking.
50
+ constexpr size_t kSizeOf_DH = 144;
51
+ constexpr size_t kSizeOf_EC_KEY = 80;
52
+ constexpr size_t kSizeOf_EVP_CIPHER_CTX = 168;
53
+ constexpr size_t kSizeOf_EVP_MD_CTX = 48;
54
+ constexpr size_t kSizeOf_EVP_PKEY = 72;
55
+ constexpr size_t kSizeOf_EVP_PKEY_CTX = 80;
56
+ constexpr size_t kSizeOf_HMAC_CTX = 32;
57
+ constexpr size_t kSizeOf_SSL_CTX = 240;
58
+ constexpr size_t kSizeOf_X509 = 128;
59
+
60
+ template <typename T>
61
+ constexpr T NumBitsToBytes(T bits) {
62
+ return (bits / CHAR_BIT) + ((CHAR_BIT - 1 + (bits % CHAR_BIT)) / CHAR_BIT);
63
+ }
64
+
65
+ // Applies the FIPS related command line options. Returns a description of
66
+ // what went wrong, or std::nullopt when there was nothing to do or the
67
+ // options were applied successfully.
68
+ std::optional<std::string> ProcessFipsOptions();
69
+ bool IsFipsEnabled();
70
+
71
+ bool InitCryptoOnce(v8::Isolate* isolate);
72
+ void InitCryptoOnce();
73
+
74
+ void InitCrypto(v8::Local<v8::Object> target);
75
+
76
+ extern void UseExtraCaCerts(std::string_view file);
77
+ void CleanupCachedRootCertificates();
78
+
79
+ int PasswordCallback(char* buf, int size, int rwflag, void* u);
80
+ int NoPasswordCallback(char* buf, int size, int rwflag, void* u);
81
+
82
+ // Decode is used by the various stream-based crypto utilities to decode
83
+ // string input.
84
+ template <typename T>
85
+ void Decode(const v8::FunctionCallbackInfo<v8::Value>& args,
86
+ void (*callback)(T*, const v8::FunctionCallbackInfo<v8::Value>&,
87
+ const char*, size_t)) {
88
+ T* ctx;
89
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.This());
90
+
91
+ if (args[0]->IsString()) {
92
+ StringBytes::InlineDecoder decoder;
93
+ Environment* env = Environment::GetCurrent(args);
94
+ enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
95
+ if (decoder.Decode(env, args[0].As<v8::String>(), enc).IsNothing())
96
+ return;
97
+ callback(ctx, args, decoder.out(), decoder.size());
98
+ } else {
99
+ ArrayBufferViewContents<char> buf(args[0]);
100
+ callback(ctx, args, buf.data(), buf.length());
101
+ }
102
+ }
103
+
104
+ #define NODE_CRYPTO_ERROR_CODES_MAP(V) \
105
+ V(ALLOCATION_FAILED, "Failed to allocate output buffer") \
106
+ V(ARGON2_FAILED, "Argon2 derivation failed") \
107
+ V(CIPHER_JOB_FAILED, "Cipher job failed") \
108
+ V(CONTEXT_UNSUPPORTED, "Context parameter is unsupported") \
109
+ V(DECAPSULATION_FAILED, "Decapsulation failed") \
110
+ V(DERIVING_BITS_FAILED, "Deriving bits failed") \
111
+ V(ECDH_FAILED, "ECDH key agreement failed") \
112
+ V(ENCAPSULATION_FAILED, "Encapsulation failed") \
113
+ V(ENGINE_NOT_FOUND, "Engine \"%s\" was not found") \
114
+ V(HKDF_FAILED, "HKDF derivation failed") \
115
+ V(INVALID_KEY_TYPE, "Invalid key type") \
116
+ V(KEY_GENERATION_JOB_FAILED, "Key generation job failed") \
117
+ V(KMAC_FAILED, "KMAC derivation failed") \
118
+ V(OK, "Ok") \
119
+ V(PBKDF2_FAILED, "PBKDF2 derivation failed") \
120
+ V(SCRYPT_FAILED, "scrypt derivation failed")
121
+
122
+ enum class NodeCryptoError {
123
+ #define V(CODE, DESCRIPTION) CODE,
124
+ NODE_CRYPTO_ERROR_CODES_MAP(V)
125
+ #undef V
126
+ };
127
+
128
+ template <typename... Args>
129
+ std::string getNodeCryptoErrorString(const NodeCryptoError error,
130
+ Args&&... args) {
131
+ const char* error_string = nullptr;
132
+ switch (error) {
133
+ #define V(CODE, DESCRIPTION) \
134
+ case NodeCryptoError::CODE: \
135
+ error_string = DESCRIPTION; \
136
+ break;
137
+ NODE_CRYPTO_ERROR_CODES_MAP(V)
138
+ #undef V
139
+ }
140
+ return SPrintF(error_string, std::forward<Args>(args)...);
141
+ }
142
+
143
+ // Utility struct used to harvest error information from openssl's error stack
144
+ struct CryptoErrorStore final : public MemoryRetainer {
145
+ public:
146
+ void Capture();
147
+
148
+ bool Empty() const;
149
+
150
+ template <typename... Args>
151
+ void Insert(const NodeCryptoError error, Args&&... args);
152
+
153
+ v8::MaybeLocal<v8::Value> ToException(
154
+ Environment* env,
155
+ v8::Local<v8::String> exception_string = v8::Local<v8::String>()) const;
156
+
157
+ void SetNodeErrorCode(const char* code) { node_error_code_ = code; }
158
+
159
+ SET_NO_MEMORY_INFO()
160
+ SET_MEMORY_INFO_NAME(CryptoErrorStore)
161
+ SET_SELF_SIZE(CryptoErrorStore)
162
+
163
+ private:
164
+ std::vector<std::string> errors_;
165
+ unsigned long primary_openssl_error_ = 0; // NOLINT(runtime/int)
166
+ const char* node_error_code_ = nullptr;
167
+ };
168
+
169
+ template <typename... Args>
170
+ void CryptoErrorStore::Insert(const NodeCryptoError error, Args&&... args) {
171
+ const char* error_string = nullptr;
172
+ switch (error) {
173
+ #define V(CODE, DESCRIPTION) \
174
+ case NodeCryptoError::CODE: error_string = DESCRIPTION; break;
175
+ NODE_CRYPTO_ERROR_CODES_MAP(V)
176
+ #undef V
177
+ }
178
+ errors_.emplace_back(SPrintF(error_string,
179
+ std::forward<Args>(args)...));
180
+ }
181
+
182
+ v8::MaybeLocal<v8::Value> cryptoErrorListToException(
183
+ Environment* env, const ncrypto::CryptoErrorList& errors);
184
+
185
+ template <typename T>
186
+ T* MallocOpenSSL(size_t count) {
187
+ void* mem = OPENSSL_malloc(MultiplyWithOverflowCheck(count, sizeof(T)));
188
+ CHECK_IMPLIES(mem == nullptr, count == 0);
189
+ return static_cast<T*>(mem);
190
+ }
191
+
192
+ // A helper class representing a read-only byte array. When deallocated, its
193
+ // contents are zeroed.
194
+ class ByteSource final {
195
+ public:
196
+ ByteSource() = default;
197
+ ByteSource(ByteSource&& other) noexcept;
198
+ ~ByteSource();
199
+
200
+ ByteSource& operator=(ByteSource&& other) noexcept;
201
+
202
+ ByteSource(const ByteSource&) = delete;
203
+ ByteSource& operator=(const ByteSource&) = delete;
204
+
205
+ template <typename T = void>
206
+ inline const T* data() const {
207
+ return reinterpret_cast<const T*>(data_);
208
+ }
209
+
210
+ template <typename T = void>
211
+ operator ncrypto::Buffer<const T>() const {
212
+ return ncrypto::Buffer<const T>{
213
+ .data = data<T>(),
214
+ .len = size(),
215
+ };
216
+ }
217
+
218
+ inline size_t size() const { return size_; }
219
+
220
+ inline bool empty() const { return size_ == 0; }
221
+
222
+ inline operator bool() const { return data_ != nullptr; }
223
+
224
+ inline ncrypto::BignumPointer ToBN() const {
225
+ return ncrypto::BignumPointer(data<unsigned char>(), size());
226
+ }
227
+
228
+ // Creates a v8::BackingStore that takes over responsibility for
229
+ // any allocated data. The ByteSource will be reset with size = 0
230
+ // after being called.
231
+ std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(Environment* env);
232
+
233
+ v8::Local<v8::ArrayBuffer> ToArrayBuffer(Environment* env);
234
+
235
+ v8::MaybeLocal<v8::Uint8Array> ToBuffer(Environment* env);
236
+
237
+ static ByteSource Allocated(void* data, size_t size);
238
+
239
+ template <typename T>
240
+ static ByteSource Allocated(const ncrypto::Buffer<T>& buffer) {
241
+ return Allocated(buffer.data, buffer.len);
242
+ }
243
+
244
+ static ByteSource Foreign(const void* data, size_t size);
245
+
246
+ static ByteSource FromEncodedString(Environment* env,
247
+ v8::Local<v8::String> value,
248
+ enum encoding enc = BASE64);
249
+
250
+ static ByteSource FromStringOrBuffer(Environment* env,
251
+ v8::Local<v8::Value> value);
252
+
253
+ static ByteSource FromString(Environment* env,
254
+ v8::Local<v8::String> str,
255
+ bool ntc = false);
256
+
257
+ static ByteSource FromBuffer(v8::Local<v8::Value> buffer,
258
+ bool ntc = false);
259
+
260
+ static ByteSource FromBIO(const ncrypto::BIOPointer& bio);
261
+
262
+ static ByteSource NullTerminatedCopy(Environment* env,
263
+ v8::Local<v8::Value> value);
264
+
265
+ static ByteSource FromSymmetricKeyObjectHandle(v8::Local<v8::Value> handle);
266
+
267
+ static ByteSource FromSecretKeyBytes(
268
+ Environment* env, v8::Local<v8::Value> value);
269
+
270
+ private:
271
+ friend struct node::MemoryRetainerTraits<ByteSource>;
272
+ friend void TruncateToBitLength(size_t length_bits, ByteSource* bytes);
273
+
274
+ const void* data_ = nullptr;
275
+ void* allocated_data_ = nullptr;
276
+ size_t size_ = 0;
277
+
278
+ ByteSource(const void* data, void* allocated_data, size_t size)
279
+ : data_(data), allocated_data_(allocated_data), size_(size) {}
280
+ };
281
+
282
+ void TruncateToBitLength(size_t length_bits, ByteSource* bytes);
283
+
284
+ enum CryptoJobMode { kCryptoJobAsync, kCryptoJobSync, kCryptoJobWebCrypto };
285
+
286
+ CryptoJobMode GetCryptoJobMode(v8::Local<v8::Value> args);
287
+ bool IsCryptoJobAsync(CryptoJobMode mode);
288
+
289
+ v8::MaybeLocal<v8::Value> CreateWebCryptoJobError(Environment* env,
290
+ v8::Local<v8::Value> cause);
291
+
292
+ v8::MaybeLocal<v8::Value> ToWebCryptoJobResult(Environment* env,
293
+ v8::Local<v8::Value> value);
294
+
295
+ template <typename CryptoJobTraits>
296
+ class CryptoJob : public AsyncWrap, public ThreadPoolWork {
297
+ public:
298
+ using AdditionalParams = typename CryptoJobTraits::AdditionalParameters;
299
+
300
+ explicit CryptoJob(Environment* env,
301
+ v8::Local<v8::Object> object,
302
+ AsyncWrap::ProviderType type,
303
+ CryptoJobMode mode,
304
+ AdditionalParams&& params)
305
+ : AsyncWrap(env, object, type),
306
+ ThreadPoolWork(env, "crypto"),
307
+ mode_(mode),
308
+ params_(std::move(params)) {
309
+ // If the CryptoJob is async, then the instance will be
310
+ // cleaned up when AfterThreadPoolWork is called.
311
+ if (mode == kCryptoJobSync) MakeWeak();
312
+ }
313
+
314
+ bool IsNotIndicativeOfMemoryLeakAtExit() const override {
315
+ // CryptoJobs run a work in the libuv thread pool and may still
316
+ // exist when the event loop empties and starts to exit.
317
+ return true;
318
+ }
319
+
320
+ void AfterThreadPoolWork(int status) override {
321
+ Environment* env = AsyncWrap::env();
322
+ CHECK(IsCryptoJobAsync(mode_));
323
+ CHECK(status == 0 || status == UV_ECANCELED);
324
+ std::unique_ptr<CryptoJob> ptr(this);
325
+ if (mode_ == kCryptoJobWebCrypto) {
326
+ v8::HandleScope handle_scope(env->isolate());
327
+ v8::Context::Scope context_scope(env->context());
328
+ InternalCallbackScope callback_scope(this);
329
+
330
+ if (status == UV_ECANCELED) {
331
+ v8::Local<v8::Value> exception = v8::Exception::Error(
332
+ OneByteString(env->isolate(), "The operation was canceled"));
333
+ ptr->RejectWebCrypto(exception);
334
+ return;
335
+ }
336
+
337
+ v8::Local<v8::Value> err;
338
+ v8::Local<v8::Value> result;
339
+ {
340
+ node::errors::TryCatchScope try_catch(env);
341
+ if (ptr->ToResult(&err, &result).IsNothing()) {
342
+ CHECK(try_catch.HasCaught());
343
+ CHECK(try_catch.CanContinue());
344
+ err = try_catch.Exception();
345
+ }
346
+ }
347
+
348
+ if (!err.IsEmpty() && !err->IsUndefined()) {
349
+ ptr->RejectWebCrypto(err);
350
+ return;
351
+ }
352
+
353
+ CHECK(!result.IsEmpty());
354
+ v8::Local<v8::Value> webcrypto_result;
355
+ {
356
+ node::errors::TryCatchScope try_catch(env);
357
+ if (!ToWebCryptoJobResult(env, result).ToLocal(&webcrypto_result)) {
358
+ CHECK(try_catch.HasCaught());
359
+ CHECK(try_catch.CanContinue());
360
+ ptr->RejectWebCrypto(try_catch.Exception());
361
+ return;
362
+ }
363
+ }
364
+
365
+ ptr->ResolveWebCrypto(webcrypto_result);
366
+ return;
367
+ }
368
+
369
+ // If the job was canceled do not execute the callback.
370
+ // TODO(@jasnell): We should likely revisit skipping the
371
+ // callback on cancel as that could leave the JS in a pending
372
+ // state (e.g. unresolved promises...)
373
+ if (status == UV_ECANCELED) return;
374
+ v8::HandleScope handle_scope(env->isolate());
375
+ v8::Context::Scope context_scope(env->context());
376
+
377
+ v8::Local<v8::Value> exception;
378
+ v8::Local<v8::Value> args[2];
379
+ {
380
+ node::errors::TryCatchScope try_catch(env);
381
+ // If ToResult returns Nothing, then an exception should have been
382
+ // thrown and we should have caught it. Otherwise, args[0] and args[1]
383
+ // both should have been set to a value, even if the value is undefined.
384
+ if (ptr->ToResult(&args[0], &args[1]).IsNothing()) {
385
+ CHECK(try_catch.HasCaught());
386
+ CHECK(try_catch.CanContinue());
387
+ exception = try_catch.Exception();
388
+ }
389
+ }
390
+
391
+ if (!exception.IsEmpty()) {
392
+ ptr->MakeCallback(env->ondone_string(), 1, &exception);
393
+ } else {
394
+ CHECK(!args[0].IsEmpty());
395
+ CHECK(!args[1].IsEmpty());
396
+ ptr->MakeCallback(env->ondone_string(), arraysize(args), args);
397
+ }
398
+ }
399
+
400
+ virtual v8::Maybe<void> ToResult(v8::Local<v8::Value>* err,
401
+ v8::Local<v8::Value>* result) = 0;
402
+
403
+ CryptoJobMode mode() const { return mode_; }
404
+
405
+ CryptoErrorStore* errors() { return &errors_; }
406
+
407
+ AdditionalParams* params() { return &params_; }
408
+
409
+ const char* MemoryInfoName() const override {
410
+ return CryptoJobTraits::JobName;
411
+ }
412
+
413
+ void MemoryInfo(MemoryTracker* tracker) const override {
414
+ tracker->TrackField("params", params_);
415
+ tracker->TrackField("errors", errors_);
416
+ }
417
+
418
+ static void Run(const v8::FunctionCallbackInfo<v8::Value>& args) {
419
+ Environment* env = Environment::GetCurrent(args);
420
+
421
+ CryptoJob<CryptoJobTraits>* job;
422
+ ASSIGN_OR_RETURN_UNWRAP(&job, args.This());
423
+ if (job->mode() == kCryptoJobWebCrypto) {
424
+ v8::Local<v8::Promise::Resolver> resolver;
425
+ if (!v8::Promise::Resolver::New(env->context()).ToLocal(&resolver)) {
426
+ return;
427
+ }
428
+
429
+ CHECK(job->resolver_.IsEmpty());
430
+ job->resolver_.Reset(env->isolate(), resolver);
431
+ args.GetReturnValue().Set(resolver->GetPromise());
432
+
433
+ return job->ScheduleWork();
434
+ }
435
+
436
+ if (job->mode() == kCryptoJobAsync)
437
+ return job->ScheduleWork();
438
+
439
+ v8::Local<v8::Value> ret[2];
440
+ env->PrintSyncTrace();
441
+ job->DoThreadPoolWork();
442
+ if (job->ToResult(&ret[0], &ret[1]).IsJust()) {
443
+ CHECK(!ret[0].IsEmpty());
444
+ CHECK(!ret[1].IsEmpty());
445
+ args.GetReturnValue().Set(
446
+ v8::Array::New(env->isolate(), ret, arraysize(ret)));
447
+ }
448
+ }
449
+
450
+ static void Initialize(
451
+ v8::FunctionCallback new_fn,
452
+ Environment* env,
453
+ v8::Local<v8::Object> target) {
454
+ v8::Isolate* isolate = env->isolate();
455
+ v8::HandleScope scope(isolate);
456
+ v8::Local<v8::Context> context = env->context();
457
+ v8::Local<v8::FunctionTemplate> job = NewFunctionTemplate(isolate, new_fn);
458
+ job->Inherit(AsyncWrap::GetConstructorTemplate(env));
459
+ job->InstanceTemplate()->SetInternalFieldCount(
460
+ CryptoJob::kInternalFieldCount);
461
+ SetProtoMethod(isolate, job, "run", Run);
462
+ SetConstructorFunction(context, target, CryptoJobTraits::JobName, job);
463
+ }
464
+
465
+ static void RegisterExternalReferences(v8::FunctionCallback new_fn,
466
+ ExternalReferenceRegistry* registry) {
467
+ registry->Register(new_fn);
468
+ registry->Register(Run);
469
+ }
470
+
471
+ private:
472
+ void ResolveWebCrypto(v8::Local<v8::Value> value) {
473
+ Environment* env = AsyncWrap::env();
474
+ v8::Local<v8::Context> context = env->context();
475
+ v8::Local<v8::Promise::Resolver> resolver =
476
+ v8::Local<v8::Promise::Resolver>::New(env->isolate(), resolver_);
477
+
478
+ bool should_delete_then = false;
479
+ v8::Local<v8::String> then_key;
480
+ v8::Local<v8::Value> exception;
481
+ {
482
+ node::errors::TryCatchScope try_catch(env);
483
+ if (value->IsObject()) {
484
+ then_key = env->then_string();
485
+ v8::Local<v8::Object> object = value.As<v8::Object>();
486
+ v8::Maybe<bool> has_own_then =
487
+ object->HasOwnProperty(context, then_key);
488
+ if (has_own_then.IsNothing()) {
489
+ if (try_catch.HasCaught() && try_catch.CanContinue()) {
490
+ exception = try_catch.Exception();
491
+ }
492
+ } else if (!has_own_then.FromJust()) {
493
+ if (object
494
+ ->DefineOwnProperty(context,
495
+ then_key,
496
+ v8::Undefined(env->isolate()),
497
+ v8::DontEnum)
498
+ .FromMaybe(false)) {
499
+ should_delete_then = true;
500
+ } else if (try_catch.HasCaught() && try_catch.CanContinue()) {
501
+ exception = try_catch.Exception();
502
+ } else {
503
+ exception = v8::Exception::Error(OneByteString(
504
+ env->isolate(), "Failed to prepare WebCrypto job result"));
505
+ }
506
+ }
507
+ }
508
+
509
+ if (exception.IsEmpty() && resolver->Resolve(context, value).IsJust()) {
510
+ if (should_delete_then) {
511
+ USE(value.As<v8::Object>()->Delete(context, then_key));
512
+ }
513
+ resolver_.Reset();
514
+ return;
515
+ }
516
+ if (try_catch.HasCaught() && try_catch.CanContinue()) {
517
+ exception = try_catch.Exception();
518
+ }
519
+ }
520
+
521
+ if (should_delete_then) {
522
+ USE(value.As<v8::Object>()->Delete(context, then_key));
523
+ }
524
+ if (!exception.IsEmpty()) {
525
+ USE(resolver->Reject(context, exception));
526
+ }
527
+ resolver_.Reset();
528
+ }
529
+
530
+ void RejectWebCrypto(v8::Local<v8::Value> cause) {
531
+ Environment* env = AsyncWrap::env();
532
+ v8::Local<v8::Value> exception;
533
+ if (!CreateWebCryptoJobError(env, cause).ToLocal(&exception)) {
534
+ exception = cause;
535
+ }
536
+ v8::Local<v8::Promise::Resolver> resolver =
537
+ v8::Local<v8::Promise::Resolver>::New(env->isolate(), resolver_);
538
+ USE(resolver->Reject(env->context(), exception));
539
+ resolver_.Reset();
540
+ }
541
+
542
+ const CryptoJobMode mode_;
543
+ CryptoErrorStore errors_;
544
+ AdditionalParams params_;
545
+ v8::Global<v8::Promise::Resolver> resolver_;
546
+ };
547
+
548
+ template <typename DeriveBitsTraits>
549
+ class DeriveBitsJob final : public CryptoJob<DeriveBitsTraits> {
550
+ public:
551
+ using AdditionalParams = typename DeriveBitsTraits::AdditionalParameters;
552
+
553
+ static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
554
+ Environment* env = Environment::GetCurrent(args);
555
+
556
+ CryptoJobMode mode = GetCryptoJobMode(args[0]);
557
+
558
+ AdditionalParams params;
559
+ if (DeriveBitsTraits::AdditionalConfig(mode, args, 1, &params)
560
+ .IsNothing()) {
561
+ // The DeriveBitsTraits::AdditionalConfig is responsible for
562
+ // calling an appropriate THROW_CRYPTO_* variant reporting
563
+ // whatever error caused initialization to fail.
564
+ return;
565
+ }
566
+
567
+ new DeriveBitsJob(env, args.This(), mode, std::move(params));
568
+ }
569
+
570
+ static void Initialize(
571
+ Environment* env,
572
+ v8::Local<v8::Object> target) {
573
+ CryptoJob<DeriveBitsTraits>::Initialize(New, env, target);
574
+ }
575
+
576
+ static void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
577
+ CryptoJob<DeriveBitsTraits>::RegisterExternalReferences(New, registry);
578
+ }
579
+
580
+ DeriveBitsJob(Environment* env,
581
+ v8::Local<v8::Object> object,
582
+ CryptoJobMode mode,
583
+ AdditionalParams&& params)
584
+ : CryptoJob<DeriveBitsTraits>(
585
+ env, object, DeriveBitsTraits::Provider, mode, std::move(params)) {}
586
+
587
+ void DoThreadPoolWork() override {
588
+ ncrypto::ClearErrorOnReturn clear_error_on_return;
589
+ CryptoErrorStore* errors = CryptoJob<DeriveBitsTraits>::errors();
590
+ if (!DeriveBitsTraits::DeriveBits(AsyncWrap::env(),
591
+ *CryptoJob<DeriveBitsTraits>::params(),
592
+ &out_,
593
+ this->mode(),
594
+ errors)) {
595
+ if (errors->Empty()) errors->Capture();
596
+ if (errors->Empty()) {
597
+ errors->Insert(NodeCryptoError::DERIVING_BITS_FAILED);
598
+ errors->SetNodeErrorCode("ERR_CRYPTO_OPERATION_FAILED");
599
+ }
600
+ return;
601
+ }
602
+ success_ = true;
603
+ }
604
+
605
+ v8::Maybe<void> ToResult(v8::Local<v8::Value>* err,
606
+ v8::Local<v8::Value>* result) override {
607
+ Environment* env = AsyncWrap::env();
608
+ CryptoErrorStore* errors = CryptoJob<DeriveBitsTraits>::errors();
609
+ if (success_) {
610
+ CHECK(errors->Empty());
611
+ *err = v8::Undefined(env->isolate());
612
+ if (!DeriveBitsTraits::EncodeOutput(
613
+ env, *CryptoJob<DeriveBitsTraits>::params(), &out_)
614
+ .ToLocal(result)) {
615
+ return v8::Nothing<void>();
616
+ }
617
+ } else {
618
+ if (errors->Empty()) errors->Capture();
619
+ CHECK(!errors->Empty());
620
+ *result = v8::Undefined(env->isolate());
621
+ if (!errors->ToException(env).ToLocal(err)) {
622
+ return v8::Nothing<void>();
623
+ }
624
+ }
625
+ CHECK(!result->IsEmpty());
626
+ CHECK(!err->IsEmpty());
627
+ return v8::JustVoid();
628
+ }
629
+
630
+ SET_SELF_SIZE(DeriveBitsJob)
631
+ void MemoryInfo(MemoryTracker* tracker) const override {
632
+ tracker->TraitTrackInline(out_, "out");
633
+ CryptoJob<DeriveBitsTraits>::MemoryInfo(tracker);
634
+ }
635
+
636
+ private:
637
+ ByteSource out_;
638
+ bool success_ = false;
639
+ };
640
+
641
+ void ThrowCryptoError(Environment* env,
642
+ unsigned long err, // NOLINT(runtime/int)
643
+ const char* message = nullptr);
644
+
645
+ // WebIDL AllowSharedBufferSource.
646
+ inline bool IsAnyBufferSource(v8::Local<v8::Value> arg) {
647
+ return arg->IsArrayBufferView() ||
648
+ arg->IsArrayBuffer() ||
649
+ arg->IsSharedArrayBuffer();
650
+ }
651
+
652
+ template <typename T>
653
+ class ArrayBufferOrViewContents final {
654
+ public:
655
+ ArrayBufferOrViewContents() = default;
656
+ ArrayBufferOrViewContents(const ArrayBufferOrViewContents&) = delete;
657
+ void operator=(const ArrayBufferOrViewContents&) = delete;
658
+
659
+ inline explicit ArrayBufferOrViewContents(v8::Local<v8::Value> buf) {
660
+ if (buf.IsEmpty()) {
661
+ return;
662
+ }
663
+
664
+ CHECK(IsAnyBufferSource(buf));
665
+ if (buf->IsArrayBufferView()) {
666
+ auto view = buf.As<v8::ArrayBufferView>();
667
+ offset_ = view->ByteOffset();
668
+ length_ = view->ByteLength();
669
+ data_ = view->Buffer()->Data();
670
+ } else if (buf->IsArrayBuffer()) {
671
+ auto ab = buf.As<v8::ArrayBuffer>();
672
+ offset_ = 0;
673
+ length_ = ab->ByteLength();
674
+ data_ = ab->Data();
675
+ } else {
676
+ auto sab = buf.As<v8::SharedArrayBuffer>();
677
+ offset_ = 0;
678
+ length_ = sab->ByteLength();
679
+ data_ = sab->Data();
680
+ }
681
+ }
682
+
683
+ inline const T* data() const {
684
+ // Ideally, these would return nullptr if IsEmpty() or length_ is zero,
685
+ // but some of the openssl API react badly if given a nullptr even when
686
+ // length is zero, so we have to return something.
687
+ if (empty()) return &buf;
688
+ return reinterpret_cast<T*>(data_) + offset_;
689
+ }
690
+
691
+ inline T* data() {
692
+ // Ideally, these would return nullptr if IsEmpty() or length_ is zero,
693
+ // but some of the openssl API react badly if given a nullptr even when
694
+ // length is zero, so we have to return something.
695
+ if (empty()) return &buf;
696
+ return reinterpret_cast<T*>(data_) + offset_;
697
+ }
698
+
699
+ inline size_t size() const { return length_; }
700
+
701
+ inline bool empty() const { return length_ == 0; }
702
+
703
+ // In most cases, input buffer sizes passed in to openssl need to
704
+ // be limited to <= INT_MAX. This utility method helps us check.
705
+ inline bool CheckSizeInt32() { return size() <= INT_MAX; }
706
+
707
+ inline ByteSource ToByteSource() const {
708
+ return ByteSource::Foreign(data(), size());
709
+ }
710
+
711
+ inline ByteSource ToCopy() const {
712
+ if (empty()) return {};
713
+ auto buf = ncrypto::DataPointer::Alloc(size());
714
+ memcpy(buf.get(), data(), size());
715
+ return ByteSource::Allocated(buf.release());
716
+ }
717
+
718
+ inline ByteSource ToNullTerminatedCopy() const {
719
+ if (empty()) return {};
720
+ auto buf = ncrypto::DataPointer::Alloc(size() + 1);
721
+ memcpy(buf.get(), data(), size());
722
+ static_cast<char*>(buf.get())[size()] = 0;
723
+ return ByteSource::Allocated(buf.release());
724
+ }
725
+
726
+ inline ncrypto::DataPointer ToDataPointer() const {
727
+ if (empty()) return {};
728
+ if (auto dp = ncrypto::DataPointer::Alloc(size())) {
729
+ memcpy(dp.get(), data(), size());
730
+ return dp;
731
+ }
732
+ return {};
733
+ }
734
+
735
+ template <typename M>
736
+ requires(sizeof(M) == 1)
737
+ void CopyTo(M* dest, size_t len) const {
738
+ len = std::min(len, size());
739
+ if (len > 0 && data() != nullptr) {
740
+ memcpy(dest, data(), len);
741
+ }
742
+ }
743
+
744
+ private:
745
+ T buf = 0;
746
+ size_t offset_ = 0;
747
+ size_t length_ = 0;
748
+ void* data_ = nullptr;
749
+
750
+ // Declaring operator new and delete as deleted is not spec compliant.
751
+ // Therefore declare them private instead to disable dynamic alloc
752
+ void* operator new(size_t);
753
+ void* operator new[](size_t);
754
+ void operator delete(void*);
755
+ void operator delete[](void*);
756
+ };
757
+
758
+ v8::MaybeLocal<v8::Value> EncodeBignum(Environment* env,
759
+ const BIGNUM* bn,
760
+ int size);
761
+
762
+ v8::Maybe<void> SetEncodedValue(Environment* env,
763
+ v8::Local<v8::Object> target,
764
+ v8::Local<v8::String> name,
765
+ const BIGNUM* bn,
766
+ int size = 0);
767
+
768
+ namespace Util {
769
+ void Initialize(Environment* env, v8::Local<v8::Object> target);
770
+ void RegisterExternalReferences(ExternalReferenceRegistry* registry);
771
+ } // namespace Util
772
+ } // namespace node::crypto
773
+
774
+ #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
775
+ #endif // SRC_CRYPTO_CRYPTO_UTIL_H_