Skip to content

Commit c5f3e75

Browse files
sam-githubandrew749
authored andcommitted
test: move common tls connect setup into fixtures
TLS connection setup boilerplate is common to many TLS tests, factor it into a test fixture so tests are clearer to read and faster to write. Backport-PR-URL: nodejs/node#12468 PR-URL: nodejs/node#10389 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gibson Fahnestock <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 5cdda42 commit c5f3e75

File tree

4 files changed

+181
-118
lines changed

4 files changed

+181
-118
lines changed

test/fixtures/tls-connect.js

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// One shot call to connect a TLS client and server based on options to
2+
// tls.createServer() and tls.connect(), so assertions can be made on both ends
3+
// of the connection.
4+
'use strict';
5+
6+
const common = require('../common');
7+
const fs = require('fs');
8+
const join = require('path').join;
9+
const tls = require('tls');
10+
const util = require('util');
11+
12+
module.exports = exports = checkCrypto;
13+
14+
function checkCrypto() {
15+
if (!common.hasCrypto) {
16+
common.skip('missing crypto');
17+
process.exit(0);
18+
}
19+
return exports;
20+
}
21+
22+
exports.assert = require('assert');
23+
exports.debug = util.debuglog('test');
24+
exports.tls = tls;
25+
26+
// Pre-load keys from common fixtures for ease of use by tests.
27+
const keys = exports.keys = {
28+
agent1: load('agent1', 'ca1'),
29+
agent2: load('agent2', 'agent2'),
30+
agent3: load('agent3', 'ca2'),
31+
agent4: load('agent4', 'ca2'),
32+
agent5: load('agent5', 'ca2'),
33+
agent6: load('agent6', 'ca1'),
34+
agent7: load('agent7', 'fake-cnnic-root'),
35+
ec: load('ec', 'ec'),
36+
};
37+
38+
function load(cert, issuer) {
39+
issuer = issuer || cert; // Assume self-signed if no issuer
40+
const id = {
41+
key: read(cert + '-key.pem'),
42+
cert: read(cert + '-cert.pem'),
43+
ca: read(issuer + '-cert.pem'),
44+
};
45+
return id;
46+
}
47+
48+
function read(file) {
49+
return fs.readFileSync(join(common.fixturesDir, 'keys', file), 'binary');
50+
}
51+
52+
exports.connect = function connect(options, callback) {
53+
callback = common.mustCall(callback);
54+
55+
const server = {};
56+
const client = {};
57+
const pair = {
58+
server: server,
59+
client: client,
60+
};
61+
62+
tls.createServer(options.server, function(conn) {
63+
server.conn = conn;
64+
conn.pipe(conn);
65+
maybeCallback()
66+
}).listen(0, function() {
67+
server.server = this;
68+
69+
const optClient = util._extend({
70+
port: this.address().port,
71+
}, options.client);
72+
73+
tls.connect(optClient)
74+
.on('secureConnect', function() {
75+
client.conn = this;
76+
maybeCallback();
77+
})
78+
.on('error', function(err) {
79+
client.err = err;
80+
client.conn = this;
81+
maybeCallback();
82+
});
83+
});
84+
85+
function maybeCallback() {
86+
if (!callback)
87+
return;
88+
if (server.conn && (client.conn || client.err)) {
89+
const err = pair.client.err || pair.server.err;
90+
callback(err, pair, cleanup);
91+
callback = null;
92+
93+
function cleanup() {
94+
if (server.server)
95+
server.server.close();
96+
if (client.conn)
97+
client.conn.end();
98+
}
99+
}
100+
}
101+
}

test/parallel/test-tls-addca.js

+33-45
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,50 @@
11
'use strict';
22
const common = require('../common');
3-
const fs = require('fs');
43

5-
if (!common.hasCrypto) {
6-
common.skip('missing crypto');
7-
return;
8-
}
9-
const tls = require('tls');
10-
11-
function filenamePEM(n) {
12-
return require('path').join(common.fixturesDir, 'keys', n + '.pem');
13-
}
4+
// Adding a CA certificate to contextWithCert should not also add it to
5+
// contextWithoutCert. This is tested by trying to connect to a server that
6+
// depends on that CA using contextWithoutCert.
147

