Skip to content

Commit 6a7a61b

Browse files
danbevBethGriggs
authored andcommitted
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>
1 parent c509485 commit 6a7a61b

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

node.gyp

+3
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,9 @@
13601360
'defines': [
13611361
'HAVE_OPENSSL=1',
13621362
],
1363+
'sources': [
1364+
'test/cctest/test_node_crypto.cc',
1365+
]
13631366
}],
13641367
[ 'node_use_openssl=="true" and experimental_quic==1', {
13651368
'defines': [

src/crypto/crypto_context.cc

+7-3
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,15 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
186186
issuer);
187187
}
188188

189-
static X509_STORE* NewRootCertStore() {
189+
} // namespace
190+
191+
X509_STORE* NewRootCertStore() {
190192
static std::vector<X509*> root_certs_vector;
191193
static Mutex root_certs_vector_mutex;
192194
Mutex::ScopedLock lock(root_certs_vector_mutex);
193195

194-
if (root_certs_vector.empty()) {
196+
if (root_certs_vector.empty() &&
197+
per_process::cli_options->ssl_openssl_cert_store == false) {
195198
for (size_t i = 0; i < arraysize(root_certs); i++) {
196199
X509* x509 =
197200
PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
@@ -209,7 +212,9 @@ static X509_STORE* NewRootCertStore() {
209212

210213
X509_STORE* store = X509_STORE_new();
211214
if (*system_cert_path != '\0') {
215+
ERR_set_mark();
212216
X509_STORE_load_locations(store, system_cert_path, nullptr);
217+
ERR_pop_to_mark();
213218
}
214219

215220
Mutex::ScopedLock cli_lock(node::per_process::cli_options_mutex);
@@ -224,7 +229,6 @@ static X509_STORE* NewRootCertStore() {
224229

225230
return store;
226231
}
227-
} // namespace
228232

229233
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
230234
Environment* env = Environment::GetCurrent(args);

src/crypto/crypto_context.h

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ void GetRootCertificates(
2121
void IsExtraRootCertsFileLoaded(
2222
const v8::FunctionCallbackInfo<v8::Value>& args);
2323

24+
X509_STORE* NewRootCertStore();
25+
2426
class SecureContext final : public BaseObject {
2527
public:
2628
using GetSessionCb = SSL_SESSION* (*)(SSL*, const unsigned char*, int, int*);

test/cctest/test_node_crypto.cc

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// This simulates specifying the configuration option --openssl-system-ca-path
2+
// and settting it to a file that does not exist.
3+
#define NODE_OPENSSL_SYSTEM_CERT_PATH "/missing/ca.pem"
4+
5+
#include "crypto/crypto_context.h"
6+
#include "node_options.h"
7+
#include "openssl/err.h"
8+
#include "gtest/gtest.h"
9+
10+
/*
11+
* This test verifies that a call to NewRootCertDir with the build time
12+
* configuration option --openssl-system-ca-path set to an missing file, will
13+
* not leave any OpenSSL errors on the OpenSSL error stack.
14+
* See https://github.com/nodejs/node/issues/35456 for details.
15+
*/
16+
TEST(NodeCrypto, NewRootCertStore) {
17+
node::per_process::cli_options->ssl_openssl_cert_store = true;
18+
X509_STORE* store = node::crypto::NewRootCertStore();
19+
ASSERT_TRUE(store);
20+
ASSERT_EQ(ERR_peek_error(), 0UL) << "NewRootCertStore should not have left "
21+
"any errors on the OpenSSL error stack\n";
22+
X509_STORE_free(store);
23+
}

0 commit comments

Comments
 (0)