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';
|
'use strict';
|
||||||
const common = require('../common');
|
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
|
// Adding a CA certificate to contextWithCert should not also add it to
|
||||||
// contextWithoutCert. This is tested by trying to connect to a server that
|
// contextWithoutCert. This is tested by trying to connect to a server that
|
||||||
// depends on that CA using contextWithoutCert.
|
// 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 = {
|
const serverOptions = {
|
||||||
key: loadPEM('agent1-key'),
|
key: keys.agent1.key,
|
||||||
cert: loadPEM('agent1-cert'),
|
cert: keys.agent1.cert,
|
||||||
};
|
};
|
||||||
const server = tls.createServer(serverOptions, function() {});
|
|
||||||
|
|
||||||
const clientOptions = {
|
const clientOptions = {
|
||||||
port: undefined,
|
ca: [keys.agent1.ca],
|
||||||
ca: [caCert],
|
|
||||||
servername: 'agent1',
|
servername: 'agent1',
|
||||||
rejectUnauthorized: true,
|
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.
|
// 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;
|
clientOptions.secureContext = contextWithCert;
|
||||||
const client2 = tls.connect(clientOptions, common.mustCall(() => {
|
connect({
|
||||||
client2.destroy();
|
client: clientOptions,
|
||||||
server.close();
|
server: serverOptions,
|
||||||
}));
|
}, function(err, pair, cleanup) {
|
||||||
client2.on('error', (e) => {
|
assert.ifError(err);
|
||||||
console.log(e);
|
cleanup();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
}
|
|
||||||
|
|
||||||
server.listen(0, startTest);
|
|
||||||
|
@ -1,37 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
|
|
||||||
if (!common.hasCrypto) {
|
// Verify connection with explicitly created client SecureContext.
|
||||||
common.skip('missing crypto');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tls = require('tls');
|
|
||||||
|
|
||||||
const fs = require('fs');
|
const join = require('path').join;
|
||||||
const path = require('path');
|
const {
|
||||||
|
assert, connect, keys, tls
|
||||||
|
} = require(join(common.fixturesDir, 'tls-connect'))();
|
||||||
|
|
||||||
const keysDir = path.join(common.fixturesDir, 'keys');
|
connect({
|
||||||
|
client: {
|
||||||
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,
|
|
||||||
servername: 'agent1',
|
servername: 'agent1',
|
||||||
port: this.address().port
|
secureContext: tls.createSecureContext({
|
||||||
}, common.mustCall(function() {
|
ca: keys.agent1.ca,
|
||||||
server.close();
|
}),
|
||||||
socket.end();
|
},
|
||||||
}));
|
server: {
|
||||||
|
cert: keys.agent1.cert,
|
||||||
|
key: keys.agent1.key,
|
||||||
|
},
|
||||||
|
}, function(err, pair, cleanup) {
|
||||||
|
assert.ifError(err);
|
||||||
|
return cleanup();
|
||||||
});
|
});
|
||||||
|
@ -1,39 +1,26 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
|
||||||
|
|
||||||
if (!common.hasCrypto) {
|
// Verify that detailed getPeerCertificate() return value has all certs.
|
||||||
common.skip('missing crypto');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tls = require('tls');
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const util = require('util');
|
|
||||||
const join = require('path').join;
|
const join = require('path').join;
|
||||||
|
const {
|
||||||
|
assert, connect, debug, keys
|
||||||
|
} = require(join(common.fixturesDir, 'tls-connect'))();
|
||||||
|
|
||||||
const options = {
|
connect({
|
||||||
key: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-key.pem')),
|
client: {rejectUnauthorized: false},
|
||||||
cert: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-cert.pem')),
|
server: keys.agent1,
|
||||||
ca: [ fs.readFileSync(join(common.fixturesDir, 'keys', 'ca1-cert.pem')) ]
|
}, function(err, pair, cleanup) {
|
||||||
};
|
assert.ifError(err);
|
||||||
|
const socket = pair.client.conn;
|
||||||
const server = tls.createServer(options, function(cleartext) {
|
|
||||||
cleartext.end('World');
|
|
||||||
});
|
|
||||||
server.listen(0, common.mustCall(function() {
|
|
||||||
const socket = tls.connect({
|
|
||||||
port: this.address().port,
|
|
||||||
rejectUnauthorized: false
|
|
||||||
}, common.mustCall(function() {
|
|
||||||
let peerCert = socket.getPeerCertificate();
|
let peerCert = socket.getPeerCertificate();
|
||||||
assert.ok(!peerCert.issuerCertificate);
|
assert.ok(!peerCert.issuerCertificate);
|
||||||
|
|
||||||
// Verify that detailed return value has all certs
|
|
||||||
peerCert = socket.getPeerCertificate(true);
|
peerCert = socket.getPeerCertificate(true);
|
||||||
assert.ok(peerCert.issuerCertificate);
|
debug('peerCert:\n', peerCert);
|
||||||
|
|
||||||
console.error(util.inspect(peerCert));
|
assert.ok(peerCert.issuerCertificate);
|
||||||
assert.strictEqual(peerCert.subject.emailAddress, 'ry@tinyclouds.org');
|
assert.strictEqual(peerCert.subject.emailAddress, 'ry@tinyclouds.org');
|
||||||
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
|
assert.strictEqual(peerCert.serialNumber, '9A84ABCFB8A72AC0');
|
||||||
assert.strictEqual(peerCert.exponent, '0x10001');
|
assert.strictEqual(peerCert.exponent, '0x10001');
|
||||||
@ -47,7 +34,6 @@ server.listen(0, common.mustCall(function() {
|
|||||||
const issuer = peerCert.issuerCertificate;
|
const issuer = peerCert.issuerCertificate;
|
||||||
assert.strictEqual(issuer.issuerCertificate, issuer);
|
assert.strictEqual(issuer.issuerCertificate, issuer);
|
||||||
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
|
assert.strictEqual(issuer.serialNumber, '8DF21C01468AF393');
|
||||||
server.close();
|
|
||||||
}));
|
return cleanup();
|
||||||
socket.end('Hello');
|
});
|
||||||
}));
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user