Skip to content

Commit

Permalink
src: set CONF_MFLAGS_DEFAULT_SECTION for OpenSSL 3
Browse files Browse the repository at this point in the history
This commit adds a call to OPENSSL_init_crypto to initialize
OPENSSL_INIT_LOAD_CONFIG to avoid the default behavior where errors
raised during the parsing of the OpenSSL configuration file are not
propagated and cannot be detected.

The motivation for this is that if FIPS is configured the OpenSSL
configuration file will have an .include pointing to the fipsmodule.cnf
file generated by the openssl fipsinstall command. If the path to this
file is incorrect no error will be reported. For Node.js this will mean
that EntropySource will be called by V8 as part of its initalization
process, and EntropySource will in turn call CheckEntropy. CheckEntropy
will call RAND_status which will now always return 0 leading to an
endless loop and the node process will appear to hang/freeze.

I'll continue investigating the cause of this and see if this is
expected behavior or not, but in the mean time it would be good to be
able to workaround this issue with this commit.

PR-URL: #38732
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Refs: #38633 (review)
  • Loading branch information
danbev authored and danielleadams committed May 31, 2021
1 parent 717a8b6 commit 3741595
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/crypto/crypto_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ void InitCryptoOnce() {
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();

#if OPENSSL_VERSION_MAJOR < 3
// --openssl-config=...
if (!per_process::cli_options->openssl_config.empty()) {
const char* conf = per_process::cli_options->openssl_config.c_str();
OPENSSL_INIT_set_config_filename(settings, conf);
}
#endif

OPENSSL_init_ssl(0, settings);
OPENSSL_INIT_free(settings);
Expand Down
38 changes: 36 additions & 2 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1024,12 +1024,46 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
// In the case of FIPS builds we should make sure
// the random source is properly initialized first.
#if OPENSSL_VERSION_MAJOR >= 3
if (EVP_default_properties_is_fips_enabled(nullptr)) {
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
// avoid the default behavior where errors raised during the parsing of the
// OpenSSL configuration file are not propagated and cannot be detected.
//
// If FIPS is configured the OpenSSL configuration file will have an .include
// pointing to the fipsmodule.cnf file generated by the openssl fipsinstall
// command. If the path to this file is incorrect no error will be reported.
//
// For Node.js this will mean that EntropySource will be called by V8 as part
// of its initalization process, and EntropySource will in turn call
// CheckEntropy. CheckEntropy will call RAND_status which will now always
// return 0, leading to an endless loop and the node process will appear to
// hang/freeze.
std::string env_openssl_conf;
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);

bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
if (has_cli_conf || !env_openssl_conf.empty()) {
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
if (has_cli_conf) {
const char* conf = per_process::cli_options->openssl_config.c_str();
OPENSSL_INIT_set_config_filename(settings, conf);
}
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
OPENSSL_INIT_free(settings);

if (ERR_peek_error() != 0) {
result.exit_code = ERR_GET_REASON(ERR_peek_error());
result.early_return = true;
fprintf(stderr, "OpenSSL configuration error:\n");
ERR_print_errors_fp(stderr);
return result;
}
}
#else
if (FIPS_mode()) {
OPENSSL_init();
#endif
}
#endif
// V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool.
V8::SetEntropySource(crypto::EntropySource);
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-cli-node-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ if (common.isLinux) {
if (common.hasCrypto) {
expectNoWorker('--use-openssl-ca', 'B\n');
expectNoWorker('--use-bundled-ca', 'B\n');
expectNoWorker('--openssl-config=_ossl_cfg', 'B\n');
if (!common.hasOpenSSL3)
expectNoWorker('--openssl-config=_ossl_cfg', 'B\n');
}

// V8 options
Expand Down

0 comments on commit 3741595

Please sign in to comment.