Skip to content

Commit 0bc8aa8

Browse files
committed
tls: rename 'as' to 'format' in getCACertificates, default 'string'
1 parent 3445144 commit 0bc8aa8

File tree

3 files changed

+64
-18
lines changed

3 files changed

+64
-18
lines changed

doc/api/tls.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,12 +2326,16 @@ changes:
23262326
If an object, it may contain:
23272327
* `type` {string} The type of CA certificates to return. One of `"default"`, `"system"`, `"bundled"`, or `"extra"`.
23282328
**Default:** `"default"`.
2329-
* `as` {string} The format of returned certificates. **Default**: `"buffer"`.
2329+
* `format` {string} The format of returned certificates. One of `"string"`, `"buffer"`, or `"x509"`.
2330+
**Default**: `"string"`.
2331+
* `"string"`: Returns PEM-encoded strings by default. See `encoding` for DER.
23302332
* `"buffer"`: Returns an array of certificate data as `Buffer` objects.
2331-
* `"x509"`: Returns an array of \[`X509Certificate`]\[] instances.
2333+
* `"x509"`: Returns an array of [`X509Certificate`][x509certificate] instances.
2334+
* `encoding` {string} When `format` is `"string"`, the encoding of the returned strings.
2335+
One of `"pem"` (PEM-encoded) or `"der"` (base64 DER). **Default:** `"pem"`.
23322336

2333-
* Returns: {Array.\<Buffer|X509Certificate>}
2334-
An array of certificates in the specified format.
2337+
* Returns: {Array}
2338+
An array of certificate data in the specified format (Buffer or X509Certificate).
23352339

