Skip to content

Commit becb4e9

Browse files
brendanashworthFishrock123
authored andcommitted
test: distribute crypto tests into separate files
This commit distributes many of the various tests that were previously strewn about `test-crypto.js` into their own files, such as for Ciphers and Deciphers, Hashing, and HMACs. Copy pasta, and no style changes besides removing a few now-unnecessary closures. Helps eliminate file bloat and allows for easier test prognosis. PR-URL: #827 Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 789ff95 commit becb4e9

8 files changed

+1180
-1107
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
4+
try {
5+
var crypto = require('crypto');
6+
} catch (e) {
7+
console.log('Not compiled with OPENSSL support.');
8+
process.exit();
9+
}
10+
11+
function testCipher1(key) {
12+
// Test encryption and decryption
13+
var plaintext = 'Keep this a secret? No! Tell everyone about node.js!';
14+
var cipher = crypto.createCipher('aes192', key);
15+
16+
// encrypt plaintext which is in utf8 format
17+
// to a ciphertext which will be in hex
18+
var ciph = cipher.update(plaintext, 'utf8', 'hex');
19+
// Only use binary or hex, not base64.
20+
ciph += cipher.final('hex');
21+
22+
var decipher = crypto.createDecipher('aes192', key);
23+
var txt = decipher.update(ciph, 'hex', 'utf8');
24+
txt += decipher.final('utf8');
25+
26+
assert.equal(txt, plaintext, 'encryption and decryption');
27+
28+
// streaming cipher interface
29+
// NB: In real life, it's not guaranteed that you can get all of it
30+
// in a single read() like this. But in this case, we know it's
31+
// quite small, so there's no harm.
32+
var cStream = crypto.createCipher('aes192', key);
33+
cStream.end(plaintext);
34+
ciph = cStream.read();
35+
36+
var dStream = crypto.createDecipher('aes192', key);
37+
dStream.end(ciph);
38+
txt = dStream.read().toString('utf8');
39+
40+
assert.equal(txt, plaintext, 'encryption and decryption with streams');
41+
}
42+
43+
44+
function testCipher2(key) {
45+
// encryption and decryption with Base64
46+
// reported in https://github.com/joyent/node/issues/738
47+
var plaintext =
48+
'32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
49+
'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
50+
'jAfaFg**';
51+
var cipher = crypto.createCipher('aes256', key);
52+
53+
// encrypt plaintext which is in utf8 format
54+
// to a ciphertext which will be in Base64
55+
var ciph = cipher.update(plaintext, 'utf8', 'base64');
56+
ciph += cipher.final('base64');
57+
58+
var decipher = crypto.createDecipher('aes256', key);
59+
var txt = decipher.update(ciph, 'base64', 'utf8');
60+
txt += decipher.final('utf8');
61+
62+
assert.equal(txt, plaintext, 'encryption and decryption with Base64');
63+
}
64+
65+
66+
function testCipher3(key, iv) {
67+
// Test encyrption and decryption with explicit key and iv
68+
var plaintext =
69+
'32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
70+
'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
71+
'jAfaFg**';
72+
var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
73+
var ciph = cipher.update(plaintext, 'utf8', 'hex');
74+
ciph += cipher.final('hex');
75+
76+
var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
77+
var txt = decipher.update(ciph, 'hex', 'utf8');
78+
txt += decipher.final('utf8');
79+
80+
assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
81+
82+
// streaming cipher interface
83+
// NB: In real life, it's not guaranteed that you can get all of it
84+
// in a single read() like this. But in this case, we know it's
85+
// quite small, so there's no harm.
86+
var cStream = crypto.createCipheriv('des-ede3-cbc', key, iv);
87+
cStream.end(plaintext);
88+
ciph = cStream.read();
89+
90+
var dStream = crypto.createDecipheriv('des-ede3-cbc', key, iv);
91+
dStream.end(ciph);
92+
txt = dStream.read().toString('utf8');
93+
94+
assert.equal(txt, plaintext, 'streaming cipher iv');
95+
}
96+
97+
98+
function testCipher4(key, iv) {
99+
// Test encyrption and decryption with explicit key and iv
100+
var plaintext =
101+
'32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
102+
'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
103+
'jAfaFg**';
104+
var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
105+
var ciph = cipher.update(plaintext, 'utf8', 'buffer');
106+
ciph = Buffer.concat([ciph, cipher.final('buffer')]);
107+
108+
var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
109+
var txt = decipher.update(ciph, 'buffer', 'utf8');
110+
txt += decipher.final('utf8');
111+
112+
assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
113+
}
114+
115+
116+
testCipher1('MySecretKey123');
117+
testCipher1(new Buffer('MySecretKey123'));
118+
119+
testCipher2('0123456789abcdef');
120+
testCipher2(new Buffer('0123456789abcdef'));
121+
122+
testCipher3('0123456789abcd0123456789', '12345678');
123+
testCipher3('0123456789abcd0123456789', new Buffer('12345678'));
124+
testCipher3(new Buffer('0123456789abcd0123456789'), '12345678');
125+
testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
126+
127+
testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
128+
129+
130+
// Base64 padding regression test, see #4837.
131+
(function() {
132+
var c = crypto.createCipher('aes-256-cbc', 'secret');
133+
var s = c.update('test', 'utf8', 'base64') + c.final('base64');
134+
assert.equal(s, '375oxUQCIocvxmC5At+rvA==');
135+
})();
136+
137+
// Calling Cipher.final() or Decipher.final() twice should error but
138+
// not assert. See #4886.
139+
(function() {
140+
var c = crypto.createCipher('aes-256-cbc', 'secret');
141+
try { c.final('xxx') } catch (e) { /* Ignore. */ }
142+
try { c.final('xxx') } catch (e) { /* Ignore. */ }
143+
try { c.final('xxx') } catch (e) { /* Ignore. */ }
144+
var d = crypto.createDecipher('aes-256-cbc', 'secret');
145+
try { d.final('xxx') } catch (e) { /* Ignore. */ }
146+
try { d.final('xxx') } catch (e) { /* Ignore. */ }
147+
try { d.final('xxx') } catch (e) { /* Ignore. */ }
148+
})();
149+
150+
// Regression test for #5482: string to Cipher#update() should not assert.
151+
(function() {
152+
var c = crypto.createCipher('aes192', '0123456789abcdef');
153+
c.update('update');
154+
c.final();
155+
})();
156+
157+
// #5655 regression tests, 'utf-8' and 'utf8' are identical.
158+
(function() {
159+
var c = crypto.createCipher('aes192', '0123456789abcdef');
160+
c.update('update', ''); // Defaults to "utf8".
161+
c.final('utf-8'); // Should not throw.
162+
163+
c = crypto.createCipher('aes192', '0123456789abcdef');
164+
c.update('update', 'utf8');
165+
c.final('utf-8'); // Should not throw.
166+
167+
c = crypto.createCipher('aes192', '0123456789abcdef');
168+
c.update('update', 'utf-8');
169+
c.final('utf8'); // Should not throw.
170+
})();

