• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 'use strict';
2 const common = require('../common');
3 
4 if (!common.hasCrypto)
5   common.skip('missing crypto');
6 if (!common.opensslCli)
7   common.skip('missing openssl cli');
8 
9 const assert = require('assert');
10 const tls = require('tls');
11 const net = require('net');
12 const { spawn } = require('child_process');
13 
14 const CIPHERS = 'PSK+HIGH';
15 const KEY = 'd731ef57be09e5204f0b205b60627028';
16 const IDENTITY = 'Client_identity';  // Hardcoded by `openssl s_server`
17 
18 const 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 
28 const cleanUp = (err) => {
29   clearTimeout(timeout);
30   if (err)
31     console.log('Failed:', err);
32   server.kill();
33   process.exitCode = err ? 1 : 0;
34 };
35 
36 const timeout = setTimeout(() => cleanUp('Timeouted'), 5000);
37 
38 function 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 
53 waitForPort(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 
70 function 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