44
44
#if HAVE_OPENSSL
45
45
#include " allocated_buffer-inl.h" // Inlined functions needed by node_crypto.h
46
46
#include " node_crypto.h"
47
+ #include < openssl/conf.h>
47
48
#endif
48
49
49
50
#if defined(NODE_HAVE_I18N_SUPPORT)
@@ -162,6 +163,11 @@ PVOID old_vectored_exception_handler;
162
163
struct V8Platform v8_platform;
163
164
} // namespace per_process
164
165
166
+ // The section in the OpenSSL configuration file to be loaded.
167
+ const char * conf_section_name = STRINGIFY(NODE_OPENSSL_CONF_NAME);
168
+
169
+ const char * fips_error_msg = " OpenSSL error when trying to enable FIPS:\n " ;
170
+
165
171
#ifdef __POSIX__
166
172
void SignalExit (int signo, siginfo_t * info, void * ucontext) {
167
173
ResetStdio ();
@@ -975,6 +981,16 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
975
981
return InitializeOncePerProcess (argc, argv, kDefaultInitialization );
976
982
}
977
983
984
+ InitializationResult handle_openssl_error (int exit_code,
985
+ const char * msg,
986
+ InitializationResult* result) {
987
+ result->exit_code = exit_code;
988
+ result->early_return = true ;
989
+ fprintf (stderr, " %s" , msg);
990
+ ERR_print_errors_fp (stderr);
991
+ return *result;
992
+ }
993
+
978
994
InitializationResult InitializeOncePerProcess (
979
995
int argc,
980
996
char ** argv,
@@ -1054,7 +1070,6 @@ InitializationResult InitializeOncePerProcess(
1054
1070
}
1055
1071
// In the case of FIPS builds we should make sure
1056
1072
// the random source is properly initialized first.
1057
- #if OPENSSL_VERSION_MAJOR >= 3
1058
1073
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
1059
1074
// avoid the default behavior where errors raised during the parsing of the
1060
1075
// OpenSSL configuration file are not propagated and cannot be detected.
@@ -1069,46 +1084,58 @@ InitializationResult InitializeOncePerProcess(
1069
1084
// CheckEntropy. CheckEntropy will call RAND_status which will now always
1070
1085
// return 0, leading to an endless loop and the node process will appear to
1071
1086
// hang/freeze.
1087
+
1088
+ // Passing NULL as the config file will allow the default openssl.cnf file
1089
+ // to be loaded, but the default section in that file will not be used,
1090
+ // instead only the section that matches the value of conf_section_name
1091
+ // will be read from the default configuration file.
1092
+ const char * conf_file = nullptr ;
1093
+ // Use OPENSSL_CONF environment variable is set.
1072
1094
std::string env_openssl_conf;
1073
1095
credentials::SafeGetenv (" OPENSSL_CONF" , &env_openssl_conf);
1096
+ if (!env_openssl_conf.empty ()) {
1097
+ conf_file = env_openssl_conf.c_str ();
1098
+ }
1099
+ // Use --openssl-conf command line option if specified.
1100
+ if (!per_process::cli_options->openssl_config .empty ()) {
1101
+ conf_file = per_process::cli_options->openssl_config .c_str ();
1102
+ }
1074
1103
1075
- bool has_cli_conf = !per_process::cli_options->openssl_config .empty ();
1076
- if (has_cli_conf || !env_openssl_conf.empty ()) {
1077
- OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new ();
1078
- OPENSSL_INIT_set_config_file_flags (settings, CONF_MFLAGS_DEFAULT_SECTION);
1079
- if (has_cli_conf) {
1080
- const char * conf = per_process::cli_options->openssl_config .c_str ();
1081
- OPENSSL_INIT_set_config_filename (settings, conf);
1082
- }
1083
- OPENSSL_init_crypto (OPENSSL_INIT_LOAD_CONFIG, settings);
1084
- OPENSSL_INIT_free (settings);
1085
-
1086
- if (ERR_peek_error () != 0 ) {
1087
- result.exit_code = ERR_GET_REASON (ERR_peek_error ());
1088
- result.early_return = true ;
1089
- fprintf (stderr, " OpenSSL configuration error:\n " );
1090
- ERR_print_errors_fp (stderr);
1091
- return result;
1104
+ OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new ();
1105
+ OPENSSL_INIT_set_config_filename (settings, conf_file);
1106
+ OPENSSL_INIT_set_config_appname (settings, conf_section_name);
1107
+ OPENSSL_INIT_set_config_file_flags (settings,
1108
+ CONF_MFLAGS_IGNORE_MISSING_FILE);
1109
+
1110
+ OPENSSL_init_crypto (OPENSSL_INIT_LOAD_CONFIG, settings);
1111
+ OPENSSL_INIT_free (settings);
1112
+
1113
+ if (ERR_peek_error () != 0 ) {
1114
+ int ossl_error_code = ERR_GET_REASON (ERR_peek_error ());
1115
+ if (ossl_error_code == EVP_R_FIPS_MODE_NOT_SUPPORTED) {
1116
+ if (!crypto::ProcessFipsOptions ()) {
1117
+ return handle_openssl_error (ossl_error_code, fips_error_msg, &result);
1118
+ }
1119
+ } else {
1120
+ return handle_openssl_error (ossl_error_code,
1121
+ " OpenSSL configuration error:\n " ,
1122
+ &result);
1092
1123
}
1093
1124
}
1094
- #else // OPENSSL_VERSION_MAJOR < 3
1095
1125
if (FIPS_mode ()) {
1096
1126
OPENSSL_init ();
1097
1127
}
1098
- #endif
1099
- if (!crypto::ProcessFipsOptions ()) {
1100
- result.exit_code = ERR_GET_REASON (ERR_peek_error ());
1101
- result.early_return = true ;
1102
- fprintf (stderr, " OpenSSL error when trying to enable FIPS:\n " );
1103
- ERR_print_errors_fp (stderr);
1104
- return result;
1105
- }
1106
1128
1107
- // V8 on Windows doesn't have a good source of entropy. Seed it from
1108
- // OpenSSL's pool.
1109
- V8::SetEntropySource (crypto::EntropySource);
1129
+ // V8 on Windows doesn't have a good source of entropy. Seed it from
1130
+ // OpenSSL's pool.
1131
+ V8::SetEntropySource (crypto::EntropySource);
1132
+ if (!crypto::ProcessFipsOptions ()) {
1133
+ return handle_openssl_error (ERR_GET_REASON (ERR_peek_error ()),
1134
+ fips_error_msg,
1135
+ &result);
1136
+ }
1110
1137
#endif // HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
1111
- }
1138
+ }
1112
1139
per_process::v8_platform.Initialize (
1113
1140
static_cast <int >(per_process::cli_options->v8_thread_pool_size ));
1114
1141
if (init_flags & kInitializeV8 ) {
0 commit comments