aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Bevenius <daniel.bevenius@gmail.com>2020-10-06 13:25:23 +0200
committerDaniel Bevenius <daniel.bevenius@gmail.com>2020-10-21 14:32:59 +0200
commit610c68c4587db1ed47a074f28a527cc24223c7a6 (patch)
tree0d0151fa35c42ee5d4866f8600d8e38abae1d4c6
parenta987a3256c6e5553af58fd4adcdc6aed2417e8ce (diff)
downloadios-node-v8-610c68c4587db1ed47a074f28a527cc24223c7a6.tar.gz
ios-node-v8-610c68c4587db1ed47a074f28a527cc24223c7a6.tar.bz2
ios-node-v8-610c68c4587db1ed47a074f28a527cc24223c7a6.zip
src: mark/pop OpenSSL errors in NewRootCertStore
This commit sets the OpenSSL error mark before calling X509_STORE_load_locations and pops the error mark afterwards. The motivation for this is that it is possible that X509_STORE_load_locations can produce errors if the configuration option --openssl-system-ca-path file does not exist. Later if a different function is called which calls an OpenSSL function it could fail because these errors might still be on the OpenSSL error stack. Currently, all functions that call NewRootCertStore clear the OpenSSL error queue upon returning, but this was not the case for example in v12.18.0. PR-URL: https://github.com/nodejs/node/pull/35514 Fixes: https://github.com/nodejs/node/issues/35456 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
-rw-r--r--node.gyp3
-rw-r--r--src/crypto/crypto_context.cc10
-rw-r--r--src/crypto/crypto_context.h2
-rw-r--r--test/cctest/test_node_crypto.cc23
4 files changed, 35 insertions, 3 deletions
diff --git a/node.gyp b/node.gyp
index cf214280bb..d364286fba 100644
--- a/node.gyp
+++ b/node.gyp
@@ -1363,6 +1363,9 @@
'defines': [
'HAVE_OPENSSL=1',
],
+ 'sources': [
+ 'test/cctest/test_node_crypto.cc',
+ ]
}],
[ 'node_use_openssl=="true" and experimental_quic==1', {
'defines': [
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index d021007916..856b34e54a 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -186,12 +186,15 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
issuer);
}
-static X509_STORE* NewRootCertStore() {
+} // namespace
+
+X509_STORE* NewRootCertStore() {
static std::vector<X509*> root_certs_vector;
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],
@@ -209,7 +212,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);
@@ -224,7 +229,6 @@ static X509_STORE* NewRootCertStore() {
return store;
}
-} // namespace
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h
index e36a76c5a8..5a2126c2ea 100644
--- a/src/crypto/crypto_context.h
+++ b/src/crypto/crypto_context.h
@@ -21,6 +21,8 @@ void GetRootCertificates(
void IsExtraRootCertsFileLoaded(
const v8::FunctionCallbackInfo<v8::Value>& args);
+X509_STORE* NewRootCertStore();
+
class SecureContext final : public BaseObject {
public:
using GetSessionCb = SSL_SESSION* (*)(SSL*, const unsigned char*, int, int*);
diff --git a/test/cctest/test_node_crypto.cc b/test/cctest/test_node_crypto.cc
new file mode 100644
index 0000000000..c0ce5f2549
--- /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 "crypto/crypto_context.h"
+#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);
+}