15-
function loadPEM(n) {
16-
return fs.readFileSync(filenamePEM(n));
17-
}
8+
const join = require('path').join;
9+
const {
10+
assert, connect, keys, tls
11+
} = require(join(common.fixturesDir, 'tls-connect'))();
1812

19-
const caCert = loadPEM('ca1-cert');
2013
const contextWithoutCert = tls.createSecureContext({});
2114
const contextWithCert = tls.createSecureContext({});
22-
// Adding a CA certificate to contextWithCert should not also add it to
23-
// contextWithoutCert. This is tested by trying to connect to a server that
24-
// depends on that CA using contextWithoutCert.
25-
contextWithCert.context.addCACert(caCert);
15+
contextWithCert.context.addCACert(keys.agent1.ca);
2616

2717
const serverOptions = {
28-
key: loadPEM('agent1-key'),
29-
cert: loadPEM('agent1-cert'),
18+
key: keys.agent1.key,
19+
cert: keys.agent1.cert,
3020
};
31-
const server = tls.createServer(serverOptions, function() {});
3221

3322
const clientOptions = {
34-
port: undefined,
35-
ca: [caCert],
23+
ca: [keys.agent1.ca],
3624
servername: 'agent1',
3725
rejectUnauthorized: true,
3826
};
3927

40-
function startTest() {
41-
// This client should fail to connect because it doesn't trust the CA
28+
// This client should fail to connect because it doesn't trust the CA
29+
// certificate.
30+
clientOptions.secureContext = contextWithoutCert;
31+
32+
connect({
33+
client: clientOptions,
34+
server: serverOptions,
35+
}, function(err, pair, cleanup) {
36+
assert(err);
37+
assert.strictEqual(err.message, 'unable to verify the first certificate');
38+
cleanup();
39+
40+
// This time it should connect because contextWithCert includes the needed CA
4241
// certificate.
43-
clientOptions.secureContext = contextWithoutCert;
44-
clientOptions.port = server.address().port;
45-
const client = tls.connect(clientOptions, common.fail);
46-
client.on('error', common.mustCall(() => {
47-
client.destroy();
48-
49-
// This time it should connect because contextWithCert includes the needed
50-
// CA certificate.
51-
clientOptions.secureContext = contextWithCert;
52-
const client2 = tls.connect(clientOptions, common.mustCall(() => {
53-
client2.destroy();
54-
server.close();
55-
}));
56-
client2.on('error', (e) => {
57-
console.log(e);
58-
});
59-
}));
60-
}
61-
62-
server.listen(0, startTest);
42+
clientOptions.secureContext = contextWithCert;
43+
connect({
44+
client: clientOptions,
45+
server: serverOptions,
46+
}, function(err, pair, cleanup) {
47+
assert.ifError(err);
48+
cleanup();
49+
});
50+
});
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,25 @@
11
'use strict';
22
const common = require('../common');
33

4-
if (!common.hasCrypto) {
5-
common.skip('missing crypto');
6-
return;
7-
}
8-
const tls = require('tls');
4+
// Verify connection with explicitly created client SecureContext.
95

10-
const fs = require('fs');
11-
const path = require('path');
6+
const join = require('path').join;
7+
const {
8+
assert, connect, keys, tls
9+
} = require(join(common.fixturesDir, 'tls-connect'))();
1210

