@encharm/cws 4.5.2 → 4.6.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 (284) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/CLAUDE.md +81 -0
  3. package/README.md +10 -5
  4. package/dist/bindings/cws_darwin_arm64_node115.node +0 -0
  5. package/dist/bindings/cws_darwin_arm64_node127.node +0 -0
  6. package/dist/bindings/cws_darwin_arm64_node137.node +0 -0
  7. package/dist/bindings/cws_darwin_arm64_node147.node +0 -0
  8. package/dist/bindings/cws_linux_arm64_node115.node +0 -0
  9. package/dist/bindings/cws_linux_arm64_node127.node +0 -0
  10. package/dist/bindings/cws_linux_arm64_node137.node +0 -0
  11. package/dist/bindings/cws_linux_arm64_node147.node +0 -0
  12. package/dist/bindings/cws_linux_x64_node115.node +0 -0
  13. package/dist/bindings/cws_linux_x64_node127.node +0 -0
  14. package/dist/bindings/cws_linux_x64_node137.node +0 -0
  15. package/dist/bindings/cws_linux_x64_node147.node +0 -0
  16. package/dist/bindings/cws_win32_x64_node115.node +0 -0
  17. package/dist/bindings/cws_win32_x64_node127.node +0 -0
  18. package/dist/bindings/cws_win32_x64_node137.node +0 -0
  19. package/dist/bindings/cws_win32_x64_node147.node +0 -0
  20. package/package.json +1 -1
  21. package/src/Addon.cpp +2 -1
  22. package/src/Addon.h +70 -14
  23. package/src/Hub.h +1 -0
  24. package/src/Networking.h +11 -0
  25. package/src/Socket.h +201 -6
  26. package/src/WebSocket.cpp +4 -1
  27. package/src/cSNode.cpp +2 -0
  28. package/src/cSNode.h +4 -0
  29. package/src/headers/24/tracing/agent.h +195 -0
  30. package/src/headers/24/tracing/trace_event.h +722 -0
  31. package/src/headers/26/acorn_version.h +6 -0
  32. package/src/headers/26/aliased_buffer-inl.h +264 -0
  33. package/src/headers/26/aliased_buffer.h +205 -0
  34. package/src/headers/26/aliased_struct-inl.h +143 -0
  35. package/src/headers/26/aliased_struct.h +248 -0
  36. package/src/headers/26/amaro_version.h +6 -0
  37. package/src/headers/26/async_context_frame.h +33 -0
  38. package/src/headers/26/async_wrap-inl.h +123 -0
  39. package/src/headers/26/async_wrap.h +254 -0
  40. package/src/headers/26/base_object-inl.h +333 -0
  41. package/src/headers/26/base_object.h +339 -0
  42. package/src/headers/26/base_object_types.h +76 -0
  43. package/src/headers/26/blob_serializer_deserializer-inl.h +385 -0
  44. package/src/headers/26/blob_serializer_deserializer.h +142 -0
  45. package/src/headers/26/builtin_info.h +57 -0
  46. package/src/headers/26/callback_queue-inl.h +97 -0
  47. package/src/headers/26/callback_queue.h +79 -0
  48. package/src/headers/26/cares_wrap.h +475 -0
  49. package/src/headers/26/cleanup_queue-inl.h +36 -0
  50. package/src/headers/26/cleanup_queue.h +79 -0
  51. package/src/headers/26/compile_cache.h +134 -0
  52. package/src/headers/26/connect_wrap.h +26 -0
  53. package/src/headers/26/connection_wrap.h +30 -0
  54. package/src/headers/26/cppgc_helpers-inl.h +69 -0
  55. package/src/headers/26/cppgc_helpers.h +162 -0
  56. package/src/headers/26/crypto/crypto_aes.h +107 -0
  57. package/src/headers/26/crypto/crypto_argon2.h +88 -0
  58. package/src/headers/26/crypto/crypto_bio.h +193 -0
  59. package/src/headers/26/crypto/crypto_chacha20_poly1305.h +62 -0
  60. package/src/headers/26/crypto/crypto_cipher.h +291 -0
  61. package/src/headers/26/crypto/crypto_common.h +48 -0
  62. package/src/headers/26/crypto/crypto_context.h +219 -0
  63. package/src/headers/26/crypto/crypto_dh.h +104 -0
  64. package/src/headers/26/crypto/crypto_dsa.h +50 -0
  65. package/src/headers/26/crypto/crypto_ec.h +102 -0
  66. package/src/headers/26/crypto/crypto_hash.h +157 -0
  67. package/src/headers/26/crypto/crypto_hkdf.h +62 -0
  68. package/src/headers/26/crypto/crypto_hmac.h +92 -0
  69. package/src/headers/26/crypto/crypto_kem.h +131 -0
  70. package/src/headers/26/crypto/crypto_keygen.h +382 -0
  71. package/src/headers/26/crypto/crypto_keys.h +366 -0
  72. package/src/headers/26/crypto/crypto_kmac.h +79 -0
  73. package/src/headers/26/crypto/crypto_pbkdf2.h +76 -0
  74. package/src/headers/26/crypto/crypto_pqc.h +39 -0
  75. package/src/headers/26/crypto/crypto_random.h +127 -0
  76. package/src/headers/26/crypto/crypto_rsa.h +108 -0
  77. package/src/headers/26/crypto/crypto_scrypt.h +85 -0
  78. package/src/headers/26/crypto/crypto_sig.h +159 -0
  79. package/src/headers/26/crypto/crypto_spkac.h +21 -0
  80. package/src/headers/26/crypto/crypto_timing.h +20 -0
  81. package/src/headers/26/crypto/crypto_tls.h +342 -0
  82. package/src/headers/26/crypto/crypto_turboshake.h +105 -0
  83. package/src/headers/26/crypto/crypto_util.h +775 -0
  84. package/src/headers/26/crypto/crypto_x509.h +140 -0
  85. package/src/headers/26/dataqueue/queue.h +311 -0
  86. package/src/headers/26/debug_utils-inl.h +291 -0
  87. package/src/headers/26/debug_utils.h +200 -0
  88. package/src/headers/26/diagnosticfilename-inl.h +33 -0
  89. package/src/headers/26/embedded_data.h +17 -0
  90. package/src/headers/26/encoding_binding.h +59 -0
  91. package/src/headers/26/env-inl.h +956 -0
  92. package/src/headers/26/env.h +1294 -0
  93. package/src/headers/26/env_properties.h +562 -0
  94. package/src/headers/26/ffi/data.h +30 -0
  95. package/src/headers/26/ffi/fast.h +96 -0
  96. package/src/headers/26/ffi/jit_memory.h +26 -0
  97. package/src/headers/26/ffi/types.h +99 -0
  98. package/src/headers/26/handle_wrap.h +123 -0
  99. package/src/headers/26/histogram-inl.h +211 -0
  100. package/src/headers/26/histogram.h +474 -0
  101. package/src/headers/26/inspector/dom_storage_agent.h +68 -0
  102. package/src/headers/26/inspector/inspector_object_utils.h +38 -0
  103. package/src/headers/26/inspector/io_agent.h +30 -0
  104. package/src/headers/26/inspector/main_thread_interface.h +116 -0
  105. package/src/headers/26/inspector/network_agent.h +110 -0
  106. package/src/headers/26/inspector/network_inspector.h +45 -0
  107. package/src/headers/26/inspector/network_requests_buffer.h +195 -0
  108. package/src/headers/26/inspector/network_resource_manager.h +29 -0
  109. package/src/headers/26/inspector/node_json.h +24 -0
  110. package/src/headers/26/inspector/node_string.h +101 -0
  111. package/src/headers/26/inspector/notification_emitter.h +38 -0
  112. package/src/headers/26/inspector/protocol_helper.h +27 -0
  113. package/src/headers/26/inspector/runtime_agent.h +41 -0
  114. package/src/headers/26/inspector/storage_agent.h +33 -0
  115. package/src/headers/26/inspector/target_agent.h +59 -0
  116. package/src/headers/26/inspector/target_manager.h +70 -0
  117. package/src/headers/26/inspector/tracing_agent.h +43 -0
  118. package/src/headers/26/inspector/worker_agent.h +40 -0
  119. package/src/headers/26/inspector/worker_inspector.h +124 -0
  120. package/src/headers/26/inspector_agent.h +168 -0
  121. package/src/headers/26/inspector_io.h +78 -0
  122. package/src/headers/26/inspector_profiler.h +149 -0
  123. package/src/headers/26/inspector_socket.h +60 -0
  124. package/src/headers/26/inspector_socket_server.h +110 -0
  125. package/src/headers/26/js_native_api.h +634 -0
  126. package/src/headers/26/js_native_api_types.h +244 -0
  127. package/src/headers/26/js_native_api_v8.h +485 -0
  128. package/src/headers/26/js_native_api_v8_internals.h +45 -0
  129. package/src/headers/26/js_stream.h +57 -0
  130. package/src/headers/26/json_utils.h +172 -0
  131. package/src/headers/26/large_pages/node_large_page.h +34 -0
  132. package/src/headers/26/lru_cache-inl.h +69 -0
  133. package/src/headers/26/memory_tracker-inl.h +461 -0
  134. package/src/headers/26/memory_tracker.h +341 -0
  135. package/src/headers/26/module_wrap.h +231 -0
  136. package/src/headers/26/ncrypto.h +2008 -0
  137. package/src/headers/26/node.h +1693 -0
  138. package/src/headers/26/node_api.h +265 -0
  139. package/src/headers/26/node_api_internals.h +48 -0
  140. package/src/headers/26/node_api_types.h +58 -0
  141. package/src/headers/26/node_binding.h +170 -0
  142. package/src/headers/26/node_blob.h +160 -0
  143. package/src/headers/26/node_bob-inl.h +36 -0
  144. package/src/headers/26/node_bob.h +107 -0
  145. package/src/headers/26/node_buffer.h +92 -0
  146. package/src/headers/26/node_builtins.h +239 -0
  147. package/src/headers/26/node_concepts.h +46 -0
  148. package/src/headers/26/node_config_file.h +77 -0
  149. package/src/headers/26/node_constants.h +82 -0
  150. package/src/headers/26/node_context_data.h +171 -0
  151. package/src/headers/26/node_contextify.h +261 -0
  152. package/src/headers/26/node_crypto.h +66 -0
  153. package/src/headers/26/node_debug.h +30 -0
  154. package/src/headers/26/node_diagnostics_channel.h +121 -0
  155. package/src/headers/26/node_dir.h +52 -0
  156. package/src/headers/26/node_dotenv.h +45 -0
  157. package/src/headers/26/node_errors.h +378 -0
  158. package/src/headers/26/node_exit_code.h +54 -0
  159. package/src/headers/26/node_external_reference.h +171 -0
  160. package/src/headers/26/node_ffi.h +212 -0
  161. package/src/headers/26/node_file-inl.h +421 -0
  162. package/src/headers/26/node_file.h +561 -0
  163. package/src/headers/26/node_file_utils.h +39 -0
  164. package/src/headers/26/node_hash.h +212 -0
  165. package/src/headers/26/node_http2.h +1202 -0
  166. package/src/headers/26/node_http2_state.h +159 -0
  167. package/src/headers/26/node_http_common-inl.h +199 -0
  168. package/src/headers/26/node_http_common.h +535 -0
  169. package/src/headers/26/node_i18n.h +132 -0
  170. package/src/headers/26/node_internals.h +485 -0
  171. package/src/headers/26/node_locks.h +184 -0
  172. package/src/headers/26/node_main_instance.h +67 -0
  173. package/src/headers/26/node_mem-inl.h +113 -0
  174. package/src/headers/26/node_mem.h +45 -0
  175. package/src/headers/26/node_messaging.h +389 -0
  176. package/src/headers/26/node_metadata.h +172 -0
  177. package/src/headers/26/node_modules.h +102 -0
  178. package/src/headers/26/node_mutex.h +323 -0
  179. package/src/headers/26/node_object_wrap.h +145 -0
  180. package/src/headers/26/node_options-inl.h +524 -0
  181. package/src/headers/26/node_options.h +710 -0
  182. package/src/headers/26/node_perf.h +167 -0
  183. package/src/headers/26/node_perf_common.h +103 -0
  184. package/src/headers/26/node_platform.h +290 -0
  185. package/src/headers/26/node_process-inl.h +26 -0
  186. package/src/headers/26/node_process.h +112 -0
  187. package/src/headers/26/node_profiling.h +38 -0
  188. package/src/headers/26/node_realm-inl.h +156 -0
  189. package/src/headers/26/node_realm.h +236 -0
  190. package/src/headers/26/node_report.h +43 -0
  191. package/src/headers/26/node_revert.h +82 -0
  192. package/src/headers/26/node_root_certs.h +2937 -0
  193. package/src/headers/26/node_sea.h +101 -0
  194. package/src/headers/26/node_shadow_realm.h +46 -0
  195. package/src/headers/26/node_snapshot_builder.h +57 -0
  196. package/src/headers/26/node_snapshotable.h +167 -0
  197. package/src/headers/26/node_sockaddr-inl.h +248 -0
  198. package/src/headers/26/node_sockaddr.h +459 -0
  199. package/src/headers/26/node_sqlite.h +607 -0
  200. package/src/headers/26/node_stat_watcher.h +73 -0
  201. package/src/headers/26/node_task_runner.h +92 -0
  202. package/src/headers/26/node_threadsafe_cow-inl.h +54 -0
  203. package/src/headers/26/node_threadsafe_cow.h +105 -0
  204. package/src/headers/26/node_union_bytes.h +81 -0
  205. package/src/headers/26/node_url.h +101 -0
  206. package/src/headers/26/node_url_pattern.h +118 -0
  207. package/src/headers/26/node_v8.h +78 -0
  208. package/src/headers/26/node_v8_embedder.h +26 -0
  209. package/src/headers/26/node_v8_platform-inl.h +96 -0
  210. package/src/headers/26/node_version.h +116 -0
  211. package/src/headers/26/node_wasi.h +184 -0
  212. package/src/headers/26/node_wasm_web_api.h +55 -0
  213. package/src/headers/26/node_watchdog.h +164 -0
  214. package/src/headers/26/node_webstorage.h +62 -0
  215. package/src/headers/26/node_worker.h +162 -0
  216. package/src/headers/26/path.h +36 -0
  217. package/src/headers/26/permission/boolean_permission.h +50 -0
  218. package/src/headers/26/permission/fs_permission.h +192 -0
  219. package/src/headers/26/permission/permission.h +155 -0
  220. package/src/headers/26/permission/permission_base.h +79 -0
  221. package/src/headers/26/pipe_wrap.h +80 -0
  222. package/src/headers/26/quic/application.h +279 -0
  223. package/src/headers/26/quic/arena.h +373 -0
  224. package/src/headers/26/quic/bindingdata.h +440 -0
  225. package/src/headers/26/quic/cid.h +127 -0
  226. package/src/headers/26/quic/data.h +358 -0
  227. package/src/headers/26/quic/defs.h +417 -0
  228. package/src/headers/26/quic/endpoint.h +519 -0
  229. package/src/headers/26/quic/guard.h +5 -0
  230. package/src/headers/26/quic/http3.h +25 -0
  231. package/src/headers/26/quic/packet.h +166 -0
  232. package/src/headers/26/quic/preferredaddress.h +72 -0
  233. package/src/headers/26/quic/session.h +770 -0
  234. package/src/headers/26/quic/session_manager.h +107 -0
  235. package/src/headers/26/quic/sessionticket.h +110 -0
  236. package/src/headers/26/quic/streams.h +518 -0
  237. package/src/headers/26/quic/tlscontext.h +353 -0
  238. package/src/headers/26/quic/tokens.h +263 -0
  239. package/src/headers/26/quic/transportparams.h +184 -0
  240. package/src/headers/26/req_wrap-inl.h +175 -0
  241. package/src/headers/26/req_wrap.h +79 -0
  242. package/src/headers/26/spawn_sync.h +243 -0
  243. package/src/headers/26/stream_base-inl.h +170 -0
  244. package/src/headers/26/stream_base.h +487 -0
  245. package/src/headers/26/stream_pipe.h +76 -0
  246. package/src/headers/26/stream_wrap.h +137 -0
  247. package/src/headers/26/string_bytes.h +114 -0
  248. package/src/headers/26/string_decoder-inl.h +31 -0
  249. package/src/headers/26/string_decoder.h +49 -0
  250. package/src/headers/26/tcp_wrap.h +138 -0
  251. package/src/headers/26/threadpoolwork-inl.h +70 -0
  252. package/src/headers/26/timer_wrap-inl.h +32 -0
  253. package/src/headers/26/timer_wrap.h +87 -0
  254. package/src/headers/26/timers.h +70 -0
  255. package/src/headers/26/tracing/agent.h +125 -0
  256. package/src/headers/26/tracing/agent_legacy.h +146 -0
  257. package/src/headers/26/tracing/agent_perfetto.h +145 -0
  258. package/src/headers/26/tracing/node_trace_buffer.h +91 -0
  259. package/src/headers/26/tracing/node_trace_writer.h +79 -0
  260. package/src/headers/26/tracing/trace_event.h +27 -0
  261. package/src/headers/26/tracing/trace_event_helper.h +40 -0
  262. package/src/headers/26/tracing/trace_event_legacy.h +1113 -0
  263. package/src/headers/26/tracing/trace_event_legacy_inl.h +711 -0
  264. package/src/headers/26/tracing/trace_event_perfetto.h +47 -0
  265. package/src/headers/26/tracing/traced_value.h +167 -0
  266. package/src/headers/26/tty_wrap.h +65 -0
  267. package/src/headers/26/udp_wrap.h +231 -0
  268. package/src/headers/26/undici_version.h +6 -0
  269. package/src/headers/26/util-inl.h +788 -0
  270. package/src/headers/26/util.h +1207 -0
  271. package/src/headers/26/v8-cpp-heap-external.h +56 -0
  272. package/src/headers/26/v8-external-memory-accounter.h +60 -0
  273. package/src/headers/26/v8-fast-api-calls.h +784 -0
  274. package/src/headers/26/v8-inspector-protocol.h +13 -0
  275. package/src/headers/26/v8-inspector.h +458 -0
  276. package/src/headers/26/v8-metrics.h +273 -0
  277. package/src/headers/26/v8-trace-categories.h +28 -0
  278. package/src/headers/26/v8-unwinder-state.h +30 -0
  279. package/src/headers/26/v8-util.h +549 -0
  280. package/src/headers/26/v8-value-serializer-version.h +24 -0
  281. package/src/headers/26/v8-version-string.h +38 -0
  282. package/src/headers/26/v8-wasm-trap-handler-posix.h +31 -0
  283. package/src/headers/26/v8-wasm-trap-handler-win.h +28 -0
  284. package/src/headers/26/zlib_version.h +6 -0
