test: skip/replace weak crypto tests in FIPS mode
FIPS 140-2 does not permit the use of MD5 and RC4, skip or tests that use them, or substitute with stronger crypto where applicable. PR-URL: https://github.com/nodejs/node/pull/3757 Reviewed-By: Fedor Indutny <fedor@indutny.com> Reviewed-By: James Snell <jasnell@gmail.com> Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This commit is contained in:
parent
5900d14966
commit
e499ea849c
@ -324,12 +324,14 @@ var rfc2202_sha1 = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
|
for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
|
||||||
|
if (!common.hasFipsCrypto) {
|
||||||
assert.equal(rfc2202_md5[i]['hmac'],
|
assert.equal(rfc2202_md5[i]['hmac'],
|
||||||
crypto.createHmac('md5', rfc2202_md5[i]['key'])
|
crypto.createHmac('md5', rfc2202_md5[i]['key'])
|
||||||
.update(rfc2202_md5[i]['data'])
|
.update(rfc2202_md5[i]['data'])
|
||||||
.digest('hex'),
|
.digest('hex'),
|
||||||
'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
|
'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
|
for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
|
||||||
assert.equal(rfc2202_sha1[i]['hmac'],
|
assert.equal(rfc2202_sha1[i]['hmac'],
|
||||||
crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
|
crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
|
||||||
@ -339,15 +341,19 @@ for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test hashing
|
// Test hashing
|
||||||
var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
|
var a1 = crypto.createHash('sha1').update('Test123').digest('hex');
|
||||||
var a1 = crypto.createHash('md5').update('Test123').digest('binary');
|
|
||||||
var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
|
var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
|
||||||
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
|
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
|
||||||
var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
|
var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
|
||||||
|
|
||||||
assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
|
if (!common.hasFipsCrypto) {
|
||||||
assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
|
var a0 = crypto.createHash('md5').update('Test123').digest('binary');
|
||||||
|
assert.equal(a0, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
|
||||||
'\u00bd\u008c', 'Test MD5 as binary');
|
'\u00bd\u008c', 'Test MD5 as binary');
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
|
||||||
|
|
||||||
assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
|
assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
|
||||||
'Test SHA256 as base64');
|
'Test SHA256 as base64');
|
||||||
|
|
||||||
|
@ -11,8 +11,7 @@ if (!common.hasCrypto) {
|
|||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
|
||||||
// Test hashing
|
// Test hashing
|
||||||
var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
|
var a1 = crypto.createHash('sha1').update('Test123').digest('hex');
|
||||||
var a1 = crypto.createHash('md5').update('Test123').digest('binary');
|
|
||||||
var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
|
var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
|
||||||
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
|
var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
|
||||||
var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
|
var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
|
||||||
@ -38,9 +37,12 @@ a8.write('');
|
|||||||
a8.end();
|
a8.end();
|
||||||
a8 = a8.read();
|
a8 = a8.read();
|
||||||
|
|
||||||
assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
|
if (!common.hasFipsCrypto) {
|
||||||
assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
|
var a0 = crypto.createHash('md5').update('Test123').digest('binary');
|
||||||
|
assert.equal(a0, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
|
||||||
'\u00bd\u008c', 'Test MD5 as binary');
|
'\u00bd\u008c', 'Test MD5 as binary');
|
||||||
|
}
|
||||||
|
assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
|
||||||
assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
|
assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
|
||||||
'Test SHA256 as base64');
|
'Test SHA256 as base64');
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -61,6 +61,9 @@ var wikipedia = [
|
|||||||
|
|
||||||
for (var i = 0, l = wikipedia.length; i < l; i++) {
|
for (var i = 0, l = wikipedia.length; i < l; i++) {
|
||||||
for (var hash in wikipedia[i]['hmac']) {
|
for (var hash in wikipedia[i]['hmac']) {
|
||||||
|
// FIPS does not support MD5.
|
||||||
|
if (common.hasFipsCrypto && hash == 'md5' )
|
||||||
|
continue;
|
||||||
var result = crypto.createHmac(hash, wikipedia[i]['key'])
|
var result = crypto.createHmac(hash, wikipedia[i]['key'])
|
||||||
.update(wikipedia[i]['data'])
|
.update(wikipedia[i]['data'])
|
||||||
.digest('hex');
|
.digest('hex');
|
||||||
@ -346,6 +349,7 @@ var rfc2202_sha1 = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (!common.hasFipsCrypto) {
|
||||||
for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
|
for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
|
||||||
assert.equal(rfc2202_md5[i]['hmac'],
|
assert.equal(rfc2202_md5[i]['hmac'],
|
||||||
crypto.createHmac('md5', rfc2202_md5[i]['key'])
|
crypto.createHmac('md5', rfc2202_md5[i]['key'])
|
||||||
@ -353,6 +357,7 @@ for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
|
|||||||
.digest('hex'),
|
.digest('hex'),
|
||||||
'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
|
'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
|
for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
|
||||||
assert.equal(rfc2202_sha1[i]['hmac'],
|
assert.equal(rfc2202_sha1[i]['hmac'],
|
||||||
crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
|
crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
|
||||||
|
@ -26,6 +26,7 @@ Stream2buffer.prototype._write = function(data, encodeing, done) {
|
|||||||
return done(null);
|
return done(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!common.hasFipsCrypto) {
|
||||||
// Create an md5 hash of "Hallo world"
|
// Create an md5 hash of "Hallo world"
|
||||||
var hasher1 = crypto.createHash('md5');
|
var hasher1 = crypto.createHash('md5');
|
||||||
hasher1.pipe(new Stream2buffer(common.mustCall(function end(err, hash) {
|
hasher1.pipe(new Stream2buffer(common.mustCall(function end(err, hash) {
|
||||||
@ -39,6 +40,7 @@ crypto.createHash('md5').unpipe({});
|
|||||||
crypto.createHash('md5').setEncoding('utf8');
|
crypto.createHash('md5').setEncoding('utf8');
|
||||||
crypto.createHash('md5').pause();
|
crypto.createHash('md5').pause();
|
||||||
crypto.createHash('md5').resume();
|
crypto.createHash('md5').resume();
|
||||||
|
}
|
||||||
|
|
||||||
// Decipher._flush() should emit an error event, not an exception.
|
// Decipher._flush() should emit an error event, not an exception.
|
||||||
var key = new Buffer('48fb56eb10ffeb13fc0ef551bbca3b1b', 'hex'),
|
var key = new Buffer('48fb56eb10ffeb13fc0ef551bbca3b1b', 'hex'),
|
||||||
|
@ -14,7 +14,7 @@ var fs = require('fs');
|
|||||||
var options = {
|
var options = {
|
||||||
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
||||||
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
||||||
ciphers: '-ALL:ECDHE-RSA-RC4-SHA',
|
ciphers: '-ALL:ECDHE-RSA-AES128-SHA256',
|
||||||
ecdhCurve: 'prime256v1'
|
ecdhCurve: 'prime256v1'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ if (!common.hasCrypto) {
|
|||||||
var tls = require('tls');
|
var tls = require('tls');
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var cipher_list = ['RC4-SHA', 'AES256-SHA'];
|
var cipher_list = ['AES128-SHA256', 'AES256-SHA256'];
|
||||||
var cipher_version_pattern = /TLS|SSL/;
|
var cipher_version_pattern = /TLS|SSL/;
|
||||||
var options = {
|
var options = {
|
||||||
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
||||||
|
@ -19,7 +19,7 @@ var fs = require('fs');
|
|||||||
var options = {
|
var options = {
|
||||||
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
||||||
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
||||||
ciphers: 'RC4-MD5'
|
ciphers: 'DES-CBC3-SHA'
|
||||||
};
|
};
|
||||||
|
|
||||||
var reply = 'I AM THE WALRUS'; // something recognizable
|
var reply = 'I AM THE WALRUS'; // something recognizable
|
||||||
|
@ -20,27 +20,30 @@ assert.throws(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var hashes = {
|
var hashes = {
|
||||||
modp1 : 'b4b330a6ffeacfbd861e7fe2135b4431',
|
modp1 : '630e9acd2cc63f7e80d8507624ba60ac0757201a',
|
||||||
modp2 : '7c3c5cad8b9f378d88f1dd64a4b6413a',
|
modp2 : '18f7aa964484137f57bca64b21917a385b6a0b60',
|
||||||
modp5 : 'b1d2acc22c542e08669a5c5ae812694d',
|
modp5 : 'c0a8eec0c2c8a5ec2f9c26f9661eb339a010ec61',
|
||||||
modp14 : '8d041538cecc1a7d915ba4b718f8ad20',
|
modp14 : 'af5455606fe74cec49782bb374e4c63c9b1d132c',
|
||||||
modp15 : 'dc3b93def24e078c4fbf92d5e14ba69b',
|
modp15 : '7bdd39e5cdbb9748113933e5c2623b559c534e74',
|
||||||
modp16 : 'a273487f46f699461f613b3878d9dfd9',
|
modp16 : 'daea5277a7ad0116e734a8e0d2f297ef759d1161',
|
||||||
modp17 : 'dc76e09935310348c492de9bd82014d0',
|
modp17 : '3b62aaf0142c2720f0bf26a9589b0432c00eadc1',
|
||||||
modp18 : 'db08973bfd2371758a69db180871c993'
|
modp18 : 'a870b491bbbec9b131ae9878d07449d32e54f160'
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var name in hashes) {
|
for (var name in hashes) {
|
||||||
var group = crypto.getDiffieHellman(name);
|
var group = crypto.getDiffieHellman(name);
|
||||||
var private_key = group.getPrime('hex');
|
var private_key = group.getPrime('hex');
|
||||||
var hash1 = hashes[name];
|
var hash1 = hashes[name];
|
||||||
var hash2 = crypto.createHash('md5')
|
var hash2 = crypto.createHash('sha1')
|
||||||
.update(private_key.toUpperCase()).digest('hex');
|
.update(private_key.toUpperCase()).digest('hex');
|
||||||
assert.equal(hash1, hash2);
|
assert.equal(hash1, hash2);
|
||||||
assert.equal(group.getGenerator('hex'), '02');
|
assert.equal(group.getGenerator('hex'), '02');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var name in hashes) {
|
for (var name in hashes) {
|
||||||
|
// modp1 is 768 bits, FIPS requires >= 1024
|
||||||
|
if (name == 'modp1' && common.hasFipsCrypto)
|
||||||
|
continue;
|
||||||
var group1 = crypto.getDiffieHellman(name);
|
var group1 = crypto.getDiffieHellman(name);
|
||||||
var group2 = crypto.getDiffieHellman(name);
|
var group2 = crypto.getDiffieHellman(name);
|
||||||
group1.generateKeys();
|
group1.generateKeys();
|
||||||
|
@ -10,9 +10,10 @@ var tls = require('tls');
|
|||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var nconns = 0;
|
var nconns = 0;
|
||||||
// test only in TLSv1 to use DES which is no longer supported TLSv1.2
|
|
||||||
// to be safe when the default method is updated in the future
|
// We explicitly set TLS version to 1.2 so as to be safe when the
|
||||||
var SSL_Method = 'TLSv1_method';
|
// default method is updated in the future
|
||||||
|
var SSL_Method = 'TLSv1_2_method';
|
||||||
var localhost = '127.0.0.1';
|
var localhost = '127.0.0.1';
|
||||||
|
|
||||||
process.on('exit', function() {
|
process.on('exit', function() {
|
||||||
@ -24,7 +25,8 @@ function test(honorCipherOrder, clientCipher, expectedCipher, cb) {
|
|||||||
secureProtocol: SSL_Method,
|
secureProtocol: SSL_Method,
|
||||||
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
|
||||||
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
|
||||||
ciphers: 'DES-CBC-SHA:AES256-SHA:RC4-SHA:ECDHE-RSA-AES256-SHA',
|
ciphers: 'AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256:' +
|
||||||
|
'ECDHE-RSA-AES128-GCM-SHA256',
|
||||||
honorCipherOrder: !!honorCipherOrder
|
honorCipherOrder: !!honorCipherOrder
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,37 +59,40 @@ test1();
|
|||||||
|
|
||||||
function test1() {
|
function test1() {
|
||||||
// Client has the preference of cipher suites by default
|
// Client has the preference of cipher suites by default
|
||||||
test(false, 'AES256-SHA:DES-CBC-SHA:RC4-SHA', 'AES256-SHA', test2);
|
test(false, 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
|
||||||
|
'AES128-GCM-SHA256', test2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test2() {
|
function test2() {
|
||||||
// Server has the preference of cipher suites where DES-CBC-SHA is in
|
// Server has the preference of cipher suites, and AES256-SHA256 is
|
||||||
// the first.
|
// the server's top choice.
|
||||||
test(true, 'AES256-SHA:DES-CBC-SHA:RC4-SHA', 'DES-CBC-SHA', test3);
|
test(true, 'AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256',
|
||||||
|
'AES256-SHA256', test3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test3() {
|
function test3() {
|
||||||
// Server has the preference of cipher suites. RC4-SHA is given
|
// Server has the preference of cipher suites. AES128-GCM-SHA256 is given
|
||||||
// higher priority over DES-CBC-SHA among client cipher suites.
|
// higher priority over AES128-SHA256 among client cipher suites.
|
||||||
test(true, 'RC4-SHA:AES256-SHA', 'AES256-SHA', test4);
|
test(true, 'AES128-SHA256:AES128-GCM-SHA256', 'AES128-GCM-SHA256', test4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test4() {
|
function test4() {
|
||||||
// As client has only one cipher, server has no choice in regardless
|
// As client has only one cipher, server has no choice, irrespective
|
||||||
// of honorCipherOrder.
|
// of honorCipherOrder.
|
||||||
test(true, 'RC4-SHA', 'RC4-SHA', test5);
|
test(true, 'AES128-SHA256', 'AES128-SHA256', test5);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test5() {
|
function test5() {
|
||||||
// Client did not explicitly set ciphers. Ensure that client defaults to
|
// Client did not explicitly set ciphers and client offers
|
||||||
// sane ciphers. Even though server gives top priority to DES-CBC-SHA
|
// tls.DEFAULT_CIPHERS. All ciphers of the server are included in the
|
||||||
// it should not be negotiated because it's not in default client ciphers.
|
// default list so the negotiated cipher is selected according to the
|
||||||
test(true, null, 'AES256-SHA', test6);
|
// server's top preference of AES256-SHA256.
|
||||||
|
test(true, null, 'AES256-SHA256', test6);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test6() {
|
function test6() {
|
||||||
// Ensure that `tls.DEFAULT_CIPHERS` is used
|
// Ensure that `tls.DEFAULT_CIPHERS` is used
|
||||||
SSL_Method = 'TLSv1_2_method';
|
tls.DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-GCM-SHA256';
|
||||||
tls.DEFAULT_CIPHERS = 'ECDHE-RSA-AES256-SHA';
|
test(true, null, 'ECDHE-RSA-AES128-GCM-SHA256');
|
||||||
test(true, null, 'ECDHE-RSA-AES256-SHA');
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user