Browse Source

crypto: support OPENSSL_CONF again

A side-effect of https://github.com/nodejs/node-private/pull/82
was to remove support for OPENSSL_CONF, as well as removing the default
read of a configuration file on startup.

Partly revert this, allowing OPENSSL_CONF to be used to specify a
configuration file to read on startup, but do not read a file by
default.

If the --openssl-config command line option is provided, its value is
used, not the OPENSSL_CONF environment variable.

Fix: https://github.com/nodejs/node/issues/10938
PR-URL: https://github.com/nodejs/node/pull/11006
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
v6
Sam Roberts 8 years ago
parent
commit
59afa275ad
  1. 13
      doc/api/cli.md
  2. 10
      doc/node.1
  3. 14
      src/node.cc
  4. 4
      src/node_crypto.cc
  5. 2
      src/node_internals.h
  6. 25
      test/parallel/test-crypto-fips.js

13
doc/api/cli.md

@ -387,6 +387,18 @@ misformatted, but any errors are otherwise ignored.
Note that neither the well known nor extra certificates are used when the `ca` Note that neither the well known nor extra certificates are used when the `ca`
options property is explicitly specified for a TLS or HTTPS client or server. options property is explicitly specified for a TLS or HTTPS client or server.
### `OPENSSL_CONF=file`
<!-- YAML
added: REPLACEME
-->
Load an OpenSSL configuration file on startup. Among other uses, this can be
used to enable FIPS-compliant crypto if Node.js is built with `./configure
\-\-openssl\-fips`.
If the [`--openssl-config`][] command line option is used, the environment
variable is ignored.
### `SSL_CERT_DIR=dir` ### `SSL_CERT_DIR=dir`
If `--use-openssl-ca` is enabled, this overrides and sets OpenSSL's directory If `--use-openssl-ca` is enabled, this overrides and sets OpenSSL's directory
@ -421,3 +433,4 @@ equivalent to using the `--redirect-warnings=file` command-line flag.
[debugger]: debugger.html [debugger]: debugger.html
[REPL]: repl.html [REPL]: repl.html
[SlowBuffer]: buffer.html#buffer_class_slowbuffer [SlowBuffer]: buffer.html#buffer_class_slowbuffer
[`--openssl-config`]: #cli_openssl_config_file

10
doc/node.1

@ -256,6 +256,16 @@ asynchronous when outputting to a TTY on platforms which support async stdio.
Setting this will void any guarantee that stdio will not be interleaved or Setting this will void any guarantee that stdio will not be interleaved or
dropped at program exit. \fBAvoid use.\fR dropped at program exit. \fBAvoid use.\fR
.TP
.BR OPENSSL_CONF = \fIfile\fR
Load an OpenSSL configuration file on startup. Among other uses, this can be
used to enable FIPS-compliant crypto if Node.js is built with
\fB./configure \-\-openssl\-fips\fR.
If the
\fB\-\-openssl\-config\fR
command line option is used, the environment variable is ignored.
.TP .TP
.BR SSL_CERT_DIR = \fIdir\fR .BR SSL_CERT_DIR = \fIdir\fR
If \fB\-\-use\-openssl\-ca\fR is enabled, this overrides and sets OpenSSL's directory If \fB\-\-use\-openssl\-ca\fR is enabled, this overrides and sets OpenSSL's directory

14
src/node.cc

@ -176,7 +176,7 @@ bool ssl_openssl_cert_store =
bool enable_fips_crypto = false; bool enable_fips_crypto = false;
bool force_fips_crypto = false; bool force_fips_crypto = false;
# endif // NODE_FIPS_MODE # endif // NODE_FIPS_MODE
const char* openssl_config = nullptr; std::string openssl_config; // NOLINT(runtime/string)
#endif // HAVE_OPENSSL #endif // HAVE_OPENSSL
// true if process warnings should be suppressed // true if process warnings should be suppressed
@ -3561,8 +3561,9 @@ static void PrintHelp() {
" --enable-fips enable FIPS crypto at startup\n" " --enable-fips enable FIPS crypto at startup\n"
" --force-fips force FIPS crypto (cannot be disabled)\n" " --force-fips force FIPS crypto (cannot be disabled)\n"
#endif /* NODE_FIPS_MODE */ #endif /* NODE_FIPS_MODE */
" --openssl-config=path load OpenSSL configuration file from\n" " --openssl-config=file load OpenSSL configuration from the\n"
" the specified path\n" " specified file (overrides\n"
" OPENSSL_CONF)\n"
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
" --icu-data-dir=dir set ICU data load path to dir\n" " --icu-data-dir=dir set ICU data load path to dir\n"
@ -3597,6 +3598,8 @@ static void PrintHelp() {
" file\n" " file\n"
"NODE_REDIRECT_WARNINGS write warnings to path instead of\n" "NODE_REDIRECT_WARNINGS write warnings to path instead of\n"
" stderr\n" " stderr\n"
"OPENSSL_CONF load OpenSSL configuration from file\n"
"\n"
"Documentation can be found at https://nodejs.org/\n"); "Documentation can be found at https://nodejs.org/\n");
} }
@ -3746,7 +3749,7 @@ static void ParseArgs(int* argc,
force_fips_crypto = true; force_fips_crypto = true;
#endif /* NODE_FIPS_MODE */ #endif /* NODE_FIPS_MODE */
} else if (strncmp(arg, "--openssl-config=", 17) == 0) { } else if (strncmp(arg, "--openssl-config=", 17) == 0) {
openssl_config = arg + 17; openssl_config.assign(arg + 17);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
} else if (strncmp(arg, "--icu-data-dir=", 15) == 0) { } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
@ -4246,6 +4249,9 @@ void Init(int* argc,
if (config_warning_file.empty()) if (config_warning_file.empty())
SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file); SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file);
if (openssl_config.empty())
SafeGetenv("OPENSSL_CONF", &openssl_config);
// Parse a few arguments which are specific to Node. // Parse a few arguments which are specific to Node.
int v8_argc; int v8_argc;
const char** v8_argv; const char** v8_argv;

