1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24if (!common.hasCrypto) 25 common.skip('missing crypto'); 26 27const assert = require('assert'); 28const tls = require('tls'); 29const fixtures = require('../common/fixtures'); 30 31const testCases = [ 32 { ca: ['ca1-cert'], 33 key: 'agent2-key', 34 cert: 'agent2-cert', 35 servers: [ 36 { ok: true, key: 'agent1-key', cert: 'agent1-cert' }, 37 { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, 38 { ok: false, key: 'agent3-key', cert: 'agent3-cert' }, 39 ] }, 40 41 { ca: [], 42 key: 'agent2-key', 43 cert: 'agent2-cert', 44 servers: [ 45 { ok: false, key: 'agent1-key', cert: 'agent1-cert' }, 46 { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, 47 { ok: false, key: 'agent3-key', cert: 'agent3-cert' }, 48 ] }, 49 50 { ca: ['ca1-cert', 'ca2-cert'], 51 key: 'agent2-key', 52 cert: 'agent2-cert', 53 servers: [ 54 { ok: true, key: 'agent1-key', cert: 'agent1-cert' }, 55 { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, 56 { ok: true, key: 'agent3-key', cert: 'agent3-cert' }, 57 ] }, 58]; 59 60 61function loadPEM(n) { 62 return fixtures.readKey(`${n}.pem`); 63} 64 65let successfulTests = 0; 66 67function testServers(index, servers, clientOptions, cb) { 68 const serverOptions = servers[index]; 69 if (!serverOptions) { 70 cb(); 71 return; 72 } 73 74 const ok = serverOptions.ok; 75 76 if (serverOptions.key) { 77 serverOptions.key = loadPEM(serverOptions.key); 78 } 79 80 if (serverOptions.cert) { 81 serverOptions.cert = loadPEM(serverOptions.cert); 82 } 83 84 const server = tls.createServer(serverOptions, common.mustCall(function(s) { 85 s.end('hello world\n'); 86 })); 87 88 server.listen(0, common.mustCall(function() { 89 let b = ''; 90 91 console.error('connecting...'); 92 clientOptions.port = this.address().port; 93 const client = tls.connect(clientOptions, common.mustCall(function() { 94 const authorized = client.authorized || 95 (client.authorizationError === 'ERR_TLS_CERT_ALTNAME_INVALID'); 96 97 console.error(`expected: ${ok} authed: ${authorized}`); 98 99 assert.strictEqual(authorized, ok); 100 server.close(); 101 })); 102 103 client.on('data', function(d) { 104 b += d.toString(); 105 }); 106 107 client.on('end', common.mustCall(function() { 108 assert.strictEqual(b, 'hello world\n'); 109 })); 110 111 client.on('close', common.mustCall(function() { 112 testServers(index + 1, servers, clientOptions, cb); 113 })); 114 })); 115} 116 117 118function runTest(testIndex) { 119 const tcase = testCases[testIndex]; 120 if (!tcase) return; 121 122 const clientOptions = { 123 port: undefined, 124 ca: tcase.ca.map(loadPEM), 125 key: loadPEM(tcase.key), 126 cert: loadPEM(tcase.cert), 127 rejectUnauthorized: false 128 }; 129 130 131 testServers(0, tcase.servers, clientOptions, common.mustCall(function() { 132 successfulTests++; 133 runTest(testIndex + 1); 134 })); 135} 136 137 138runTest(0); 139 140 141process.on('exit', function() { 142 console.log(`successful tests: ${successfulTests}`); 143 assert.strictEqual(successfulTests, testCases.length); 144}); 145