test/parallel/test-crypto-dh.js

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var constants = require('constants');
4+
5+
try {
6+
var crypto = require('crypto');
7+
} catch (e) {
8+
console.log('Not compiled with OPENSSL support.');
9+
process.exit();
10+
}
11+
12+
// Test Diffie-Hellman with two parties sharing a secret,
13+
// using various encodings as we go along
14+
var dh1 = crypto.createDiffieHellman(256);
15+
var p1 = dh1.getPrime('buffer');
16+
var dh2 = crypto.createDiffieHellman(p1, 'buffer');
17+
var key1 = dh1.generateKeys();
18+
var key2 = dh2.generateKeys('hex');
19+
var secret1 = dh1.computeSecret(key2, 'hex', 'base64');
20+
var secret2 = dh2.computeSecret(key1, 'binary', 'buffer');
21+
22+
assert.equal(secret1, secret2.toString('base64'));
23+
assert.equal(dh1.verifyError, 0);
24+
assert.equal(dh2.verifyError, 0);
25+
26+
assert.throws(function() {
27+
crypto.createDiffieHellman([0x1, 0x2]);
28+
});
29+
30+
assert.throws(function() {
31+
crypto.createDiffieHellman(function() { });
32+
});
33+
34+
assert.throws(function() {
35+
crypto.createDiffieHellman(/abc/);
36+
});
37+
38+
assert.throws(function() {
39+
crypto.createDiffieHellman({});
40+
});
41+
42+
// Create "another dh1" using generated keys from dh1,
43+
// and compute secret again
44+
var dh3 = crypto.createDiffieHellman(p1, 'buffer');
45+
var privkey1 = dh1.getPrivateKey();
46+
dh3.setPublicKey(key1);
47+
dh3.setPrivateKey(privkey1);
48+
49+
assert.deepEqual(dh1.getPrime(), dh3.getPrime());
50+
assert.deepEqual(dh1.getGenerator(), dh3.getGenerator());
51+
assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey());
52+
assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey());
53+
assert.equal(dh3.verifyError, 0);
54+
55+
var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
56+
57+
assert.equal(secret1, secret3);
58+
59+
// Run this one twice to make sure that the dh3 clears its error properly
60+
(function() {
61+
var c = crypto.createDecipher('aes-128-ecb', '');
62+
assert.throws(function() { c.final('utf8') }, /wrong final block length/);
63+
})();
64+
65+
assert.throws(function() {
66+
dh3.computeSecret('');
67+
}, /key is too small/i);
68+
69+
(function() {
70+
var c = crypto.createDecipher('aes-128-ecb', '');
71+
assert.throws(function() { c.final('utf8') }, /wrong final block length/);
72+
})();
73+
74+
// Create a shared using a DH group.
75+
var alice = crypto.createDiffieHellmanGroup('modp5');
76+
var bob = crypto.createDiffieHellmanGroup('modp5');
77+
alice.generateKeys();
78+
bob.generateKeys();
79+
var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex');
80+
var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex');
81+
assert.equal(aSecret, bSecret);
82+
assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
83+
assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
84+
85+
// Ensure specific generator (buffer) works as expected.
86+
var modp1 = crypto.createDiffieHellmanGroup('modp1');
87+
var modp1buf = new Buffer([
88+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f,
89+
0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
90+
0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67,
91+
0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22,
92+
0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95,
93+
0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
94+
0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51,
95+
0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
96+
0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff,
97+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
98+
]);
99+
var exmodp1 = crypto.createDiffieHellman(modp1buf, new Buffer([2]));
100+
modp1.generateKeys();
101+
exmodp1.generateKeys();
102+
var modp1Secret = modp1.computeSecret(exmodp1.getPublicKey()).toString('hex');
103+
var exmodp1Secret = exmodp1.computeSecret(modp1.getPublicKey()).toString('hex');
104+
assert.equal(modp1Secret, exmodp1Secret);
105+
assert.equal(modp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
106+
assert.equal(exmodp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
107+
108+
109+
// Ensure specific generator (string with encoding) works as expected.
110+
var exmodp1_2 = crypto.createDiffieHellman(modp1buf, '02', 'hex');
111+
exmodp1_2.generateKeys();
112+
modp1Secret = modp1.computeSecret(exmodp1_2.getPublicKey()).toString('hex');
113+
var exmodp1_2Secret = exmodp1_2.computeSecret(modp1.getPublicKey())
114+
.toString('hex');
115+
assert.equal(modp1Secret, exmodp1_2Secret);
116+
assert.equal(exmodp1_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
117+
118+
119+
// Ensure specific generator (string without encoding) works as expected.
120+
var exmodp1_3 = crypto.createDiffieHellman(modp1buf, '\x02');
121+
exmodp1_3.generateKeys();
122+
modp1Secret = modp1.computeSecret(exmodp1_3.getPublicKey()).toString('hex');
123+
var exmodp1_3Secret = exmodp1_3.computeSecret(modp1.getPublicKey())
124+
.toString('hex');
125+
assert.equal(modp1Secret, exmodp1_3Secret);
126+
assert.equal(exmodp1_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
127+
128+
129+
// Ensure specific generator (numeric) works as expected.
130+
var exmodp1_4 = crypto.createDiffieHellman(modp1buf, 2);
131+
exmodp1_4.generateKeys();
132+
modp1Secret = modp1.computeSecret(exmodp1_4.getPublicKey()).toString('hex');
133+
var exmodp1_4Secret = exmodp1_4.computeSecret(modp1.getPublicKey())
134+
.toString('hex');
135+
assert.equal(modp1Secret, exmodp1_4Secret);
136+
assert.equal(exmodp1_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
137+
138+
139+
var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +
140+
'020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' +
141+
'4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' +
142+
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
143+
var bad_dh = crypto.createDiffieHellman(p, 'hex');
144+
assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
145+
146+
147+
// Test ECDH
148+
var ecdh1 = crypto.createECDH('prime256v1');
149+
var ecdh2 = crypto.createECDH('prime256v1');
150+
var key1 = ecdh1.generateKeys();
151+
var key2 = ecdh2.generateKeys('hex');
152+
var secret1 = ecdh1.computeSecret(key2, 'hex', 'base64');
153+
var secret2 = ecdh2.computeSecret(key1, 'binary', 'buffer');
154+
155+
assert.equal(secret1, secret2.toString('base64'));
156+
157+
// Point formats
158+
assert.equal(ecdh1.getPublicKey('buffer', 'uncompressed')[0], 4);
159+
var firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0];
160+
assert(firstByte === 2 || firstByte === 3);
161+
var firstByte = ecdh1.getPublicKey('buffer', 'hybrid')[0];
162+
assert(firstByte === 6 || firstByte === 7);
163+
164+
// ECDH should check that point is on curve
165+
var ecdh3 = crypto.createECDH('secp256k1');
166+
var key3 = ecdh3.generateKeys();
167+
168+
assert.throws(function() {
169+
var secret3 = ecdh2.computeSecret(key3, 'binary', 'buffer');
170+
});
171+
172+
// ECDH should allow .setPrivateKey()/.setPublicKey()
173+
var ecdh4 = crypto.createECDH('prime256v1');
174+
175+
ecdh4.setPrivateKey(ecdh1.getPrivateKey());
176+
ecdh4.setPublicKey(ecdh1.getPublicKey());
177+
178+
assert.throws(function() {
179+
ecdh4.setPublicKey(ecdh3.getPublicKey());
180+
});

0 commit comments

Comments
 (0)