@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,2008 @@
1
+ #pragma once
2
+
3
+ #include <openssl/bio.h>
4
+ #include <openssl/bn.h>
5
+ #include <openssl/dh.h>
6
+ #include <openssl/dsa.h>
7
+ #include <openssl/ec.h>
8
+ #include <openssl/err.h>
9
+ #include <openssl/evp.h>
10
+ #include <openssl/hmac.h>
11
+ #include <openssl/kdf.h>
12
+ #include <openssl/rsa.h>
13
+ #include <openssl/ssl.h>
14
+ #include <openssl/x509.h>
15
+ #include <cstddef>
16
+ #include <functional>
17
+ #include <list>
18
+ #include <memory>
19
+ #include <optional>
20
+ #include <string>
21
+ #include <string_view>
22
+ #if defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT && \
23
+ !defined(OPENSSL_NO_ENGINE)
24
+ #include <openssl/engine.h>
25
+ #endif // NCRYPTO_ENGINE_COMPAT && !OPENSSL_NO_ENGINE
26
+
27
+ #ifndef OPENSSL_VERSION_PREREQ
28
+ #define OPENSSL_VERSION_PREREQ(maj, min) \
29
+ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20)))
30
+ #endif
31
+
32
+ // BoringSSL declares the EVP_*_do_all* APIs, but their implementation may
33
+ // live in libdecrepit. This matches standalone ncrypto's build flag.
34
+ #ifndef NCRYPTO_BSSL_LIBDECREPIT_MISSING
35
+ #define NCRYPTO_BSSL_LIBDECREPIT_MISSING 0
36
+ #endif
37
+
38
+ #if defined(OPENSSL_IS_BORINGSSL) && NCRYPTO_BSSL_LIBDECREPIT_MISSING
39
+ #define NCRYPTO_USE_BORINGSSL_EVP_DO_ALL_FALLBACK 1
40
+ #else
41
+ #define NCRYPTO_USE_BORINGSSL_EVP_DO_ALL_FALLBACK 0
42
+ #endif
43
+
44
+ // Backend split:
45
+ // - OpenSSL >= 3 uses provider APIs and hides deprecated low-level objects.
46
+ // - BoringSSL has its own API-compatible branch.
47
+ // - OpenSSL < 3 remains the legacy fallback branch.
48
+ #if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0)
49
+ #define NCRYPTO_USE_OPENSSL3_PROVIDER 1
50
+ #else
51
+ #define NCRYPTO_USE_OPENSSL3_PROVIDER 0
52
+ #endif
53
+
54
+ #ifdef OPENSSL_IS_BORINGSSL
55
+ #define NCRYPTO_USE_BORINGSSL 1
56
+ #else
57
+ #define NCRYPTO_USE_BORINGSSL 0
58
+ #endif
59
+
60
+ #if !NCRYPTO_USE_OPENSSL3_PROVIDER && !NCRYPTO_USE_BORINGSSL
61
+ #define NCRYPTO_USE_LEGACY_OPENSSL 1
62
+ #else
63
+ #define NCRYPTO_USE_LEGACY_OPENSSL 0
64
+ #endif
65
+
66
+ #if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_LEGACY_OPENSSL
67
+ #define NCRYPTO_USE_LEGACY_KEY_TYPES 1
68
+ #else
69
+ #define NCRYPTO_USE_LEGACY_KEY_TYPES 0
70
+ #endif
71
+
72
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
73
+ #include <openssl/core_names.h>
74
+ #include <openssl/encoder.h>
75
+ #include <openssl/param_build.h>
76
+ #endif
77
+
78
+ // The FIPS-related functions are only available
79
+ // when the OpenSSL itself was compiled with FIPS support.
80
+ #if defined(OPENSSL_FIPS) && !OPENSSL_VERSION_PREREQ(3, 0)
81
+ #include <openssl/fips.h>
82
+ #endif // OPENSSL_FIPS
83
+
84
+ #if OPENSSL_VERSION_PREREQ(3, 0)
85
+ #define OPENSSL_WITH_AES_OCB 1
86
+ #else
87
+ #define OPENSSL_WITH_AES_OCB 0
88
+ #endif
89
+
90
+ #if !defined(OPENSSL_NO_ARGON2) && OPENSSL_VERSION_PREREQ(3, 2)
91
+ #define OPENSSL_WITH_ARGON2 1
92
+ #else
93
+ #define OPENSSL_WITH_ARGON2 0
94
+ #endif
95
+
96
+ #if OPENSSL_VERSION_PREREQ(3, 0) || defined(OPENSSL_IS_BORINGSSL)
97
+ #define OPENSSL_WITH_KEM 1
98
+ #else
99
+ #define OPENSSL_WITH_KEM 0
100
+ #endif
101
+
102
+ #if OPENSSL_VERSION_PREREQ(3, 0)
103
+ #define OPENSSL_WITH_EVP_MAC 1
104
+ #else
105
+ #define OPENSSL_WITH_EVP_MAC 0
106
+ #endif
107
+
108
+ #if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0)
109
+ #define OPENSSL_WITH_AES_SIV 1
110
+ #else
111
+ #define OPENSSL_WITH_AES_SIV 0
112
+ #endif
113
+
114
+ #if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 2)
115
+ #define OPENSSL_WITH_AES_GCM_SIV 1
116
+ #else
117
+ #define OPENSSL_WITH_AES_GCM_SIV 0
118
+ #endif
119
+
120
+ #if defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_PREREQ(3, 2)
121
+ #define OPENSSL_WITH_SIGNATURE_CONTEXT_STRING 1
122
+ #else
123
+ #define OPENSSL_WITH_SIGNATURE_CONTEXT_STRING 0
124
+ #endif
125
+
126
+ #if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 2)
127
+ #define OPENSSL_WITH_OPENSSL_DHKEM 1
128
+ #else
129
+ #define OPENSSL_WITH_OPENSSL_DHKEM 0
130
+ #endif
131
+
132
+ #if OPENSSL_WITH_KEM && !defined(OPENSSL_IS_BORINGSSL) && \
133
+ !OPENSSL_VERSION_PREREQ(3, 5)
134
+ #define OPENSSL_WITH_KEM_OPERATION_PARAM 1
135
+ #else
136
+ #define OPENSSL_WITH_KEM_OPERATION_PARAM 0
137
+ #endif
138
+
139
+ // Post-quantum cryptography support. Keep these explicit so code can
140
+ // distinguish provider API shape from the available algorithm set.
141
+ #if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 5)
142
+ #define OPENSSL_WITH_OPENSSL_PQC 1
143
+ #else
144
+ #define OPENSSL_WITH_OPENSSL_PQC 0
145
+ #endif
146
+
147
+ #ifdef OPENSSL_IS_BORINGSSL
148
+ #define OPENSSL_WITH_BORINGSSL_PQC 1
149
+ #else
150
+ #define OPENSSL_WITH_BORINGSSL_PQC 0
151
+ #endif
152
+
153
+ #define OPENSSL_WITH_PQC \
154
+ (OPENSSL_WITH_OPENSSL_PQC || OPENSSL_WITH_BORINGSSL_PQC)
155
+ #define OPENSSL_WITH_PQC_ML_KEM_512 OPENSSL_WITH_OPENSSL_PQC
156
+ #define OPENSSL_WITH_PQC_SLH_DSA OPENSSL_WITH_OPENSSL_PQC
157
+
158
+ #if OPENSSL_WITH_OPENSSL_PQC
159
+ #define EVP_PKEY_ML_KEM_512 NID_ML_KEM_512
160
+ #define EVP_PKEY_ML_KEM_768 NID_ML_KEM_768
161
+ #define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024
162
+ #elif OPENSSL_WITH_BORINGSSL_PQC
163
+ #define EVP_PKEY_ML_KEM_768 NID_ML_KEM_768
164
+ #define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024
165
+ #endif
166
+
167
+ #if OPENSSL_VERSION_PREREQ(3, 0)
168
+ #define OSSL3_CONST const
169
+ #else
170
+ #define OSSL3_CONST
171
+ #endif
172
+
173
+ #ifdef __GNUC__
174
+ #define NCRYPTO_MUST_USE_RESULT __attribute__((warn_unused_result))
175
+ #else
176
+ #define NCRYPTO_MUST_USE_RESULT
177
+ #endif
178
+
179
+ #ifdef OPENSSL_IS_BORINGSSL
180
+ // Boringssl has opted to use size_t for some size related
181
+ // APIs while Openssl is still using ints
182
+ using OPENSSL_SIZE_T = size_t;
183
+ #else
184
+ using OPENSSL_SIZE_T = int;
185
+ #endif
186
+
187
+ namespace ncrypto {
188
+
189
+ // ============================================================================
190
+ // Utility macros
191
+
192
+ #if NCRYPTO_DEVELOPMENT_CHECKS
193
+ #define NCRYPTO_STR(x) #x
194
+ #define NCRYPTO_REQUIRE(EXPR) \
195
+ { \
196
+ if (!(EXPR)) { \
197
+ abort(); \
198
+ } \
199
+ }
200
+
201
+ #define NCRYPTO_FAIL(MESSAGE) \
202
+ do { \
203
+ std::cerr << "FAIL: " << (MESSAGE) << std::endl; \
204
+ abort(); \
205
+ } while (0);
206
+ #define NCRYPTO_ASSERT_EQUAL(LHS, RHS, MESSAGE) \
207
+ do { \
208
+ if (LHS != RHS) { \
209
+ std::cerr << "Mismatch: '" << LHS << "' - '" << RHS << "'" << std::endl; \
210
+ NCRYPTO_FAIL(MESSAGE); \
211
+ } \
212
+ } while (0);
213
+ #define NCRYPTO_ASSERT_TRUE(COND) \
214
+ do { \
215
+ if (!(COND)) { \
216
+ std::cerr << "Assert at line " << __LINE__ << " of file " << __FILE__ \
217
+ << std::endl; \
218
+ NCRYPTO_FAIL(NCRYPTO_STR(COND)); \
219
+ } \
220
+ } while (0);
221
+ #else
222
+ #define NCRYPTO_FAIL(MESSAGE)
223
+ #define NCRYPTO_ASSERT_EQUAL(LHS, RHS, MESSAGE)
224
+ #define NCRYPTO_ASSERT_TRUE(COND)
225
+ #endif
226
+
227
+ #define NCRYPTO_DISALLOW_COPY(Name) \
228
+ Name(const Name&) = delete; \
229
+ Name& operator=(const Name&) = delete;
230
+ #define NCRYPTO_DISALLOW_MOVE(Name) \
231
+ Name(Name&&) = delete; \
232
+ Name& operator=(Name&&) = delete;
233
+ #define NCRYPTO_DISALLOW_COPY_AND_MOVE(Name) \
234
+ NCRYPTO_DISALLOW_COPY(Name) \
235
+ NCRYPTO_DISALLOW_MOVE(Name)
236
+ #define NCRYPTO_DISALLOW_NEW_DELETE() \
237
+ void* operator new(size_t) = delete; \
238
+ void operator delete(void*) = delete;
239
+
240
+ [[noreturn]] inline void unreachable() {
241
+ #ifdef __GNUC__
242
+ __builtin_unreachable();
243
+ #elif defined(_MSC_VER)
244
+ __assume(false);
245
+ #else
246
+ #endif
247
+ }
248
+
249
+ static constexpr int kX509NameFlagsMultiline =
250
+ ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_UTF8_CONVERT |
251
+ XN_FLAG_SEP_MULTILINE | XN_FLAG_FN_SN;
252
+
253
+ // ============================================================================
254
+ // Error handling utilities
255
+
256
+ // Capture the current OpenSSL Error Stack. The stack will be ordered such
257
+ // that the error currently at the top of the stack is at the end of the
258
+ // list and the error at the bottom of the stack is at the beginning.
259
+ class CryptoErrorList final {
260
+ public:
261
+ enum class Option { NONE, CAPTURE_ON_CONSTRUCT };
262
+ CryptoErrorList(Option option = Option::CAPTURE_ON_CONSTRUCT);
263
+
264
+ void capture();
265
+
266
+ // Add an error message to the end of the stack.
267
+ void add(std::string message);
268
+
269
+ inline const std::string& peek_back() const { return errors_.back(); }
270
+ inline size_t size() const { return errors_.size(); }
271
+ inline bool empty() const { return errors_.empty(); }
272
+
273
+ inline auto begin() const noexcept { return errors_.begin(); }
274
+ inline auto end() const noexcept { return errors_.end(); }
275
+ inline auto rbegin() const noexcept { return errors_.rbegin(); }
276
+ inline auto rend() const noexcept { return errors_.rend(); }
277
+
278
+ std::optional<std::string> pop_back();
279
+ std::optional<std::string> pop_front();
280
+
281
+ private:
282
+ std::list<std::string> errors_;
283
+ };
284
+
285
+ // Forcibly clears the error stack on destruction. This stops stale errors
286
+ // from popping up later in the lifecycle of crypto operations where they
287
+ // would cause spurious failures. It is a rather blunt method, though, and
288
+ // ERR_clear_error() isn't necessarily cheap.
289
+ //
290
+ // If created with a pointer to a CryptoErrorList, the current OpenSSL error
291
+ // stack will be captured before clearing the error.
292
+ class ClearErrorOnReturn final {
293
+ public:
294
+ ClearErrorOnReturn(CryptoErrorList* errors = nullptr);
295
+ ~ClearErrorOnReturn();
296
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(ClearErrorOnReturn)
297
+ NCRYPTO_DISALLOW_NEW_DELETE()
298
+
299
+ unsigned long peekError(); // NOLINT(runtime/int)
300
+
301
+ private:
302
+ CryptoErrorList* errors_;
303
+ };
304
+
305
+ // Pop errors from OpenSSL's error stack that were added between when this
306
+ // was constructed and destructed.
307
+ //
308
+ // If created with a pointer to a CryptoErrorList, the current OpenSSL error
309
+ // stack will be captured before resetting the error to the mark.
310
+ class MarkPopErrorOnReturn final {
311
+ public:
312
+ MarkPopErrorOnReturn(CryptoErrorList* errors = nullptr);
313
+ ~MarkPopErrorOnReturn();
314
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(MarkPopErrorOnReturn)
315
+ NCRYPTO_DISALLOW_NEW_DELETE()
316
+
317
+ unsigned long peekError(); // NOLINT(runtime/int)
318
+
319
+ private:
320
+ CryptoErrorList* errors_;
321
+ };
322
+
323
+ // TODO(@jasnell): Eventually replace with std::expected when we are able to
324
+ // bump up to c++23.
325
+ template <typename T, typename E>
326
+ struct Result final {
327
+ const bool has_value;
328
+ T value;
329
+ std::optional<E> error = std::nullopt;
330
+ // NOLINTNEXTLINE(runtime/int) -- matches ERR_peek_error()
331
+ std::optional<unsigned long> openssl_error = std::nullopt;
332
+ Result(T&& value) : has_value(true), value(std::move(value)) {}
333
+ // NOLINTNEXTLINE(runtime/int) -- matches ERR_peek_error()
334
+ Result(E&& error, std::optional<unsigned long> openssl_error = std::nullopt)
335
+ : has_value(false),
336
+ error(std::move(error)),
337
+ openssl_error(std::move(openssl_error)) {}
338
+ inline operator bool() const { return has_value; }
339
+ };
340
+
341
+ // ============================================================================
342
+ // Various smart pointer aliases for OpenSSL types.
343
+
344
+ template <typename T, void (*function)(T*)>
345
+ struct FunctionDeleter {
346
+ void operator()(T* pointer) const { function(pointer); }
347
+ typedef std::unique_ptr<T, FunctionDeleter> Pointer;
348
+ };
349
+
350
+ template <typename T, void (*function)(T*)>
351
+ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
352
+
353
+ using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
354
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
355
+ using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
356
+ #endif
357
+ using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
358
+
359
+ class BIOPointer;
360
+ class BignumPointer;
361
+ class CipherCtxPointer;
362
+ class DataPointer;
363
+ class DHPointer;
364
+ class ECKeyPointer;
365
+ class EVPKeyPointer;
366
+ class EVPMacCtxPointer;
367
+ class EVPMacPointer;
368
+ class EVPMDCtxPointer;
369
+ class SSLCtxPointer;
370
+ class SSLPointer;
371
+ class X509View;
372
+ class X509Pointer;
373
+ class ECDSASigPointer;
374
+ class ECGroupPointer;
375
+ class ECPointPointer;
376
+ class ECKeyPointer;
377
+ class Dsa;
378
+ class Rsa;
379
+ class Ec;
380
+
381
+ struct StackOfXASN1Deleter {
382
+ void operator()(STACK_OF(ASN1_OBJECT) * p) const {
383
+ sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
384
+ }
385
+ };
386
+ using StackOfASN1 = std::unique_ptr<STACK_OF(ASN1_OBJECT), StackOfXASN1Deleter>;
387
+
388
+ // An unowned, unmanaged pointer to a buffer of data.
389
+ template <typename T>
390
+ struct Buffer {
391
+ T* data = nullptr;
392
+ size_t len = 0;
393
+ };
394
+
395
+ class Digest final {
396
+ public:
397
+ static constexpr size_t MAX_SIZE = EVP_MAX_MD_SIZE;
398
+ Digest() = default;
399
+ Digest(const EVP_MD* md) : md_(md) {}
400
+ Digest(const Digest&) = default;
401
+ Digest& operator=(const Digest&) = default;
402
+ inline Digest& operator=(const EVP_MD* md) {
403
+ md_ = md;
404
+ return *this;
405
+ }
406
+ NCRYPTO_DISALLOW_MOVE(Digest)
407
+
408
+ size_t size() const;
409
+
410
+ inline const EVP_MD* get() const { return md_; }
411
+ inline operator const EVP_MD*() const { return md_; }
412
+ inline operator bool() const { return md_ != nullptr; }
413
+
414
+ static const Digest MD5;
415
+ static const Digest SHA1;
416
+ static const Digest SHA256;
417
+ static const Digest SHA384;
418
+ static const Digest SHA512;
419
+
420
+ static const Digest FromName(const char* name);
421
+
422
+ private:
423
+ const EVP_MD* md_ = nullptr;
424
+ };
425
+
426
+ // Computes a fixed-length digest.
427
+ DataPointer hashDigest(const Buffer<const unsigned char>& data,
428
+ const EVP_MD* md);
429
+ // Computes a variable-length digest for XOF algorithms (e.g. SHAKE128).
430
+ DataPointer xofHashDigest(const Buffer<const unsigned char>& data,
431
+ const EVP_MD* md,
432
+ size_t length);
433
+
434
+ class Cipher final {
435
+ public:
436
+ static constexpr size_t MAX_KEY_LENGTH = EVP_MAX_KEY_LENGTH;
437
+ static constexpr size_t MAX_IV_LENGTH = EVP_MAX_IV_LENGTH;
438
+ #ifdef EVP_MAX_AEAD_TAG_LENGTH
439
+ static constexpr size_t MAX_AUTH_TAG_LENGTH = EVP_MAX_AEAD_TAG_LENGTH;
440
+ #else
441
+ static constexpr size_t MAX_AUTH_TAG_LENGTH = 16;
442
+ #endif
443
+ static_assert(EVP_GCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH
444
+ #ifndef OPENSSL_IS_BORINGSSL
445
+ && EVP_CCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH &&
446
+ EVP_CHACHAPOLY_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH
447
+ #endif
448
+ ); // NOLINT(whitespace/parens)
449
+
450
+ Cipher() = default;
451
+ Cipher(const EVP_CIPHER* cipher) : cipher_(cipher) {}
452
+ Cipher(const Cipher& other);
453
+ Cipher& operator=(const Cipher& other);
454
+ inline Cipher& operator=(const EVP_CIPHER* cipher) {
455
+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
456
+ fetched_cipher_.reset();
457
+ #endif
458
+ cipher_ = cipher;
459
+ return *this;
460
+ }
461
+ NCRYPTO_DISALLOW_MOVE(Cipher)
462
+
463
+ inline const EVP_CIPHER* get() const { return cipher_; }
464
+ inline operator const EVP_CIPHER*() const { return cipher_; }
465
+ inline operator bool() const { return cipher_ != nullptr; }
466
+
467
+ int getNid() const;
468
+ int getMode() const;
469
+ int getIvLength() const;
470
+ int getKeyLength() const;
471
+ int getBlockSize() const;
472
+ std::string_view getModeLabel() const;
473
+ const char* getName() const;
474
+
475
+ bool isGcmMode() const;
476
+ bool isWrapMode() const;
477
+ bool isCtrMode() const;
478
+ bool isCcmMode() const;
479
+ bool isOcbMode() const;
480
+ bool isSivMode() const;
481
+ bool isGcmSivMode() const;
482
+ bool isStreamMode() const;
483
+ bool isChaCha20Poly1305() const;
484
+
485
+ bool isSupportedAuthenticatedMode() const;
486
+
487
+ int bytesToKey(const Digest& digest,
488
+ const Buffer<const unsigned char>& input,
489
+ unsigned char* key,
490
+ unsigned char* iv) const;
491
+
492
+ static const Cipher FromName(const char* name);
493
+ static const Cipher FromNid(int nid);
494
+ static const Cipher FromCtx(const CipherCtxPointer& ctx);
495
+
496
+ using CipherNameCallback = std::function<void(const char* name)>;
497
+
498
+ // Iterates the known ciphers if the underlying implementation
499
+ // is able to do so.
500
+ static void ForEach(CipherNameCallback callback);
501
+
502
+ // Utilities to get various ciphers by type. If the underlying
503
+ // implementation does not support the requested cipher, then
504
+ // the result will be an empty Cipher object whose bool operator
505
+ // will return false.
506
+
507
+ static const Cipher EMPTY;
508
+ static const Cipher AES_128_CBC;
509
+ static const Cipher AES_192_CBC;
510
+ static const Cipher AES_256_CBC;
511
+ static const Cipher AES_128_CTR;
512
+ static const Cipher AES_192_CTR;
513
+ static const Cipher AES_256_CTR;
514
+ static const Cipher AES_128_GCM;
515
+ static const Cipher AES_192_GCM;
516
+ static const Cipher AES_256_GCM;
517
+ static const Cipher AES_128_KW;
518
+ static const Cipher AES_192_KW;
519
+ static const Cipher AES_256_KW;
520
+ static const Cipher AES_128_OCB;
521
+ static const Cipher AES_192_OCB;
522
+ static const Cipher AES_256_OCB;
523
+ static const Cipher CHACHA20_POLY1305;
524
+
525
+ struct CipherParams {
526
+ int padding;
527
+ Digest digest;
528
+ Digest mgf1_digest;
529
+ const Buffer<const void> label;
530
+ };
531
+
532
+ static DataPointer encrypt(const EVPKeyPointer& key,
533
+ const CipherParams& params,
534
+ const Buffer<const void> in);
535
+ static DataPointer decrypt(const EVPKeyPointer& key,
536
+ const CipherParams& params,
537
+ const Buffer<const void> in);
538
+
539
+ static DataPointer sign(const EVPKeyPointer& key,
540
+ const CipherParams& params,
541
+ const Buffer<const void> in);
542
+
543
+ static DataPointer recover(const EVPKeyPointer& key,
544
+ const CipherParams& params,
545
+ const Buffer<const void> in);
546
+
547
+ static constexpr bool IsValidGCMTagLength(unsigned int tag_len) {
548
+ return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
549
+ }
550
+
551
+ private:
552
+ const EVP_CIPHER* cipher_ = nullptr;
553
+ #if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV
554
+ explicit Cipher(DeleteFnPtr<EVP_CIPHER, EVP_CIPHER_free> cipher);
555
+ DeleteFnPtr<EVP_CIPHER, EVP_CIPHER_free> fetched_cipher_;
556
+ #endif
557
+ };
558
+
559
+ // ============================================================================
560
+ // DSA
561
+
562
+ class Dsa final {
563
+ public:
564
+ Dsa();
565
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
566
+ explicit Dsa(const EVP_PKEY* pkey);
567
+ #else
568
+ Dsa(OSSL3_CONST DSA* dsa);
569
+ #endif
570
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(Dsa)
571
+
572
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
573
+ inline operator bool() const {
574
+ return dsa_;
575
+ }
576
+ #else
577
+ inline operator bool() const { return dsa_ != nullptr; }
578
+ #endif
579
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
580
+ inline operator OSSL3_CONST DSA*() const { return dsa_; }
581
+ #endif
582
+
583
+ const BIGNUM* getP() const;
584
+ const BIGNUM* getQ() const;
585
+ size_t getModulusLength() const;
586
+ size_t getDivisorLength() const;
587
+
588
+ private:
589
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
590
+ bool dsa_ = false;
591
+ DeleteFnPtr<BIGNUM, BN_free> p_;
592
+ DeleteFnPtr<BIGNUM, BN_free> q_;
593
+ #else
594
+ OSSL3_CONST DSA* dsa_;
595
+ #endif
596
+ };
597
+
598
+ // ============================================================================
599
+ // RSA
600
+
601
+ class Rsa final {
602
+ public:
603
+ Rsa();
604
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
605
+ explicit Rsa(const EVP_PKEY* pkey);
606
+ #else
607
+ Rsa(OSSL3_CONST RSA* rsa);
608
+ #endif
609
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(Rsa)
610
+
611
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
612
+ inline operator bool() const {
613
+ return rsa_;
614
+ }
615
+ #else
616
+ inline operator bool() const { return rsa_ != nullptr; }
617
+ #endif
618
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
619
+ inline operator OSSL3_CONST RSA*() const { return rsa_; }
620
+ #endif
621
+
622
+ struct PublicKey {
623
+ const BIGNUM* n;
624
+ const BIGNUM* e;
625
+ const BIGNUM* d;
626
+ };
627
+ struct PrivateKey {
628
+ const BIGNUM* p;
629
+ const BIGNUM* q;
630
+ const BIGNUM* dp;
631
+ const BIGNUM* dq;
632
+ const BIGNUM* qi;
633
+ };
634
+ struct PssParams {
635
+ std::string_view digest = "sha1";
636
+ std::optional<std::string_view> mgf1_digest = "sha1";
637
+ int64_t salt_length = 20;
638
+ };
639
+
640
+ const PublicKey getPublicKey() const;
641
+ const PrivateKey getPrivateKey() const;
642
+ const std::optional<PssParams> getPssParams() const;
643
+
644
+ bool setPublicKey(BignumPointer&& n, BignumPointer&& e);
645
+ bool setPrivateKey(BignumPointer&& d,
646
+ BignumPointer&& q,
647
+ BignumPointer&& p,
648
+ BignumPointer&& dp,
649
+ BignumPointer&& dq,
650
+ BignumPointer&& qi);
651
+
652
+ using CipherParams = Cipher::CipherParams;
653
+
654
+ BIOPointer derPublicKey() const;
655
+
656
+ static DataPointer encrypt(const EVPKeyPointer& key,
657
+ const CipherParams& params,
658
+ const Buffer<const void> in);
659
+ static DataPointer decrypt(const EVPKeyPointer& key,
660
+ const CipherParams& params,
661
+ const Buffer<const void> in);
662
+
663
+ private:
664
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
665
+ bool rsa_ = false;
666
+ bool rsa_pss_ = false;
667
+ DeleteFnPtr<BIGNUM, BN_free> n_;
668
+ DeleteFnPtr<BIGNUM, BN_free> e_;
669
+ DeleteFnPtr<BIGNUM, BN_clear_free> d_;
670
+ DeleteFnPtr<BIGNUM, BN_clear_free> p_;
671
+ DeleteFnPtr<BIGNUM, BN_clear_free> q_;
672
+ DeleteFnPtr<BIGNUM, BN_clear_free> dp_;
673
+ DeleteFnPtr<BIGNUM, BN_clear_free> dq_;
674
+ DeleteFnPtr<BIGNUM, BN_clear_free> qi_;
675
+ std::optional<PssParams> pss_params_;
676
+ #else
677
+ OSSL3_CONST RSA* rsa_;
678
+ #endif
679
+ };
680
+
681
+ class Ec final {
682
+ public:
683
+ Ec();
684
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
685
+ explicit Ec(const EVP_PKEY* pkey);
686
+ #else
687
+ Ec(OSSL3_CONST EC_KEY* key);
688
+ #endif
689
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(Ec)
690
+
691
+ const EC_GROUP* getGroup() const;
692
+ const EC_POINT* getPublicKey() const;
693
+ point_conversion_form_t getPointConversionForm() const;
694
+ int getCurve() const;
695
+
696
+ inline operator bool() const { return ec_ != nullptr; }
697
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
698
+ inline operator OSSL3_CONST EC_KEY*() const { return ec_; }
699
+ #endif
700
+
701
+ static int GetCurveIdFromName(const char* name);
702
+
703
+ using GetCurveCallback = std::function<bool(const char*)>;
704
+ static bool GetCurves(GetCurveCallback callback);
705
+
706
+ private:
707
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
708
+ DeleteFnPtr<EC_GROUP, EC_GROUP_free> ec_;
709
+ DeleteFnPtr<EC_POINT, EC_POINT_free> pub_;
710
+ point_conversion_form_t form_ = POINT_CONVERSION_UNCOMPRESSED;
711
+ #else
712
+ OSSL3_CONST EC_KEY* ec_ = nullptr;
713
+ #endif
714
+ };
715
+
716
+ // A managed pointer to a buffer of data. When destroyed the underlying
717
+ // buffer will be freed.
718
+ class DataPointer final {
719
+ public:
720
+ static DataPointer Alloc(size_t len);
721
+ static DataPointer Copy(const Buffer<const void>& buffer);
722
+
723
+ // Attempts to allocate the buffer space using the secure heap, if
724
+ // supported/enabled. If the secure heap is disabled, then this
725
+ // ends up being equivalent to Alloc(len). Note that allocation
726
+ // will fail if there is not enough free space remaining in the
727
+ // secure heap space.
728
+ static DataPointer SecureAlloc(size_t len);
729
+
730
+ // If the secure heap is enabled, returns the amount of data that
731
+ // has been allocated from the heap.
732
+ static size_t GetSecureHeapUsed();
733
+
734
+ enum class InitSecureHeapResult {
735
+ FAILED,
736
+ UNABLE_TO_MEMORY_MAP,
737
+ OK,
738
+ };
739
+
740
+ // Attempt to initialize the secure heap. The secure heap is not
741
+ // supported on all operating systems and whenever boringssl is
742
+ // used.
743
+ static InitSecureHeapResult TryInitSecureHeap(size_t amount, size_t min);
744
+
745
+ DataPointer() = default;
746
+ explicit DataPointer(void* data, size_t len, bool secure = false);
747
+ explicit DataPointer(const Buffer<void>& buffer, bool secure = false);
748
+ DataPointer(DataPointer&& other) noexcept;
749
+ DataPointer& operator=(DataPointer&& other) noexcept;
750
+ NCRYPTO_DISALLOW_COPY(DataPointer)
751
+ ~DataPointer();
752
+
753
+ inline bool operator==(std::nullptr_t) noexcept { return data_ == nullptr; }
754
+ inline operator bool() const { return data_ != nullptr; }
755
+
756
+ template <typename T = void>
757
+ inline T* get() const noexcept {
758
+ return static_cast<T*>(data_);
759
+ }
760
+
761
+ inline size_t size() const noexcept { return len_; }
762
+ void reset(void* data = nullptr, size_t len = 0);
763
+ void reset(const Buffer<void>& buffer);
764
+
765
+ // Sets the underlying data buffer to all zeros.
766
+ void zero();
767
+
768
+ DataPointer resize(size_t len);
769
+
770
+ // Releases ownership of the underlying data buffer. It is the caller's
771
+ // responsibility to ensure the buffer is appropriately freed.
772
+ Buffer<void> release();
773
+
774
+ // Returns a Buffer struct that is a view of the underlying data.
775
+ template <typename T = void>
776
+ inline operator const Buffer<T>() const {
777
+ return {
778
+ .data = static_cast<T*>(data_),
779
+ .len = len_,
780
+ };
781
+ }
782
+
783
+ bool isSecure() const { return secure_; }
784
+
785
+ private:
786
+ void* data_ = nullptr;
787
+ size_t len_ = 0;
788
+ bool secure_ = false;
789
+ };
790
+
791
+ class BIOPointer final {
792
+ public:
793
+ static BIOPointer NewMem();
794
+ static BIOPointer NewSecMem();
795
+ static BIOPointer New(const BIO_METHOD* method);
796
+ static BIOPointer New(const void* data, size_t len);
797
+ static BIOPointer New(const BIGNUM* bn);
798
+ static BIOPointer NewFile(const char* filename, const char* mode);
799
+ static BIOPointer NewFp(FILE* fd, int flags);
800
+
801
+ template <typename T>
802
+ static BIOPointer New(const Buffer<T>& buf) {
803
+ return New(buf.data, buf.len);
804
+ }
805
+
806
+ BIOPointer() = default;
807
+ BIOPointer(std::nullptr_t) : bio_(nullptr) {}
808
+ explicit BIOPointer(BIO* bio);
809
+ BIOPointer(BIOPointer&& other) noexcept;
810
+ BIOPointer& operator=(BIOPointer&& other) noexcept;
811
+ NCRYPTO_DISALLOW_COPY(BIOPointer)
812
+ ~BIOPointer();
813
+
814
+ inline bool operator==(std::nullptr_t) noexcept { return bio_ == nullptr; }
815
+ inline operator bool() const { return bio_ != nullptr; }
816
+ inline BIO* get() const noexcept { return bio_.get(); }
817
+
818
+ inline operator BUF_MEM*() const {
819
+ BUF_MEM* mem = nullptr;
820
+ if (!bio_) return mem;
821
+ BIO_get_mem_ptr(bio_.get(), &mem);
822
+ return mem;
823
+ }
824
+
825
+ inline operator BIO*() const { return bio_.get(); }
826
+
827
+ void reset(BIO* bio = nullptr);
828
+ BIO* release();
829
+
830
+ bool resetBio() const;
831
+
832
+ static int Write(BIOPointer* bio, std::string_view message);
833
+
834
+ template <typename... Args>
835
+ static void Printf(BIOPointer* bio, const char* format, Args... args) {
836
+ if (bio == nullptr || !*bio) return;
837
+ BIO_printf(bio->get(), format, std::forward<Args...>(args...));
838
+ }
839
+
840
+ private:
841
+ mutable DeleteFnPtr<BIO, BIO_free_all> bio_;
842
+ };
843
+
844
+ class BignumPointer final {
845
+ public:
846
+ BignumPointer() = default;
847
+ explicit BignumPointer(BIGNUM* bignum);
848
+ explicit BignumPointer(const unsigned char* data, size_t len);
849
+ BignumPointer(BignumPointer&& other) noexcept;
850
+ BignumPointer& operator=(BignumPointer&& other) noexcept;
851
+ NCRYPTO_DISALLOW_COPY(BignumPointer)
852
+ ~BignumPointer();
853
+
854
+ int operator<=>(const BignumPointer& other) const noexcept;
855
+ int operator<=>(const BIGNUM* other) const noexcept;
856
+ inline operator bool() const { return bn_ != nullptr; }
857
+ inline BIGNUM* get() const noexcept { return bn_.get(); }
858
+ void reset(BIGNUM* bn = nullptr);
859
+ void reset(const unsigned char* data, size_t len);
860
+ BIGNUM* release();
861
+
862
+ bool isZero() const;
863
+ bool isOne() const;
864
+
865
+ bool setWord(unsigned long w); // NOLINT(runtime/int)
866
+ std::optional<unsigned long> getWord() const; // NOLINT(runtime/int)
867
+
868
+ size_t byteLength() const;
869
+
870
+ DataPointer toHex() const;
871
+ DataPointer encode() const;
872
+ DataPointer encodePadded(size_t size) const;
873
+ size_t encodeInto(unsigned char* out) const;
874
+ size_t encodePaddedInto(unsigned char* out, size_t size) const;
875
+
876
+ using PrimeCheckCallback = std::function<bool(int, int)>;
877
+ int isPrime(int checks,
878
+ PrimeCheckCallback cb = defaultPrimeCheckCallback) const;
879
+ struct PrimeConfig {
880
+ int bits;
881
+ bool safe = false;
882
+ const BignumPointer& add;
883
+ const BignumPointer& rem;
884
+ };
885
+
886
+ static BignumPointer NewPrime(
887
+ const PrimeConfig& params,
888
+ PrimeCheckCallback cb = defaultPrimeCheckCallback);
889
+
890
+ bool generate(const PrimeConfig& params,
891
+ PrimeCheckCallback cb = defaultPrimeCheckCallback) const;
892
+
893
+ static BignumPointer New();
894
+ static BignumPointer NewSecure();
895
+ static BignumPointer NewSub(const BignumPointer& a, const BignumPointer& b);
896
+ static BignumPointer NewLShift(size_t length);
897
+
898
+ static DataPointer Encode(const BIGNUM* bn);
899
+ static DataPointer EncodePadded(const BIGNUM* bn, size_t size);
900
+ static size_t EncodePaddedInto(const BIGNUM* bn,
901
+ unsigned char* out,
902
+ size_t size);
903
+ static int GetBitCount(const BIGNUM* bn);
904
+ static int GetByteCount(const BIGNUM* bn);
905
+ static std::optional<unsigned long> GetWord( // NOLINT(runtime/int)
906
+ const BIGNUM* bn);
907
+ static const BIGNUM* One();
908
+
909
+ BignumPointer clone();
910
+
911
+ private:
912
+ DeleteFnPtr<BIGNUM, BN_clear_free> bn_;
913
+
914
+ static bool defaultPrimeCheckCallback(int, int) { return 1; }
915
+ };
916
+
917
+ class CipherCtxPointer final {
918
+ public:
919
+ static CipherCtxPointer New();
920
+
921
+ CipherCtxPointer() = default;
922
+ explicit CipherCtxPointer(EVP_CIPHER_CTX* ctx);
923
+ CipherCtxPointer(CipherCtxPointer&& other) noexcept;
924
+ CipherCtxPointer& operator=(CipherCtxPointer&& other) noexcept;
925
+ NCRYPTO_DISALLOW_COPY(CipherCtxPointer)
926
+ ~CipherCtxPointer();
927
+
928
+ inline bool operator==(std::nullptr_t) const noexcept {
929
+ return ctx_ == nullptr;
930
+ }
931
+ inline operator bool() const { return ctx_ != nullptr; }
932
+ inline EVP_CIPHER_CTX* get() const { return ctx_.get(); }
933
+ inline operator EVP_CIPHER_CTX*() const { return ctx_.get(); }
934
+ void reset(EVP_CIPHER_CTX* ctx = nullptr);
935
+ EVP_CIPHER_CTX* release();
936
+
937
+ void setAllowWrap();
938
+
939
+ bool setKeyLength(size_t length);
940
+ bool setIvLength(size_t length);
941
+ bool setAeadTag(const Buffer<const char>& tag);
942
+ bool setAeadTagLength(size_t length);
943
+ bool setPadding(bool padding);
944
+ bool init(const Cipher& cipher,
945
+ bool encrypt,
946
+ const unsigned char* key = nullptr,
947
+ const unsigned char* iv = nullptr);
948
+
949
+ int getBlockSize() const;
950
+ int getMode() const;
951
+ int getNid() const;
952
+
953
+ bool isGcmMode() const;
954
+ bool isOcbMode() const;
955
+ bool isCcmMode() const;
956
+ bool isWrapMode() const;
957
+ bool isSivMode() const;
958
+ bool isGcmSivMode() const;
959
+ bool isChaCha20Poly1305() const;
960
+
961
+ bool update(const Buffer<const unsigned char>& in,
962
+ unsigned char* out,
963
+ int* out_len,
964
+ bool finalize = false);
965
+ bool getAeadTag(size_t len, unsigned char* out);
966
+
967
+ private:
968
+ DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
969
+ };
970
+
971
+ class EVPKeyCtxPointer final {
972
+ public:
973
+ EVPKeyCtxPointer();
974
+ explicit EVPKeyCtxPointer(EVP_PKEY_CTX* ctx);
975
+ EVPKeyCtxPointer(EVPKeyCtxPointer&& other) noexcept;
976
+ EVPKeyCtxPointer& operator=(EVPKeyCtxPointer&& other) noexcept;
977
+ NCRYPTO_DISALLOW_COPY(EVPKeyCtxPointer)
978
+ ~EVPKeyCtxPointer();
979
+
980
+ inline bool operator==(std::nullptr_t) const noexcept {
981
+ return ctx_ == nullptr;
982
+ }
983
+ inline operator bool() const { return ctx_ != nullptr; }
984
+ inline EVP_PKEY_CTX* get() const { return ctx_.get(); }
985
+ void reset(EVP_PKEY_CTX* ctx = nullptr);
986
+ EVP_PKEY_CTX* release();
987
+
988
+ bool initForDerive(const EVPKeyPointer& peer);
989
+ DataPointer derive() const;
990
+
991
+ bool initForParamgen();
992
+ bool setDhParameters(int prime_size, uint32_t generator);
993
+ bool setDsaParameters(uint32_t bits, std::optional<int> q_bits);
994
+ bool setEcParameters(int curve, int encoding);
995
+
996
+ bool setRsaOaepMd(const Digest& md);
997
+ bool setRsaMgf1Md(const Digest& md);
998
+ bool setRsaPadding(int padding);
999
+ bool setRsaKeygenPubExp(BignumPointer&& e);
1000
+ bool setRsaKeygenBits(int bits);
1001
+ bool setRsaPssKeygenMd(const Digest& md);
1002
+ bool setRsaPssKeygenMgf1Md(const Digest& md);
1003
+ bool setRsaPssSaltlen(int salt_len);
1004
+ bool setRsaImplicitRejection();
1005
+ bool setRsaOaepLabel(DataPointer&& data);
1006
+
1007
+ bool setSignatureMd(const EVPMDCtxPointer& md);
1008
+
1009
+ bool publicCheck() const;
1010
+ bool privateCheck() const;
1011
+
1012
+ bool verify(const Buffer<const unsigned char>& sig,
1013
+ const Buffer<const unsigned char>& data);
1014
+ DataPointer sign(const Buffer<const unsigned char>& data);
1015
+ bool signInto(const Buffer<const unsigned char>& data,
1016
+ Buffer<unsigned char>* sig);
1017
+
1018
+ static constexpr int kDefaultRsaExponent = 0x10001;
1019
+
1020
+ static bool setRsaPadding(EVP_PKEY_CTX* ctx,
1021
+ int padding,
1022
+ std::optional<int> salt_len = std::nullopt);
1023
+
1024
+ EVPKeyPointer paramgen() const;
1025
+
1026
+ bool initForEncrypt();
1027
+ bool initForDecrypt();
1028
+ bool initForKeygen();
1029
+ int initForVerify();
1030
+ int initForSign();
1031
+
1032
+ static EVPKeyCtxPointer New(const EVPKeyPointer& key);
1033
+ static EVPKeyCtxPointer NewFromID(int id);
1034
+
1035
+ private:
1036
+ DeleteFnPtr<EVP_PKEY_CTX, EVP_PKEY_CTX_free> ctx_;
1037
+ };
1038
+
1039
+ class EVPKeyPointer final {
1040
+ public:
1041
+ static EVPKeyPointer New();
1042
+ static EVPKeyPointer NewRawPublic(int id,
1043
+ const Buffer<const unsigned char>& data);
1044
+ static EVPKeyPointer NewRawPrivate(int id,
1045
+ const Buffer<const unsigned char>& data);
1046
+ #if OPENSSL_WITH_PQC
1047
+ static EVPKeyPointer NewRawSeed(int id,
1048
+ const Buffer<const unsigned char>& data);
1049
+ #endif
1050
+ static EVPKeyPointer NewDH(DHPointer&& dh);
1051
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1052
+ static EVPKeyPointer NewRSA(const Rsa& rsa);
1053
+ #else
1054
+ static EVPKeyPointer NewRSA(RSAPointer&& rsa);
1055
+ #endif
1056
+
1057
+ enum class PKEncodingType {
1058
+ // RSAPublicKey / RSAPrivateKey according to PKCS#1.
1059
+ PKCS1,
1060
+ // PrivateKeyInfo or EncryptedPrivateKeyInfo according to PKCS#8.
1061
+ PKCS8,
1062
+ // SubjectPublicKeyInfo according to X.509.
1063
+ SPKI,
1064
+ // ECPrivateKey according to SEC1.
1065
+ SEC1,
1066
+ };
1067
+
1068
+ enum class PKFormatType {
1069
+ DER,
1070
+ PEM,
1071
+ JWK,
1072
+ RAW_PUBLIC,
1073
+ RAW_PRIVATE,
1074
+ RAW_SEED,
1075
+ STORE,
1076
+ };
1077
+
1078
+ enum class PKParseError { NOT_RECOGNIZED, NEED_PASSPHRASE, FAILED };
1079
+ using ParseKeyResult = Result<EVPKeyPointer, PKParseError>;
1080
+
1081
+ struct AsymmetricKeyEncodingConfig {
1082
+ bool output_key_object = false;
1083
+ PKFormatType format = PKFormatType::DER;
1084
+ PKEncodingType type = PKEncodingType::PKCS8;
1085
+ int ec_point_form = POINT_CONVERSION_UNCOMPRESSED;
1086
+ AsymmetricKeyEncodingConfig() = default;
1087
+ AsymmetricKeyEncodingConfig(bool output_key_object,
1088
+ PKFormatType format,
1089
+ PKEncodingType type);
1090
+ AsymmetricKeyEncodingConfig(const AsymmetricKeyEncodingConfig&) = default;
1091
+ AsymmetricKeyEncodingConfig& operator=(const AsymmetricKeyEncodingConfig&) =
1092
+ default;
1093
+ };
1094
+ using PublicKeyEncodingConfig = AsymmetricKeyEncodingConfig;
1095
+
1096
+ struct PrivateKeyEncodingConfig : public AsymmetricKeyEncodingConfig {
1097
+ const EVP_CIPHER* cipher = nullptr;
1098
+ std::optional<DataPointer> passphrase = std::nullopt;
1099
+ PrivateKeyEncodingConfig() = default;
1100
+ PrivateKeyEncodingConfig(bool output_key_object,
1101
+ PKFormatType format,
1102
+ PKEncodingType type)
1103
+ : AsymmetricKeyEncodingConfig(output_key_object, format, type) {}
1104
+ PrivateKeyEncodingConfig(const PrivateKeyEncodingConfig&);
1105
+ PrivateKeyEncodingConfig& operator=(const PrivateKeyEncodingConfig&);
1106
+ };
1107
+
1108
+ struct StorePrivateKeyConfig {
1109
+ std::string_view uri;
1110
+ std::optional<std::string_view> properties = std::nullopt;
1111
+ std::optional<Buffer<const char>> passphrase = std::nullopt;
1112
+ };
1113
+
1114
+ static ParseKeyResult TryParsePublicKey(
1115
+ const PublicKeyEncodingConfig& config,
1116
+ const Buffer<const unsigned char>& buffer);
1117
+
1118
+ static ParseKeyResult TryParsePublicKeyPEM(
1119
+ const Buffer<const unsigned char>& buffer);
1120
+
1121
+ static ParseKeyResult TryParsePrivateKey(
1122
+ const PrivateKeyEncodingConfig& config,
1123
+ const Buffer<const unsigned char>& buffer);
1124
+
1125
+ // Loads a private key through an OpenSSL STORE loader using the configured
1126
+ // URI (e.g. "file:", a provider-backed scheme such as "pkcs11:"). The
1127
+ // optional passphrase is used as the PIN/passphrase for encrypted or
1128
+ // token-protected keys.
1129
+ // Returns NOT_RECOGNIZED when no private key is found at the URI.
1130
+ static ParseKeyResult TryLoadPrivateKeyFromStore(
1131
+ const StorePrivateKeyConfig& config);
1132
+
1133
+ EVPKeyPointer() = default;
1134
+ explicit EVPKeyPointer(EVP_PKEY* pkey);
1135
+ EVPKeyPointer(EVPKeyPointer&& other) noexcept;
1136
+ EVPKeyPointer& operator=(EVPKeyPointer&& other) noexcept;
1137
+ NCRYPTO_DISALLOW_COPY(EVPKeyPointer)
1138
+ ~EVPKeyPointer();
1139
+
1140
+ bool assign(const ECKeyPointer& eckey);
1141
+ bool set(const ECKeyPointer& eckey);
1142
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
1143
+ operator const EC_KEY*() const;
1144
+ #endif
1145
+
1146
+ inline bool operator==(std::nullptr_t) const noexcept {
1147
+ return pkey_ == nullptr;
1148
+ }
1149
+ inline operator bool() const { return pkey_ != nullptr; }
1150
+ inline EVP_PKEY* get() const { return pkey_.get(); }
1151
+ void reset(EVP_PKEY* pkey = nullptr);
1152
+ EVP_PKEY* release();
1153
+
1154
+ static int id(const EVP_PKEY* key);
1155
+ static int base_id(const EVP_PKEY* key);
1156
+
1157
+ int id() const;
1158
+ int base_id() const;
1159
+ int bits() const;
1160
+ size_t size() const;
1161
+
1162
+ size_t rawPublicKeySize() const;
1163
+ size_t rawPrivateKeySize() const;
1164
+ DataPointer rawPublicKey() const;
1165
+ DataPointer rawPrivateKey() const;
1166
+ BIOPointer derPublicKey() const;
1167
+
1168
+ #if OPENSSL_WITH_PQC
1169
+ DataPointer rawSeed() const;
1170
+ #endif
1171
+
1172
+ Result<BIOPointer, bool> writePrivateKey(
1173
+ const PrivateKeyEncodingConfig& config) const;
1174
+ Result<BIOPointer, bool> writePublicKey(
1175
+ const PublicKeyEncodingConfig& config) const;
1176
+
1177
+ EVPKeyCtxPointer newCtx() const;
1178
+
1179
+ static bool IsRSAPrivateKey(const Buffer<const unsigned char>& buffer);
1180
+
1181
+ std::optional<uint32_t> getBytesOfRS() const;
1182
+ int getDefaultSignPadding() const;
1183
+ operator Rsa() const;
1184
+ operator Dsa() const;
1185
+
1186
+ bool isRsaVariant() const;
1187
+ bool isOneShotVariant() const;
1188
+ bool isSigVariant() const;
1189
+ bool validateDsaParameters() const;
1190
+
1191
+ private:
1192
+ DeleteFnPtr<EVP_PKEY, EVP_PKEY_free> pkey_;
1193
+ };
1194
+
1195
+ class DHPointer final {
1196
+ public:
1197
+ enum class FindGroupOption {
1198
+ NONE,
1199
+ // There are known and documented security issues with prime groups smaller
1200
+ // than 2048 bits. When the NO_SMALL_PRIMES option is set, these small prime
1201
+ // groups will not be supported.
1202
+ NO_SMALL_PRIMES,
1203
+ };
1204
+
1205
+ static BignumPointer GetStandardGenerator();
1206
+
1207
+ static BignumPointer FindGroup(
1208
+ std::string_view name, FindGroupOption option = FindGroupOption::NONE);
1209
+ static DHPointer FromGroup(std::string_view name,
1210
+ FindGroupOption option = FindGroupOption::NONE);
1211
+
1212
+ static DHPointer New(BignumPointer&& p, BignumPointer&& g);
1213
+ static DHPointer New(size_t bits, unsigned int generator);
1214
+
1215
+ DHPointer() = default;
1216
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1217
+ explicit DHPointer(EVPKeyPointer&& key, const char* group_name = nullptr);
1218
+ DHPointer(BignumPointer&& p, BignumPointer&& g, const char* group_name);
1219
+ #else
1220
+ explicit DHPointer(DH* dh);
1221
+ #endif
1222
+ DHPointer(DHPointer&& other) noexcept;
1223
+ DHPointer& operator=(DHPointer&& other) noexcept;
1224
+ NCRYPTO_DISALLOW_COPY(DHPointer)
1225
+ ~DHPointer();
1226
+
1227
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1228
+ inline bool operator==(std::nullptr_t) noexcept {
1229
+ return !operator bool();
1230
+ }
1231
+ inline operator bool() const {
1232
+ return dh_ != nullptr || (p_ && g_);
1233
+ }
1234
+ #else
1235
+ inline bool operator==(std::nullptr_t) noexcept { return dh_ == nullptr; }
1236
+ inline operator bool() const { return dh_ != nullptr; }
1237
+ #endif
1238
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
1239
+ inline DH* get() const { return dh_.get(); }
1240
+ void reset(DH* dh = nullptr);
1241
+ DH* release();
1242
+ #else
1243
+ inline EVP_PKEY* get() const {
1244
+ return dh_.get();
1245
+ }
1246
+ void reset(EVP_PKEY* dh = nullptr);
1247
+ EVP_PKEY* release();
1248
+ #endif
1249
+
1250
+ enum class CheckResult {
1251
+ NONE,
1252
+ P_NOT_PRIME = 0x01,
1253
+ P_NOT_SAFE_PRIME = 0x02,
1254
+ UNABLE_TO_CHECK_GENERATOR = 0x04,
1255
+ NOT_SUITABLE_GENERATOR = 0x08,
1256
+ Q_NOT_PRIME = 0x10,
1257
+ INVALID_Q = 0x20,
1258
+ #ifndef OPENSSL_IS_BORINGSSL
1259
+ // BoringSSL does not define DH_CHECK_INVALID_J_VALUE.
1260
+ INVALID_J = 0x40,
1261
+ MODULUS_TOO_SMALL = 0x80,
1262
+ MODULUS_TOO_LARGE = 0x100,
1263
+ #endif
1264
+ CHECK_FAILED = 512,
1265
+ };
1266
+ CheckResult check();
1267
+
1268
+ enum class CheckPublicKeyResult {
1269
+ NONE,
1270
+ TOO_SMALL,
1271
+ TOO_LARGE,
1272
+ INVALID,
1273
+ CHECK_FAILED = 512,
1274
+ };
1275
+ // Check to see if the given public key is suitable for this DH instance.
1276
+ CheckPublicKeyResult checkPublicKey(const BignumPointer& pub_key);
1277
+
1278
+ DataPointer getPrime() const;
1279
+ size_t getPrimeBits() const;
1280
+ DataPointer getGenerator() const;
1281
+ DataPointer getPublicKey() const;
1282
+ DataPointer getPrivateKey() const;
1283
+ bool hasPrivateKey() const;
1284
+ DataPointer generateKeys();
1285
+ DataPointer computeSecret(const BignumPointer& peer) const;
1286
+
1287
+ bool setPublicKey(BignumPointer&& key);
1288
+ bool setPrivateKey(BignumPointer&& key);
1289
+
1290
+ size_t size() const;
1291
+
1292
+ static DataPointer stateless(const EVPKeyPointer& ourKey,
1293
+ const EVPKeyPointer& theirKey);
1294
+
1295
+ private:
1296
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1297
+ DeleteFnPtr<EVP_PKEY, EVP_PKEY_free> dh_;
1298
+ BignumPointer p_;
1299
+ BignumPointer g_;
1300
+ BignumPointer pub_key_;
1301
+ BignumPointer pvt_key_;
1302
+ const char* group_name_ = nullptr;
1303
+ #else
1304
+ DeleteFnPtr<DH, DH_free> dh_;
1305
+ #endif
1306
+ };
1307
+
1308
+ struct StackOfX509Deleter {
1309
+ void operator()(STACK_OF(X509) * p) const { sk_X509_pop_free(p, X509_free); }
1310
+ };
1311
+ using StackOfX509 = std::unique_ptr<STACK_OF(X509), StackOfX509Deleter>;
1312
+
1313
+ class SSLCtxPointer final {
1314
+ public:
1315
+ SSLCtxPointer() = default;
1316
+ explicit SSLCtxPointer(SSL_CTX* ctx);
1317
+ SSLCtxPointer(SSLCtxPointer&& other) noexcept;
1318
+ SSLCtxPointer& operator=(SSLCtxPointer&& other) noexcept;
1319
+ NCRYPTO_DISALLOW_COPY(SSLCtxPointer)
1320
+ ~SSLCtxPointer();
1321
+
1322
+ inline bool operator==(std::nullptr_t) const noexcept {
1323
+ return ctx_ == nullptr;
1324
+ }
1325
+ inline operator bool() const { return ctx_ != nullptr; }
1326
+ inline SSL_CTX* get() const { return ctx_.get(); }
1327
+ void reset(SSL_CTX* ctx = nullptr);
1328
+ void reset(const SSL_METHOD* method);
1329
+ SSL_CTX* release();
1330
+
1331
+ bool setGroups(const char* groups);
1332
+ void setStatusCallback(auto callback) {
1333
+ if (!ctx_) return;
1334
+ SSL_CTX_set_tlsext_status_cb(get(), callback);
1335
+ SSL_CTX_set_tlsext_status_arg(get(), nullptr);
1336
+ }
1337
+
1338
+ bool setCipherSuites(const char* ciphers);
1339
+
1340
+ static SSLCtxPointer NewServer();
1341
+ static SSLCtxPointer NewClient();
1342
+ static SSLCtxPointer New(const SSL_METHOD* method = TLS_method());
1343
+
1344
+ private:
1345
+ DeleteFnPtr<SSL_CTX, SSL_CTX_free> ctx_;
1346
+ };
1347
+
1348
+ class SSLPointer final {
1349
+ public:
1350
+ SSLPointer() = default;
1351
+ explicit SSLPointer(SSL* ssl);
1352
+ SSLPointer(SSLPointer&& other) noexcept;
1353
+ SSLPointer& operator=(SSLPointer&& other) noexcept;
1354
+ NCRYPTO_DISALLOW_COPY(SSLPointer)
1355
+ ~SSLPointer();
1356
+
1357
+ inline bool operator==(std::nullptr_t) noexcept { return ssl_ == nullptr; }
1358
+ inline operator bool() const { return ssl_ != nullptr; }
1359
+ inline SSL* get() const { return ssl_.get(); }
1360
+ inline operator SSL*() const { return ssl_.get(); }
1361
+ void reset(SSL* ssl = nullptr);
1362
+ SSL* release();
1363
+
1364
+ bool setSession(const SSLSessionPointer& session);
1365
+ bool setSniContext(const SSLCtxPointer& ctx) const;
1366
+
1367
+ std::optional<const std::string_view> getServerName() const;
1368
+ X509View getCertificate() const;
1369
+ EVPKeyPointer getPeerTempKey() const;
1370
+ std::optional<std::string_view> getNegotiatedGroup() const;
1371
+ const SSL_CIPHER* getCipher() const;
1372
+ bool isServer() const;
1373
+
1374
+ std::optional<std::string_view> getCipherName() const;
1375
+ std::optional<std::string_view> getCipherStandardName() const;
1376
+ std::optional<std::string_view> getCipherVersion() const;
1377
+
1378
+ std::optional<uint32_t> verifyPeerCertificate() const;
1379
+
1380
+ static std::optional<int> getSecurityLevel();
1381
+
1382
+ void getCiphers(std::function<void(const char*)> cb) const;
1383
+
1384
+ static SSLPointer New(const SSLCtxPointer& ctx);
1385
+ static std::optional<const std::string_view> GetServerName(const SSL* ssl);
1386
+
1387
+ private:
1388
+ DeleteFnPtr<SSL, SSL_free> ssl_;
1389
+ };
1390
+
1391
+ class X509Name final {
1392
+ public:
1393
+ X509Name();
1394
+ explicit X509Name(const X509_NAME* name);
1395
+ NCRYPTO_DISALLOW_COPY_AND_MOVE(X509Name)
1396
+
1397
+ inline operator const X509_NAME*() const { return name_; }
1398
+ inline operator bool() const { return name_ != nullptr; }
1399
+ inline const X509_NAME* get() const { return name_; }
1400
+ inline size_t size() const { return total_; }
1401
+
1402
+ class Iterator final {
1403
+ public:
1404
+ Iterator(const X509Name& name, int pos);
1405
+ Iterator(const Iterator& other) = default;
1406
+ Iterator(Iterator&& other) = default;
1407
+ Iterator& operator=(const Iterator& other) = delete;
1408
+ Iterator& operator=(Iterator&& other) = delete;
1409
+ Iterator& operator++();
1410
+ operator bool() const;
1411
+ bool operator==(const Iterator& other) const;
1412
+ bool operator!=(const Iterator& other) const;
1413
+ std::pair<std::string, std::string> operator*() const;
1414
+
1415
+ private:
1416
+ const X509Name& name_;
1417
+ int loc_;
1418
+ };
1419
+
1420
+ inline Iterator begin() const { return Iterator(*this, 0); }
1421
+ inline Iterator end() const { return Iterator(*this, total_); }
1422
+
1423
+ private:
1424
+ const X509_NAME* name_;
1425
+ int total_;
1426
+ };
1427
+
1428
+ class X509View final {
1429
+ public:
1430
+ static X509View From(const SSLPointer& ssl);
1431
+ static X509View From(const SSLCtxPointer& ctx);
1432
+
1433
+ X509View() = default;
1434
+ inline explicit X509View(const X509* cert) : cert_(cert) {}
1435
+ X509View(const X509View& other) = default;
1436
+ X509View& operator=(const X509View& other) = default;
1437
+ NCRYPTO_DISALLOW_MOVE(X509View)
1438
+
1439
+ inline X509* get() const { return const_cast<X509*>(cert_); }
1440
+ inline operator X509*() const { return const_cast<X509*>(cert_); }
1441
+ inline operator const X509*() const { return cert_; }
1442
+
1443
+ inline bool operator==(std::nullptr_t) noexcept { return cert_ == nullptr; }
1444
+ inline operator bool() const { return cert_ != nullptr; }
1445
+
1446
+ BIOPointer toPEM() const;
1447
+ BIOPointer toDER() const;
1448
+
1449
+ const X509Name getSubjectName() const;
1450
+ const X509Name getIssuerName() const;
1451
+ BIOPointer getSubject() const;
1452
+ BIOPointer getSubjectAltName() const;
1453
+ BIOPointer getIssuer() const;
1454
+ BIOPointer getInfoAccess() const;
1455
+ BIOPointer getValidFrom() const;
1456
+ BIOPointer getValidTo() const;
1457
+ std::optional<std::string_view> getSignatureAlgorithm() const;
1458
+ std::optional<std::string> getSignatureAlgorithmOID() const;
1459
+ int64_t getValidFromTime() const;
1460
+ int64_t getValidToTime() const;
1461
+ DataPointer getSerialNumber() const;
1462
+ Result<EVPKeyPointer, int> getPublicKey() const;
1463
+ StackOfASN1 getKeyUsage() const;
1464
+
1465
+ bool isCA() const;
1466
+ bool isIssuedBy(const X509View& other) const;
1467
+ bool checkPrivateKey(const EVPKeyPointer& pkey) const;
1468
+ bool checkPublicKey(const EVPKeyPointer& pkey) const;
1469
+
1470
+ std::optional<std::string> getFingerprint(const Digest& method) const;
1471
+
1472
+ X509Pointer clone() const;
1473
+
1474
+ enum class CheckMatch {
1475
+ NO_MATCH,
1476
+ MATCH,
1477
+ INVALID_NAME,
1478
+ OPERATION_FAILED,
1479
+ };
1480
+ CheckMatch checkHost(std::string_view host,
1481
+ int flags,
1482
+ DataPointer* peerName = nullptr) const;
1483
+ CheckMatch checkEmail(std::string_view email, int flags) const;
1484
+ CheckMatch checkIp(std::string_view ip, int flags) const;
1485
+
1486
+ using UsageCallback = std::function<void(const char*)>;
1487
+ bool enumUsages(UsageCallback callback) const;
1488
+
1489
+ template <typename T>
1490
+ using KeyCallback = std::function<bool(const T& t)>;
1491
+ bool ifRsa(KeyCallback<Rsa> callback) const;
1492
+ bool ifEc(KeyCallback<Ec> callback) const;
1493
+
1494
+ private:
1495
+ const X509* cert_ = nullptr;
1496
+ };
1497
+
1498
+ class X509Pointer final {
1499
+ public:
1500
+ static Result<X509Pointer, int> Parse(Buffer<const unsigned char> buffer);
1501
+ static X509Pointer IssuerFrom(const SSLPointer& ssl, const X509View& view);
1502
+ static X509Pointer IssuerFrom(const SSL_CTX* ctx, const X509View& view);
1503
+ static X509Pointer PeerFrom(const SSLPointer& ssl);
1504
+
1505
+ X509Pointer() = default;
1506
+ explicit X509Pointer(X509* cert);
1507
+ X509Pointer(X509Pointer&& other) noexcept;
1508
+ X509Pointer& operator=(X509Pointer&& other) noexcept;
1509
+ NCRYPTO_DISALLOW_COPY(X509Pointer)
1510
+ ~X509Pointer();
1511
+
1512
+ inline bool operator==(std::nullptr_t) noexcept { return cert_ == nullptr; }
1513
+ inline operator bool() const { return cert_ != nullptr; }
1514
+ inline X509* get() const { return cert_.get(); }
1515
+ inline operator X509*() const { return cert_.get(); }
1516
+ inline operator const X509*() const { return cert_.get(); }
1517
+ void reset(X509* cert = nullptr);
1518
+ X509* release();
1519
+
1520
+ X509View view() const;
1521
+ operator X509View() const { return view(); }
1522
+
1523
+ static const char* ErrorCode(int32_t err);
1524
+ static std::optional<const char*> ErrorReason(int32_t err);
1525
+
1526
+ private:
1527
+ DeleteFnPtr<X509, X509_free> cert_;
1528
+ };
1529
+
1530
+ class ECDSASigPointer final {
1531
+ public:
1532
+ explicit ECDSASigPointer();
1533
+ explicit ECDSASigPointer(ECDSA_SIG* sig);
1534
+ ECDSASigPointer(ECDSASigPointer&& other) noexcept;
1535
+ ECDSASigPointer& operator=(ECDSASigPointer&& other) noexcept;
1536
+ NCRYPTO_DISALLOW_COPY(ECDSASigPointer)
1537
+ ~ECDSASigPointer();
1538
+
1539
+ inline bool operator==(std::nullptr_t) noexcept { return sig_ == nullptr; }
1540
+ inline operator bool() const { return sig_ != nullptr; }
1541
+ inline ECDSA_SIG* get() const { return sig_.get(); }
1542
+ inline operator ECDSA_SIG*() const { return sig_.get(); }
1543
+ void reset(ECDSA_SIG* sig = nullptr);
1544
+ ECDSA_SIG* release();
1545
+
1546
+ static ECDSASigPointer New();
1547
+ static ECDSASigPointer Parse(const Buffer<const unsigned char>& buffer);
1548
+
1549
+ inline const BIGNUM* r() const { return pr_; }
1550
+ inline const BIGNUM* s() const { return ps_; }
1551
+
1552
+ bool setParams(BignumPointer&& r, BignumPointer&& s);
1553
+
1554
+ Buffer<unsigned char> encode() const;
1555
+
1556
+ private:
1557
+ DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free> sig_;
1558
+ const BIGNUM* pr_ = nullptr;
1559
+ const BIGNUM* ps_ = nullptr;
1560
+ };
1561
+
1562
+ class ECGroupPointer final {
1563
+ public:
1564
+ explicit ECGroupPointer();
1565
+ explicit ECGroupPointer(EC_GROUP* group);
1566
+ ECGroupPointer(ECGroupPointer&& other) noexcept;
1567
+ ECGroupPointer& operator=(ECGroupPointer&& other) noexcept;
1568
+ NCRYPTO_DISALLOW_COPY(ECGroupPointer)
1569
+ ~ECGroupPointer();
1570
+
1571
+ inline bool operator==(std::nullptr_t) noexcept { return group_ == nullptr; }
1572
+ inline operator bool() const { return group_ != nullptr; }
1573
+ inline EC_GROUP* get() const { return group_.get(); }
1574
+ inline operator EC_GROUP*() const { return group_.get(); }
1575
+ void reset(EC_GROUP* group = nullptr);
1576
+ EC_GROUP* release();
1577
+
1578
+ static ECGroupPointer NewByCurveName(int nid);
1579
+
1580
+ private:
1581
+ DeleteFnPtr<EC_GROUP, EC_GROUP_free> group_;
1582
+ };
1583
+
1584
+ class ECPointPointer final {
1585
+ public:
1586
+ ECPointPointer();
1587
+ explicit ECPointPointer(EC_POINT* point);
1588
+ ECPointPointer(ECPointPointer&& other) noexcept;
1589
+ ECPointPointer& operator=(ECPointPointer&& other) noexcept;
1590
+ NCRYPTO_DISALLOW_COPY(ECPointPointer)
1591
+ ~ECPointPointer();
1592
+
1593
+ inline bool operator==(std::nullptr_t) noexcept { return point_ == nullptr; }
1594
+ inline operator bool() const { return point_ != nullptr; }
1595
+ inline EC_POINT* get() const { return point_.get(); }
1596
+ inline operator EC_POINT*() const { return point_.get(); }
1597
+ void reset(EC_POINT* point = nullptr);
1598
+ EC_POINT* release();
1599
+
1600
+ bool setFromBuffer(const Buffer<const unsigned char>& buffer,
1601
+ const EC_GROUP* group);
1602
+ bool mul(const EC_GROUP* group, const BIGNUM* priv_key);
1603
+
1604
+ static ECPointPointer New(const EC_GROUP* group);
1605
+
1606
+ private:
1607
+ DeleteFnPtr<EC_POINT, EC_POINT_free> point_;
1608
+ };
1609
+
1610
+ class ECKeyPointer final {
1611
+ friend class EVPKeyPointer;
1612
+
1613
+ public:
1614
+ ECKeyPointer();
1615
+ explicit ECKeyPointer(const EVPKeyPointer& key);
1616
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
1617
+ explicit ECKeyPointer(EC_KEY* key);
1618
+ #endif
1619
+ ECKeyPointer(ECKeyPointer&& other) noexcept;
1620
+ ECKeyPointer& operator=(ECKeyPointer&& other) noexcept;
1621
+ NCRYPTO_DISALLOW_COPY(ECKeyPointer)
1622
+ ~ECKeyPointer();
1623
+
1624
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1625
+ inline bool operator==(std::nullptr_t) noexcept {
1626
+ return group_ == nullptr;
1627
+ }
1628
+ inline operator bool() const {
1629
+ return group_ != nullptr;
1630
+ }
1631
+ #else
1632
+ inline bool operator==(std::nullptr_t) noexcept { return key_ == nullptr; }
1633
+ inline operator bool() const { return key_ != nullptr; }
1634
+ #endif
1635
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
1636
+ inline EC_KEY* get() const { return key_.get(); }
1637
+ inline operator EC_KEY*() const { return key_.get(); }
1638
+ void reset(EC_KEY* key = nullptr);
1639
+ EC_KEY* release();
1640
+ #else
1641
+ void reset();
1642
+ #endif
1643
+
1644
+ ECKeyPointer clone() const;
1645
+ bool setPrivateKey(const BignumPointer& priv);
1646
+ bool setPublicKey(const ECPointPointer& pub);
1647
+ bool setPublicKeyRaw(const BignumPointer& x, const BignumPointer& y);
1648
+ bool generate();
1649
+ bool checkKey() const;
1650
+ DataPointer computeSecret(const ECPointPointer& peer) const;
1651
+
1652
+ const EC_GROUP* getGroup() const;
1653
+ const BIGNUM* getPrivateKey() const;
1654
+ const EC_POINT* getPublicKey() const;
1655
+
1656
+ static ECKeyPointer New(const EC_GROUP* group);
1657
+ static ECKeyPointer NewByCurveName(int nid);
1658
+
1659
+ #if NCRYPTO_USE_LEGACY_KEY_TYPES
1660
+ static const EC_POINT* GetPublicKey(const EC_KEY* key);
1661
+ static const BIGNUM* GetPrivateKey(const EC_KEY* key);
1662
+ static const EC_GROUP* GetGroup(const EC_KEY* key);
1663
+ static int GetGroupName(const EC_KEY* key);
1664
+ static bool Check(const EC_KEY* key);
1665
+ #endif
1666
+
1667
+ private:
1668
+ #if NCRYPTO_USE_OPENSSL3_PROVIDER
1669
+ DeleteFnPtr<EC_GROUP, EC_GROUP_free> group_;
1670
+ DeleteFnPtr<EC_POINT, EC_POINT_free> pub_;
1671
+ DeleteFnPtr<BIGNUM, BN_clear_free> priv_;
1672
+ #else
1673
+ DeleteFnPtr<EC_KEY, EC_KEY_free> key_;
1674
+ #endif
1675
+ };
1676
+
1677
+ class EVPMDCtxPointer final {
1678
+ public:
1679
+ EVPMDCtxPointer();
1680
+ explicit EVPMDCtxPointer(EVP_MD_CTX* ctx);
1681
+ EVPMDCtxPointer(EVPMDCtxPointer&& other) noexcept;
1682
+ EVPMDCtxPointer& operator=(EVPMDCtxPointer&& other) noexcept;
1683
+ NCRYPTO_DISALLOW_COPY(EVPMDCtxPointer)
1684
+ ~EVPMDCtxPointer();
1685
+
1686
+ inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; }
1687
+ inline operator bool() const { return ctx_ != nullptr; }
1688
+ inline EVP_MD_CTX* get() const { return ctx_.get(); }
1689
+ inline operator EVP_MD_CTX*() const { return ctx_.get(); }
1690
+ void reset(EVP_MD_CTX* ctx = nullptr);
1691
+ EVP_MD_CTX* release();
1692
+
1693
+ bool digestInit(const Digest& digest);
1694
+ bool digestUpdate(const Buffer<const void>& in);
1695
+ DataPointer digestFinal(size_t length);
1696
+ bool digestFinalInto(Buffer<void>* buf);
1697
+ size_t getExpectedSize();
1698
+
1699
+ std::optional<EVP_PKEY_CTX*> signInit(const EVPKeyPointer& key,
1700
+ const Digest& digest);
1701
+ std::optional<EVP_PKEY_CTX*> verifyInit(const EVPKeyPointer& key,
1702
+ const Digest& digest);
1703
+
1704
+ std::optional<EVP_PKEY_CTX*> signInitWithContext(
1705
+ const EVPKeyPointer& key,
1706
+ const Digest& digest,
1707
+ const Buffer<const unsigned char>& context_string);
1708
+ std::optional<EVP_PKEY_CTX*> verifyInitWithContext(
1709
+ const EVPKeyPointer& key,
1710
+ const Digest& digest,
1711
+ const Buffer<const unsigned char>& context_string);
1712
+
1713
+ DataPointer signOneShot(const Buffer<const unsigned char>& buf) const;
1714
+ DataPointer sign(const Buffer<const unsigned char>& buf) const;
1715
+ bool verify(const Buffer<const unsigned char>& buf,
1716
+ const Buffer<const unsigned char>& sig) const;
1717
+ // Unlike verify(), preserves EVP_DigestVerify()'s three-way result.
1718
+ int verifyOneShot(const Buffer<const unsigned char>& buf,
1719
+ const Buffer<const unsigned char>& sig) const;
1720
+
1721
+ const EVP_MD* getDigest() const;
1722
+ size_t getDigestSize() const;
1723
+ bool hasXofFlag() const;
1724
+
1725
+ bool copyTo(const EVPMDCtxPointer& other) const;
1726
+
1727
+ static EVPMDCtxPointer New();
1728
+
1729
+ private:
1730
+ DeleteFnPtr<EVP_MD_CTX, EVP_MD_CTX_free> ctx_;
1731
+ };
1732
+
1733
+ #if !OPENSSL_WITH_EVP_MAC
1734
+ class HMACCtxPointer final {
1735
+ public:
1736
+ HMACCtxPointer();
1737
+ explicit HMACCtxPointer(HMAC_CTX* ctx);
1738
+ HMACCtxPointer(HMACCtxPointer&& other) noexcept;
1739
+ HMACCtxPointer& operator=(HMACCtxPointer&& other) noexcept;
1740
+ NCRYPTO_DISALLOW_COPY(HMACCtxPointer)
1741
+ ~HMACCtxPointer();
1742
+
1743
+ inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; }
1744
+ inline operator bool() const { return ctx_ != nullptr; }
1745
+ inline HMAC_CTX* get() const { return ctx_.get(); }
1746
+ inline operator HMAC_CTX*() const { return ctx_.get(); }
1747
+ void reset(HMAC_CTX* ctx = nullptr);
1748
+ HMAC_CTX* release();
1749
+
1750
+ bool init(const Buffer<const void>& buf, const Digest& md);
1751
+ bool update(const Buffer<const void>& buf);
1752
+ DataPointer digest();
1753
+ bool digestInto(Buffer<void>* buf);
1754
+
1755
+ static HMACCtxPointer New();
1756
+
1757
+ private:
1758
+ DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_;
1759
+ };
1760
+ #endif // !OPENSSL_WITH_EVP_MAC
1761
+
1762
+ #if OPENSSL_WITH_EVP_MAC
1763
+ class EVPMacPointer final {
1764
+ public:
1765
+ EVPMacPointer() = default;
1766
+ explicit EVPMacPointer(EVP_MAC* mac);
1767
+ EVPMacPointer(EVPMacPointer&& other) noexcept;
1768
+ EVPMacPointer& operator=(EVPMacPointer&& other) noexcept;
1769
+ NCRYPTO_DISALLOW_COPY(EVPMacPointer)
1770
+ ~EVPMacPointer();
1771
+
1772
+ inline bool operator==(std::nullptr_t) noexcept { return mac_ == nullptr; }
1773
+ inline operator bool() const { return mac_ != nullptr; }
1774
+ inline EVP_MAC* get() const { return mac_.get(); }
1775
+ inline operator EVP_MAC*() const { return mac_.get(); }
1776
+ void reset(EVP_MAC* mac = nullptr);
1777
+ EVP_MAC* release();
1778
+
1779
+ static EVPMacPointer Fetch(const char* algorithm);
1780
+
1781
+ private:
1782
+ DeleteFnPtr<EVP_MAC, EVP_MAC_free> mac_;
1783
+ };
1784
+
1785
+ class EVPMacCtxPointer final {
1786
+ public:
1787
+ EVPMacCtxPointer() = default;
1788
+ explicit EVPMacCtxPointer(EVP_MAC_CTX* ctx);
1789
+ EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept;
1790
+ EVPMacCtxPointer& operator=(EVPMacCtxPointer&& other) noexcept;
1791
+ NCRYPTO_DISALLOW_COPY(EVPMacCtxPointer)
1792
+ ~EVPMacCtxPointer();
1793
+
1794
+ inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; }
1795
+ inline operator bool() const { return ctx_ != nullptr; }
1796
+ inline EVP_MAC_CTX* get() const { return ctx_.get(); }
1797
+ inline operator EVP_MAC_CTX*() const { return ctx_.get(); }
1798
+ void reset(EVP_MAC_CTX* ctx = nullptr);
1799
+ EVP_MAC_CTX* release();
1800
+
1801
+ bool init(const Buffer<const void>& key, const OSSL_PARAM* params = nullptr);
1802
+ bool update(const Buffer<const void>& data);
1803
+ DataPointer final(size_t length);
1804
+
1805
+ static EVPMacCtxPointer New(EVP_MAC* mac);
1806
+
1807
+ private:
1808
+ DeleteFnPtr<EVP_MAC_CTX, EVP_MAC_CTX_free> ctx_;
1809
+ };
1810
+
1811
+ class HMACCtxPointer final {
1812
+ public:
1813
+ HMACCtxPointer();
1814
+ HMACCtxPointer(HMACCtxPointer&& other) noexcept;
1815
+ HMACCtxPointer& operator=(HMACCtxPointer&& other) noexcept;
1816
+ NCRYPTO_DISALLOW_COPY(HMACCtxPointer)
1817
+ ~HMACCtxPointer();
1818
+
1819
+ inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; }
1820
+ inline operator bool() const { return ctx_ != nullptr; }
1821
+ void reset();
1822
+
1823
+ bool init(const Buffer<const void>& buf, const Digest& md);
1824
+ bool update(const Buffer<const void>& buf);
1825
+ DataPointer digest();
1826
+ bool digestInto(Buffer<void>* buf);
1827
+
1828
+ static HMACCtxPointer New();
1829
+
1830
+ private:
1831
+ HMACCtxPointer(EVPMacPointer&& mac, EVPMacCtxPointer&& ctx);
1832
+
1833
+ EVPMacPointer mac_;
1834
+ EVPMacCtxPointer ctx_;
1835
+ size_t md_size_ = 0;
1836
+ };
1837
+ #endif // OPENSSL_WITH_EVP_MAC
1838
+
1839
+ #ifndef OPENSSL_NO_ENGINE
1840
+ class EnginePointer final {
1841
+ public:
1842
+ EnginePointer() = default;
1843
+
1844
+ explicit EnginePointer(void* engine_, bool finish_on_exit = false);
1845
+ EnginePointer(EnginePointer&& other) noexcept;
1846
+ EnginePointer& operator=(EnginePointer&& other) noexcept;
1847
+ NCRYPTO_DISALLOW_COPY(EnginePointer)
1848
+ ~EnginePointer();
1849
+
1850
+ inline operator bool() const { return engine != nullptr; }
1851
+ inline void setFinishOnExit() { finish_on_exit = true; }
1852
+
1853
+ void reset(void* engine_ = nullptr, bool finish_on_exit_ = false);
1854
+
1855
+ bool setAsDefault(uint32_t flags, CryptoErrorList* errors = nullptr);
1856
+ bool init(bool finish_on_exit = false);
1857
+ EVPKeyPointer loadPrivateKey(const char* key_name);
1858
+ bool setClientCertEngine(SSL_CTX* ctx);
1859
+
1860
+ void* release();
1861
+
1862
+ // Retrieve an OpenSSL Engine instance by name. If the name does not
1863
+ // identify a valid named engine, the returned EnginePointer will be
1864
+ // empty.
1865
+ static EnginePointer getEngineByName(const char* name,
1866
+ CryptoErrorList* errors = nullptr);
1867
+
1868
+ // Call once when initializing OpenSSL at startup for the process.
1869
+ static void initEnginesOnce();
1870
+
1871
+ private:
1872
+ void* engine = nullptr;
1873
+ bool finish_on_exit = false;
1874
+ };
1875
+ #endif // !OPENSSL_NO_ENGINE
1876
+
1877
+ // ============================================================================
1878
+ // FIPS
1879
+ bool isFipsEnabled();
1880
+
1881
+ bool setFipsEnabled(bool enabled, CryptoErrorList* errors);
1882
+
1883
+ bool testFipsEnabled();
1884
+
1885
+ // ============================================================================
1886
+ // Various utilities
1887
+
1888
+ bool CSPRNG(void* buffer, size_t length) NCRYPTO_MUST_USE_RESULT;
1889
+
1890
+ // This callback is used to avoid the default passphrase callback in OpenSSL
1891
+ // which will typically prompt for the passphrase. The prompting is designed
1892
+ // for the OpenSSL CLI, but works poorly for some environments like Node.js
1893
+ // because it involves synchronous interaction with the controlling terminal,
1894
+ // something we never want, and use this function to avoid it.
1895
+ int NoPasswordCallback(char* buf, int size, int rwflag, void* u);
1896
+
1897
+ int PasswordCallback(char* buf, int size, int rwflag, void* u);
1898
+
1899
+ bool SafeX509SubjectAltNamePrint(const BIOPointer& out,
1900
+ const X509_EXTENSION* ext);
1901
+ bool SafeX509InfoAccessPrint(const BIOPointer& out, const X509_EXTENSION* ext);
1902
+
1903
+ // ============================================================================
1904
+ // SPKAC
1905
+
1906
+ bool VerifySpkac(const char* input, size_t length);
1907
+ BIOPointer ExportPublicKey(const char* input, size_t length);
1908
+
1909
+ // The caller takes ownership of the returned Buffer<char>
1910
+ Buffer<char> ExportChallenge(const char* input, size_t length);
1911
+
1912
+ // ============================================================================
1913
+ // KDF
1914
+
1915
+ const EVP_MD* getDigestByName(const char* name);
1916
+ const EVP_CIPHER* getCipherByName(const char* name);
1917
+
1918
+ // Verify that the specified HKDF output length is valid for the given digest.
1919
+ // The maximum length for HKDF output for a given digest is 255 times the
1920
+ // hash size for the given digest algorithm.
1921
+ bool checkHkdfLength(const Digest& digest, size_t length);
1922
+
1923
+ bool extractP1363(const Buffer<const unsigned char>& buf,
1924
+ unsigned char* dest,
1925
+ size_t n);
1926
+
1927
+ DataPointer hkdf(const Digest& md,
1928
+ const Buffer<const unsigned char>& key,
1929
+ const Buffer<const unsigned char>& info,
1930
+ const Buffer<const unsigned char>& salt,
1931
+ size_t length);
1932
+
1933
+ bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem);
1934
+
1935
+ DataPointer scrypt(const Buffer<const char>& pass,
1936
+ const Buffer<const unsigned char>& salt,
1937
+ uint64_t N,
1938
+ uint64_t r,
1939
+ uint64_t p,
1940
+ uint64_t maxmem,
1941
+ size_t length);
1942
+
1943
+ DataPointer pbkdf2(const Digest& md,
1944
+ const Buffer<const char>& pass,
1945
+ const Buffer<const unsigned char>& salt,
1946
+ uint32_t iterations,
1947
+ size_t length);
1948
+
1949
+ #if OPENSSL_WITH_ARGON2
1950
+ enum class Argon2Type { ARGON2D, ARGON2I, ARGON2ID };
1951
+
1952
+ DataPointer argon2(const Buffer<const char>& pass,
1953
+ const Buffer<const unsigned char>& salt,
1954
+ uint32_t lanes,
1955
+ size_t length,
1956
+ uint32_t memcost,
1957
+ uint32_t iter,
1958
+ uint32_t version,
1959
+ const Buffer<const unsigned char>& secret,
1960
+ const Buffer<const unsigned char>& ad,
1961
+ Argon2Type type);
1962
+ #endif
1963
+
1964
+ // ============================================================================
1965
+ // KEM (Key Encapsulation Mechanism)
1966
+ #if OPENSSL_WITH_KEM
1967
+
1968
+ class KEM final {
1969
+ public:
1970
+ struct EncapsulateResult {
1971
+ DataPointer ciphertext;
1972
+ DataPointer shared_key;
1973
+
1974
+ EncapsulateResult() = default;
1975
+ EncapsulateResult(DataPointer ct, DataPointer sk)
1976
+ : ciphertext(std::move(ct)), shared_key(std::move(sk)) {}
1977
+ };
1978
+
1979
+ // Encapsulate a shared secret using KEM with a public key.
1980
+ // Returns both the ciphertext and shared secret.
1981
+ static std::optional<EncapsulateResult> Encapsulate(
1982
+ const EVPKeyPointer& public_key);
1983
+
1984
+ // Decapsulate a shared secret using KEM with a private key and ciphertext.
1985
+ // Returns the shared secret.
1986
+ static DataPointer Decapsulate(const EVPKeyPointer& private_key,
1987
+ const Buffer<const void>& ciphertext);
1988
+
1989
+ private:
1990
+ #if OPENSSL_WITH_KEM_OPERATION_PARAM
1991
+ static bool SetOperationParameter(EVP_PKEY_CTX* ctx,
1992
+ const EVPKeyPointer& key);
1993
+ #endif
1994
+ };
1995
+
1996
+ #endif // OPENSSL_WITH_KEM
1997
+
1998
+ // ============================================================================
1999
+ // Version metadata
2000
+ #define NCRYPTO_VERSION "0.0.1"
2001
+
2002
+ enum {
2003
+ NCRYPTO_VERSION_MAJOR = 0,
2004
+ NCRYPTO_VERSION_MINOR = 0,
2005
+ NCRYPTO_VERSION_REVISION = 1,
2006
+ };
2007
+
2008
+ } // namespace ncrypto