crypto_spec.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2019 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. var _crypto = require("../../core/crypto");
  24. var _primitives = require("../../core/primitives");
  25. var _util = require("../../shared/util");
  26. describe('crypto', function () {
  27. function hex2binary(s) {
  28. var digits = '0123456789ABCDEF';
  29. s = s.toUpperCase();
  30. var n = s.length >> 1,
  31. i,
  32. j;
  33. var result = new Uint8Array(n);
  34. for (i = 0, j = 0; i < n; ++i) {
  35. var d1 = s.charAt(j++);
  36. var d2 = s.charAt(j++);
  37. var value = digits.indexOf(d1) << 4 | digits.indexOf(d2);
  38. result[i] = value;
  39. }
  40. return result;
  41. }
  42. describe('calculateMD5', function () {
  43. it('should pass RFC 1321 test #1', function () {
  44. var input, result, expected;
  45. input = (0, _util.stringToBytes)('');
  46. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  47. expected = hex2binary('d41d8cd98f00b204e9800998ecf8427e');
  48. expect(result).toEqual(expected);
  49. });
  50. it('should pass RFC 1321 test #2', function () {
  51. var input, result, expected;
  52. input = (0, _util.stringToBytes)('a');
  53. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  54. expected = hex2binary('0cc175b9c0f1b6a831c399e269772661');
  55. expect(result).toEqual(expected);
  56. });
  57. it('should pass RFC 1321 test #3', function () {
  58. var input, result, expected;
  59. input = (0, _util.stringToBytes)('abc');
  60. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  61. expected = hex2binary('900150983cd24fb0d6963f7d28e17f72');
  62. expect(result).toEqual(expected);
  63. });
  64. it('should pass RFC 1321 test #4', function () {
  65. var input, result, expected;
  66. input = (0, _util.stringToBytes)('message digest');
  67. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  68. expected = hex2binary('f96b697d7cb7938d525a2f31aaf161d0');
  69. expect(result).toEqual(expected);
  70. });
  71. it('should pass RFC 1321 test #5', function () {
  72. var input, result, expected;
  73. input = (0, _util.stringToBytes)('abcdefghijklmnopqrstuvwxyz');
  74. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  75. expected = hex2binary('c3fcd3d76192e4007dfb496cca67e13b');
  76. expect(result).toEqual(expected);
  77. });
  78. it('should pass RFC 1321 test #6', function () {
  79. var input, result, expected;
  80. input = (0, _util.stringToBytes)('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv' + 'wxyz0123456789');
  81. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  82. expected = hex2binary('d174ab98d277d9f5a5611c2c9f419d9f');
  83. expect(result).toEqual(expected);
  84. });
  85. it('should pass RFC 1321 test #7', function () {
  86. var input, result, expected;
  87. input = (0, _util.stringToBytes)('123456789012345678901234567890123456789012345678' + '90123456789012345678901234567890');
  88. result = (0, _crypto.calculateMD5)(input, 0, input.length);
  89. expected = hex2binary('57edf4a22be3c955ac49da2e2107b67a');
  90. expect(result).toEqual(expected);
  91. });
  92. });
  93. describe('ARCFourCipher', function () {
  94. it('should pass test #1', function () {
  95. var key, input, result, expected, cipher;
  96. key = hex2binary('0123456789abcdef');
  97. input = hex2binary('0123456789abcdef');
  98. cipher = new _crypto.ARCFourCipher(key);
  99. result = cipher.encryptBlock(input);
  100. expected = hex2binary('75b7878099e0c596');
  101. expect(result).toEqual(expected);
  102. });
  103. it('should pass test #2', function () {
  104. var key, input, result, expected, cipher;
  105. key = hex2binary('0123456789abcdef');
  106. input = hex2binary('0000000000000000');
  107. cipher = new _crypto.ARCFourCipher(key);
  108. result = cipher.encryptBlock(input);
  109. expected = hex2binary('7494c2e7104b0879');
  110. expect(result).toEqual(expected);
  111. });
  112. it('should pass test #3', function () {
  113. var key, input, result, expected, cipher;
  114. key = hex2binary('0000000000000000');
  115. input = hex2binary('0000000000000000');
  116. cipher = new _crypto.ARCFourCipher(key);
  117. result = cipher.encryptBlock(input);
  118. expected = hex2binary('de188941a3375d3a');
  119. expect(result).toEqual(expected);
  120. });
  121. it('should pass test #4', function () {
  122. var key, input, result, expected, cipher;
  123. key = hex2binary('ef012345');
  124. input = hex2binary('00000000000000000000');
  125. cipher = new _crypto.ARCFourCipher(key);
  126. result = cipher.encryptBlock(input);
  127. expected = hex2binary('d6a141a7ec3c38dfbd61');
  128. expect(result).toEqual(expected);
  129. });
  130. it('should pass test #5', function () {
  131. var key, input, result, expected, cipher;
  132. key = hex2binary('0123456789abcdef');
  133. input = hex2binary('010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '10101010101010101010101010101010101010101010101010101010101010101010' + '101010101010101010101');
  134. cipher = new _crypto.ARCFourCipher(key);
  135. result = cipher.encryptBlock(input);
  136. expected = hex2binary('7595c3e6114a09780c4ad452338e1ffd9a1be9498f813d76' + '533449b6778dcad8c78a8d2ba9ac66085d0e53d59c26c2d1c490c1ebbe0ce66d1b6b' + '1b13b6b919b847c25a91447a95e75e4ef16779cde8bf0a95850e32af9689444fd377' + '108f98fdcbd4e726567500990bcc7e0ca3c4aaa304a387d20f3b8fbbcd42a1bd311d' + '7a4303dda5ab078896ae80c18b0af66dff319616eb784e495ad2ce90d7f772a81747' + 'b65f62093b1e0db9e5ba532fafec47508323e671327df9444432cb7367cec82f5d44' + 'c0d00b67d650a075cd4b70dedd77eb9b10231b6b5b741347396d62897421d43df9b4' + '2e446e358e9c11a9b2184ecbef0cd8e7a877ef968f1390ec9b3d35a5585cb009290e' + '2fcde7b5ec66d9084be44055a619d9dd7fc3166f9487f7cb272912426445998514c1' + '5d53a18c864ce3a2b7555793988126520eacf2e3066e230c91bee4dd5304f5fd0405' + 'b35bd99c73135d3d9bc335ee049ef69b3867bf2d7bd1eaa595d8bfc0066ff8d31509' + 'eb0c6caa006c807a623ef84c3d33c195d23ee320c40de0558157c822d4b8c569d849' + 'aed59d4e0fd7f379586b4b7ff684ed6a189f7486d49b9c4bad9ba24b96abf924372c' + '8a8fffb10d55354900a77a3db5f205e1b99fcd8660863a159ad4abe40fa48934163d' + 'dde542a6585540fd683cbfd8c00f12129a284deacc4cdefe58be7137541c047126c8' + 'd49e2755ab181ab7e940b0c0');
  137. expect(result).toEqual(expected);
  138. });
  139. it('should pass test #6', function () {
  140. var key, input, result, expected, cipher;
  141. key = hex2binary('fb029e3031323334');
  142. input = hex2binary('aaaa0300000008004500004e661a00008011be640a0001220af' + 'fffff00890089003a000080a601100001000000000000204543454a4548454346434' + '550464545494546464343414341434143414341414100002000011bd0b604');
  143. cipher = new _crypto.ARCFourCipher(key);
  144. result = cipher.encryptBlock(input);
  145. expected = hex2binary('f69c5806bd6ce84626bcbefb9474650aad1f7909b0f64d5f' + '58a503a258b7ed22eb0ea64930d3a056a55742fcce141d485f8aa836dea18df42c53' + '80805ad0c61a5d6f58f41040b24b7d1a693856ed0d4398e7aee3bf0e2a2ca8f7');
  146. expect(result).toEqual(expected);
  147. });
  148. it('should pass test #7', function () {
  149. var key, input, result, expected, cipher;
  150. key = hex2binary('0123456789abcdef');
  151. input = hex2binary('123456789abcdef0123456789abcdef0123456789abcdef0123' + '45678');
  152. cipher = new _crypto.ARCFourCipher(key);
  153. result = cipher.encryptBlock(input);
  154. expected = hex2binary('66a0949f8af7d6891f7f832ba833c00c892ebe30143ce287' + '40011ecf');
  155. expect(result).toEqual(expected);
  156. });
  157. });
  158. describe('calculateSHA256', function () {
  159. it('should properly hash abc', function () {
  160. var input, result, expected;
  161. input = (0, _util.stringToBytes)('abc');
  162. result = (0, _crypto.calculateSHA256)(input, 0, input.length);
  163. expected = hex2binary('BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9C' + 'B410FF61F20015AD');
  164. expect(result).toEqual(expected);
  165. });
  166. it('should properly hash a multiblock input', function () {
  167. var input, result, expected;
  168. input = (0, _util.stringToBytes)('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmno' + 'mnopnopq');
  169. result = (0, _crypto.calculateSHA256)(input, 0, input.length);
  170. expected = hex2binary('248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167' + 'F6ECEDD419DB06C1');
  171. expect(result).toEqual(expected);
  172. });
  173. });
  174. describe('calculateSHA384', function () {
  175. it('should properly hash abc', function () {
  176. var input, result, expected;
  177. input = (0, _util.stringToBytes)('abc');
  178. result = (0, _crypto.calculateSHA384)(input, 0, input.length);
  179. expected = hex2binary('CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED163' + '1A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7');
  180. expect(result).toEqual(expected);
  181. });
  182. it('should properly hash a multiblock input', function () {
  183. var input, result, expected;
  184. input = (0, _util.stringToBytes)('abcdefghbcdefghicdefghijdefghijkefghijklfghijklm' + 'ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs' + 'mnopqrstnopqrstu');
  185. result = (0, _crypto.calculateSHA384)(input, 0, input.length);
  186. expected = hex2binary('09330C33F71147E83D192FC782CD1B4753111B173B3B05D2' + '2FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039');
  187. expect(result).toEqual(expected);
  188. });
  189. });
  190. describe('calculateSHA512', function () {
  191. it('should properly hash abc', function () {
  192. var input, result, expected;
  193. input = (0, _util.stringToBytes)('abc');
  194. result = (0, _crypto.calculateSHA512)(input, 0, input.length);
  195. expected = hex2binary('DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2' + '0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD' + '454D4423643CE80E2A9AC94FA54CA49F');
  196. expect(result).toEqual(expected);
  197. });
  198. it('should properly hash a multiblock input', function () {
  199. var input, result, expected;
  200. input = (0, _util.stringToBytes)('abcdefghbcdefghicdefghijdefghijkefghijklfghijklm' + 'ghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrs' + 'mnopqrstnopqrstu');
  201. result = (0, _crypto.calculateSHA512)(input, 0, input.length);
  202. expected = hex2binary('8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1' + '7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A' + 'C7D329EEB6DD26545E96E55B874BE909');
  203. expect(result).toEqual(expected);
  204. });
  205. });
  206. describe('AES128', function () {
  207. describe('Encryption', function () {
  208. it('should be able to encrypt a block', function () {
  209. var input, key, result, expected, iv, cipher;
  210. input = hex2binary('00112233445566778899aabbccddeeff');
  211. key = hex2binary('000102030405060708090a0b0c0d0e0f');
  212. iv = hex2binary('00000000000000000000000000000000');
  213. cipher = new _crypto.AES128Cipher(key);
  214. result = cipher.encrypt(input, iv);
  215. expected = hex2binary('69c4e0d86a7b0430d8cdb78070b4c55a');
  216. expect(result).toEqual(expected);
  217. });
  218. });
  219. describe('Decryption', function () {
  220. it('should be able to decrypt a block with IV in stream', function () {
  221. var input, key, result, expected, cipher;
  222. input = hex2binary('0000000000000000000000000000000069c4e0d86a7b0430d' + '8cdb78070b4c55a');
  223. key = hex2binary('000102030405060708090a0b0c0d0e0f');
  224. cipher = new _crypto.AES128Cipher(key);
  225. result = cipher.decryptBlock(input);
  226. expected = hex2binary('00112233445566778899aabbccddeeff');
  227. expect(result).toEqual(expected);
  228. });
  229. });
  230. });
  231. describe('AES256', function () {
  232. describe('Encryption', function () {
  233. it('should be able to encrypt a block', function () {
  234. var input, key, result, expected, iv, cipher;
  235. input = hex2binary('00112233445566778899aabbccddeeff');
  236. key = hex2binary('000102030405060708090a0b0c0d0e0f101112131415161718' + '191a1b1c1d1e1f');
  237. iv = hex2binary('00000000000000000000000000000000');
  238. cipher = new _crypto.AES256Cipher(key);
  239. result = cipher.encrypt(input, iv);
  240. expected = hex2binary('8ea2b7ca516745bfeafc49904b496089');
  241. expect(result).toEqual(expected);
  242. });
  243. });
  244. describe('Decryption', function () {
  245. it('should be able to decrypt a block with specified iv', function () {
  246. var input, key, result, expected, cipher, iv;
  247. input = hex2binary('8ea2b7ca516745bfeafc49904b496089');
  248. key = hex2binary('000102030405060708090a0b0c0d0e0f101112131415161718' + '191a1b1c1d1e1f');
  249. iv = hex2binary('00000000000000000000000000000000');
  250. cipher = new _crypto.AES256Cipher(key);
  251. result = cipher.decryptBlock(input, false, iv);
  252. expected = hex2binary('00112233445566778899aabbccddeeff');
  253. expect(result).toEqual(expected);
  254. });
  255. it('should be able to decrypt a block with IV in stream', function () {
  256. var input, key, result, expected, cipher;
  257. input = hex2binary('000000000000000000000000000000008ea2b7ca516745bf' + 'eafc49904b496089');
  258. key = hex2binary('000102030405060708090a0b0c0d0e0f101112131415161718' + '191a1b1c1d1e1f');
  259. cipher = new _crypto.AES256Cipher(key);
  260. result = cipher.decryptBlock(input, false);
  261. expected = hex2binary('00112233445566778899aabbccddeeff');
  262. expect(result).toEqual(expected);
  263. });
  264. });
  265. });
  266. describe('PDF17Algorithm', function () {
  267. it('should correctly check a user key', function () {
  268. var password, userValidation, userPassword, alg, result;
  269. alg = new _crypto.PDF17();
  270. password = new Uint8Array([117, 115, 101, 114]);
  271. userValidation = new Uint8Array([117, 169, 4, 32, 159, 101, 22, 220]);
  272. userPassword = new Uint8Array([131, 242, 143, 160, 87, 2, 138, 134, 79, 253, 189, 173, 224, 73, 144, 241, 190, 81, 197, 15, 249, 105, 145, 151, 15, 194, 65, 3, 1, 126, 187, 221]);
  273. result = alg.checkUserPassword(password, userValidation, userPassword);
  274. expect(result).toEqual(true);
  275. });
  276. it('should correctly check an owner key', function () {
  277. var password, ownerValidation, ownerPassword, alg, result, uBytes;
  278. alg = new _crypto.PDF17();
  279. password = new Uint8Array([111, 119, 110, 101, 114]);
  280. ownerValidation = new Uint8Array([243, 118, 71, 153, 128, 17, 101, 62]);
  281. ownerPassword = new Uint8Array([60, 98, 137, 35, 51, 101, 200, 152, 210, 178, 226, 228, 134, 205, 163, 24, 204, 126, 177, 36, 106, 50, 36, 125, 210, 172, 171, 120, 222, 108, 139, 115]);
  282. uBytes = new Uint8Array([131, 242, 143, 160, 87, 2, 138, 134, 79, 253, 189, 173, 224, 73, 144, 241, 190, 81, 197, 15, 249, 105, 145, 151, 15, 194, 65, 3, 1, 126, 187, 221, 117, 169, 4, 32, 159, 101, 22, 220, 168, 94, 215, 192, 100, 38, 188, 40]);
  283. result = alg.checkOwnerPassword(password, ownerValidation, uBytes, ownerPassword);
  284. expect(result).toEqual(true);
  285. });
  286. it('should generate a file encryption key from the user key', function () {
  287. var password, userKeySalt, expected, alg, result, userEncryption;
  288. alg = new _crypto.PDF17();
  289. password = new Uint8Array([117, 115, 101, 114]);
  290. userKeySalt = new Uint8Array([168, 94, 215, 192, 100, 38, 188, 40]);
  291. userEncryption = new Uint8Array([35, 150, 195, 169, 245, 51, 51, 255, 158, 158, 33, 242, 231, 75, 125, 190, 25, 126, 172, 114, 195, 244, 137, 245, 234, 165, 42, 74, 60, 38, 17, 17]);
  292. result = alg.getUserKey(password, userKeySalt, userEncryption);
  293. expected = new Uint8Array([63, 114, 136, 209, 87, 61, 12, 30, 249, 1, 186, 144, 254, 248, 163, 153, 151, 51, 133, 10, 80, 152, 206, 15, 72, 187, 231, 33, 224, 239, 13, 213]);
  294. expect(result).toEqual(expected);
  295. });
  296. it('should generate a file encryption key from the owner key', function () {
  297. var password, ownerKeySalt, expected, alg, result, ownerEncryption;
  298. var uBytes;
  299. alg = new _crypto.PDF17();
  300. password = new Uint8Array([111, 119, 110, 101, 114]);
  301. ownerKeySalt = new Uint8Array([200, 245, 242, 12, 218, 123, 24, 120]);
  302. ownerEncryption = new Uint8Array([213, 202, 14, 189, 110, 76, 70, 191, 6, 195, 10, 190, 157, 100, 144, 85, 8, 62, 123, 178, 156, 229, 50, 40, 229, 216, 54, 222, 34, 38, 106, 223]);
  303. uBytes = new Uint8Array([131, 242, 143, 160, 87, 2, 138, 134, 79, 253, 189, 173, 224, 73, 144, 241, 190, 81, 197, 15, 249, 105, 145, 151, 15, 194, 65, 3, 1, 126, 187, 221, 117, 169, 4, 32, 159, 101, 22, 220, 168, 94, 215, 192, 100, 38, 188, 40]);
  304. result = alg.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption);
  305. expected = new Uint8Array([63, 114, 136, 209, 87, 61, 12, 30, 249, 1, 186, 144, 254, 248, 163, 153, 151, 51, 133, 10, 80, 152, 206, 15, 72, 187, 231, 33, 224, 239, 13, 213]);
  306. expect(result).toEqual(expected);
  307. });
  308. });
  309. describe('PDF20Algorithm', function () {
  310. it('should correctly check a user key', function () {
  311. var password, userValidation, userPassword, alg, result;
  312. alg = new _crypto.PDF20();
  313. password = new Uint8Array([117, 115, 101, 114]);
  314. userValidation = new Uint8Array([83, 245, 146, 101, 198, 247, 34, 198]);
  315. userPassword = new Uint8Array([94, 230, 205, 75, 166, 99, 250, 76, 219, 128, 17, 85, 57, 17, 33, 164, 150, 46, 103, 176, 160, 156, 187, 233, 166, 223, 163, 253, 147, 235, 95, 184]);
  316. result = alg.checkUserPassword(password, userValidation, userPassword);
  317. expect(result).toEqual(true);
  318. });
  319. it('should correctly check an owner key', function () {
  320. var password, ownerValidation, ownerPassword, alg, result, uBytes;
  321. alg = new _crypto.PDF20();
  322. password = new Uint8Array([111, 119, 110, 101, 114]);
  323. ownerValidation = new Uint8Array([142, 232, 169, 208, 202, 214, 5, 185]);
  324. ownerPassword = new Uint8Array([88, 232, 62, 54, 245, 26, 245, 209, 137, 123, 221, 72, 199, 49, 37, 217, 31, 74, 115, 167, 127, 158, 176, 77, 45, 163, 87, 47, 39, 90, 217, 141]);
  325. uBytes = new Uint8Array([94, 230, 205, 75, 166, 99, 250, 76, 219, 128, 17, 85, 57, 17, 33, 164, 150, 46, 103, 176, 160, 156, 187, 233, 166, 223, 163, 253, 147, 235, 95, 184, 83, 245, 146, 101, 198, 247, 34, 198, 191, 11, 16, 94, 237, 216, 20, 175]);
  326. result = alg.checkOwnerPassword(password, ownerValidation, uBytes, ownerPassword);
  327. expect(result).toEqual(true);
  328. });
  329. it('should generate a file encryption key from the user key', function () {
  330. var password, userKeySalt, expected, alg, result, userEncryption;
  331. alg = new _crypto.PDF20();
  332. password = new Uint8Array([117, 115, 101, 114]);
  333. userKeySalt = new Uint8Array([191, 11, 16, 94, 237, 216, 20, 175]);
  334. userEncryption = new Uint8Array([121, 208, 2, 181, 230, 89, 156, 60, 253, 143, 212, 28, 84, 180, 196, 177, 173, 128, 221, 107, 46, 20, 94, 186, 135, 51, 95, 24, 20, 223, 254, 36]);
  335. result = alg.getUserKey(password, userKeySalt, userEncryption);
  336. expected = new Uint8Array([42, 218, 213, 39, 73, 91, 72, 79, 67, 38, 248, 133, 18, 189, 61, 34, 107, 79, 29, 56, 59, 181, 213, 118, 113, 34, 65, 210, 87, 174, 22, 239]);
  337. expect(result).toEqual(expected);
  338. });
  339. it('should generate a file encryption key from the owner key', function () {
  340. var password, ownerKeySalt, expected, alg, result, ownerEncryption;
  341. var uBytes;
  342. alg = new _crypto.PDF20();
  343. password = new Uint8Array([111, 119, 110, 101, 114]);
  344. ownerKeySalt = new Uint8Array([29, 208, 185, 46, 11, 76, 135, 149]);
  345. ownerEncryption = new Uint8Array([209, 73, 224, 77, 103, 155, 201, 181, 190, 68, 223, 20, 62, 90, 56, 210, 5, 240, 178, 128, 238, 124, 68, 254, 253, 244, 62, 108, 208, 135, 10, 251]);
  346. uBytes = new Uint8Array([94, 230, 205, 75, 166, 99, 250, 76, 219, 128, 17, 85, 57, 17, 33, 164, 150, 46, 103, 176, 160, 156, 187, 233, 166, 223, 163, 253, 147, 235, 95, 184, 83, 245, 146, 101, 198, 247, 34, 198, 191, 11, 16, 94, 237, 216, 20, 175]);
  347. result = alg.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption);
  348. expected = new Uint8Array([42, 218, 213, 39, 73, 91, 72, 79, 67, 38, 248, 133, 18, 189, 61, 34, 107, 79, 29, 56, 59, 181, 213, 118, 113, 34, 65, 210, 87, 174, 22, 239]);
  349. expect(result).toEqual(expected);
  350. });
  351. });
  352. });
  353. describe('CipherTransformFactory', function () {
  354. function buildDict(map) {
  355. var dict = new _primitives.Dict();
  356. for (var key in map) {
  357. dict.set(key, map[key]);
  358. }
  359. return dict;
  360. }
  361. function ensurePasswordCorrect(done, dict, fileId, password) {
  362. try {
  363. var factory = new _crypto.CipherTransformFactory(dict, fileId, password);
  364. expect('createCipherTransform' in factory).toEqual(true);
  365. } catch (ex) {
  366. done.fail('Password should be accepted: ' + ex);
  367. return;
  368. }
  369. done();
  370. }
  371. function ensurePasswordNeeded(done, dict, fileId, password) {
  372. try {
  373. new _crypto.CipherTransformFactory(dict, fileId, password);
  374. } catch (ex) {
  375. expect(ex instanceof _util.PasswordException).toEqual(true);
  376. expect(ex.code).toEqual(_util.PasswordResponses.NEED_PASSWORD);
  377. done();
  378. return;
  379. }
  380. done.fail('Password should be rejected.');
  381. }
  382. function ensurePasswordIncorrect(done, dict, fileId, password) {
  383. try {
  384. new _crypto.CipherTransformFactory(dict, fileId, password);
  385. } catch (ex) {
  386. expect(ex instanceof _util.PasswordException).toEqual(true);
  387. expect(ex.code).toEqual(_util.PasswordResponses.INCORRECT_PASSWORD);
  388. done();
  389. return;
  390. }
  391. done.fail('Password should be rejected.');
  392. }
  393. var fileId1, fileId2, dict1, dict2;
  394. var aes256Dict, aes256IsoDict, aes256BlankDict, aes256IsoBlankDict;
  395. beforeAll(function (done) {
  396. fileId1 = unescape('%F6%C6%AF%17%F3rR%8DRM%9A%80%D1%EF%DF%18');
  397. fileId2 = unescape('%3CL_%3AD%96%AF@%9A%9D%B3%3Cx%1Cv%AC');
  398. dict1 = buildDict({
  399. Filter: _primitives.Name.get('Standard'),
  400. V: 2,
  401. Length: 128,
  402. O: unescape('%80%C3%04%96%91o%20sl%3A%E6%1B%13T%91%F2%0DV%12%E3%FF%5E%B' + 'B%E9VO%D8k%9A%CA%7C%5D'),
  403. U: unescape('j%0C%8D%3EY%19%00%BCjd%7D%91%BD%AA%00%18%00%00%00%00%00%00' + '%00%00%00%00%00%00%00%00%00%00'),
  404. P: -1028,
  405. R: 3
  406. });
  407. dict2 = buildDict({
  408. Filter: _primitives.Name.get('Standard'),
  409. V: 4,
  410. Length: 128,
  411. O: unescape('sF%14v.y5%27%DB%97%0A5%22%B3%E1%D4%AD%BD%9B%3C%B4%A5%89u%1' + '5%B2Y%F1h%D9%E9%F4'),
  412. U: unescape('%93%04%89%A9%BF%8AE%A6%88%A2%DB%C2%A0%A8gn%00%00%00%00%00%' + '00%00%00%00%00%00%00%00%00%00%00'),
  413. P: -1084,
  414. R: 4
  415. });
  416. aes256Dict = buildDict({
  417. Filter: _primitives.Name.get('Standard'),
  418. V: 5,
  419. Length: 256,
  420. O: unescape('%3Cb%89%233e%C8%98%D2%B2%E2%E4%86%CD%A3%18%CC%7E%B1%24j2%2' + '4%7D%D2%AC%ABx%DEl%8Bs%F3vG%99%80%11e%3E%C8%F5%F2%0C%DA%7B' + '%18x'),
  421. U: unescape('%83%F2%8F%A0W%02%8A%86O%FD%BD%AD%E0I%90%F1%BEQ%C5%0F%F9i%9' + '1%97%0F%C2A%03%01%7E%BB%DDu%A9%04%20%9Fe%16%DC%A8%5E%D7%C0' + 'd%26%BC%28'),
  422. OE: unescape('%D5%CA%0E%BDnLF%BF%06%C3%0A%BE%9Dd%90U%08%3E%7B%B2%9C%E52' + '%28%E5%D86%DE%22%26j%DF'),
  423. UE: unescape('%23%96%C3%A9%F533%FF%9E%9E%21%F2%E7K%7D%BE%19%7E%ACr%C3%F' + '4%89%F5%EA%A5*J%3C%26%11%11'),
  424. Perms: unescape('%D8%FC%844%E5e%0DB%5D%7Ff%FD%3COMM'),
  425. P: -1084,
  426. R: 5
  427. });
  428. aes256IsoDict = buildDict({
  429. Filter: _primitives.Name.get('Standard'),
  430. V: 5,
  431. Length: 256,
  432. O: unescape('X%E8%3E6%F5%1A%F5%D1%89%7B%DDH%C71%25%D9%1FJs%A7%7F%9E%B0M' + '-%A3W/%27Z%D9%8D%8E%E8%A9%D0%CA%D6%05%B9%1D%D0%B9.%0BL%87%' + '95'),
  433. U: unescape('%5E%E6%CDK%A6c%FAL%DB%80%11U9%11%21%A4%96.g%B0%A0%9C%BB%E9' + '%A6%DF%A3%FD%93%EB_%B8S%F5%92e%C6%F7%22%C6%BF%0B%10%5E%ED%' + 'D8%14%AF'),
  434. OE: unescape('%D1I%E0Mg%9B%C9%B5%BED%DF%14%3EZ8%D2%05%F0%B2%80%EE%7CD%F' + 'E%FD%F4%3El%D0%87%0A%FB'),
  435. UE: unescape('y%D0%02%B5%E6Y%9C%3C%FD%8F%D4%1CT%B4%C4%B1%AD%80%DDk.%14%' + '5E%BA%873_%18%14%DF%FE%24'),
  436. Perms: unescape('l%AD%0F%A0%EBM%86WM%3E%CB%B5%E0X%C97'),
  437. P: -1084,
  438. R: 6
  439. });
  440. aes256BlankDict = buildDict({
  441. Filter: _primitives.Name.get('Standard'),
  442. V: 5,
  443. Length: 256,
  444. O: unescape('%B8p%04%C3g%26%FCW%CCN%D4%16%A1%E8%950YZ%C9%9E%B1-%97%F3%F' + 'E%03%13%19ffZn%8F%F5%EB%EC%CC5sV%10e%CEl%B5%E9G%C1'),
  445. U: unescape('%83%D4zi%F1O0%961%12%CC%82%CB%CA%BF5y%FD%21%EB%E4%D1%B5%1D' + '%D6%FA%14%F3%BE%8Fqs%EF%88%DE%E2%E8%DC%F55%E4%B8%16%C8%14%' + '8De%1E'),
  446. OE: unescape('%8F%19%E8%D4%27%D5%07%CA%C6%A1%11%A6a%5Bt%F4%DF%0F%84%29%' + '0F%E4%EFF7%5B%5B%11%A0%8F%17e'),
  447. UE: unescape('%81%F5%5D%B0%28%81%E4%7F_%7C%8F%85b%A0%7E%10%D0%88lx%7B%7' + 'EJ%5E%912%B6d%12%27%05%F6'),
  448. Perms: unescape('%86%1562%0D%AE%A2%FB%5D%3B%22%3Dq%12%B2H'),
  449. P: -1084,
  450. R: 5
  451. });
  452. aes256IsoBlankDict = buildDict({
  453. Filter: _primitives.Name.get('Standard'),
  454. V: 5,
  455. Length: 256,
  456. O: unescape('%F7%DB%99U%A6M%ACk%AF%CF%D7AFw%E9%C1%91%CBDgI%23R%CF%0C%15' + 'r%D74%0D%CE%E9%91@%E4%98QF%BF%88%7Ej%DE%AD%8F%F4@%C1'),
  457. U: unescape('%1A%A9%DC%918%83%93k%29%5B%117%B16%DB%E8%8E%FE%28%E5%89%D4' + '%0E%AD%12%3B%7DN_6fez%8BG%18%05YOh%7DZH%A3Z%87%17*'),
  458. OE: unescape('%A4a%88%20h%1B%7F%CD%D5%CAc%D8R%83%E5%D6%1C%D2%98%07%984%' + 'BA%AF%1B%B4%7FQ%F8%1EU%7D'),
  459. UE: unescape('%A0%0AZU%27%1D%27%2C%0B%FE%0E%A2L%F9b%5E%A1%B9%D6v7b%B26%' + 'A9N%99%F1%A4Deq'),
  460. Perms: unescape('%03%F2i%07%0D%C3%F9%F2%28%80%B7%F5%DD%D1c%EB'),
  461. P: -1084,
  462. R: 6
  463. });
  464. done();
  465. });
  466. afterAll(function () {
  467. fileId1 = fileId2 = dict1 = dict2 = null;
  468. aes256Dict = aes256IsoDict = aes256BlankDict = aes256IsoBlankDict = null;
  469. });
  470. describe('#ctor', function () {
  471. describe('AES256 Revision 5', function () {
  472. it('should accept user password', function (done) {
  473. ensurePasswordCorrect(done, aes256Dict, fileId1, 'user');
  474. });
  475. it('should accept owner password', function (done) {
  476. ensurePasswordCorrect(done, aes256Dict, fileId1, 'owner');
  477. });
  478. it('should not accept blank password', function (done) {
  479. ensurePasswordNeeded(done, aes256Dict, fileId1);
  480. });
  481. it('should not accept wrong password', function (done) {
  482. ensurePasswordIncorrect(done, aes256Dict, fileId1, 'wrong');
  483. });
  484. it('should accept blank password', function (done) {
  485. ensurePasswordCorrect(done, aes256BlankDict, fileId1);
  486. });
  487. });
  488. describe('AES256 Revision 6', function () {
  489. it('should accept user password', function (done) {
  490. ensurePasswordCorrect(done, aes256IsoDict, fileId1, 'user');
  491. });
  492. it('should accept owner password', function (done) {
  493. ensurePasswordCorrect(done, aes256IsoDict, fileId1, 'owner');
  494. });
  495. it('should not accept blank password', function (done) {
  496. ensurePasswordNeeded(done, aes256IsoDict, fileId1);
  497. });
  498. it('should not accept wrong password', function (done) {
  499. ensurePasswordIncorrect(done, aes256IsoDict, fileId1, 'wrong');
  500. });
  501. it('should accept blank password', function (done) {
  502. ensurePasswordCorrect(done, aes256IsoBlankDict, fileId1);
  503. });
  504. });
  505. it('should accept user password', function (done) {
  506. ensurePasswordCorrect(done, dict1, fileId1, '123456');
  507. });
  508. it('should accept owner password', function (done) {
  509. ensurePasswordCorrect(done, dict1, fileId1, '654321');
  510. });
  511. it('should not accept blank password', function (done) {
  512. ensurePasswordNeeded(done, dict1, fileId1);
  513. });
  514. it('should not accept wrong password', function (done) {
  515. ensurePasswordIncorrect(done, dict1, fileId1, 'wrong');
  516. });
  517. it('should accept blank password', function (done) {
  518. ensurePasswordCorrect(done, dict2, fileId2);
  519. });
  520. });
  521. });