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. PR-URL: https://github.com/nodejs/node/pull/10389 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
This commit is contained in:
parent
7f20c8a3d4
commit
99b0c2e7a7
101
test/fixtures/tls-connect.js
vendored
Normal file
101
test/fixtures/tls-connect.js
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
// One shot call to connect a TLS client and server based on options to
|
||||
// tls.createServer() and tls.connect(), so assertions can be made on both ends
|
||||
// of the connection.
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const fs = require('fs');
|
||||
const join = require('path').join;
|
||||
const tls = require('tls');
|
||||
const util = require('util');
|
||||
|
||||
module.exports = exports = checkCrypto;
|
||||
|
||||
function checkCrypto() {
|
||||
if (!common.hasCrypto) {
|
||||
common.skip('missing crypto');
|
||||
process.exit(0);
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
|
||||
exports.assert = require('assert');
|
||||
exports.debug = util.debuglog('test');
|
||||
exports.tls = tls;
|
||||
|
||||
// Pre-load keys from common fixtures for ease of use by tests.
|
||||
const keys = exports.keys = {
|
||||
agent1: load('agent1', 'ca1'),
|
||||
agent2: load('agent2', 'agent2'),
|
||||
agent3: load('agent3', 'ca2'),
|
||||
agent4: load('agent4', 'ca2'),
|
||||
agent5: load('agent5', 'ca2'),
|
||||
agent6: load('agent6', 'ca1'),
|
||||
agent7: load('agent7', 'fake-cnnic-root'),
|
||||
ec: load('ec', 'ec'),
|
||||
};
|
||||
|
||||
function load(cert, issuer) {
|
||||
issuer = issuer || cert; // Assume self-signed if no issuer
|
||||
const id = {
|
||||
key: read(cert + '-key.pem'),
|
||||
cert: read(cert + '-cert.pem'),
|
||||
ca: read(issuer + '-cert.pem'),
|
||||
};
|
||||
return id;
|
||||
}
|
||||
|
||||
function read(file) {
|
||||
return fs.readFileSync(join(common.fixturesDir, 'keys', file), 'binary');
|
||||
}
|
||||
|
||||
exports.connect = function connect(options, callback) {
|
||||
callback = common.mustCall(callback);
|
||||
|
||||
const server = {};
|
||||
const client = {};
|
||||
const pair = {
|
||||
server: server,
|
||||
client: client,
|
||||
};
|
||||
|
||||
tls.createServer(options.server, function(conn) {
|
||||
server.conn = conn;
|
||||
conn.pipe(conn);
|
||||
maybeCallback()
|
||||
}).listen(0, function() {
|
||||
server.server = this;
|
||||
|
||||
const optClient = util._extend({
|
||||
port: this.address().port,
|
||||
}, options.client);
|
||||
|
||||
tls.connect(optClient)
|
||||
.on('secureConnect', function() {
|
||||
client.conn = this;
|
||||
maybeCallback();
|
||||
})
|
||||
.on('error', function(err) {
|
||||
client.err = err;
|
||||
client.conn = this;
|
||||
maybeCallback();
|
||||
});
|
||||
});
|
||||
|
||||
function maybeCallback() {
|
||||
if (!callback)
|
||||
return;
|
||||
if (server.conn && (client.conn || client.err)) {
|
||||
const err = pair.client.err || pair.server.err;
|
||||
callback(err, pair, cleanup);
|
||||
callback = null;
|
||||
|
||||
function cleanup() {
|
||||
if (server.server)
|
||||
server.server.close();
|
||||
if (client.conn)
|
||||
client.conn.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +1,50 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const fs = require('fs');
|
||||
|
||||
if (!common.hasCrypto) {
|
||||
common.skip('missing crypto');
|
||||
return;
|
||||
}
|
||||
const tls = require('tls');
|
||||
|
||||
function filenamePEM(n) {
|
||||
return require('path').join(common.fixturesDir, 'keys', n + '.pem');
|
||||
}
|
||||
|
||||
function loadPEM(n) {
|
||||
return fs.readFileSync(filenamePEM(n));
|
||||
}
|
||||
|
||||
const caCert = loadPEM('ca1-cert');
|
||||
const contextWithoutCert = tls.createSecureContext({});
|
||||
const contextWithCert = tls.createSecureContext({});
|
||||
// Adding a CA certificate to contextWithCert should not also add it to
|
||||
// contextWithoutCert. This is tested by trying to connect to a server that
|
||||
// depends on that CA using contextWithoutCert.
|
||||
contextWithCert.context.addCACert(caCert);
|
||||
|
||||
const join = require('path').join;
|
||||
const {
|
||||
assert, connect, keys, tls
|
||||
} = require(join(common.fixturesDir, 'tls-connect'))();
|
||||
|
||||
const contextWithoutCert = tls.createSecureContext({});
|
||||
const contextWithCert = tls.createSecureContext({});
|
||||
contextWithCert.context.addCACert(keys.agent1.ca);
|
||||
|
||||
const serverOptions = {
|
||||
key: loadPEM('agent1-key'),
|
||||
cert: loadPEM('agent1-cert'),
|
||||
key: keys.agent1.key,
|
||||
cert: keys.agent1.cert,
|
||||
};
|
||||
const server = tls.createServer(serverOptions, function() {});
|
||||
|
||||
const clientOptions = {
|
||||
port: undefined,
|
||||
ca: [caCert],
|
||||
ca: [keys.agent1.ca],
|
||||
servername: 'agent1',
|
||||
rejectUnauthorized: true,
|
||||
};
|
||||
|
||||
function startTest() {
|
||||
// This client should fail to connect because it doesn't trust the CA
|
||||
// This client should fail to connect because it doesn't trust the CA
|
||||
// certificate.
|
||||
clientOptions.secureContext = contextWithoutCert;
|
||||
|
||||
connect({
|
||||
client: clientOptions,
|
||||
server: serverOptions,
|
||||
}, function(err, pair, cleanup) {
|
||||
assert(err);
|
||||
assert.strictEqual(err.message, 'unable to verify the first certificate');
|
||||
cleanup();
|
||||
|
||||
// This time it should connect because contextWithCert includes the needed CA
|
||||
// certificate.
|
||||
clientOptions.secureContext = contextWithoutCert;
|
||||
clientOptions.port = server.address().port;
|
||||
const client = tls.connect(clientOptions, common.fail);
|
||||
client.on('error', common.mustCall(() => {
|
||||
client.destroy();
|
||||
|
||||
// This time it should connect because contextWithCert includes the needed
|
||||
// CA certificate.
|
||||
clientOptions.secureContext = contextWithCert;
|
||||
const client2 = tls.connect(clientOptions, common.mustCall(() => {
|
||||
client2.destroy();
|
||||
server.close();
|
||||
}));
|
||||
client2.on('error', (e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
server.listen(0, startTest);
|
||||
clientOptions.secureContext = contextWithCert;
|
||||
connect({
|
||||
client: clientOptions,
|
||||
server: serverOptions,
|
||||
}, function(err, pair, cleanup) {
|
||||
assert.ifError(err);
|
||||
cleanup();
|
||||
});
|
||||
});
|
||||
|
@ -1,37 +1,25 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
|
||||
if (!common.hasCrypto) {
|
||||
common.skip('missing crypto');
|
||||
return;
|
||||
}
|
||||
const tls = require('tls');
|
||||
// Verify connection with explicitly created client SecureContext.
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const join = require('path').join;
|
||||
const {
|
||||
assert, connect, keys, tls
|
||||
} = require(join(common.fixturesDir, 'tls-connect'))();
|
||||
|
||||
const keysDir = path.join(common.fixturesDir, 'keys');
|
||||
|
||||
const ca = fs.readFileSync(path.join(keysDir, 'ca1-cert.pem'));
|
||||
const cert = fs.readFileSync(path.join(keysDir, 'agent1-cert.pem'));
|
||||
const key = fs.readFileSync(path.join(keysDir, 'agent1-key.pem'));
|
||||
|
||||
const server = tls.createServer({
|
||||
cert: cert,
|
||||
key: key
|
||||
}, function(c) {
|
||||
c.end();
|
||||
}).listen(0, function() {
|
||||
const secureContext = tls.createSecureContext({
|
||||
ca: ca
|
||||
});
|
||||
|
||||
const socket = tls.connect({
|
||||
secureContext: secureContext,
|
||||
connect({
|
||||
client: {
|
||||
servername: 'agent1',
|
||||
port: this.address().port
|
||||
}, common.mustCall(function() {
|
||||
server.close();
|
||||
socket.end();
|
||||
}));
|
||||
secureContext: tls.createSecureContext({
|
||||
ca: keys.agent1.ca,
|
||||
}),
|
||||
},
|
||||
server: {
|
||||
cert: keys.agent1.cert,
|
||||
key: keys.agent1.key,
|
||||
},
|
||||
}, function(err, pair, cleanup) {
|
||||
assert.ifError(err);
|
||||
return cleanup();
|
||||
});
|
||||
|
@ -1,53 +1,39 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
if (!common.hasCrypto) {
|
||||
common.skip('missing crypto');
|
||||
return;
|
||||
}
|
||||
const tls = require('tls');
|
||||
// Verify that detailed getPeerCertificate() return value has all certs.
|
||||
|
||||
const fs = require('fs');
|
||||
const util = require('util');
|
||||
const join = require('path').join;
|
||||
const {
|
||||
assert, connect, debug, keys
|
||||
} = require(join(common.fixturesDir, 'tls-connect'))();
|
||||
|
||||
const options = {
|
||||
key: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-key.pem')),
|
||||
cert: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-cert.pem')),
|
||||
ca: [ fs.readFileSync(join(common.fixturesDir, 'keys', 'ca1-cert.pem')) ]
|
||||
};
|
||||
connect({
|
||||
client: {rejectUnauthorized: false},
|
||||
server: keys.agent1,
|
||||
}, function(err, pair, cleanup) {
|
||||
assert.ifError(err);
|
||||
const socket = pair.client.conn;
|
||||
let peerCert = socket.getPeerCertificate();
|
||||
assert.ok(!peerCert.issuerCertificate);
|
||||
|
||||
const server = tls.createServer(options, function(cleartext) {
|
||||
cleartext.end('World');
|
||||
peerCert = socket.getPeerCertificate(true);
|
||||
debug('peerCert:\n', peerCert);
|
||||
|
||||
assert.ok(peerCert.issuerCertificate);
|
||||
assert.strictEqual(peerCert.subject.emailAddress, 'ry@tinyclouds.org');
|
||||
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
|
||||
assert.strictEqual(peerCert.exponent, '0x10001');
|
||||
assert.strictEqual(
|
||||
peerCert.fingerprint,
|
||||
'8D:06:3A:B3:E5:8B:85:29:72:4F:7D:1B:54:CD:95:19:3C:EF:6F:AA'
|
||||
);
|
||||
assert.deepStrictEqual(peerCert.infoAccess['OCSP - URI'],
|
||||
[ 'http://ocsp.nodejs.org/' ]);
|
||||
|
||||
const issuer = peerCert.issuerCertificate;
|
||||
assert.strictEqual(issuer.issuerCertificate, issuer);
|
||||
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
|
||||
|
||||
return cleanup();
|
||||
});
|
||||
server.listen(0, common.mustCall(function() {
|
||||
const socket = tls.connect({
|
||||
port: this.address().port,
|
||||
rejectUnauthorized: false
|
||||
}, common.mustCall(function() {
|
||||
let peerCert = socket.getPeerCertificate();
|
||||
assert.ok(!peerCert.issuerCertificate);
|
||||
|
||||
// Verify that detailed return value has all certs
|
||||
peerCert = socket.getPeerCertificate(true);
|
||||
assert.ok(peerCert.issuerCertificate);
|
||||
|
||||
console.error(util.inspect(peerCert));
|
||||
assert.strictEqual(peerCert.subject.emailAddress, 'ry@tinyclouds.org');
|
||||
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
|
||||
assert.strictEqual(peerCert.exponent, '0x10001');
|
||||
assert.strictEqual(
|
||||
peerCert.fingerprint,
|
||||
'8D:06:3A:B3:E5:8B:85:29:72:4F:7D:1B:54:CD:95:19:3C:EF:6F:AA'
|
||||
);
|
||||
assert.deepStrictEqual(peerCert.infoAccess['OCSP - URI'],
|
||||
[ 'http://ocsp.nodejs.org/' ]);
|
||||
|
||||
const issuer = peerCert.issuerCertificate;
|
||||
assert.strictEqual(issuer.issuerCertificate, issuer);
|
||||
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
|
||||
server.close();
|
||||
}));
|
||||
socket.end('Hello');
|
||||
}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user