Skip to content

Commit e105034

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 5a6d80f commit e105034

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
@@ -988,6 +988,24 @@ static X509_STORE* NewRootCertStore() {
988988
}
989989

990990

991+
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
992+
Environment* env = Environment::GetCurrent(args);
993+
Local<Value> result[arraysize(root_certs)];
994+
995+
for (size_t i = 0; i < arraysize(root_certs); i++) {
996+
if (!String::NewFromOneByte(
997+
env->isolate(),
998+
reinterpret_cast<const uint8_t*>(root_certs[i]),
999+
NewStringType::kNormal).ToLocal(&result[i])) {
1000+
return;
1001+
}
1002+
}
1003+
1004+
args.GetReturnValue().Set(
1005+
Array::New(env->isolate(), result, arraysize(root_certs)));
1006+
}
1007+
1008+
9911009
void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
9921010
Environment* env = Environment::GetCurrent(args);
9931011

@@ -2664,21 +2682,6 @@ static inline Local<Value> BIOToStringOrBuffer(Environment* env,
26642682
}
26652683
}
26662684

2667-
static MaybeLocal<Value> X509ToPEM(Environment* env, X509* cert) {
2668-
BIOPointer bio(BIO_new(BIO_s_mem()));
2669-
if (!bio) {
2670-
ThrowCryptoError(env, ERR_get_error(), "BIO_new");
2671-
return MaybeLocal<Value>();
2672-
}
2673-
2674-
if (PEM_write_bio_X509(bio.get(), cert) == 0) {
2675-
ThrowCryptoError(env, ERR_get_error(), "PEM_write_bio_X509");
2676-
return MaybeLocal<Value>();
2677-
}
2678-
2679-
return BIOToStringOrBuffer(env, bio.get(), kKeyFormatPEM);
2680-
}
2681-
26822685
static bool WritePublicKeyInner(EVP_PKEY* pkey,
26832686
const BIOPointer& bio,
26842687
const PublicKeyEncodingConfig& config) {
@@ -6676,36 +6679,6 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
66766679
}
66776680

66786681

6679-
void GetRootCertificates(const FunctionCallbackInfo<Value>& args) {
6680-
Environment* env = Environment::GetCurrent(args);
6681-
6682-
if (root_cert_store == nullptr)
6683-
root_cert_store = NewRootCertStore();
6684-
6685-
stack_st_X509_OBJECT* objs = X509_STORE_get0_objects(root_cert_store);
6686-
int num_objs = sk_X509_OBJECT_num(objs);
6687-
6688-
std::vector<Local<Value>> result;
6689-
result.reserve(num_objs);
6690-
6691-
for (int i = 0; i < num_objs; i++) {
6692-
X509_OBJECT* obj = sk_X509_OBJECT_value(objs, i);
6693-
if (X509_OBJECT_get_type(obj) == X509_LU_X509) {
6694-
X509* cert = X509_OBJECT_get0_X509(obj);
6695-
6696-
Local<Value> value;
6697-
if (!X509ToPEM(env, cert).ToLocal(&value))
6698-
return;
6699-
6700-
result.push_back(value);
6701-
}
6702-
}
6703-
6704-
args.GetReturnValue().Set(
6705-
Array::New(env->isolate(), result.data(), result.size()));
6706-
}
6707-
6708-
67096682
// Convert the input public key to compressed, uncompressed, or hybrid formats.
67106683
void ConvertKey(const FunctionCallbackInfo<Value>& args) {
67116684
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)