13-
const keysDir = path.join(common.fixturesDir, 'keys');
14-
15-
const ca = fs.readFileSync(path.join(keysDir, 'ca1-cert.pem'));
16-
const cert = fs.readFileSync(path.join(keysDir, 'agent1-cert.pem'));
17-
const key = fs.readFileSync(path.join(keysDir, 'agent1-key.pem'));
18-
19-
const server = tls.createServer({
20-
cert: cert,
21-
key: key
22-
}, function(c) {
23-
c.end();
24-
}).listen(0, function() {
25-
const secureContext = tls.createSecureContext({
26-
ca: ca
27-
});
28-
29-
const socket = tls.connect({
30-
secureContext: secureContext,
11+
connect({
12+
client: {
3113
servername: 'agent1',
32-
port: this.address().port
33-
}, common.mustCall(function() {
34-
server.close();
35-
socket.end();
36-
}));
14+
secureContext: tls.createSecureContext({
15+
ca: keys.agent1.ca,
16+
}),
17+
},
18+
server: {
19+
cert: keys.agent1.cert,
20+
key: keys.agent1.key,
21+
},
22+
}, function(err, pair, cleanup) {
23+
assert.ifError(err);
24+
return cleanup();
3725
});
+29-43
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,39 @@
11
'use strict';
22
const common = require('../common');
3-
const assert = require('assert');
43

5-
if (!common.hasCrypto) {
6-
common.skip('missing crypto');
7-
return;
8-
}
9-
const tls = require('tls');
4+
// Verify that detailed getPeerCertificate() return value has all certs.
105

11-
const fs = require('fs');
12-
const util = require('util');
136
const join = require('path').join;
7+
const {
8+
assert, connect, debug, keys
9+
} = require(join(common.fixturesDir, 'tls-connect'))();
1410

15-
const options = {
16-
key: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-key.pem')),
17-
cert: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-cert.pem')),
18-
ca: [ fs.readFileSync(join(common.fixturesDir, 'keys', 'ca1-cert.pem')) ]
19-
};
11+
connect({
12+
client: {rejectUnauthorized: false},
13+
server: keys.agent1,
14+
}, function(err, pair, cleanup) {
15+
assert.ifError(err);
16+
const socket = pair.client.conn;
17+
let peerCert = socket.getPeerCertificate();
18+
assert.ok(!peerCert.issuerCertificate);
2019

21-
const server = tls.createServer(options, function(cleartext) {
22-
cleartext.end('World');
23-
});
24-
server.listen(0, common.mustCall(function() {
25-
const socket = tls.connect({
26-
port: this.address().port,
27-
rejectUnauthorized: false
28-
}, common.mustCall(function() {
29-
let peerCert = socket.getPeerCertificate();
30-
assert.ok(!peerCert.issuerCertificate);
20+
peerCert = socket.getPeerCertificate(true);
21+
debug('peerCert:\n', peerCert);
3122

32-
// Verify that detailed return value has all certs
33-
peerCert = socket.getPeerCertificate(true);
34-
assert.ok(peerCert.issuerCertificate);
23+
assert.ok(peerCert.issuerCertificate);
24+
assert.strictEqual(peerCert.subject.emailAddress, '[email protected]');
25+
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
26+
assert.strictEqual(peerCert.exponent, '0x10001');
27+
assert.strictEqual(
28+
peerCert.fingerprint,
29+
'8D:06:3A:B3:E5:8B:85:29:72:4F:7D:1B:54:CD:95:19:3C:EF:6F:AA'
30+
);
31+
assert.deepStrictEqual(peerCert.infoAccess['OCSP - URI'],
32+
[ 'http://ocsp.nodejs.org/' ]);
3533

36-
console.error(util.inspect(peerCert));
37-
assert.strictEqual(peerCert.subject.emailAddress, '[email protected]');
38-
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
39-
assert.strictEqual(peerCert.exponent, '0x10001');
40-
assert.strictEqual(
41-
peerCert.fingerprint,
42-
'8D:06:3A:B3:E5:8B:85:29:72:4F:7D:1B:54:CD:95:19:3C:EF:6F:AA'
43-
);
44-
assert.deepStrictEqual(peerCert.infoAccess['OCSP - URI'],
45-
[ 'http://ocsp.nodejs.org/' ]);
34+
const issuer = peerCert.issuerCertificate;
35+
assert.strictEqual(issuer.issuerCertificate, issuer);
36+
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
4637

47-
const issuer = peerCert.issuerCertificate;
48-
assert.strictEqual(issuer.issuerCertificate, issuer);
49-
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
50-
server.close();
51-
}));
52-
socket.end('Hello');
53-
}));
38+
return cleanup();
39+
});

0 commit comments

Comments
 (0)