Skip to content

Commit 5c84c65

Browse files
vvm-broadsoftbestander
authored andcommitted
Add support for 'ca' config file option (#1742)
1 parent 96a0fbb commit 5c84c65

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

__tests__/util/request-manager.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,49 @@ test('RequestManager.request with cafile', async () => {
3535
expect(body).toBe('ok');
3636
});
3737

38+
test('RequestManager.request with ca (string)', async () => {
39+
let body;
40+
const options = {
41+
key: await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'server-key.pem')),
42+
cert: await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'server-cert.pem')),
43+
};
44+
const server = https.createServer(options, (req, res) => { res.end('ok'); });
45+
try {
46+
server.listen(0);
47+
const bundle = await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'cacerts.pem'));
48+
const hasPemPrefix = (block) => block.startsWith('-----BEGIN ');
49+
const caCerts = bundle.split(/(-----BEGIN .*\r?\n[^-]+\r?\n--.*)/).filter(hasPemPrefix);
50+
// the 2nd cert is valid one
51+
const config = await createConfig({'ca': caCerts[1]});
52+
const port = server.address().port;
53+
body = await config.requestManager.request({url: `https://localhost:${port}/?nocache`, headers: {Connection: 'close'}});
54+
} finally {
55+
server.close();
56+
}
57+
expect(body).toBe('ok');
58+
});
59+
60+
test('RequestManager.request with ca (array)', async () => {
61+
let body;
62+
const options = {
63+
key: await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'server-key.pem')),
64+
cert: await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'server-cert.pem')),
65+
};
66+
const server = https.createServer(options, (req, res) => { res.end('ok'); });
67+
try {
68+
server.listen(0);
69+
const bundle = await fs.readFile(path.join(__dirname, '..', 'fixtures', 'certificates', 'cacerts.pem'));
70+
const hasPemPrefix = (block) => block.startsWith('-----BEGIN ');
71+
const caCerts = bundle.split(/(-----BEGIN .*\r?\n[^-]+\r?\n--.*)/).filter(hasPemPrefix);
72+
const config = await createConfig({'ca': caCerts});
73+
const port = server.address().port;
74+
body = await config.requestManager.request({url: `https://localhost:${port}/?nocache`, headers: {Connection: 'close'}});
75+
} finally {
76+
server.close();
77+
}
78+
expect(body).toBe('ok');
79+
});
80+
3881
test('RequestManager.request with mutual TLS', async () => {
3982
let body;
4083
const options = {

src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export default class Config {
197197
httpProxy: String(opts.httpProxy || this.getOption('proxy') || ''),
198198
httpsProxy: String(opts.httpsProxy || this.getOption('https-proxy') || ''),
199199
strictSSL: Boolean(this.getOption('strict-ssl')),
200+
ca: Array.prototype.concat(opts.ca || this.getOption('ca') || []).map(String),
200201
cafile: String(opts.cafile || this.getOption('cafile') || ''),
201202
cert: String(opts.cert || this.getOption('cert') || ''),
202203
key: String(opts.key || this.getOption('key') || ''),

src/util/request-manager.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export default class RequestManager {
111111
httpProxy?: string,
112112
httpsProxy?: string,
113113
strictSSL?: boolean,
114+
ca?: Array<string>,
114115
cafile?: string,
115116
cert?: string,
116117
key?: string,
@@ -139,13 +140,18 @@ export default class RequestManager {
139140
this.strictSSL = opts.strictSSL;
140141
}
141142

143+
if (opts.ca != null && opts.ca.length > 0) {
144+
this.ca = opts.ca;
145+
}
146+
142147
if (opts.cafile != null && opts.cafile != '') {
143148
// The CA bundle file can contain one or more certificates with comments/text between each PEM block.
144149
// tls.connect wants an array of certificates without any comments/text, so we need to split the string
145150
// and strip out any text in between the certificates
146151
try {
147152
const bundle = fs.readFileSync(opts.cafile).toString();
148153
const hasPemPrefix = (block) => block.startsWith('-----BEGIN ');
154+
// opts.cafile overrides opts.ca, this matches with npm behavior
149155
this.ca = bundle.split(/(-----BEGIN .*\r?\n[^-]+\r?\n--.*)/).filter(hasPemPrefix);
150156
} catch (err) {
151157
this.reporter.error(`Could not open cafile: ${err.message}`);

0 commit comments

Comments
 (0)