fd9896663a8e3a27291eb350f66ce51b0894561f
[platform/upstream/nodejs.git] / test / simple / test-crypto.js
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
23
24
25 var common = require('../common');
26 var assert = require('assert');
27 var util = require('util');
28
29 try {
30   var crypto = require('crypto');
31 } catch (e) {
32   console.log('Not compiled with OPENSSL support.');
33   process.exit();
34 }
35
36 crypto.DEFAULT_ENCODING = 'buffer';
37
38 var fs = require('fs');
39 var path = require('path');
40 var constants = require('constants');
41
42 // Test Certificates
43 var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
44 var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
45 var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
46 var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
47 var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
48     'ascii');
49 var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem',
50     'ascii');
51 var rsaKeyPemEncrypted = fs.readFileSync(
52   common.fixturesDir + '/test_rsa_privkey_encrypted.pem', 'ascii');
53 var dsaPubPem = fs.readFileSync(common.fixturesDir + '/test_dsa_pubkey.pem',
54     'ascii');
55 var dsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_dsa_privkey.pem',
56     'ascii');
57 var dsaKeyPemEncrypted = fs.readFileSync(
58   common.fixturesDir + '/test_dsa_privkey_encrypted.pem', 'ascii');
59
60
61 // TODO(indunty): move to a separate test eventually
62 try {
63   var tls = require('tls');
64   var context = tls.createSecureContext({
65     key: keyPem,
66     cert: certPem,
67     ca: caPem
68   });
69 } catch (e) {
70   console.log('Not compiled with OPENSSL support.');
71   process.exit();
72 }
73
74 // 'this' safety
75 // https://github.com/joyent/node/issues/6690
76 assert.throws(function() {
77   var options = {key: keyPem, cert: certPem, ca: caPem};
78   var credentials = crypto.createCredentials(options);
79   var context = credentials.context;
80   var notcontext = { setOptions: context.setOptions, setKey: context.setKey };
81   crypto.createCredentials({ secureOptions: 1 }, notcontext);
82 }, TypeError);
83
84 // PFX tests
85 assert.doesNotThrow(function() {
86   tls.createSecureContext({pfx:certPfx, passphrase:'sample'});
87 });
88
89 assert.throws(function() {
90   tls.createSecureContext({pfx:certPfx});
91 }, 'mac verify failure');
92
93 assert.throws(function() {
94   tls.createSecureContext({pfx:certPfx, passphrase:'test'});
95 }, 'mac verify failure');
96
97 assert.throws(function() {
98   tls.createSecureContext({pfx:'sample', passphrase:'test'});
99 }, 'not enough data');
100
101 // Test HMAC
102 var h1 = crypto.createHmac('sha1', 'Node')
103                .update('some data')
104                .update('to hmac')
105                .digest('hex');
106 assert.equal(h1, '19fd6e1ba73d9ed2224dd5094a71babe85d9a892', 'test HMAC');
107
108 // Test HMAC (Wikipedia Test Cases)
109 var wikipedia = [
110   {
111     key: 'key', data: 'The quick brown fox jumps over the lazy dog',
112     hmac: {  // HMACs lifted from Wikipedia.
113       md5: '80070713463e7749b90c2dc24911e275',
114       sha1: 'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9',
115       sha256:
116           'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc' +
117           '2d1a3cd8'
118     }
119   },
120   {
121     key: 'key', data: '',
122     hmac: {  // Intermediate test to help debugging.
123       md5: '63530468a04e386459855da0063b6596',
124       sha1: 'f42bb0eeb018ebbd4597ae7213711ec60760843f',
125       sha256:
126           '5d5d139563c95b5967b9bd9a8c9b233a9dedb45072794cd232dc1b74' +
127           '832607d0'
128     }
129   },
130   {
131     key: '', data: 'The quick brown fox jumps over the lazy dog',
132     hmac: {  // Intermediate test to help debugging.
133       md5: 'ad262969c53bc16032f160081c4a07a0',
134       sha1: '2ba7f707ad5f187c412de3106583c3111d668de8',
135       sha256:
136           'fb011e6154a19b9a4c767373c305275a5a69e8b68b0b4c9200c383dc' +
137           'ed19a416'
138     }
139   },
140   {
141     key: '', data: '',
142     hmac: {  // HMACs lifted from Wikipedia.
143       md5: '74e6f7298a9c2d168935f58c001bad88',
144       sha1: 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d',
145       sha256:
146           'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c71214' +
147           '4292c5ad'
148     }
149   },
150 ]
151
152 for (var i = 0, l = wikipedia.length; i < l; i++) {
153   for (var hash in wikipedia[i]['hmac']) {
154     var result = crypto.createHmac(hash, wikipedia[i]['key'])
155                      .update(wikipedia[i]['data'])
156                      .digest('hex');
157     assert.equal(wikipedia[i]['hmac'][hash],
158                  result,
159                  'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' wikipedia');
160   }
161 }
162
163
164 // Test HMAC-SHA-* (rfc 4231 Test Cases)
165 var rfc4231 = [
166   {
167     key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
168     data: new Buffer('4869205468657265', 'hex'), // 'Hi There'
169     hmac: {
170       sha224: '896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22',
171       sha256:
172           'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c' +
173           '2e32cff7',
174       sha384:
175           'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c' +
176           '7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6',
177       sha512:
178           '87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b305' +
179           '45e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f170' +
180           '2e696c203a126854'
181     }
182   },
183   {
184     key: new Buffer('4a656665', 'hex'), // 'Jefe'
185     data: new Buffer('7768617420646f2079612077616e7420666f72206e6f74686' +
186                      '96e673f', 'hex'), // 'what do ya want for nothing?'
187     hmac: {
188       sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44',
189       sha256:
190           '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b9' +
191           '64ec3843',
192       sha384:
193           'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec373' +
194           '6322445e8e2240ca5e69e2c78b3239ecfab21649',
195       sha512:
196           '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7' +
197           'ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b' +
198           '636e070a38bce737'
199     }
200   },
201   {
202     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
203     data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' +
204                      'ddddddddddddddddddddddddddddddddddddddddddddddddddd',
205                      'hex'),
206     hmac: {
207       sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea',
208       sha256:
209           '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514' +
210           'ced565fe',
211       sha384:
212           '88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e5' +
213           '5966144b2a5ab39dc13814b94e3ab6e101a34f27',
214       sha512:
215           'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33' +
216           'b2279d39bf3e848279a722c806b485a47e67c807b946a337bee89426' +
217           '74278859e13292fb'
218     }
219   },
220   {
221     key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
222                     'hex'),
223     data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
224                      'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd',
225                      'hex'),
226     hmac: {
227       sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a',
228       sha256:
229           '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff4' +
230           '6729665b',
231       sha384:
232           '3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e' +
233           '1f573b4e6801dd23c4a7d679ccf8a386c674cffb',
234       sha512:
235           'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050' +
236           '361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2d' +
237           'e2adebeb10a298dd'
238     }
239   },
240
241   {
242     key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
243     // 'Test With Truncation'
244     data: new Buffer('546573742057697468205472756e636174696f6e', 'hex'),
245     hmac: {
246       sha224: '0e2aea68a90c8d37c988bcdb9fca6fa8',
247       sha256: 'a3b6167473100ee06e0c796c2955552b',
248       sha384: '3abf34c3503b2a23a46efc619baef897',
249       sha512: '415fad6271580a531d4179bc891d87a6'
250     },
251     truncate: true
252   },
253   {
254     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
255                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
256                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
257                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
258                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
259                     'aaaaaaaaaaaa', 'hex'),
260     // 'Test Using Larger Than Block-Size Key - Hash Key First'
261     data: new Buffer('54657374205573696e67204c6172676572205468616e20426' +
262                      'c6f636b2d53697a65204b6579202d2048617368204b657920' +
263                      '4669727374', 'hex'),
264     hmac: {
265       sha224: '95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e',
266       sha256:
267           '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f' +
268           '0ee37f54',
269       sha384:
270           '4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05' +
271           '033ac4c60c2ef6ab4030fe8296248df163f44952',
272       sha512:
273           '80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b0137' +
274           '83f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec' +
275           '8b915a985d786598'
276     }
277   },
278   {
279     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
280                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
281                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
282                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
283                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
284                     'aaaaaaaaaaaa', 'hex'),
285     // 'This is a test using a larger than block-size key and a larger ' +
286     // 'than block-size data. The key needs to be hashed before being ' +
287     // 'used by the HMAC algorithm.'
288     data: new Buffer('5468697320697320612074657374207573696e672061206c6' +
289                      '172676572207468616e20626c6f636b2d73697a65206b6579' +
290                      '20616e642061206c6172676572207468616e20626c6f636b2' +
291                      'd73697a6520646174612e20546865206b6579206e65656473' +
292                      '20746f20626520686173686564206265666f7265206265696' +
293                      'e6720757365642062792074686520484d414320616c676f72' +
294                      '6974686d2e', 'hex'),
295     hmac: {
296       sha224: '3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1',
297       sha256:
298           '9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f5153' +
299           '5c3a35e2',
300       sha384:
301           '6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82' +
302           '461e99c5a678cc31e799176d3860e6110c46523e',
303       sha512:
304           'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d' +
305           '20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de04460' +
306           '65c97440fa8c6a58'
307     }
308   }
309 ];
310
311 for (var i = 0, l = rfc4231.length; i < l; i++) {
312   for (var hash in rfc4231[i]['hmac']) {
313     var str = crypto.createHmac(hash, rfc4231[i].key);
314     str.end(rfc4231[i].data);
315     var strRes = str.read().toString('hex');
316     var result = crypto.createHmac(hash, rfc4231[i]['key'])
317                      .update(rfc4231[i]['data'])
318                      .digest('hex');
319     if (rfc4231[i]['truncate']) {
320       result = result.substr(0, 32); // first 128 bits == 32 hex chars
321       strRes = strRes.substr(0, 32);
322     }
323     assert.equal(rfc4231[i]['hmac'][hash],
324                  result,
325                  'Test HMAC-' + hash + ': Test case ' + (i + 1) + ' rfc 4231');
326     assert.equal(strRes, result, 'Should get same result from stream');
327   }
328 }
329
330 // Test HMAC-MD5/SHA1 (rfc 2202 Test Cases)
331 var rfc2202_md5 = [
332   {
333     key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
334     data: 'Hi There',
335     hmac: '9294727a3638bb1c13f48ef8158bfc9d'
336   },
337   {
338     key: 'Jefe',
339     data: 'what do ya want for nothing?',
340     hmac: '750c783e6ab0b503eaa86e310a5db738'
341   },
342   {
343     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
344     data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddddddd' +
345                      'ddddddddddddddddddddddddddddddddddddddddddddddddddd',
346                      'hex'),
347     hmac: '56be34521d144c88dbb8c733f0e8b3f6'
348   },
349   {
350     key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
351                     'hex'),
352     data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
353                      'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' +
354                      'cdcdcdcdcd',
355                      'hex'),
356     hmac: '697eaf0aca3a3aea3a75164746ffaa79'
357   },
358   {
359     key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
360     data: 'Test With Truncation',
361     hmac: '56461ef2342edc00f9bab995690efd4c'
362   },
363   {
364     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
365                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
366                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
367                     'aaaaaaaaaaaaaaaaaaaaaa',
368                     'hex'),
369     data: 'Test Using Larger Than Block-Size Key - Hash Key First',
370     hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd'
371   },
372   {
373     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
374                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
375                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
376                     'aaaaaaaaaaaaaaaaaaaaaa',
377                     'hex'),
378     data:
379         'Test Using Larger Than Block-Size Key and Larger Than One ' +
380         'Block-Size Data',
381     hmac: '6f630fad67cda0ee1fb1f562db3aa53e'
382   }
383 ];
384 var rfc2202_sha1 = [
385   {
386     key: new Buffer('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
387     data: 'Hi There',
388     hmac: 'b617318655057264e28bc0b6fb378c8ef146be00'
389   },
390   {
391     key: 'Jefe',
392     data: 'what do ya want for nothing?',
393     hmac: 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'
394   },
395   {
396     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
397     data: new Buffer('ddddddddddddddddddddddddddddddddddddddddddddd' +
398                      'ddddddddddddddddddddddddddddddddddddddddddddd' +
399                      'dddddddddd',
400                      'hex'),
401     hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3'
402   },
403   {
404     key: new Buffer('0102030405060708090a0b0c0d0e0f10111213141516171819',
405                     'hex'),
406     data: new Buffer('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' +
407                      'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' +
408                      'cdcdcdcdcd',
409                      'hex'),
410     hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da'
411   },
412   {
413     key: new Buffer('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
414     data: 'Test With Truncation',
415     hmac: '4c1a03424b55e07fe7f27be1d58bb9324a9a5a04'
416   },
417   {
418     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
419                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
420                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
421                     'aaaaaaaaaaaaaaaaaaaaaa',
422                     'hex'),
423     data: 'Test Using Larger Than Block-Size Key - Hash Key First',
424     hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112'
425   },
426   {
427     key: new Buffer('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
428                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
429                     'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +
430                     'aaaaaaaaaaaaaaaaaaaaaa',
431                     'hex'),
432     data:
433         'Test Using Larger Than Block-Size Key and Larger Than One ' +
434         'Block-Size Data',
435     hmac: 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91'
436   }
437 ];
438
439 for (var i = 0, l = rfc2202_md5.length; i < l; i++) {
440   assert.equal(rfc2202_md5[i]['hmac'],
441                crypto.createHmac('md5', rfc2202_md5[i]['key'])
442                    .update(rfc2202_md5[i]['data'])
443                    .digest('hex'),
444                'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202');
445 }
446 for (var i = 0, l = rfc2202_sha1.length; i < l; i++) {
447   assert.equal(rfc2202_sha1[i]['hmac'],
448                crypto.createHmac('sha1', rfc2202_sha1[i]['key'])
449                    .update(rfc2202_sha1[i]['data'])
450                    .digest('hex'),
451                'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202');
452 }
453
454 // Test hashing
455 var a0 = crypto.createHash('sha1').update('Test123').digest('hex');
456 var a1 = crypto.createHash('md5').update('Test123').digest('binary');
457 var a2 = crypto.createHash('sha256').update('Test123').digest('base64');
458 var a3 = crypto.createHash('sha512').update('Test123').digest(); // binary
459 var a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
460
461 // stream interface
462 var a5 = crypto.createHash('sha512');
463 a5.end('Test123');
464 a5 = a5.read();
465
466 var a6 = crypto.createHash('sha512');
467 a6.write('Te');
468 a6.write('st');
469 a6.write('123');
470 a6.end();
471 a6 = a6.read();
472
473 var a7 = crypto.createHash('sha512');
474 a7.end();
475 a7 = a7.read();
476
477 var a8 = crypto.createHash('sha512');
478 a8.write('');
479 a8.end();
480 a8 = a8.read();
481
482 assert.equal(a0, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1');
483 assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
484              '\u00bd\u008c', 'Test MD5 as binary');
485 assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
486              'Test SHA256 as base64');
487 assert.deepEqual(
488   a3,
489   new Buffer(
490     '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
491     '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
492     '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
493     '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
494     '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
495     'binary'),
496   'Test SHA512 as assumed buffer');
497 assert.deepEqual(a4,
498                  new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
499                  'Test SHA1');
500
501 // stream interface should produce the same result.
502 assert.deepEqual(a5, a3, 'stream interface is consistent');
503 assert.deepEqual(a6, a3, 'stream interface is consistent');
504 assert.notEqual(a7, undefined, 'no data should return data');
505 assert.notEqual(a8, undefined, 'empty string should generate data');
506
507 // Test multiple updates to same hash
508 var h1 = crypto.createHash('sha1').update('Test123').digest('hex');
509 var h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex');
510 assert.equal(h1, h2, 'multipled updates');
511
512 // Test hashing for binary files
513 var fn = path.join(common.fixturesDir, 'sample.png');
514 var sha1Hash = crypto.createHash('sha1');
515 var fileStream = fs.createReadStream(fn);
516 fileStream.on('data', function(data) {
517   sha1Hash.update(data);
518 });
519 fileStream.on('close', function() {
520   assert.equal(sha1Hash.digest('hex'),
521                '22723e553129a336ad96e10f6aecdf0f45e4149e',
522                'Test SHA1 of sample.png');
523 });
524
525 // Issue #2227: unknown digest method should throw an error.
526 assert.throws(function() {
527   crypto.createHash('xyzzy');
528 });
529
530 // Test signing and verifying
531 var s1 = crypto.createSign('RSA-SHA1')
532                .update('Test123')
533                .sign(keyPem, 'base64');
534 var s1stream = crypto.createSign('RSA-SHA1');
535 s1stream.end('Test123');
536 s1stream = s1stream.sign(keyPem, 'base64');
537 assert.equal(s1, s1stream, 'Stream produces same output');
538
539 var verified = crypto.createVerify('RSA-SHA1')
540                      .update('Test')
541                      .update('123')
542                      .verify(certPem, s1, 'base64');
543 assert.strictEqual(verified, true, 'sign and verify (base 64)');
544
545 var s2 = crypto.createSign('RSA-SHA256')
546                .update('Test123')
547                .sign(keyPem, 'binary');
548 var s2stream = crypto.createSign('RSA-SHA256');
549 s2stream.end('Test123');
550 s2stream = s2stream.sign(keyPem, 'binary');
551 assert.equal(s2, s2stream, 'Stream produces same output');
552
553 var verified = crypto.createVerify('RSA-SHA256')
554                      .update('Test')
555                      .update('123')
556                      .verify(certPem, s2, 'binary');
557 assert.strictEqual(verified, true, 'sign and verify (binary)');
558
559 var verStream = crypto.createVerify('RSA-SHA256');
560 verStream.write('Tes');
561 verStream.write('t12');
562 verStream.end('3');
563 verified = verStream.verify(certPem, s2, 'binary');
564 assert.strictEqual(verified, true, 'sign and verify (stream)');
565
566 var s3 = crypto.createSign('RSA-SHA1')
567                .update('Test123')
568                .sign(keyPem, 'buffer');
569 var verified = crypto.createVerify('RSA-SHA1')
570                      .update('Test')
571                      .update('123')
572                      .verify(certPem, s3);
573 assert.strictEqual(verified, true, 'sign and verify (buffer)');
574
575 var verStream = crypto.createVerify('RSA-SHA1');
576 verStream.write('Tes');
577 verStream.write('t12');
578 verStream.end('3');
579 verified = verStream.verify(certPem, s3);
580 assert.strictEqual(verified, true, 'sign and verify (stream)');
581
582
583 function testCipher1(key) {
584   // Test encryption and decryption
585   var plaintext = 'Keep this a secret? No! Tell everyone about node.js!';
586   var cipher = crypto.createCipher('aes192', key);
587
588   // encrypt plaintext which is in utf8 format
589   // to a ciphertext which will be in hex
590   var ciph = cipher.update(plaintext, 'utf8', 'hex');
591   // Only use binary or hex, not base64.
592   ciph += cipher.final('hex');
593
594   var decipher = crypto.createDecipher('aes192', key);
595   var txt = decipher.update(ciph, 'hex', 'utf8');
596   txt += decipher.final('utf8');
597
598   assert.equal(txt, plaintext, 'encryption and decryption');
599
600   // streaming cipher interface
601   // NB: In real life, it's not guaranteed that you can get all of it
602   // in a single read() like this.  But in this case, we know it's
603   // quite small, so there's no harm.
604   var cStream = crypto.createCipher('aes192', key);
605   cStream.end(plaintext);
606   ciph = cStream.read();
607
608   var dStream = crypto.createDecipher('aes192', key);
609   dStream.end(ciph);
610   txt = dStream.read().toString('utf8');
611
612   assert.equal(txt, plaintext, 'encryption and decryption with streams');
613 }
614
615
616 function testCipher2(key) {
617   // encryption and decryption with Base64
618   // reported in https://github.com/joyent/node/issues/738
619   var plaintext =
620       '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
621       'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
622       'jAfaFg**';
623   var cipher = crypto.createCipher('aes256', key);
624
625   // encrypt plaintext which is in utf8 format
626   // to a ciphertext which will be in Base64
627   var ciph = cipher.update(plaintext, 'utf8', 'base64');
628   ciph += cipher.final('base64');
629
630   var decipher = crypto.createDecipher('aes256', key);
631   var txt = decipher.update(ciph, 'base64', 'utf8');
632   txt += decipher.final('utf8');
633
634   assert.equal(txt, plaintext, 'encryption and decryption with Base64');
635 }
636
637
638 function testCipher3(key, iv) {
639   // Test encyrption and decryption with explicit key and iv
640   var plaintext =
641       '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
642       'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
643       'jAfaFg**';
644   var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
645   var ciph = cipher.update(plaintext, 'utf8', 'hex');
646   ciph += cipher.final('hex');
647
648   var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
649   var txt = decipher.update(ciph, 'hex', 'utf8');
650   txt += decipher.final('utf8');
651
652   assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
653
654   // streaming cipher interface
655   // NB: In real life, it's not guaranteed that you can get all of it
656   // in a single read() like this.  But in this case, we know it's
657   // quite small, so there's no harm.
658   var cStream = crypto.createCipheriv('des-ede3-cbc', key, iv);
659   cStream.end(plaintext);
660   ciph = cStream.read();
661
662   var dStream = crypto.createDecipheriv('des-ede3-cbc', key, iv);
663   dStream.end(ciph);
664   txt = dStream.read().toString('utf8');
665
666   assert.equal(txt, plaintext, 'streaming cipher iv');
667 }
668
669
670 function testCipher4(key, iv) {
671   // Test encyrption and decryption with explicit key and iv
672   var plaintext =
673       '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' +
674       'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' +
675       'jAfaFg**';
676   var cipher = crypto.createCipheriv('des-ede3-cbc', key, iv);
677   var ciph = cipher.update(plaintext, 'utf8', 'buffer');
678   ciph = Buffer.concat([ciph, cipher.final('buffer')]);
679
680   var decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv);
681   var txt = decipher.update(ciph, 'buffer', 'utf8');
682   txt += decipher.final('utf8');
683
684   assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
685 }
686
687
688 testCipher1('MySecretKey123');
689 testCipher1(new Buffer('MySecretKey123'));
690
691 testCipher2('0123456789abcdef');
692 testCipher2(new Buffer('0123456789abcdef'));
693
694 testCipher3('0123456789abcd0123456789', '12345678');
695 testCipher3('0123456789abcd0123456789', new Buffer('12345678'));
696 testCipher3(new Buffer('0123456789abcd0123456789'), '12345678');
697 testCipher3(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
698
699 testCipher4(new Buffer('0123456789abcd0123456789'), new Buffer('12345678'));
700
701
702 // update() should only take buffers / strings
703 assert.throws(function() {
704   crypto.createHash('sha1').update({foo: 'bar'});
705 }, /buffer/);
706
707
708 // Test Diffie-Hellman with two parties sharing a secret,
709 // using various encodings as we go along
710 var dh1 = crypto.createDiffieHellman(256);
711 var p1 = dh1.getPrime('buffer');
712 var dh2 = crypto.createDiffieHellman(p1, 'buffer');
713 var key1 = dh1.generateKeys();
714 var key2 = dh2.generateKeys('hex');
715 var secret1 = dh1.computeSecret(key2, 'hex', 'base64');
716 var secret2 = dh2.computeSecret(key1, 'binary', 'buffer');
717
718 assert.equal(secret1, secret2.toString('base64'));
719 assert.equal(dh1.verifyError, 0);
720 assert.equal(dh2.verifyError, 0);
721
722 // Create "another dh1" using generated keys from dh1,
723 // and compute secret again
724 var dh3 = crypto.createDiffieHellman(p1, 'buffer');
725 var privkey1 = dh1.getPrivateKey();
726 dh3.setPublicKey(key1);
727 dh3.setPrivateKey(privkey1);
728
729 assert.deepEqual(dh1.getPrime(), dh3.getPrime());
730 assert.deepEqual(dh1.getGenerator(), dh3.getGenerator());
731 assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey());
732 assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey());
733 assert.equal(dh3.verifyError, 0);
734
735 var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
736
737 assert.equal(secret1, secret3);
738
739 // Run this one twice to make sure that the dh3 clears its error properly
740 (function() {
741   var c = crypto.createDecipher('aes-128-ecb', '');
742   assert.throws(function() { c.final('utf8') }, /wrong final block length/);
743 })();
744
745 assert.throws(function() {
746   dh3.computeSecret('');
747 }, /key is too small/i);
748
749 (function() {
750   var c = crypto.createDecipher('aes-128-ecb', '');
751   assert.throws(function() { c.final('utf8') }, /wrong final block length/);
752 })();
753
754 // Create a shared using a DH group.
755 var alice = crypto.createDiffieHellmanGroup('modp5');
756 var bob = crypto.createDiffieHellmanGroup('modp5');
757 alice.generateKeys();
758 bob.generateKeys();
759 var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex');
760 var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex');
761 assert.equal(aSecret, bSecret);
762 assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
763 assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
764
765 // Ensure specific generator (buffer) works as expected.
766 var modp1 = crypto.createDiffieHellmanGroup('modp1');
767 var modp1buf = new Buffer([
768   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f,
769   0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
770   0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67,
771   0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22,
772   0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95,
773   0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
774   0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51,
775   0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
776   0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff,
777   0xff, 0xff, 0xff, 0xff, 0xff, 0xff
778 ]);
779 var exmodp1 = crypto.createDiffieHellman(modp1buf, new Buffer([2]));
780 modp1.generateKeys();
781 exmodp1.generateKeys();
782 var modp1Secret = modp1.computeSecret(exmodp1.getPublicKey()).toString('hex');
783 var exmodp1Secret = exmodp1.computeSecret(modp1.getPublicKey()).toString('hex');
784 assert.equal(modp1Secret, exmodp1Secret);
785 assert.equal(modp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
786 assert.equal(exmodp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
787
788
789 // Ensure specific generator (string with encoding) works as expected.
790 var exmodp1_2 = crypto.createDiffieHellman(modp1buf, '02', 'hex');
791 exmodp1_2.generateKeys();
792 modp1Secret = modp1.computeSecret(exmodp1_2.getPublicKey()).toString('hex');
793 var exmodp1_2Secret = exmodp1_2.computeSecret(modp1.getPublicKey())
794                                .toString('hex');
795 assert.equal(modp1Secret, exmodp1_2Secret);
796 assert.equal(exmodp1_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
797
798
799 // Ensure specific generator (string without encoding) works as expected.
800 var exmodp1_3 = crypto.createDiffieHellman(modp1buf, '\x02');
801 exmodp1_3.generateKeys();
802 modp1Secret = modp1.computeSecret(exmodp1_3.getPublicKey()).toString('hex');
803 var exmodp1_3Secret = exmodp1_3.computeSecret(modp1.getPublicKey())
804                                .toString('hex');
805 assert.equal(modp1Secret, exmodp1_3Secret);
806 assert.equal(exmodp1_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
807
808
809 // Ensure specific generator (numeric) works as expected.
810 var exmodp1_4 = crypto.createDiffieHellman(modp1buf, 2);
811 exmodp1_4.generateKeys();
812 modp1Secret = modp1.computeSecret(exmodp1_4.getPublicKey()).toString('hex');
813 var exmodp1_4Secret = exmodp1_4.computeSecret(modp1.getPublicKey())
814                                .toString('hex');
815 assert.equal(modp1Secret, exmodp1_4Secret);
816 assert.equal(exmodp1_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
817
818
819 var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +
820         '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' +
821         '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' +
822         'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
823 var bad_dh = crypto.createDiffieHellman(p, 'hex');
824 assert.equal(bad_dh.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
825
826 // Test RSA encryption/decryption
827 (function() {
828   var input = 'I AM THE WALRUS';
829   var bufferToEncrypt = new Buffer(input);
830
831   var encryptedBuffer = crypto.publicEncrypt(rsaPubPem, bufferToEncrypt);
832
833   var decryptedBuffer = crypto.privateDecrypt(rsaKeyPem, encryptedBuffer);
834   assert.equal(input, decryptedBuffer.toString());
835
836   var decryptedBufferWithPassword = crypto.privateDecrypt({
837     key: rsaKeyPemEncrypted,
838     passphrase: 'password'
839   }, encryptedBuffer);
840   assert.equal(input, decryptedBufferWithPassword.toString());
841
842   encryptedBuffer = crypto.publicEncrypt(certPem, bufferToEncrypt);
843
844   decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer);
845   assert.equal(input, decryptedBuffer.toString());
846
847   encryptedBuffer = crypto.publicEncrypt(keyPem, bufferToEncrypt);
848
849   decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer);
850   assert.equal(input, decryptedBuffer.toString());
851
852   assert.throws(function() {
853     crypto.privateDecrypt({
854       key: rsaKeyPemEncrypted,
855       passphrase: 'wrong'
856     }, encryptedBuffer);
857   });
858 })();
859
860 // Test RSA key signing/verification
861 var rsaSign = crypto.createSign('RSA-SHA1');
862 var rsaVerify = crypto.createVerify('RSA-SHA1');
863 assert.ok(rsaSign);
864 assert.ok(rsaVerify);
865
866 rsaSign.update(rsaPubPem);
867 var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex');
868 assert.equal(rsaSignature,
869              '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
870              '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
871              'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
872              '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
873              '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
874
875 rsaVerify.update(rsaPubPem);
876 assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
877
878 // Test RSA key signing/verification with encrypted key
879 rsaSign = crypto.createSign('RSA-SHA1');
880 rsaSign.update(rsaPubPem);
881 assert.doesNotThrow(function() {
882   var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'password' };
883   rsaSignature = rsaSign.sign(signOptions, 'hex');
884 });
885 assert.equal(rsaSignature,
886              '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
887              '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
888              'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
889              '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
890              '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
891
892 rsaVerify = crypto.createVerify('RSA-SHA1');
893 rsaVerify.update(rsaPubPem);
894 assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
895
896 rsaSign = crypto.createSign('RSA-SHA1');
897 rsaSign.update(rsaPubPem);
898 assert.throws(function() {
899   var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' };
900   rsaSign.sign(signOptions, 'hex');
901 });
902
903 //
904 // Test RSA signing and verification
905 //
906 (function() {
907   var privateKey = fs.readFileSync(
908       common.fixturesDir + '/test_rsa_privkey_2.pem');
909
910   var publicKey = fs.readFileSync(
911       common.fixturesDir + '/test_rsa_pubkey_2.pem');
912
913   var input = 'I AM THE WALRUS';
914
915   var signature =
916       '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89' +
917       '396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa' +
918       '235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb2' +
919       '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' +
920       '0ddfb299bedeb1ad';
921
922   var sign = crypto.createSign('RSA-SHA256');
923   sign.update(input);
924
925   var output = sign.sign(privateKey, 'hex');
926   assert.equal(output, signature);
927
928   var verify = crypto.createVerify('RSA-SHA256');
929   verify.update(input);
930
931   assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true);
932 })();
933
934
935 //
936 // Test DSA signing and verification
937 //
938 (function() {
939   var input = 'I AM THE WALRUS';
940
941   // DSA signatures vary across runs so there is no static string to verify
942   // against
943   var sign = crypto.createSign('DSS1');
944   sign.update(input);
945   var signature = sign.sign(dsaKeyPem, 'hex');
946
947   var verify = crypto.createVerify('DSS1');
948   verify.update(input);
949
950   assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
951 })();
952
953
954 //
955 // Test DSA signing and verification with encrypted key
956 //
957 (function() {
958   var input = 'I AM THE WALRUS';
959
960   var sign = crypto.createSign('DSS1');
961   sign.update(input);
962   assert.throws(function() {
963     sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex');
964   });
965
966   // DSA signatures vary across runs so there is no static string to verify
967   // against
968   var sign = crypto.createSign('DSS1');
969   sign.update(input);
970
971   var signature;
972   assert.doesNotThrow(function() {
973     var signOptions = { key: dsaKeyPemEncrypted, passphrase: 'password' };
974     signature = sign.sign(signOptions, 'hex');
975   });
976
977   var verify = crypto.createVerify('DSS1');
978   verify.update(input);
979
980   assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
981 })();
982
983
984 //
985 // Test PBKDF2 with RFC 6070 test vectors (except #4)
986 //
987 function testPBKDF2(password, salt, iterations, keylen, expected) {
988   var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen);
989   assert.equal(actual.toString('binary'), expected);
990
991   crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) {
992     assert.equal(actual.toString('binary'), expected);
993   });
994 }
995
996
997 testPBKDF2('password', 'salt', 1, 20,
998            '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' +
999            '\xaf\x60\x12\x06\x2f\xe0\x37\xa6');
1000
1001 testPBKDF2('password', 'salt', 2, 20,
1002            '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' +
1003            '\xce\x1d\x41\xf0\xd8\xde\x89\x57');
1004
1005 testPBKDF2('password', 'salt', 4096, 20,
1006            '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' +
1007            '\xf7\x21\xd0\x65\xa4\x29\xc1');
1008
1009 testPBKDF2('passwordPASSWORDpassword',
1010            'saltSALTsaltSALTsaltSALTsaltSALTsalt',
1011            4096,
1012            25,
1013            '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' +
1014            '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38');
1015
1016 testPBKDF2('pass\0word', 'sa\0lt', 4096, 16,
1017            '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' +
1018            '\x25\xe0\xc3');
1019
1020 (function() {
1021   var expected =
1022       '64c486c55d30d4c5a079b8823b7d7cb37ff0556f537da8410233bcec330ed956';
1023   var key = crypto.pbkdf2Sync('password', 'salt', 32, 32, 'sha256');
1024   assert.equal(key.toString('hex'), expected);
1025
1026   crypto.pbkdf2('password', 'salt', 32, 32, 'sha256', common.mustCall(ondone));
1027   function ondone(err, key) {
1028     if (err) throw err;
1029     assert.equal(key.toString('hex'), expected);
1030   }
1031 })();
1032
1033 function assertSorted(list) {
1034   // Array#sort() modifies the list in place so make a copy.
1035   var sorted = util._extend([], list).sort();
1036   assert.deepEqual(list, sorted);
1037 }
1038
1039 // Assume that we have at least AES-128-CBC.
1040 assert.notEqual(0, crypto.getCiphers().length);
1041 assert.notEqual(-1, crypto.getCiphers().indexOf('aes-128-cbc'));
1042 assert.equal(-1, crypto.getCiphers().indexOf('AES-128-CBC'));
1043 assertSorted(crypto.getCiphers());
1044
1045 // Assume that we have at least AES256-SHA.
1046 var tls = require('tls');
1047 assert.notEqual(0, tls.getCiphers().length);
1048 assert.notEqual(-1, tls.getCiphers().indexOf('aes256-sha'));
1049 assert.equal(-1, tls.getCiphers().indexOf('AES256-SHA'));
1050 assertSorted(tls.getCiphers());
1051
1052 // Assert that we have sha and sha1 but not SHA and SHA1.
1053 assert.notEqual(0, crypto.getHashes().length);
1054 assert.notEqual(-1, crypto.getHashes().indexOf('sha1'));
1055 assert.notEqual(-1, crypto.getHashes().indexOf('sha'));
1056 assert.equal(-1, crypto.getHashes().indexOf('SHA1'));
1057 assert.equal(-1, crypto.getHashes().indexOf('SHA'));
1058 assert.notEqual(-1, crypto.getHashes().indexOf('RSA-SHA1'));
1059 assert.equal(-1, crypto.getHashes().indexOf('rsa-sha1'));
1060 assertSorted(crypto.getHashes());
1061
1062 // Base64 padding regression test, see #4837.
1063 (function() {
1064   var c = crypto.createCipher('aes-256-cbc', 'secret');
1065   var s = c.update('test', 'utf8', 'base64') + c.final('base64');
1066   assert.equal(s, '375oxUQCIocvxmC5At+rvA==');
1067 })();
1068
1069 // Error path should not leak memory (check with valgrind).
1070 assert.throws(function() {
1071   crypto.pbkdf2('password', 'salt', 1, 20, null);
1072 });
1073
1074 // Calling Cipher.final() or Decipher.final() twice should error but
1075 // not assert. See #4886.
1076 (function() {
1077   var c = crypto.createCipher('aes-256-cbc', 'secret');
1078   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1079   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1080   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1081   var d = crypto.createDecipher('aes-256-cbc', 'secret');
1082   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1083   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1084   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1085 })();
1086
1087 // Regression test for #5482: string to Cipher#update() should not assert.
1088 (function() {
1089   var c = crypto.createCipher('aes192', '0123456789abcdef');
1090   c.update('update');
1091   c.final();
1092 })();
1093
1094 // #5655 regression tests, 'utf-8' and 'utf8' are identical.
1095 (function() {
1096   var c = crypto.createCipher('aes192', '0123456789abcdef');
1097   c.update('update', '');  // Defaults to "utf8".
1098   c.final('utf-8');  // Should not throw.
1099
1100   c = crypto.createCipher('aes192', '0123456789abcdef');
1101   c.update('update', 'utf8');
1102   c.final('utf-8');  // Should not throw.
1103
1104   c = crypto.createCipher('aes192', '0123456789abcdef');
1105   c.update('update', 'utf-8');
1106   c.final('utf8');  // Should not throw.
1107 })();
1108
1109 // Regression tests for #5725: hex input that's not a power of two should
1110 // throw, not assert in C++ land.
1111 assert.throws(function() {
1112   crypto.createCipher('aes192', 'test').update('0', 'hex');
1113 }, /Bad input string/);
1114
1115 assert.throws(function() {
1116   crypto.createDecipher('aes192', 'test').update('0', 'hex');
1117 }, /Bad input string/);
1118
1119 assert.throws(function() {
1120   crypto.createHash('sha1').update('0', 'hex');
1121 }, /Bad input string/);
1122
1123 assert.throws(function() {
1124   crypto.createSign('RSA-SHA1').update('0', 'hex');
1125 }, /Bad input string/);
1126
1127 assert.throws(function() {
1128   crypto.createVerify('RSA-SHA1').update('0', 'hex');
1129 }, /Bad input string/);
1130
1131 assert.throws(function() {
1132   var private = [
1133     '-----BEGIN RSA PRIVATE KEY-----',
1134     'MIGrAgEAAiEA+3z+1QNF2/unumadiwEr+C5vfhezsb3hp4jAnCNRpPcCAwEAAQIgQNriSQK4',
1135     'EFwczDhMZp2dvbcz7OUUyt36z3S4usFPHSECEQD/41K7SujrstBfoCPzwC1xAhEA+5kt4BJy',
1136     'eKN7LggbF3Dk5wIQN6SL+fQ5H/+7NgARsVBp0QIRANxYRukavs4QvuyNhMx+vrkCEQCbf6j/',
1137     'Ig6/HueCK/0Jkmp+',
1138     '-----END RSA PRIVATE KEY-----',
1139     ''
1140   ].join('\n');
1141   crypto.createSign('RSA-SHA256').update('test').sign(private);
1142 }, /RSA_sign:digest too big for rsa key/);
1143
1144 // Make sure memory isn't released before being returned
1145 console.log(crypto.randomBytes(16));