Skip to content

Commit fc25c33

Browse files
committed
test
test test test
1 parent d305270 commit fc25c33

9 files changed

Lines changed: 212 additions & 223 deletions

File tree

doc/api/tls.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,7 @@ const additionalCerts = ['-----BEGIN CERTIFICATE-----\n...'];
23532353
tls.setDefaultCACertificates([...currentCerts, ...additionalCerts]);
23542354
```
23552355

2356-
## `tls.getCACertificates([type[, subjectNameOrCert]])`
2356+
## `tls.getCACertificates([type[, cert]])`
23572357

23582358
<!-- YAML
23592359
added:
@@ -2364,9 +2364,12 @@ added:
23642364
* `type` {string|undefined} The type of CA certificates that will be returned. Valid values
23652365
are `"default"`, `"system"`, `"bundled"`, `"extra"` and `"openssl"`.
23662366
**Default:** `"default"`.
2367-
* `subjectNameOrCert` {string|ArrayBufferView|X509Certificate|undefined}
2368-
The subject name or certificate used to filter OpenSSL CA certificates.
2369-
Required when `type` is `"openssl"`.
2367+
* `cert` {string|ArrayBufferView|X509Certificate|undefined} The certificate used
2368+
to look up its issuer in the selected CA store. Strings must contain a
2369+
PEM-encoded certificate. An `ArrayBufferView` may contain a PEM or DER encoded
2370+
certificate.
2371+
Required when `type` is `"openssl"`, or when `type` is `"default"` and
2372+
[`--use-openssl-ca`][] is enabled.
23702373
* Returns: {string\[]} An array of PEM-encoded certificates. The array may contain duplicates
23712374
if the same certificate is repeatedly stored in multiple sources.
23722375

@@ -2375,10 +2378,15 @@ Returns an array containing the CA certificates from various sources, depending
23752378
* `"default"`: return the CA certificates that will be used by the Node.js TLS clients by default.
23762379
* When [`--use-bundled-ca`][] is enabled (default), or [`--use-openssl-ca`][] is not enabled,
23772380
this would include CA certificates from the bundled Mozilla CA store.
2381+
* When OpenSSL's default CA store is selected, either at build time or through
2382+
[`--use-openssl-ca`][], `cert` is required. OpenSSL's default certificate
2383+
locations form the base of the default CA store. Certificate directories
2384+
use subject-hash lookup and cannot be enumerated without a certificate
2385+
lookup key. Calling this method without `cert` throws.
23782386
* When [`--use-system-ca`][] is enabled, this would also include certificates from the system's
23792387
trusted store.
2380-
* When [`NODE_EXTRA_CA_CERTS`][] is used, this would also include certificates loaded from the specified
2381-
file.
2388+
* When [`NODE_EXTRA_CA_CERTS`][] is used, certificates from the specified
2389+
file are included in the default CA store.
23822390
* `"system"`: return the CA certificates that are loaded from the system's trusted store, according
23832391
to rules set by [`--use-system-ca`][]. This can be used to get the certificates from the system
23842392
when [`--use-system-ca`][] is not enabled.
@@ -2387,10 +2395,9 @@ Returns an array containing the CA certificates from various sources, depending
23872395
* `"extra"`: return the CA certificates loaded from [`NODE_EXTRA_CA_CERTS`][]. It's an empty array if
23882396
[`NODE_EXTRA_CA_CERTS`][] is not set.
23892397
* `"openssl"`: return CA certificates looked up from OpenSSL's default CA
2390-
store using `subjectNameOrCert`. If `subjectNameOrCert` is a certificate,
2391-
its issuer name is used for the lookup. If it is a subject name string, the
2392-
subject name is used directly. This follows OpenSSL's hashed-directory lookup
2393-
behavior for certificates loaded from the default certificate directory.
2398+
store using the issuer name of `cert`. This follows OpenSSL's
2399+
hashed-directory lookup behavior for certificates loaded from the default
2400+
certificate directory.
23942401

23952402
## `tls.getCiphers()`
23962403

@@ -2570,7 +2577,7 @@ added: v0.11.3
25702577
[`tls.connect()`]: #tlsconnectoptions-callback
25712578
[`tls.createSecureContext()`]: #tlscreatesecurecontextoptions
25722579
[`tls.createServer()`]: #tlscreateserveroptions-secureconnectionlistener
2573-
[`tls.getCACertificates()`]: #tlsgetcacertificatestype
2580+
[`tls.getCACertificates()`]: #tlsgetcacertificatestype-cert
25742581
[`tls.getCiphers()`]: #tlsgetciphers
25752582
[`tls.rootCertificates`]: #tlsrootcertificates
25762583
[`x509.checkHost()`]: crypto.md#x509checkhostname-options

lib/tls.js

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@ const {
3939
ERR_OUT_OF_RANGE,
4040
ERR_INVALID_ARG_VALUE,
4141
ERR_INVALID_ARG_TYPE,
42+
ERR_MISSING_ARGS,
4243
} = require('internal/errors').codes;
4344

4445
const {
4546
getBundledRootCertificates,
4647
getExtraCACertificates,
47-
// getOpenSSLCACertificates,
48+
lookupDefaultCACertificates,
4849
lookupOpenSSLCACertificates,
4950
getSystemCACertificates,
5051
resetRootCertStore,
@@ -150,37 +151,30 @@ function cacheSystemCACertificates() {
150151

151152
return systemCACertificates;
152153
}
153-
154-
// let opensslCACertificates;
155-
// function cacheOpenSSLCACertificates() {
156-
// opensslCACertificates ||= ObjectFreeze(getOpenSSLCACertificates());
157-
158-
// return opensslCACertificates;
159-
// }
160-
161154
let opensslCACertificateLookup;
162-
function cacheOpenSSLCertificateLookup(subjectNameOrCert) {
155+
function cacheOpenSSLCertificateLookup(cert) {
163156
opensslCACertificateLookup ??= new SafeMap();
164157

165-
const key = isArrayBufferView(subjectNameOrCert) ?
158+
const key = isArrayBufferView(cert) ?
166159
`buffer:${Buffer.from(
167-
subjectNameOrCert.buffer,
168-
subjectNameOrCert.byteOffset,
169-
subjectNameOrCert.byteLength).toString('base64')}` :
170-
`subject:${subjectNameOrCert}`;
160+
cert.buffer,
161+
cert.byteOffset,
162+
cert.byteLength).toString('base64')}` :
163+
`cert:${cert}`;
171164