4
src/node_crypto.cc

@ -5893,14 +5893,14 @@ void InitCryptoOnce() {
OPENSSL_no_config(); OPENSSL_no_config();
// --openssl-config=... // --openssl-config=...
if (openssl_config != nullptr) { if (!openssl_config.empty()) {
OPENSSL_load_builtin_modules(); OPENSSL_load_builtin_modules();
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
ENGINE_load_builtin_engines(); ENGINE_load_builtin_engines();
#endif #endif
ERR_clear_error(); ERR_clear_error();
CONF_modules_load_file( CONF_modules_load_file(
openssl_config, openssl_config.c_str(),
nullptr, nullptr,
CONF_MFLAGS_DEFAULT_SECTION); CONF_MFLAGS_DEFAULT_SECTION);
int err = ERR_get_error(); int err = ERR_get_error();

2
src/node_internals.h

@ -37,7 +37,7 @@ namespace node {
// Set in node.cc by ParseArgs with the value of --openssl-config. // Set in node.cc by ParseArgs with the value of --openssl-config.
// Used in node_crypto.cc when initializing OpenSSL. // Used in node_crypto.cc when initializing OpenSSL.
extern const char* openssl_config; extern std::string openssl_config;
// Set in node.cc by ParseArgs when --preserve-symlinks is used. // Set in node.cc by ParseArgs when --preserve-symlinks is used.
// Used in node_config.cc to set a constant on process.binding('config') // Used in node_config.cc to set a constant on process.binding('config')

25
test/parallel/test-crypto-fips.js

@ -37,8 +37,9 @@ function testHelper(stream, args, expectedOutput, cmd, env) {
env: env env: env
}); });
console.error('Spawned child [pid:' + child.pid + '] with cmd ' + console.error('Spawned child [pid:' + child.pid + '] with cmd \'' +
cmd + ' and args \'' + args + '\''); cmd + '\' expect %j with args \'' + args + '\'' +
' OPENSSL_CONF=%j', expectedOutput, env.OPENSSL_CONF);
function childOk(child) { function childOk(child) {
console.error('Child #' + ++num_children_ok + console.error('Child #' + ++num_children_ok +
@ -92,10 +93,26 @@ testHelper(
compiledWithFips() ? FIPS_ENABLED : FIPS_DISABLED, compiledWithFips() ? FIPS_ENABLED : FIPS_DISABLED,
'require("crypto").fips', 'require("crypto").fips',
process.env); process.env);
// OPENSSL_CONF should _not_ be able to turn on FIPS mode
// OPENSSL_CONF should be able to turn on FIPS mode
testHelper( testHelper(
'stdout', 'stdout',
[], [],
compiledWithFips() ? FIPS_ENABLED : FIPS_DISABLED,
'require("crypto").fips',
addToEnv('OPENSSL_CONF', CNF_FIPS_ON));
// --openssl-config option should override OPENSSL_CONF
testHelper(
'stdout',
[`--openssl-config=${CNF_FIPS_ON}`],
compiledWithFips() ? FIPS_ENABLED : FIPS_DISABLED,
'require("crypto").fips',
addToEnv('OPENSSL_CONF', CNF_FIPS_OFF));
testHelper(
'stdout',
[`--openssl-config=${CNF_FIPS_OFF}`],
FIPS_DISABLED, FIPS_DISABLED,
'require("crypto").fips', 'require("crypto").fips',
addToEnv('OPENSSL_CONF', CNF_FIPS_ON)); addToEnv('OPENSSL_CONF', CNF_FIPS_ON));
@ -107,6 +124,7 @@ testHelper(
compiledWithFips() ? FIPS_ENABLED : OPTION_ERROR_STRING, compiledWithFips() ? FIPS_ENABLED : OPTION_ERROR_STRING,
'require("crypto").fips', 'require("crypto").fips',
process.env); process.env);
// OPENSSL_CONF should _not_ make a difference to --enable-fips // OPENSSL_CONF should _not_ make a difference to --enable-fips
testHelper( testHelper(
compiledWithFips() ? 'stdout' : 'stderr', compiledWithFips() ? 'stdout' : 'stderr',
@ -122,6 +140,7 @@ testHelper(
compiledWithFips() ? FIPS_ENABLED : OPTION_ERROR_STRING, compiledWithFips() ? FIPS_ENABLED : OPTION_ERROR_STRING,
'require("crypto").fips', 'require("crypto").fips',
process.env); process.env);
// Using OPENSSL_CONF should not make a difference to --force-fips // Using OPENSSL_CONF should not make a difference to --force-fips
testHelper( testHelper(
compiledWithFips() ? 'stdout' : 'stderr', compiledWithFips() ? 'stdout' : 'stderr',

Loading…
Cancel
Save