From 0aa8ac72bad67d5af3f51f62a5fcc541a9a22799 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Wed, 21 Dec 2016 11:16:38 +0100 Subject: [PATCH 1/3] crypto: do not use pointers to std::vector The pointer to std::vector is unnecessary, so replace it with standard instance. Also, make the for() loop more readable by using actual type instead of inferred - there is no readability benefit here from obfuscating the type. --- src/node_crypto.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 7b3bc406091494..e4ce65d456f7c9 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -123,7 +123,7 @@ const char* const root_certs[] = { std::string extra_root_certs_file; // NOLINT(runtime/string) X509_STORE* root_cert_store; -std::vector* root_certs_vector; +std::vector root_certs_vector; // Just to generate static methods template class SSLWrap; @@ -693,9 +693,7 @@ static int X509_up_ref(X509* cert) { static X509_STORE* NewRootCertStore() { - if (!root_certs_vector) { - root_certs_vector = new std::vector; - + if (root_certs_vector.empty()) { for (size_t i = 0; i < arraysize(root_certs); i++) { BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i])); X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr); @@ -707,12 +705,12 @@ static X509_STORE* NewRootCertStore() { return nullptr; } - root_certs_vector->push_back(x509); + root_certs_vector.push_back(x509); } } X509_STORE* store = X509_STORE_new(); - for (auto& cert : *root_certs_vector) { + for (X509 *cert : root_certs_vector) { X509_up_ref(cert); X509_STORE_add_cert(store, cert); } From d1e022847b08e1bea4a8d490640290b865dc6b44 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Wed, 21 Dec 2016 11:16:38 +0100 Subject: [PATCH 2/3] crypto: Use system CAs instead of using bundled ones NodeJS can already use an external, shared OpenSSL library. This library knows where to look for OS managed certificates. Allow a compile-time option to use this CA store by default instead of using bundled certificates. In case when using bundled OpenSSL, the paths are also valid for majority of Linux systems without additional intervention. If this is not set, we can use SSL_CERT_DIR to point it to correct location. Fixes: https://github.com/nodejs/node/issues/3159 PR-URL: https://github.com/nodejs/node/pull/8334 --- configure | 7 +++++++ src/node_crypto.cc | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/configure b/configure index bf937ca702a550..4cfa1f76ff68f2 100755 --- a/configure +++ b/configure @@ -133,6 +133,11 @@ parser.add_option('--openssl-fips', dest='openssl_fips', help='Build OpenSSL using FIPS canister .o file in supplied folder') +parser.add_option('--openssl-use-def-ca-store', + action='store_true', + dest='use_openssl_ca_store', + help='Use OpenSSL supplied CA store instead of compiled-in Mozilla CA copy.') + shared_optgroup.add_option('--shared-http-parser', action='store_true', dest='shared_http_parser', @@ -927,6 +932,8 @@ def configure_openssl(o): o['variables']['node_use_openssl'] = b(not options.without_ssl) o['variables']['node_shared_openssl'] = b(options.shared_openssl) 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_fips: o['variables']['openssl_fips'] = options.openssl_fips fips_dir = os.path.join(root_dir, 'deps', 'openssl', 'fips') diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e4ce65d456f7c9..dcaeed9f52bf05 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -710,10 +710,14 @@ static X509_STORE* NewRootCertStore() { } X509_STORE* store = X509_STORE_new(); +#if defined(NODE_OPENSSL_CERT_STORE) + X509_STORE_set_default_paths(store); +#else for (X509 *cert : root_certs_vector) { X509_up_ref(cert); X509_STORE_add_cert(store, cert); } +#endif return store; } From 1172288a13eb634bd0ff103a19d3d76ab2db182b Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Wed, 21 Dec 2016 11:16:39 +0100 Subject: [PATCH 3/3] crypto: ability to select cert store at runtime --- doc/api/cli.md | 28 ++++++++++++++++++++++++++++ doc/node.1 | 25 +++++++++++++++++++++++++ src/node.cc | 22 ++++++++++++++++++++++ src/node.h | 5 ++++- src/node_crypto.cc | 14 +++++++------- 5 files changed, 86 insertions(+), 8 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 2000c2b3334b74..c7165112bcc243 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -257,6 +257,24 @@ 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`. +### `--use-openssl-ca`, `--use-bundled-ca` + + +Use OpenSSL's default CA store or use bundled Mozilla CA store as supplied by +current NodeJS version. The default store is selectable at build-time. + +Using OpenSSL store allows for external modifications of the store. For most +Linux and BSD distributions, this store is maintained by the distribution +maintainers and system administrators. OpenSSL CA store location is dependent on +configuration of the OpenSSL library but this can be altered at runtime using +environmental variables. + +The bundled CA store, as supplied by NodeJS, is a snapshot of Mozilla CA store +that is fixed at release time. It is identical on all supported platforms. + +See `SSL_CERT_DIR` and `SSL_CERT_FILE`. ### `--icu-data-dir=file`