@@ -0,0 +1,353 @@
1
+ #pragma once
2
+
3
+ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4
+
5
+ #include <base_object.h>
6
+ #include <crypto/crypto_context.h>
7
+ #include <crypto/crypto_keys.h>
8
+ #include <memory_tracker.h>
9
+ #include <ncrypto.h>
10
+ #include <ngtcp2/ngtcp2_crypto.h>
11
+ #include <ngtcp2/ngtcp2_crypto_ossl.h>
12
+ #include <unordered_map>
13
+ #include "bindingdata.h"
14
+ #include "data.h"
15
+ #include "defs.h"
16
+ #include "sessionticket.h"
17
+
18
+ namespace node::quic {
19
+
20
+ class Session;
21
+ class TLSContext;
22
+
23
+ #if OPENSSL_IS_BORING
24
+ static_assert(false,
25
+ "This implementation of tlscontext relies on OpenSSL APIS "
26
+ "that are not available in BoringSSL. An alternative impl "
27
+ "using the equivalent BoringSSL APIs is possible but not "
28
+ "yet implemented.");
29
+ #endif
30
+
31
+ // The OSSLContext is a wrapper around the ngtcp2_crypto_ossl_ctx that
32
+ // holds the state for the OpenSSL TLS session. The ngtcp2_crypto_ossl_ctx
33
+ // is required by ngtcp2's adapter for OpenSSL.
34
+ class OSSLContext final {
35
+ public:
36
+ OSSLContext();
37
+ ~OSSLContext();
38
+ DISALLOW_COPY_AND_MOVE(OSSLContext)
39
+
40
+ operator SSL*() const;
41
+ operator ngtcp2_crypto_ossl_ctx*() const;
42
+
43
+ void Initialize(SSL* ssl,
44
+ ngtcp2_crypto_conn_ref* ref,
45
+ ngtcp2_conn* connection,
46
+ SSL_CTX* ssl_ctx);
47
+
48
+ std::string_view get_cipher_name() const;
49
+ std::string get_selected_alpn() const;
50
+ std::string_view get_negotiated_group() const;
51
+
52
+ bool set_alpn_protocols(std::string_view protocols) const;
53
+ bool set_hostname(std::string_view hostname) const;
54
+ bool set_verify_hostname(std::string_view hostname) const;
55
+ bool set_early_data_enabled() const;
56
+ bool set_transport_params(const ngtcp2_vec& tp) const;
57
+
58
+ bool get_early_data_accepted() const;
59
+ bool get_early_data_rejected() const;
60
+ bool get_early_data_attempted() const;
61
+
62
+ // Sets the session ticket for 0-RTT resumption. Returns true if the
63
+ // ticket was set successfully and the ticket supports early data.
64
+ bool set_session_ticket(const ncrypto::SSLSessionPointer& ticket);
65
+
66
+ bool ConfigureServer() const;
67
+ bool ConfigureClient() const;
68
+
69
+ void reset();
70
+ inline operator bool() const { return ctx_ != nullptr; }
71
+
72
+ private:
73
+ ngtcp2_crypto_ossl_ctx* ctx_;
74
+ ngtcp2_conn* connection_ = nullptr;
75
+ };
76
+
77
+ // Every QUIC Session has exactly one TLSSession that maintains the state
78
+ // of the TLS handshake and negotiated keys after the handshake has been
79
+ // completed. It is separated out from the main Session class only as a
80
+ // convenience to help make the code more maintainable and understandable.
81
+ // A TLSSession is created from a TLSContext and maintains a reference to
82
+ // the context.
83
+ class TLSSession final : public MemoryRetainer {
84
+ public:
85
+ // TODO(@jasnell): In order to support using QUIC with host embedders
86
+ // like Electron, we need to abstract the TLSContext and TLSSession
87
+ // more so that they can use either the OpenSSL 3.5 or BoringSSL APIs.
88
+ // This can be done by creatig an internal TLSSession::Impl and
89
+ // TLSContext::Impl abstractions that can be implemented using either
90
+ // of the two APIs, keeping the TLSSession and TLSContext APIs the same
91
+ // for each.
92
+
93
+ // Gets the TLSSession from the SSL pointer app data.
94
+ static const TLSSession& From(const SSL* ssl);
95
+
96
+ // The constructor is public in order to satisfy the call to std::make_unique
97
+ // in TLSContext::NewSession. It should not be called directly.
98
+ TLSSession(Session* session,
99
+ std::shared_ptr<TLSContext> context,
100
+ const std::optional<SessionTicket>& maybeSessionTicket);
101
+ DISALLOW_COPY_AND_MOVE(TLSSession)
102
+
103
+ inline bool is_valid() const { return ossl_context_; }
104
+ inline operator bool() const { return is_valid(); }
105
+ inline Session& session() const { return *session_; }
106
+ inline TLSContext& context() const { return *context_; }
107
+
108
+ // Returns true if the handshake has been completed and early data was
109
+ // accepted by the TLS session. This will assert if the handshake has
110
+ // not been completed.
111
+ bool early_data_was_accepted() const;
112
+ bool early_data_was_rejected() const;
113
+ bool early_data_was_attempted() const;
114
+
115
+ v8::MaybeLocal<v8::Object> cert(Environment* env) const;
116
+ v8::MaybeLocal<v8::Object> peer_cert(Environment* env) const;
117
+ v8::MaybeLocal<v8::Object> ephemeral_key(Environment* env) const;
118
+ v8::MaybeLocal<v8::Value> cipher_name(Environment* env) const;
119
+ v8::MaybeLocal<v8::Value> cipher_version(Environment* env) const;
120
+
121
+ // The SNI (server name) negotiated for the session
122
+ const std::string_view servername() const;
123
+
124
+ // The ALPN (protocol name) negotiated for the session
125
+ const std::string protocol() const;
126
+
127
+ // Triggers key update to begin. This will fail and return false if either a
128
+ // previous key update is in progress or if the initial handshake has not yet
129
+ // been confirmed.
130
+ bool InitiateKeyUpdate();
131
+
132
+ struct PeerIdentityValidationError {
133
+ v8::MaybeLocal<v8::Value> reason;
134
+ v8::MaybeLocal<v8::Value> code;
135
+ };
136
+
137
+ // Checks the peer identity against the configured CA and CRL. If the peer
138
+ // certificate is valid, std::nullopt is returned. Otherwise a
139
+ // PeerIdentityValidationError is returned with the reason and code for the
140
+ // failure. If there was an error setting the reason or code, the fields
141
+ // will be empty but the PeerIdentityValidationError will still be returned.
142
+ // This is an indication that an exception has been scheduled by v8.
143
+ std::optional<PeerIdentityValidationError> VerifyPeerIdentity(
144
+ Environment* env);
145
+
146
+ inline std::string_view validation_error() const { return validation_error_; }
147
+
148
+ void MemoryInfo(MemoryTracker* tracker) const override;
149
+ SET_MEMORY_INFO_NAME(TLSSession)
150
+ SET_SELF_SIZE(TLSSession)
151
+
152
+ private:
153
+ operator SSL*() const;
154
+ void Initialize(const std::optional<SessionTicket>& maybeSessionTicket);
155
+
156
+ static ngtcp2_conn* connection(ngtcp2_crypto_conn_ref* ref);
157
+
158
+ ngtcp2_crypto_conn_ref ref_;
159
+ std::shared_ptr<TLSContext> context_;
160
+ OSSLContext ossl_context_;
161
+ Session* session_;
162
+ ncrypto::BIOPointer bio_trace_;
163
+ std::string validation_error_ = "";
164
+ };
165
+
166
+ // The TLSContext is used to create a TLSSession. For the client, there is
167
+ // typically only a single TLSContext for each TLSSession. For the server,
168
+ // there is a single TLSContext for the server and a TLSSession for every
169
+ // QUIC session created by that server.
170
+ class TLSContext final : public MemoryRetainer,
171
+ public std::enable_shared_from_this<TLSContext> {
172
+ public:
173
+ static constexpr auto DEFAULT_CIPHERS = "TLS_AES_128_GCM_SHA256:"
174
+ "TLS_AES_256_GCM_SHA384:"
175
+ "TLS_CHACHA20_POLY1305_"
176
+ "SHA256:TLS_AES_128_CCM_SHA256";
177
+ static constexpr auto DEFAULT_GROUPS = "X25519:P-256:P-384:P-521";
178
+
179
+ struct Options final : public MemoryRetainer {
180
+ // The SNI servername to use for this session. This option is only used by
181
+ // the client.
182
+ std::string servername = "localhost";
183
+
184
+ // The ALPN protocol identifier(s) in wire format (length-prefixed,
185
+ // concatenated). For clients this is a single entry. For servers
186
+ // this may contain multiple entries in preference order.
187
+ std::string alpn = NGHTTP3_ALPN_H3;
188
+
189
+ // The list of TLS ciphers to use for this session.
190
+ std::string ciphers = DEFAULT_CIPHERS;
191
+
192
+ // The list of TLS groups to use for this session.
193
+ std::string groups = DEFAULT_GROUPS;
194
+
195
+ // TLS certificate compression (RFC 8879) preference, packed by the JS
196
+ // layer as (length | alg0<<8 | alg1<<16 | alg2<<24). Algorithm IDs match
197
+ // OpenSSL's TLSEXT_comp_cert_zlib (1), _brotli (2), _zstd (3). A value of
198
+ // 0 means certificate compression is disabled (the default). Certificate
199
+ // compression is particularly valuable for QUIC because it reduces the
200
+ // size of the server's Certificate message, which is otherwise likely to
201
+ // exceed the anti-amplification limit and force an extra handshake round
202
+ // trip. JavaScript option name "certificateCompression".
203
+ uint32_t certificate_compression = 0;
204
+
205
+ // When true, enables keylog output for the session.
206
+ bool keylog = false;
207
+
208
+ // When true, the peer certificate is verified against the list of supplied
209
+ // CA. If verification fails, the connection will be refused. When set,
210
+ // instructs the server session to request a client auth certificate. This
211
+ // option is only used by the server side.
212
+ bool verify_client = false;
213
+
214
+ // When true (the default), client certificates that fail chain
215
+ // validation are rejected during the handshake. When false, the
216
+ // handshake completes and the validation result is passed to JS
217
+ // via the handshake callback for the application to decide.
218
+ // This option is only used by the server side.
219
+ bool reject_unauthorized = true;
220
+
221
+ // When true, the client will set SSL_VERIFY_PEER so that OpenSSL
222
+ // aborts the handshake if the server's certificate fails validation.
223
+ // This is the "strict" verify_peer mode. When false (the default),
224
+ // the handshake completes regardless and VerifyPeerIdentity is
225
+ // called after to surface errors to JS. This option is only used
226
+ // by the client side.
227
+ bool verify_peer_strict = false;
228
+
229
+ // When true, OpenSSL verifies that the server's certificate matches
230
+ // the servername (hostname verification via SSL_set1_host). Should
231
+ // be true for 'strict' and 'auto' verifyPeer modes, false for
232
+ // 'manual'. Without this, a valid certificate for any domain would
233
+ // be accepted. This option is only used by the client side.
234
+ bool verify_hostname = false;
235
+
236
+ // When true (the default), the server accepts 0-RTT early data
237
+ // from clients with valid session tickets. When false, early data
238
+ // is disabled and clients must complete a full handshake before
239
+ // sending application data. Disabling early data prevents replay
240
+ // attacks at the cost of an additional round trip.
241
+ // This option is only used by the server side.
242
+ bool enable_early_data = true;
243
+
244
+ // When true, enables TLS tracing for the session. This should only be used
245
+ // for debugging.
246
+ // JavaScript option name "tlsTrace".
247
+ bool enable_tls_trace = false;
248
+
249
+ // When true, causes the private key passed in for the session to be
250
+ // verified.
251
+ // JavaScript option name "verifyPrivateKey"
252
+ bool verify_private_key = false;
253
+
254
+ // The TLS private key(s) to use for this session.
255
+ // JavaScript option name "keys"
256
+ std::vector<crypto::KeyObjectData> keys;
257
+
258
+ // Collection of certificates to use for this session.
259
+ // JavaScript option name "certs"
260
+ std::vector<Store> certs;
261
+
262
+ // Optional certificate authority overrides to use.
263
+ // JavaScript option name "ca"
264
+ std::vector<Store> ca;
265
+
266
+ // Optional certificate revocation lists to use.
267
+ // JavaScript option name "crl"
268
+ std::vector<Store> crl;
269
+
270
+ // The port to advertise in ORIGIN frames for this hostname.
271
+ // Defaults to 443 (the standard HTTPS port). Only relevant for
272
+ // server-side SNI entries used with HTTP/3.
273
+ uint16_t port = 443;
274
+
275
+ // Whether this hostname should be included in ORIGIN frames.
276
+ // Only relevant for server-side SNI entries.
277
+ bool authoritative = true;
278
+
279
+ void MemoryInfo(MemoryTracker* tracker) const override;
280
+ SET_MEMORY_INFO_NAME(TLSContext::Options)
281
+ SET_SELF_SIZE(Options)
282
+
283
+ // The default TLS configuration.
284
+ static const Options kDefault;
285
+
286
+ static v8::Maybe<Options> From(Environment* env,
287
+ v8::Local<v8::Value> value);
288
+
289
+ std::string ToString() const;
290
+ };
291
+
292
+ static std::shared_ptr<TLSContext> CreateClient(Environment* env,
293
+ const Options& options);
294
+ static std::shared_ptr<TLSContext> CreateServer(Environment* env,
295
+ const Options& options);
296
+
297
+ TLSContext(Environment* env, Side side, const Options& options);
298
+ DISALLOW_COPY_AND_MOVE(TLSContext)
299
+
300
+ // Each QUIC Session has exactly one TLSSession. Each TLSSession maintains
301
+ // a reference to the TLSContext used to create it.
302
+ std::unique_ptr<TLSSession> NewSession(
303
+ Session* session, const std::optional<SessionTicket>& maybeSessionTicket);
304
+
305
+ bool AddSNIContext(Environment* env,
306
+ const std::string& hostname,
307
+ const Options& options);
308
+
309
+ bool SetSNIContexts(Environment* env,
310
+ const std::unordered_map<std::string, Options>& entries);
311
+
312
+ inline Side side() const { return side_; }
313
+ inline const Options& options() const { return options_; }
314
+ inline operator bool() const { return ctx_ != nullptr; }
315
+ inline operator const ncrypto::SSLCtxPointer&() const { return ctx_; }
316
+
317
+ inline const std::string_view validation_error() const {
318
+ return validation_error_;
319
+ }
320
+
321
+ void MemoryInfo(MemoryTracker* tracker) const override;
322
+ SET_MEMORY_INFO_NAME(TLSContext)
323
+ SET_SELF_SIZE(TLSContext)
324
+
325
+ private:
326
+ ncrypto::SSLCtxPointer Initialize(Environment* env);
327
+ operator SSL_CTX*() const;
328
+
329
+ static void OnKeylog(const SSL* ssl, const char* line);
330
+ static int OnNewSession(SSL* ssl, SSL_SESSION* session);
331
+ static int OnSelectAlpn(SSL* ssl,
332
+ const unsigned char** out,
333
+ unsigned char* outlen,
334
+ const unsigned char* in,
335
+ unsigned int inlen,
336
+ void* arg);
337
+ static int OnVerifyClientCertificate(int preverify_ok, X509_STORE_CTX* ctx);
338
+ static int OnSNI(SSL* ssl, int* ad, void* arg);
339
+
340
+ Side side_;
341
+ Options options_;
342
+ ncrypto::X509Pointer cert_;
343
+ ncrypto::X509Pointer issuer_;
344
+ std::string validation_error_ = "";
345
+ ncrypto::SSLCtxPointer ctx_;
346
+ std::unordered_map<std::string, std::shared_ptr<TLSContext>> sni_contexts_;
347
+
348
+ friend class TLSSession;
349
+ };
350
+
351
+ } // namespace node::quic
352
+
353
+ #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
@@ -0,0 +1,263 @@
1
+ #pragma once
2
+
3
+ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4
+
5
+ #include <memory_tracker.h>
6
+ #include <ngtcp2/ngtcp2_crypto.h>
7
+ #include <node_internals.h>
8
+ #include <node_sockaddr.h>
9
+ #include "cid.h"
10
+ #include "defs.h"
11
+
12
+ namespace node::quic {
13
+
14
+ // TokenSecrets are used to generate things like stateless reset tokens,
15
+ // retry tokens, and token packets. They are always QUIC_TOKENSECRET_LEN
16
+ // bytes in length.
17
+ //
18
+ // In the default case, token secrets will always be generated randomly.
19
+ // User code will be given the option to provide a secret directly
20
+ // however.
21
+ class TokenSecret final : public MemoryRetainer {
22
+ public:
23
+ static constexpr int QUIC_TOKENSECRET_LEN = 16;
24
+
25
+ // Generate a random secret.
26
+ TokenSecret();
27
+
28
+ // Copy the given secret. The uint8_t* is assumed
29
+ // to be QUIC_TOKENSECRET_LEN in length. Note that
30
+ // the length is not verified so care must be taken
31
+ // when this constructor is used.
32
+ explicit TokenSecret(const uint8_t* secret);
33
+ ~TokenSecret();
34
+
35
+ TokenSecret(const TokenSecret&) = default;
36
+ TokenSecret& operator=(const TokenSecret&) = default;
37
+ DISALLOW_MOVE(TokenSecret)
38
+
39
+ operator const uint8_t*() const;
40
+ uint8_t operator[](int pos) const;
41
+
42
+ std::string ToString() const;
43
+
44
+ SET_NO_MEMORY_INFO()
45
+ SET_MEMORY_INFO_NAME(TokenSecret)
46
+ SET_SELF_SIZE(TokenSecret)
47
+
48
+ private:
49
+ operator const char*() const;
50
+ uint8_t buf_[QUIC_TOKENSECRET_LEN];
51
+ };
52
+
53
+ // A stateless reset token is used when a QUIC endpoint receives a QUIC packet
54
+ // with a short header but the associated connection ID cannot be matched to any
55
+ // known Session. In such cases, the receiver may choose to send a subtle opaque
56
+ // indication to the sending peer that state for the Session has apparently been
57
+ // lost. For any on- or off- path attacker, a stateless reset packet resembles
58
+ // any other QUIC packet with a short header. In order to be successfully
59
+ // handled as a stateless reset, the peer must have already seen a reset token
60
+ // issued to it associated with the given CID. The token itself is opaque to the
61
+ // peer that receives is but must be possible to statelessly recreate by the
62
+ // peer that originally created it. The actual implementation is Node.js
63
+ // specific but we currently defer to a utility function provided by ngtcp2.
64
+ //
65
+ // QUIC leaves the generation of stateless session tokens up to the
66
+ // implementation to figure out. The idea, however, is that it ought to be
67
+ // possible to generate a stateless reset token reliably even when all state
68
+ // for a connection has been lost. We use the cid as it is the only reliably
69
+ // consistent bit of data we have when a session is destroyed.
70
+ //
71
+ // StatlessResetTokens are always kStatelessTokenLen bytes,
72
+ // as are the secrets used to generate the token.
73
+ class StatelessResetToken final : public ngtcp2_stateless_reset_token,
74
+ public MemoryRetainer {
75
+ public:
76
+ static constexpr int kStatelessTokenLen = NGTCP2_STATELESS_RESET_TOKENLEN;
77
+
78
+ StatelessResetToken();
79
+
80
+ // Generates a stateless reset token using HKDF with the cid and token secret
81
+ // as input. The token secret is either provided by user code when an Endpoint
82
+ // is created or is generated randomly. The token is stored in the inherited
83
+ // ngtcp2_stateless_reset_token::data and ptr_ is set to this.
84
+ StatelessResetToken(const TokenSecret& secret, const CID& cid);
85
+
86
+ // Generates a stateless reset token into the given external storage.
87
+ // The StatelessResetToken wraps the token and does not take ownership.
88
+ StatelessResetToken(uint8_t* token,
89
+ const TokenSecret& secret,
90
+ const CID& cid);
91
+
92
+ // Generates a stateless reset token into the given external storage.
93
+ // The StatelessResetToken wraps the token and does not take ownership.
94
+ StatelessResetToken(ngtcp2_stateless_reset_token* token,
95
+ const TokenSecret& secret,
96
+ const CID& cid);
97
+
98
+ // Wraps the given token. Does not take over ownership of the token storage.
99
+ explicit StatelessResetToken(const uint8_t* token);
100
+
101
+ // Wraps the given token. Does not take over ownership of the token storage.
102
+ explicit StatelessResetToken(const ngtcp2_stateless_reset_token* token);
103
+
104
+ StatelessResetToken(const StatelessResetToken& other);
105
+ DISALLOW_MOVE(StatelessResetToken)
106
+
107
+ std::string ToString() const;
108
+
109
+ operator const uint8_t*() const;
110
+ operator const ngtcp2_stateless_reset_token*() const;
111
+ operator bool() const;
112
+
113
+ bool operator==(const StatelessResetToken& other) const;
114
+ bool operator!=(const StatelessResetToken& other) const;
115
+
116
+ struct Hash {
117
+ size_t operator()(const StatelessResetToken& token) const;
118
+ };
119
+
120
+ SET_NO_MEMORY_INFO()
121
+ SET_MEMORY_INFO_NAME(StatelessResetToken)
122
+ SET_SELF_SIZE(StatelessResetToken)
123
+
124
+ template <typename T>
125
+ using Map =
126
+ std::unordered_map<StatelessResetToken, T, StatelessResetToken::Hash>;
127
+
128
+ static StatelessResetToken kInvalid;
129
+
130
+ private:
131
+ operator const char*() const;
132
+
133
+ const ngtcp2_stateless_reset_token* ptr_;
134
+ };
135
+
136
+ // A RETRY packet communicates a retry token to the client. Retry tokens are
137
+ // generated only by QUIC servers for the purpose of validating the network path
138
+ // between a client and server. The content payload of the RETRY packet is
139
+ // opaque to the clientand must not be guessable by on- or off-path attackers.
140
+ //
141
+ // A QUIC server sends a RETRY token as a way of initiating explicit path
142
+ // validation in response to an initial QUIC packet. The client, upon receiving
143
+ // a RETRY, must abandon the initial connection attempt and try again with the
144
+ // received retry token included with the new initial packet sent to the server.
145
+ // If the server is performing explicit validation, it will look for the
146
+ // presence of the retry token and attempt to validate it if found. The internal
147
+ // structure of the retry token must be meaningful to the server, and the server
148
+ // must be able to validate that the token is correct without relying on any
149
+ // state left over from the previous connection attempt. We use an
150
+ // implementation that is provided by ngtcp2.
151
+ //
152
+ // The token secret must be kept private on the QUIC server that generated the
153
+ // retry. When multiple QUIC servers are used in a cluster, it cannot be
154
+ // guaranteed that the same QUIC server instance will receive the subsequent new
155
+ // Initial packet. Therefore, all QUIC servers in the cluster should either
156
+ // share or be aware of the same token secret or a mechanism needs to be
157
+ // implemented to ensure that subsequent packets are routed to the same QUIC
158
+ // server instance.
159
+ class RetryToken final : public MemoryRetainer {
160
+ public:
161
+ // The token prefix that is used to differentiate between a retry token
162
+ // and a regular token.
163
+ static constexpr uint8_t kTokenMagic = NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY;
164
+ static constexpr int kRetryTokenLen = NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN;
165
+
166
+ static constexpr uint64_t QUIC_DEFAULT_RETRYTOKEN_EXPIRATION =
167
+ 10 * NGTCP2_SECONDS;
168
+ static constexpr uint64_t QUIC_MIN_RETRYTOKEN_EXPIRATION = 1 * NGTCP2_SECONDS;
169
+ static constexpr uint64_t QUIC_MAX_RETRYTOKEN_EXPIRATION =
170
+ 60 * NGTCP2_SECONDS;
171
+
172
+ // Generates a new retry token.
173
+ RetryToken(uint32_t version,
174
+ const SocketAddress& address,
175
+ const CID& retry_cid,
176
+ const CID& odcid,
177
+ const TokenSecret& token_secret);
178
+
179
+ // Wraps the given retry token
180
+ RetryToken(const uint8_t* token, size_t length);
181
+
182
+ // Validates the retry token given the input. If the token is valid,
183
+ // the embedded original CID will be extracted from the token an
184
+ // returned. If the token is invalid, std::nullopt will be returned.
185
+ std::optional<CID> Validate(
186
+ uint32_t version,
187
+ const SocketAddress& address,
188
+ const CID& cid,
189
+ const TokenSecret& token_secret,
190
+ uint64_t verification_expiration = QUIC_DEFAULT_RETRYTOKEN_EXPIRATION);
191
+
192
+ operator const ngtcp2_vec&() const;
193
+ operator const ngtcp2_vec*() const;
194
+ operator bool() const;
195
+
196
+ std::string ToString() const;
197
+
198
+ SET_NO_MEMORY_INFO()
199
+ SET_MEMORY_INFO_NAME(RetryToken)
200
+ SET_SELF_SIZE(RetryToken)
201
+
202
+ private:
203
+ operator const char*() const;
204
+ uint8_t buf_[kRetryTokenLen];
205
+ const ngtcp2_vec ptr_;
206
+ };
207
+
208
+ // A NEW_TOKEN packet communicates a regular token to a client that the server
209
+ // would like the client to send in the header of an initial packet for a
210
+ // future connection. It is similar to RETRY and used for the same purpose,
211
+ // except a NEW_TOKEN is used in advance of the client establishing a new
212
+ // connection and a RETRY is sent in response to the client trying to open
213
+ // a new connection.
214
+ class RegularToken final : public MemoryRetainer {
215
+ public:
216
+ // The token prefix that is used to differentiate between a retry token
217
+ // and a regular token.
218
+ static constexpr uint8_t kTokenMagic = NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR;
219
+ static constexpr int kRegularTokenLen = NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN;
220
+ static constexpr uint64_t QUIC_DEFAULT_REGULARTOKEN_EXPIRATION =
221
+ 10 * NGTCP2_SECONDS;
222
+ static constexpr uint64_t QUIC_MIN_REGULARTOKEN_EXPIRATION =
223
+ 1 * NGTCP2_SECONDS;
224
+ static constexpr uint64_t QUIC_MAX_REGULARTOKEN_EXPIRATION =
225
+ 5 * 60 * NGTCP2_SECONDS;
226
+
227
+ RegularToken();
228
+
229
+ // Generates a new regular token.
230
+ RegularToken(uint32_t version,
231
+ const SocketAddress& address,
232
+ const TokenSecret& token_secret);
233
+
234
+ // Wraps the given regular token
235
+ RegularToken(const uint8_t* token, size_t length);
236
+
237
+ // Validates the regular token given the input.
238
+ bool Validate(
239
+ uint32_t version,
240
+ const SocketAddress& address,
241
+ const TokenSecret& token_secret,
242
+ uint64_t verification_expiration = QUIC_DEFAULT_REGULARTOKEN_EXPIRATION);
243
+
244
+ operator const ngtcp2_vec&() const;
245
+ operator const ngtcp2_vec*() const;
246
+
247
+ operator bool() const;
248
+
249
+ std::string ToString() const;
250
+
251
+ SET_NO_MEMORY_INFO()
252
+ SET_MEMORY_INFO_NAME(RegularToken)
253
+ SET_SELF_SIZE(RegularToken)
254
+
255
+ private:
256
+ operator const char*() const;
257
+ uint8_t buf_[kRegularTokenLen];
258
+ const ngtcp2_vec ptr_;
259
+ };
260
+
261
+ } // namespace node::quic
262
+
263
+ #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS