Permalink
Browse files

test: remove s_client from test-tls-ci-reneg-attack

Rewrite test-tls-ci-reneg-attack to use tls.renegotiate() instead of
external (and potentially unpredictable/quirky/buggy) s_client.

Refs: #25676 (comment)

PR-URL: #25700
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
  • Loading branch information...
Trott authored and addaleax committed Jan 25, 2019
1 parent 190c063 commit 271126ad3b6d0d94aac654e9216ac0dad396056e
Showing with 21 additions and 36 deletions.
  1. +21 −36 test/pummel/test-tls-ci-reneg-attack.js
@@ -28,7 +28,6 @@ if (!common.opensslCli)
common.skip('node compiled without OpenSSL CLI.');

const assert = require('assert');
const spawn = require('child_process').spawn;
const tls = require('tls');
const fixtures = require('../common/fixtures');

@@ -51,63 +50,49 @@ function test(next) {
key: fixtures.readSync('test_key.pem')
};

let seenError = false;

const server = tls.createServer(options, function(conn) {
conn.on('error', function(err) {
console.error(`Caught exception: ${err}`);
assert(/TLS session renegotiation attack/.test(err));
conn.destroy();
seenError = true;
});
conn.pipe(conn);
});

server.listen(common.PORT, function() {
const args = (`s_client -connect 127.0.0.1:${common.PORT}`).split(' ');
const child = spawn(common.opensslCli, args);

child.stdout.resume();
child.stderr.resume();
server.listen(0, function() {
const options = {
host: server.address().host,
port: server.address().port,
rejectUnauthorized: false
};
const client = tls.connect(options, spam);

// Count handshakes, start the attack after the initial handshake is done
let handshakes = 0;
let renegs = 0;

child.stderr.on('data', function(data) {
if (seenError) return;
handshakes += ((String(data)).match(/verify return:1/g) || []).length;
if (handshakes === 2) spam();
renegs += ((String(data)).match(/RENEGOTIATING/g) || []).length;
});

child.on('exit', function() {
client.on('close', function() {
assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1);
server.close();
process.nextTick(next);
});

let closed = false;
child.stdin.on('error', function(err) {
switch (err.code) {
case 'ECONNRESET':
case 'EPIPE':
break;
default:
assert.strictEqual(err.code, 'ECONNRESET');
break;
}
closed = true;
client.on('error', function(err) {
console.log('CLIENT ERR', err);
throw err;
});
child.stdin.on('close', function() {
closed = true;

client.on('close', function(hadErr) {
assert.strictEqual(hadErr, false);
});

// simulate renegotiation attack
function spam() {
if (closed) return;
child.stdin.write('R\n');
setTimeout(spam, 50);
client.write('');
client.renegotiate({}, (err) => {
assert.ifError(err);
assert.ok(renegs <= tls.CLIENT_RENEG_LIMIT);
spam();
});
renegs++;
}
});
}

0 comments on commit 271126a

Please sign in to comment.