172165
const cached = opensslCACertificateLookup.get(key);
173166
if (cached !== undefined) return cached;
174167

175-
const result = ObjectFreeze(lookupOpenSSLCACertificates(subjectNameOrCert));
168+
const result = ObjectFreeze(lookupOpenSSLCACertificates(cert));
176169
opensslCACertificateLookup.set(key, result);
177170
return result;
178171
}
179172

180173
let defaultCACertificates;
174+
let defaultCACertificateLookup;
181175
let hasResetDefaultCACertificates = false;
182176

183-
function cacheDefaultCACertificates() {
177+
function cacheDefaultCACertificates(cert) {
184178
if (defaultCACertificates) { return defaultCACertificates; }
185179

186180
if (hasResetDefaultCACertificates) {
@@ -189,26 +183,44 @@ function cacheDefaultCACertificates() {
189183
return defaultCACertificates;
190184
}
191185

192-
defaultCACertificates = [];
193-
194-
if (!getOptionValue('--use-openssl-ca')) {
195-
const bundled = cacheBundledRootCertificates();
196-
for (let i = 0; i < bundled.length; ++i) {
197-
ArrayPrototypePush(defaultCACertificates, bundled[i]);
186+
if (getOptionValue('[ssl_openssl_cert_store]')) {
187+
if (cert === undefined) {
188+
throw new ERR_MISSING_ARGS('cert');
198189
}
199-
if (getOptionValue('--use-system-ca')) {
200-
const system = cacheSystemCACertificates();
201-
for (let i = 0; i < system.length; ++i) {
190+
cert = validateOpenSSLCACertificate(cert);
191+
192+
const key = isArrayBufferView(cert) ?
193+
`buffer:${Buffer.from(
194+
cert.buffer,
195+
cert.byteOffset,
196+
cert.byteLength).toString('base64')}` :
197+
`cert:${cert}`;
198+
199+
defaultCACertificateLookup ??= new SafeMap();
200+
const cached = defaultCACertificateLookup.get(key);
201+
if (cached !== undefined) return cached;
202+
203+
const result = ObjectFreeze(lookupDefaultCACertificates(cert));
204+
defaultCACertificateLookup.set(key, result);
205+
return result;
206+
}
202207

203-
ArrayPrototypePush(defaultCACertificates, system[i]);
204-
}
208+
defaultCACertificates = [];
209+
210+
const bundled = cacheBundledRootCertificates();
211+
for (let i = 0; i < bundled.length; ++i) {
212+
ArrayPrototypePush(defaultCACertificates, bundled[i]);
213+
}
214+
if (getOptionValue('--use-system-ca')) {
215+
const system = cacheSystemCACertificates();
216+
for (let i = 0; i < system.length; ++i) {
217+
ArrayPrototypePush(defaultCACertificates, system[i]);
205218
}
206219
}
207220

208221
if (process.env.NODE_EXTRA_CA_CERTS) {
209222
const extra = cacheExtraCACertificates();
210223
for (let i = 0; i < extra.length; ++i) {
211-
212224
ArrayPrototypePush(defaultCACertificates, extra[i]);
213225
}
214226
}
@@ -217,40 +229,35 @@ function cacheDefaultCACertificates() {
217229
return defaultCACertificates;
218230
}
219231

220-
function validateOpenSSLCACertificateFilter(subjectNameOrCert) {
221-
if (subjectNameOrCert !== null &&
222-
(typeof subjectNameOrCert === 'object' ||
223-
typeof subjectNameOrCert === 'function') &&
224-
isX509Certificate(subjectNameOrCert)) {
225-
return subjectNameOrCert[kHandle].pem();
232+
function validateOpenSSLCACertificate(cert) {
233+
if (cert !== null &&
234+
(typeof cert === 'object' || typeof cert === 'function') &&
235+
isX509Certificate(cert)) {
236+
return cert[kHandle].pem();
226237
}
227-
if (typeof subjectNameOrCert !== 'string' &&
228-
!isArrayBufferView(subjectNameOrCert)) {
238+
if (typeof cert !== 'string' && !isArrayBufferView(cert)) {
229239
throw new ERR_INVALID_ARG_TYPE(
230-
'subjectNameOrCert',
231-
['string', 'ArrayBufferView', 'X509Certificate'],
232-
subjectNameOrCert);
240+
'cert', ['string', 'ArrayBufferView', 'X509Certificate'], cert);
233241
}
234-
return subjectNameOrCert;
242+
return cert;
235243
}
236244

237245
// TODO(joyeecheung): support X509Certificate output?
238-
function getCACertificates(type = 'default', subjectNameOrCert) {
246+
function getCACertificates(type = 'default', cert) {
239247
validateString(type, 'type');
240248

241249
switch (type) {
242250
case 'default':
243-
return cacheDefaultCACertificates();
251+
return cacheDefaultCACertificates(cert);
244252
case 'bundled':
245253
return cacheBundledRootCertificates();
246254
case 'system':
247255
return cacheSystemCACertificates();
248256
case 'extra':
249257
return cacheExtraCACertificates();
250258
case 'openssl':
251-
subjectNameOrCert =
252-
validateOpenSSLCACertificateFilter(subjectNameOrCert);
253-
return cacheOpenSSLCertificateLookup(subjectNameOrCert);
259+
cert = validateOpenSSLCACertificate(cert);
260+
return cacheOpenSSLCertificateLookup(cert);
254261
default:
255262
throw new ERR_INVALID_ARG_VALUE('type', type);
256263
}
@@ -272,6 +279,7 @@ function setDefaultCACertificates(certs) {
272279

273280
resetRootCertStore(certs);
274281
defaultCACertificates = undefined; // Reset the cached default certificates
282+
defaultCACertificateLookup = undefined;
275283
hasResetDefaultCACertificates = true;
276284
}
277285

@@ -285,6 +293,7 @@ if (isBuildingSnapshot()) {
285293
systemCACertificates = undefined;
286294
// opensslCACertificates = undefined;
287295
opensslCACertificateLookup = undefined;
296+
defaultCACertificateLookup = undefined;
288297
if (hasResetDefaultCACertificates) {
289298
defaultCACertificates = undefined;
290299
}

0 commit comments

Comments
 (0)