X Tutup
The Wayback Machine - https://web.archive.org/web/20220319214911/https://github.com/nodejs/node/commit/6a7a61be7c
Skip to content
Permalink
Browse files
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: #35514
Fixes: #35456
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
danbev authored and BethGriggs committed Oct 21, 2020
1 parent c509485 commit 6a7a61be7c58809990f42659c1d114233c9d1d3e
Showing with 35 additions and 3 deletions.
  1. +3 −0 node.gyp
  2. +7 −3 src/crypto/crypto_context.cc
  3. +2 −0 src/crypto/crypto_context.h
  4. +23 −0 test/cctest/test_node_crypto.cc
@@ -1360,6 +1360,9 @@
'defines': [
'HAVE_OPENSSL=1',
],
'sources': [
'test/cctest/test_node_crypto.cc',
]
}],
[ 'node_use_openssl=="true" and experimental_quic==1', {
'defines': [
@@ -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);
@@ -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*);
@@ -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);
}

0 comments on commit 6a7a61b

Please sign in to comment.
X Tutup