From b2ad1797bde3da028813b073e68dc5ae2d3c9541 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 25 Jan 2019 22:30:07 -0800 Subject: [PATCH] test: replace s_client in test-https-ci-reneg-attack Replace `s_client` in test-https-ci-reneg-attack with built-in client calling `tls.renegotiate()`. This also fixes the currently-broken test. (It is broken due to a change in behavior in a recently-updated-in-core version of `s_client`.) --- test/pummel/test-https-ci-reneg-attack.js | 72 +++++++++++------------ 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/test/pummel/test-https-ci-reneg-attack.js b/test/pummel/test-https-ci-reneg-attack.js index 50e16192e1b1ca..592dd6827320a1 100644 --- a/test/pummel/test-https-ci-reneg-attack.js +++ b/test/pummel/test-https-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 https = require('https'); const fixtures = require('../common/fixtures'); @@ -63,50 +62,47 @@ function test(next) { }); server.listen(0, function() { - const cmd = `s_client -connect 127.0.0.1:${server.address().port}`; - const args = cmd.split(' '); - const child = spawn(common.opensslCli, args); - - child.stdout.resume(); - child.stderr.resume(); + const agent = https.Agent({ + keepAlive: true, + }); - // Count handshakes, start the attack after the initial handshake is done - let handshakes = 0; + let client; let renegs = 0; - child.stderr.on('data', function(data) { - handshakes += ((String(data)).match(/verify return:1/g) || []).length; - if (handshakes === 2) spam(); - renegs += ((String(data)).match(/RENEGOTIATING/g) || []).length; - }); + const options = { + rejectUnauthorized: false, + agent + }; - child.on('exit', function() { - assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1); - server.close(); - process.nextTick(next); - }); + const { port } = server.address(); + + https.get(`https://localhost:${port}/`, options, (res) => { + client = res.socket; - let closed = false; - child.stdin.on('error', function(err) { - switch (err.code) { - case 'ECONNRESET': - case 'EPIPE': - break; - default: - assert.strictEqual(err.code, 'ECONNRESET'); - break; + client.on('close', function(hadErr) { + assert.strictEqual(hadErr, false); + assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1); + server.close(); + process.nextTick(next); + }); + + client.on('error', function(err) { + console.log('CLIENT ERR', err); + throw err; + }); + + spam(); + + // simulate renegotiation attack + function spam() { + client.renegotiate({}, (err) => { + assert.ifError(err); + assert.ok(renegs <= tls.CLIENT_RENEG_LIMIT); + setImmediate(spam); + }); + renegs++; } - closed = true; - }); - child.stdin.on('close', function() { - closed = true; }); - // simulate renegotiation attack - function spam() { - if (closed) return; - child.stdin.write('R\n'); - setTimeout(spam, 50); - } }); }