• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
27if (!common.opensslCli)
28  common.skip('missing openssl-cli');
29
30const assert = require('assert');
31const tls = require('tls');
32const net = require('net');
33const spawn = require('child_process').spawn;
34const fixtures = require('../common/fixtures');
35
36const key = fixtures.readKey('rsa_private.pem');
37const cert = fixtures.readKey('rsa_cert.crt');
38
39function log(a) {
40  console.error('***server***', a);
41}
42
43const server = net.createServer(common.mustCall(function(socket) {
44  log(`connection fd=${socket.fd}`);
45  const sslcontext = tls.createSecureContext({ key, cert });
46  sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA');
47
48  const pair = tls.createSecurePair(sslcontext, true);
49
50  assert.ok(pair.encrypted.writable);
51  assert.ok(pair.cleartext.writable);
52
53  pair.encrypted.pipe(socket);
54  socket.pipe(pair.encrypted);
55
56  log('i set it secure');
57
58  pair.on('secure', function() {
59    log('connected+secure!');
60    pair.cleartext.write('hello\r\n');
61    log(pair.cleartext.getPeerCertificate());
62    log(pair.cleartext.getCipher());
63  });
64
65  pair.cleartext.on('data', function(data) {
66    log(`read bytes ${data.length}`);
67    pair.cleartext.write(data);
68  });
69
70  socket.on('end', function() {
71    log('socket end');
72  });
73
74  pair.cleartext.on('error', function(err) {
75    log('got error: ');
76    log(err);
77    socket.destroy();
78  });
79
80  pair.encrypted.on('error', function(err) {
81    log('encrypted error: ');
82    log(err);
83    socket.destroy();
84  });
85
86  socket.on('error', function(err) {
87    log('socket error: ');
88    log(err);
89    socket.destroy();
90  });
91
92  socket.on('close', function(err) {
93    log('socket closed');
94  });
95
96  pair.on('error', function(err) {
97    log('secure error: ');
98    log(err);
99    socket.destroy();
100  });
101}));
102
103let gotHello = false;
104let sentWorld = false;
105let gotWorld = false;
106
107server.listen(0, common.mustCall(function() {
108  // To test use: openssl s_client -connect localhost:8000
109
110  const args = ['s_client', '-connect', `127.0.0.1:${this.address().port}`];
111
112  const client = spawn(common.opensslCli, args);
113
114
115  let out = '';
116
117  client.stdout.setEncoding('utf8');
118  client.stdout.on('data', function(d) {
119    out += d;
120
121    if (!gotHello && /hello/.test(out)) {
122      gotHello = true;
123      client.stdin.write('world\r\n');
124      sentWorld = true;
125    }
126
127    if (!gotWorld && /world/.test(out)) {
128      gotWorld = true;
129      client.stdin.end();
130    }
131  });
132
133  client.stdout.pipe(process.stdout, { end: false });
134
135  client.on('exit', common.mustCall(function(code) {
136    assert.strictEqual(code, 0);
137    server.close();
138  }));
139}));
140
141process.on('exit', function() {
142  assert.ok(gotHello);
143  assert.ok(sentWorld);
144  assert.ok(gotWorld);
145});
146