Skip to content

Commit 2248ba7

Browse files
ebickleMylesBorins
authored andcommitted
src: fix missing extra ca in tls.rootCertificates
Fixes tls.rootCertificates missing certificates loaded from NODE_EXTRA_CA_CERTS. Fixes: #32074 PR-URL: #32075 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 49a07f7 commit 2248ba7

File tree

2 files changed

+89
-43
lines changed

2 files changed

+89
-43
lines changed

‎src/node_crypto.cc‎

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -986,24 +986,6 @@ static X509_STORE* NewRootCertStore(){
986986
}
987987

988988

989-
voidGetRootCertificates(const FunctionCallbackInfo<Value>& args){
990-
Environment* env = Environment::GetCurrent(args);
991-
Local<Value> result[arraysize(root_certs)];
992-
993-
for (size_t i = 0; i < arraysize(root_certs); i++){
994-
if (!String::NewFromOneByte(
995-
env->isolate(),
996-
reinterpret_cast<constuint8_t*>(root_certs[i]),
997-
NewStringType::kNormal).ToLocal(&result[i])){
998-
return;
999-
}
1000-
}
1001-
1002-
args.GetReturnValue().Set(
1003-
Array::New(env->isolate(), result, arraysize(root_certs)));
1004-
}
1005-
1006-
1007989
voidSecureContext::AddCACert(const FunctionCallbackInfo<Value>& args){
1008990
Environment* env = Environment::GetCurrent(args);
1009991

@@ -2680,6 +2662,21 @@ static inline Local<Value> BIOToStringOrBuffer(Environment* env,
26802662
}
26812663
}
26822664

2665+
static MaybeLocal<Value> X509ToPEM(Environment* env, X509* cert){
2666+
BIOPointer bio(BIO_new(BIO_s_mem()));
2667+
if (!bio){
2668+
ThrowCryptoError(env, ERR_get_error(), "BIO_new");
2669+
return MaybeLocal<Value>();
2670+
}
2671+
2672+
if (PEM_write_bio_X509(bio.get(), cert) == 0){
2673+
ThrowCryptoError(env, ERR_get_error(), "PEM_write_bio_X509");
2674+
return MaybeLocal<Value>();
2675+
}
2676+
2677+
returnBIOToStringOrBuffer(env, bio.get(), kKeyFormatPEM);
2678+
}
2679+
26832680
staticboolWritePublicKeyInner(EVP_PKEY* pkey,
26842681
const BIOPointer& bio,
26852682
const PublicKeyEncodingConfig& config){
@@ -6660,6 +6657,36 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args){
66606657
}
66616658

66626659

6660+
voidGetRootCertificates(const FunctionCallbackInfo<Value>& args){
6661+
Environment* env = Environment::GetCurrent(args);
6662+
6663+
if (root_cert_store == nullptr)
6664+
root_cert_store = NewRootCertStore();
6665+
6666+
stack_st_X509_OBJECT* objs = X509_STORE_get0_objects(root_cert_store);
6667+
int num_objs = sk_X509_OBJECT_num(objs);
6668+
6669+
std::vector<Local<Value>> result;
6670+
result.reserve(num_objs);
6671+
6672+
for (int i = 0; i < num_objs; i++){
6673+
X509_OBJECT* obj = sk_X509_OBJECT_value(objs, i);
6674+
if (X509_OBJECT_get_type(obj) == X509_LU_X509){
6675+
X509* cert = X509_OBJECT_get0_X509(obj);
6676+
6677+
Local<Value> value;
6678+
if (!X509ToPEM(env, cert).ToLocal(&value))
6679+
return;
6680+
6681+
result.push_back(value);
6682+
}
6683+
}
6684+
6685+
args.GetReturnValue().Set(
6686+
Array::New(env->isolate(), result.data(), result.size()));
6687+
}
6688+
6689+
66636690
// Convert the input public key to compressed, uncompressed, or hybrid formats.
66646691
voidConvertKey(const FunctionCallbackInfo<Value>& args){
66656692
MarkPopErrorOnReturn mark_pop_error_on_return;

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

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,49 @@
22
constcommon=require('../common');
33
if(!common.hasCrypto)common.skip('missing crypto');
44

5+
constfixtures=require('../common/fixtures');
56
constassert=require('assert');
67
consttls=require('tls');
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-
newSet(tls.rootCertificates).size);
24-
25-
assert(tls.rootCertificates.every((s)=>{
26-
returns.startsWith('-----BEGIN CERTIFICATE-----\n');
27-
}));
28-
29-
assert(tls.rootCertificates.every((s)=>{
30-
returns.endsWith('\n-----END CERTIFICATE-----');
31-
}));
8+
const{ fork }=require('child_process');
9+
10+
if(process.argv[2]!=='child'){
11+
// Parent
12+
constNODE_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+
newSet(tls.rootCertificates).size);
39+
40+
assert(tls.rootCertificates.every((s)=>{
41+
returns.startsWith('-----BEGIN CERTIFICATE-----\n');
42+
}));
43+
44+
assert(tls.rootCertificates.every((s)=>{
45+
returns.endsWith('\n-----END CERTIFICATE-----\n');
46+
}));
47+
48+
constextraCert=fixtures.readKey('ca1-cert.pem','utf8');
49+
assert(tls.rootCertificates.includes(extraCert));
50+
}

0 commit comments

Comments
(0)