From 498a189e8a8796477ca05f88881b3d5bbe7a1639 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 31 2016 08:44:37 +0000 Subject: import rh-nodejs4-nodejs-4.4.2-1.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eacc019 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/node-v4.4.2-stripped.tar.gz diff --git a/.rh-nodejs4-nodejs.metadata b/.rh-nodejs4-nodejs.metadata new file mode 100644 index 0000000..88f383e --- /dev/null +++ b/.rh-nodejs4-nodejs.metadata @@ -0,0 +1 @@ +1f266af65dfa2ff097501fc04836109df09d976c SOURCES/node-v4.4.2-stripped.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 98f42b4..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/nodejs-disable-crypto-tests.patch b/SOURCES/nodejs-disable-crypto-tests.patch new file mode 100644 index 0000000..6bc0434 --- /dev/null +++ b/SOURCES/nodejs-disable-crypto-tests.patch @@ -0,0 +1,4688 @@ +--- + test/disabled/test-crypto-authenticated.js | 177 +++++++ + test/disabled/test-crypto-binary-default.js | 666 +++++++++++++++++++++++++ + test/disabled/test-crypto-cipher-decipher.js | 115 +++++ + test/disabled/test-crypto-dh-odd-key.js | 25 + + test/disabled/test-crypto.js | 143 ++++++ + test/disabled/test-net-connect-options-ipv6.js | 70 +++ + test/disabled/test-npm-install.js | 47 ++ + test/disabled/test-stdout-close-unref.js | 16 + + test/disabled/test-tls-cnnic-whitelist.js | 83 +++ + test/disabled/test-tls-dhe.js | 95 ++++ + test/disabled/test-tls-ecdh-disable.js | 46 ++ + test/disabled/test-tls-ecdh.js | 48 ++ + test/disabled/test-tls-js-stream.js | 76 +++ + test/disabled/test-tls-ocsp-callback.js | 130 +++++ + test/disabled/test-tls-pfx-gh-5100-regr.js | 36 ++ + test/disabled/test-tls-securepair-server.js | 138 +++++ + test/disabled/test-tls-sni-option.js | 169 +++++++ + test/disabled/test-tls-sni-server-client.js | 117 +++++ + test/parallel/test-crypto-authenticated.js | 177 ------- + test/parallel/test-crypto-binary-default.js | 666 ------------------------- + test/parallel/test-crypto-cipher-decipher.js | 115 ----- + test/parallel/test-crypto-dh-odd-key.js | 25 - + test/parallel/test-crypto.js | 143 ------ + test/parallel/test-net-connect-options-ipv6.js | 70 --- + test/parallel/test-npm-install.js | 47 -- + test/parallel/test-stdout-close-unref.js | 16 - + test/parallel/test-tls-cnnic-whitelist.js | 83 --- + test/parallel/test-tls-dhe.js | 95 ---- + test/parallel/test-tls-ecdh-disable.js | 46 -- + test/parallel/test-tls-ecdh.js | 48 -- + test/parallel/test-tls-js-stream.js | 76 --- + test/parallel/test-tls-ocsp-callback.js | 130 ----- + test/parallel/test-tls-pfx-gh-5100-regr.js | 36 -- + test/parallel/test-tls-securepair-server.js | 138 ----- + test/parallel/test-tls-sni-option.js | 169 ------- + test/parallel/test-tls-sni-server-client.js | 117 ----- + 36 files changed, 2197 insertions(+), 2197 deletions(-) + create mode 100644 test/disabled/test-crypto-authenticated.js + create mode 100644 test/disabled/test-crypto-binary-default.js + create mode 100644 test/disabled/test-crypto-cipher-decipher.js + create mode 100644 test/disabled/test-crypto-dh-odd-key.js + create mode 100644 test/disabled/test-crypto.js + create mode 100644 test/disabled/test-net-connect-options-ipv6.js + create mode 100644 test/disabled/test-npm-install.js + create mode 100644 test/disabled/test-stdout-close-unref.js + create mode 100644 test/disabled/test-tls-cnnic-whitelist.js + create mode 100644 test/disabled/test-tls-dhe.js + create mode 100644 test/disabled/test-tls-ecdh-disable.js + create mode 100644 test/disabled/test-tls-ecdh.js + create mode 100644 test/disabled/test-tls-js-stream.js + create mode 100644 test/disabled/test-tls-ocsp-callback.js + create mode 100644 test/disabled/test-tls-pfx-gh-5100-regr.js + create mode 100644 test/disabled/test-tls-securepair-server.js + create mode 100644 test/disabled/test-tls-sni-option.js + create mode 100644 test/disabled/test-tls-sni-server-client.js + delete mode 100644 test/parallel/test-crypto-authenticated.js + delete mode 100644 test/parallel/test-crypto-binary-default.js + delete mode 100644 test/parallel/test-crypto-cipher-decipher.js + delete mode 100644 test/parallel/test-crypto-dh-odd-key.js + delete mode 100644 test/parallel/test-crypto.js + delete mode 100644 test/parallel/test-net-connect-options-ipv6.js + delete mode 100644 test/parallel/test-npm-install.js + delete mode 100644 test/parallel/test-stdout-close-unref.js + delete mode 100644 test/parallel/test-tls-cnnic-whitelist.js + delete mode 100644 test/parallel/test-tls-dhe.js + delete mode 100644 test/parallel/test-tls-ecdh-disable.js + delete mode 100644 test/parallel/test-tls-ecdh.js + delete mode 100644 test/parallel/test-tls-js-stream.js + delete mode 100644 test/parallel/test-tls-ocsp-callback.js + delete mode 100644 test/parallel/test-tls-pfx-gh-5100-regr.js + delete mode 100644 test/parallel/test-tls-securepair-server.js + delete mode 100644 test/parallel/test-tls-sni-option.js + delete mode 100644 test/parallel/test-tls-sni-server-client.js + +diff --git a/test/disabled/test-crypto-authenticated.js b/test/disabled/test-crypto-authenticated.js +new file mode 100644 +index 0000000..fa9a78c +--- /dev/null ++++ b/test/disabled/test-crypto-authenticated.js +@@ -0,0 +1,177 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var crypto = require('crypto'); ++ ++crypto.DEFAULT_ENCODING = 'buffer'; ++ ++// ++// Test authenticated encryption modes. ++// ++// !NEVER USE STATIC IVs IN REAL LIFE! ++// ++ ++var TEST_CASES = [ ++ { algo: 'aes-128-gcm', ++ key: '6970787039613669314d623455536234', ++ iv: '583673497131313748307652', plain: 'Hello World!', ++ ct: '4BE13896F64DFA2C2D0F2C76', ++ tag: '272B422F62EB545EAA15B5FF84092447', tampered: false }, ++ { algo: 'aes-128-gcm', ++ key: '6970787039613669314d623455536234', ++ iv: '583673497131313748307652', plain: 'Hello World!', ++ ct: '4BE13896F64DFA2C2D0F2C76', aad: '000000FF', ++ tag: 'BA2479F66275665A88CB7B15F43EB005', tampered: false }, ++ { algo: 'aes-128-gcm', ++ key: '6970787039613669314d623455536234', ++ iv: '583673497131313748307652', plain: 'Hello World!', ++ ct: '4BE13596F64DFA2C2D0FAC76', ++ tag: '272B422F62EB545EAA15B5FF84092447', tampered: true }, ++ { algo: 'aes-256-gcm', ++ key: '337a54767a7233703637564336316a6d56353472495975313534357834546c59', ++ iv: '36306950306836764a6f4561', plain: 'Hello node.js world!', ++ ct: '58E62CFE7B1D274111A82267EBB93866E72B6C2A', ++ tag: '9BB44F663BADABACAE9720881FB1EC7A', tampered: false }, ++ { algo: 'aes-256-gcm', ++ key: '337a54767a7233703637564336316a6d56353472495975313534357834546c59', ++ iv: '36306950306836764a6f4561', plain: 'Hello node.js world!', ++ ct: '58E62CFF7B1D274011A82267EBB93866E72B6C2B', ++ tag: '9BB44F663BADABACAE9720881FB1EC7A', tampered: true }, ++ { algo: 'aes-192-gcm', ++ key: '1ed2233fa2223ef5d7df08546049406c7305220bca40d4c9', ++ iv: '0e1791e9db3bd21a9122c416', plain: 'Hello node.js world!', ++ password: 'very bad password', aad: '63616c76696e', ++ ct: 'DDA53A4059AA17B88756984995F7BBA3C636CC44', ++ tag: 'D2A35E5C611E5E3D2258360241C5B045', tampered: false } ++]; ++ ++var ciphers = crypto.getCiphers(); ++ ++for (var i in TEST_CASES) { ++ var test = TEST_CASES[i]; ++ ++ if (ciphers.indexOf(test.algo) == -1) { ++ console.log('1..0 # Skipped: unsupported ' + test.algo + ' test'); ++ continue; ++ } ++ ++ (function() { ++ var encrypt = crypto.createCipheriv(test.algo, ++ new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); ++ if (test.aad) ++ encrypt.setAAD(new Buffer(test.aad, 'hex')); ++ var hex = encrypt.update(test.plain, 'ascii', 'hex'); ++ hex += encrypt.final('hex'); ++ var auth_tag = encrypt.getAuthTag(); ++ // only test basic encryption run if output is marked as tampered. ++ if (!test.tampered) { ++ assert.equal(hex.toUpperCase(), test.ct); ++ assert.equal(auth_tag.toString('hex').toUpperCase(), test.tag); ++ } ++ })(); ++ ++ (function() { ++ var decrypt = crypto.createDecipheriv(test.algo, ++ new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); ++ decrypt.setAuthTag(new Buffer(test.tag, 'hex')); ++ if (test.aad) ++ decrypt.setAAD(new Buffer(test.aad, 'hex')); ++ var msg = decrypt.update(test.ct, 'hex', 'ascii'); ++ if (!test.tampered) { ++ msg += decrypt.final('ascii'); ++ assert.equal(msg, test.plain); ++ } else { ++ // assert that final throws if input data could not be verified! ++ assert.throws(function() { decrypt.final('ascii'); }, / auth/); ++ } ++ })(); ++ ++ (function() { ++ if (!test.password) return; ++ if (common.hasFipsCrypto) { ++ assert.throws(function() ++ { crypto.createCipher(test.algo, test.password); }, ++ /not supported in FIPS mode/); ++ } else { ++ var encrypt = crypto.createCipher(test.algo, test.password); ++ if (test.aad) ++ encrypt.setAAD(new Buffer(test.aad, 'hex')); ++ var hex = encrypt.update(test.plain, 'ascii', 'hex'); ++ hex += encrypt.final('hex'); ++ var auth_tag = encrypt.getAuthTag(); ++ // only test basic encryption run if output is marked as tampered. ++ if (!test.tampered) { ++ assert.equal(hex.toUpperCase(), test.ct); ++ assert.equal(auth_tag.toString('hex').toUpperCase(), test.tag); ++ } ++ } ++ })(); ++ ++ (function() { ++ if (!test.password) return; ++ if (common.hasFipsCrypto) { ++ assert.throws(function() ++ { crypto.createDecipher(test.algo, test.password); }, ++ /not supported in FIPS mode/); ++ } else { ++ var decrypt = crypto.createDecipher(test.algo, test.password); ++ decrypt.setAuthTag(new Buffer(test.tag, 'hex')); ++ if (test.aad) ++ decrypt.setAAD(new Buffer(test.aad, 'hex')); ++ var msg = decrypt.update(test.ct, 'hex', 'ascii'); ++ if (!test.tampered) { ++ msg += decrypt.final('ascii'); ++ assert.equal(msg, test.plain); ++ } else { ++ // assert that final throws if input data could not be verified! ++ assert.throws(function() { decrypt.final('ascii'); }, / auth/); ++ } ++ } ++ })(); ++ ++ // after normal operation, test some incorrect ways of calling the API: ++ // it's most certainly enough to run these tests with one algorithm only. ++ ++ if (i > 0) { ++ continue; ++ } ++ ++ (function() { ++ // non-authenticating mode: ++ var encrypt = crypto.createCipheriv('aes-128-cbc', ++ 'ipxp9a6i1Mb4USb4', '6fKjEjR3Vl30EUYC'); ++ encrypt.update('blah', 'ascii'); ++ encrypt.final(); ++ assert.throws(function() { encrypt.getAuthTag(); }, / state/); ++ assert.throws(function() { ++ encrypt.setAAD(new Buffer('123', 'ascii')); }, / state/); ++ })(); ++ ++ (function() { ++ // trying to get tag before inputting all data: ++ var encrypt = crypto.createCipheriv(test.algo, ++ new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); ++ encrypt.update('blah', 'ascii'); ++ assert.throws(function() { encrypt.getAuthTag(); }, / state/); ++ })(); ++ ++ (function() { ++ // trying to set tag on encryption object: ++ var encrypt = crypto.createCipheriv(test.algo, ++ new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); ++ assert.throws(function() { ++ encrypt.setAuthTag(new Buffer(test.tag, 'hex')); }, / state/); ++ })(); ++ ++ (function() { ++ // trying to read tag from decryption object: ++ var decrypt = crypto.createDecipheriv(test.algo, ++ new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); ++ assert.throws(function() { decrypt.getAuthTag(); }, / state/); ++ })(); ++} +diff --git a/test/disabled/test-crypto-binary-default.js b/test/disabled/test-crypto-binary-default.js +new file mode 100644 +index 0000000..6418f52 +--- /dev/null ++++ b/test/disabled/test-crypto-binary-default.js +@@ -0,0 +1,666 @@ ++'use strict'; ++// This is the same as test/simple/test-crypto, but from before the shift ++// to use buffers by default. ++ ++ ++var common = require('../common'); ++var assert = require('assert'); ++var constants = require('constants'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var crypto = require('crypto'); ++var tls = require('tls'); ++ ++crypto.DEFAULT_ENCODING = 'binary'; ++ ++var fs = require('fs'); ++var path = require('path'); ++ ++// Test Certificates ++var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); ++var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx'); ++var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); ++var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem', ++ 'ascii'); ++var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem', ++ 'ascii'); ++ ++// PFX tests ++assert.doesNotThrow(function() { ++ tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); ++}); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:certPfx}); ++}, 'mac verify failure'); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:certPfx, passphrase:'test'}); ++}, 'mac verify failure'); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:'sample', passphrase:'test'}); ++}, 'not enough data'); ++ ++// Test HMAC ++const hmacHash = crypto.createHmac('sha1', 'Node') ++ .update('some data') ++ .update('to hmac') ++ .digest('hex'); ++assert.equal(hmacHash, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', 'test HMAC'); ++ ++// Test HMAC-SHA-* (rfc 4231 Test Cases) ++var rfc4231 = [ ++ { ++ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), ++ data: new Buffer('4869205468657265', 'hex'), // 'Hi There' ++ hmac: { ++ sha224: '896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22', ++ sha256: ++ 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c' + ++ '2e32cff7', ++ sha384: ++ 'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c' + ++ '7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6', ++ sha512: ++ '87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b305' + ++ '45e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f170' + ++ '2e696c203a126854' ++ } ++ }, ++ { ++ key: new Buffer('4a656665', 'hex'), // 'Jefe' ++ data: new Buffer('7768617420646f2079612077616e7420666f72206e6f74686' + ++ '96e673f', 'hex'), // 'what do ya want for nothing?' ++ hmac: { ++ sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44', ++ sha256: ++ '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b9' + ++ '64ec3843', ++ sha384: ++ 'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec373' + ++ '6322445e8e2240ca5e69e2c78b3239ecfab21649', ++ sha512: ++ '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7' + ++ 'ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b' + ++ '636e070a38bce737' ++ } ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), ++ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' + ++ 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', ++ 'hex'), ++ hmac: { ++ sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea', ++ sha256: ++ '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514' + ++ 'ced565fe', ++ sha384: ++ '88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e5' + ++ '5966144b2a5ab39dc13814b94e3ab6e101a34f27', ++ sha512: ++ 'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33' + ++ 'b2279d39bf3e848279a722c806b485a47e67c807b946a337bee89426' + ++ '74278859e13292fb' ++ } ++ }, ++ { ++ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', ++ 'hex'), ++ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + ++ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', ++ 'hex'), ++ hmac: { ++ sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a', ++ sha256: ++ '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff4' + ++ '6729665b', ++ sha384: ++ '3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e' + ++ '1f573b4e6801dd23c4a7d679ccf8a386c674cffb', ++ sha512: ++ 'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050' + ++ '361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2d' + ++ 'e2adebeb10a298dd' ++ } ++ }, ++ ++ { ++ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), ++ // 'Test With Truncation' ++ data: new Buffer('546573742057697468205472756e636174696f6e', 'hex'), ++ hmac: { ++ sha224: '0e2aea68a90c8d37c988bcdb9fca6fa8', ++ sha256: 'a3b6167473100ee06e0c796c2955552b', ++ sha384: '3abf34c3503b2a23a46efc619baef897', ++ sha512: '415fad6271580a531d4179bc891d87a6' ++ }, ++ truncate: true ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaa', 'hex'), ++ // 'Test Using Larger Than Block-Size Key - Hash Key First' ++ data: new Buffer('54657374205573696e67204c6172676572205468616e20426' + ++ 'c6f636b2d53697a65204b6579202d2048617368204b657920' + ++ '4669727374', 'hex'), ++ hmac: { ++ sha224: '95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e', ++ sha256: ++ '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f' + ++ '0ee37f54', ++ sha384: ++ '4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05' + ++ '033ac4c60c2ef6ab4030fe8296248df163f44952', ++ sha512: ++ '80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b0137' + ++ '83f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec' + ++ '8b915a985d786598' ++ } ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaa', 'hex'), ++ // 'This is a test using a larger than block-size key and a larger ' + ++ // 'than block-size data. The key needs to be hashed before being ' + ++ // 'used by the HMAC algorithm.' ++ data: new Buffer('5468697320697320612074657374207573696e672061206c6' + ++ '172676572207468616e20626c6f636b2d73697a65206b6579' + ++ '20616e642061206c6172676572207468616e20626c6f636b2' + ++ 'd73697a6520646174612e20546865206b6579206e65656473' + ++ '20746f20626520686173686564206265666f7265206265696' + ++ 'e6720757365642062792074686520484d414320616c676f72' + ++ '6974686d2e', 'hex'), ++ hmac: { ++ sha224: '3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1', ++ sha256: ++ '9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f5153' + ++ '5c3a35e2', ++ sha384: ++ '6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82' + ++ '461e99c5a678cc31e799176d3860e6110c46523e', ++ sha512: ++ 'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d' + ++ '20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de04460' + ++ '65c97440fa8c6a58' ++ } ++ } ++]; ++ ++for (let i = 0, l = rfc4231.length; i < l; i++) { ++ for (var hash in rfc4231[i]['hmac']) { ++ var result = crypto.createHmac(hash, rfc4231[i]['key']) ++ .update(rfc4231[i]['data']) ++ .digest('hex'); ++ if (rfc4231[i]['truncate']) { ++ result = result.substr(0, 32); // first 128 bits == 32 hex chars ++ } ++ assert.equal(rfc4231[i]['hmac'][hash], ++ result, ++ 'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' rfc 4231'); ++ } ++} ++ ++// Test HMAC-MD5/SHA1 (rfc 2202 Test Cases) ++var rfc2202_md5 = [ ++ { ++ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), ++ data: 'Hi There', ++ hmac: '9294727a3638bb1c13f48ef8158bfc9d' ++ }, ++ { ++ key: 'Jefe', ++ data: 'what do ya want for nothing?', ++ hmac: '750c783e6ab0b503eaa86e310a5db738' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), ++ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' + ++ 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', ++ 'hex'), ++ hmac: '56be34521d144c88dbb8c733f0e8b3f6' ++ }, ++ { ++ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', ++ 'hex'), ++ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + ++ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + ++ 'cdcdcdcdcd', ++ 'hex'), ++ hmac: '697eaf0aca3a3aea3a75164746ffaa79' ++ }, ++ { ++ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), ++ data: 'Test With Truncation', ++ hmac: '56461ef2342edc00f9bab995690efd4c' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaa', ++ 'hex'), ++ data: 'Test Using Larger Than Block-Size Key - Hash Key First', ++ hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaa', ++ 'hex'), ++ data: ++ 'Test Using Larger Than Block-Size Key and Larger Than One ' + ++ 'Block-Size Data', ++ hmac: '6f630fad67cda0ee1fb1f562db3aa53e' ++ } ++]; ++var rfc2202_sha1 = [ ++ { ++ key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), ++ data: 'Hi There', ++ hmac: 'b617318655057264e28bc0b6fb378c8ef146be00' ++ }, ++ { ++ key: 'Jefe', ++ data: 'what do ya want for nothing?', ++ hmac: 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), ++ data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddd' + ++ 'ddddddddddddddddddddddddddddddddddddddddddddd' + ++ 'dddddddddd', ++ 'hex'), ++ hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3' ++ }, ++ { ++ key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', ++ 'hex'), ++ data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + ++ 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + ++ 'cdcdcdcdcd', ++ 'hex'), ++ hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da' ++ }, ++ { ++ key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), ++ data: 'Test With Truncation', ++ hmac: '4c1a03424b55e07fe7f27be1d58bb9324a9a5a04' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaa', ++ 'hex'), ++ data: 'Test Using Larger Than Block-Size Key - Hash Key First', ++ hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112' ++ }, ++ { ++ key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + ++ 'aaaaaaaaaaaaaaaaaaaaaa', ++ 'hex'), ++ data: ++ 'Test Using Larger Than Block-Size Key and Larger Than One ' + ++ 'Block-Size Data', ++ hmac: 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91' ++ } ++]; ++ ++for (let i = 0, l = rfc2202_md5.length; i < l; i++) { ++ if (!common.hasFipsCrypto) { ++ assert.equal(rfc2202_md5[i]['hmac'], ++ crypto.createHmac('md5', rfc2202_md5[i]['key']) ++ .update(rfc2202_md5[i]['data']) ++ .digest('hex'), ++ 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202'); ++ } ++} ++for (let i = 0, l = rfc2202_sha1.length; i < l; i++) { ++ assert.equal(rfc2202_sha1[i]['hmac'], ++ crypto.createHmac('sha1', rfc2202_sha1[i]['key']) ++ .update(rfc2202_sha1[i]['data']) ++ .digest('hex'), ++ 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202'); ++} ++ ++// Test hashing ++var a1 = crypto.createHash('sha1').update('Test123').digest('hex'); ++var a2 = crypto.createHash('sha256').update('Test123').digest('base64'); ++var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary ++var a4 = crypto.createHash('sha1').update('Test123').digest('buffer'); ++ ++if (!common.hasFipsCrypto) { ++ 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'); ++} ++ ++assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1'); ++ ++assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=', ++ 'Test SHA256 as base64'); ++ ++assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' + ++ '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' + ++ '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' + ++ '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' + ++ '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'', ++ 'Test SHA512 as assumed binary'); ++ ++assert.deepEqual(a4, ++ new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'), ++ 'Test SHA1'); ++ ++// Test multiple updates to same hash ++var h1 = crypto.createHash('sha1').update('Test123').digest('hex'); ++var h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex'); ++assert.equal(h1, h2, 'multipled updates'); ++ ++// Test hashing for binary files ++var fn = path.join(common.fixturesDir, 'sample.png'); ++var sha1Hash = crypto.createHash('sha1'); ++var fileStream = fs.createReadStream(fn); ++fileStream.on('data', function(data) { ++ sha1Hash.update(data); ++}); ++fileStream.on('close', function() { ++ assert.equal(sha1Hash.digest('hex'), ++ '22723e553129a336ad96e10f6aecdf0f45e4149e', ++ 'Test SHA1 of sample.png'); ++}); ++ ++// Issue #2227: unknown digest method should throw an error. ++assert.throws(function() { ++ crypto.createHash('xyzzy'); ++}); ++ ++// Test signing and verifying ++var s1 = crypto.createSign('RSA-SHA1') ++ .update('Test123') ++ .sign(keyPem, 'base64'); ++var s1Verified = crypto.createVerify('RSA-SHA1') ++ .update('Test') ++ .update('123') ++ .verify(certPem, s1, 'base64'); ++assert.strictEqual(s1Verified, true, 'sign and verify (base 64)'); ++ ++var s2 = crypto.createSign('RSA-SHA256') ++ .update('Test123') ++ .sign(keyPem); // binary ++var s2Verified = crypto.createVerify('RSA-SHA256') ++ .update('Test') ++ .update('123') ++ .verify(certPem, s2); // binary ++assert.strictEqual(s2Verified, true, 'sign and verify (binary)'); ++ ++var s3 = crypto.createSign('RSA-SHA1') ++ .update('Test123') ++ .sign(keyPem, 'buffer'); ++var s3Verified = crypto.createVerify('RSA-SHA1') ++ .update('Test') ++ .update('123') ++ .verify(certPem, s3); ++assert.strictEqual(s3Verified, true, 'sign and verify (buffer)'); ++ ++ ++function testCipher1(key) { ++ // Test encryption and decryption ++ var plaintext = 'Keep this a secret? No! Tell everyone about node.js!'; ++ var cipher = crypto.createCipher('aes192', key); ++ ++ // encrypt plaintext which is in utf8 format ++ // to a ciphertext which will be in hex ++ var ciph = cipher.update(plaintext, 'utf8', 'hex'); ++ // Only use binary or hex, not base64. ++ ciph += cipher.final('hex'); ++ ++ var decipher = crypto.createDecipher('aes192', key); ++ var txt = decipher.update(ciph, 'hex', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption'); ++} ++ ++ ++function testCipher2(key) { ++ // encryption and decryption with Base64 ++ // reported in https://github.com/joyent/node/issues/738 ++ var plaintext = ++ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + ++ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + ++ 'jAfaFg**'; ++ var cipher = crypto.createCipher('aes256', key); ++ ++ // encrypt plaintext which is in utf8 format ++ // to a ciphertext which will be in Base64 ++ var ciph = cipher.update(plaintext, 'utf8', 'base64'); ++ ciph += cipher.final('base64'); ++ ++ var decipher = crypto.createDecipher('aes256', key); ++ var txt = decipher.update(ciph, 'base64', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption with Base64'); ++} ++ ++ ++function testCipher3(key, iv) { ++ // Test encyrption and decryption with explicit key and iv ++ var plaintext = ++ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + ++ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + ++ 'jAfaFg**'; ++ var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); ++ var ciph = cipher.update(plaintext, 'utf8', 'hex'); ++ ciph += cipher.final('hex'); ++ ++ var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); ++ var txt = decipher.update(ciph, 'hex', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption with key and iv'); ++} ++ ++ ++function testCipher4(key, iv) { ++ // Test encyrption and decryption with explicit key and iv ++ var plaintext = ++ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + ++ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + ++ 'jAfaFg**'; ++ var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); ++ var ciph = cipher.update(plaintext, 'utf8', 'buffer'); ++ ciph = Buffer.concat([ciph, cipher.final('buffer')]); ++ ++ var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); ++ var txt = decipher.update(ciph, 'buffer', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption with key and iv'); ++} ++ ++if (!common.hasFipsCrypto) { ++ testCipher1('MySecretKey123'); ++ testCipher1(new Buffer('MySecretKey123')); ++ ++ testCipher2('0123456789abcdef'); ++ testCipher2(new Buffer('0123456789abcdef')); ++} ++ ++testCipher3('0123456789abcd0123456789', '12345678'); ++testCipher3('0123456789abcd0123456789', new Buffer('12345678')); ++testCipher3(new Buffer('0123456789abcd0123456789'), '12345678'); ++testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678')); ++ ++testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678')); ++ ++ ++// update() should only take buffers / strings ++assert.throws(function() { ++ crypto.createHash('sha1').update({foo: 'bar'}); ++}, /buffer/); ++ ++ ++// Test Diffie-Hellman with two parties sharing a secret, ++// using various encodings as we go along ++var dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); ++var p1 = dh1.getPrime('buffer'); ++var dh2 = crypto.createDiffieHellman(p1, 'base64'); ++var key1 = dh1.generateKeys(); ++var key2 = dh2.generateKeys('hex'); ++var secret1 = dh1.computeSecret(key2, 'hex', 'base64'); ++var secret2 = dh2.computeSecret(key1, 'binary', 'buffer'); ++ ++assert.equal(secret1, secret2.toString('base64')); ++ ++// Create "another dh1" using generated keys from dh1, ++// and compute secret again ++var dh3 = crypto.createDiffieHellman(p1, 'buffer'); ++var privkey1 = dh1.getPrivateKey(); ++dh3.setPublicKey(key1); ++dh3.setPrivateKey(privkey1); ++ ++assert.equal(dh1.getPrime(), dh3.getPrime()); ++assert.equal(dh1.getGenerator(), dh3.getGenerator()); ++assert.equal(dh1.getPublicKey(), dh3.getPublicKey()); ++assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey()); ++ ++var secret3 = dh3.computeSecret(key2, 'hex', 'base64'); ++ ++assert.equal(secret1, secret3); ++ ++// https://github.com/joyent/node/issues/2338 ++var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + ++ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' + ++ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + ++ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; ++var d = crypto.createDiffieHellman(p, 'hex'); ++assert.equal(d.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++// Test RSA key signing/verification ++var rsaSign = crypto.createSign('RSA-SHA1'); ++var rsaVerify = crypto.createVerify('RSA-SHA1'); ++assert.ok(rsaSign); ++assert.ok(rsaVerify); ++ ++rsaSign.update(rsaPubPem); ++var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex'); ++assert.equal(rsaSignature, ++ '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' + ++ '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' + ++ 'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' + ++ '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' + ++ '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6'); ++ ++rsaVerify.update(rsaPubPem); ++assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); ++ ++ ++// ++// Test RSA signing and verification ++// ++(function() { ++ var privateKey = fs.readFileSync( ++ common.fixturesDir + '/test_rsa_privkey_2.pem'); ++ ++ var publicKey = fs.readFileSync( ++ common.fixturesDir + '/test_rsa_pubkey_2.pem'); ++ ++ var input = 'I AM THE WALRUS'; ++ ++ var signature = ++ '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89' + ++ '396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa' + ++ '235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb2' + ++ '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' + ++ '0ddfb299bedeb1ad'; ++ ++ var sign = crypto.createSign('RSA-SHA256'); ++ sign.update(input); ++ ++ var output = sign.sign(privateKey, 'hex'); ++ assert.equal(output, signature); ++ ++ var verify = crypto.createVerify('RSA-SHA256'); ++ verify.update(input); ++ ++ assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); ++})(); ++ ++ ++// ++// Test DSA signing and verification ++// ++(function() { ++ var privateKey = fs.readFileSync( ++ common.fixturesDir + '/test_dsa_privkey.pem'); ++ ++ var publicKey = fs.readFileSync( ++ common.fixturesDir + '/test_dsa_pubkey.pem'); ++ ++ var input = 'I AM THE WALRUS'; ++ ++ // DSA signatures vary across runs so there is no static string to verify ++ // against ++ var sign = crypto.createSign('DSS1'); ++ sign.update(input); ++ var signature = sign.sign(privateKey, 'hex'); ++ ++ var verify = crypto.createVerify('DSS1'); ++ verify.update(input); ++ ++ assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); ++})(); ++ ++ ++// ++// Test PBKDF2 with RFC 6070 test vectors (except #4) ++// ++function testPBKDF2(password, salt, iterations, keylen, expected) { ++ var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen); ++ assert.equal(actual, expected); ++ ++ crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) { ++ assert.equal(actual, expected); ++ }); ++} ++ ++ ++testPBKDF2('password', 'salt', 1, 20, ++ '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' + ++ '\xaf\x60\x12\x06\x2f\xe0\x37\xa6'); ++ ++testPBKDF2('password', 'salt', 2, 20, ++ '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' + ++ '\xce\x1d\x41\xf0\xd8\xde\x89\x57'); ++ ++testPBKDF2('password', 'salt', 4096, 20, ++ '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' + ++ '\xf7\x21\xd0\x65\xa4\x29\xc1'); ++ ++testPBKDF2('passwordPASSWORDpassword', ++ 'saltSALTsaltSALTsaltSALTsaltSALTsalt', ++ 4096, ++ 25, ++ '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' + ++ '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38'); ++ ++testPBKDF2('pass\0word', 'sa\0lt', 4096, 16, ++ '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' + ++ '\x25\xe0\xc3'); +diff --git a/test/disabled/test-crypto-cipher-decipher.js b/test/disabled/test-crypto-cipher-decipher.js +new file mode 100644 +index 0000000..5f86773 +--- /dev/null ++++ b/test/disabled/test-crypto-cipher-decipher.js +@@ -0,0 +1,115 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++if (common.hasFipsCrypto) { ++ console.log('1..0 # Skipped: not supported in FIPS mode'); ++ return; ++} ++var crypto = require('crypto'); ++ ++function testCipher1(key) { ++ // Test encryption and decryption ++ var plaintext = 'Keep this a secret? No! Tell everyone about node.js!'; ++ var cipher = crypto.createCipher('aes192', key); ++ ++ // encrypt plaintext which is in utf8 format ++ // to a ciphertext which will be in hex ++ var ciph = cipher.update(plaintext, 'utf8', 'hex'); ++ // Only use binary or hex, not base64. ++ ciph += cipher.final('hex'); ++ ++ var decipher = crypto.createDecipher('aes192', key); ++ var txt = decipher.update(ciph, 'hex', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption'); ++ ++ // streaming cipher interface ++ // NB: In real life, it's not guaranteed that you can get all of it ++ // in a single read() like this. But in this case, we know it's ++ // quite small, so there's no harm. ++ var cStream = crypto.createCipher('aes192', key); ++ cStream.end(plaintext); ++ ciph = cStream.read(); ++ ++ var dStream = crypto.createDecipher('aes192', key); ++ dStream.end(ciph); ++ txt = dStream.read().toString('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption with streams'); ++} ++ ++ ++function testCipher2(key) { ++ // encryption and decryption with Base64 ++ // reported in https://github.com/joyent/node/issues/738 ++ var plaintext = ++ '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + ++ 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + ++ 'jAfaFg**'; ++ var cipher = crypto.createCipher('aes256', key); ++ ++ // encrypt plaintext which is in utf8 format ++ // to a ciphertext which will be in Base64 ++ var ciph = cipher.update(plaintext, 'utf8', 'base64'); ++ ciph += cipher.final('base64'); ++ ++ var decipher = crypto.createDecipher('aes256', key); ++ var txt = decipher.update(ciph, 'base64', 'utf8'); ++ txt += decipher.final('utf8'); ++ ++ assert.equal(txt, plaintext, 'encryption and decryption with Base64'); ++} ++ ++testCipher1('MySecretKey123'); ++testCipher1(new Buffer('MySecretKey123')); ++ ++testCipher2('0123456789abcdef'); ++testCipher2(new Buffer('0123456789abcdef')); ++ ++// Base64 padding regression test, see #4837. ++(function() { ++ var c = crypto.createCipher('aes-256-cbc', 'secret'); ++ var s = c.update('test', 'utf8', 'base64') + c.final('base64'); ++ assert.equal(s, '375oxUQCIocvxmC5At+rvA=='); ++})(); ++ ++// Calling Cipher.final() or Decipher.final() twice should error but ++// not assert. See #4886. ++(function() { ++ var c = crypto.createCipher('aes-256-cbc', 'secret'); ++ try { c.final('xxx'); } catch (e) { /* Ignore. */ } ++ try { c.final('xxx'); } catch (e) { /* Ignore. */ } ++ try { c.final('xxx'); } catch (e) { /* Ignore. */ } ++ var d = crypto.createDecipher('aes-256-cbc', 'secret'); ++ try { d.final('xxx'); } catch (e) { /* Ignore. */ } ++ try { d.final('xxx'); } catch (e) { /* Ignore. */ } ++ try { d.final('xxx'); } catch (e) { /* Ignore. */ } ++})(); ++ ++// Regression test for #5482: string to Cipher#update() should not assert. ++(function() { ++ var c = crypto.createCipher('aes192', '0123456789abcdef'); ++ c.update('update'); ++ c.final(); ++})(); ++ ++// #5655 regression tests, 'utf-8' and 'utf8' are identical. ++(function() { ++ var c = crypto.createCipher('aes192', '0123456789abcdef'); ++ c.update('update', ''); // Defaults to "utf8". ++ c.final('utf-8'); // Should not throw. ++ ++ c = crypto.createCipher('aes192', '0123456789abcdef'); ++ c.update('update', 'utf8'); ++ c.final('utf-8'); // Should not throw. ++ ++ c = crypto.createCipher('aes192', '0123456789abcdef'); ++ c.update('update', 'utf-8'); ++ c.final('utf8'); // Should not throw. ++})(); +diff --git a/test/disabled/test-crypto-dh-odd-key.js b/test/disabled/test-crypto-dh-odd-key.js +new file mode 100644 +index 0000000..503ba2f +--- /dev/null ++++ b/test/disabled/test-crypto-dh-odd-key.js +@@ -0,0 +1,25 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var crypto = require('crypto'); ++ ++function test() { ++ var odd = new Buffer(39); ++ odd.fill('A'); ++ ++ var c = crypto.createDiffieHellman(32); ++ c.setPrivateKey(odd); ++ c.generateKeys(); ++} ++ ++// FIPS requires a length of at least 1024 ++if (!common.hasFipsCrypto) { ++ assert.doesNotThrow(function() { test(); }); ++} else { ++ assert.throws(function() { test(); }, /key size too small/); ++} +diff --git a/test/disabled/test-crypto.js b/test/disabled/test-crypto.js +new file mode 100644 +index 0000000..192e428 +--- /dev/null ++++ b/test/disabled/test-crypto.js +@@ -0,0 +1,143 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++var util = require('util'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var crypto = require('crypto'); ++ ++crypto.DEFAULT_ENCODING = 'buffer'; ++ ++var fs = require('fs'); ++ ++// Test Certificates ++var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii'); ++var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); ++var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx'); ++var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); ++var tls = require('tls'); ++ ++// 'this' safety ++// https://github.com/joyent/node/issues/6690 ++assert.throws(function() { ++ var options = {key: keyPem, cert: certPem, ca: caPem}; ++ var credentials = crypto.createCredentials(options); ++ var context = credentials.context; ++ var notcontext = { setOptions: context.setOptions, setKey: context.setKey }; ++ crypto.createCredentials({ secureOptions: 1 }, notcontext); ++}, TypeError); ++ ++// PFX tests ++assert.doesNotThrow(function() { ++ tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); ++}); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:certPfx}); ++}, 'mac verify failure'); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:certPfx, passphrase:'test'}); ++}, 'mac verify failure'); ++ ++assert.throws(function() { ++ tls.createSecureContext({pfx:'sample', passphrase:'test'}); ++}, 'not enough data'); ++ ++ ++// update() should only take buffers / strings ++assert.throws(function() { ++ crypto.createHash('sha1').update({foo: 'bar'}); ++}, /buffer/); ++ ++ ++function assertSorted(list) { ++ // Array#sort() modifies the list in place so make a copy. ++ var sorted = util._extend([], list).sort(); ++ assert.deepEqual(list, sorted); ++} ++ ++// Assume that we have at least AES-128-CBC. ++assert.notEqual(0, crypto.getCiphers().length); ++assert.notEqual(-1, crypto.getCiphers().indexOf('aes-128-cbc')); ++assert.equal(-1, crypto.getCiphers().indexOf('AES-128-CBC')); ++assertSorted(crypto.getCiphers()); ++ ++// Assume that we have at least AES256-SHA. ++assert.notEqual(0, tls.getCiphers().length); ++assert.notEqual(-1, tls.getCiphers().indexOf('aes256-sha')); ++assert.equal(-1, tls.getCiphers().indexOf('AES256-SHA')); ++assertSorted(tls.getCiphers()); ++ ++// Assert that we have sha and sha1 but not SHA and SHA1. ++assert.notEqual(0, crypto.getHashes().length); ++assert.notEqual(-1, crypto.getHashes().indexOf('sha1')); ++assert.notEqual(-1, crypto.getHashes().indexOf('sha')); ++assert.equal(-1, crypto.getHashes().indexOf('SHA1')); ++assert.equal(-1, crypto.getHashes().indexOf('SHA')); ++assert.notEqual(-1, crypto.getHashes().indexOf('RSA-SHA1')); ++assert.equal(-1, crypto.getHashes().indexOf('rsa-sha1')); ++assertSorted(crypto.getHashes()); ++ ++// Assume that we have at least secp384r1. ++assert.notEqual(0, crypto.getCurves().length); ++assert.notEqual(-1, crypto.getCurves().indexOf('secp384r1')); ++assert.equal(-1, crypto.getCurves().indexOf('SECP384R1')); ++assertSorted(crypto.getCurves()); ++ ++// Regression tests for #5725: hex input that's not a power of two should ++// throw, not assert in C++ land. ++assert.throws(function() { ++ crypto.createCipher('aes192', 'test').update('0', 'hex'); ++}, common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/); ++ ++assert.throws(function() { ++ crypto.createDecipher('aes192', 'test').update('0', 'hex'); ++}, common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/); ++ ++assert.throws(function() { ++ crypto.createHash('sha1').update('0', 'hex'); ++}, /Bad input string/); ++ ++assert.throws(function() { ++ crypto.createSign('RSA-SHA1').update('0', 'hex'); ++}, /Bad input string/); ++ ++assert.throws(function() { ++ crypto.createVerify('RSA-SHA1').update('0', 'hex'); ++}, /Bad input string/); ++ ++assert.throws(function() { ++ var priv = [ ++ '-----BEGIN RSA PRIVATE KEY-----', ++ 'MIGrAgEAAiEA+3z+1QNF2/unumadiwEr+C5vfhezsb3hp4jAnCNRpPcCAwEAAQIgQNriSQK4', ++ 'EFwczDhMZp2dvbcz7OUUyt36z3S4usFPHSECEQD/41K7SujrstBfoCPzwC1xAhEA+5kt4BJy', ++ 'eKN7LggbF3Dk5wIQN6SL+fQ5H/+7NgARsVBp0QIRANxYRukavs4QvuyNhMx+vrkCEQCbf6j/', ++ 'Ig6/HueCK/0Jkmp+', ++ '-----END RSA PRIVATE KEY-----', ++ '' ++ ].join('\n'); ++ crypto.createSign('RSA-SHA256').update('test').sign(priv); ++}, /digest too big for rsa key/); ++ ++assert.throws(function() { ++ // The correct header inside `test_bad_rsa_privkey.pem` should have been ++ // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- ++ // instead of ++ // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- ++ // It is generated in this way: ++ // $ openssl genrsa -out mykey.pem 512; ++ // $ openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \ ++ // -out private_key.pem -nocrypt; ++ // Then open private_key.pem and change its header and footer. ++ var sha1_privateKey = fs.readFileSync(common.fixturesDir + ++ '/test_bad_rsa_privkey.pem', 'ascii'); ++ // this would inject errors onto OpenSSL's error stack ++ crypto.createSign('sha1').sign(sha1_privateKey); ++}, /asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/); ++ ++// Make sure memory isn't released before being returned ++console.log(crypto.randomBytes(16)); +diff --git a/test/disabled/test-net-connect-options-ipv6.js b/test/disabled/test-net-connect-options-ipv6.js +new file mode 100644 +index 0000000..5cce732 +--- /dev/null ++++ b/test/disabled/test-net-connect-options-ipv6.js +@@ -0,0 +1,70 @@ ++'use strict'; ++const common = require('../common'); ++const assert = require('assert'); ++const net = require('net'); ++ ++if (!common.hasIPv6) { ++ console.log('1..0 # Skipped: no IPv6 support'); ++ return; ++} ++ ++const hosts = common.localIPv6Hosts; ++var hostIdx = 0; ++var host = hosts[hostIdx]; ++var localhostTries = 10; ++ ++const server = net.createServer({allowHalfOpen: true}, function(socket) { ++ socket.resume(); ++ socket.on('end', common.mustCall(function() {})); ++ socket.end(); ++}); ++ ++server.listen(common.PORT, '::1', tryConnect); ++ ++function tryConnect() { ++ const client = net.connect({ ++ host: host, ++ port: common.PORT, ++ family: 6, ++ allowHalfOpen: true ++ }, function() { ++ console.error('client connect cb'); ++ client.resume(); ++ client.on('end', common.mustCall(function() { ++ setTimeout(function() { ++ assert(client.writable); ++ client.end(); ++ }, 10); ++ })); ++ client.on('close', function() { ++ server.close(); ++ }); ++ }).on('error', function(err) { ++ // ENOTFOUND means we don't have the requested address. In this ++ // case we try the next one in the list and if we run out of ++ // candidates we assume IPv6 is not supported on the ++ // machine and skip the test. ++ // EAI_AGAIN means we tried to remotely resolve the address and ++ // timed out or hit some intermittent connectivity issue with the ++ // dns server. Although we are looking for local loopback addresses ++ // we may go remote since the list we search includes addresses that ++ // cover more than is available on any one distribution. The ++ // net is that if we get an EAI_AGAIN we were looking for an ++ // address which does not exist in this distribution so the error ++ // is not significant and we should just move on and try the ++ // next address in the list. ++ if ((err.syscall === 'getaddrinfo') && ((err.code === 'ENOTFOUND') || ++ (err.code === 'EAI_AGAIN'))) { ++ if (host !== 'localhost' || --localhostTries === 0) ++ host = hosts[++hostIdx]; ++ if (host) ++ tryConnect(); ++ else { ++ console.log('1..0 # Skipped: no IPv6 localhost support'); ++ server.close(); ++ } ++ return; ++ } ++ throw err; ++ }); ++} +diff --git a/test/disabled/test-npm-install.js b/test/disabled/test-npm-install.js +new file mode 100644 +index 0000000..0c2e4df +--- /dev/null ++++ b/test/disabled/test-npm-install.js +@@ -0,0 +1,47 @@ ++'use strict'; ++const common = require('../common'); ++ ++const path = require('path'); ++const spawn = require('child_process').spawn; ++const assert = require('assert'); ++const fs = require('fs'); ++ ++common.refreshTmpDir(); ++ ++const npmPath = path.join( ++ common.testDir, ++ '..', ++ 'deps', ++ 'npm', ++ 'bin', ++ 'npm-cli.js' ++); ++ ++const args = [ ++ npmPath, ++ 'install' ++]; ++ ++const pkgContent = JSON.stringify({ ++ dependencies: { ++ 'package-name': common.fixturesDir + '/packages/main' ++ } ++}); ++ ++const pkgPath = path.join(common.tmpDir, 'package.json'); ++ ++fs.writeFileSync(pkgPath, pkgContent); ++ ++const proc = spawn(process.execPath, args, { ++ cwd: common.tmpDir ++}); ++ ++function handleExit(code, signalCode) { ++ assert.equal(code, 0, 'npm install should run without an error'); ++ assert.ok(signalCode === null, 'signalCode should be null'); ++ assert.doesNotThrow(function() { ++ fs.accessSync(common.tmpDir + '/node_modules/package-name'); ++ }); ++} ++ ++proc.on('exit', common.mustCall(handleExit)); +diff --git a/test/disabled/test-stdout-close-unref.js b/test/disabled/test-stdout-close-unref.js +new file mode 100644 +index 0000000..37ab498 +--- /dev/null ++++ b/test/disabled/test-stdout-close-unref.js +@@ -0,0 +1,16 @@ ++'use strict'; ++require('../common'); ++var assert = require('assert'); ++ ++var errs = 0; ++ ++process.stdin.resume(); ++process.stdin._handle.close(); ++process.stdin._handle.unref(); // Should not segfault. ++process.stdin.on('error', function(err) { ++ errs++; ++}); ++ ++process.on('exit', function() { ++ assert.strictEqual(errs, 1); ++}); +diff --git a/test/disabled/test-tls-cnnic-whitelist.js b/test/disabled/test-tls-cnnic-whitelist.js +new file mode 100644 +index 0000000..85e1d90 +--- /dev/null ++++ b/test/disabled/test-tls-cnnic-whitelist.js +@@ -0,0 +1,83 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++ ++var tls = require('tls'); ++var fs = require('fs'); ++var path = require('path'); ++var finished = 0; ++ ++function filenamePEM(n) { ++ return path.join(common.fixturesDir, 'keys', n + '.pem'); ++} ++ ++function loadPEM(n) { ++ return fs.readFileSync(filenamePEM(n)); ++} ++ ++var testCases = [ ++ { // Test 0: for the check of a cert not existed in the whitelist. ++ // agent7-cert.pem is issued by the fake CNNIC root CA so that its ++ // hash is not listed in the whitelist. ++ // fake-cnnic-root-cert has the same subject name as the original ++ // rootCA. ++ serverOpts: { ++ key: loadPEM('agent7-key'), ++ cert: loadPEM('agent7-cert') ++ }, ++ clientOpts: { ++ port: common.PORT, ++ rejectUnauthorized: true, ++ ca: [loadPEM('fake-cnnic-root-cert')] ++ }, ++ errorCode: 'CERT_REVOKED' ++ }, ++ // Test 1: for the fix of node#2061 ++ // agent6-cert.pem is signed by intermidate cert of ca3. ++ // The server has a cert chain of agent6->ca3->ca1(root) but ++ // tls.connect should be failed with an error of ++ // UNABLE_TO_GET_ISSUER_CERT_LOCALLY since the root CA of ca1 is not ++ // installed locally. ++ { ++ serverOpts: { ++ ca: loadPEM('ca3-key'), ++ key: loadPEM('agent6-key'), ++ cert: loadPEM('agent6-cert') ++ }, ++ clientOpts: { ++ port: common.PORT, ++ rejectUnauthorized: true ++ }, ++ errorCode: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' ++ } ++]; ++ ++function runTest(tindex) { ++ var tcase = testCases[tindex]; ++ ++ if (!tcase) return; ++ ++ var server = tls.createServer(tcase.serverOpts, function(s) { ++ s.resume(); ++ }).listen(common.PORT, function() { ++ var client = tls.connect(tcase.clientOpts); ++ client.on('error', function(e) { ++ assert.strictEqual(e.code, tcase.errorCode); ++ server.close(function() { ++ finished++; ++ runTest(tindex + 1); ++ }); ++ }); ++ }); ++} ++ ++runTest(0); ++ ++process.on('exit', function() { ++ assert.equal(finished, testCases.length); ++}); +diff --git a/test/disabled/test-tls-dhe.js b/test/disabled/test-tls-dhe.js +new file mode 100644 +index 0000000..ffcf529 +--- /dev/null ++++ b/test/disabled/test-tls-dhe.js +@@ -0,0 +1,95 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var spawn = require('child_process').spawn; ++var fs = require('fs'); ++var key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); ++var cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); ++var nsuccess = 0; ++var ntests = 0; ++var ciphers = 'DHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; ++ ++ ++function loadDHParam(n) { ++ var path = common.fixturesDir; ++ if (n !== 'error') path += '/keys'; ++ return fs.readFileSync(path + '/dh' + n + '.pem'); ++} ++ ++function test(keylen, expectedCipher, cb) { ++ var options = { ++ key: key, ++ cert: cert, ++ ciphers: ciphers, ++ dhparam: loadDHParam(keylen) ++ }; ++ ++ var server = tls.createServer(options, function(conn) { ++ conn.end(); ++ }); ++ ++ server.on('close', function(err) { ++ assert(!err); ++ if (cb) cb(); ++ }); ++ ++ server.listen(common.PORT, '127.0.0.1', function() { ++ var args = ['s_client', '-connect', '127.0.0.1:' + common.PORT, ++ '-cipher', ciphers]; ++ ++ // for the performance and stability issue in s_client on Windows ++ if (common.isWindows) ++ args.push('-no_rand_screen'); ++ ++ var client = spawn(common.opensslCli, args); ++ var out = ''; ++ client.stdout.setEncoding('utf8'); ++ client.stdout.on('data', function(d) { ++ out += d; ++ }); ++ client.stdout.on('end', function() { ++ // DHE key length can be checked -brief option in s_client but it ++ // is only supported in openssl 1.0.2 so we cannot check it. ++ var reg = new RegExp('Cipher : ' + expectedCipher); ++ if (reg.test(out)) { ++ nsuccess++; ++ server.close(); ++ } ++ }); ++ }); ++} ++ ++function test512() { ++ assert.throws(function() { ++ test(512, 'DHE-RSA-AES128-SHA256', null); ++ }, /DH parameter is less than 1024 bits/); ++} ++ ++function test1024() { ++ test(1024, 'DHE-RSA-AES128-SHA256', test2048); ++ ntests++; ++} ++ ++function test2048() { ++ test(2048, 'DHE-RSA-AES128-SHA256', testError); ++ ntests++; ++} ++ ++function testError() { ++ test('error', 'ECDHE-RSA-AES128-SHA256', test512); ++ ntests++; ++} ++ ++test1024(); ++ ++process.on('exit', function() { ++ assert.equal(ntests, nsuccess); ++ assert.equal(ntests, 3); ++}); +diff --git a/test/disabled/test-tls-ecdh-disable.js b/test/disabled/test-tls-ecdh-disable.js +new file mode 100644 +index 0000000..9bfb5f8 +--- /dev/null ++++ b/test/disabled/test-tls-ecdh-disable.js +@@ -0,0 +1,46 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var exec = require('child_process').exec; ++var fs = require('fs'); ++ ++var options = { ++ key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'), ++ cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'), ++ ciphers: 'ECDHE-RSA-RC4-SHA', ++ ecdhCurve: false ++}; ++ ++var nconns = 0; ++ ++process.on('exit', function() { ++ assert.equal(nconns, 0); ++}); ++ ++var server = tls.createServer(options, function(conn) { ++ conn.end(); ++ nconns++; ++}); ++ ++server.listen(common.PORT, '127.0.0.1', function() { ++ var cmd = '"' + common.opensslCli + '" s_client -cipher ' + options.ciphers + ++ ' -connect 127.0.0.1:' + common.PORT; ++ ++ // for the performance and stability issue in s_client on Windows ++ if (common.isWindows) ++ cmd += ' -no_rand_screen'; ++ ++ exec(cmd, function(err, stdout, stderr) { ++ // Old versions of openssl will still exit with 0 so we ++ // can't just check if err is not null. ++ assert.notEqual(stderr.indexOf('handshake failure'), -1); ++ server.close(); ++ }); ++}); +diff --git a/test/disabled/test-tls-ecdh.js b/test/disabled/test-tls-ecdh.js +new file mode 100644 +index 0000000..a6e1611 +--- /dev/null ++++ b/test/disabled/test-tls-ecdh.js +@@ -0,0 +1,48 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var exec = require('child_process').exec; ++var fs = require('fs'); ++ ++var options = { ++ key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'), ++ cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'), ++ ciphers: '-ALL:ECDHE-RSA-AES128-SHA256', ++ ecdhCurve: 'prime256v1' ++}; ++ ++var reply = 'I AM THE WALRUS'; // something recognizable ++var nconns = 0; ++var response = ''; ++ ++process.on('exit', function() { ++ assert.equal(nconns, 1); ++ assert.notEqual(response.indexOf(reply), -1); ++}); ++ ++var server = tls.createServer(options, function(conn) { ++ conn.end(reply); ++ nconns++; ++}); ++ ++server.listen(common.PORT, '127.0.0.1', function() { ++ var cmd = '"' + common.opensslCli + '" s_client -cipher ' + options.ciphers + ++ ' -connect 127.0.0.1:' + common.PORT; ++ ++ // for the performance and stability issue in s_client on Windows ++ if (common.isWindows) ++ cmd += ' -no_rand_screen'; ++ ++ exec(cmd, function(err, stdout, stderr) { ++ if (err) throw err; ++ response = stdout; ++ server.close(); ++ }); ++}); +diff --git a/test/disabled/test-tls-js-stream.js b/test/disabled/test-tls-js-stream.js +new file mode 100644 +index 0000000..1c5e749 +--- /dev/null ++++ b/test/disabled/test-tls-js-stream.js +@@ -0,0 +1,76 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var stream = require('stream'); ++var fs = require('fs'); ++var net = require('net'); ++ ++var connected = { ++ client: 0, ++ server: 0 ++}; ++ ++var server = tls.createServer({ ++ key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), ++ cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') ++}, function(c) { ++ console.log('new client'); ++ connected.server++; ++ c.end('ohai'); ++}).listen(common.PORT, function() { ++ var raw = net.connect(common.PORT); ++ ++ var pending = false; ++ raw.on('readable', function() { ++ if (pending) ++ p._read(); ++ }); ++ ++ var p = new stream.Duplex({ ++ read: function read() { ++ pending = false; ++ ++ var chunk = raw.read(); ++ if (chunk) { ++ console.log('read', chunk); ++ this.push(chunk); ++ } else { ++ pending = true; ++ } ++ }, ++ write: function write(data, enc, cb) { ++ console.log('write', data, enc); ++ raw.write(data, enc, cb); ++ } ++ }); ++ ++ var socket = tls.connect({ ++ socket: p, ++ rejectUnauthorized: false ++ }, function() { ++ console.log('client secure'); ++ ++ connected.client++; ++ ++ socket.end('hello'); ++ socket.resume(); ++ socket.destroy(); ++ }); ++ ++ socket.once('close', function() { ++ console.log('client close'); ++ server.close(); ++ }); ++}); ++ ++process.once('exit', function() { ++ assert.equal(connected.client, 1); ++ assert.equal(connected.server, 1); ++}); +diff --git a/test/disabled/test-tls-ocsp-callback.js b/test/disabled/test-tls-ocsp-callback.js +new file mode 100644 +index 0000000..e9443f4 +--- /dev/null ++++ b/test/disabled/test-tls-ocsp-callback.js +@@ -0,0 +1,130 @@ ++'use strict'; ++var common = require('../common'); ++ ++if (!process.features.tls_ocsp) { ++ console.log('1..0 # Skipped: node compiled without OpenSSL or ' + ++ 'with old OpenSSL version.'); ++ return; ++} ++if (!common.opensslCli) { ++ console.log('1..0 # Skipped: node compiled without OpenSSL CLI.'); ++ return; ++} ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var assert = require('assert'); ++var constants = require('constants'); ++var fs = require('fs'); ++var join = require('path').join; ++ ++var pfx = fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-pfx.pem')); ++ ++function test(testOptions, cb) { ++ ++ var keyFile = join(common.fixturesDir, 'keys', 'agent1-key.pem'); ++ var certFile = join(common.fixturesDir, 'keys', 'agent1-cert.pem'); ++ var caFile = join(common.fixturesDir, 'keys', 'ca1-cert.pem'); ++ var key = fs.readFileSync(keyFile); ++ var cert = fs.readFileSync(certFile); ++ var ca = fs.readFileSync(caFile); ++ var options = { ++ key: key, ++ cert: cert, ++ ca: [ca] ++ }; ++ var requestCount = 0; ++ var clientSecure = 0; ++ var ocspCount = 0; ++ var ocspResponse; ++ ++ if (testOptions.pfx) { ++ delete options.key; ++ delete options.cert; ++ options.pfx = testOptions.pfx; ++ options.passphrase = testOptions.passphrase; ++ } ++ ++ var server = tls.createServer(options, function(cleartext) { ++ cleartext.on('error', function(er) { ++ // We're ok with getting ECONNRESET in this test, but it's ++ // timing-dependent, and thus unreliable. Any other errors ++ // are just failures, though. ++ if (er.code !== 'ECONNRESET') ++ throw er; ++ }); ++ ++requestCount; ++ cleartext.end(); ++ }); ++ server.on('OCSPRequest', function(cert, issuer, callback) { ++ ++ocspCount; ++ assert.ok(Buffer.isBuffer(cert)); ++ assert.ok(Buffer.isBuffer(issuer)); ++ ++ // Just to check that async really works there ++ setTimeout(function() { ++ callback(null, ++ testOptions.response ? new Buffer(testOptions.response) : null); ++ }, 100); ++ }); ++ server.listen(common.PORT, function() { ++ var client = tls.connect({ ++ port: common.PORT, ++ requestOCSP: testOptions.ocsp !== false, ++ secureOptions: testOptions.ocsp === false ? ++ constants.SSL_OP_NO_TICKET : 0, ++ rejectUnauthorized: false ++ }, function() { ++ clientSecure++; ++ }); ++ client.on('OCSPResponse', function(resp) { ++ ocspResponse = resp; ++ if (resp) ++ client.destroy(); ++ }); ++ client.on('close', function() { ++ server.close(cb); ++ }); ++ }); ++ ++ process.on('exit', function() { ++ if (testOptions.ocsp === false) { ++ assert.equal(requestCount, clientSecure); ++ assert.equal(requestCount, 1); ++ return; ++ } ++ ++ if (testOptions.response) { ++ assert.equal(ocspResponse.toString(), testOptions.response); ++ } else { ++ assert.ok(ocspResponse === null); ++ } ++ assert.equal(requestCount, testOptions.response ? 0 : 1); ++ assert.equal(clientSecure, requestCount); ++ assert.equal(ocspCount, 1); ++ }); ++} ++ ++var tests = [ ++ { response: false }, ++ { response: 'hello world' }, ++ { ocsp: false } ++]; ++ ++if (!common.hasFipsCrypto) { ++ tests.push({ pfx: pfx, passphrase: 'sample', response: 'hello pfx' }); ++} ++ ++function runTests(i) { ++ if (i === tests.length) return; ++ ++ test(tests[i], common.mustCall(function() { ++ runTests(i + 1); ++ })); ++} ++ ++runTests(0); +diff --git a/test/disabled/test-tls-pfx-gh-5100-regr.js b/test/disabled/test-tls-pfx-gh-5100-regr.js +new file mode 100644 +index 0000000..865ac2b +--- /dev/null ++++ b/test/disabled/test-tls-pfx-gh-5100-regr.js +@@ -0,0 +1,36 @@ ++'use strict'; ++ ++const common = require('../common'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: node compiled without crypto.'); ++ return; ++} ++ ++const assert = require('assert'); ++const tls = require('tls'); ++const fs = require('fs'); ++const path = require('path'); ++ ++const pfx = fs.readFileSync( ++ path.join(common.fixturesDir, 'keys', 'agent1-pfx.pem')); ++ ++const server = tls.createServer({ ++ pfx: pfx, ++ passphrase: 'sample', ++ requestCert: true, ++ rejectUnauthorized: false ++}, common.mustCall(function(c) { ++ assert(c.authorizationError === null, 'authorizationError must be null'); ++ c.end(); ++})).listen(common.PORT, function() { ++ var client = tls.connect({ ++ port: common.PORT, ++ pfx: pfx, ++ passphrase: 'sample', ++ rejectUnauthorized: false ++ }, function() { ++ client.end(); ++ server.close(); ++ }); ++}); +diff --git a/test/disabled/test-tls-securepair-server.js b/test/disabled/test-tls-securepair-server.js +new file mode 100644 +index 0000000..ef182f3 +--- /dev/null ++++ b/test/disabled/test-tls-securepair-server.js +@@ -0,0 +1,138 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++var join = require('path').join; ++var net = require('net'); ++var fs = require('fs'); ++var spawn = require('child_process').spawn; ++ ++var connections = 0; ++var key = fs.readFileSync(join(common.fixturesDir, 'agent.key')).toString(); ++var cert = fs.readFileSync(join(common.fixturesDir, 'agent.crt')).toString(); ++ ++function log(a) { ++ console.error('***server*** ' + a); ++} ++ ++var server = net.createServer(function(socket) { ++ connections++; ++ log('connection fd=' + socket.fd); ++ var sslcontext = tls.createSecureContext({key: key, cert: cert}); ++ sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); ++ ++ var pair = tls.createSecurePair(sslcontext, true); ++ ++ assert.ok(pair.encrypted.writable); ++ assert.ok(pair.cleartext.writable); ++ ++ pair.encrypted.pipe(socket); ++ socket.pipe(pair.encrypted); ++ ++ log('i set it secure'); ++ ++ pair.on('secure', function() { ++ log('connected+secure!'); ++ pair.cleartext.write('hello\r\n'); ++ log(pair.cleartext.getPeerCertificate()); ++ log(pair.cleartext.getCipher()); ++ }); ++ ++ pair.cleartext.on('data', function(data) { ++ log('read bytes ' + data.length); ++ pair.cleartext.write(data); ++ }); ++ ++ socket.on('end', function() { ++ log('socket end'); ++ }); ++ ++ pair.cleartext.on('error', function(err) { ++ log('got error: '); ++ log(err); ++ log(err.stack); ++ socket.destroy(); ++ }); ++ ++ pair.encrypted.on('error', function(err) { ++ log('encrypted error: '); ++ log(err); ++ log(err.stack); ++ socket.destroy(); ++ }); ++ ++ socket.on('error', function(err) { ++ log('socket error: '); ++ log(err); ++ log(err.stack); ++ socket.destroy(); ++ }); ++ ++ socket.on('close', function(err) { ++ log('socket closed'); ++ }); ++ ++ pair.on('error', function(err) { ++ log('secure error: '); ++ log(err); ++ log(err.stack); ++ socket.destroy(); ++ }); ++}); ++ ++var gotHello = false; ++var sentWorld = false; ++var gotWorld = false; ++var opensslExitCode = -1; ++ ++server.listen(common.PORT, function() { ++ // To test use: openssl s_client -connect localhost:8000 ++ ++ var args = ['s_client', '-connect', '127.0.0.1:' + common.PORT]; ++ ++ // for the performance and stability issue in s_client on Windows ++ if (common.isWindows) ++ args.push('-no_rand_screen'); ++ ++ var client = spawn(common.opensslCli, args); ++ ++ ++ var out = ''; ++ ++ client.stdout.setEncoding('utf8'); ++ client.stdout.on('data', function(d) { ++ out += d; ++ ++ if (!gotHello && /hello/.test(out)) { ++ gotHello = true; ++ client.stdin.write('world\r\n'); ++ sentWorld = true; ++ } ++ ++ if (!gotWorld && /world/.test(out)) { ++ gotWorld = true; ++ client.stdin.end(); ++ } ++ }); ++ ++ client.stdout.pipe(process.stdout, { end: false }); ++ ++ client.on('exit', function(code) { ++ opensslExitCode = code; ++ server.close(); ++ }); ++}); ++ ++process.on('exit', function() { ++ assert.equal(1, connections); ++ assert.ok(gotHello); ++ assert.ok(sentWorld); ++ assert.ok(gotWorld); ++ assert.equal(0, opensslExitCode); ++}); +diff --git a/test/disabled/test-tls-sni-option.js b/test/disabled/test-tls-sni-option.js +new file mode 100644 +index 0000000..83e6213 +--- /dev/null ++++ b/test/disabled/test-tls-sni-option.js +@@ -0,0 +1,169 @@ ++'use strict'; ++if (!process.features.tls_sni) { ++ console.log('1..0 # Skipped: node compiled without OpenSSL or ' + ++ 'with old OpenSSL version.'); ++ return; ++} ++ ++const common = require('../common'); ++const assert = require('assert'); ++const fs = require('fs'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++function filenamePEM(n) { ++ return require('path').join(common.fixturesDir, 'keys', n + '.pem'); ++} ++ ++function loadPEM(n) { ++ return fs.readFileSync(filenamePEM(n)); ++} ++ ++var serverOptions = { ++ key: loadPEM('agent2-key'), ++ cert: loadPEM('agent2-cert'), ++ requestCert: true, ++ rejectUnauthorized: false, ++ SNICallback: function(servername, callback) { ++ var context = SNIContexts[servername]; ++ ++ // Just to test asynchronous callback ++ setTimeout(function() { ++ if (context) { ++ if (context.emptyRegression) ++ callback(null, {}); ++ else ++ callback(null, tls.createSecureContext(context)); ++ } else { ++ callback(null, null); ++ } ++ }, 100); ++ } ++}; ++ ++var SNIContexts = { ++ 'a.example.com': { ++ key: loadPEM('agent1-key'), ++ cert: loadPEM('agent1-cert'), ++ ca: [ loadPEM('ca2-cert') ] ++ }, ++ 'b.example.com': { ++ key: loadPEM('agent3-key'), ++ cert: loadPEM('agent3-cert') ++ }, ++ 'c.another.com': { ++ emptyRegression: true ++ } ++}; ++ ++var serverPort = common.PORT; ++ ++var clientsOptions = [{ ++ port: serverPort, ++ key: loadPEM('agent1-key'), ++ cert: loadPEM('agent1-cert'), ++ ca: [loadPEM('ca1-cert')], ++ servername: 'a.example.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ key: loadPEM('agent4-key'), ++ cert: loadPEM('agent4-cert'), ++ ca: [loadPEM('ca1-cert')], ++ servername: 'a.example.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ key: loadPEM('agent2-key'), ++ cert: loadPEM('agent2-cert'), ++ ca: [loadPEM('ca2-cert')], ++ servername: 'b.example.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ key: loadPEM('agent3-key'), ++ cert: loadPEM('agent3-cert'), ++ ca: [loadPEM('ca1-cert')], ++ servername: 'c.wrong.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ key: loadPEM('agent3-key'), ++ cert: loadPEM('agent3-cert'), ++ ca: [loadPEM('ca1-cert')], ++ servername: 'c.another.com', ++ rejectUnauthorized: false ++}]; ++ ++const serverResults = []; ++const clientResults = []; ++const serverErrors = []; ++const clientErrors = []; ++let serverError; ++let clientError; ++ ++var server = tls.createServer(serverOptions, function(c) { ++ serverResults.push({ sni: c.servername, authorized: c.authorized }); ++}); ++ ++server.on('clientError', function(err) { ++ serverResults.push(null); ++ serverError = err.message; ++}); ++ ++server.listen(serverPort, startTest); ++ ++function startTest() { ++ function connectClient(i, callback) { ++ var options = clientsOptions[i]; ++ clientError = null; ++ serverError = null; ++ ++ var client = tls.connect(options, function() { ++ clientResults.push( ++ /Hostname\/IP doesn't/.test(client.authorizationError || '')); ++ client.destroy(); ++ ++ next(); ++ }); ++ ++ client.on('error', function(err) { ++ clientResults.push(false); ++ clientError = err.message; ++ next(); ++ }); ++ ++ function next() { ++ clientErrors.push(clientError); ++ serverErrors.push(serverError); ++ ++ if (i === clientsOptions.length - 1) ++ callback(); ++ else ++ connectClient(i + 1, callback); ++ } ++ } ++ ++ connectClient(0, function() { ++ server.close(); ++ }); ++} ++ ++process.on('exit', function() { ++ assert.deepEqual(serverResults, [ ++ { sni: 'a.example.com', authorized: false }, ++ { sni: 'a.example.com', authorized: true }, ++ { sni: 'b.example.com', authorized: false }, ++ { sni: 'c.wrong.com', authorized: false }, ++ null ++ ]); ++ assert.deepEqual(clientResults, [true, true, true, false, false]); ++ assert.deepEqual(clientErrors, [null, null, null, null, 'socket hang up']); ++ assert.deepEqual(serverErrors, [ ++ null, null, null, null, 'Invalid SNI context' ++ ]); ++}); +diff --git a/test/disabled/test-tls-sni-server-client.js b/test/disabled/test-tls-sni-server-client.js +new file mode 100644 +index 0000000..733713c +--- /dev/null ++++ b/test/disabled/test-tls-sni-server-client.js +@@ -0,0 +1,117 @@ ++'use strict'; ++if (!process.features.tls_sni) { ++ console.log('1..0 # Skipped: node compiled without OpenSSL or ' + ++ 'with old OpenSSL version.'); ++ return; ++} ++ ++const common = require('../common'); ++const assert = require('assert'); ++const fs = require('fs'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var tls = require('tls'); ++ ++function filenamePEM(n) { ++ return require('path').join(common.fixturesDir, 'keys', n + '.pem'); ++} ++ ++function loadPEM(n) { ++ return fs.readFileSync(filenamePEM(n)); ++} ++ ++var serverOptions = { ++ key: loadPEM('agent2-key'), ++ cert: loadPEM('agent2-cert') ++}; ++ ++var SNIContexts = { ++ 'a.example.com': { ++ key: loadPEM('agent1-key'), ++ cert: loadPEM('agent1-cert') ++ }, ++ 'asterisk.test.com': { ++ key: loadPEM('agent3-key'), ++ cert: loadPEM('agent3-cert') ++ }, ++ 'chain.example.com': { ++ key: loadPEM('agent6-key'), ++ // NOTE: Contains ca3 chain cert ++ cert: loadPEM('agent6-cert') ++ } ++}; ++ ++var serverPort = common.PORT; ++ ++var clientsOptions = [{ ++ port: serverPort, ++ ca: [loadPEM('ca1-cert')], ++ servername: 'a.example.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ ca: [loadPEM('ca2-cert')], ++ servername: 'b.test.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ ca: [loadPEM('ca2-cert')], ++ servername: 'a.b.test.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ ca: [loadPEM('ca1-cert')], ++ servername: 'c.wrong.com', ++ rejectUnauthorized: false ++}, { ++ port: serverPort, ++ ca: [loadPEM('ca1-cert')], ++ servername: 'chain.example.com', ++ rejectUnauthorized: false ++}]; ++ ++const serverResults = []; ++const clientResults = []; ++ ++var server = tls.createServer(serverOptions, function(c) { ++ serverResults.push(c.servername); ++}); ++ ++server.addContext('a.example.com', SNIContexts['a.example.com']); ++server.addContext('*.test.com', SNIContexts['asterisk.test.com']); ++server.addContext('chain.example.com', SNIContexts['chain.example.com']); ++ ++server.listen(serverPort, startTest); ++ ++function startTest() { ++ var i = 0; ++ function start() { ++ // No options left ++ if (i === clientsOptions.length) ++ return server.close(); ++ ++ var options = clientsOptions[i++]; ++ var client = tls.connect(options, function() { ++ clientResults.push( ++ client.authorizationError && ++ /Hostname\/IP doesn't/.test(client.authorizationError)); ++ client.destroy(); ++ ++ // Continue ++ start(); ++ }); ++ } ++ ++ start(); ++} ++ ++process.on('exit', function() { ++ assert.deepEqual(serverResults, [ ++ 'a.example.com', 'b.test.com', 'a.b.test.com', 'c.wrong.com', ++ 'chain.example.com' ++ ]); ++ assert.deepEqual(clientResults, [true, true, false, false, true]); ++}); +diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js +deleted file mode 100644 +index fa9a78c..0000000 +--- a/test/parallel/test-crypto-authenticated.js ++++ /dev/null +@@ -1,177 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var crypto = require('crypto'); +- +-crypto.DEFAULT_ENCODING = 'buffer'; +- +-// +-// Test authenticated encryption modes. +-// +-// !NEVER USE STATIC IVs IN REAL LIFE! +-// +- +-var TEST_CASES = [ +- { algo: 'aes-128-gcm', +- key: '6970787039613669314d623455536234', +- iv: '583673497131313748307652', plain: 'Hello World!', +- ct: '4BE13896F64DFA2C2D0F2C76', +- tag: '272B422F62EB545EAA15B5FF84092447', tampered: false }, +- { algo: 'aes-128-gcm', +- key: '6970787039613669314d623455536234', +- iv: '583673497131313748307652', plain: 'Hello World!', +- ct: '4BE13896F64DFA2C2D0F2C76', aad: '000000FF', +- tag: 'BA2479F66275665A88CB7B15F43EB005', tampered: false }, +- { algo: 'aes-128-gcm', +- key: '6970787039613669314d623455536234', +- iv: '583673497131313748307652', plain: 'Hello World!', +- ct: '4BE13596F64DFA2C2D0FAC76', +- tag: '272B422F62EB545EAA15B5FF84092447', tampered: true }, +- { algo: 'aes-256-gcm', +- key: '337a54767a7233703637564336316a6d56353472495975313534357834546c59', +- iv: '36306950306836764a6f4561', plain: 'Hello node.js world!', +- ct: '58E62CFE7B1D274111A82267EBB93866E72B6C2A', +- tag: '9BB44F663BADABACAE9720881FB1EC7A', tampered: false }, +- { algo: 'aes-256-gcm', +- key: '337a54767a7233703637564336316a6d56353472495975313534357834546c59', +- iv: '36306950306836764a6f4561', plain: 'Hello node.js world!', +- ct: '58E62CFF7B1D274011A82267EBB93866E72B6C2B', +- tag: '9BB44F663BADABACAE9720881FB1EC7A', tampered: true }, +- { algo: 'aes-192-gcm', +- key: '1ed2233fa2223ef5d7df08546049406c7305220bca40d4c9', +- iv: '0e1791e9db3bd21a9122c416', plain: 'Hello node.js world!', +- password: 'very bad password', aad: '63616c76696e', +- ct: 'DDA53A4059AA17B88756984995F7BBA3C636CC44', +- tag: 'D2A35E5C611E5E3D2258360241C5B045', tampered: false } +-]; +- +-var ciphers = crypto.getCiphers(); +- +-for (var i in TEST_CASES) { +- var test = TEST_CASES[i]; +- +- if (ciphers.indexOf(test.algo) == -1) { +- console.log('1..0 # Skipped: unsupported ' + test.algo + ' test'); +- continue; +- } +- +- (function() { +- var encrypt = crypto.createCipheriv(test.algo, +- new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); +- if (test.aad) +- encrypt.setAAD(new Buffer(test.aad, 'hex')); +- var hex = encrypt.update(test.plain, 'ascii', 'hex'); +- hex += encrypt.final('hex'); +- var auth_tag = encrypt.getAuthTag(); +- // only test basic encryption run if output is marked as tampered. +- if (!test.tampered) { +- assert.equal(hex.toUpperCase(), test.ct); +- assert.equal(auth_tag.toString('hex').toUpperCase(), test.tag); +- } +- })(); +- +- (function() { +- var decrypt = crypto.createDecipheriv(test.algo, +- new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); +- decrypt.setAuthTag(new Buffer(test.tag, 'hex')); +- if (test.aad) +- decrypt.setAAD(new Buffer(test.aad, 'hex')); +- var msg = decrypt.update(test.ct, 'hex', 'ascii'); +- if (!test.tampered) { +- msg += decrypt.final('ascii'); +- assert.equal(msg, test.plain); +- } else { +- // assert that final throws if input data could not be verified! +- assert.throws(function() { decrypt.final('ascii'); }, / auth/); +- } +- })(); +- +- (function() { +- if (!test.password) return; +- if (common.hasFipsCrypto) { +- assert.throws(function() +- { crypto.createCipher(test.algo, test.password); }, +- /not supported in FIPS mode/); +- } else { +- var encrypt = crypto.createCipher(test.algo, test.password); +- if (test.aad) +- encrypt.setAAD(new Buffer(test.aad, 'hex')); +- var hex = encrypt.update(test.plain, 'ascii', 'hex'); +- hex += encrypt.final('hex'); +- var auth_tag = encrypt.getAuthTag(); +- // only test basic encryption run if output is marked as tampered. +- if (!test.tampered) { +- assert.equal(hex.toUpperCase(), test.ct); +- assert.equal(auth_tag.toString('hex').toUpperCase(), test.tag); +- } +- } +- })(); +- +- (function() { +- if (!test.password) return; +- if (common.hasFipsCrypto) { +- assert.throws(function() +- { crypto.createDecipher(test.algo, test.password); }, +- /not supported in FIPS mode/); +- } else { +- var decrypt = crypto.createDecipher(test.algo, test.password); +- decrypt.setAuthTag(new Buffer(test.tag, 'hex')); +- if (test.aad) +- decrypt.setAAD(new Buffer(test.aad, 'hex')); +- var msg = decrypt.update(test.ct, 'hex', 'ascii'); +- if (!test.tampered) { +- msg += decrypt.final('ascii'); +- assert.equal(msg, test.plain); +- } else { +- // assert that final throws if input data could not be verified! +- assert.throws(function() { decrypt.final('ascii'); }, / auth/); +- } +- } +- })(); +- +- // after normal operation, test some incorrect ways of calling the API: +- // it's most certainly enough to run these tests with one algorithm only. +- +- if (i > 0) { +- continue; +- } +- +- (function() { +- // non-authenticating mode: +- var encrypt = crypto.createCipheriv('aes-128-cbc', +- 'ipxp9a6i1Mb4USb4', '6fKjEjR3Vl30EUYC'); +- encrypt.update('blah', 'ascii'); +- encrypt.final(); +- assert.throws(function() { encrypt.getAuthTag(); }, / state/); +- assert.throws(function() { +- encrypt.setAAD(new Buffer('123', 'ascii')); }, / state/); +- })(); +- +- (function() { +- // trying to get tag before inputting all data: +- var encrypt = crypto.createCipheriv(test.algo, +- new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); +- encrypt.update('blah', 'ascii'); +- assert.throws(function() { encrypt.getAuthTag(); }, / state/); +- })(); +- +- (function() { +- // trying to set tag on encryption object: +- var encrypt = crypto.createCipheriv(test.algo, +- new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); +- assert.throws(function() { +- encrypt.setAuthTag(new Buffer(test.tag, 'hex')); }, / state/); +- })(); +- +- (function() { +- // trying to read tag from decryption object: +- var decrypt = crypto.createDecipheriv(test.algo, +- new Buffer(test.key, 'hex'), new Buffer(test.iv, 'hex')); +- assert.throws(function() { decrypt.getAuthTag(); }, / state/); +- })(); +-} +diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js +deleted file mode 100644 +index 6418f52..0000000 +--- a/test/parallel/test-crypto-binary-default.js ++++ /dev/null +@@ -1,666 +0,0 @@ +-'use strict'; +-// This is the same as test/simple/test-crypto, but from before the shift +-// to use buffers by default. +- +- +-var common = require('../common'); +-var assert = require('assert'); +-var constants = require('constants'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var crypto = require('crypto'); +-var tls = require('tls'); +- +-crypto.DEFAULT_ENCODING = 'binary'; +- +-var fs = require('fs'); +-var path = require('path'); +- +-// Test Certificates +-var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); +-var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx'); +-var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); +-var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem', +- 'ascii'); +-var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem', +- 'ascii'); +- +-// PFX tests +-assert.doesNotThrow(function() { +- tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); +-}); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:certPfx}); +-}, 'mac verify failure'); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:certPfx, passphrase:'test'}); +-}, 'mac verify failure'); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:'sample', passphrase:'test'}); +-}, 'not enough data'); +- +-// Test HMAC +-const hmacHash = crypto.createHmac('sha1', 'Node') +- .update('some data') +- .update('to hmac') +- .digest('hex'); +-assert.equal(hmacHash, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', 'test HMAC'); +- +-// Test HMAC-SHA-* (rfc 4231 Test Cases) +-var rfc4231 = [ +- { +- key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), +- data: new Buffer('4869205468657265', 'hex'), // 'Hi There' +- hmac: { +- sha224: '896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22', +- sha256: +- 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c' + +- '2e32cff7', +- sha384: +- 'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c' + +- '7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6', +- sha512: +- '87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b305' + +- '45e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f170' + +- '2e696c203a126854' +- } +- }, +- { +- key: new Buffer('4a656665', 'hex'), // 'Jefe' +- data: new Buffer('7768617420646f2079612077616e7420666f72206e6f74686' + +- '96e673f', 'hex'), // 'what do ya want for nothing?' +- hmac: { +- sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44', +- sha256: +- '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b9' + +- '64ec3843', +- sha384: +- 'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec373' + +- '6322445e8e2240ca5e69e2c78b3239ecfab21649', +- sha512: +- '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7' + +- 'ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b' + +- '636e070a38bce737' +- } +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), +- data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' + +- 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', +- 'hex'), +- hmac: { +- sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea', +- sha256: +- '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514' + +- 'ced565fe', +- sha384: +- '88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e5' + +- '5966144b2a5ab39dc13814b94e3ab6e101a34f27', +- sha512: +- 'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33' + +- 'b2279d39bf3e848279a722c806b485a47e67c807b946a337bee89426' + +- '74278859e13292fb' +- } +- }, +- { +- key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', +- 'hex'), +- data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + +- 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', +- 'hex'), +- hmac: { +- sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a', +- sha256: +- '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff4' + +- '6729665b', +- sha384: +- '3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e' + +- '1f573b4e6801dd23c4a7d679ccf8a386c674cffb', +- sha512: +- 'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050' + +- '361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2d' + +- 'e2adebeb10a298dd' +- } +- }, +- +- { +- key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), +- // 'Test With Truncation' +- data: new Buffer('546573742057697468205472756e636174696f6e', 'hex'), +- hmac: { +- sha224: '0e2aea68a90c8d37c988bcdb9fca6fa8', +- sha256: 'a3b6167473100ee06e0c796c2955552b', +- sha384: '3abf34c3503b2a23a46efc619baef897', +- sha512: '415fad6271580a531d4179bc891d87a6' +- }, +- truncate: true +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaa', 'hex'), +- // 'Test Using Larger Than Block-Size Key - Hash Key First' +- data: new Buffer('54657374205573696e67204c6172676572205468616e20426' + +- 'c6f636b2d53697a65204b6579202d2048617368204b657920' + +- '4669727374', 'hex'), +- hmac: { +- sha224: '95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e', +- sha256: +- '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f' + +- '0ee37f54', +- sha384: +- '4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05' + +- '033ac4c60c2ef6ab4030fe8296248df163f44952', +- sha512: +- '80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b0137' + +- '83f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec' + +- '8b915a985d786598' +- } +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaa', 'hex'), +- // 'This is a test using a larger than block-size key and a larger ' + +- // 'than block-size data. The key needs to be hashed before being ' + +- // 'used by the HMAC algorithm.' +- data: new Buffer('5468697320697320612074657374207573696e672061206c6' + +- '172676572207468616e20626c6f636b2d73697a65206b6579' + +- '20616e642061206c6172676572207468616e20626c6f636b2' + +- 'd73697a6520646174612e20546865206b6579206e65656473' + +- '20746f20626520686173686564206265666f7265206265696' + +- 'e6720757365642062792074686520484d414320616c676f72' + +- '6974686d2e', 'hex'), +- hmac: { +- sha224: '3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1', +- sha256: +- '9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f5153' + +- '5c3a35e2', +- sha384: +- '6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82' + +- '461e99c5a678cc31e799176d3860e6110c46523e', +- sha512: +- 'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d' + +- '20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de04460' + +- '65c97440fa8c6a58' +- } +- } +-]; +- +-for (let i = 0, l = rfc4231.length; i < l; i++) { +- for (var hash in rfc4231[i]['hmac']) { +- var result = crypto.createHmac(hash, rfc4231[i]['key']) +- .update(rfc4231[i]['data']) +- .digest('hex'); +- if (rfc4231[i]['truncate']) { +- result = result.substr(0, 32); // first 128 bits == 32 hex chars +- } +- assert.equal(rfc4231[i]['hmac'][hash], +- result, +- 'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' rfc 4231'); +- } +-} +- +-// Test HMAC-MD5/SHA1 (rfc 2202 Test Cases) +-var rfc2202_md5 = [ +- { +- key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), +- data: 'Hi There', +- hmac: '9294727a3638bb1c13f48ef8158bfc9d' +- }, +- { +- key: 'Jefe', +- data: 'what do ya want for nothing?', +- hmac: '750c783e6ab0b503eaa86e310a5db738' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), +- data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' + +- 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', +- 'hex'), +- hmac: '56be34521d144c88dbb8c733f0e8b3f6' +- }, +- { +- key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', +- 'hex'), +- data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + +- 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + +- 'cdcdcdcdcd', +- 'hex'), +- hmac: '697eaf0aca3a3aea3a75164746ffaa79' +- }, +- { +- key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), +- data: 'Test With Truncation', +- hmac: '56461ef2342edc00f9bab995690efd4c' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaa', +- 'hex'), +- data: 'Test Using Larger Than Block-Size Key - Hash Key First', +- hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaa', +- 'hex'), +- data: +- 'Test Using Larger Than Block-Size Key and Larger Than One ' + +- 'Block-Size Data', +- hmac: '6f630fad67cda0ee1fb1f562db3aa53e' +- } +-]; +-var rfc2202_sha1 = [ +- { +- key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), +- data: 'Hi There', +- hmac: 'b617318655057264e28bc0b6fb378c8ef146be00' +- }, +- { +- key: 'Jefe', +- data: 'what do ya want for nothing?', +- hmac: 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), +- data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddd' + +- 'ddddddddddddddddddddddddddddddddddddddddddddd' + +- 'dddddddddd', +- 'hex'), +- hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3' +- }, +- { +- key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819', +- 'hex'), +- data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + +- 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + +- 'cdcdcdcdcd', +- 'hex'), +- hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da' +- }, +- { +- key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), +- data: 'Test With Truncation', +- hmac: '4c1a03424b55e07fe7f27be1d58bb9324a9a5a04' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaa', +- 'hex'), +- data: 'Test Using Larger Than Block-Size Key - Hash Key First', +- hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112' +- }, +- { +- key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + +- 'aaaaaaaaaaaaaaaaaaaaaa', +- 'hex'), +- data: +- 'Test Using Larger Than Block-Size Key and Larger Than One ' + +- 'Block-Size Data', +- hmac: 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91' +- } +-]; +- +-for (let i = 0, l = rfc2202_md5.length; i < l; i++) { +- if (!common.hasFipsCrypto) { +- assert.equal(rfc2202_md5[i]['hmac'], +- crypto.createHmac('md5', rfc2202_md5[i]['key']) +- .update(rfc2202_md5[i]['data']) +- .digest('hex'), +- 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202'); +- } +-} +-for (let i = 0, l = rfc2202_sha1.length; i < l; i++) { +- assert.equal(rfc2202_sha1[i]['hmac'], +- crypto.createHmac('sha1', rfc2202_sha1[i]['key']) +- .update(rfc2202_sha1[i]['data']) +- .digest('hex'), +- 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202'); +-} +- +-// Test hashing +-var a1 = crypto.createHash('sha1').update('Test123').digest('hex'); +-var a2 = crypto.createHash('sha256').update('Test123').digest('base64'); +-var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary +-var a4 = crypto.createHash('sha1').update('Test123').digest('buffer'); +- +-if (!common.hasFipsCrypto) { +- 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'); +-} +- +-assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1'); +- +-assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=', +- 'Test SHA256 as base64'); +- +-assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' + +- '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' + +- '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' + +- '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' + +- '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'', +- 'Test SHA512 as assumed binary'); +- +-assert.deepEqual(a4, +- new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'), +- 'Test SHA1'); +- +-// Test multiple updates to same hash +-var h1 = crypto.createHash('sha1').update('Test123').digest('hex'); +-var h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex'); +-assert.equal(h1, h2, 'multipled updates'); +- +-// Test hashing for binary files +-var fn = path.join(common.fixturesDir, 'sample.png'); +-var sha1Hash = crypto.createHash('sha1'); +-var fileStream = fs.createReadStream(fn); +-fileStream.on('data', function(data) { +- sha1Hash.update(data); +-}); +-fileStream.on('close', function() { +- assert.equal(sha1Hash.digest('hex'), +- '22723e553129a336ad96e10f6aecdf0f45e4149e', +- 'Test SHA1 of sample.png'); +-}); +- +-// Issue #2227: unknown digest method should throw an error. +-assert.throws(function() { +- crypto.createHash('xyzzy'); +-}); +- +-// Test signing and verifying +-var s1 = crypto.createSign('RSA-SHA1') +- .update('Test123') +- .sign(keyPem, 'base64'); +-var s1Verified = crypto.createVerify('RSA-SHA1') +- .update('Test') +- .update('123') +- .verify(certPem, s1, 'base64'); +-assert.strictEqual(s1Verified, true, 'sign and verify (base 64)'); +- +-var s2 = crypto.createSign('RSA-SHA256') +- .update('Test123') +- .sign(keyPem); // binary +-var s2Verified = crypto.createVerify('RSA-SHA256') +- .update('Test') +- .update('123') +- .verify(certPem, s2); // binary +-assert.strictEqual(s2Verified, true, 'sign and verify (binary)'); +- +-var s3 = crypto.createSign('RSA-SHA1') +- .update('Test123') +- .sign(keyPem, 'buffer'); +-var s3Verified = crypto.createVerify('RSA-SHA1') +- .update('Test') +- .update('123') +- .verify(certPem, s3); +-assert.strictEqual(s3Verified, true, 'sign and verify (buffer)'); +- +- +-function testCipher1(key) { +- // Test encryption and decryption +- var plaintext = 'Keep this a secret? No! Tell everyone about node.js!'; +- var cipher = crypto.createCipher('aes192', key); +- +- // encrypt plaintext which is in utf8 format +- // to a ciphertext which will be in hex +- var ciph = cipher.update(plaintext, 'utf8', 'hex'); +- // Only use binary or hex, not base64. +- ciph += cipher.final('hex'); +- +- var decipher = crypto.createDecipher('aes192', key); +- var txt = decipher.update(ciph, 'hex', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption'); +-} +- +- +-function testCipher2(key) { +- // encryption and decryption with Base64 +- // reported in https://github.com/joyent/node/issues/738 +- var plaintext = +- '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + +- 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + +- 'jAfaFg**'; +- var cipher = crypto.createCipher('aes256', key); +- +- // encrypt plaintext which is in utf8 format +- // to a ciphertext which will be in Base64 +- var ciph = cipher.update(plaintext, 'utf8', 'base64'); +- ciph += cipher.final('base64'); +- +- var decipher = crypto.createDecipher('aes256', key); +- var txt = decipher.update(ciph, 'base64', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption with Base64'); +-} +- +- +-function testCipher3(key, iv) { +- // Test encyrption and decryption with explicit key and iv +- var plaintext = +- '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + +- 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + +- 'jAfaFg**'; +- var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); +- var ciph = cipher.update(plaintext, 'utf8', 'hex'); +- ciph += cipher.final('hex'); +- +- var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); +- var txt = decipher.update(ciph, 'hex', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption with key and iv'); +-} +- +- +-function testCipher4(key, iv) { +- // Test encyrption and decryption with explicit key and iv +- var plaintext = +- '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + +- 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + +- 'jAfaFg**'; +- var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); +- var ciph = cipher.update(plaintext, 'utf8', 'buffer'); +- ciph = Buffer.concat([ciph, cipher.final('buffer')]); +- +- var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); +- var txt = decipher.update(ciph, 'buffer', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption with key and iv'); +-} +- +-if (!common.hasFipsCrypto) { +- testCipher1('MySecretKey123'); +- testCipher1(new Buffer('MySecretKey123')); +- +- testCipher2('0123456789abcdef'); +- testCipher2(new Buffer('0123456789abcdef')); +-} +- +-testCipher3('0123456789abcd0123456789', '12345678'); +-testCipher3('0123456789abcd0123456789', new Buffer('12345678')); +-testCipher3(new Buffer('0123456789abcd0123456789'), '12345678'); +-testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678')); +- +-testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678')); +- +- +-// update() should only take buffers / strings +-assert.throws(function() { +- crypto.createHash('sha1').update({foo: 'bar'}); +-}, /buffer/); +- +- +-// Test Diffie-Hellman with two parties sharing a secret, +-// using various encodings as we go along +-var dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); +-var p1 = dh1.getPrime('buffer'); +-var dh2 = crypto.createDiffieHellman(p1, 'base64'); +-var key1 = dh1.generateKeys(); +-var key2 = dh2.generateKeys('hex'); +-var secret1 = dh1.computeSecret(key2, 'hex', 'base64'); +-var secret2 = dh2.computeSecret(key1, 'binary', 'buffer'); +- +-assert.equal(secret1, secret2.toString('base64')); +- +-// Create "another dh1" using generated keys from dh1, +-// and compute secret again +-var dh3 = crypto.createDiffieHellman(p1, 'buffer'); +-var privkey1 = dh1.getPrivateKey(); +-dh3.setPublicKey(key1); +-dh3.setPrivateKey(privkey1); +- +-assert.equal(dh1.getPrime(), dh3.getPrime()); +-assert.equal(dh1.getGenerator(), dh3.getGenerator()); +-assert.equal(dh1.getPublicKey(), dh3.getPublicKey()); +-assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey()); +- +-var secret3 = dh3.computeSecret(key2, 'hex', 'base64'); +- +-assert.equal(secret1, secret3); +- +-// https://github.com/joyent/node/issues/2338 +-var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + +- '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' + +- '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + +- 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; +-var d = crypto.createDiffieHellman(p, 'hex'); +-assert.equal(d.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +-// Test RSA key signing/verification +-var rsaSign = crypto.createSign('RSA-SHA1'); +-var rsaVerify = crypto.createVerify('RSA-SHA1'); +-assert.ok(rsaSign); +-assert.ok(rsaVerify); +- +-rsaSign.update(rsaPubPem); +-var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex'); +-assert.equal(rsaSignature, +- '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' + +- '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' + +- 'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' + +- '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' + +- '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6'); +- +-rsaVerify.update(rsaPubPem); +-assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); +- +- +-// +-// Test RSA signing and verification +-// +-(function() { +- var privateKey = fs.readFileSync( +- common.fixturesDir + '/test_rsa_privkey_2.pem'); +- +- var publicKey = fs.readFileSync( +- common.fixturesDir + '/test_rsa_pubkey_2.pem'); +- +- var input = 'I AM THE WALRUS'; +- +- var signature = +- '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89' + +- '396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa' + +- '235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb2' + +- '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' + +- '0ddfb299bedeb1ad'; +- +- var sign = crypto.createSign('RSA-SHA256'); +- sign.update(input); +- +- var output = sign.sign(privateKey, 'hex'); +- assert.equal(output, signature); +- +- var verify = crypto.createVerify('RSA-SHA256'); +- verify.update(input); +- +- assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); +-})(); +- +- +-// +-// Test DSA signing and verification +-// +-(function() { +- var privateKey = fs.readFileSync( +- common.fixturesDir + '/test_dsa_privkey.pem'); +- +- var publicKey = fs.readFileSync( +- common.fixturesDir + '/test_dsa_pubkey.pem'); +- +- var input = 'I AM THE WALRUS'; +- +- // DSA signatures vary across runs so there is no static string to verify +- // against +- var sign = crypto.createSign('DSS1'); +- sign.update(input); +- var signature = sign.sign(privateKey, 'hex'); +- +- var verify = crypto.createVerify('DSS1'); +- verify.update(input); +- +- assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); +-})(); +- +- +-// +-// Test PBKDF2 with RFC 6070 test vectors (except #4) +-// +-function testPBKDF2(password, salt, iterations, keylen, expected) { +- var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen); +- assert.equal(actual, expected); +- +- crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) { +- assert.equal(actual, expected); +- }); +-} +- +- +-testPBKDF2('password', 'salt', 1, 20, +- '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' + +- '\xaf\x60\x12\x06\x2f\xe0\x37\xa6'); +- +-testPBKDF2('password', 'salt', 2, 20, +- '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' + +- '\xce\x1d\x41\xf0\xd8\xde\x89\x57'); +- +-testPBKDF2('password', 'salt', 4096, 20, +- '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' + +- '\xf7\x21\xd0\x65\xa4\x29\xc1'); +- +-testPBKDF2('passwordPASSWORDpassword', +- 'saltSALTsaltSALTsaltSALTsaltSALTsalt', +- 4096, +- 25, +- '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' + +- '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38'); +- +-testPBKDF2('pass\0word', 'sa\0lt', 4096, 16, +- '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' + +- '\x25\xe0\xc3'); +diff --git a/test/parallel/test-crypto-cipher-decipher.js b/test/parallel/test-crypto-cipher-decipher.js +deleted file mode 100644 +index 5f86773..0000000 +--- a/test/parallel/test-crypto-cipher-decipher.js ++++ /dev/null +@@ -1,115 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-if (common.hasFipsCrypto) { +- console.log('1..0 # Skipped: not supported in FIPS mode'); +- return; +-} +-var crypto = require('crypto'); +- +-function testCipher1(key) { +- // Test encryption and decryption +- var plaintext = 'Keep this a secret? No! Tell everyone about node.js!'; +- var cipher = crypto.createCipher('aes192', key); +- +- // encrypt plaintext which is in utf8 format +- // to a ciphertext which will be in hex +- var ciph = cipher.update(plaintext, 'utf8', 'hex'); +- // Only use binary or hex, not base64. +- ciph += cipher.final('hex'); +- +- var decipher = crypto.createDecipher('aes192', key); +- var txt = decipher.update(ciph, 'hex', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption'); +- +- // streaming cipher interface +- // NB: In real life, it's not guaranteed that you can get all of it +- // in a single read() like this. But in this case, we know it's +- // quite small, so there's no harm. +- var cStream = crypto.createCipher('aes192', key); +- cStream.end(plaintext); +- ciph = cStream.read(); +- +- var dStream = crypto.createDecipher('aes192', key); +- dStream.end(ciph); +- txt = dStream.read().toString('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption with streams'); +-} +- +- +-function testCipher2(key) { +- // encryption and decryption with Base64 +- // reported in https://github.com/joyent/node/issues/738 +- var plaintext = +- '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + +- 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + +- 'jAfaFg**'; +- var cipher = crypto.createCipher('aes256', key); +- +- // encrypt plaintext which is in utf8 format +- // to a ciphertext which will be in Base64 +- var ciph = cipher.update(plaintext, 'utf8', 'base64'); +- ciph += cipher.final('base64'); +- +- var decipher = crypto.createDecipher('aes256', key); +- var txt = decipher.update(ciph, 'base64', 'utf8'); +- txt += decipher.final('utf8'); +- +- assert.equal(txt, plaintext, 'encryption and decryption with Base64'); +-} +- +-testCipher1('MySecretKey123'); +-testCipher1(new Buffer('MySecretKey123')); +- +-testCipher2('0123456789abcdef'); +-testCipher2(new Buffer('0123456789abcdef')); +- +-// Base64 padding regression test, see #4837. +-(function() { +- var c = crypto.createCipher('aes-256-cbc', 'secret'); +- var s = c.update('test', 'utf8', 'base64') + c.final('base64'); +- assert.equal(s, '375oxUQCIocvxmC5At+rvA=='); +-})(); +- +-// Calling Cipher.final() or Decipher.final() twice should error but +-// not assert. See #4886. +-(function() { +- var c = crypto.createCipher('aes-256-cbc', 'secret'); +- try { c.final('xxx'); } catch (e) { /* Ignore. */ } +- try { c.final('xxx'); } catch (e) { /* Ignore. */ } +- try { c.final('xxx'); } catch (e) { /* Ignore. */ } +- var d = crypto.createDecipher('aes-256-cbc', 'secret'); +- try { d.final('xxx'); } catch (e) { /* Ignore. */ } +- try { d.final('xxx'); } catch (e) { /* Ignore. */ } +- try { d.final('xxx'); } catch (e) { /* Ignore. */ } +-})(); +- +-// Regression test for #5482: string to Cipher#update() should not assert. +-(function() { +- var c = crypto.createCipher('aes192', '0123456789abcdef'); +- c.update('update'); +- c.final(); +-})(); +- +-// #5655 regression tests, 'utf-8' and 'utf8' are identical. +-(function() { +- var c = crypto.createCipher('aes192', '0123456789abcdef'); +- c.update('update', ''); // Defaults to "utf8". +- c.final('utf-8'); // Should not throw. +- +- c = crypto.createCipher('aes192', '0123456789abcdef'); +- c.update('update', 'utf8'); +- c.final('utf-8'); // Should not throw. +- +- c = crypto.createCipher('aes192', '0123456789abcdef'); +- c.update('update', 'utf-8'); +- c.final('utf8'); // Should not throw. +-})(); +diff --git a/test/parallel/test-crypto-dh-odd-key.js b/test/parallel/test-crypto-dh-odd-key.js +deleted file mode 100644 +index 503ba2f..0000000 +--- a/test/parallel/test-crypto-dh-odd-key.js ++++ /dev/null +@@ -1,25 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var crypto = require('crypto'); +- +-function test() { +- var odd = new Buffer(39); +- odd.fill('A'); +- +- var c = crypto.createDiffieHellman(32); +- c.setPrivateKey(odd); +- c.generateKeys(); +-} +- +-// FIPS requires a length of at least 1024 +-if (!common.hasFipsCrypto) { +- assert.doesNotThrow(function() { test(); }); +-} else { +- assert.throws(function() { test(); }, /key size too small/); +-} +diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js +deleted file mode 100644 +index 192e428..0000000 +--- a/test/parallel/test-crypto.js ++++ /dev/null +@@ -1,143 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +-var util = require('util'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var crypto = require('crypto'); +- +-crypto.DEFAULT_ENCODING = 'buffer'; +- +-var fs = require('fs'); +- +-// Test Certificates +-var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii'); +-var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); +-var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx'); +-var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); +-var tls = require('tls'); +- +-// 'this' safety +-// https://github.com/joyent/node/issues/6690 +-assert.throws(function() { +- var options = {key: keyPem, cert: certPem, ca: caPem}; +- var credentials = crypto.createCredentials(options); +- var context = credentials.context; +- var notcontext = { setOptions: context.setOptions, setKey: context.setKey }; +- crypto.createCredentials({ secureOptions: 1 }, notcontext); +-}, TypeError); +- +-// PFX tests +-assert.doesNotThrow(function() { +- tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); +-}); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:certPfx}); +-}, 'mac verify failure'); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:certPfx, passphrase:'test'}); +-}, 'mac verify failure'); +- +-assert.throws(function() { +- tls.createSecureContext({pfx:'sample', passphrase:'test'}); +-}, 'not enough data'); +- +- +-// update() should only take buffers / strings +-assert.throws(function() { +- crypto.createHash('sha1').update({foo: 'bar'}); +-}, /buffer/); +- +- +-function assertSorted(list) { +- // Array#sort() modifies the list in place so make a copy. +- var sorted = util._extend([], list).sort(); +- assert.deepEqual(list, sorted); +-} +- +-// Assume that we have at least AES-128-CBC. +-assert.notEqual(0, crypto.getCiphers().length); +-assert.notEqual(-1, crypto.getCiphers().indexOf('aes-128-cbc')); +-assert.equal(-1, crypto.getCiphers().indexOf('AES-128-CBC')); +-assertSorted(crypto.getCiphers()); +- +-// Assume that we have at least AES256-SHA. +-assert.notEqual(0, tls.getCiphers().length); +-assert.notEqual(-1, tls.getCiphers().indexOf('aes256-sha')); +-assert.equal(-1, tls.getCiphers().indexOf('AES256-SHA')); +-assertSorted(tls.getCiphers()); +- +-// Assert that we have sha and sha1 but not SHA and SHA1. +-assert.notEqual(0, crypto.getHashes().length); +-assert.notEqual(-1, crypto.getHashes().indexOf('sha1')); +-assert.notEqual(-1, crypto.getHashes().indexOf('sha')); +-assert.equal(-1, crypto.getHashes().indexOf('SHA1')); +-assert.equal(-1, crypto.getHashes().indexOf('SHA')); +-assert.notEqual(-1, crypto.getHashes().indexOf('RSA-SHA1')); +-assert.equal(-1, crypto.getHashes().indexOf('rsa-sha1')); +-assertSorted(crypto.getHashes()); +- +-// Assume that we have at least secp384r1. +-assert.notEqual(0, crypto.getCurves().length); +-assert.notEqual(-1, crypto.getCurves().indexOf('secp384r1')); +-assert.equal(-1, crypto.getCurves().indexOf('SECP384R1')); +-assertSorted(crypto.getCurves()); +- +-// Regression tests for #5725: hex input that's not a power of two should +-// throw, not assert in C++ land. +-assert.throws(function() { +- crypto.createCipher('aes192', 'test').update('0', 'hex'); +-}, common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/); +- +-assert.throws(function() { +- crypto.createDecipher('aes192', 'test').update('0', 'hex'); +-}, common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/); +- +-assert.throws(function() { +- crypto.createHash('sha1').update('0', 'hex'); +-}, /Bad input string/); +- +-assert.throws(function() { +- crypto.createSign('RSA-SHA1').update('0', 'hex'); +-}, /Bad input string/); +- +-assert.throws(function() { +- crypto.createVerify('RSA-SHA1').update('0', 'hex'); +-}, /Bad input string/); +- +-assert.throws(function() { +- var priv = [ +- '-----BEGIN RSA PRIVATE KEY-----', +- 'MIGrAgEAAiEA+3z+1QNF2/unumadiwEr+C5vfhezsb3hp4jAnCNRpPcCAwEAAQIgQNriSQK4', +- 'EFwczDhMZp2dvbcz7OUUyt36z3S4usFPHSECEQD/41K7SujrstBfoCPzwC1xAhEA+5kt4BJy', +- 'eKN7LggbF3Dk5wIQN6SL+fQ5H/+7NgARsVBp0QIRANxYRukavs4QvuyNhMx+vrkCEQCbf6j/', +- 'Ig6/HueCK/0Jkmp+', +- '-----END RSA PRIVATE KEY-----', +- '' +- ].join('\n'); +- crypto.createSign('RSA-SHA256').update('test').sign(priv); +-}, /digest too big for rsa key/); +- +-assert.throws(function() { +- // The correct header inside `test_bad_rsa_privkey.pem` should have been +- // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- +- // instead of +- // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- +- // It is generated in this way: +- // $ openssl genrsa -out mykey.pem 512; +- // $ openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \ +- // -out private_key.pem -nocrypt; +- // Then open private_key.pem and change its header and footer. +- var sha1_privateKey = fs.readFileSync(common.fixturesDir + +- '/test_bad_rsa_privkey.pem', 'ascii'); +- // this would inject errors onto OpenSSL's error stack +- crypto.createSign('sha1').sign(sha1_privateKey); +-}, /asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/); +- +-// Make sure memory isn't released before being returned +-console.log(crypto.randomBytes(16)); +diff --git a/test/parallel/test-net-connect-options-ipv6.js b/test/parallel/test-net-connect-options-ipv6.js +deleted file mode 100644 +index 5cce732..0000000 +--- a/test/parallel/test-net-connect-options-ipv6.js ++++ /dev/null +@@ -1,70 +0,0 @@ +-'use strict'; +-const common = require('../common'); +-const assert = require('assert'); +-const net = require('net'); +- +-if (!common.hasIPv6) { +- console.log('1..0 # Skipped: no IPv6 support'); +- return; +-} +- +-const hosts = common.localIPv6Hosts; +-var hostIdx = 0; +-var host = hosts[hostIdx]; +-var localhostTries = 10; +- +-const server = net.createServer({allowHalfOpen: true}, function(socket) { +- socket.resume(); +- socket.on('end', common.mustCall(function() {})); +- socket.end(); +-}); +- +-server.listen(common.PORT, '::1', tryConnect); +- +-function tryConnect() { +- const client = net.connect({ +- host: host, +- port: common.PORT, +- family: 6, +- allowHalfOpen: true +- }, function() { +- console.error('client connect cb'); +- client.resume(); +- client.on('end', common.mustCall(function() { +- setTimeout(function() { +- assert(client.writable); +- client.end(); +- }, 10); +- })); +- client.on('close', function() { +- server.close(); +- }); +- }).on('error', function(err) { +- // ENOTFOUND means we don't have the requested address. In this +- // case we try the next one in the list and if we run out of +- // candidates we assume IPv6 is not supported on the +- // machine and skip the test. +- // EAI_AGAIN means we tried to remotely resolve the address and +- // timed out or hit some intermittent connectivity issue with the +- // dns server. Although we are looking for local loopback addresses +- // we may go remote since the list we search includes addresses that +- // cover more than is available on any one distribution. The +- // net is that if we get an EAI_AGAIN we were looking for an +- // address which does not exist in this distribution so the error +- // is not significant and we should just move on and try the +- // next address in the list. +- if ((err.syscall === 'getaddrinfo') && ((err.code === 'ENOTFOUND') || +- (err.code === 'EAI_AGAIN'))) { +- if (host !== 'localhost' || --localhostTries === 0) +- host = hosts[++hostIdx]; +- if (host) +- tryConnect(); +- else { +- console.log('1..0 # Skipped: no IPv6 localhost support'); +- server.close(); +- } +- return; +- } +- throw err; +- }); +-} +diff --git a/test/parallel/test-npm-install.js b/test/parallel/test-npm-install.js +deleted file mode 100644 +index 0c2e4df..0000000 +--- a/test/parallel/test-npm-install.js ++++ /dev/null +@@ -1,47 +0,0 @@ +-'use strict'; +-const common = require('../common'); +- +-const path = require('path'); +-const spawn = require('child_process').spawn; +-const assert = require('assert'); +-const fs = require('fs'); +- +-common.refreshTmpDir(); +- +-const npmPath = path.join( +- common.testDir, +- '..', +- 'deps', +- 'npm', +- 'bin', +- 'npm-cli.js' +-); +- +-const args = [ +- npmPath, +- 'install' +-]; +- +-const pkgContent = JSON.stringify({ +- dependencies: { +- 'package-name': common.fixturesDir + '/packages/main' +- } +-}); +- +-const pkgPath = path.join(common.tmpDir, 'package.json'); +- +-fs.writeFileSync(pkgPath, pkgContent); +- +-const proc = spawn(process.execPath, args, { +- cwd: common.tmpDir +-}); +- +-function handleExit(code, signalCode) { +- assert.equal(code, 0, 'npm install should run without an error'); +- assert.ok(signalCode === null, 'signalCode should be null'); +- assert.doesNotThrow(function() { +- fs.accessSync(common.tmpDir + '/node_modules/package-name'); +- }); +-} +- +-proc.on('exit', common.mustCall(handleExit)); +diff --git a/test/parallel/test-stdout-close-unref.js b/test/parallel/test-stdout-close-unref.js +deleted file mode 100644 +index 37ab498..0000000 +--- a/test/parallel/test-stdout-close-unref.js ++++ /dev/null +@@ -1,16 +0,0 @@ +-'use strict'; +-require('../common'); +-var assert = require('assert'); +- +-var errs = 0; +- +-process.stdin.resume(); +-process.stdin._handle.close(); +-process.stdin._handle.unref(); // Should not segfault. +-process.stdin.on('error', function(err) { +- errs++; +-}); +- +-process.on('exit', function() { +- assert.strictEqual(errs, 1); +-}); +diff --git a/test/parallel/test-tls-cnnic-whitelist.js b/test/parallel/test-tls-cnnic-whitelist.js +deleted file mode 100644 +index 85e1d90..0000000 +--- a/test/parallel/test-tls-cnnic-whitelist.js ++++ /dev/null +@@ -1,83 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +- +-var tls = require('tls'); +-var fs = require('fs'); +-var path = require('path'); +-var finished = 0; +- +-function filenamePEM(n) { +- return path.join(common.fixturesDir, 'keys', n + '.pem'); +-} +- +-function loadPEM(n) { +- return fs.readFileSync(filenamePEM(n)); +-} +- +-var testCases = [ +- { // Test 0: for the check of a cert not existed in the whitelist. +- // agent7-cert.pem is issued by the fake CNNIC root CA so that its +- // hash is not listed in the whitelist. +- // fake-cnnic-root-cert has the same subject name as the original +- // rootCA. +- serverOpts: { +- key: loadPEM('agent7-key'), +- cert: loadPEM('agent7-cert') +- }, +- clientOpts: { +- port: common.PORT, +- rejectUnauthorized: true, +- ca: [loadPEM('fake-cnnic-root-cert')] +- }, +- errorCode: 'CERT_REVOKED' +- }, +- // Test 1: for the fix of node#2061 +- // agent6-cert.pem is signed by intermidate cert of ca3. +- // The server has a cert chain of agent6->ca3->ca1(root) but +- // tls.connect should be failed with an error of +- // UNABLE_TO_GET_ISSUER_CERT_LOCALLY since the root CA of ca1 is not +- // installed locally. +- { +- serverOpts: { +- ca: loadPEM('ca3-key'), +- key: loadPEM('agent6-key'), +- cert: loadPEM('agent6-cert') +- }, +- clientOpts: { +- port: common.PORT, +- rejectUnauthorized: true +- }, +- errorCode: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' +- } +-]; +- +-function runTest(tindex) { +- var tcase = testCases[tindex]; +- +- if (!tcase) return; +- +- var server = tls.createServer(tcase.serverOpts, function(s) { +- s.resume(); +- }).listen(common.PORT, function() { +- var client = tls.connect(tcase.clientOpts); +- client.on('error', function(e) { +- assert.strictEqual(e.code, tcase.errorCode); +- server.close(function() { +- finished++; +- runTest(tindex + 1); +- }); +- }); +- }); +-} +- +-runTest(0); +- +-process.on('exit', function() { +- assert.equal(finished, testCases.length); +-}); +diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js +deleted file mode 100644 +index ffcf529..0000000 +--- a/test/parallel/test-tls-dhe.js ++++ /dev/null +@@ -1,95 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var spawn = require('child_process').spawn; +-var fs = require('fs'); +-var key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); +-var cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); +-var nsuccess = 0; +-var ntests = 0; +-var ciphers = 'DHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; +- +- +-function loadDHParam(n) { +- var path = common.fixturesDir; +- if (n !== 'error') path += '/keys'; +- return fs.readFileSync(path + '/dh' + n + '.pem'); +-} +- +-function test(keylen, expectedCipher, cb) { +- var options = { +- key: key, +- cert: cert, +- ciphers: ciphers, +- dhparam: loadDHParam(keylen) +- }; +- +- var server = tls.createServer(options, function(conn) { +- conn.end(); +- }); +- +- server.on('close', function(err) { +- assert(!err); +- if (cb) cb(); +- }); +- +- server.listen(common.PORT, '127.0.0.1', function() { +- var args = ['s_client', '-connect', '127.0.0.1:' + common.PORT, +- '-cipher', ciphers]; +- +- // for the performance and stability issue in s_client on Windows +- if (common.isWindows) +- args.push('-no_rand_screen'); +- +- var client = spawn(common.opensslCli, args); +- var out = ''; +- client.stdout.setEncoding('utf8'); +- client.stdout.on('data', function(d) { +- out += d; +- }); +- client.stdout.on('end', function() { +- // DHE key length can be checked -brief option in s_client but it +- // is only supported in openssl 1.0.2 so we cannot check it. +- var reg = new RegExp('Cipher : ' + expectedCipher); +- if (reg.test(out)) { +- nsuccess++; +- server.close(); +- } +- }); +- }); +-} +- +-function test512() { +- assert.throws(function() { +- test(512, 'DHE-RSA-AES128-SHA256', null); +- }, /DH parameter is less than 1024 bits/); +-} +- +-function test1024() { +- test(1024, 'DHE-RSA-AES128-SHA256', test2048); +- ntests++; +-} +- +-function test2048() { +- test(2048, 'DHE-RSA-AES128-SHA256', testError); +- ntests++; +-} +- +-function testError() { +- test('error', 'ECDHE-RSA-AES128-SHA256', test512); +- ntests++; +-} +- +-test1024(); +- +-process.on('exit', function() { +- assert.equal(ntests, nsuccess); +- assert.equal(ntests, 3); +-}); +diff --git a/test/parallel/test-tls-ecdh-disable.js b/test/parallel/test-tls-ecdh-disable.js +deleted file mode 100644 +index 9bfb5f8..0000000 +--- a/test/parallel/test-tls-ecdh-disable.js ++++ /dev/null +@@ -1,46 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var exec = require('child_process').exec; +-var fs = require('fs'); +- +-var options = { +- key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'), +- cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'), +- ciphers: 'ECDHE-RSA-RC4-SHA', +- ecdhCurve: false +-}; +- +-var nconns = 0; +- +-process.on('exit', function() { +- assert.equal(nconns, 0); +-}); +- +-var server = tls.createServer(options, function(conn) { +- conn.end(); +- nconns++; +-}); +- +-server.listen(common.PORT, '127.0.0.1', function() { +- var cmd = '"' + common.opensslCli + '" s_client -cipher ' + options.ciphers + +- ' -connect 127.0.0.1:' + common.PORT; +- +- // for the performance and stability issue in s_client on Windows +- if (common.isWindows) +- cmd += ' -no_rand_screen'; +- +- exec(cmd, function(err, stdout, stderr) { +- // Old versions of openssl will still exit with 0 so we +- // can't just check if err is not null. +- assert.notEqual(stderr.indexOf('handshake failure'), -1); +- server.close(); +- }); +-}); +diff --git a/test/parallel/test-tls-ecdh.js b/test/parallel/test-tls-ecdh.js +deleted file mode 100644 +index a6e1611..0000000 +--- a/test/parallel/test-tls-ecdh.js ++++ /dev/null +@@ -1,48 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var exec = require('child_process').exec; +-var fs = require('fs'); +- +-var options = { +- key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'), +- cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'), +- ciphers: '-ALL:ECDHE-RSA-AES128-SHA256', +- ecdhCurve: 'prime256v1' +-}; +- +-var reply = 'I AM THE WALRUS'; // something recognizable +-var nconns = 0; +-var response = ''; +- +-process.on('exit', function() { +- assert.equal(nconns, 1); +- assert.notEqual(response.indexOf(reply), -1); +-}); +- +-var server = tls.createServer(options, function(conn) { +- conn.end(reply); +- nconns++; +-}); +- +-server.listen(common.PORT, '127.0.0.1', function() { +- var cmd = '"' + common.opensslCli + '" s_client -cipher ' + options.ciphers + +- ' -connect 127.0.0.1:' + common.PORT; +- +- // for the performance and stability issue in s_client on Windows +- if (common.isWindows) +- cmd += ' -no_rand_screen'; +- +- exec(cmd, function(err, stdout, stderr) { +- if (err) throw err; +- response = stdout; +- server.close(); +- }); +-}); +diff --git a/test/parallel/test-tls-js-stream.js b/test/parallel/test-tls-js-stream.js +deleted file mode 100644 +index 1c5e749..0000000 +--- a/test/parallel/test-tls-js-stream.js ++++ /dev/null +@@ -1,76 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var stream = require('stream'); +-var fs = require('fs'); +-var net = require('net'); +- +-var connected = { +- client: 0, +- server: 0 +-}; +- +-var server = tls.createServer({ +- key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), +- cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') +-}, function(c) { +- console.log('new client'); +- connected.server++; +- c.end('ohai'); +-}).listen(common.PORT, function() { +- var raw = net.connect(common.PORT); +- +- var pending = false; +- raw.on('readable', function() { +- if (pending) +- p._read(); +- }); +- +- var p = new stream.Duplex({ +- read: function read() { +- pending = false; +- +- var chunk = raw.read(); +- if (chunk) { +- console.log('read', chunk); +- this.push(chunk); +- } else { +- pending = true; +- } +- }, +- write: function write(data, enc, cb) { +- console.log('write', data, enc); +- raw.write(data, enc, cb); +- } +- }); +- +- var socket = tls.connect({ +- socket: p, +- rejectUnauthorized: false +- }, function() { +- console.log('client secure'); +- +- connected.client++; +- +- socket.end('hello'); +- socket.resume(); +- socket.destroy(); +- }); +- +- socket.once('close', function() { +- console.log('client close'); +- server.close(); +- }); +-}); +- +-process.once('exit', function() { +- assert.equal(connected.client, 1); +- assert.equal(connected.server, 1); +-}); +diff --git a/test/parallel/test-tls-ocsp-callback.js b/test/parallel/test-tls-ocsp-callback.js +deleted file mode 100644 +index e9443f4..0000000 +--- a/test/parallel/test-tls-ocsp-callback.js ++++ /dev/null +@@ -1,130 +0,0 @@ +-'use strict'; +-var common = require('../common'); +- +-if (!process.features.tls_ocsp) { +- console.log('1..0 # Skipped: node compiled without OpenSSL or ' + +- 'with old OpenSSL version.'); +- return; +-} +-if (!common.opensslCli) { +- console.log('1..0 # Skipped: node compiled without OpenSSL CLI.'); +- return; +-} +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var assert = require('assert'); +-var constants = require('constants'); +-var fs = require('fs'); +-var join = require('path').join; +- +-var pfx = fs.readFileSync(join(common.fixturesDir, 'keys', 'agent1-pfx.pem')); +- +-function test(testOptions, cb) { +- +- var keyFile = join(common.fixturesDir, 'keys', 'agent1-key.pem'); +- var certFile = join(common.fixturesDir, 'keys', 'agent1-cert.pem'); +- var caFile = join(common.fixturesDir, 'keys', 'ca1-cert.pem'); +- var key = fs.readFileSync(keyFile); +- var cert = fs.readFileSync(certFile); +- var ca = fs.readFileSync(caFile); +- var options = { +- key: key, +- cert: cert, +- ca: [ca] +- }; +- var requestCount = 0; +- var clientSecure = 0; +- var ocspCount = 0; +- var ocspResponse; +- +- if (testOptions.pfx) { +- delete options.key; +- delete options.cert; +- options.pfx = testOptions.pfx; +- options.passphrase = testOptions.passphrase; +- } +- +- var server = tls.createServer(options, function(cleartext) { +- cleartext.on('error', function(er) { +- // We're ok with getting ECONNRESET in this test, but it's +- // timing-dependent, and thus unreliable. Any other errors +- // are just failures, though. +- if (er.code !== 'ECONNRESET') +- throw er; +- }); +- ++requestCount; +- cleartext.end(); +- }); +- server.on('OCSPRequest', function(cert, issuer, callback) { +- ++ocspCount; +- assert.ok(Buffer.isBuffer(cert)); +- assert.ok(Buffer.isBuffer(issuer)); +- +- // Just to check that async really works there +- setTimeout(function() { +- callback(null, +- testOptions.response ? new Buffer(testOptions.response) : null); +- }, 100); +- }); +- server.listen(common.PORT, function() { +- var client = tls.connect({ +- port: common.PORT, +- requestOCSP: testOptions.ocsp !== false, +- secureOptions: testOptions.ocsp === false ? +- constants.SSL_OP_NO_TICKET : 0, +- rejectUnauthorized: false +- }, function() { +- clientSecure++; +- }); +- client.on('OCSPResponse', function(resp) { +- ocspResponse = resp; +- if (resp) +- client.destroy(); +- }); +- client.on('close', function() { +- server.close(cb); +- }); +- }); +- +- process.on('exit', function() { +- if (testOptions.ocsp === false) { +- assert.equal(requestCount, clientSecure); +- assert.equal(requestCount, 1); +- return; +- } +- +- if (testOptions.response) { +- assert.equal(ocspResponse.toString(), testOptions.response); +- } else { +- assert.ok(ocspResponse === null); +- } +- assert.equal(requestCount, testOptions.response ? 0 : 1); +- assert.equal(clientSecure, requestCount); +- assert.equal(ocspCount, 1); +- }); +-} +- +-var tests = [ +- { response: false }, +- { response: 'hello world' }, +- { ocsp: false } +-]; +- +-if (!common.hasFipsCrypto) { +- tests.push({ pfx: pfx, passphrase: 'sample', response: 'hello pfx' }); +-} +- +-function runTests(i) { +- if (i === tests.length) return; +- +- test(tests[i], common.mustCall(function() { +- runTests(i + 1); +- })); +-} +- +-runTests(0); +diff --git a/test/parallel/test-tls-pfx-gh-5100-regr.js b/test/parallel/test-tls-pfx-gh-5100-regr.js +deleted file mode 100644 +index 865ac2b..0000000 +--- a/test/parallel/test-tls-pfx-gh-5100-regr.js ++++ /dev/null +@@ -1,36 +0,0 @@ +-'use strict'; +- +-const common = require('../common'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: node compiled without crypto.'); +- return; +-} +- +-const assert = require('assert'); +-const tls = require('tls'); +-const fs = require('fs'); +-const path = require('path'); +- +-const pfx = fs.readFileSync( +- path.join(common.fixturesDir, 'keys', 'agent1-pfx.pem')); +- +-const server = tls.createServer({ +- pfx: pfx, +- passphrase: 'sample', +- requestCert: true, +- rejectUnauthorized: false +-}, common.mustCall(function(c) { +- assert(c.authorizationError === null, 'authorizationError must be null'); +- c.end(); +-})).listen(common.PORT, function() { +- var client = tls.connect({ +- port: common.PORT, +- pfx: pfx, +- passphrase: 'sample', +- rejectUnauthorized: false +- }, function() { +- client.end(); +- server.close(); +- }); +-}); +diff --git a/test/parallel/test-tls-securepair-server.js b/test/parallel/test-tls-securepair-server.js +deleted file mode 100644 +index ef182f3..0000000 +--- a/test/parallel/test-tls-securepair-server.js ++++ /dev/null +@@ -1,138 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-var join = require('path').join; +-var net = require('net'); +-var fs = require('fs'); +-var spawn = require('child_process').spawn; +- +-var connections = 0; +-var key = fs.readFileSync(join(common.fixturesDir, 'agent.key')).toString(); +-var cert = fs.readFileSync(join(common.fixturesDir, 'agent.crt')).toString(); +- +-function log(a) { +- console.error('***server*** ' + a); +-} +- +-var server = net.createServer(function(socket) { +- connections++; +- log('connection fd=' + socket.fd); +- var sslcontext = tls.createSecureContext({key: key, cert: cert}); +- sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); +- +- var pair = tls.createSecurePair(sslcontext, true); +- +- assert.ok(pair.encrypted.writable); +- assert.ok(pair.cleartext.writable); +- +- pair.encrypted.pipe(socket); +- socket.pipe(pair.encrypted); +- +- log('i set it secure'); +- +- pair.on('secure', function() { +- log('connected+secure!'); +- pair.cleartext.write('hello\r\n'); +- log(pair.cleartext.getPeerCertificate()); +- log(pair.cleartext.getCipher()); +- }); +- +- pair.cleartext.on('data', function(data) { +- log('read bytes ' + data.length); +- pair.cleartext.write(data); +- }); +- +- socket.on('end', function() { +- log('socket end'); +- }); +- +- pair.cleartext.on('error', function(err) { +- log('got error: '); +- log(err); +- log(err.stack); +- socket.destroy(); +- }); +- +- pair.encrypted.on('error', function(err) { +- log('encrypted error: '); +- log(err); +- log(err.stack); +- socket.destroy(); +- }); +- +- socket.on('error', function(err) { +- log('socket error: '); +- log(err); +- log(err.stack); +- socket.destroy(); +- }); +- +- socket.on('close', function(err) { +- log('socket closed'); +- }); +- +- pair.on('error', function(err) { +- log('secure error: '); +- log(err); +- log(err.stack); +- socket.destroy(); +- }); +-}); +- +-var gotHello = false; +-var sentWorld = false; +-var gotWorld = false; +-var opensslExitCode = -1; +- +-server.listen(common.PORT, function() { +- // To test use: openssl s_client -connect localhost:8000 +- +- var args = ['s_client', '-connect', '127.0.0.1:' + common.PORT]; +- +- // for the performance and stability issue in s_client on Windows +- if (common.isWindows) +- args.push('-no_rand_screen'); +- +- var client = spawn(common.opensslCli, args); +- +- +- var out = ''; +- +- client.stdout.setEncoding('utf8'); +- client.stdout.on('data', function(d) { +- out += d; +- +- if (!gotHello && /hello/.test(out)) { +- gotHello = true; +- client.stdin.write('world\r\n'); +- sentWorld = true; +- } +- +- if (!gotWorld && /world/.test(out)) { +- gotWorld = true; +- client.stdin.end(); +- } +- }); +- +- client.stdout.pipe(process.stdout, { end: false }); +- +- client.on('exit', function(code) { +- opensslExitCode = code; +- server.close(); +- }); +-}); +- +-process.on('exit', function() { +- assert.equal(1, connections); +- assert.ok(gotHello); +- assert.ok(sentWorld); +- assert.ok(gotWorld); +- assert.equal(0, opensslExitCode); +-}); +diff --git a/test/parallel/test-tls-sni-option.js b/test/parallel/test-tls-sni-option.js +deleted file mode 100644 +index 83e6213..0000000 +--- a/test/parallel/test-tls-sni-option.js ++++ /dev/null +@@ -1,169 +0,0 @@ +-'use strict'; +-if (!process.features.tls_sni) { +- console.log('1..0 # Skipped: node compiled without OpenSSL or ' + +- 'with old OpenSSL version.'); +- return; +-} +- +-const common = require('../common'); +-const assert = require('assert'); +-const fs = require('fs'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-function filenamePEM(n) { +- return require('path').join(common.fixturesDir, 'keys', n + '.pem'); +-} +- +-function loadPEM(n) { +- return fs.readFileSync(filenamePEM(n)); +-} +- +-var serverOptions = { +- key: loadPEM('agent2-key'), +- cert: loadPEM('agent2-cert'), +- requestCert: true, +- rejectUnauthorized: false, +- SNICallback: function(servername, callback) { +- var context = SNIContexts[servername]; +- +- // Just to test asynchronous callback +- setTimeout(function() { +- if (context) { +- if (context.emptyRegression) +- callback(null, {}); +- else +- callback(null, tls.createSecureContext(context)); +- } else { +- callback(null, null); +- } +- }, 100); +- } +-}; +- +-var SNIContexts = { +- 'a.example.com': { +- key: loadPEM('agent1-key'), +- cert: loadPEM('agent1-cert'), +- ca: [ loadPEM('ca2-cert') ] +- }, +- 'b.example.com': { +- key: loadPEM('agent3-key'), +- cert: loadPEM('agent3-cert') +- }, +- 'c.another.com': { +- emptyRegression: true +- } +-}; +- +-var serverPort = common.PORT; +- +-var clientsOptions = [{ +- port: serverPort, +- key: loadPEM('agent1-key'), +- cert: loadPEM('agent1-cert'), +- ca: [loadPEM('ca1-cert')], +- servername: 'a.example.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- key: loadPEM('agent4-key'), +- cert: loadPEM('agent4-cert'), +- ca: [loadPEM('ca1-cert')], +- servername: 'a.example.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- key: loadPEM('agent2-key'), +- cert: loadPEM('agent2-cert'), +- ca: [loadPEM('ca2-cert')], +- servername: 'b.example.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- key: loadPEM('agent3-key'), +- cert: loadPEM('agent3-cert'), +- ca: [loadPEM('ca1-cert')], +- servername: 'c.wrong.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- key: loadPEM('agent3-key'), +- cert: loadPEM('agent3-cert'), +- ca: [loadPEM('ca1-cert')], +- servername: 'c.another.com', +- rejectUnauthorized: false +-}]; +- +-const serverResults = []; +-const clientResults = []; +-const serverErrors = []; +-const clientErrors = []; +-let serverError; +-let clientError; +- +-var server = tls.createServer(serverOptions, function(c) { +- serverResults.push({ sni: c.servername, authorized: c.authorized }); +-}); +- +-server.on('clientError', function(err) { +- serverResults.push(null); +- serverError = err.message; +-}); +- +-server.listen(serverPort, startTest); +- +-function startTest() { +- function connectClient(i, callback) { +- var options = clientsOptions[i]; +- clientError = null; +- serverError = null; +- +- var client = tls.connect(options, function() { +- clientResults.push( +- /Hostname\/IP doesn't/.test(client.authorizationError || '')); +- client.destroy(); +- +- next(); +- }); +- +- client.on('error', function(err) { +- clientResults.push(false); +- clientError = err.message; +- next(); +- }); +- +- function next() { +- clientErrors.push(clientError); +- serverErrors.push(serverError); +- +- if (i === clientsOptions.length - 1) +- callback(); +- else +- connectClient(i + 1, callback); +- } +- } +- +- connectClient(0, function() { +- server.close(); +- }); +-} +- +-process.on('exit', function() { +- assert.deepEqual(serverResults, [ +- { sni: 'a.example.com', authorized: false }, +- { sni: 'a.example.com', authorized: true }, +- { sni: 'b.example.com', authorized: false }, +- { sni: 'c.wrong.com', authorized: false }, +- null +- ]); +- assert.deepEqual(clientResults, [true, true, true, false, false]); +- assert.deepEqual(clientErrors, [null, null, null, null, 'socket hang up']); +- assert.deepEqual(serverErrors, [ +- null, null, null, null, 'Invalid SNI context' +- ]); +-}); +diff --git a/test/parallel/test-tls-sni-server-client.js b/test/parallel/test-tls-sni-server-client.js +deleted file mode 100644 +index 733713c..0000000 +--- a/test/parallel/test-tls-sni-server-client.js ++++ /dev/null +@@ -1,117 +0,0 @@ +-'use strict'; +-if (!process.features.tls_sni) { +- console.log('1..0 # Skipped: node compiled without OpenSSL or ' + +- 'with old OpenSSL version.'); +- return; +-} +- +-const common = require('../common'); +-const assert = require('assert'); +-const fs = require('fs'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var tls = require('tls'); +- +-function filenamePEM(n) { +- return require('path').join(common.fixturesDir, 'keys', n + '.pem'); +-} +- +-function loadPEM(n) { +- return fs.readFileSync(filenamePEM(n)); +-} +- +-var serverOptions = { +- key: loadPEM('agent2-key'), +- cert: loadPEM('agent2-cert') +-}; +- +-var SNIContexts = { +- 'a.example.com': { +- key: loadPEM('agent1-key'), +- cert: loadPEM('agent1-cert') +- }, +- 'asterisk.test.com': { +- key: loadPEM('agent3-key'), +- cert: loadPEM('agent3-cert') +- }, +- 'chain.example.com': { +- key: loadPEM('agent6-key'), +- // NOTE: Contains ca3 chain cert +- cert: loadPEM('agent6-cert') +- } +-}; +- +-var serverPort = common.PORT; +- +-var clientsOptions = [{ +- port: serverPort, +- ca: [loadPEM('ca1-cert')], +- servername: 'a.example.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- ca: [loadPEM('ca2-cert')], +- servername: 'b.test.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- ca: [loadPEM('ca2-cert')], +- servername: 'a.b.test.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- ca: [loadPEM('ca1-cert')], +- servername: 'c.wrong.com', +- rejectUnauthorized: false +-}, { +- port: serverPort, +- ca: [loadPEM('ca1-cert')], +- servername: 'chain.example.com', +- rejectUnauthorized: false +-}]; +- +-const serverResults = []; +-const clientResults = []; +- +-var server = tls.createServer(serverOptions, function(c) { +- serverResults.push(c.servername); +-}); +- +-server.addContext('a.example.com', SNIContexts['a.example.com']); +-server.addContext('*.test.com', SNIContexts['asterisk.test.com']); +-server.addContext('chain.example.com', SNIContexts['chain.example.com']); +- +-server.listen(serverPort, startTest); +- +-function startTest() { +- var i = 0; +- function start() { +- // No options left +- if (i === clientsOptions.length) +- return server.close(); +- +- var options = clientsOptions[i++]; +- var client = tls.connect(options, function() { +- clientResults.push( +- client.authorizationError && +- /Hostname\/IP doesn't/.test(client.authorizationError)); +- client.destroy(); +- +- // Continue +- start(); +- }); +- } +- +- start(); +-} +- +-process.on('exit', function() { +- assert.deepEqual(serverResults, [ +- 'a.example.com', 'b.test.com', 'a.b.test.com', 'c.wrong.com', +- 'chain.example.com' +- ]); +- assert.deepEqual(clientResults, [true, true, false, false, true]); +-}); +-- +1.8.3.1 + diff --git a/SOURCES/nodejs-disable-failing-tests.patch b/SOURCES/nodejs-disable-failing-tests.patch new file mode 100644 index 0000000..5055483 --- /dev/null +++ b/SOURCES/nodejs-disable-failing-tests.patch @@ -0,0 +1,459 @@ +From 106474d876b3e371487e87ccbe2e49bb396047fb Mon Sep 17 00:00:00 2001 +From: Tomas Hrcka +Date: Thu, 31 Mar 2016 15:58:28 +0200 +Subject: [PATCH] Disable failing tests + +--- + test/disabled/test-crypto-dh.js | 190 ++++++++++++++++++++++++++++++ + test/disabled/test-http-header-obstext.js | 18 +++ + test/parallel/test-crypto-dh.js | 190 ------------------------------ + test/parallel/test-http-header-obstext.js | 18 --- + 4 files changed, 208 insertions(+), 208 deletions(-) + create mode 100644 test/disabled/test-crypto-dh.js + create mode 100644 test/disabled/test-http-header-obstext.js + delete mode 100644 test/parallel/test-crypto-dh.js + delete mode 100644 test/parallel/test-http-header-obstext.js + +diff --git a/test/disabled/test-crypto-dh.js b/test/disabled/test-crypto-dh.js +new file mode 100644 +index 0000000..d391945 +--- /dev/null ++++ b/test/disabled/test-crypto-dh.js +@@ -0,0 +1,190 @@ ++'use strict'; ++var common = require('../common'); ++var assert = require('assert'); ++var constants = require('constants'); ++ ++if (!common.hasCrypto) { ++ console.log('1..0 # Skipped: missing crypto'); ++ return; ++} ++var crypto = require('crypto'); ++ ++// Test Diffie-Hellman with two parties sharing a secret, ++// using various encodings as we go along ++var dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); ++var p1 = dh1.getPrime('buffer'); ++var dh2 = crypto.createDiffieHellman(p1, 'buffer'); ++var key1 = dh1.generateKeys(); ++var key2 = dh2.generateKeys('hex'); ++var secret1 = dh1.computeSecret(key2, 'hex', 'base64'); ++var secret2 = dh2.computeSecret(key1, 'binary', 'buffer'); ++ ++assert.equal(secret1, secret2.toString('base64')); ++assert.equal(dh1.verifyError, 0); ++assert.equal(dh2.verifyError, 0); ++ ++assert.throws(function() { ++ crypto.createDiffieHellman([0x1, 0x2]); ++}); ++ ++assert.throws(function() { ++ crypto.createDiffieHellman(function() { }); ++}); ++ ++assert.throws(function() { ++ crypto.createDiffieHellman(/abc/); ++}); ++ ++assert.throws(function() { ++ crypto.createDiffieHellman({}); ++}); ++ ++// Create "another dh1" using generated keys from dh1, ++// and compute secret again ++var dh3 = crypto.createDiffieHellman(p1, 'buffer'); ++var privkey1 = dh1.getPrivateKey(); ++dh3.setPublicKey(key1); ++dh3.setPrivateKey(privkey1); ++ ++assert.deepEqual(dh1.getPrime(), dh3.getPrime()); ++assert.deepEqual(dh1.getGenerator(), dh3.getGenerator()); ++assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey()); ++assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey()); ++assert.equal(dh3.verifyError, 0); ++ ++var secret3 = dh3.computeSecret(key2, 'hex', 'base64'); ++ ++assert.equal(secret1, secret3); ++ ++// Run this one twice to make sure that the dh3 clears its error properly ++(function() { ++ var c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); ++ assert.throws(function() { c.final('utf8'); }, /wrong final block length/); ++})(); ++ ++assert.throws(function() { ++ dh3.computeSecret(''); ++}, /key is too small/i); ++ ++(function() { ++ var c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); ++ assert.throws(function() { c.final('utf8'); }, /wrong final block length/); ++})(); ++ ++// Create a shared using a DH group. ++var alice = crypto.createDiffieHellmanGroup('modp5'); ++var bob = crypto.createDiffieHellmanGroup('modp5'); ++alice.generateKeys(); ++bob.generateKeys(); ++var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex'); ++var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex'); ++assert.equal(aSecret, bSecret); ++assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++/* Ensure specific generator (buffer) works as expected. ++ * The values below (modp2/modp2buf) are for a 1024 bits long prime from ++ * RFC 2412 E.2, see https://tools.ietf.org/html/rfc2412. */ ++var modp2 = crypto.createDiffieHellmanGroup('modp2'); ++var modp2buf = new Buffer([ ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, ++ 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, ++ 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, ++ 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, ++ 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, ++ 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, ++ 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, ++ 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, ++ 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, ++ 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, ++ 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, ++ 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ++]); ++var exmodp2 = crypto.createDiffieHellman(modp2buf, new Buffer([2])); ++modp2.generateKeys(); ++exmodp2.generateKeys(); ++var modp2Secret = modp2.computeSecret(exmodp2.getPublicKey()).toString('hex'); ++var exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey()).toString('hex'); ++assert.equal(modp2Secret, exmodp2Secret); ++assert.equal(modp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++assert.equal(exmodp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++ ++// Ensure specific generator (string with encoding) works as expected. ++var exmodp2_2 = crypto.createDiffieHellman(modp2buf, '02', 'hex'); ++exmodp2_2.generateKeys(); ++modp2Secret = modp2.computeSecret(exmodp2_2.getPublicKey()).toString('hex'); ++var exmodp2_2Secret = exmodp2_2.computeSecret(modp2.getPublicKey()) ++ .toString('hex'); ++assert.equal(modp2Secret, exmodp2_2Secret); ++assert.equal(exmodp2_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++ ++// Ensure specific generator (string without encoding) works as expected. ++var exmodp2_3 = crypto.createDiffieHellman(modp2buf, '\x02'); ++exmodp2_3.generateKeys(); ++modp2Secret = modp2.computeSecret(exmodp2_3.getPublicKey()).toString('hex'); ++var exmodp2_3Secret = exmodp2_3.computeSecret(modp2.getPublicKey()) ++ .toString('hex'); ++assert.equal(modp2Secret, exmodp2_3Secret); ++assert.equal(exmodp2_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++ ++// Ensure specific generator (numeric) works as expected. ++var exmodp2_4 = crypto.createDiffieHellman(modp2buf, 2); ++exmodp2_4.generateKeys(); ++modp2Secret = modp2.computeSecret(exmodp2_4.getPublicKey()).toString('hex'); ++var exmodp2_4Secret = exmodp2_4.computeSecret(modp2.getPublicKey()) ++ .toString('hex'); ++assert.equal(modp2Secret, exmodp2_4Secret); ++assert.equal(exmodp2_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++ ++var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + ++ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' + ++ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + ++ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; ++var bad_dh = crypto.createDiffieHellman(p, 'hex'); ++assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); ++ ++ ++// Test ECDH ++var ecdh1 = crypto.createECDH('prime256v1'); ++var ecdh2 = crypto.createECDH('prime256v1'); ++key1 = ecdh1.generateKeys(); ++key2 = ecdh2.generateKeys('hex'); ++secret1 = ecdh1.computeSecret(key2, 'hex', 'base64'); ++secret2 = ecdh2.computeSecret(key1, 'binary', 'buffer'); ++ ++assert.equal(secret1, secret2.toString('base64')); ++ ++// Oakley curves do not clean up ERR stack, it was causing unexpected failure ++// when accessing other OpenSSL APIs afterwards. ++crypto.createECDH('Oakley-EC2N-3'); ++crypto.createHash('sha256'); ++ ++// Point formats ++assert.equal(ecdh1.getPublicKey('buffer', 'uncompressed')[0], 4); ++var firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0]; ++assert(firstByte === 2 || firstByte === 3); ++firstByte = ecdh1.getPublicKey('buffer', 'hybrid')[0]; ++assert(firstByte === 6 || firstByte === 7); ++ ++// ECDH should check that point is on curve ++var ecdh3 = crypto.createECDH('secp256k1'); ++var key3 = ecdh3.generateKeys(); ++ ++assert.throws(function() { ++ ecdh2.computeSecret(key3, 'binary', 'buffer'); ++}); ++ ++// ECDH should allow .setPrivateKey()/.setPublicKey() ++var ecdh4 = crypto.createECDH('prime256v1'); ++ ++ecdh4.setPrivateKey(ecdh1.getPrivateKey()); ++ecdh4.setPublicKey(ecdh1.getPublicKey()); ++ ++assert.throws(function() { ++ ecdh4.setPublicKey(ecdh3.getPublicKey()); ++}); +diff --git a/test/disabled/test-http-header-obstext.js b/test/disabled/test-http-header-obstext.js +new file mode 100644 +index 0000000..ba28768 +--- /dev/null ++++ b/test/disabled/test-http-header-obstext.js +@@ -0,0 +1,18 @@ ++'use strict'; ++ ++const common = require('../common'); ++const http = require('http'); ++const assert = require('assert'); ++ ++const server = http.createServer(common.mustCall((req, res) => { ++ res.end('ok'); ++})); ++server.listen(common.PORT, () => { ++ http.get({ ++ port: common.PORT, ++ headers: {'Test': 'Düsseldorf'} ++ }, common.mustCall((res) => { ++ assert.equal(res.statusCode, 200); ++ server.close(); ++ })); ++}); +diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js +deleted file mode 100644 +index d391945..0000000 +--- a/test/parallel/test-crypto-dh.js ++++ /dev/null +@@ -1,190 +0,0 @@ +-'use strict'; +-var common = require('../common'); +-var assert = require('assert'); +-var constants = require('constants'); +- +-if (!common.hasCrypto) { +- console.log('1..0 # Skipped: missing crypto'); +- return; +-} +-var crypto = require('crypto'); +- +-// Test Diffie-Hellman with two parties sharing a secret, +-// using various encodings as we go along +-var dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); +-var p1 = dh1.getPrime('buffer'); +-var dh2 = crypto.createDiffieHellman(p1, 'buffer'); +-var key1 = dh1.generateKeys(); +-var key2 = dh2.generateKeys('hex'); +-var secret1 = dh1.computeSecret(key2, 'hex', 'base64'); +-var secret2 = dh2.computeSecret(key1, 'binary', 'buffer'); +- +-assert.equal(secret1, secret2.toString('base64')); +-assert.equal(dh1.verifyError, 0); +-assert.equal(dh2.verifyError, 0); +- +-assert.throws(function() { +- crypto.createDiffieHellman([0x1, 0x2]); +-}); +- +-assert.throws(function() { +- crypto.createDiffieHellman(function() { }); +-}); +- +-assert.throws(function() { +- crypto.createDiffieHellman(/abc/); +-}); +- +-assert.throws(function() { +- crypto.createDiffieHellman({}); +-}); +- +-// Create "another dh1" using generated keys from dh1, +-// and compute secret again +-var dh3 = crypto.createDiffieHellman(p1, 'buffer'); +-var privkey1 = dh1.getPrivateKey(); +-dh3.setPublicKey(key1); +-dh3.setPrivateKey(privkey1); +- +-assert.deepEqual(dh1.getPrime(), dh3.getPrime()); +-assert.deepEqual(dh1.getGenerator(), dh3.getGenerator()); +-assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey()); +-assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey()); +-assert.equal(dh3.verifyError, 0); +- +-var secret3 = dh3.computeSecret(key2, 'hex', 'base64'); +- +-assert.equal(secret1, secret3); +- +-// Run this one twice to make sure that the dh3 clears its error properly +-(function() { +- var c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); +- assert.throws(function() { c.final('utf8'); }, /wrong final block length/); +-})(); +- +-assert.throws(function() { +- dh3.computeSecret(''); +-}, /key is too small/i); +- +-(function() { +- var c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); +- assert.throws(function() { c.final('utf8'); }, /wrong final block length/); +-})(); +- +-// Create a shared using a DH group. +-var alice = crypto.createDiffieHellmanGroup('modp5'); +-var bob = crypto.createDiffieHellmanGroup('modp5'); +-alice.generateKeys(); +-bob.generateKeys(); +-var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex'); +-var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex'); +-assert.equal(aSecret, bSecret); +-assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +-assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +-/* Ensure specific generator (buffer) works as expected. +- * The values below (modp2/modp2buf) are for a 1024 bits long prime from +- * RFC 2412 E.2, see https://tools.ietf.org/html/rfc2412. */ +-var modp2 = crypto.createDiffieHellmanGroup('modp2'); +-var modp2buf = new Buffer([ +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, +- 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, +- 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, +- 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, +- 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, +- 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, +- 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, +- 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, +- 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, +- 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, +- 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, +- 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +-]); +-var exmodp2 = crypto.createDiffieHellman(modp2buf, new Buffer([2])); +-modp2.generateKeys(); +-exmodp2.generateKeys(); +-var modp2Secret = modp2.computeSecret(exmodp2.getPublicKey()).toString('hex'); +-var exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey()).toString('hex'); +-assert.equal(modp2Secret, exmodp2Secret); +-assert.equal(modp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +-assert.equal(exmodp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +- +-// Ensure specific generator (string with encoding) works as expected. +-var exmodp2_2 = crypto.createDiffieHellman(modp2buf, '02', 'hex'); +-exmodp2_2.generateKeys(); +-modp2Secret = modp2.computeSecret(exmodp2_2.getPublicKey()).toString('hex'); +-var exmodp2_2Secret = exmodp2_2.computeSecret(modp2.getPublicKey()) +- .toString('hex'); +-assert.equal(modp2Secret, exmodp2_2Secret); +-assert.equal(exmodp2_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +- +-// Ensure specific generator (string without encoding) works as expected. +-var exmodp2_3 = crypto.createDiffieHellman(modp2buf, '\x02'); +-exmodp2_3.generateKeys(); +-modp2Secret = modp2.computeSecret(exmodp2_3.getPublicKey()).toString('hex'); +-var exmodp2_3Secret = exmodp2_3.computeSecret(modp2.getPublicKey()) +- .toString('hex'); +-assert.equal(modp2Secret, exmodp2_3Secret); +-assert.equal(exmodp2_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +- +-// Ensure specific generator (numeric) works as expected. +-var exmodp2_4 = crypto.createDiffieHellman(modp2buf, 2); +-exmodp2_4.generateKeys(); +-modp2Secret = modp2.computeSecret(exmodp2_4.getPublicKey()).toString('hex'); +-var exmodp2_4Secret = exmodp2_4.computeSecret(modp2.getPublicKey()) +- .toString('hex'); +-assert.equal(modp2Secret, exmodp2_4Secret); +-assert.equal(exmodp2_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +- +-var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + +- '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' + +- '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + +- 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; +-var bad_dh = crypto.createDiffieHellman(p, 'hex'); +-assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); +- +- +-// Test ECDH +-var ecdh1 = crypto.createECDH('prime256v1'); +-var ecdh2 = crypto.createECDH('prime256v1'); +-key1 = ecdh1.generateKeys(); +-key2 = ecdh2.generateKeys('hex'); +-secret1 = ecdh1.computeSecret(key2, 'hex', 'base64'); +-secret2 = ecdh2.computeSecret(key1, 'binary', 'buffer'); +- +-assert.equal(secret1, secret2.toString('base64')); +- +-// Oakley curves do not clean up ERR stack, it was causing unexpected failure +-// when accessing other OpenSSL APIs afterwards. +-crypto.createECDH('Oakley-EC2N-3'); +-crypto.createHash('sha256'); +- +-// Point formats +-assert.equal(ecdh1.getPublicKey('buffer', 'uncompressed')[0], 4); +-var firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0]; +-assert(firstByte === 2 || firstByte === 3); +-firstByte = ecdh1.getPublicKey('buffer', 'hybrid')[0]; +-assert(firstByte === 6 || firstByte === 7); +- +-// ECDH should check that point is on curve +-var ecdh3 = crypto.createECDH('secp256k1'); +-var key3 = ecdh3.generateKeys(); +- +-assert.throws(function() { +- ecdh2.computeSecret(key3, 'binary', 'buffer'); +-}); +- +-// ECDH should allow .setPrivateKey()/.setPublicKey() +-var ecdh4 = crypto.createECDH('prime256v1'); +- +-ecdh4.setPrivateKey(ecdh1.getPrivateKey()); +-ecdh4.setPublicKey(ecdh1.getPublicKey()); +- +-assert.throws(function() { +- ecdh4.setPublicKey(ecdh3.getPublicKey()); +-}); +diff --git a/test/parallel/test-http-header-obstext.js b/test/parallel/test-http-header-obstext.js +deleted file mode 100644 +index ba28768..0000000 +--- a/test/parallel/test-http-header-obstext.js ++++ /dev/null +@@ -1,18 +0,0 @@ +-'use strict'; +- +-const common = require('../common'); +-const http = require('http'); +-const assert = require('assert'); +- +-const server = http.createServer(common.mustCall((req, res) => { +- res.end('ok'); +-})); +-server.listen(common.PORT, () => { +- http.get({ +- port: common.PORT, +- headers: {'Test': 'Düsseldorf'} +- }, common.mustCall((res) => { +- assert.equal(res.statusCode, 200); +- server.close(); +- })); +-}); +-- +2.5.5 + diff --git a/SOURCES/nodejs-disable-gyp-deps.patch b/SOURCES/nodejs-disable-gyp-deps.patch new file mode 100644 index 0000000..91f0f09 --- /dev/null +++ b/SOURCES/nodejs-disable-gyp-deps.patch @@ -0,0 +1,25 @@ +From 8a53e16138f7fa4371eebde91d3bf216285e75a0 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Tue, 1 Dec 2015 16:35:29 -0500 +Subject: [PATCH 1/2] disable running gyp files for bundled deps + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 94eb419..a2b682b 100644 +--- a/Makefile ++++ b/Makefile +@@ -49,7 +49,7 @@ $(NODE_G_EXE): config.gypi out/Makefile + $(MAKE) -C out BUILDTYPE=Debug V=$(V) + ln -fs out/Debug/$(NODE_EXE) $@ + +-out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi ++out/Makefile: common.gypi deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi + $(PYTHON) tools/gyp_node.py -f make + + config.gypi: configure +-- +2.5.0 + diff --git a/SOURCES/nodejs-disable-openssl-1.0.2-features.patch b/SOURCES/nodejs-disable-openssl-1.0.2-features.patch new file mode 100644 index 0000000..669e78a --- /dev/null +++ b/SOURCES/nodejs-disable-openssl-1.0.2-features.patch @@ -0,0 +1,593 @@ +From f32cc672fd1bf3012427f0a2f4188e47ca45f4aa Mon Sep 17 00:00:00 2001 +From: Tomas Hrcka +Date: Tue, 5 Apr 2016 17:02:03 +0200 +Subject: [PATCH] pllm + +--- + doc/api/tls.markdown | 5 ++ + src/node_constants.cc | 7 ++ + src/node_crypto.cc | 241 +++++++++++++++++++++++++++++++++++++++++++------- + src/node_crypto.h | 18 +++- + src/tls_wrap.cc | 10 ++- + 5 files changed, 247 insertions(+), 34 deletions(-) + +diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown +index 2d23e3f..f2f0c57 100644 +--- a/doc/api/tls.markdown ++++ b/doc/api/tls.markdown +@@ -130,6 +130,11 @@ handshake extensions allowing you: + * NPN - to use one TLS server for multiple protocols (HTTP, SPDY) + * SNI - to use one TLS server for multiple hostnames with different SSL + certificates. ++ **NOTE**: dueto a design flaw in node **SNI cannot be ++ used on the server side**, even so all parameters in related functions are ++ accepted for compatibility reasons. And thus the related events will not ++ fire unless one aranges this explicitly. This may change, when the OS ++ provides OpenSSL v1.0.2 or better and node gets linked to this version. + + + ## Perfect Forward Secrecy +diff --git a/src/node_constants.cc b/src/node_constants.cc +index 51c2ee8..ca8dae4 100644 +--- a/src/node_constants.cc ++++ b/src/node_constants.cc +@@ -12,8 +12,13 @@ + #include + + #if HAVE_OPENSSL ++# include ++# include ++#ifndef OPENSSL_NO_EC + # include ++#endif + # include ++ + # ifndef OPENSSL_NO_ENGINE + # include + # endif // !OPENSSL_NO_ENGINE +@@ -961,12 +966,14 @@ void DefineOpenSSLConstants(Local target) { + + #if HAVE_OPENSSL + // NOTE: These are not defines ++# ifndef OPENSSL_NO_EC + NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_COMPRESSED); + + NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_UNCOMPRESSED); + + NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_HYBRID); + #endif ++#endif + } + + void DefineSystemConstants(Local target) { +diff --git a/src/node_crypto.cc b/src/node_crypto.cc +index 382a42f..a9570fe 100644 +--- a/src/node_crypto.cc ++++ b/src/node_crypto.cc +@@ -34,6 +34,83 @@ + #define OPENSSL_CONST + #endif + ++#ifndef SSL_get_server_tmp_key ++/* ++ 1.0.2 SSL_get_server_tmp_key(s, pk) "backport". BAD HACK!!! ++ NOTE: This imports "foreign" knowledge and thus will break, when SESS_CERT ++ or CERT_PKEY change, which is definitely the case for the later for ++ all OpenSSL lib vers != 1.0.1. So don't try to bind to something else! ++ */ ++# define SSL_PKEY_NUM 8 ++typedef struct cert_pkey_st { ++ X509 *x509; ++ EVP_PKEY *privatekey; ++ /* Digest to use when signing */ ++ const EVP_MD *digest; ++} CERT_PKEY; ++ ++typedef struct sess_cert_st { ++ STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */ ++ /* The 'peer_...' members are used only by clients. */ ++ int peer_cert_type; ++ CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never ++ * NULL!) */ ++ CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; ++ /* ++ * Obviously we don't have the private keys of these, so maybe we ++ * shouldn't even use the CERT_PKEY type here. ++ */ ++# ifndef OPENSSL_NO_RSA ++ RSA *peer_rsa_tmp; /* not used for SSL 2 */ ++# endif ++# ifndef OPENSSL_NO_DH ++ DH *peer_dh_tmp; /* not used for SSL 2 */ ++# endif ++# ifndef OPENSSL_NO_ECDH ++ EC_KEY *peer_ecdh_tmp; ++# endif ++ int references; /* actually always 1 at the moment */ ++} SESS_CERT; ++ ++static long SSL_get_server_tmp_key(SSL *s, void *parg) { ++ if (s->server || !s->session || !s->session->sess_cert) ++ return 0; ++ else { ++ SESS_CERT *sc; ++ EVP_PKEY *ptmp; ++ int rv = 0; ++ sc = s->session->sess_cert; ++#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH) ++ if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp) ++ return 0; ++#endif ++ ptmp = EVP_PKEY_new(); ++ if (!ptmp) ++ return 0; ++ if (0) ; ++#ifndef OPENSSL_NO_RSA ++ else if (sc->peer_rsa_tmp) ++ rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); ++#endif ++#ifndef OPENSSL_NO_DH ++ else if (sc->peer_dh_tmp) ++ rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); ++#endif ++#ifndef OPENSSL_NO_ECDH ++ else if (sc->peer_ecdh_tmp) ++ rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); ++#endif ++ if (rv) { ++ *(EVP_PKEY **)parg = ptmp; ++ return 1; ++ } ++ EVP_PKEY_free(ptmp); ++ return 0; ++ } ++} ++#endif /* SSL_get_server_tmp_key */ ++ ++ + #define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val) \ + do { \ + if (!Buffer::HasInstance(val) && !val->IsString()) { \ +@@ -164,7 +241,11 @@ template int SSLWrap::TLSExtStatusCallback(SSL* s, void* arg); + #endif + + template void SSLWrap::DestroySSL(); ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + template int SSLWrap::SSLCertCallback(SSL* s, void* arg); ++#else ++template int SSLWrap::SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey); ++#endif + template void SSLWrap::WaitForCertCb(CertCb cb, void* arg); + + +@@ -258,8 +339,23 @@ inline void CheckEntropy() { + } + } + ++#ifndef NODE_FIPS_MODE ++#define NODE_FIPS_MODE 0 ++#endif + + bool EntropySource(unsigned char* buffer, size_t length) { ++#ifdef OPENSSL_FIPS ++ // This call is important for FIPS Capable OpenSSL lib, otherwise ++ // RAND_status() will hang. Works for non-FIPS capable libs, too. ++ int err = FIPS_mode(); ++ // Shouldn't this be a CLI switch? ++ if (err != NODE_FIPS_MODE && !FIPS_mode_set(NODE_FIPS_MODE)) { ++ err = ERR_get_error(); ++ fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL)); ++ UNREACHABLE(); ++ } ++#endif // OPENSSL_FIPS ++ + // Ensure that OpenSSL's PRNG is properly seeded. + CheckEntropy(); + // RAND_bytes() can return 0 to indicate that the entropy data is not truly +@@ -281,8 +377,12 @@ void SecureContext::Initialize(Environment* env, Local target) { + env->SetProtoMethod(t, "addCRL", SecureContext::AddCRL); + env->SetProtoMethod(t, "addRootCerts", SecureContext::AddRootCerts); + env->SetProtoMethod(t, "setCiphers", SecureContext::SetCiphers); ++ #ifndef OPENSSL_NO_ECDH + env->SetProtoMethod(t, "setECDHCurve", SecureContext::SetECDHCurve); ++ #endif ++ #ifndef OPENSSL_NO_DH + env->SetProtoMethod(t, "setDHParam", SecureContext::SetDHParam); ++ #endif + env->SetProtoMethod(t, "setOptions", SecureContext::SetOptions); + env->SetProtoMethod(t, "setSessionIdContext", + SecureContext::SetSessionIdContext); +@@ -528,10 +628,20 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx, + + for (int i = 0; i < sk_X509_num(extra_certs); i++) { + X509* ca = sk_X509_value(extra_certs, i); +- +- // NOTE: Increments reference count on `ca` +- r = SSL_CTX_add1_chain_cert(ctx, ca); +- ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ // If ctx->cert->key != NULL create ctx->cert->key->chain if not ++ // already there, push 'ca' to this chain and finally increment the ca ++ // reference count by 1 (this is the diff between *_add1_* and *_add0_* ++ // - the later increments by 0 ;-)) and return 1. Otherwise or if ++ // something fails in between, return 0. ++ r = SSL_CTX_add1_chain_cert(ctx, ca); ++#else ++ // Create ctx->extra_certs if not already there, just push 'ca' to this ++ // chain and return 1. If something fails, return 0. ++ // NOTE: 1.0.1- does not support multiple certs having its own chain in ++ // a single context. There is just one: extra_chain! ++ r = SSL_CTX_add_extra_chain_cert(ctx, ca); ++#endif + if (!r) { + ret = 0; + *issuer = nullptr; +@@ -797,7 +907,7 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo& args) { + SSL_CTX_set_cipher_list(sc->ctx_, *ciphers); + } + +- ++#ifndef OPENSSL_NO_ECDH + void SecureContext::SetECDHCurve(const FunctionCallbackInfo& args) { + SecureContext* sc = Unwrap(args.Holder()); + Environment* env = sc->env(); +@@ -822,8 +932,9 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo& args) { + + EC_KEY_free(ecdh); + } ++#endif + +- ++#ifndef OPENSSL_NO_DH + void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { + SecureContext* sc = Unwrap(args.This()); + Environment* env = sc->env(); +@@ -861,7 +972,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { + if (!r) + return env->ThrowTypeError("Error setting temp DH parameter"); + } +- ++#endif + + void SecureContext::SetOptions(const FunctionCallbackInfo& args) { + SecureContext* sc = Unwrap(args.Holder()); +@@ -2087,7 +2198,12 @@ void SSLWrap::WaitForCertCb(CertCb cb, void* arg) { + + + template ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + int SSLWrap::SSLCertCallback(SSL* s, void* arg) { ++#else ++/* NOTE: For now this callback gets usually never called dueto design flaws */ ++int SSLWrap::SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey) { ++#endif + Base* w = static_cast(SSL_get_app_data(s)); + + if (!w->is_server()) +@@ -2159,19 +2275,53 @@ void SSLWrap::CertCbDone(const FunctionCallbackInfo& args) { + w->sni_context_.Reset(env->isolate(), ctx); + + int rv; ++ X509* x509; ++ EVP_PKEY* pkey; ++ STACK_OF(X509)* chain; + + // NOTE: reference count is not increased by this API methods +- X509* x509 = SSL_CTX_get0_certificate(sc->ctx_); +- EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_); +- STACK_OF(X509)* chain; ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ x509 = SSL_CTX_get0_certificate(sc->ctx_); ++ pkey = SSL_CTX_get0_privatekey(sc->ctx_); ++ rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain); ++#else ++ SSL *ssl = SSL_new(sc->ctx_); ++ rv = SSL_CTX_get_extra_chain_certs(sc->ctx_, &chain); ++ if (ssl) { ++ SSL_set_connect_state(ssl); /* just cleanup/reset state - cheap */ ++ x509 = SSL_get_certificate(ssl); ++ SSL_free(ssl); ++ } else { ++ x509 = NULL; ++ pkey = NULL; ++ } ++#endif + +- rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain); + if (rv) +- rv = SSL_use_certificate(w->ssl_, x509); ++ rv = SSL_use_certificate(w->ssl_, x509); + if (rv) +- rv = SSL_use_PrivateKey(w->ssl_, pkey); +- if (rv && chain != nullptr) +- rv = SSL_set1_chain(w->ssl_, chain); ++ rv = SSL_use_PrivateKey(w->ssl_, pkey); ++ if (rv && chain != nullptr) { ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ // replaces w->ssl_->cert->key->chain with a copy of the given chain, ++ // which is allowed to be NULL ++ rv = SSL_set1_chain(w->ssl_, chain); ++#else ++ // just replace the extra chain with the given chain - 1.0.1- does not ++ // support chain per cert ++ SSL_CTX_clear_extra_chain_certs(w->ssl_->ctx); ++ if (chain != NULL) { ++ int i; ++ SSL_CTX* ctx = w->ssl_->ctx; ++ for (i = 0; i < sk_X509_num(chain); i++) { ++ // can't do anything: however others might be ok and still ++ // satisfy requirements ++ SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain,i)); ++ } ++ } ++ rv = 1; ++#endif ++ } + if (rv) + rv = w->SetCACerts(sc); + if (!rv) { +@@ -2233,10 +2383,15 @@ void SSLWrap::SetSNIContext(SecureContext* sc) { + + template + int SSLWrap::SetCACerts(SecureContext* sc) { ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + int err = SSL_set1_verify_cert_store(ssl_, SSL_CTX_get_cert_store(sc->ctx_)); + if (err != 1) + return err; +- ++#else ++ // there is no ssl_->cert->verify_store in <= 1.0.1. So no need to: free the ++ // old store, set the new one to it and increment its ref count. ++#endif ++ + STACK_OF(X509_NAME)* list = SSL_dup_CA_list( + SSL_CTX_get_client_CA_list(sc->ctx_)); + +@@ -2513,8 +2668,11 @@ inline int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) { + // Server does not need to check the whitelist. + SSL* ssl = static_cast( + X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); +- ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (SSL_is_server(ssl)) ++#else ++ if (ssl->server) ++#endif + return 1; + + // Client needs to check if the server cert is listed in the +@@ -2594,8 +2752,21 @@ void Connection::New(const FunctionCallbackInfo& args) { + SSL_set_info_callback(conn->ssl_, SSLInfoCallback); + + InitNPN(sc); +- ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + SSL_set_cert_cb(conn->ssl_, SSLWrap::SSLCertCallback, conn); ++#else ++ /* 1.0.1 and less have no general cert callback. The closest for a client is ++ SSL_CTX_set_client_cert_cb(conn->ssl_->ctx, SSLWrap::SSLCertCallback); ++ but on the client it is not needed/used by this implementation. Since this ++ the SSLCertCallback actually calls lib/_tls_wrap.js:oncertcb(), which in ++ turn loadSNI() and this the actual SNICallback of the JSON object, sets ++ the context and finally requestOCSP() and certCbDone(). Not sure, why ++ the SNICallback of the JSON object, doesn't get invoked via ++ SelectSNIContextCallback_() - design flaw because lets do 2 things at once ++ (i.e. do SNICallback and attach the certs ca chain), however, this means ++ no server side support for the SNI TLS/OCSP_state extension anymore. ++ */ ++#endif + + #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + if (is_server) { +@@ -3689,7 +3860,8 @@ SignBase::Error Sign::SignFinal(const char* key_pem, + if (pkey == nullptr || 0 != ERR_peek_error()) + goto exit; + +-#ifdef NODE_FIPS_MODE ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) { + /* Validate DSA2 parameters from FIPS 186-4 */ + if (EVP_PKEY_DSA == pkey->type) { + size_t L = BN_num_bits(pkey->pkey.dsa->p); +@@ -3710,7 +3882,8 @@ SignBase::Error Sign::SignFinal(const char* key_pem, + goto exit; + } + } +-#endif // NODE_FIPS_MODE ++} ++#endif // OPENSSL_FIPS + + if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey)) + fatal = false; +@@ -4125,7 +4298,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { + delete[] out_value; + } + +- ++#ifndef OPENSSL_NO_DH + void DiffieHellman::Initialize(Environment* env, Local target) { + Local t = env->NewFunctionTemplate(New); + +@@ -4177,7 +4350,7 @@ void DiffieHellman::Initialize(Environment* env, Local target) { + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"), + t2->GetFunction()); + } +- ++#endif + + bool DiffieHellman::Init(int primeLength, int g) { + dh = DH_new(); +@@ -4517,7 +4690,7 @@ bool DiffieHellman::VerifyContext() { + return true; + } + +- ++#ifndef OPENSSL_NO_ECDH + void ECDH::Initialize(Environment* env, Local target) { + HandleScope scope(env->isolate()); + +@@ -4535,7 +4708,7 @@ void ECDH::Initialize(Environment* env, Local target) { + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH"), + t->GetFunction()); + } +- ++#endif + + void ECDH::New(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); +@@ -5240,7 +5413,7 @@ void GetHashes(const FunctionCallbackInfo& args) { + args.GetReturnValue().Set(ctx.arr); + } + +- ++#ifndef OPENSSL_NO_EC + void GetCurves(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + const size_t num_curves = EC_get_builtin_curves(nullptr, 0); +@@ -5265,7 +5438,7 @@ void GetCurves(const FunctionCallbackInfo& args) { + + args.GetReturnValue().Set(arr); + } +- ++#endif + + void Certificate::Initialize(Environment* env, Local target) { + HandleScope scope(env->isolate()); +@@ -5462,13 +5635,15 @@ void InitCryptoOnce() { + CRYPTO_set_locking_callback(crypto_lock_cb); + CRYPTO_THREADID_set_callback(crypto_threadid_cb); + +-#ifdef NODE_FIPS_MODE +- if (!FIPS_mode_set(1)) { +- int err = ERR_get_error(); ++#ifdef OPENSSL_FIPS ++ int err = FIPS_mode(); ++ // Shouldn't this be a CLI switch? ++ if (err != NODE_FIPS_MODE && !FIPS_mode_set(NODE_FIPS_MODE)) { ++ err = ERR_get_error(); + fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL)); + UNREACHABLE(); + } +-#endif // NODE_FIPS_MODE ++#endif // OPENSSL_FIPS + + + // Turn off compression. Saves memory and protects against CRIME attacks. +@@ -5544,8 +5719,12 @@ void InitCrypto(Local target, + SecureContext::Initialize(env, target); + Connection::Initialize(env, target); + CipherBase::Initialize(env, target); ++#ifndef OPENSSL_NO_EC + DiffieHellman::Initialize(env, target); ++#endif ++#ifndef OPENSSL_NO_ECDH + ECDH::Initialize(env, target); ++#endif + Hmac::Initialize(env, target); + Hash::Initialize(env, target); + Sign::Initialize(env, target); +@@ -5560,7 +5739,9 @@ void InitCrypto(Local target, + env->SetMethod(target, "getSSLCiphers", GetSSLCiphers); + env->SetMethod(target, "getCiphers", GetCiphers); + env->SetMethod(target, "getHashes", GetHashes); ++#ifndef OPENSSL_NO_EC + env->SetMethod(target, "getCurves", GetCurves); ++#endif + env->SetMethod(target, "publicEncrypt", + PublicKeyCipher::Cipher ++#ifndef OPENSSL_NO_EC + #include ++#endif ++#ifndef OPENSSL_NO_ECDH + #include ++#endif + #ifndef OPENSSL_NO_ENGINE + # include + #endif // !OPENSSL_NO_ENGINE +@@ -101,8 +105,12 @@ class SecureContext : public BaseObject { + static void AddCRL(const v8::FunctionCallbackInfo& args); + static void AddRootCerts(const v8::FunctionCallbackInfo& args); + static void SetCiphers(const v8::FunctionCallbackInfo& args); ++#ifndef OPENSSL_NO_ECDH + static void SetECDHCurve(const v8::FunctionCallbackInfo& args); ++#endif ++#ifndef OPENSSL_NO_DH + static void SetDHParam(const v8::FunctionCallbackInfo& args); ++#endif + static void SetOptions(const v8::FunctionCallbackInfo& args); + static void SetSessionIdContext( + const v8::FunctionCallbackInfo& args); +@@ -273,7 +281,11 @@ class SSLWrap { + void* arg); + #endif // OPENSSL_NPN_NEGOTIATED + static int TLSExtStatusCallback(SSL* s, void* arg); ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + static int SSLCertCallback(SSL* s, void* arg); ++#else ++ static int SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey); ++#endif + static void SSLGetter(v8::Local property, + const v8::PropertyCallbackInfo& info); + +@@ -645,7 +657,7 @@ class PublicKeyCipher { + EVP_PKEY_cipher_t EVP_PKEY_cipher> + static void Cipher(const v8::FunctionCallbackInfo& args); + }; +- ++#ifndef OPENSSL_NO_DH + class DiffieHellman : public BaseObject { + public: + ~DiffieHellman() override { +@@ -691,7 +703,9 @@ class DiffieHellman : public BaseObject { + int verifyError_; + DH* dh; + }; ++#endif + ++#ifndef OPENSSL_NO_ECDH + class ECDH : public BaseObject { + public: + ~ECDH() override { +@@ -727,7 +741,7 @@ class ECDH : public BaseObject { + EC_KEY* key_; + const EC_GROUP* group_; + }; +- ++#endif + class Certificate : public AsyncWrap { + public: + static void Initialize(Environment* env, v8::Local target); +diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc +index 85730b3..47441bd 100644 +--- a/src/tls_wrap.cc ++++ b/src/tls_wrap.cc +@@ -140,9 +140,15 @@ void TLSWrap::InitSSL() { + #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + + InitNPN(sc_); +- ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L + SSL_set_cert_cb(ssl_, SSLWrap::SSLCertCallback, this); +- ++#else ++ /* 1.0.1 and less have at most for the client side the function ++ SSL_CTX_set_client_cert_cb(ssl_->ctx, SSLWrap::SSLCertCallback); ++ but on the client it is not needed/used by this implementation. ++ For more info see comments in src/node_crypto.cc Connection::New(). ++ */ ++#endif + if (is_server()) { + SSL_set_accept_state(ssl_); + } else if (is_client()) { +-- +2.5.5 + diff --git a/SOURCES/nodejs-tarball.sh b/SOURCES/nodejs-tarball.sh new file mode 100755 index 0000000..e7e9613 --- /dev/null +++ b/SOURCES/nodejs-tarball.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +version=$(rpm -q --specfile --qf='%{version}\n' nodejs.spec | head -n1) +wget http://nodejs.org/dist/v${version}/node-v${version}.tar.gz +tar -zxf node-v${version}.tar.gz +rm -rf node-v${version}/deps/openssl +tar -zcf node-v${version}-stripped.tar.gz node-v${version} diff --git a/SOURCES/nodejs-use-system-certs.patch b/SOURCES/nodejs-use-system-certs.patch new file mode 100644 index 0000000..e14347c --- /dev/null +++ b/SOURCES/nodejs-use-system-certs.patch @@ -0,0 +1,87 @@ +From e0aac817a87c927f70a6f8edb63a4103a4109dfc Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Tue, 1 Dec 2015 16:29:07 -0500 +Subject: [PATCH 2/2] Do not bundle CA Certificates +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CA Certificates are provided by Fedora. + +Forwarded: need some feedback before submitting the matter upstream +Author: Jérémy Lal +Last-Update: 2014-03-02 + +Modified 2014-05-02 by T.C. Hollingsworth with the +correct path for Fedora + +Modified 2015-12-01 by Stephen Gallagher to update for +Node.js 4.2 + +Modified 2016-03-04 by Stephen Gallagher to update for +Node.js 5.7.1 +--- + src/node_crypto.cc | 28 ++++++++-------------------- + 1 file changed, 8 insertions(+), 20 deletions(-) + +diff --git a/src/node_crypto.cc b/src/node_crypto.cc +index acd83e9f2f41ade75ee9a3c8061acfa8b3dbf0f4..70ffe035f8be24b2eb6daf71185649d8ae7d579f 100644 +--- a/src/node_crypto.cc ++++ b/src/node_crypto.cc +@@ -119,11 +119,11 @@ static X509_NAME *cnnic_ev_name = + sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1); + + static uv_mutex_t* locks; + + const char* const root_certs[] = { +-#include "node_root_certs.h" // NOLINT(build/include_order) ++ NULL + }; + + X509_STORE* root_cert_store; + + // Just to generate static methods +@@ -748,33 +748,21 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo& args) { + (void) &clear_error_on_return; // Silence compiler warning. + + CHECK_EQ(sc->ca_store_, nullptr); + + if (!root_cert_store) { +- root_cert_store = X509_STORE_new(); +- +- for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) { +- BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i])); +- if (bp == nullptr) { +- return; +- } +- +- X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr); +- if (x509 == nullptr) { +- BIO_free_all(bp); +- return; +- } +- +- X509_STORE_add_cert(root_cert_store, x509); +- +- BIO_free_all(bp); +- X509_free(x509); ++ if (SSL_CTX_load_verify_locations(sc->ctx_, "/etc/pki/tls/certs/ca-bundle.crt", NULL) == 1) { ++ root_cert_store = SSL_CTX_get_cert_store(sc->ctx_); ++ } else { ++ // empty store ++ root_cert_store = X509_STORE_new(); + } ++ } else { ++ SSL_CTX_set_cert_store(sc->ctx_, root_cert_store); + } + + sc->ca_store_ = root_cert_store; +- SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_); + } + + + void SecureContext::SetCiphers(const FunctionCallbackInfo& args) { + SecureContext* sc = Unwrap(args.Holder()); +-- +2.7.2 + diff --git a/SPECS/nodejs.spec b/SPECS/nodejs.spec new file mode 100644 index 0000000..d163924 --- /dev/null +++ b/SPECS/nodejs.spec @@ -0,0 +1,543 @@ +%{?scl:%scl_package nodejs} +%{!?scl:%global pkg_name %{name}} + %{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} + +%global with_debug 1 + +# ARM builds currently break on the Debug builds, so we'll just +# build the standard runtime until that gets sorted out. +%ifarch %{arm} aarch64 %{power64} +%global with_debug 0 +%endif + +Name: %{?scl_prefix}nodejs +Version: 4.4.2 +Release: 1%{?dist} +Summary: JavaScript runtime +License: MIT and ASL 2.0 and ISC and BSD +Group: Development/Languages +URL: http://nodejs.org/ + +ExclusiveArch: %{nodejs_arches} + +# nodejs bundles openssl, but we use the system version in Fedora +# because openssl contains prohibited code, we remove openssl completely from +# the tarball, using the script in Source100 +Source0: node-v%{version}-stripped.tar.gz +Source100: %{pkg_name}-tarball.sh + +# The native module Requires generator remains in the nodejs SRPM, so it knows +# the nodejs and v8 versions. The remainder has migrated to the +# nodejs-packaging SRPM. +#Source7: nodejs_native.attr + +# Disable running gyp on bundled deps we don't use +Patch1: nodejs-disable-gyp-deps.patch + +# use system certificates instead of the bundled ones +# modified version of Debian patch: +# http://patch-tracker.debian.org/patch/series/view/nodejs/0.10.26~dfsg1-1/2014_donotinclude_root_certs.patch +Patch2: nodejs-use-system-certs.patch + +Patch3: nodejs-disable-failing-tests.patch + +Patch4: nodejs-disable-openssl-1.0.2-features.patch + +Patch5: nodejs-disable-crypto-tests.patch +# V8 presently breaks ABI at least every x.y release while never bumping SONAME +%global v8_abi 4.5 + +BuildRequires: python-devel +BuildRequires: %{?scl_prefix}libuv-devel >= 1.7.5 +BuildRequires: %{?scl_prefix}http-parser-devel >= 2.6.1 +BuildRequires: zlib-devel +BuildRequires: openssl-devel +Requires: %{?scl_prefix}libuv >= 1.7.5 +Requires: %{?scl_prefix}http-parser >= 2.6.1 +Requires: openssl + +# Node.js requires some features from openssl 1.0.1 for SPDY support +#BuildRequires: openssl-devel >= 1:1.0.2 + +# we need the system certificate store when Patch2 is applied +Requires: ca-certificates + +#we need ABI virtual provides where SONAMEs aren't enough/not present so deps +#break when binary compatibility is broken +%global nodejs_abi 4.4 +Provides: %{?scl_prefix}nodejs(abi) = %{nodejs_abi} +Provides: %{?scl_prefix}nodejs(v8-abi) = %{v8_abi} + +#this corresponds to the "engine" requirement in package.json +Provides: %{?scl_prefix}nodejs(engine) = %{version} + +# Node.js currently has a conflict with the 'node' package in Fedora +# The ham-radio group has agreed to rename their binary for us, but +# in the meantime, we're setting an explicit Conflicts: here +Conflicts: %{?scl_prefix}node <= 0.3.2-12 + +# The punycode module was absorbed into the standard library in v0.6. +# It still exists as a seperate package for the benefit of users of older +# versions. Since we've never shipped anything older than v0.10 in Fedora, +# we don't need the seperate nodejs-punycode package, so we Provide it here so +# dependent packages don't need to override the dependency generator. +# See also: RHBZ#11511811 +Provides: %{?scl_prefix}nodejs-punycode = 1.3.2 +Provides: %{?scl_prefix}npm(punycode) = 1.3.2 + + +# Node.js has forked c-ares from upstream in an incompatible way, so we need +# to carry the bundled version internally. +# See https://github.com/nodejs/node/commit/766d063e0578c0f7758c3a965c971763f43fec85 +Provides: %{?scl_prefix}bundled(c-ares) = 1.10.1 + +# Node.js is closely tied to the version of v8 that is used with it. It makes +# sense to use the bundled version because upstream consistently breaks ABI +# even in point releases. Node.js upstream has now removed the ability to build +# against a shared system version entirely. +# See https://github.com/nodejs/node/commit/d726a177ed59c37cf5306983ed00ecd858cfbbef +Provides: %{?scl_prefix}bundled(v8) = 4.5.103.35 + +# Node.js and http-parser share an upstream. The http-parser upstream does not +# do releases often and is almost always far behind the bundled version +#Provides: %%{?scl_prefix}bundled(http-parser) = 2.5.1 + +%description +Node.js is a platform built on Chrome's JavaScript runtime +for easily building fast, scalable network applications. +Node.js uses an event-driven, non-blocking I/O model that +makes it lightweight and efficient, perfect for data-intensive +real-time applications that run across distributed devices. + +%package devel +Summary: JavaScript runtime - development headers +Group: Development/Languages +Requires: %{?scl_prefix}%{pkg_name}%{?_isa} == %{version}-%{release} +Requires: %{?scl_prefix}libuv-devel%{?_isa} %{?scl_prefix}http-parser-devel%{?_isa} +Requires: openssl-devel%{?_isa} zlib-devel%{?_isa} +Requires: %{?scl_prefix}runtime + +%description devel +Development headers for the Node.js JavaScript runtime. + +%package docs +Summary: Node.js API documentation +Group: Documentation +BuildArch: noarch + +%description docs +The API documentation for the Node.js JavaScript runtime. + +%prep +%setup -q -n node-v%{version} + +# remove bundled dependencies that we aren't building +%patch1 -p1 +rm -rf deps/npm \ + deps/uv \ + deps/http-parser \ + deps/zlib + +# remove bundled CA certificates +%patch2 -p1 +rm -f src/node_root_certs.h + +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 + +%build +# build with debugging symbols and add defines from libuv (#892601) +# Node's v8 breaks with GCC 8 because of incorrect usage of methods on +# NULL objects. We need to pass -fno-delete-null-pointer-checks +export CFLAGS='%{optflags} -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fno-delete-null-pointer-checks' +export CXXFLAGS='%{optflags} -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \ + -fno-delete-null-pointer-checks -I%{_includedir}' +export LDFLAGS='%{optflags} -L%{_libdir}' + +./configure --prefix=%{_prefix} \ + --shared-http-parser \ + --shared-zlib \ + --shared-libuv \ + --shared-openssl \ + --without-npm \ + --without-dtrace + + +%if %{?with_debug} == 1 +# Setting BUILDTYPE=Debug builds both release and debug binaries +%{?scl:scl enable %{scl} - << \EOF} +make BUILDTYPE=Debug %{?_smp_mflags} +%{?scl:EOF} +%else +%{?scl:scl enable %{scl} - << \EOF} +make BUILDTYPE=Release %{?_smp_mflags} +%{?scl:EOF} +%endif + +%install +rm -rf %{buildroot} + +./tools/install.py install %{buildroot} %{_prefix} + +# and remove dtrace file again +rm -rf %{buildroot}/%{_prefix}/lib/dtrace + +# Set the binary permissions properly +chmod 0755 %{buildroot}/%{_bindir}/node + +%if %{?with_debug} == 1 +# Install the debug binary and set its permissions +install -Dpm0755 out/Debug/node %{buildroot}/%{_bindir}/node_g +%endif + +# own the sitelib directory +mkdir -p %{buildroot}%{_prefix}/lib/node_modules + +# ensure Requires are added to every native module that match the Provides from +# the nodejs build in the buildroot +#install -Dpm0644 %%{SOURCE7} %%{buildroot}%{_rpmconfigdir}/fileattrs/nodejs_native.attr +#cat << EOF > %{buildroot}%{_rpmconfigdir}/nodejs_native.req +#!/bin/sh +#echo 'nodejs(abi) = %nodejs_abi' +#echo 'nodejs(v8-abi) = %v8_abi' +#EOF +#chmod 0755 %{buildroot}%{_rpmconfigdir}/nodejs_native.req + +#install documentation +mkdir -p %{buildroot}%{_pkgdocdir}/html +cp -pr doc/* %{buildroot}%{_pkgdocdir}/html +rm -f %{buildroot}%{_pkgdocdir}/html/nodejs.1 + +#node-gyp needs common.gypi too +mkdir -p %{buildroot}%{_datadir}/node +cp -p common.gypi %{buildroot}%{_datadir}/node + +# Install the GDB init tool into the documentation directory +mv %{buildroot}/%{_datadir}/doc/node/gdbinit %{buildroot}/%{_pkgdocdir}/gdbinit + +%check +%{?scl:scl enable %{scl} "} +python tools/test.py --mode=release parallel -J +%{?scl:"} + +%files +%{_bindir}/node +%{_mandir}/man1/node.* +%dir %{_prefix}/lib/node_modules +%dir %{_datadir}/node +%dir %{_datadir}/systemtap +%dir %{_datadir}/systemtap/tapset +%{_datadir}/systemtap/tapset/node.stp +#%%{_rpmconfigdir}/fileattrs/nodejs_native.attr +#%%{_rpmconfigdir}/nodejs_native.req +%dir %{_pkgdocdir} +%license LICENSE +%doc AUTHORS CHANGELOG.md COLLABORATOR_GUIDE.md GOVERNANCE.md README.md +%doc ROADMAP.md WORKING_GROUPS.md + + +%files devel +%if %{?with_debug} == 1 +%{_bindir}/node_g +%endif +%{_includedir}/node +%{_datadir}/node/common.gypi +%{_pkgdocdir}/gdbinit + +%files docs +%dir %{_pkgdocdir} +%{_pkgdocdir}/html + +%changelog +* Wed Apr 06 2016 Tomas Hrcka - 4.4.2-1 +- Rebase to latest upstream LTS release 4.4.2 +- https://nodejs.org/en/blog/release/v4.4.1/ + +* Tue Apr 05 2016 Tomas Hrcka - 4.4.1-2 +- Rebase to latest upstream LTS release 4.4.1 +- https://nodejs.org/en/blog/release/v4.4.1/ + +* Thu Mar 17 2016 Tomas Hrcka - 4.4.0-1 +- Rebase to latest upstream LTS release 4.4.0 + +* Tue Mar 01 2016 Tomas Hrcka - 4.3.0-5 +- New upstream release 4.3.0 +- https://nodejs.org/en/blog/release/v4.3.0/ +- Build with bundled openssl, this will be reverted ASAP +- Unbundled http-parser + +* Thu Jul 16 2015 Tomas Hrcka - 0.10.40-1 +- Rebase to latest upstream release + +* Wed Jul 01 2015 Tomas Hrcka - 0.10.39-1 +- Rebase to latest upstream release + +* Wed Mar 25 2015 Tomas Hrcka - 0.10.35-4 +- Enable tests during build time + +* Tue Mar 17 2015 Tomas Hrcka - 0.10.35-2 +- Reflect dependency on specific ABI changes in v8 +- RHBZ#1197110 + +* Wed Jan 07 2015 Tomas Hrcka - 0.10.35-1 +- New upstream release 0.10.35 + +* Sun Feb 02 2014 Tomas Hrcka - 0.10.25-1 +- New upstream release 0.10.25 + +* Tue Jan 14 2014 Tomas Hrcka - 0.10.24-1 +- new upstream release 0.10.24 + +* Tue Nov 26 2013 Tomas Hrcka - 0.10.21-3 +- rebuilt with v8314 collection + +* Tue Nov 12 2013 T.C. Hollingsworth - 0.10.22-1 +- new upstream release 0.10.22 + http://blog.nodejs.org/2013/11/12/node-v0-10-22-stable/ + +* Mon Oct 21 2013 Tomas Hrcka - 0.10.21-2 +- Build with system wide c-ares + +* Fri Oct 18 2013 T.C. Hollingsworth - 0.10.21-1 +- new upstream release 0.10.21 + http://blog.nodejs.org/2013/10/18/node-v0-10-21-stable/ +- resolves an undisclosed security vulnerability in the http module + +* Tue Oct 01 2013 T.C. Hollingsworth - 0.10.20-1 +- new upstream release 0.10.20 + http://blog.nodejs.org/2013/09/30/node-v0-10-20-stable/ + +* Wed Sep 25 2013 T.C. Hollingsworth - 0.10.19-1 +- new upstream release 0.10.19 + http://blog.nodejs.org/2013/09/24/node-v0-10-19-stable/ + +* Fri Sep 06 2013 T.C. Hollingsworth - 0.10.18-1 +- new upstream release 0.10.18 + http://blog.nodejs.org/2013/09/04/node-v0-10-18-stable/ + +* Tue Aug 27 2013 T.C. Hollingsworth - 0.10.17-1 +- new upstream release 0.10.17 + http://blog.nodejs.org/2013/08/21/node-v0-10-17-stable/ + +* Sat Aug 17 2013 T.C. Hollingsworth - 0.10.16-1 +- new upstream release 0.10.16 + http://blog.nodejs.org/2013/08/16/node-v0-10-16-stable/ +- add v8-devel to -devel Requires +- restrict -devel Requires to the same architecture + +* Wed Aug 14 2013 T.C. Hollingsworth - 0.10.14-3 +- fix typo in _isa macro in v8 Requires + +* Wed Aug 07 2013 Tomas Hrcka - 0.10.5-6 + - Remove badly licensed fonts in script instead of patch + +* Thu Jul 25 2013 T.C. Hollingsworth - 0.10.14-1 +- new upstream release 0.10.14 + http://blog.nodejs.org/2013/07/25/node-v0-10-14-stable/ + +* Wed Jul 10 2013 T.C. Hollingsworth - 0.10.13-1 +- new upstream release 0.10.13 + http://blog.nodejs.org/2013/07/09/node-v0-10-13-stable/ +- remove RPM macros, etc. now that they've migrated to nodejs-packaging + +* Wed Jun 19 2013 Tomas Hrcka - 0.10.5-5 + - added patch to remove badly licensed web fonts + +* Wed Jun 19 2013 Tomas Hrcka - 0.10.5-5 + - added patch to remove badly licensed web fonts + +* Wed Jun 19 2013 Tomas Hrcka - 0.10.5-4 + - strip openssl from the tarball it contains prohibited code (RHBZ#967736) + - patch makefile so it do not use bundled deps + - new stripped tarball + +* Wed Jun 19 2013 T.C. Hollingsworth - 0.10.12-1 +- new upstream release 0.10.12 + http://blog.nodejs.org/2013/06/18/node-v0-10-12-stable/ +- split off a -packaging subpackage with RPM macros, etc. +- build -docs as noarch +- copy mutiple version logic from nodejs-packaging SRPM for now + +* Fri May 31 2013 T.C. Hollingsworth - 0.10.9-1 +- new upstream release 0.10.9 + http://blog.nodejs.org/2013/05/30/node-v0-10-9-stable/ + +* Wed May 29 2013 T.C. Hollingsworth - 0.10.8-1 +- new upstream release 0.10.8 + http://blog.nodejs.org/2013/05/24/node-v0-10-8-stable/ + +* Wed May 29 2013 T.C. Hollingsworth - 0.10.7-1 +- new upstream release 0.10.7 + http://blog.nodejs.org/2013/05/17/node-v0-10-7-stable/ +- strip openssl from the tarball; it contains prohibited code (RHBZ#967736) +- patch Makefile so we can just remove all bundled deps completely + +* Wed May 15 2013 T.C. Hollingsworth - 0.10.6-1 +- new upstream release 0.10.6 + http://blog.nodejs.org/2013/05/14/node-v0-10-6-stable/ + +* Tue May 14 2013 Tomas Hrcka - 0.10.5-3.1 + - updated to latest upstream stable release + +* Mon May 06 2013 T.C. Hollingsworth - 0.10.5-3 +- nodejs-fixdep: work properly when a package has no dependencies + +* Mon Apr 29 2013 T.C. Hollingsworth - 0.10.5-2 +- nodejs-symlink-deps: make it work when --check is used and just + devDependencies exist + +* Wed Apr 24 2013 T.C. Hollingsworth - 0.10.5-1 +- new upstream release 0.10.5 + http://blog.nodejs.org/2013/04/23/node-v0-10-5-stable/ + +* Mon Apr 15 2013 T.C. Hollingsworth - 0.10.4-1 +- new upstream release 0.10.4 + http://blog.nodejs.org/2013/04/11/node-v0-10-4-stable/ +- drop dependency generator files not supported on EL6 +- port nodejs_default_filter to EL6 +- add nodejs_find_provides_and_requires macro to invoke dependency generator +- invoke the standard RPM provides and requires generators from the Node.js ones +- write native module Requires from nodejs.req +- change the c-ares-devel Requires in -devel to match the BuildRequires + +* Tue Apr 09 2013 Stephen Gallagher - 0.10.3-2.1 +- Build against c-ares 1.9 + +* Mon Apr 08 2013 Stanislav Ochotnicky - 0.10.3-3 +- Add support for software collections +- Move rpm macros and tooling to separate package +- add no-op macro to permit spec compatibility with EPEL + +* Thu Apr 04 2013 T.C. Hollingsworth - 0.10.3-2 +- nodejs-symlink-deps: symlink unconditionally in the buildroot + +* Wed Apr 03 2013 T.C. Hollingsworth - 0.10.3-1 +- new upstream release 0.10.3 + http://blog.nodejs.org/2013/04/03/node-v0-10-3-stable/ +- nodejs-symlink-deps: only create symlink if target exists +- nodejs-symlink-deps: symlink devDependencies when --check is used + +* Sun Mar 31 2013 T.C. Hollingsworth - 0.10.2-1 +- new upstream release 0.10.2 + http://blog.nodejs.org/2013/03/28/node-v0-10-2-stable/ +- remove %%nodejs_arches macro since it will only be useful if it is present in + the redhat-rpm-config package +- add default filtering macro to remove unwanted Provides from native modules +- nodejs-symlink-deps now supports multiple modules in one SRPM properly +- nodejs-symlink-deps also now supports a --check argument that works in the + current working directry instead of the buildroot + +* Fri Mar 22 2013 T.C. Hollingsworth - 0.10.1-1 +- new upstream release 0.10.1 + http://blog.nodejs.org/2013/03/21/node-v0-10-1-stable/ + +* Wed Mar 20 2013 T.C. Hollingsworth - 0.10.0-4 +- fix escaping in dependency generator regular expressions (RHBZ#923941) + +* Wed Mar 13 2013 T.C. Hollingsworth - 0.10.0-3 +- add virtual ABI provides for node and v8 so binary module's deps break when + binary compatibility is broken +- automatically add matching Requires to nodejs binary modules +- add %%nodejs_arches macro to future-proof ExcluseArch stanza in dependent + packages + +* Tue Mar 12 2013 Stephen Gallagher - 0.10.0-2 +- Fix up documentation subpackage + +* Mon Mar 11 2013 Stephen Gallagher - 0.10.0-1 +- Update to stable 0.10.0 release +- https://raw.github.com/joyent/node/v0.10.0/ChangeLog + +* Thu Feb 14 2013 Fedora Release Engineering - 0.9.5-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Jan 22 2013 T.C. Hollingsworth - 0.9.5-10 +- minor bugfixes to RPM magic + - nodejs-symlink-deps: don't create an empty node_modules dir when a module + has no dependencies + - nodes-fixdep: support adding deps when none exist +- Add the full set of headers usually bundled with node as deps to nodejs-devel. + This way `npm install` for native modules that assume the stuff bundled with + node exists will usually "just work". +-move RPM magic to nodejs-devel as requested by FPC + +* Sat Jan 12 2013 T.C. Hollingsworth - 0.9.5-9 +- fix brown paper bag bug in requires generation script + +* Thu Jan 10 2013 Stephen Gallagher - 0.9.5-8 +- Build debug binary and install it in the nodejs-devel subpackage + +* Thu Jan 10 2013 T.C. Hollingsworth - 0.9.5-7 +- don't use make install since it rebuilds everything + +* Thu Jan 10 2013 T.C. Hollingsworth - 0.9.5-6 +- add %%{?isa}, epoch to v8 deps + +* Wed Jan 09 2013 T.C. Hollingsworth - 0.9.5-5 +- add defines to match libuv (#892601) +- make v8 dependency explicit (and thus more accurate) +- add -g to $C(XX)FLAGS instead of patching configure to add it +- don't write pointless 'npm(foo) > 0' deps + +* Sat Jan 05 2013 T.C. Hollingsworth - 0.9.5-4 +- install development headers +- add nodejs_sitearch macro + +* Wed Jan 02 2013 T.C. Hollingsworth - 0.9.5-3 +- make nodejs-symlink-deps actually work + +* Tue Jan 01 2013 T.C. Hollingsworth - 0.9.5-2 +- provide nodejs-devel so modules can BuildRequire it (and be consistent + with other interpreted languages in the distro) + +* Tue Jan 01 2013 T.C. Hollingsworth - 0.9.5-1 +- new upstream release 0.9.5 +- provide nodejs-devel for the moment +- fix minor bugs in RPM magic +- add nodejs_fixdep macro so packagers can easily adjust dependencies in + package.json files + +* Wed Dec 26 2012 T.C. Hollingsworth - 0.9.4-1 +- new upstream release 0.9.4 +- system library patches are now upstream +- respect optflags +- include documentation in subpackage +- add RPM dependency generation and related magic +- guard libuv depedency so it always gets bumped when nodejs does +- add -devel subpackage with enough to make node-gyp happy + +* Thu Dec 20 2012 Stephen Gallagher - 0.9.3-9 +- Drop requirement on openssl 1.0.1 + +* Wed Dec 19 2012 Dan Horák - 0.9.3-8 +- set exclusive arch list to match v8 + +* Tue Dec 18 2012 Stephen Gallagher - 0.9.3-7 +- Add remaining changes from code review +- Remove unnecessary BuildRequires on findutils +- Remove %%clean section + +* Fri Dec 14 2012 Stephen Gallagher - 0.9.3-6 +- Fixes from code review +- Fix executable permissions +- Correct the License field +- Build debuginfo properly + +* Thu Dec 13 2012 Stephen Gallagher - 0.9.3-5 +- Return back to using the standard binary name +- Temporarily adding a conflict against the ham radio node package until they + complete an agreed rename of their binary. + +* Wed Nov 28 2012 Stephen Gallagher - 0.9.3-4 +- Rename binary and manpage to nodejs + +* Mon Nov 19 2012 Stephen Gallagher - 0.9.3-3 +- Update to latest upstream development release 0.9.3 +- Include upstreamed patches to unbundle dependent libraries + +* Tue Oct 23 2012 Adrian Alves 0.8.12-1 +- Fixes and Patches suggested by Matthias Runge + +* Mon Apr 09 2012 Adrian Alves 0.6.5 +- First build.