diff --git a/WebCryptoAPI/digest/digest.https.any.js b/WebCryptoAPI/digest/digest.https.any.js index 3b0972b1f2bf7d..5061b71afcd372 100644 --- a/WebCryptoAPI/digest/digest.https.any.js +++ b/WebCryptoAPI/digest/digest.https.any.js @@ -51,48 +51,64 @@ var mixedCase = upCase.substr(0, 1) + downCase.substr(1); promise_test(function(test) { - var promise = subtle.digest({name: upCase}, sourceData[size]) + let microtaskTriggered = false; + let promise = subtle.digest({name: upCase}, sourceData[size]) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); }, function(err) { assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); }); - + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, upCase + " with " + size + " source data"); promise_test(function(test) { - var promise = subtle.digest({name: downCase}, sourceData[size]) + let microtaskTriggered = false; + let promise = subtle.digest({name: downCase}, sourceData[size]) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); }, function(err) { assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); }); - + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, downCase + " with " + size + " source data"); promise_test(function(test) { - var promise = subtle.digest({name: mixedCase}, sourceData[size]) + let microtaskTriggered = false; + let promise = subtle.digest({name: mixedCase}, sourceData[size]) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); }, function(err) { assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); }); - + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, mixedCase + " with " + size + " source data"); promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - var promise = subtle.digest({name: upCase}, copiedBuffer) + let copiedBuffer = copyBuffer(sourceData[size]); + let microtaskTriggered = false; + let promise = subtle.digest({name: upCase}, copiedBuffer) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); }, function(err) { assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); }); - copiedBuffer[0] = 255 - copiedBuffer; + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, upCase + " with " + size + " source data and altered buffer after call"); @@ -105,13 +121,17 @@ badNames.forEach(function(badName) { promise_test(function(test) { - var promise = subtle.digest({name: badName}, sourceData[size]) + let microtaskTriggered = false; + let promise = subtle.digest({name: badName}, sourceData[size]) .then(function(result) { assert_unreached("digest() should not have worked for " + badName + ":" + size); }, function(err) { + assert_false(microtaskTriggered, "promise rejected too late"); assert_equals(err.name, "NotSupportedError", "Bad algorithm name should cause NotSupportedError") }); - + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, badName + " with " + size); @@ -121,13 +141,17 @@ // Call digest() with empty algorithm object Object.keys(sourceData).forEach(function(size) { promise_test(function(test) { - var promise = subtle.digest({}, sourceData[size]) + let microtaskTriggered = false; + let promise = subtle.digest({}, sourceData[size]) .then(function(result) { assert_unreached("digest() with missing algorithm name should have thrown a TypeError"); }, function(err) { + assert_false(microtaskTriggered, "promise rejected too late"); assert_equals(err.name, "TypeError", "Missing algorithm name should cause TypeError") }); - + Promise.resolve().then(() => { + microtaskTriggered = true; + }); return promise; }, "empty algorithm object with " + size); }); diff --git a/WebCryptoAPI/encrypt_decrypt/aes.js b/WebCryptoAPI/encrypt_decrypt/aes.js index fdeb7963f761e9..4771acfbe08b11 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/WebCryptoAPI/encrypt_decrypt/aes.js @@ -17,12 +17,18 @@ function run_test() { var promise = importVectorKey(vector, ["encrypt", "decrypt"]) .then(function(vector) { promise_test(function(test) { - return subtle.encrypt(vector.algorithm, vector.key, vector.plaintext) + let microtaskTriggered = false; + let promise = subtle.encrypt(vector.algorithm, vector.key, vector.plaintext) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, vector.result), "Should return expected result"); }, function(err) { assert_unreached("encrypt error for test " + vector.name + ": " + err.message); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name); }, function(err) { // We need a failed test if the importVectorKey operation fails, so @@ -66,12 +72,18 @@ function run_test() { var promise = importVectorKey(vector, ["encrypt", "decrypt"]) .then(function(vector) { promise_test(function(test) { - return subtle.decrypt(vector.algorithm, vector.key, vector.result) + let microtaskTriggered = false; + let promise = subtle.decrypt(vector.algorithm, vector.key, vector.result) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(result, vector.plaintext), "Should return expected result"); }, function(err) { assert_unreached("decrypt error for test " + vector.name + ": " + err.message); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name + " decryption"); }, function(err) { // We need a failed test if the importVectorKey operation fails, so diff --git a/WebCryptoAPI/encrypt_decrypt/rsa.js b/WebCryptoAPI/encrypt_decrypt/rsa.js index 5eae06e474564a..0dffe76cf47cbb 100644 --- a/WebCryptoAPI/encrypt_decrypt/rsa.js +++ b/WebCryptoAPI/encrypt_decrypt/rsa.js @@ -21,12 +21,18 @@ function run_test() { } promise_test(function(test) { - return subtle.decrypt(vector.algorithm, vector.privateKey, vector.ciphertext) + let microtaskTriggered = false; + let promise = subtle.decrypt(vector.algorithm, vector.privateKey, vector.ciphertext) .then(function(plaintext) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); }, function(err) { assert_unreached("Decryption should not throw error " + vector.name + ": " + err.message + "'"); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name + " decryption"); }, function(err) { @@ -175,8 +181,11 @@ function run_test() { var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"]) .then(function(vectors) { promise_test(function(test) { - return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext) + let microtaskTriggered = false; + let promise = subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext) .then(function(ciphertext) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_equals(ciphertext.byteLength * 8, vector.privateKey.algorithm.modulusLength, "Ciphertext length matches modulus length"); // Can we get the original plaintext back via decrypt? @@ -199,6 +208,10 @@ function run_test() { }, function(err) { assert_unreached("decrypt error for test " + vector.name + ": '" + err.message + "'"); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name); }, function(err) { diff --git a/WebCryptoAPI/generateKey/failures.js b/WebCryptoAPI/generateKey/failures.js index deaac636a99be5..216d0798ef6759 100644 --- a/WebCryptoAPI/generateKey/failures.js +++ b/WebCryptoAPI/generateKey/failures.js @@ -70,16 +70,28 @@ function run_test(algorithmNames) { // or a string, tested against the error name. function testError(algorithm, extractable, usages, expectedError, testTag) { promise_test(function(test) { - return crypto.subtle.generateKey(algorithm, extractable, usages) + let microtaskTriggered = false; + let promise = crypto.subtle.generateKey(algorithm, extractable, usages) .then(function(result) { assert_unreached("Operation succeeded, but should not have"); }, function(err) { + if (testTag === "Empty usages" || testTag === "Bad usages") { + // Error checked by the generate key operation + assert_true(microtaskTriggered, "promise rejected too early"); + } else { + // Error checked by the algorithm normalization + assert_false(microtaskTriggered, "promise rejected too late"); + } if (typeof expectedError === "number") { assert_equals(err.code, expectedError, testTag + " not supported"); } else { assert_equals(err.name, expectedError, testTag + " not supported"); } }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages)); } diff --git a/WebCryptoAPI/generateKey/successes.js b/WebCryptoAPI/generateKey/successes.js index 13c96b7c735fcb..3ead8de9bc41ce 100644 --- a/WebCryptoAPI/generateKey/successes.js +++ b/WebCryptoAPI/generateKey/successes.js @@ -61,8 +61,10 @@ function run_test(algorithmNames, slowTest) { // testTag is a string to prepend to the test name. promise_test(function(test) { - return subtle.generateKey(algorithm, extractable, usages) + let microtaskTriggered = false; + let promise = subtle.generateKey(algorithm, extractable, usages) .then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); if (resultType === "CryptoKeyPair") { assert_goodCryptoKey(result.privateKey, algorithm, extractable, usages, "private"); assert_goodCryptoKey(result.publicKey, algorithm, true, usages, "public"); @@ -102,8 +104,14 @@ function run_test(algorithmNames, slowTest) { } } }, function(err) { + if (err instanceof AssertionError) + throw err; assert_unreached("exportKey threw an unexpected error: " + err.toString()); - }) + }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages)); } diff --git a/WebCryptoAPI/import_export/ec_importKey.https.any.js b/WebCryptoAPI/import_export/ec_importKey.https.any.js index a01bfbb0ef2e18..7a9a86b6b0aa27 100644 --- a/WebCryptoAPI/import_export/ec_importKey.https.any.js +++ b/WebCryptoAPI/import_export/ec_importKey.https.any.js @@ -113,16 +113,22 @@ [format] = format.split("_compressed"); } promise_test(function(test) { - return subtle.importKey(format, keyData, algorithm, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData, algorithm, extractable, usages). then(function(key) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData.d)) ? 'private' : 'public'); if (!extractable) { return; } - return subtle.exportKey(format, key). + microtaskTriggered = false; + let promise = subtle.exportKey(format, key). then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); + if (format !== "jwk") { assert_true(equalBuffers(data[format], result), "Round trip works"); } else { @@ -131,6 +137,10 @@ }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, function(err) { if (compressed && err.name === "DataError") { assert_implements_optional(false, "Compressed point format not supported: " + err.toString()); @@ -138,6 +148,10 @@ assert_unreached("Threw an unexpected error: " + err.toString()); } }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, compressed, keyData, algorithm, extractable, usages)); } diff --git a/WebCryptoAPI/import_export/importKey_failures.js b/WebCryptoAPI/import_export/importKey_failures.js index 47d12f14500dff..e72b48534a6337 100644 --- a/WebCryptoAPI/import_export/importKey_failures.js +++ b/WebCryptoAPI/import_export/importKey_failures.js @@ -63,9 +63,22 @@ function run_test(algorithmNames) { function testError(format, algorithm, keyData, keySize, usages, extractable, expectedError, testTag) { promise_test(async() => { let key; + let microtaskTriggered = false; try { - key = await subtle.importKey(format, keyData, algorithm, extractable, usages); + let promise = subtle.importKey(format, keyData, algorithm, extractable, usages); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + key = await promise; } catch(err) { + if (testTag === "Missing algorithm name") { + // Error checked by the algorithm normalization + assert_false(microtaskTriggered, "promise rejected too late"); + } else { + // Error checked by the import key operation + assert_true(microtaskTriggered, "promise rejected too early"); + } + let actualError = typeof expectedError === "number" ? err.code : err.name; assert_equals(actualError, expectedError, testTag + " not supported."); } diff --git a/WebCryptoAPI/import_export/okp_importKey.js b/WebCryptoAPI/import_export/okp_importKey.js index 8627f85e466199..d0ff9dd5c196b7 100644 --- a/WebCryptoAPI/import_export/okp_importKey.js +++ b/WebCryptoAPI/import_export/okp_importKey.js @@ -42,16 +42,22 @@ function runTests(algorithmName) { function testFormat(format, algorithm, keyData, keySize, usages, extractable) { [algorithm, algorithm.name].forEach((alg) => { promise_test(function(test) { - return subtle.importKey(format, keyData[format], alg, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData[format], alg, extractable, usages). then(function(key) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData[format].d)) ? 'private' : 'public'); if (!extractable) { return; } - return subtle.exportKey(format, key). + microtaskTriggered = false; + let promise = subtle.exportKey(format, key). then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); + if (format !== "jwk") { assert_true(equalBuffers(keyData[format], result), "Round trip works"); } else { @@ -60,9 +66,17 @@ function testFormat(format, algorithm, keyData, keySize, usages, extractable) { }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], alg, extractable, usages)); }); } diff --git a/WebCryptoAPI/import_export/rsa_importKey.https.any.js b/WebCryptoAPI/import_export/rsa_importKey.https.any.js index c0917cab683caa..c0bbe3b4cfdb6f 100644 --- a/WebCryptoAPI/import_export/rsa_importKey.https.any.js +++ b/WebCryptoAPI/import_export/rsa_importKey.https.any.js @@ -111,16 +111,22 @@ // extrable is true, export the key and verify that it matches the input. function testFormat(format, algorithm, keyData, keySize, usages, extractable) { promise_test(function(test) { - return subtle.importKey(format, keyData[format], algorithm, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData[format], algorithm, extractable, usages). then(function(key) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData[format].d)) ? 'private' : 'public'); if (!extractable) { return; } - return subtle.exportKey(format, key). + microtaskTriggered = false; + let promise = subtle.exportKey(format, key). then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); + if (format !== "jwk") { assert_true(equalBuffers(keyData[format], result), "Round trip works"); } else { @@ -129,9 +135,17 @@ }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], algorithm, extractable, usages)); } @@ -140,12 +154,18 @@ function testEmptyUsages(format, algorithm, keyData, keySize, extractable) { const usages = []; promise_test(function(test) { - return subtle.importKey(format, keyData[format], algorithm, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData[format], algorithm, extractable, usages). then(function(key) { assert_unreached("importKey succeeded but should have failed with SyntaxError"); }, function(err) { + assert_true(microtaskTriggered, "promise rejected too early"); assert_equals(err.name, "SyntaxError", "Should throw correct error, not " + err.name + ": " + err.message); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Empty Usages: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); } diff --git a/WebCryptoAPI/import_export/symmetric_importKey.https.any.js b/WebCryptoAPI/import_export/symmetric_importKey.https.any.js index 01b3180189db83..b61f8cdea8570d 100644 --- a/WebCryptoAPI/import_export/symmetric_importKey.https.any.js +++ b/WebCryptoAPI/import_export/symmetric_importKey.https.any.js @@ -67,16 +67,22 @@ // extrable is true, export the key and verify that it matches the input. function testFormat(format, algorithm, keyData, keySize, usages, extractable) { promise_test(function(test) { - return subtle.importKey(format, keyData, algorithm, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData, algorithm, extractable, usages). then(function(key) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); assert_goodCryptoKey(key, hasLength(key.algorithm) ? { length: keySize, ...algorithm } : algorithm, extractable, usages, 'secret'); if (!extractable) { return; } - return subtle.exportKey(format, key). + microtaskTriggered = false; + let promise = subtle.exportKey(format, key). then(function(result) { + assert_true(microtaskTriggered, "promise resolved too early"); + if (format !== "jwk") { assert_true(equalBuffers(keyData, result), "Round trip works"); } else { @@ -85,9 +91,17 @@ }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, function(err) { assert_unreached("Threw an unexpected error: " + err.toString()); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); } @@ -96,12 +110,18 @@ function testEmptyUsages(format, algorithm, keyData, keySize, extractable) { const usages = []; promise_test(function(test) { - return subtle.importKey(format, keyData, algorithm, extractable, usages). + let microtaskTriggered = false; + let promise = subtle.importKey(format, keyData, algorithm, extractable, usages). then(function(key) { assert_unreached("importKey succeeded but should have failed with SyntaxError"); }, function(err) { + assert_true(microtaskTriggered, "promise rejected too early"); assert_equals(err.name, "SyntaxError", "Should throw correct error, not " + err.name + ": " + err.message); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, "Empty Usages: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); } diff --git a/WebCryptoAPI/sign_verify/eddsa.js b/WebCryptoAPI/sign_verify/eddsa.js index 4024674e3c3d7f..ead6f39fe08f4a 100644 --- a/WebCryptoAPI/sign_verify/eddsa.js +++ b/WebCryptoAPI/sign_verify/eddsa.js @@ -13,9 +13,17 @@ function run_test(algorithmName) { promise_test(async() => { let isVerified = false; let key; + let microtaskTriggered = false; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) + let promise = subtle.verify(algorithm, key, vector.signature, vector.data).then(isVerified => { + assert_true(microtaskTriggered, "promise resolved too early"); + return isVerified; + }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + isVerified = await promise; } catch (err) { assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); @@ -118,7 +126,15 @@ function run_test(algorithmName) { try { privateKey = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); publicKey = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - signature = await subtle.sign(algorithm, privateKey, vector.data); + let microtaskTriggered = false; + let promise = subtle.sign(algorithm, privateKey, vector.data).then(signature => { + assert_true(microtaskTriggered, "promise resolved too early"); + return signature; + }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + signature = await promise; isVerified = await subtle.verify(algorithm, publicKey, vector.signature, vector.data) } catch (err) { assert_false(publicKey === undefined || privateKey === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); diff --git a/WebCryptoAPI/sign_verify/hmac.js b/WebCryptoAPI/sign_verify/hmac.js index f5e2ad2769cdd8..0c100ad7cca699 100644 --- a/WebCryptoAPI/sign_verify/hmac.js +++ b/WebCryptoAPI/sign_verify/hmac.js @@ -16,14 +16,18 @@ function run_test() { var promise = importVectorKeys(vector, ["verify", "sign"]) .then(function(vector) { promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, vector.plaintext) + let microtaskTriggered = false; + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, vector.plaintext) .then(function(is_verified) { + assert_true(microtaskTriggered, "promise resolved too early"); assert_true(is_verified, "Signature verified"); }, function(err) { assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); }); - - return operation; + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name + " verification"); }, function(err) { @@ -42,8 +46,8 @@ function run_test() { var promise = importVectorKeys(vector, ["verify", "sign"]) .then(function(vector) { promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) + let signature = copyBuffer(vector.signature); + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) .then(function(is_verified) { assert_true(is_verified, "Signature is not verified"); }, function(err) { @@ -51,7 +55,7 @@ function run_test() { }); signature[0] = 255 - signature[0]; - return operation; + return promise; }, vector.name + " verification with altered signature after call"); }, function(err) { promise_test(function(test) { @@ -68,7 +72,7 @@ function run_test() { .then(function(vector) { promise_test(function(test) { var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) .then(function(is_verified) { assert_true(is_verified, "Signature verified"); }, function(err) { @@ -76,7 +80,7 @@ function run_test() { }); plaintext[0] = 255 - plaintext[0]; - return operation; + return promise; }, vector.name + " with altered plaintext after call"); }, function(err) { promise_test(function(test) { @@ -115,8 +119,11 @@ function run_test() { var promise = importVectorKeys(vector, ["verify", "sign"]) .then(function(vectors) { promise_test(function(test) { - return subtle.sign({name: "HMAC", hash: vector.hash}, vector.key, vector.plaintext) + let microtaskTriggered = false; + let promise = subtle.sign({name: "HMAC", hash: vector.hash}, vector.key, vector.plaintext) .then(function(signature) { + assert_true(microtaskTriggered, "promise resolved too early"); + assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); // Can we get the verify the new signature? return subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) @@ -127,6 +134,10 @@ function run_test() { assert_unreached("verify error for test " + vector.name + ": " + err.message + "'"); }); }); + Promise.resolve().then(() => { + microtaskTriggered = true; + }); + return promise; }, vector.name + " round trip"); }, function(err) { @@ -148,14 +159,14 @@ function run_test() { return importVectorKeys(vector, ["verify", "sign"]) .then(function(vectors) { promise_test(function(test) { - var operation = subtle.sign({name: "HMAC", hash: vector.hash}, wrongKey.privateKey, vector.plaintext) + let promise = subtle.sign({name: "HMAC", hash: vector.hash}, wrongKey.privateKey, vector.plaintext) .then(function(signature) { assert_unreached("Signing should not have succeeded for " + vector.name); }, function(err) { assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); }); - return operation; + return promise; }, vector.name + " signing with wrong algorithm name"); }, function(err) { @@ -182,14 +193,14 @@ function run_test() { return importVectorKeys(vector, ["verify", "sign"]) .then(function(vector) { promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, wrongKey.publicKey, vector.signature, vector.plaintext) + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, wrongKey.publicKey, vector.signature, vector.plaintext) .then(function(signature) { assert_unreached("Verifying should not have succeeded for " + vector.name); }, function(err) { assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); }); - return operation; + return promise; }, vector.name + " verifying with wrong algorithm name"); }, function(err) { @@ -215,14 +226,14 @@ function run_test() { var plaintext = copyBuffer(vector.plaintext); plaintext[0] = 255 - plaintext[0]; promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) .then(function(is_verified) { assert_false(is_verified, "Signature is NOT verified"); }, function(err) { assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); }); - return operation; + return promise; }, vector.name + " verification failure due to wrong plaintext"); }, function(err) { @@ -240,17 +251,17 @@ function run_test() { testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) .then(function(vector) { - var signature = copyBuffer(vector.signature); + let signature = copyBuffer(vector.signature); signature[0] = 255 - signature[0]; promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) .then(function(is_verified) { assert_false(is_verified, "Signature is NOT verified"); }, function(err) { assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); }); - return operation; + return promise; }, vector.name + " verification failure due to wrong signature"); }, function(err) { @@ -268,16 +279,16 @@ function run_test() { testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) .then(function(vector) { - var signature = vector.signature.slice(1); // Drop first byte + let signature = vector.signature.slice(1); // Drop first byte promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) + let promise = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) .then(function(is_verified) { assert_false(is_verified, "Signature is NOT verified"); }, function(err) { assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); }); - return operation; + return promise; }, vector.name + " verification failure due to short signature"); }, function(err) {