• 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('node compiled without OpenSSL CLI.');
29
30const assert = require('assert');
31const tls = require('tls');
32const fixtures = require('../common/fixtures');
33
34// Renegotiation as a protocol feature was dropped after TLS1.2.
35tls.DEFAULT_MAX_VERSION = 'TLSv1.2';
36
37// Renegotiation limits to test
38const LIMITS = [0, 1, 2, 3, 5, 10, 16];
39
40{
41  let n = 0;
42  function next() {
43    if (n >= LIMITS.length) return;
44    tls.CLIENT_RENEG_LIMIT = LIMITS[n++];
45    test(next);
46  }
47  next();
48}
49
50function test(next) {
51  const options = {
52    cert: fixtures.readKey('rsa_cert.crt'),
53    key: fixtures.readKey('rsa_private.pem'),
54  };
55
56  const server = tls.createServer(options, (conn) => {
57    conn.on('error', (err) => {
58      console.error(`Caught exception: ${err}`);
59      assert.match(err.message, /TLS session renegotiation attack/);
60      conn.destroy();
61    });
62    conn.pipe(conn);
63  });
64
65  server.listen(0, () => {
66    const options = {
67      host: server.address().host,
68      port: server.address().port,
69      rejectUnauthorized: false,
70    };
71    const client = tls.connect(options, spam);
72
73    let renegs = 0;
74
75    client.on('close', () => {
76      assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1);
77      server.close();
78      process.nextTick(next);
79    });
80
81    client.on('error', (err) => {
82      console.log('CLIENT ERR', err);
83      throw err;
84    });
85
86    client.on('close', (hadErr) => {
87      assert.strictEqual(hadErr, false);
88    });
89
90    // Simulate renegotiation attack
91    function spam() {
92      client.write('');
93      client.renegotiate({}, (err) => {
94        assert.ifError(err);
95        assert.ok(renegs <= tls.CLIENT_RENEG_LIMIT);
96        spam();
97      });
98      renegs++;
99    }
100  });
101}
102