23362340
* `"default"`: return the CA certificates that will be used by the Node.js TLS clients by default.
23372341
* When [`--use-bundled-ca`][] is enabled (default), or [`--use-openssl-ca`][] is not enabled,
@@ -2467,7 +2471,6 @@ added:
24672471
[Session Resumption]: #session-resumption
24682472
[Stream]: stream.md#stream
24692473
[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS
2470-
[X509Certificate]: https://nodejs.org/api/crypto.html#class-x509certificate
24712474
[`'newSession'`]: #event-newsession
24722475
[`'resumeSession'`]: #event-resumesession
24732476
[`'secureConnect'`]: #event-secureconnect
@@ -2515,3 +2518,4 @@ added:
25152518
[cipher list format]: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html#CIPHER-LIST-FORMAT
25162519
[forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy
25172520
[perfect forward secrecy]: #perfect-forward-secrecy
2521+
[x509certificate]: https://nodejs.org/api/crypto.html#class-x509certificate

lib/tls.js

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,17 @@ function getCACertificates(options = {}) {
175175
throw new ERR_INVALID_ARG_TYPE('options', ['string', 'object'], options);
176176
}
177177

178-
const { type = 'default', as = 'buffer' } = options;
178+
const {
179+
type = 'default',
180+
format = 'string',
181+
encoding = 'pem',
182+
} = options;
183+
179184
validateString(type, 'type');
180-
validateOneOf(as, 'as', ['buffer', 'x509']);
185+
validateOneOf(format, 'format', ['string', 'buffer', 'x509']);
186+
if (format === 'string') {
187+
validateOneOf(encoding, 'encoding', ['pem', 'der']);
188+
}
181189

182190
let certs;
183191
switch (type) {
@@ -188,13 +196,38 @@ function getCACertificates(options = {}) {
188196
default: throw new ERR_INVALID_ARG_VALUE('type', type);
189197
}
190198

191-
if (as === 'x509') {
192-
return certs.map((cert) => new X509Certificate(cert));
199+
if (format === 'string' && encoding === 'pem') {
200+
return certs;
201+
}
202+
203+
if (format === 'buffer' || format === 'x509') {
204+
const buffers = certs.map((cert) => {
205+
if (Buffer.isBuffer(cert)) return cert;
206+
if (typeof cert === 'string') {
207+
const base64 = cert
208+
.replace(/-----BEGIN CERTIFICATE-----/g, '')
209+
.replace(/-----END CERTIFICATE-----/g, '')
210+
.replace(/\s+/g, '');
211+
return Buffer.from(base64, 'base64');
212+
}
213+
throw new ERR_INVALID_ARG_VALUE('cert', cert);
214+
});
215+
return (format === 'buffer') ? buffers : buffers.map((buf) => new X509Certificate(buf));
193216
}
194217

195-
return certs;
218+
return certs.map((cert) => {
219+
if (typeof cert === 'string') {
220+
const base64 = cert
221+
.replace(/-----BEGIN CERTIFICATE-----/g, '')
222+
.replace(/-----END CERTIFICATE-----/g, '')
223+
.replace(/\s+/g, '');
224+
return Buffer.from(base64, 'base64').toString('base64');
225+
}
226+
return encoding === 'pem' ? cert.toString('utf8') : cert.toString('base64');
227+
});
196228
}
197229

230+
198231
exports.getCACertificates = getCACertificates;
199232

200233
function setDefaultCACertificates(certs) {

test/parallel/test-tls-get-ca-certificates-x509-option.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const tls = require('tls');
99
const { X509Certificate } = require('crypto');
1010

1111
{
12-
const certs = tls.getCACertificates({ type: 'default', as: 'x509' });
12+
const certs = tls.getCACertificates({ type: 'default', format: 'x509' });
1313

1414
assert.ok(Array.isArray(certs), 'should return an array');
1515
assert.ok(certs.length > 0, 'should return non-empty array');
@@ -24,7 +24,7 @@ const { X509Certificate } = require('crypto');
2424
}
2525

2626
{
27-
const certs = tls.getCACertificates({ type: 'default', as: 'buffer' });
27+
const certs = tls.getCACertificates({ type: 'default', format: 'buffer' });
2828
assert.ok(Array.isArray(certs));
2929
assert.ok(certs.length > 0);
3030

@@ -38,16 +38,15 @@ const { X509Certificate } = require('crypto');
3838
const certs = tls.getCACertificates({ type: 'default' });
3939
assert.ok(Array.isArray(certs));
4040
assert.ok(certs.length > 0);
41-
4241
for (let i = 0; i < certs.length; i++) {
43-
assert.ok(Buffer.isBuffer(certs[i]),
44-
`cert at index ${i} should be a Buffer`);
42+
assert.strictEqual(typeof certs[i], 'string');
43+
assert.ok(certs[i].includes('-----BEGIN CERTIFICATE-----'));
4544
}
4645
}
4746

4847
{
4948
assert.throws(() => {
50-
tls.getCACertificates({ type: 'default', as: 'invalid' });
49+
tls.getCACertificates({ type: 'default', format: 'invalid' });
5150
}, {
5251
name: 'TypeError',
5352
code: 'ERR_INVALID_ARG_VALUE',
@@ -56,7 +55,7 @@ const { X509Certificate } = require('crypto');
5655
}
5756

5857
{
59-
const certs = tls.getCACertificates({ as: 'buffer' });
58+
const certs = tls.getCACertificates({ format: 'buffer' });
6059
assert.ok(Array.isArray(certs));
6160
assert.ok(certs.length > 0);
6261

@@ -68,10 +67,20 @@ const { X509Certificate } = require('crypto');
6867

6968
{
7069
assert.throws(() => {
71-
tls.getCACertificates({ type: 'invalid', as: 'buffer' });
70+
tls.getCACertificates({ type: 'invalid', format: 'buffer' });
7271
}, {
7372
name: 'TypeError',
7473
code: 'ERR_INVALID_ARG_VALUE',
7574
message: "The argument 'type' is invalid. Received 'invalid'"
7675
});
7776
}
77+
78+
{
79+
const certs = tls.getCACertificates({ format: 'string', encoding: 'der' });
80+
assert.ok(Array.isArray(certs));
81+
assert.ok(certs.length > 0);
82+
for (let i = 0; i < certs.length; i++) {
83+
assert.strictEqual(typeof certs[i], 'string');
84+
assert.ok(/^[A-Za-z0-9+/]+=*$/.test(certs[i]), 'should be base64 string');
85+
}
86+
}

0 commit comments

Comments
 (0)