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 42 { ca: [], 43 key: 'agent2-key', 44 cert: 'agent2-cert', 45 servers: [ 46 { ok: false, key: 'agent1-key', cert: 'agent1-cert' }, 47 { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, 48 { ok: false, key: 'agent3-key', cert: 'agent3-cert' } 49 ] 50 }, 51 52 { ca: ['ca1-cert', 'ca2-cert'], 53 key: 'agent2-key', 54 cert: 'agent2-cert', 55 servers: [ 56 { ok: true, key: 'agent1-key', cert: 'agent1-cert' }, 57 { ok: false, key: 'agent2-key', cert: 'agent2-cert' }, 58 { ok: true, key: 'agent3-key', cert: 'agent3-cert' } 59 ] 60 } 61]; 62 63 64function loadPEM(n) { 65 return fixtures.readKey(`${n}.pem`); 66} 67 68let successfulTests = 0; 69 70function testServers(index, servers, clientOptions, cb) { 71 const serverOptions = servers[index]; 72 if (!serverOptions) { 73 cb(); 74 return; 75 } 76 77 const ok = serverOptions.ok; 78 79 if (serverOptions.key) { 80 serverOptions.key = loadPEM(serverOptions.key); 81 } 82 83 if (serverOptions.cert) { 84 serverOptions.cert = loadPEM(serverOptions.cert); 85 } 86 87 const server = tls.createServer(serverOptions, common.mustCall(function(s) { 88 s.end('hello world\n'); 89 })); 90 91 server.listen(0, common.mustCall(function() { 92 let b = ''; 93 94 console.error('connecting...'); 95 clientOptions.port = this.address().port; 96 const client = tls.connect(clientOptions, common.mustCall(function() { 97 const authorized = client.authorized || 98 (client.authorizationError === 'ERR_TLS_CERT_ALTNAME_INVALID'); 99 100 console.error(`expected: ${ok} authed: ${authorized}`); 101 102 assert.strictEqual(authorized, ok); 103 server.close(); 104 })); 105 106 client.on('data', function(d) { 107 b += d.toString(); 108 }); 109 110 client.on('end', common.mustCall(function() { 111 assert.strictEqual(b, 'hello world\n'); 112 })); 113 114 client.on('close', common.mustCall(function() { 115 testServers(index + 1, servers, clientOptions, cb); 116 })); 117 })); 118} 119 120 121function runTest(testIndex) { 122 const tcase = testCases[testIndex]; 123 if (!tcase) return; 124 125 const clientOptions = { 126 port: undefined, 127 ca: tcase.ca.map(loadPEM), 128 key: loadPEM(tcase.key), 129 cert: loadPEM(tcase.cert), 130 rejectUnauthorized: false 131 }; 132 133 134 testServers(0, tcase.servers, clientOptions, common.mustCall(function() { 135 successfulTests++; 136 runTest(testIndex + 1); 137 })); 138} 139 140 141runTest(0); 142 143 144process.on('exit', function() { 145 console.log(`successful tests: ${successfulTests}`); 146 assert.strictEqual(successfulTests, testCases.length); 147}); 148