Index: LayoutTests/crypto/resources/subtle-crypto-concurrent.js |
diff --git a/LayoutTests/crypto/resources/subtle-crypto-concurrent.js b/LayoutTests/crypto/resources/subtle-crypto-concurrent.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9834489f3dcbfc4c02718bfc17496b86b9bdd34b |
--- /dev/null |
+++ b/LayoutTests/crypto/resources/subtle-crypto-concurrent.js |
@@ -0,0 +1,170 @@ |
+if (self.importScripts) { |
+ importScripts('../../resources/js-test.js'); |
+ importScripts('common.js'); |
+} |
+ |
+function shouldEvaluateAsSilent(expressionToEval, expectedResult) |
+{ |
+ var result = eval(expressionToEval); |
+ if (result !== expectedResult) { |
+ testFailed(expressionToEval + " evaluated to " + result + " instead of " + expectedResult); |
+ } |
+} |
+ |
+function doPostMessage(data) |
+{ |
+ if (isWorker()) |
+ self.postMessage(data); |
+ else |
+ self.postMessage(data, '*'); |
+} |
+ |
+function notifySuccess() |
+{ |
+ doPostMessage("TEST_FINISHED"); |
+} |
+ |
+function notifyFailure(details) |
+{ |
+ doPostMessage("FAIL:" + details); |
+} |
+ |
+function testGenerateRsaKey() |
+{ |
+ var extractable = false; |
+ var usages = ['encrypt', 'decrypt']; |
+ // Note that the modulus length is unsually small, in order to speed up the test. |
+ var algorithm = {name: "RSAES-PKCS1-v1_5", modulusLength: 256, publicExponent: hexStringToUint8Array("010001")}; |
+ |
+ return crypto.subtle.generateKey(algorithm, extractable, usages).then(function(result) { |
+ publicKey = result.publicKey; |
+ privateKey = result.privateKey; |
+ |
+ shouldEvaluateAsSilent("publicKey.type", "public"); |
+ shouldEvaluateAsSilent("publicKey.extractable", true); |
+ shouldEvaluateAsSilent("publicKey.algorithm.name", algorithm.name); |
+ shouldEvaluateAsSilent("publicKey.algorithm.modulusLength", algorithm.modulusLength); |
+ shouldEvaluateAsSilent("bytesToHexString(publicKey.algorithm.publicExponent)", "010001"); |
+ |
+ shouldEvaluateAsSilent("privateKey.type", "private"); |
+ shouldEvaluateAsSilent("privateKey.extractable", false); |
+ shouldEvaluateAsSilent("privateKey.algorithm.name", algorithm.name); |
+ shouldEvaluateAsSilent("privateKey.algorithm.modulusLength", algorithm.modulusLength); |
+ shouldEvaluateAsSilent("bytesToHexString(privateKey.algorithm.publicExponent)", "010001"); |
+ }); |
+} |
+ |
+// Very similar to "hmac-sign-verify.html". |
+function testHmac() |
+{ |
+ var importAlgorithm = {name: 'HMAC', hash: {name: "SHA-256"}}; |
+ var algorithm = {name: 'HMAC'}; |
+ |
+ var key = null; |
+ |
+ var testCase = { |
+ hash: "SHA-256", |
+ key: "9779d9120642797f1747025d5b22b7ac607cab08e1758f2f3a46c8be1e25c53b8c6a8f58ffefa176", |
+ message: "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e", |
+ mac: "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b" |
+ }; |
+ |
+ var keyData = hexStringToUint8Array(testCase.key); |
+ var usages = ['sign', 'verify']; |
+ var extractable = true; |
+ |
+ // (1) Import the key |
+ return crypto.subtle.importKey('raw', keyData, importAlgorithm, extractable, usages).then(function(result) { |
+ key = result; |
+ |
+ // shouldBe() can only resolve variables in global context. |
+ tmpKey = key; |
+ shouldEvaluateAsSilent("tmpKey.type", "secret"); |
+ shouldEvaluateAsSilent("tmpKey.extractable", true); |
+ shouldEvaluateAsSilent("tmpKey.algorithm.name", "HMAC"); |
+ shouldEvaluateAsSilent("tmpKey.algorithm.hash.name", testCase.hash); |
+ shouldEvaluateAsSilent("tmpKey.algorithm.length", keyData.length * 8); |
+ shouldEvaluateAsSilent("tmpKey.usages.join(',')", "sign,verify"); |
+ |
+ // (2) Sign. |
+ return crypto.subtle.sign(algorithm, key, hexStringToUint8Array(testCase.message)); |
+ }).then(function(result) { |
+ mac = result; |
+ shouldEvaluateAsSilent("bytesToHexString(mac)", testCase.mac); |
+ |
+ // (3) Verify |
+ return crypto.subtle.verify(algorithm, key, hexStringToUint8Array(testCase.mac), hexStringToUint8Array(testCase.message)); |
+ }).then(function(result) { |
+ verifyResult = result; |
+ shouldEvaluateAsSilent("verifyResult", true); |
+ |
+ // (4) Verify truncated mac (by stripping 1 byte off of it). |
+ var expectedMac = hexStringToUint8Array(testCase.mac); |
+ return crypto.subtle.verify(algorithm, key, expectedMac.subarray(0, expectedMac.byteLength - 1), hexStringToUint8Array(testCase.message)); |
+ }).then(function(result) { |
+ verifyResult = result; |
+ shouldEvaluateAsSilent("verifyResult", false); |
+ |
+ return crypto.subtle.exportKey('raw', key); |
+ }).then(function(result) { |
+ exportedKeyData = result; |
+ shouldEvaluateAsSilent("bytesToHexString(exportedKeyData)", testCase.key); |
+ }); |
+} |
+ |
+// Very similar to aes-gcm-encrypt-decrypt.hml |
+function testAesGcm() |
+{ |
+ var testCase = { |
+ "key": "ae7972c025d7f2ca3dd37dcc3d41c506671765087c6b61b8", |
+ "iv": "984c1379e6ba961c828d792d", |
+ "plainText": "d30b02c343487105219d6fa080acc743", |
+ "cipherText": "c4489fa64a6edf80e7e6a3b8855bc37c", |
+ "additionalData": "edd8f630f9bbc31b0acf122998f15589d6e6e3e1a3ec89e0c6a6ece751610ebbf57fdfb9d82028ff1d9faebe37a268c1", |
+ "authenticationTag": "772ee7de0f91a981c36c93a35c88" |
+ }; |
+ |
+ var key = null; |
+ var keyData = hexStringToUint8Array(testCase.key); |
+ var iv = hexStringToUint8Array(testCase.iv); |
+ var additionalData = hexStringToUint8Array(testCase.additionalData); |
+ var tag = hexStringToUint8Array(testCase.authenticationTag); |
+ var usages = ['encrypt', 'decrypt']; |
+ var extractable = false; |
+ |
+ var tagLengthBits = tag.byteLength * 8; |
+ |
+ var algorithm = {name: 'aes-gcm', iv: iv, additionalData: additionalData, tagLength: tagLengthBits}; |
+ |
+ // (1) Import the key |
+ return crypto.subtle.importKey('raw', keyData, algorithm, extractable, usages).then(function(result) { |
+ key = result; |
+ |
+ // shouldBe() can only resolve variables in global context. |
+ tmpKey = key; |
+ shouldEvaluateAsSilent("tmpKey.type", "secret"); |
+ shouldEvaluateAsSilent("tmpKey.extractable", false); |
+ shouldEvaluateAsSilent("tmpKey.algorithm.name", "AES-GCM"); |
+ shouldEvaluateAsSilent("tmpKey.usages.join(',')", "encrypt,decrypt"); |
+ |
+ // (2) Encrypt. |
+ return crypto.subtle.encrypt(algorithm, key, hexStringToUint8Array(testCase.plainText)); |
+ }).then(function(result) { |
+ cipherText = result; |
+ shouldEvaluateAsSilent("bytesToHexString(cipherText)", testCase.cipherText + testCase.authenticationTag); |
+ |
+ // (3) Decrypt |
+ return crypto.subtle.decrypt(algorithm, key, hexStringToUint8Array(testCase.cipherText + testCase.authenticationTag)); |
+ }).then(function(result) { |
+ plainText = result; |
+ shouldEvaluateAsSilent("bytesToHexString(plainText)", testCase.plainText); |
+ }); |
+} |
+ |
+Promise.all([ |
+ testHmac(), |
+ testGenerateRsaKey(), |
+ testAesGcm(), |
+ testHmac(), |
+ testAesGcm(), |
+]).then(notifySuccess, notifyFailure); |