Bug 1861467 - [wpt-sync] Update web-platform-tests to eedf737ce39c512d0ca3471f988972e...
[gecko.git] / dom / crypto / test / test_WebCrypto.html
blob90da8138802491a30a5b2ba9c2c35b744ebeb123
1 <!DOCTYPE html>
2 <html>
4 <head>
5 <title>WebCrypto Test Suite</title>
6 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7 <link rel="stylesheet" href="./test_WebCrypto.css"/>
8 <script src="/tests/SimpleTest/SimpleTest.js"></script>
10 <!-- Utilities for manipulating ABVs -->
11 <script src="util.js"></script>
13 <!-- A simple wrapper around IndexedDB -->
14 <script src="simpledb.js"></script>
16 <!-- Test vectors drawn from the literature -->
17 <script src="./test-vectors.js"></script>
19 <!-- General testing framework -->
20 <script src="./test-array.js"></script>
22 <script>/* <![CDATA[*/
23 "use strict";
25 // -----------------------------------------------------------------------------
26 TestArray.addTest(
27 "Test for presence of WebCrypto API methods",
28 function() {
29 this.complete(
30 exists(window.crypto.subtle) &&
31 exists(window.crypto.subtle.encrypt) &&
32 exists(window.crypto.subtle.decrypt) &&
33 exists(window.crypto.subtle.sign) &&
34 exists(window.crypto.subtle.verify) &&
35 exists(window.crypto.subtle.digest) &&
36 exists(window.crypto.subtle.importKey) &&
37 exists(window.crypto.subtle.exportKey) &&
38 exists(window.crypto.subtle.generateKey) &&
39 exists(window.crypto.subtle.deriveKey) &&
40 exists(window.crypto.subtle.deriveBits)
45 // -----------------------------------------------------------------------------
46 TestArray.addTest(
47 "Clean failure on a mal-formed algorithm",
48 function() {
49 var that = this;
50 var alg = {
51 get name() {
52 throw new Error("Oh no, no name!");
56 crypto.subtle.importKey("raw", tv.raw, alg, true, ["encrypt"])
57 .then(
58 error(that),
59 complete(that, function(x) { return true; })
64 // -----------------------------------------------------------------------------
65 TestArray.addTest(
66 "Import / export round-trip with 'raw'",
67 function() {
68 var that = this;
69 var alg = "AES-GCM";
71 function doExport(x) {
72 if (!hasKeyFields(x)) {
73 throw new Error("Invalid key; missing field(s)");
74 } else if ((x.algorithm.name != alg) ||
75 (x.algorithm.length != 8 * tv.raw.length) ||
76 (x.type != "secret") ||
77 (!x.extractable) ||
78 (x.usages.length != 1) ||
79 (x.usages[0] != "encrypt")) {
80 throw new Error("Invalid key: incorrect key data");
82 return crypto.subtle.exportKey("raw", x);
85 crypto.subtle.importKey("raw", tv.raw, alg, true, ["encrypt"])
86 .then(doExport)
87 .then(
88 memcmp_complete(that, tv.raw),
89 error(that)
94 // -----------------------------------------------------------------------------
95 TestArray.addTest(
96 "Import failure with format 'raw'",
97 function() {
98 var that = this;
99 var alg = "AES-GCM";
101 crypto.subtle.importKey("raw", tv.negative_raw, alg, true, ["encrypt"])
102 .then(error(that), complete(that));
106 // -----------------------------------------------------------------------------
107 TestArray.addTest(
108 "Proper handling of an ABV representing part of a buffer",
109 function() {
110 var that = this;
111 var alg = "AES-GCM";
113 var u8 = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
114 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
115 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
116 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f]);
117 var u32 = new Uint32Array(u8.buffer, 8, 4);
118 var out = u8.subarray(8, 24);
120 function doExport(x) {
121 return crypto.subtle.exportKey("raw", x);
124 crypto.subtle.importKey("raw", u32, alg, true, ["encrypt"])
125 .then(doExport, error(that))
126 .then(memcmp_complete(that, out), error(that));
130 // -----------------------------------------------------------------------------
131 TestArray.addTest(
132 "Import / export round-trip with 'pkcs8'",
133 function() {
134 var that = this;
135 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
137 function doExport(x) {
138 if (!hasKeyFields(x)) {
139 throw new Error("Invalid key; missing field(s)");
140 } else if ((x.algorithm.name != alg.name) ||
141 (x.algorithm.hash.name != alg.hash) ||
142 (x.algorithm.modulusLength != 512) ||
143 (x.algorithm.publicExponent.byteLength != 3) ||
144 (x.type != "private") ||
145 (!x.extractable) ||
146 (x.usages.length != 1) ||
147 (x.usages[0] != "sign")) {
148 throw new Error("Invalid key: incorrect key data");
150 return crypto.subtle.exportKey("pkcs8", x);
153 crypto.subtle.importKey("pkcs8", tv.pkcs8, alg, true, ["sign"])
154 .then(doExport)
155 .then(
156 memcmp_complete(that, tv.pkcs8),
157 error(that)
162 // -----------------------------------------------------------------------------
163 TestArray.addTest(
164 "Import failure with format 'pkcs8'",
165 function() {
166 var that = this;
167 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
169 crypto.subtle.importKey("pkcs8", tv.negative_pkcs8, alg, true, ["encrypt"])
170 .then(error(that), complete(that));
174 // -----------------------------------------------------------------------------
175 TestArray.addTest(
176 "Import / export round-trip with 'spki'",
177 function() {
178 var that = this;
179 var alg = {
180 name: "RSASSA-PKCS1-v1_5",
181 hash: "SHA-256",
184 function doExport(x) {
185 if (!hasKeyFields(x)) {
186 throw new Error("Invalid key; missing field(s)");
187 } else if ((x.algorithm.name != alg.name) ||
188 (x.algorithm.modulusLength != 1024) ||
189 (x.algorithm.publicExponent.byteLength != 3) ||
190 (x.type != "public") ||
191 (!x.extractable) ||
192 (x.usages.length != 1) ||
193 (x.usages[0] != "verify")) {
194 throw new Error("Invalid key: incorrect key data");
196 return crypto.subtle.exportKey("spki", x);
199 crypto.subtle.importKey("spki", tv.spki, alg, true, ["verify"])
200 .then(doExport, error(that))
201 .then(
202 memcmp_complete(that, tv.spki),
203 error(that)
208 // -----------------------------------------------------------------------------
209 TestArray.addTest(
210 "Import failure with format 'spki'",
211 function() {
212 var that = this;
213 var alg = {
214 name: "RSASSA-PKCS1-v1_5",
215 hash: "SHA-256",
218 crypto.subtle.importKey("spki", tv.negative_spki, alg, true, ["encrypt"])
219 .then(error(that), complete(that));
223 // -----------------------------------------------------------------------------
224 TestArray.addTest(
225 "Importing an ECDSA key as an RSA key should fail",
226 function() {
227 var that = this;
228 var alg = {
229 name: "RSASSA-PKCS1-v1_5",
230 hash: "SHA-256",
233 crypto.subtle.importKey("spki", tv.ecdh_p256.spki, alg, true, ["verify"])
234 .then(error(that), complete(that));
238 // -----------------------------------------------------------------------------
239 TestArray.addTest(
240 "Refuse to export non-extractable key",
241 function() {
242 var that = this;
243 var alg = "AES-GCM";
245 function doExport(x) {
246 return crypto.subtle.exportKey("raw", x);
249 crypto.subtle.importKey("raw", tv.raw, alg, false, ["encrypt"])
250 .then(doExport, error(that))
251 .then(
252 error(that),
253 complete(that)
258 // -----------------------------------------------------------------------------
259 TestArray.addTest(
260 "IndexedDB store / retrieve round-trip",
261 function() {
262 var that = this;
263 var alg = "AES-GCM";
264 var importedKey;
265 var dbname = "keyDB";
266 var dbstore = "keystore";
267 var dbversion = 1;
268 var dbkey = 0;
269 var db;
271 function doIndexedDB(x) {
272 importedKey = x;
273 var req = indexedDB.deleteDatabase(dbname);
274 req.onerror = error(that);
275 req.onsuccess = doCreateDB;
278 function doCreateDB() {
279 var req = indexedDB.open(dbname, dbversion);
280 req.onerror = error(that);
281 req.onupgradeneeded = function(e) {
282 db = e.target.result;
283 db.createObjectStore(dbstore, {keyPath: "id"});
286 req.onsuccess = doPut;
289 function doPut() {
290 var req = db.transaction([dbstore], "readwrite")
291 .objectStore(dbstore)
292 .add({id: dbkey, val: importedKey});
293 req.onerror = error(that);
294 req.onsuccess = doGet;
297 function doGet() {
298 var req = db.transaction([dbstore], "readwrite")
299 .objectStore(dbstore)
300 .get(dbkey);
301 req.onerror = error(that);
302 req.onsuccess = complete(that, function(e) {
303 db.close();
304 return hasKeyFields(e.target.result.val);
308 crypto.subtle.importKey("raw", tv.raw, alg, false, ["encrypt"])
309 .then(doIndexedDB, error(that));
313 // -----------------------------------------------------------------------------
314 TestArray.addTest(
315 "Generate a 256-bit HMAC-SHA-256 key",
316 function() {
317 var that = this;
318 var alg = { name: "HMAC", length: 256, hash: {name: "SHA-256"} };
319 crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
320 complete(that, function(x) {
321 return hasKeyFields(x) && x.algorithm.length == 256;
323 error(that)
328 // -----------------------------------------------------------------------------
329 TestArray.addTest(
330 "Generate a 256-bit HMAC-SHA-256 key without specifying a key length",
331 function() {
332 var that = this;
333 var alg = { name: "HMAC", hash: {name: "SHA-256"} };
334 crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
335 complete(that, function(x) {
336 return hasKeyFields(x) && x.algorithm.length == 512;
338 error(that)
343 // -----------------------------------------------------------------------------
344 TestArray.addTest(
345 "Generate a 256-bit HMAC-SHA-512 key without specifying a key length",
346 function() {
347 var that = this;
348 var alg = { name: "HMAC", hash: {name: "SHA-512"} };
349 crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
350 complete(that, function(x) {
351 return hasKeyFields(x) && x.algorithm.length == 1024;
353 error(that)
358 // -----------------------------------------------------------------------------
359 TestArray.addTest(
360 "Fail generating an HMAC key when specifying an invalid hash algorithm",
361 function() {
362 var that = this;
363 var alg = { name: "HMAC", hash: {name: "SHA-123"} };
364 crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
365 error(that),
366 complete(that, function() { return true; })
371 // -----------------------------------------------------------------------------
372 TestArray.addTest(
373 "Fail generating an HMAC key when specifying a zero length",
374 function() {
375 var that = this;
376 var alg = { name: "HMAC", hash: {name: "SHA-256"}, length: 0 };
377 crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
378 error(that),
379 complete(that, function() { return true; })
384 // -----------------------------------------------------------------------------
385 TestArray.addTest(
386 "Generate a 192-bit AES key",
387 function() {
388 var that = this;
389 var alg = { name: "AES-GCM", length: 192 };
390 crypto.subtle.generateKey(alg, true, ["encrypt"]).then(
391 complete(that, function(x) {
392 return hasKeyFields(x);
394 error(that)
399 // -----------------------------------------------------------------------------
400 TestArray.addTest(
401 "Fail generating an AES key of wrong length",
402 function() {
403 var that = this;
404 var alg = { name: "AES-CBC", length: 64 };
405 crypto.subtle.generateKey(alg, false, ["encrypt"]).then(
406 error(that),
407 complete(that, function(e) {
408 return e.name == "OperationError";
414 // -----------------------------------------------------------------------------
415 TestArray.addTest(
416 "Fail generating a key with bad algorithm argument",
417 function() {
418 var that = this;
419 var alg = { name: "AES", length: 128 };
420 crypto.subtle.generateKey(alg, false, ["encrypt"]).then(
421 error(that),
422 complete(that, function(e) {
423 return e.name == "NotSupportedError";
429 // -----------------------------------------------------------------------------
430 TestArray.addTest( "Generate a 1024-bit RSA key",
431 function() {
432 var that = this;
433 var alg = {
434 name: "RSASSA-PKCS1-v1_5",
435 hash: "SHA-256",
436 modulusLength: 1024,
437 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
439 crypto.subtle.generateKey(alg, false, ["sign", "verify"]).then(
440 complete(that, function(x) {
441 return exists(x.publicKey) &&
442 (x.publicKey.algorithm.name == alg.name) &&
443 (x.publicKey.algorithm.modulusLength == alg.modulusLength) &&
444 (x.publicKey.type == "public") &&
445 x.publicKey.extractable &&
446 (x.publicKey.usages.length == 1) &&
447 (x.publicKey.usages[0] == "verify") &&
448 exists(x.privateKey) &&
449 (x.privateKey.algorithm.name == alg.name) &&
450 (x.privateKey.algorithm.modulusLength == alg.modulusLength) &&
451 (x.privateKey.type == "private") &&
452 !x.privateKey.extractable &&
453 (x.privateKey.usages.length == 1) &&
454 (x.privateKey.usages[0] == "sign");
456 error(that)
461 // -----------------------------------------------------------------------------
462 TestArray.addTest(
463 "Fail cleanly when NSS refuses to generate a key pair",
464 function() {
465 var that = this;
466 var alg = {
467 name: "RSASSA-PKCS1-v1_5",
468 hash: "SHA-256",
469 modulusLength: 2299, // NSS does not like this key length
470 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
473 crypto.subtle.generateKey(alg, false, ["sign"])
474 .then( error(that), complete(that) );
478 // -----------------------------------------------------------------------------
479 TestArray.addTest(
480 "SHA-256 digest",
481 function() {
482 var that = this;
483 crypto.subtle.digest("SHA-256", tv.sha256.data).then(
484 memcmp_complete(that, tv.sha256.result),
485 error(that)
490 // -----------------------------------------------------------------------------
491 TestArray.addTest(
492 "Fail cleanly on unknown hash algorithm",
493 function() {
494 var that = this;
495 crypto.subtle.digest("GOST-34_311-95", tv.sha256.data).then(
496 error(that),
497 complete(that, function() { return true; })
502 // -----------------------------------------------------------------------------
503 TestArray.addTest(
504 "AES-CBC encrypt",
505 function() {
506 var that = this;
508 function doEncrypt(x) {
509 return crypto.subtle.encrypt(
510 { name: "AES-CBC", iv: tv.aes_cbc_enc.iv },
511 x, tv.aes_cbc_enc.data);
514 crypto.subtle.importKey("raw", tv.aes_cbc_enc.key, "AES-CBC", false, ["encrypt"])
515 .then(doEncrypt)
516 .then(
517 memcmp_complete(that, tv.aes_cbc_enc.result),
518 error(that)
523 // -----------------------------------------------------------------------------
524 TestArray.addTest(
525 "AES-CBC encrypt with wrong IV size",
526 function() {
527 var that = this;
529 function encrypt(x, iv) {
530 return crypto.subtle.encrypt(
531 { name: "AES-CBC", iv },
532 x, tv.aes_cbc_enc.data);
535 function checkPromises(promises) {
536 for (var promise of promises) {
537 if (promise.status != "rejected") {
538 return false;
540 if (promise.reason.name != "OperationError") {
541 return false;
545 return true;
548 crypto.subtle.importKey("raw", tv.aes_cbc_enc.key, "AES-CBC", false, ["encrypt"])
549 .then(function(key) {
550 var p1 = encrypt(key, new Uint8Array(15));
551 var p2 = encrypt(key, new Uint8Array(17));
553 Promise.allSettled([p1, p2])
554 .then(complete(that, checkPromises));
559 // -----------------------------------------------------------------------------
560 TestArray.addTest(
561 "AES-CBC decrypt",
562 function() {
563 var that = this;
565 function doDecrypt(x) {
566 return crypto.subtle.decrypt(
567 { name: "AES-CBC", iv: tv.aes_cbc_dec.iv },
568 x, tv.aes_cbc_dec.data);
571 crypto.subtle.importKey("raw", tv.aes_cbc_dec.key, "AES-CBC", false, ["decrypt"])
572 .then(doDecrypt)
573 .then(
574 memcmp_complete(that, tv.aes_cbc_dec.result),
575 error(that)
580 // -----------------------------------------------------------------------------
581 TestArray.addTest(
582 "AES-CBC decrypt with wrong IV size",
583 function() {
584 var that = this;
586 function decrypt(x, iv) {
587 return crypto.subtle.decrypt(
588 { name: "AES-CBC", iv },
589 x, tv.aes_cbc_dec.data);
592 function checkPromises(promises) {
593 for (var promise of promises) {
594 if (promise.status != "rejected") {
595 return false;
597 if (promise.reason.name != "OperationError") {
598 return false;
602 return true;
605 crypto.subtle.importKey("raw", tv.aes_cbc_dec.key, "AES-CBC", false, ["decrypt"])
606 .then(function(key) {
607 var p1 = decrypt(key, new Uint8Array(15));
608 var p2 = decrypt(key, new Uint8Array(17));
610 Promise.allSettled([p1, p2])
611 .then(complete(that, checkPromises));
616 // -----------------------------------------------------------------------------
617 TestArray.addTest(
618 "AES-CTR encryption",
619 function() {
620 var that = this;
622 function doEncrypt(x) {
623 return crypto.subtle.encrypt(
624 { name: "AES-CTR", counter: tv.aes_ctr_enc.iv, length: 32 },
625 x, tv.aes_ctr_enc.data);
628 crypto.subtle.importKey("raw", tv.aes_ctr_enc.key, "AES-CTR", false, ["encrypt"])
629 .then(doEncrypt)
630 .then(
631 memcmp_complete(that, tv.aes_ctr_enc.result),
632 error(that)
637 // -----------------------------------------------------------------------------
638 TestArray.addTest(
639 "AES-CTR encryption with wrong IV size",
640 function() {
641 var that = this;
643 function encrypt(x, iv) {
644 return crypto.subtle.encrypt(
645 { name: "AES-CTR", counter: iv, length: 32 },
646 x, tv.aes_ctr_enc.data);
649 function checkPromises(promises) {
650 for (var promise of promises) {
651 if (promise.status != "rejected") {
652 return false;
654 if (promise.reason.name != "OperationError") {
655 return false;
659 return true;
662 crypto.subtle.importKey("raw", tv.aes_ctr_enc.key, "AES-CTR", false, ["encrypt"])
663 .then(function(key) {
664 var p1 = encrypt(key, new Uint8Array(15));
665 var p2 = encrypt(key, new Uint8Array(17));
667 Promise.allSettled([p1, p2])
668 .then(complete(that, checkPromises));
673 // -----------------------------------------------------------------------------
674 TestArray.addTest(
675 "AES-CTR decryption",
676 function() {
677 var that = this;
679 function doDecrypt(x) {
680 return crypto.subtle.decrypt(
681 { name: "AES-CTR", counter: tv.aes_ctr_dec.iv, length: 32 },
682 x, tv.aes_ctr_dec.data);
685 crypto.subtle.importKey("raw", tv.aes_ctr_dec.key, "AES-CTR", false, ["decrypt"])
686 .then(doDecrypt)
687 .then(
688 memcmp_complete(that, tv.aes_ctr_dec.result),
689 error(that)
694 // -----------------------------------------------------------------------------
695 TestArray.addTest(
696 "AES-CTR decryption with wrong IV size",
697 function() {
698 var that = this;
700 function decrypt(x, iv) {
701 return crypto.subtle.decrypt(
702 { name: "AES-CTR", counter: iv, length: 32 },
703 x, tv.aes_ctr_dec.data);
706 function checkPromises(promises) {
707 for (var promise of promises) {
708 if (promise.status != "rejected") {
709 return false;
711 if (promise.reason.name != "OperationError") {
712 return false;
716 return true;
719 crypto.subtle.importKey("raw", tv.aes_ctr_dec.key, "AES-CTR", false, ["decrypt"])
720 .then(function(key) {
721 var p1 = decrypt(key, new Uint8Array(15));
722 var p2 = decrypt(key, new Uint8Array(17));
724 Promise.allSettled([p1, p2])
725 .then(complete(that, checkPromises));
730 // -----------------------------------------------------------------------------
731 TestArray.addTest(
732 "AES-GCM encryption",
733 function() {
734 var that = this;
736 function doEncrypt(x) {
737 return crypto.subtle.encrypt(
739 name: "AES-GCM",
740 iv: tv.aes_gcm_enc.iv,
741 additionalData: tv.aes_gcm_enc.adata,
742 tagLength: 128,
744 x, tv.aes_gcm_enc.data);
747 crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, "AES-GCM", false, ["encrypt"])
748 .then(doEncrypt)
749 .then(
750 memcmp_complete(that, tv.aes_gcm_enc.result),
751 error(that)
756 // -----------------------------------------------------------------------------
757 TestArray.addTest(
758 "AES-GCM decryption",
759 function() {
760 var that = this;
762 function doDecrypt(x) {
763 return crypto.subtle.decrypt(
765 name: "AES-GCM",
766 iv: tv.aes_gcm_dec.iv,
767 additionalData: tv.aes_gcm_dec.adata,
768 tagLength: 128,
770 x, tv.aes_gcm_dec.data);
773 crypto.subtle.importKey("raw", tv.aes_gcm_dec.key, "AES-GCM", false, ["decrypt"])
774 .then(doDecrypt)
775 .then(
776 memcmp_complete(that, tv.aes_gcm_dec.result),
777 error(that)
782 // -----------------------------------------------------------------------------
783 TestArray.addTest(
784 "AES-GCM decryption, failing authentication check",
785 function() {
786 var that = this;
788 function doDecrypt(x) {
789 return crypto.subtle.decrypt(
791 name: "AES-GCM",
792 iv: tv.aes_gcm_dec_fail.iv,
793 additionalData: tv.aes_gcm_dec_fail.adata,
794 tagLength: 128,
796 x, tv.aes_gcm_dec_fail.data);
799 crypto.subtle.importKey("raw", tv.aes_gcm_dec_fail.key, "AES-GCM", false, ["decrypt"])
800 .then(doDecrypt)
801 .then(
802 error(that),
803 complete(that)
808 // -----------------------------------------------------------------------------
809 TestArray.addTest(
810 "AES-GCM encryption, fail with a zero-length IV",
811 function() {
812 var that = this;
813 var alg = {
814 name: "AES-GCM",
815 iv: new Uint8Array(),
816 additionalData: tv.aes_gcm_enc.adata,
817 tagLength: 128,
820 function doEncrypt(x) {
821 return crypto.subtle.encrypt(alg, x, tv.aes_gcm_enc.data);
824 crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, "AES-GCM", false, ["encrypt"])
825 .then(doEncrypt)
826 .then(error(that), complete(that));
830 // -----------------------------------------------------------------------------
831 TestArray.addTest(
832 "AES-GCM encryption, accept an all-zero IV (1 byte)",
833 function() {
834 var that = this;
835 var alg = {
836 name: "AES-GCM",
837 iv: new Uint8Array(1),
838 additionalData: tv.aes_gcm_enc.adata,
839 tagLength: 128,
842 function doEncrypt(x) {
843 return crypto.subtle.encrypt(alg, x, tv.aes_gcm_enc.data);
846 crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, "AES-GCM", false, ["encrypt"])
847 .then(doEncrypt)
848 .then(complete(that), error(that));
852 // -----------------------------------------------------------------------------
853 TestArray.addTest(
854 "AES-GCM encryption, accept an all-zero IV (12 bytes)",
855 function() {
856 var that = this;
857 var alg = {
858 name: "AES-GCM",
859 iv: new Uint8Array(12),
860 additionalData: tv.aes_gcm_enc.adata,
861 tagLength: 128,
864 function doEncrypt(x) {
865 return crypto.subtle.encrypt(alg, x, tv.aes_gcm_enc.data);
868 crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, "AES-GCM", false, ["encrypt"])
869 .then(doEncrypt)
870 .then(complete(that), error(that));
874 // -----------------------------------------------------------------------------
875 TestArray.addTest(
876 "AES-GCM encryption, accept an all-zero IV (16 bytes)",
877 function() {
878 var that = this;
879 var alg = {
880 name: "AES-GCM",
881 iv: new Uint8Array(16),
882 additionalData: tv.aes_gcm_enc.adata,
883 tagLength: 128,
886 function doEncrypt(x) {
887 return crypto.subtle.encrypt(alg, x, tv.aes_gcm_enc.data);
890 crypto.subtle.importKey("raw", tv.aes_gcm_enc.key, "AES-GCM", false, ["encrypt"])
891 .then(doEncrypt)
892 .then(complete(that), error(that));
896 // -----------------------------------------------------------------------------
897 TestArray.addTest(
898 "HMAC SHA-256 sign",
899 function() {
900 var that = this;
901 var alg = {
902 name: "HMAC",
903 hash: "SHA-256",
906 function doSign(x) {
907 return crypto.subtle.sign("HMAC", x, tv.hmac_sign.data);
910 crypto.subtle.importKey("raw", tv.hmac_sign.key, alg, false, ["sign"])
911 .then(doSign)
912 .then(
913 memcmp_complete(that, tv.hmac_sign.result),
914 error(that)
919 // -----------------------------------------------------------------------------
920 TestArray.addTest(
921 "HMAC SHA-256 verify",
922 function() {
923 var that = this;
924 var alg = {
925 name: "HMAC",
926 hash: "SHA-256",
929 function doVerify(x) {
930 return crypto.subtle.verify("HMAC", x, tv.hmac_verify.sig, tv.hmac_verify.data);
933 crypto.subtle.importKey("raw", tv.hmac_verify.key, alg, false, ["verify"])
934 .then(doVerify)
935 .then(
936 complete(that, function(x) { return !!x; }),
937 error(that)
942 // -----------------------------------------------------------------------------
943 TestArray.addTest(
944 "HMAC SHA-256, failing verification due to bad signature",
945 function() {
946 var that = this;
947 var alg = {
948 name: "HMAC",
949 hash: "SHA-256",
952 function doVerify(x) {
953 return crypto.subtle.verify("HMAC", x, tv.hmac_verify.sig_fail,
954 tv.hmac_verify.data);
957 crypto.subtle.importKey("raw", tv.hmac_verify.key, alg, false, ["verify"])
958 .then(doVerify)
959 .then(
960 complete(that, function(x) { return !x; }),
961 error(that)
966 // -----------------------------------------------------------------------------
967 TestArray.addTest(
968 "HMAC SHA-256, failing verification due to key usage restriction",
969 function() {
970 var that = this;
971 var alg = {
972 name: "HMAC",
973 hash: "SHA-256",
976 function doVerify(x) {
977 return crypto.subtle.verify("HMAC", x, tv.hmac_verify.sig,
978 tv.hmac_verify.data);
981 crypto.subtle.importKey("raw", tv.hmac_verify.key, alg, false, ["encrypt"])
982 .then(doVerify)
983 .then(
984 error(that),
985 complete(that, function(x) { return true; })
990 // -----------------------------------------------------------------------------
991 TestArray.addTest(
992 "RSASSA/SHA-1 signature",
993 function() {
994 var that = this;
995 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
997 function doSign(x) {
998 return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
1001 crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ["sign"])
1002 .then( doSign )
1003 .then( memcmp_complete(that, tv.rsassa.sig1), error(that) );
1007 // -----------------------------------------------------------------------------
1008 TestArray.addTest(
1009 "RSASSA verification (SHA-1)",
1010 function() {
1011 var that = this;
1012 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
1014 function doVerify(x) {
1015 return crypto.subtle.verify(alg.name, x, tv.rsassa.sig1, tv.rsassa.data);
1018 crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ["verify"])
1019 .then( doVerify )
1020 .then(
1021 complete(that, function(x) { return x; }),
1022 error(that)
1027 // -----------------------------------------------------------------------------
1028 TestArray.addTest(
1029 "RSASSA verification (SHA-1), failing verification",
1030 function() {
1031 var that = this;
1032 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
1034 function doVerify(x) {
1035 return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
1038 crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ["verify"])
1039 .then( doVerify )
1040 .then(
1041 complete(that, function(x) { return !x; }),
1042 error(that)
1047 // -----------------------------------------------------------------------------
1048 TestArray.addTest(
1049 "RSASSA/SHA-256 signature",
1050 function() {
1051 var that = this;
1052 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
1054 function doSign(x) {
1055 return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
1058 crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ["sign"])
1059 .then( doSign )
1060 .then( memcmp_complete(that, tv.rsassa.sig256), error(that) );
1064 // -----------------------------------------------------------------------------
1065 TestArray.addTest(
1066 "RSASSA verification (SHA-256)",
1067 function() {
1068 var that = this;
1069 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
1071 function doVerify(x) {
1072 return crypto.subtle.verify(alg.name, x, tv.rsassa.sig256, tv.rsassa.data);
1075 crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ["verify"])
1076 .then( doVerify )
1077 .then(
1078 complete(that, function(x) { return x; }),
1079 error(that)
1084 // -----------------------------------------------------------------------------
1085 TestArray.addTest(
1086 "RSASSA verification (SHA-256), failing verification",
1087 function() {
1088 var that = this;
1089 var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
1091 function doVerify(x) {
1092 return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
1095 crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ["verify"])
1096 .then( doVerify )
1097 .then(
1098 complete(that, function(x) { return !x; }),
1099 error(that)
1104 // -----------------------------------------------------------------------------
1105 TestArray.addTest(
1106 "Test that we return ArrayBuffers not ArrayBufferViews",
1107 function() {
1108 var that = this;
1110 crypto.subtle.digest("SHA-256", tv.sha256.data)
1111 .then(complete(that, function(x) {
1112 return x instanceof ArrayBuffer;
1113 }), error(that));
1117 // -----------------------------------------------------------------------------
1118 TestArray.addTest(
1119 "Ensure that importing an invalid key doesn't crash",
1120 function() {
1121 var that = this;
1122 var alg = {name: "RSA-OAEP", hash: "SHA-1"};
1124 crypto.subtle.importKey("pkcs8", tv.broken_pkcs8.rsa, alg, false, ["decrypt"])
1125 .then(error(that), complete(that));
1129 // -----------------------------------------------------------------------------
1130 TestArray.addTest(
1131 "Test that we check keys before using them for encryption/signatures",
1132 function() {
1133 var that = this;
1135 function doCheckRSASSA() {
1136 var alg = {name: "HMAC", hash: {name: "SHA-1"}};
1138 function doSign(x) {
1139 return crypto.subtle.sign("RSASSA-PKCS1-v1_5", x, new Uint8Array());
1142 return crypto.subtle.generateKey(alg, false, ["sign"]).then(doSign);
1145 doCheckRSASSA().then(error(that), complete(that));
1149 // -----------------------------------------------------------------------------
1150 TestArray.addTest(
1151 "Test that we're using the right globals when creating objects",
1152 function() {
1153 // This test isn't supported in workers.
1154 if (window.importScripts) {
1155 return this.complete(true);
1158 var that = this;
1159 var data = crypto.getRandomValues(new Uint8Array(10));
1160 var hmacAlg = {name: "HMAC", length: 256, hash: "SHA-1"};
1162 var rsaAlg = {
1163 name: "RSA-PSS",
1164 hash: "SHA-1",
1165 modulusLength: 1024,
1166 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
1169 function checkPrototypes(obj, type) {
1170 return obj.__proto__ != window[type].prototype &&
1171 obj.__proto__ == frames[0][type].prototype;
1174 var p1 = crypto.subtle.importKey.call(
1175 frames[0].crypto.subtle, "raw", data, hmacAlg, false, ["sign", "verify"]);
1176 var p2 = crypto.subtle.generateKey.call(
1177 frames[0].crypto.subtle, hmacAlg, false, ["sign", "verify"]);
1178 var p3 = crypto.subtle.generateKey.call(
1179 frames[0].crypto.subtle, rsaAlg, false, ["sign", "verify"]);
1181 if (!checkPrototypes(p1, "Promise") ||
1182 !checkPrototypes(p2, "Promise") ||
1183 !checkPrototypes(p3, "Promise")) {
1184 error(that)();
1187 return Promise.all([p1, p2, p3]).then(complete(that, keys => {
1188 return keys.every(key => {
1189 if (key instanceof frames[0].CryptoKey) {
1190 return checkPrototypes(key, "CryptoKey");
1193 return checkPrototypes(key.publicKey, "CryptoKey") &&
1194 checkPrototypes(key.privateKey, "CryptoKey");
1196 }), error(that));
1199 /* ]]>*/</script>
1200 </head>
1202 <body>
1204 <div id="content">
1205 <div id="head">
1206 <b>Web</b>Crypto<br>
1207 </div>
1209 <iframe style="display: none;"></iframe>
1210 <div id="start" onclick="start();">RUN ALL</div>
1212 <div id="resultDiv" class="content">
1213 Summary:
1214 <span class="pass"><span id="passN">0</span> passed, </span>
1215 <span class="fail"><span id="failN">0</span> failed, </span>
1216 <span class="pending"><span id="pendingN">0</span> pending.</span>
1217 <br/>
1218 <br/>
1220 <table id="results">
1221 <tr>
1222 <th>Test</th>
1223 <th>Result</th>
1224 <th>Time</th>
1225 </tr>
1226 </table>
1228 </div>
1230 <div id="foot"></div>
1231 </div>
1233 </body>
1234 </html>