|
1 var ScriptableUnicodeConverter = |
|
2 Components.Constructor("@mozilla.org/intl/scriptableunicodeconverter", |
|
3 "nsIScriptableUnicodeConverter"); |
|
4 var CryptoHash = |
|
5 Components.Constructor("@mozilla.org/security/hash;1", |
|
6 "nsICryptoHash", |
|
7 "initWithString"); |
|
8 |
|
9 var messages = [ |
|
10 "The quick brown fox jumps over the lazy dog", |
|
11 "" |
|
12 ]; |
|
13 var hashes = { |
|
14 md2: [ |
|
15 "03d85a0d629d2c442e987525319fc471", |
|
16 "8350e5a3e24c153df2275c9f80692773" |
|
17 ], |
|
18 md5: [ |
|
19 "9e107d9d372bb6826bd81d3542a419d6", |
|
20 "d41d8cd98f00b204e9800998ecf8427e" |
|
21 ], |
|
22 sha1: [ |
|
23 "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", |
|
24 "da39a3ee5e6b4b0d3255bfef95601890afd80709" |
|
25 ], |
|
26 sha256: [ |
|
27 "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", |
|
28 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" |
|
29 ], |
|
30 sha384: [ |
|
31 "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", |
|
32 "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" |
|
33 ], |
|
34 sha512: [ |
|
35 "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", |
|
36 "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" |
|
37 ] |
|
38 }; |
|
39 |
|
40 function hexdigest(data) { |
|
41 /* |
|
42 * Coment taken from bug 383390: |
|
43 * |
|
44 * First, |data| is the final string value produced by the cryptohash. |for (i in |
|
45 * data)| uses the Mozilla JS extension that iterating over a string iterates over |
|
46 * its character indexes, so that's 0..length-1 over the hash string. |
|
47 * |
|
48 * Returning to the left, the |charCodeAt| gets the value of the character at that |
|
49 * index in the string. |
|
50 * |
|
51 * |slice(-2)| is equivalent to |slice(length of this string - 2)| as a convenient |
|
52 * way of wrapping around to the other end of a string without doing the actual |
|
53 * calculation. When provided with only one argument, slice selects to the end of |
|
54 * the string, so this chomps off the last two characters of the string. |
|
55 * |
|
56 * The last-two-characters part clarifies the |"0" +| -- if the Unicode value is |
|
57 * <10, we have a single-character hex string when we want one that's two |
|
58 * characters, and unconditionally prepending a "0" solves the problem. |
|
59 * |
|
60 * The array comprehension just creates an array whose elements are these |
|
61 * two-character strings. |
|
62 */ |
|
63 return [("0" + data.charCodeAt(i).toString(16)).slice(-2) for (i in data)].join(""); |
|
64 } |
|
65 |
|
66 function doHash(algo, value, cmp) { |
|
67 var converter = new ScriptableUnicodeConverter(); |
|
68 var hash = new CryptoHash(algo); |
|
69 |
|
70 converter.charset = 'utf8'; |
|
71 value = converter.convertToByteArray(value); |
|
72 hash.update(value, value.length); |
|
73 var hash1 = hexdigest(hash.finish(false)); |
|
74 if (cmp != hash1) { |
|
75 do_throw("Hash mismatch!\n" + |
|
76 " Expected: " + cmp + "\n" + |
|
77 " Actual: " + hash1 + "\n" + |
|
78 " Algo: " + algo); |
|
79 } |
|
80 |
|
81 hash.initWithString(algo); |
|
82 hash.update(value, value.length); |
|
83 var hash2 = hexdigest(hash.finish(false)); |
|
84 if (cmp != hash2) { |
|
85 do_throw("Hash mismatch after crypto hash re-init!\n" + |
|
86 " Expected: " + cmp + "\n" + |
|
87 " Actual: " + hash2 + "\n" + |
|
88 " Algo: " + algo); |
|
89 } |
|
90 } |
|
91 |
|
92 function doHashStream(algo, value, cmp) { |
|
93 var converter = new ScriptableUnicodeConverter(); |
|
94 var hash = new CryptoHash(algo); |
|
95 |
|
96 converter.charset = 'utf8'; |
|
97 var stream = converter.convertToInputStream(value); |
|
98 hash.updateFromStream(stream, stream.available()); |
|
99 hash = hexdigest(hash.finish(false)); |
|
100 if (cmp != hash) { |
|
101 do_throw("Hash mismatch!\n" + |
|
102 " Expected: " + cmp + "\n" + |
|
103 " Actual: " + hash + "\n" + |
|
104 " Algo: " + algo); |
|
105 } |
|
106 } |
|
107 |
|
108 function run_test() { |
|
109 for (algo in hashes) { |
|
110 hashes[algo].forEach( |
|
111 function(e, i) { |
|
112 doHash(algo, messages[i], e); |
|
113 |
|
114 if (messages[i].length) { |
|
115 // this test doesn't work for empty string/stream |
|
116 doHashStream(algo, messages[i], e); |
|
117 } |
|
118 } |
|
119 ); |
|
120 } |
|
121 } |