Skip to content

Commit 3f1c756

Browse files
ebicklecodebytere
authored andcommitted
Revert "src: fix missing extra ca in tls.rootCertificates"
A fix to tls.rootCertificates to have it correctly return the process' current root certificates resulted in non-deterministic behavior when Node.js is configured to use an OpenSSL system or file-based certificate store. The safest action is to revert the change and change the specification for tls.rootCertificates to state that it only returns the bundled certificates instead of the current ones. Fixes: #32229 Refs: #32074 PR-URL: #33313 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent c31d514 commit 3f1c756

File tree

2 files changed

+43
-89
lines changed

2 files changed

+43
-89
lines changed

src/node_crypto.cc

+18-45
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,24 @@ static X509_STORE* NewRootCertStore() {
10081008
}
10091009

10101010

1011+
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
1012+
Environment* env = Environment::GetCurrent(args);
1013+
Local<Value> result[arraysize(root_certs)];
1014+
1015+
for (size_t i = 0; i < arraysize(root_certs); i++) {
1016+
if (!String::NewFromOneByte(
1017+
env->isolate(),
1018+
reinterpret_cast<const uint8_t*>(root_certs[i]),
1019+
NewStringType::kNormal).ToLocal(&result[i])) {
1020+
return;
1021+
}
1022+
}
1023+
1024+
args.GetReturnValue().Set(
1025+
Array::New(env->isolate(), result, arraysize(root_certs)));
1026+
}
1027+
1028+
10111029
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
10121030
Environment* env = Environment::GetCurrent(args);
10131031

@@ -2684,21 +2702,6 @@ static inline Local<Value> BIOToStringOrBuffer(Environment* env,
26842702
}
26852703
}
26862704

2687-
static MaybeLocal<Value> X509ToPEM(Environment* env, X509* cert) {
2688-
BIOPointer bio(BIO_new(BIO_s_mem()));
2689-
if (!bio) {
2690-
ThrowCryptoError(env, ERR_get_error(), "BIO_new");
2691-
return MaybeLocal<Value>();
2692-
}
2693-
2694-
if (PEM_write_bio_X509(bio.get(), cert) == 0) {
2695-
ThrowCryptoError(env, ERR_get_error(), "PEM_write_bio_X509");
2696-
return MaybeLocal<Value>();
2697-
}
2698-
2699-
return BIOToStringOrBuffer(env, bio.get(), kKeyFormatPEM);
2700-
}
2701-
27022705
static bool WritePublicKeyInner(EVP_PKEY* pkey,
27032706
const BIOPointer& bio,
27042707
const PublicKeyEncodingConfig& config) {
@@ -6648,36 +6651,6 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
66486651
}
66496652

66506653

6651-
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
6652-
Environment* env = Environment::GetCurrent(args);
6653-
6654-
if (root_cert_store == nullptr)
6655-
root_cert_store = NewRootCertStore();
6656-
6657-
stack_st_X509_OBJECT* objs = X509_STORE_get0_objects(root_cert_store);
6658-
int num_objs = sk_X509_OBJECT_num(objs);
6659-
6660-
std::vector<Local<Value>> result;
6661-
result.reserve(num_objs);
6662-
6663-
for (int i = 0; i < num_objs; i++) {
6664-
X509_OBJECT* obj = sk_X509_OBJECT_value(objs, i);
6665-
if (X509_OBJECT_get_type(obj) == X509_LU_X509) {
6666-
X509* cert = X509_OBJECT_get0_X509(obj);
6667-
6668-
Local<Value> value;
6669-
if (!X509ToPEM(env, cert).ToLocal(&value))
6670-
return;
6671-
6672-
result.push_back(value);
6673-
}
6674-
}
6675-
6676-
args.GetReturnValue().Set(
6677-
Array::New(env->isolate(), result.data(), result.size()));
6678-
}
6679-
6680-
66816654
// Convert the input public key to compressed, uncompressed, or hybrid formats.
66826655
void ConvertKey(const FunctionCallbackInfo<Value>& args) {
66836656
MarkPopErrorOnReturn mark_pop_error_on_return;

test/parallel/test-tls-root-certificates.js

+25-44
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,30 @@
22
const common = require('../common');
33
if (!common.hasCrypto) common.skip('missing crypto');
44

5-
const fixtures = require('../common/fixtures');
65
const assert = require('assert');
76
const tls = require('tls');
8-
const { fork } = require('child_process');
9-
10-
if (process.argv[2] !== 'child') {
11-
// Parent
12-
const NODE_EXTRA_CA_CERTS = fixtures.path('keys', 'ca1-cert.pem');
13-
14-
fork(
15-
__filename,
16-
['child'],
17-
{ env: { ...process.env, NODE_EXTRA_CA_CERTS } }
18-
).on('exit', common.mustCall(function(status) {
19-
assert.strictEqual(status, 0);
20-
}));
21-
} else {
22-
// Child
23-
assert(Array.isArray(tls.rootCertificates));
24-
assert(tls.rootCertificates.length > 0);
25-
26-
// Getter should return the same object.
27-
assert.strictEqual(tls.rootCertificates, tls.rootCertificates);
28-
29-
// Array is immutable...
30-
assert.throws(() => tls.rootCertificates[0] = 0, /TypeError/);
31-
assert.throws(() => tls.rootCertificates.sort(), /TypeError/);
32-
33-
// ...and so is the property.
34-
assert.throws(() => tls.rootCertificates = 0, /TypeError/);
35-
36-
// Does not contain duplicates.
37-
assert.strictEqual(tls.rootCertificates.length,
38-
new Set(tls.rootCertificates).size);
39-
40-
assert(tls.rootCertificates.every((s) => {
41-
return s.startsWith('-----BEGIN CERTIFICATE-----\n');
42-
}));
43-
44-
assert(tls.rootCertificates.every((s) => {
45-
return s.endsWith('\n-----END CERTIFICATE-----\n');
46-
}));
47-
48-
const extraCert = fixtures.readKey('ca1-cert.pem', 'utf8');
49-
assert(tls.rootCertificates.includes(extraCert));
50-
}
7+
8+
assert(Array.isArray(tls.rootCertificates));
9+
assert(tls.rootCertificates.length > 0);
10+
11+
// Getter should return the same object.
12+
assert.strictEqual(tls.rootCertificates, tls.rootCertificates);
13+
14+
// Array is immutable...
15+
assert.throws(() => tls.rootCertificates[0] = 0, /TypeError/);
16+
assert.throws(() => tls.rootCertificates.sort(), /TypeError/);
17+
18+
// ...and so is the property.
19+
assert.throws(() => tls.rootCertificates = 0, /TypeError/);
20+
21+
// Does not contain duplicates.
22+
assert.strictEqual(tls.rootCertificates.length,
23+
new Set(tls.rootCertificates).size);
24+
25+
assert(tls.rootCertificates.every((s) => {
26+
return s.startsWith('-----BEGIN CERTIFICATE-----\n');
27+
}));
28+
29+
assert(tls.rootCertificates.every((s) => {
30+
return s.endsWith('\n-----END CERTIFICATE-----');
31+
}));

0 commit comments

Comments
 (0)