diff --git a/node.gyp b/node.gyp index 264a2cb408ed8b..dcbcca87aa8859 100644 --- a/node.gyp +++ b/node.gyp @@ -1361,6 +1361,9 @@ 'defines': [ 'HAVE_OPENSSL=1', ], + 'sources': [ + 'test/cctest/test_node_crypto.cc', + ] }], [ 'node_use_openssl=="true" and experimental_quic==1', { 'defines': [ @@ -1385,7 +1388,10 @@ ] }], ['OS=="solaris"', { - 'ldflags': [ '-I<(SHARED_INTERMEDIATE_DIR)' ] + 'ldflags': [ '-I<(SHARED_INTERMEDIATE_DIR)' ], + 'sources!': [ + 'test/cctest/test_node_crypto.cc', + ] }], # Skip cctest while building shared lib node for Windows [ 'OS=="win" and node_shared=="true"', { diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 16a14ffcc89591..54ea3404b55218 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -192,7 +192,8 @@ static X509_STORE* NewRootCertStore() { static Mutex root_certs_vector_mutex; Mutex::ScopedLock lock(root_certs_vector_mutex); - if (root_certs_vector.empty()) { + if (root_certs_vector.empty() && + per_process::cli_options->ssl_openssl_cert_store == false) { for (size_t i = 0; i < arraysize(root_certs); i++) { X509* x509 = PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i], @@ -210,7 +211,9 @@ static X509_STORE* NewRootCertStore() { X509_STORE* store = X509_STORE_new(); if (*system_cert_path != '\0') { + ERR_set_mark(); X509_STORE_load_locations(store, system_cert_path, nullptr); + ERR_pop_to_mark(); } Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex); diff --git a/test/cctest/test_node_crypto.cc b/test/cctest/test_node_crypto.cc new file mode 100644 index 00000000000000..c8bb0577d4def2 --- /dev/null +++ b/test/cctest/test_node_crypto.cc @@ -0,0 +1,23 @@ +// This simulates specifying the configuration option --openssl-system-ca-path +// and settting it to a file that does not exist. +#define NODE_OPENSSL_SYSTEM_CERT_PATH "/missing/ca.pem" + +#include "../../src/crypto/crypto_context.cc" // NOLINT(build/include) +#include "node_options.h" +#include "openssl/err.h" +#include "gtest/gtest.h" + +/* + * This test verifies that a call to NewRootCertDir with the build time + * configuration option --openssl-system-ca-path set to an missing file, will + * not leave any OpenSSL errors on the OpenSSL error stack. + * See https://github.com/nodejs/node/issues/35456 for details. + */ +TEST(NodeCrypto, NewRootCertStore) { + node::per_process::cli_options->ssl_openssl_cert_store = true; + X509_STORE* store = node::crypto::NewRootCertStore(); + ASSERT_TRUE(store); + ASSERT_EQ(ERR_peek_error(), 0UL) << "NewRootCertStore should not have left " + "any errors on the OpenSSL error stack\n"; + X509_STORE_free(store); +}