Skip to content

Commit 3f0c3e1

Browse files
danbevBethGriggs
authored andcommitted
src,deps,build,test: add OpenSSL config appname
This commit adds the setting of an appname (configuration section name), 'nodejs_conf', to be used when reading OpenSSL configuration files. The motivation for this is that currently the default OpenSSL configuration, 'openssl_conf', element will be used which may be undesirable as it might configure OpenSSL in unwanted ways. With this commit it is still possible to use a default openssl.cnf file but the only section that Node.js will read from is a section named 'nodejs_conf'. PR-URL: #43124 Backport-PR-URL: #43539 Refs: #40366 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Beth Griggs <bgriggs@redhat.com>
1 parent 8af0b83 commit 3f0c3e1

8 files changed

+96
-26
lines changed

BUILDING.md

+17
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ file a new issue.
5252
* [Build with a specific ICU](#build-with-a-specific-icu)
5353
* [Unix/macOS](#unixmacos-3)
5454
* [Windows](#windows-4)
55+
* [Configuring OpenSSL config appname](#configure-openssl-appname)
5556
* [Building Node.js with FIPS-compliant OpenSSL](#building-nodejs-with-fips-compliant-openssl)
5657
* [Building Node.js with external core modules](#building-nodejs-with-external-core-modules)
5758
* [Unix/macOS](#unixmacos-4)
@@ -768,6 +769,19 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)
768769
> .\vcbuild full-icu
769770
```
770771

772+
### Configure OpenSSL appname
773+
774+
Node.js can use an OpenSSL configuration file by specifying the environment
775+
variable `OPENSSL_CONF`, or using the command line option `--openssl-conf`, and
776+
if none of those are specified will default to reading the default OpenSSL
777+
configuration file `openssl.cnf`. Node.js will only read a section that is by
778+
default named `nodejs_conf`, but this name can be overridden using the following
779+
configure option:
780+
781+
```console
782+
$ ./configure --openssl-conf-name=<some_conf_name>
783+
```
784+
771785
## Building Node.js with FIPS-compliant OpenSSL
772786

773787
The current version of Node.js supports FIPS when statically and
@@ -819,6 +833,9 @@ $ ls out/Release/obj.target/deps/openssl/lib/openssl-modules/
819833
fips.so
820834
```
821835

836+
Running `configure` without `--openssl-is-fips` flag and rebuilding will reset
837+
the FIPS configuration.
838+
822839
### FIPS support when dynamically linking OpenSSL
823840

824841
For quictls/openssl 3.0 it is possible to enable FIPS when dynamically linking.

configure.py

+8
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@
181181
"e.g. /root/x/y.js will be referenced via require('root/x/y'). "
182182
"Can be used multiple times")
183183

184+
parser.add_argument("--openssl-conf-name",
185+
action="store",
186+
dest="openssl_conf_name",
187+
default='nodejs_conf',
188+
help="The OpenSSL config appname (config section name) used by Node.js")
189+
184190
parser.add_argument('--openssl-default-cipher-list',
185191
action='store',
186192
dest='openssl_default_cipher_list',
@@ -1488,6 +1494,8 @@ def configure_openssl(o):
14881494
if options.openssl_no_asm:
14891495
variables['openssl_no_asm'] = 1
14901496

1497+
o['defines'] += ['NODE_OPENSSL_CONF_NAME=' + options.openssl_conf_name]
1498+
14911499
if options.without_ssl:
14921500
def without_ssl_error(option):
14931501
error('--without-ssl is incompatible with %s' % option)

deps/openssl/nodejs-openssl.cnf

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Use this in order to automatically load providers.
2+
nodejs_conf = openssl_init
3+
4+
# Optionally include a file that is generated by the OpenSSL fipsinstall
5+
# application. This file contains configuration data required by the OpenSSL
6+
# fips provider. It contains a named section e.g. [fips_sect] which is
7+
# referenced from the [provider_sect] below.
8+
# Refer to the OpenSSL security policy for more information.
9+
# .include fipsmodule.cnf
10+
11+
[openssl_init]
12+
providers = provider_sect
13+
14+
# List of providers to load
15+
[provider_sect]
16+
default = default_sect
17+
# The fips section name should match the section name inside the
18+
# included fipsmodule.cnf.
19+
# fips = fips_sect
20+
21+
# If no providers are activated explicitly, the default one is activated implicitly.
22+
# See man 7 OSSL_PROVIDER-default for more details.
23+
#
24+
# If you add a section explicitly activating any other provider(s), you most
25+
# probably need to explicitly activate the default provider, otherwise it
26+
# becomes unavailable in openssl. As a consequence applications depending on
27+
# OpenSSL may not work correctly which could lead to significant system
28+
# problems including inability to remotely access the system.
29+
[default_sect]
30+
# activate = 1

node.gyp

+5-5
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@
364364
'variables': {
365365
'openssl-cli': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)openssl-cli<(EXECUTABLE_SUFFIX)',
366366
'provider_name': 'libopenssl-fipsmodule',
367-
'opensslconfig': './deps/openssl/openssl/apps/openssl.cnf',
367+
'opensslconfig': './deps/openssl/nodejs-openssl.cnf',
368368
'conditions': [
369369
['GENERATOR == "ninja"', {
370370
'fipsmodule_internal': '<(PRODUCT_DIR)/lib/<(provider_name).so',
@@ -374,7 +374,7 @@
374374
}, {
375375
'fipsmodule_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/<(provider_name).so',
376376
'fipsmodule': '<(PRODUCT_DIR)/obj.target/deps/openssl/lib/openssl-modules/fips.so',
377-
'fipsconfig': '<(PRODUCT_DIR)/obj/deps/openssl/fipsmodule.cnf',
377+
'fipsconfig': '<(PRODUCT_DIR)/obj.target/deps/openssl/fipsmodule.cnf',
378378
'opensslconfig_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/openssl.cnf',
379379
}],
380380
],
@@ -426,7 +426,7 @@
426426
}, {
427427
'variables': {
428428
'opensslconfig_internal': '<(obj_dir)/deps/openssl/openssl.cnf',
429-
'opensslconfig': './deps/openssl/openssl/apps/openssl.cnf',
429+
'opensslconfig': './deps/openssl/nodejs-openssl.cnf',
430430
},
431431
'actions': [
432432
{
@@ -435,8 +435,8 @@
435435
'outputs': [ '<(opensslconfig_internal)', ],
436436
'action': [
437437
'python', 'tools/copyfile.py',
438-
'./deps/openssl/openssl/apps/openssl.cnf',
439-
'<(obj_dir)/deps/openssl/openssl.cnf',
438+
'<(opensslconfig)',
439+
'<(opensslconfig_internal)',
440440
],
441441
},
442442
],

src/node.cc

+33-18
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ PVOID old_vectored_exception_handler;
162162
struct V8Platform v8_platform;
163163
} // namespace per_process
164164

165+
// The section in the OpenSSL configuration file to be loaded.
166+
const char* conf_section_name = STRINGIFY(NODE_OPENSSL_CONF_NAME);
167+
165168
#ifdef __POSIX__
166169
void SignalExit(int signo, siginfo_t* info, void* ucontext) {
167170
ResetStdio();
@@ -1084,27 +1087,39 @@ InitializationResult InitializeOncePerProcess(
10841087
// CheckEntropy. CheckEntropy will call RAND_status which will now always
10851088
// return 0, leading to an endless loop and the node process will appear to
10861089
// hang/freeze.
1090+
1091+
// Passing NULL as the config file will allow the default openssl.cnf file
1092+
// to be loaded, but the default section in that file will not be used,
1093+
// instead only the section that matches the value of conf_section_name
1094+
// will be read from the default configuration file.
1095+
// fprintf(stderr, "appanme: %s\n", conf_section_name);
1096+
const char* conf_file = nullptr;
1097+
// Use OPENSSL_CONF environment variable is set.
10871098
std::string env_openssl_conf;
10881099
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);
1100+
if (!env_openssl_conf.empty()) {
1101+
conf_file = env_openssl_conf.c_str();
1102+
}
1103+
// Use --openssl-conf command line option if specified.
1104+
if (!per_process::cli_options->openssl_config.empty()) {
1105+
conf_file = per_process::cli_options->openssl_config.c_str();
1106+
}
10891107

1090-
bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
1091-
if (has_cli_conf || !env_openssl_conf.empty()) {
1092-
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
1093-
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
1094-
if (has_cli_conf) {
1095-
const char* conf = per_process::cli_options->openssl_config.c_str();
1096-
OPENSSL_INIT_set_config_filename(settings, conf);
1097-
}
1098-
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
1099-
OPENSSL_INIT_free(settings);
1100-
1101-
if (ERR_peek_error() != 0) {
1102-
result.exit_code = ERR_GET_REASON(ERR_peek_error());
1103-
result.early_return = true;
1104-
fprintf(stderr, "OpenSSL configuration error:\n");
1105-
ERR_print_errors_fp(stderr);
1106-
return result;
1107-
}
1108+
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
1109+
OPENSSL_INIT_set_config_filename(settings, conf_file);
1110+
OPENSSL_INIT_set_config_appname(settings, conf_section_name);
1111+
OPENSSL_INIT_set_config_file_flags(settings,
1112+
CONF_MFLAGS_IGNORE_MISSING_FILE);
1113+
1114+
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
1115+
OPENSSL_INIT_free(settings);
1116+
1117+
if (ERR_peek_error() != 0) {
1118+
result.exit_code = ERR_GET_REASON(ERR_peek_error());
1119+
result.early_return = true;
1120+
fprintf(stderr, "OpenSSL configuration error:\n");
1121+
ERR_print_errors_fp(stderr);
1122+
return result;
11081123
}
11091124
#else // OPENSSL_VERSION_MAJOR < 3
11101125
if (FIPS_mode()) {

test/fixtures/openssl_fips_disabled.cnf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Skeleton openssl.cnf for testing with FIPS
22

3-
openssl_conf = openssl_conf_section
3+
nodejs_conf = openssl_conf_section
44
authorityKeyIdentifier=keyid:always,issuer:always
55

66
[openssl_conf_section]

test/fixtures/openssl_fips_enabled.cnf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Skeleton openssl.cnf for testing with FIPS
22

3-
openssl_conf = openssl_conf_section
3+
nodejs_conf = openssl_conf_section
44
authorityKeyIdentifier=keyid:always,issuer:always
55

66
[openssl_conf_section]

test/parallel/test-crypto-fips.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ testHelper(
8383
[],
8484
FIPS_DISABLED,
8585
'require("crypto").getFips()',
86-
{ ...process.env, 'OPENSSL_CONF': '' });
86+
{ ...process.env, 'OPENSSL_CONF': ' ' });
8787

8888
// This should succeed for both FIPS and non-FIPS builds in combination with
8989
// OpenSSL 1.1.1 or OpenSSL 3.0

0 commit comments

Comments
 (0)