blob: 2e66a02828b67f15ccc95aa7f006e6d77c0a86c4 [file] [log] [blame]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001From 86d1c0cc6a5dcf57e413a1cc1c29203e87cf9a14 Mon Sep 17 00:00:00 2001
2From: Daniel Bevenius <daniel.bevenius@gmail.com>
3Date: Sat, 16 Oct 2021 08:50:16 +0200
4Subject: [PATCH] src: add --openssl-legacy-provider option
5
6This commit adds an option to Node.js named --openssl-legacy-provider
7and if specified will load OpenSSL 3.0 Legacy provider.
8
9$ ./node --help
10...
11--openssl-legacy-provider enable OpenSSL 3.0 legacy provider
12
13Example usage:
14
15$ ./node --openssl-legacy-provider -p 'crypto.createHash("md4")'
16Hash {
17 _options: undefined,
18 [Symbol(kHandle)]: Hash {},
19 [Symbol(kState)]: { [Symbol(kFinalized)]: false }
20}
21
22Co-authored-by: Richard Lau <rlau@redhat.com>
23
24Refs: https://github.com/nodejs/node/issues/40455
25---
26 doc/api/cli.md | 10 ++++++++++
27 src/crypto/crypto_util.cc | 10 ++++++++++
28 src/node_options.cc | 10 ++++++++++
29 src/node_options.h | 7 +++++++
30 .../test-process-env-allowed-flags-are-documented.js | 5 +++++
31 5 files changed, 42 insertions(+)
32
33diff --git a/doc/api/cli.md b/doc/api/cli.md
34index 74057706bf8d..608b9cdeddf1 100644
35--- a/doc/api/cli.md
36+++ b/doc/api/cli.md
37@@ -652,6 +652,14 @@ Load an OpenSSL configuration file on startup. Among other uses, this can be
38 used to enable FIPS-compliant crypto if Node.js is built
39 against FIPS-enabled OpenSSL.
40
41+### `--openssl-legacy-provider`
42+<!-- YAML
43+added: REPLACEME
44+-->
45+
46+Enable OpenSSL 3.0 legacy provider. For more information please see
47+[providers readme][].
48+
49 ### `--pending-deprecation`
50 <!-- YAML
51 added: v8.0.0
52@@ -1444,6 +1452,7 @@ Node.js options that are allowed are:
53 * `--no-warnings`
54 * `--node-memory-debug`
55 * `--openssl-config`
56+* `--openssl-legacy-provider`
57 * `--pending-deprecation`
58 * `--policy-integrity`
59 * `--preserve-symlinks-main`
60@@ -1814,6 +1823,7 @@ $ node --max-old-space-size=1536 index.js
61 [emit_warning]: process.md#process_process_emitwarning_warning_type_code_ctor
62 [jitless]: https://v8.dev/blog/jitless
63 [libuv threadpool documentation]: https://docs.libuv.org/en/latest/threadpool.html
64+[providers readme]: https://github.com/openssl/openssl/blob/openssl-3.0.0/README-PROVIDERS.md
65 [remote code execution]: https://www.owasp.org/index.php/Code_Injection
66 [timezone IDs]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
67 [ways that `TZ` is handled in other environments]: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
68diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
69index 7e0c8ba3eb60..796ea3025e41 100644
70--- a/src/crypto/crypto_util.cc
71+++ b/src/crypto/crypto_util.cc
72@@ -136,6 +136,16 @@ void InitCryptoOnce() {
73 }
74 #endif
75
76+#if OPENSSL_VERSION_MAJOR >= 3
77+ // --openssl-legacy-provider
78+ if (per_process::cli_options->openssl_legacy_provider) {
79+ OSSL_PROVIDER* legacy_provider = OSSL_PROVIDER_load(nullptr, "legacy");
80+ if (legacy_provider == nullptr) {
81+ fprintf(stderr, "Unable to load legacy provider.\n");
82+ }
83+ }
84+#endif
85+
86 OPENSSL_init_ssl(0, settings);
87 OPENSSL_INIT_free(settings);
88 settings = nullptr;
89diff --git a/src/node_options.cc b/src/node_options.cc
90index 00bdc6688a4c..3363860919a9 100644
91--- a/src/node_options.cc
92+++ b/src/node_options.cc
93@@ -4,6 +4,9 @@
94 #include "env-inl.h"
95 #include "node_binding.h"
96 #include "node_internals.h"
97+#if HAVE_OPENSSL
98+#include "openssl/opensslv.h"
99+#endif
100
101 #include <errno.h>
102 #include <sstream>
103@@ -809,6 +812,13 @@ PerProcessOptionsParser::PerProcessOptionsParser(
104 &PerProcessOptions::secure_heap_min,
105 kAllowedInEnvironment);
106 #endif
107+#if OPENSSL_VERSION_MAJOR >= 3
108+ AddOption("--openssl-legacy-provider",
109+ "enable OpenSSL 3.0 legacy provider",
110+ &PerProcessOptions::openssl_legacy_provider,
111+ kAllowedInEnvironment);
112+
113+#endif // OPENSSL_VERSION_MAJOR
114 AddOption("--use-largepages",
115 "Map the Node.js static code to large pages. Options are "
116 "'off' (the default value, meaning do not map), "
117diff --git a/src/node_options.h b/src/node_options.h
118index fd772478d04d..1c0e018ab16f 100644
119--- a/src/node_options.h
120+++ b/src/node_options.h
121@@ -11,6 +11,10 @@
122 #include "node_mutex.h"
123 #include "util.h"
124
125+#if HAVE_OPENSSL
126+#include "openssl/opensslv.h"
127+#endif
128+
129 namespace node {
130
131 class HostPort {
132@@ -251,6 +255,9 @@ class PerProcessOptions : public Options {
133 bool enable_fips_crypto = false;
134 bool force_fips_crypto = false;
135 #endif
136+#if OPENSSL_VERSION_MAJOR >= 3
137+ bool openssl_legacy_provider = false;
138+#endif
139
140 // Per-process because reports can be triggered outside a known V8 context.
141 bool report_on_fatalerror = false;
142diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js
143index 64626b71f019..8a4e35997907 100644
144--- a/test/parallel/test-process-env-allowed-flags-are-documented.js
145+++ b/test/parallel/test-process-env-allowed-flags-are-documented.js
146@@ -40,6 +40,10 @@ for (const line of [...nodeOptionsLines, ...v8OptionsLines]) {
147 }
148 }
149
150+if (!common.hasOpenSSL3) {
151+ documented.delete('--openssl-legacy-provider');
152+}
153+
154 // Filter out options that are conditionally present.
155 const conditionalOpts = [
156 {
157@@ -47,6 +51,7 @@ const conditionalOpts = [
158 filter: (opt) => {
159 return [
160 '--openssl-config',
161+ common.hasOpenSSL3 ? '--openssl-legacy-provider' : '',
162 '--tls-cipher-list',
163 '--use-bundled-ca',
164 '--use-openssl-ca',
165