@passmarked/ssl
Version:
Rules that relate to checking the SSL configuration of each individual resolved server from the domain to ensure locked down config with the broadest compatibility
232 lines (152 loc) • 4.79 kB
JavaScript
// modules
const assert = require('assert');
const tls = require('tls');
const _ = require('underscore');
const passmarked = require('passmarked');
const testFunc = require('../lib/checks/chain');
const Constants = require('../lib/constants');
const moment = require('moment');
const fs = require('fs');
const dns = require('dns');
/**
* Wrap for a secure client connection
**/
var execSecureConnection = function(payload, params, fn) {
// get the dns
dns.resolve4(params.servername, function(err, ips) {
// build the options
var options = _.extend({
isServer: false,
rejectUnauthorized: false,
port: 443,
authorized: false,
requestCert: true,
host: ips[0]
}, params);
// upgrade to a TLS session
var client = new tls.connect(options);
// keep us sane :)
client.setEncoding( 'utf8' );
/**
* handle the plain socket connection
**/
client.on('connect' , function() {
/**
* The socket connected, but we're waiting for the handshake
* where the certificate is returned with the event - "secureConnect"
**/
});
/**
* Handle the handshake of the TLS connection
**/
client.on('secureConnect', function() {
// execute the items
testFunc(payload, {
address: options.host,
client: client
}, function(err) {
// did we get a error
if(err) assert.fail('Got a JS error from the rule');
// done
fn(null, payload);
try {
// close connection
client.close();
} catch(err) {}
});
})
/**
* Handle any errors that might come our way
**/
client.on('error', function( err ) {
// output the error
assert.fail('Problem connecting to remote host');
// throw back with our error
fn(err);
})
/**
* Handle the data to be sure we clear the buffer and don't hang
**/
client.resume();
});
};
// checks warnings that we check for
describe('chain', function() {
// disabled for now
return;
// handle the error output
it('Should return the missing error if we are missing a certificate from the chain', function(done) {
// the payload
var payload = passmarked.createPayload({
url: 'https://incomplete-chain.badssl.com/'
}, {}, null);
// build the options
execSecureConnection(payload, {
servername: 'incomplete-chain.badssl.com'
}, function(err) {
// did we get a error
if(err) assert.fail('Got a JS error from the rule');
// get the rules
var rules = payload.getRules();
// check for a missing certificate in the chain
var rule = _.find(rules || [], function(item) {
// check the rule key
return item.key === 'chain.missing';
});
// do we have a rule ?
if(!rule) assert.fail('Expected a error');
// done
done();
});
});
// handle the error output
it('Should not return a error if the chain is complete', function(done) {
// the payload
var payload = passmarked.createPayload({
url: 'https://badssl.com/'
}, {}, null);
// build the options
execSecureConnection(payload, {
servername: 'badssl.com'
}, function(err) {
// did we get a error
if(err) assert.fail('Got a JS error from the rule');
// get the rules
var rules = payload.getRules();
// check for a missing certificate in the chain
var rule = _.find(rules || [], function(item) {
// check the rule key
return item.key === 'chain.missing';
});
// do we have a rule ?
if(rule) assert.fail('Did not expect a error');
// done
done();
});
});
// handle the error output
it('Should give back the signature if is sha1', function(done) {
// the payload
var payload = passmarked.createPayload({
url: 'https://sha1-2016.badssl.com/'
}, {}, null);
// build the options
execSecureConnection(payload, {
servername: 'sha1-2016.badssl.com'
}, function(err) {
// did we get a error
if(err) assert.fail('Got a JS error from the rule');
// get the rules
var rules = payload.getRules();
// check for a missing certificate in the chain
var rule = _.find(rules || [], function(item) {
// check the rule key
return item.key === 'chain.weak';
});
// do we have a rule ?
if(!rule) assert.fail('Expected a error');
// done
done();
});
});
});