Skip to content

Commit 651a42d

Browse files
committed
tls: Improve getCACertificates() caching and test
1 parent 1b254d2 commit 651a42d

4 files changed

Lines changed: 50 additions & 23 deletions

File tree

β€Žlib/tls.jsβ€Ž

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ function cacheDefaultCACertificates() {
184184
return defaultCACertificates;
185185
}
186186

187+
const certificateCache = { __proto__: null };
188+
187189
function getCACertificates(options = {}) {
188190
if (typeof options === 'string') {
189191
options = { type: options };
@@ -193,11 +195,37 @@ function getCACertificates(options = {}) {
193195

194196
const {
195197
type = 'default',
196-
format = 'string',
198+
format = 'pem',
197199
} = options;
198200

199201
validateString(type, 'type');
200-
validateOneOf(format, 'format', ['string', 'buffer', 'x509']);
202+
validateOneOf(format, 'format', ['pem', 'der', 'x509', 'string', 'buffer']);
203+
204+
let effectiveFormat = format;
205+
if (format === 'string') {
206+
effectiveFormat = 'pem';
207+
} else if (format === 'buffer') {
208+
effectiveFormat = 'der';
209+
}
210+
211+
if (certificateCache[type]) {
212+
const cachedCerts = certificateCache[type];
213+
214+
if (effectiveFormat === 'pem') {
215+
return cachedCerts;
216+
}
217+
218+
const buffers = cachedCerts.map((cert) => {
219+
const base64 = cert.replace(/(?:\s|-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----)+/g, '');
220+
return Buffer.from(base64, 'base64');
221+
});
222+
223+
if (effectiveFormat === 'der') {
224+
return buffers;
225+
}
226+
227+
return buffers.map((buf) => new X509Certificate(buf));
228+
}
201229

202230
let certs;
203231
switch (type) {
@@ -208,32 +236,28 @@ function getCACertificates(options = {}) {
208236
default: throw new ERR_INVALID_ARG_VALUE('type', type);
209237
}
210238

211-
if (format === 'string') {
212-
// Return PEM strings directly
213-
return certs.map((cert) => {
214-
if (typeof cert === 'string') return cert;
215-
if (Buffer.isBuffer(cert)) return cert.toString('ascii');
216-
throw new ERR_INVALID_ARG_VALUE('cert', cert);
217-
});
218-
}
219-
220-
const buffers = certs.map((cert) => {
221-
if (Buffer.isBuffer(cert)) return cert;
239+
const pemCerts = certs.map((cert) => {
222240
if (typeof cert === 'string') {
223-
const base64 = cert
224-
.replace(/-----BEGIN CERTIFICATE-----/g, '')
225-
.replace(/-----END CERTIFICATE-----/g, '')
226-
.replace(/\s+/g, '');
227-
return Buffer.from(base64, 'base64');
241+
return cert;
228242
}
229-
throw new ERR_INVALID_ARG_VALUE('cert', cert);
243+
return `-----BEGIN CERTIFICATE-----\n${cert.toString('base64').match(/.{1,64}/g).join('\n')}\n-----END CERTIFICATE-----`;
244+
});
245+
certificateCache[type] = pemCerts;
246+
247+
if (effectiveFormat === 'pem') {
248+
return pemCerts;
249+
}
250+
251+
const derBuffers = pemCerts.map((cert) => {
252+
const base64 = cert.replace(/(?:\s|-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----)+/g, '');
253+
return Buffer.from(base64, 'base64');
230254
});
231255

232-
if (format === 'buffer') {
233-
return buffers;
256+
if (effectiveFormat === 'der') {
257+
return derBuffers;
234258
}
235259

236-
return buffers.map((buf) => new X509Certificate(buf));
260+
return derBuffers.map((buf) => new X509Certificate(buf));
237261
}
238262

239263
exports.getCACertificates = getCACertificates;

β€Žtest/parallel/test-tls-get-ca-certificates-bundled.jsβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ const certs2 = tls.getCACertificates('bundled');
2020
assertIsCAArray(certs2);
2121

2222
assert.deepStrictEqual(certs2, tls.rootCertificates);
23+
assert.strictEqual(certs, tls.getCACertificates({ type: 'bundled', format: 'string' }));

β€Žtest/parallel/test-tls-get-ca-certificates-default.jsβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ assert.deepStrictEqual(certs, certs2);
1616

1717
assert.deepStrictEqual(certs, tls.getCACertificates({ type: 'default', format: 'string' }));
1818

19-
const certs3 = tls.getCACertificates('bundled');
19+
const certs3 = tls.getCACertificates('default');
2020
assertIsCAArray(certs3);
2121

2222
assert.deepStrictEqual(certs3, tls.rootCertificates);
23+
assert.strictEqual(certs2, tls.getCACertificates({ type: 'default', format: 'string' }));

β€Žtest/parallel/test-tls-get-ca-certificates-system.jsβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ const certs = tls.getCACertificates('bundled');
3131
assertIsCAArray(certs);
3232

3333
assert.deepStrictEqual(certs, tls.rootCertificates);
34+
assert.strictEqual(systemCerts, tls.getCACertificates({ type: 'system', format: 'string' }));

0 commit comments

Comments
Β (0)