From d2cd548e862ddf1432d81e45400e4c747541ded4 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 6 Nov 2017 10:30:29 +0100 Subject: [PATCH] src: add openssl-system-ca-path configure option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The motivation for this commit is that we need to specify system CA certificates when building node. While we are aware of the environment variable NODE_EXTRA_CA_CERTS this is not a great solution as we build an RPM and we also don't want users to be able to unset them. The suggestion is to add a configure time property like this: --openssl-system-ca-path=OPENSSL_SYSTEM_CA_PATH Use the specified path to system CA (PEM format) in addition to the OpenSSL supplied CA store or compiled- in Mozilla CA copy. Usage example: $ ./configure --openssl-system-ca-path=/etc/pki/tls/certs/ca-bundle.crt This would add the specified CA certificates in addition to the ones already being used. PR-URL: https://github.com/nodejs/node/pull/16790 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: Tobias Nießen --- configure | 8 ++++++++ node.gyp | 10 ++++++++++ src/node_crypto.cc | 5 +++++ test/parallel/test-process-config.js | 4 +++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 7939887add4111..5a242a1afeec0e 100755 --- a/configure +++ b/configure @@ -174,6 +174,12 @@ parser.add_option('--openssl-use-def-ca-store', dest='use_openssl_ca_store', help='Use OpenSSL supplied CA store instead of compiled-in Mozilla CA copy.') +parser.add_option('--openssl-system-ca-path', + action='store', + dest='openssl_system_ca_path', + help='Use the specified path to system CA (PEM format) in addition to ' + 'the OpenSSL supplied CA store or compiled-in Mozilla CA copy.') + shared_optgroup.add_option('--shared-http-parser', action='store_true', dest='shared_http_parser', @@ -1035,6 +1041,8 @@ def configure_openssl(o): o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 if options.use_openssl_ca_store: o['defines'] += ['NODE_OPENSSL_CERT_STORE'] + if options.openssl_system_ca_path: + o['variables']['openssl_system_ca_path'] = options.openssl_system_ca_path o['variables']['node_without_node_options'] = b(options.without_node_options) if options.without_node_options: o['defines'] += ['NODE_WITHOUT_NODE_OPTIONS'] diff --git a/node.gyp b/node.gyp index 4ae9d36a552413..e42e2ab915c55d 100644 --- a/node.gyp +++ b/node.gyp @@ -284,12 +284,17 @@ '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', ], + 'variables': { + 'openssl_system_ca_path%': '', + }, + 'defines': [ 'NODE_ARCH="<(target_arch)"', 'NODE_PLATFORM="<(OS)"', 'NODE_WANT_INTERNALS=1', # Warn when using deprecated V8 APIs. 'V8_DEPRECATION_WARNINGS=1', + 'NODE_OPENSSL_SYSTEM_CERT_PATH="<(openssl_system_ca_path)"', ], 'conditions': [ [ 'node_shared=="true" and node_module_version!="" and OS!="win"', { @@ -441,6 +446,11 @@ 'defines': [ 'HAVE_OPENSSL=0' ] }], ], + 'direct_dependent_settings': { + 'defines': [ + 'NODE_OPENSSL_SYSTEM_CERT_PATH="<(openssl_system_ca_path)"', + ], + }, }, { 'target_name': 'mkssldef', diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 5504ea3f7ee6cb..3b819acb350fe1 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -148,6 +148,8 @@ static const char* const root_certs[] = { #include "node_root_certs.h" // NOLINT(build/include_order) }; +static const char system_cert_path[] = NODE_OPENSSL_SYSTEM_CERT_PATH; + static std::string extra_root_certs_file; // NOLINT(runtime/string) static X509_STORE* root_cert_store; @@ -800,6 +802,9 @@ static X509_STORE* NewRootCertStore() { } X509_STORE* store = X509_STORE_new(); + if (*system_cert_path != '\0') { + X509_STORE_load_locations(store, system_cert_path, nullptr); + } if (ssl_openssl_cert_store) { X509_STORE_set_default_paths(store); } else { diff --git a/test/parallel/test-process-config.js b/test/parallel/test-process-config.js index 05616480e07861..05f4ca915a5524 100644 --- a/test/parallel/test-process-config.js +++ b/test/parallel/test-process-config.js @@ -45,7 +45,9 @@ if (!fs.existsSync(configPath)) { let config = fs.readFileSync(configPath, 'utf8'); // Clean up comment at the first line. -config = config.split('\n').slice(1).join('\n').replace(/'/g, '"'); +config = config.split('\n').slice(1).join('\n'); +config = config.replace(/"/g, '\\"'); +config = config.replace(/'/g, '"'); config = JSON.parse(config, function(key, value) { if (value === 'true') return true; if (value === 'false') return false;