crypto: allow padding in RSA methods
[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 function test_rsa(padding) {
861   var input = new Buffer(padding === 'RSA_NO_PADDING' ? 1024 / 8 : 32);
862   for (var i = 0; i < input.length; i++)
863     input[i] = (i * 7 + 11) & 0xff;
864   var bufferToEncrypt = new Buffer(input);
865
866   padding = constants[padding];
867
868   var encryptedBuffer = crypto.publicEncrypt({
869     key: rsaPubPem,
870     padding: padding
871   }, bufferToEncrypt);
872
873   var decryptedBuffer = crypto.privateDecrypt({
874     key: rsaKeyPem,
875     padding: padding
876   }, encryptedBuffer);
877   assert.equal(input, decryptedBuffer.toString());
878 }
879
880 test_rsa('RSA_NO_PADDING');
881 test_rsa('RSA_PKCS1_PADDING');
882 test_rsa('RSA_PKCS1_OAEP_PADDING');
883
884 // Test RSA key signing/verification
885 var rsaSign = crypto.createSign('RSA-SHA1');
886 var rsaVerify = crypto.createVerify('RSA-SHA1');
887 assert.ok(rsaSign);
888 assert.ok(rsaVerify);
889
890 rsaSign.update(rsaPubPem);
891 var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex');
892 assert.equal(rsaSignature,
893              '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
894              '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
895              'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
896              '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
897              '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
898
899 rsaVerify.update(rsaPubPem);
900 assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
901
902 // Test RSA key signing/verification with encrypted key
903 rsaSign = crypto.createSign('RSA-SHA1');
904 rsaSign.update(rsaPubPem);
905 assert.doesNotThrow(function() {
906   var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'password' };
907   rsaSignature = rsaSign.sign(signOptions, 'hex');
908 });
909 assert.equal(rsaSignature,
910              '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
911              '8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
912              'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
913              '60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
914              '40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
915
916 rsaVerify = crypto.createVerify('RSA-SHA1');
917 rsaVerify.update(rsaPubPem);
918 assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
919
920 rsaSign = crypto.createSign('RSA-SHA1');
921 rsaSign.update(rsaPubPem);
922 assert.throws(function() {
923   var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' };
924   rsaSign.sign(signOptions, 'hex');
925 });
926
927 //
928 // Test RSA signing and verification
929 //
930 (function() {
931   var privateKey = fs.readFileSync(
932       common.fixturesDir + '/test_rsa_privkey_2.pem');
933
934   var publicKey = fs.readFileSync(
935       common.fixturesDir + '/test_rsa_pubkey_2.pem');
936
937   var input = 'I AM THE WALRUS';
938
939   var signature =
940       '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89' +
941       '396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa' +
942       '235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb2' +
943       '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' +
944       '0ddfb299bedeb1ad';
945
946   var sign = crypto.createSign('RSA-SHA256');
947   sign.update(input);
948
949   var output = sign.sign(privateKey, 'hex');
950   assert.equal(output, signature);
951
952   var verify = crypto.createVerify('RSA-SHA256');
953   verify.update(input);
954
955   assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true);
956 })();
957
958
959 //
960 // Test DSA signing and verification
961 //
962 (function() {
963   var input = 'I AM THE WALRUS';
964
965   // DSA signatures vary across runs so there is no static string to verify
966   // against
967   var sign = crypto.createSign('DSS1');
968   sign.update(input);
969   var signature = sign.sign(dsaKeyPem, 'hex');
970
971   var verify = crypto.createVerify('DSS1');
972   verify.update(input);
973
974   assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
975 })();
976
977
978 //
979 // Test DSA signing and verification with encrypted key
980 //
981 (function() {
982   var input = 'I AM THE WALRUS';
983
984   var sign = crypto.createSign('DSS1');
985   sign.update(input);
986   assert.throws(function() {
987     sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex');
988   });
989
990   // DSA signatures vary across runs so there is no static string to verify
991   // against
992   var sign = crypto.createSign('DSS1');
993   sign.update(input);
994
995   var signature;
996   assert.doesNotThrow(function() {
997     var signOptions = { key: dsaKeyPemEncrypted, passphrase: 'password' };
998     signature = sign.sign(signOptions, 'hex');
999   });
1000
1001   var verify = crypto.createVerify('DSS1');
1002   verify.update(input);
1003
1004   assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
1005 })();
1006
1007
1008 //
1009 // Test PBKDF2 with RFC 6070 test vectors (except #4)
1010 //
1011 function testPBKDF2(password, salt, iterations, keylen, expected) {
1012   var actual = crypto.pbkdf2Sync(password, salt, iterations, keylen);
1013   assert.equal(actual.toString('binary'), expected);
1014
1015   crypto.pbkdf2(password, salt, iterations, keylen, function(err, actual) {
1016     assert.equal(actual.toString('binary'), expected);
1017   });
1018 }
1019
1020
1021 testPBKDF2('password', 'salt', 1, 20,
1022            '\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24' +
1023            '\xaf\x60\x12\x06\x2f\xe0\x37\xa6');
1024
1025 testPBKDF2('password', 'salt', 2, 20,
1026            '\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a' +
1027            '\xce\x1d\x41\xf0\xd8\xde\x89\x57');
1028
1029 testPBKDF2('password', 'salt', 4096, 20,
1030            '\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26' +
1031            '\xf7\x21\xd0\x65\xa4\x29\xc1');
1032
1033 testPBKDF2('passwordPASSWORDpassword',
1034            'saltSALTsaltSALTsaltSALTsaltSALTsalt',
1035            4096,
1036            25,
1037            '\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62' +
1038            '\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38');
1039
1040 testPBKDF2('pass\0word', 'sa\0lt', 4096, 16,
1041            '\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34' +
1042            '\x25\xe0\xc3');
1043
1044 (function() {
1045   var expected =
1046       '64c486c55d30d4c5a079b8823b7d7cb37ff0556f537da8410233bcec330ed956';
1047   var key = crypto.pbkdf2Sync('password', 'salt', 32, 32, 'sha256');
1048   assert.equal(key.toString('hex'), expected);
1049
1050   crypto.pbkdf2('password', 'salt', 32, 32, 'sha256', common.mustCall(ondone));
1051   function ondone(err, key) {
1052     if (err) throw err;
1053     assert.equal(key.toString('hex'), expected);
1054   }
1055 })();
1056
1057 function assertSorted(list) {
1058   // Array#sort() modifies the list in place so make a copy.
1059   var sorted = util._extend([], list).sort();
1060   assert.deepEqual(list, sorted);
1061 }
1062
1063 // Assume that we have at least AES-128-CBC.
1064 assert.notEqual(0, crypto.getCiphers().length);
1065 assert.notEqual(-1, crypto.getCiphers().indexOf('aes-128-cbc'));
1066 assert.equal(-1, crypto.getCiphers().indexOf('AES-128-CBC'));
1067 assertSorted(crypto.getCiphers());
1068
1069 // Assume that we have at least AES256-SHA.
1070 var tls = require('tls');
1071 assert.notEqual(0, tls.getCiphers().length);
1072 assert.notEqual(-1, tls.getCiphers().indexOf('aes256-sha'));
1073 assert.equal(-1, tls.getCiphers().indexOf('AES256-SHA'));
1074 assertSorted(tls.getCiphers());
1075
1076 // Assert that we have sha and sha1 but not SHA and SHA1.
1077 assert.notEqual(0, crypto.getHashes().length);
1078 assert.notEqual(-1, crypto.getHashes().indexOf('sha1'));
1079 assert.notEqual(-1, crypto.getHashes().indexOf('sha'));
1080 assert.equal(-1, crypto.getHashes().indexOf('SHA1'));
1081 assert.equal(-1, crypto.getHashes().indexOf('SHA'));
1082 assert.notEqual(-1, crypto.getHashes().indexOf('RSA-SHA1'));
1083 assert.equal(-1, crypto.getHashes().indexOf('rsa-sha1'));
1084 assertSorted(crypto.getHashes());
1085
1086 // Base64 padding regression test, see #4837.
1087 (function() {
1088   var c = crypto.createCipher('aes-256-cbc', 'secret');
1089   var s = c.update('test', 'utf8', 'base64') + c.final('base64');
1090   assert.equal(s, '375oxUQCIocvxmC5At+rvA==');
1091 })();
1092
1093 // Error path should not leak memory (check with valgrind).
1094 assert.throws(function() {
1095   crypto.pbkdf2('password', 'salt', 1, 20, null);
1096 });
1097
1098 // Calling Cipher.final() or Decipher.final() twice should error but
1099 // not assert. See #4886.
1100 (function() {
1101   var c = crypto.createCipher('aes-256-cbc', 'secret');
1102   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1103   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1104   try { c.final('xxx') } catch (e) { /* Ignore. */ }
1105   var d = crypto.createDecipher('aes-256-cbc', 'secret');
1106   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1107   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1108   try { d.final('xxx') } catch (e) { /* Ignore. */ }
1109 })();
1110
1111 // Regression test for #5482: string to Cipher#update() should not assert.
1112 (function() {
1113   var c = crypto.createCipher('aes192', '0123456789abcdef');
1114   c.update('update');
1115   c.final();
1116 })();
1117
1118 // #5655 regression tests, 'utf-8' and 'utf8' are identical.
1119 (function() {
1120   var c = crypto.createCipher('aes192', '0123456789abcdef');
1121   c.update('update', '');  // Defaults to "utf8".
1122   c.final('utf-8');  // Should not throw.
1123
1124   c = crypto.createCipher('aes192', '0123456789abcdef');
1125   c.update('update', 'utf8');
1126   c.final('utf-8');  // Should not throw.
1127
1128   c = crypto.createCipher('aes192', '0123456789abcdef');
1129   c.update('update', 'utf-8');
1130   c.final('utf8');  // Should not throw.
1131 })();
1132
1133 // Regression tests for #5725: hex input that's not a power of two should
1134 // throw, not assert in C++ land.
1135 assert.throws(function() {
1136   crypto.createCipher('aes192', 'test').update('0', 'hex');
1137 }, /Bad input string/);
1138
1139 assert.throws(function() {
1140   crypto.createDecipher('aes192', 'test').update('0', 'hex');
1141 }, /Bad input string/);
1142
1143 assert.throws(function() {
1144   crypto.createHash('sha1').update('0', 'hex');
1145 }, /Bad input string/);
1146
1147 assert.throws(function() {
1148   crypto.createSign('RSA-SHA1').update('0', 'hex');
1149 }, /Bad input string/);
1150
1151 assert.throws(function() {
1152   crypto.createVerify('RSA-SHA1').update('0', 'hex');
1153 }, /Bad input string/);
1154
1155 assert.throws(function() {
1156   var private = [
1157     '-----BEGIN RSA PRIVATE KEY-----',
1158     'MIGrAgEAAiEA+3z+1QNF2/unumadiwEr+C5vfhezsb3hp4jAnCNRpPcCAwEAAQIgQNriSQK4',
1159     'EFwczDhMZp2dvbcz7OUUyt36z3S4usFPHSECEQD/41K7SujrstBfoCPzwC1xAhEA+5kt4BJy',
1160     'eKN7LggbF3Dk5wIQN6SL+fQ5H/+7NgARsVBp0QIRANxYRukavs4QvuyNhMx+vrkCEQCbf6j/',
1161     'Ig6/HueCK/0Jkmp+',
1162     '-----END RSA PRIVATE KEY-----',
1163     ''
1164   ].join('\n');
1165   crypto.createSign('RSA-SHA256').update('test').sign(private);
1166 }, /RSA_sign:digest too big for rsa key/);
1167
1168 // Make sure memory isn't released before being returned
1169 console.log(crypto.randomBytes(16));