1'use strict'; 2const common = require('../common'); 3 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6if (!common.opensslCli) 7 common.skip('missing openssl cli'); 8 9const assert = require('assert'); 10const tls = require('tls'); 11const net = require('net'); 12const { spawn } = require('child_process'); 13 14const CIPHERS = 'PSK+HIGH'; 15const KEY = 'd731ef57be09e5204f0b205b60627028'; 16const IDENTITY = 'Client_identity'; // Hardcoded by `openssl s_server` 17 18const server = spawn(common.opensslCli, [ 19 's_server', 20 '-accept', common.PORT, 21 '-cipher', CIPHERS, 22 '-psk', KEY, 23 '-psk_hint', IDENTITY, 24 '-nocert', 25 '-rev', 26]); 27 28const cleanUp = (err) => { 29 clearTimeout(timeout); 30 if (err) 31 console.log('Failed:', err); 32 server.kill(); 33 process.exitCode = err ? 1 : 0; 34}; 35 36const timeout = setTimeout(() => cleanUp('Timeouted'), 5000); 37 38function waitForPort(port, cb) { 39 const socket = net.connect(common.PORT, () => { 40 socket.on('data', () => {}); 41 socket.end(); 42 socket.on('end', cb); 43 }); 44 socket.on('error', (e) => { 45 if (e.code === 'ENOENT' || e.code === 'ECONNREFUSED') { 46 setTimeout(() => waitForPort(port, cb), 1000); 47 } else { 48 cb(e); 49 } 50 }); 51} 52 53waitForPort(common.PORT, common.mustCall((err) => { 54 if (err) { 55 cleanUp(err); 56 return; 57 } 58 59 const message = 'hello'; 60 const reverse = message.split('').reverse().join(''); 61 runClient(message, common.mustCall((err, data) => { 62 try { 63 if (!err) assert.strictEqual(data.trim(), reverse); 64 } finally { 65 cleanUp(err); 66 } 67 })); 68})); 69 70function runClient(message, cb) { 71 const s = tls.connect(common.PORT, { 72 ciphers: CIPHERS, 73 checkServerIdentity: () => {}, 74 pskCallback(hint) { 75 // 'hint' will be null in TLS1.3. 76 if (hint === null || hint === IDENTITY) { 77 return { 78 identity: IDENTITY, 79 psk: Buffer.from(KEY, 'hex') 80 }; 81 } 82 } 83 }); 84 s.on('secureConnect', common.mustCall(() => { 85 let data = ''; 86 s.on('data', common.mustCallAtLeast((d) => { 87 data += d; 88 })); 89 s.on('end', common.mustCall(() => { 90 cb(null, data); 91 })); 92 s.end(message); 93 })); 94 s.on('error', (e) => { 95 cb(e); 96 }); 97} 98