diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 2ce7de20ded95f..20c7df576e73b6 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -34,7 +34,7 @@ Last update: - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi - web-locks: https://github.com/web-platform-tests/wpt/tree/10a122a6bc/web-locks -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/7cbe7e8ed9/WebCryptoAPI +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/42e47329fd/WebCryptoAPI - webidl: https://github.com/web-platform-tests/wpt/tree/63ca529a02/webidl - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/2f96fa1996/webidl/ecmascript-binding/es-exceptions - webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/6495c91853/webmessaging/broadcastchannel diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js index e793722d8be598..d5f790e42b4982 100644 --- a/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js @@ -171,26 +171,42 @@ Object.keys(digestedData).forEach(function (alg) { }); }, alg + ' with ' + length + ' bit output and ' + size + ' source data'); - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - return crypto.subtle - .digest({ name: alg, length: length }, buffer) - .then(function (result) { - // Alter the buffer after calling digest - if (buffer.length > 0) { + if (sourceData[size].length > 0) { + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + // Alter the buffer before calling digest + buffer[0] = ~buffer[0]; + return crypto.subtle + .digest({ + get name() { + // Alter the buffer back while calling digest + buffer[0] = sourceData[size][0]; + return alg; + }, + length + }, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, digestedData[alg][length][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + length + ' bit output and ' + size + ' source data and altered buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + return crypto.subtle + .digest({ name: alg, length: length }, buffer) + .then(function (result) { + // Alter the buffer after calling digest buffer[0] = ~buffer[0]; - } - assert_true( - equalBuffers(result, digestedData[alg][length][size]), - 'digest matches expected' - ); - }); - }, alg + - ' with ' + - length + - ' bit output and ' + - size + - ' source data and altered buffer after call'); + assert_true( + equalBuffers(result, digestedData[alg][length][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + length + ' bit output and ' + size + ' source data and altered buffer after call'); + } }); }); }); diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js index 3b0972b1f2bf7d..e0c85f8f6b30e4 100644 --- a/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js @@ -83,19 +83,37 @@ return promise; }, mixedCase + " with " + size + " source data"); - promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - var promise = subtle.digest({name: upCase}, copiedBuffer) - .then(function(result) { - 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; - return promise; - }, upCase + " with " + size + " source data and altered buffer after call"); - + if (sourceData[size].length > 0) { + promise_test(function(test) { + var copiedBuffer = copyBuffer(sourceData[size]); + copiedBuffer[0] = 255 - copiedBuffer[0]; + var promise = subtle.digest({ + get name() { + copiedBuffer[0] = sourceData[size][0]; + return upCase; + } + }, copiedBuffer) + .then(function(result) { + 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); + }); + return promise; + }, upCase + " with " + size + " source data and altered buffer during call"); + + promise_test(function(test) { + var copiedBuffer = copyBuffer(sourceData[size]); + var promise = subtle.digest({name: upCase}, copiedBuffer) + .then(function(result) { + 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[0]; + return promise; + }, upCase + " with " + size + " source data and altered buffer after call"); + } }); }); diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js index 8f84ad08ca1a25..fc33608e07ab14 100644 --- a/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js @@ -109,19 +109,39 @@ Object.keys(sourceData).forEach(function (size) { }); }, alg + ' with ' + size + ' source data'); - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - return crypto.subtle.digest(alg, buffer).then(function (result) { - // Alter the buffer after calling digest - if (buffer.length > 0) { + if (sourceData[size].length > 0) { + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + // Alter the buffer before calling digest + buffer[0] = ~buffer[0]; + return crypto.subtle + .digest({ + get name() { + // Alter the buffer back while calling digest + buffer[0] = sourceData[size][0]; + return alg; + } + }, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, digestedData[alg][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + size + ' source data and altered buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + return crypto.subtle.digest(alg, buffer).then(function (result) { + // Alter the buffer after calling digest buffer[0] = ~buffer[0]; - } - assert_true( - equalBuffers(result, digestedData[alg][size]), - 'digest matches expected' - ); - }); - }, alg + ' with ' + size + ' source data and altered buffer after call'); + assert_true( + equalBuffers(result, digestedData[alg][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + size + ' source data and altered buffer after call'); + } }); }); diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js index d93b60f8b87569..b157a94a0dc4fb 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js @@ -35,6 +35,38 @@ function run_test() { all_promises.push(promise); }); + // Check for successful encryption even if the buffer is changed while calling encrypt. + passingVectors.forEach(function(vector) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var promise = importVectorKey(vector, ["encrypt", "decrypt"]) + .then(function(vector) { + promise_test(function(test) { + var operation = subtle.encrypt({ + ...vector.algorithm, + get name() { + plaintext[0] = vector.plaintext[0]; + return vector.algorithm.name; + } + }, vector.key, plaintext) + .then(function(result) { + assert_true(equalBuffers(result, vector.result), "Should return expected result"); + }, function(err) { + assert_unreached("encrypt error for test " + vector.name + ": " + err.message); + }); + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested encryption + promise_test(function(test) { + assert_unreached("importKey failed for " + vector.name); + }, "importKey step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful encryption even if the buffer is changed after calling encrypt. passingVectors.forEach(function(vector) { var plaintext = copyBuffer(vector.plaintext); @@ -49,13 +81,13 @@ function run_test() { }); plaintext[0] = 255 - plaintext[0]; return operation; - }, vector.name + " with altered plaintext"); + }, vector.name + " with altered plaintext after call"); }, function(err) { // We need a failed test if the importVectorKey operation fails, so // we know we never tested encryption promise_test(function(test) { assert_unreached("importKey failed for " + vector.name); - }, "importKey step: " + vector.name + " with altered plaintext"); + }, "importKey step: " + vector.name + " with altered plaintext after call"); }); all_promises.push(promise); @@ -84,7 +116,39 @@ function run_test() { all_promises.push(promise); }); - // Check for successful decryption even if ciphertext is altered. + // Check for successful decryption even if ciphertext is altered while calling encrypt. + passingVectors.forEach(function(vector) { + var ciphertext = copyBuffer(vector.result); + ciphertext[0] = 255 - ciphertext[0]; + var promise = importVectorKey(vector, ["encrypt", "decrypt"]) + .then(function(vector) { + promise_test(function(test) { + var operation = subtle.decrypt({ + ...vector.algorithm, + get name() { + ciphertext[0] = vector.result[0]; + return vector.algorithm.name; + } + }, vector.key, ciphertext) + .then(function(result) { + assert_true(equalBuffers(result, vector.plaintext), "Should return expected result"); + }, function(err) { + assert_unreached("decrypt error for test " + vector.name + ": " + err.message); + }); + return operation; + }, vector.name + " decryption with altered ciphertext during call"); + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested encryption + promise_test(function(test) { + assert_unreached("importKey failed for " + vector.name); + }, "importKey step for decryption: " + vector.name + " with altered ciphertext during call"); + }); + + all_promises.push(promise); + }); + + // Check for successful decryption even if ciphertext is altered after calling encrypt. passingVectors.forEach(function(vector) { var ciphertext = copyBuffer(vector.result); var promise = importVectorKey(vector, ["encrypt", "decrypt"]) @@ -98,13 +162,13 @@ function run_test() { }); ciphertext[0] = 255 - ciphertext[0]; return operation; - }, vector.name + " decryption with altered ciphertext"); + }, vector.name + " decryption with altered ciphertext after call"); }, function(err) { // We need a failed test if the importVectorKey operation fails, so // we know we never tested encryption promise_test(function(test) { assert_unreached("importKey failed for " + vector.name); - }, "importKey step for decryption: " + vector.name + " with altered ciphertext"); + }, "importKey step for decryption: " + vector.name + " with altered ciphertext after call"); }); all_promises.push(promise); diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/rsa.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/rsa.js index 5eae06e474564a..76c90809783205 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/rsa.js +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/rsa.js @@ -40,6 +40,44 @@ function run_test() { all_promises.push(promise); }); + // Test decryption with an altered buffer during call + passingVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"]) + .then(function(vectors) { + // Get a one byte longer plaintext to encrypt + if (!("ciphertext" in vector)) { + return; + } + + promise_test(function(test) { + var ciphertext = copyBuffer(vector.ciphertext); + ciphertext[0] = 255 - ciphertext[0]; + var operation = subtle.decrypt({ + ...vector.algorithm, + get name() { + ciphertext[0] = vector.ciphertext[0]; + return vector.algorithm.name; + } + }, vector.privateKey, ciphertext) + .then(function(plaintext) { + assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); + }, function(err) { + assert_unreached("Decryption should not throw error " + vector.name + ": " + err.message + "'"); + }); + return operation; + }, vector.name + " decryption with altered ciphertext during call"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested encryption + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " decryption with altered ciphertext during call"); + }); + + all_promises.push(promise); + }); + // Test decryption with an altered buffer passingVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"]) @@ -59,14 +97,14 @@ function run_test() { }); ciphertext[0] = 255 - ciphertext[0]; return operation; - }, vector.name + " decryption with altered ciphertext"); + }, vector.name + " decryption with altered ciphertext after call"); }, function(err) { // We need a failed test if the importVectorKey operation fails, so // we know we never tested encryption promise_test(function(test) { assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " decryption with altered ciphertext"); + }, "importVectorKeys step: " + vector.name + " decryption with altered ciphertext after call"); }); all_promises.push(promise); @@ -125,6 +163,57 @@ function run_test() { }); + // Check for successful encryption even if plaintext is altered during call. + passingVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"]) + .then(function(vectors) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle.encrypt({ + ...vector.algorithm, + get name() { + plaintext[0] = vector.plaintext[0]; + return vector.algorithm.name; + } + }, vector.publicKey, plaintext) + .then(function(ciphertext) { + assert_equals(ciphertext.byteLength * 8, vector.privateKey.algorithm.modulusLength, "Ciphertext length matches modulus length"); + // Can we get the original plaintext back via decrypt? + return subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext) + .then(function(result) { + assert_true(equalBuffers(result, vector.plaintext), "Round trip returns original plaintext"); + return ciphertext; + }, function(err) { + assert_unreached("decrypt error for test " + vector.name + ": " + err.message + "'"); + }); + }) + .then(function(priorCiphertext) { + // Will a second encrypt give us different ciphertext, as it should? + return subtle.encrypt(vector.algorithm, vector.publicKey, vector.plaintext) + .then(function(ciphertext) { + assert_false(equalBuffers(priorCiphertext, ciphertext), "Two encrypts give different results") + }, function(err) { + assert_unreached("second time encrypt error for test " + vector.name + ": '" + err.message + "'"); + }); + }, function(err) { + assert_unreached("decrypt error for test " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested encryption + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful encryption even if plaintext is altered after call. passingVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["encrypt"], ["decrypt"]) @@ -157,14 +246,14 @@ function run_test() { plaintext[0] = 255 - plaintext[0]; return operation; - }, vector.name + " with altered plaintext"); + }, vector.name + " with altered plaintext after call"); }, function(err) { // We need a failed test if the importVectorKey operation fails, so // we know we never tested encryption promise_test(function(test) { assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); }); all_promises.push(promise); diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js index 6bf662adcc547f..9b47868fe32bfb 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js @@ -39,6 +39,38 @@ function run_test() { all_promises.push(promise); }); + // Test verification with an altered buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var algorithm = { + hash: vector.hashName, + get name() { + signature[0] = vector.signature[0]; + return vector.algorithmName; + } + }; + var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with altered signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); + }); + + all_promises.push(promise); + }); + // Test verification with an altered buffer after call testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify"], ["sign"]) @@ -65,6 +97,38 @@ function run_test() { all_promises.push(promise); }); + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var algorithm = { + hash: vector.hashName, + get name() { + plaintext[0] = vector.plaintext[0]; + return vector.algorithmName; + } + }; + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful verification even if plaintext is altered after call. testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify"], ["sign"]) diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/eddsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/eddsa.js index 4024674e3c3d7f..4bf1887b2ae9bb 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/eddsa.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/eddsa.js @@ -23,6 +23,27 @@ function run_test(algorithmName) { assert_true(isVerified, "Signature verified"); }, vector.name + " verification"); + // Test verification with an altered buffer during call + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + isVerified = await subtle.verify({ + get name() { + signature[0] = vector.signature[0]; + return vector.algorithmName; + } + }, key, signature, vector.data); + } 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 + "'"); + }; + assert_true(isVerified, "Signature verified"); + }, vector.name + " verification with altered signature during call"); + // Test verification with an altered buffer after call promise_test(async() => { let isVerified = false; @@ -41,6 +62,27 @@ function run_test(algorithmName) { assert_true(isVerified, "Signature verified"); }, vector.name + " verification with altered signature after call"); + // Check for successful verification even if data is altered during call. + promise_test(async() => { + let isVerified = false; + let key; + try { + key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); + var data = copyBuffer(vector.data); + data[0] = 255 - data[0]; + isVerified = await subtle.verify({ + get name() { + data[0] = vector.data[0]; + return vector.algorithmName; + } + }, key, vector.signature, data); + } 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 + "'"); + }; + assert_true(isVerified, "Signature verified"); + }, vector.name + " with altered data during call"); + // Check for successful verification even if data is altered after call. promise_test(async() => { let isVerified = false; diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.js index f5e2ad2769cdd8..dff8c994d83de0 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/hmac.js @@ -37,6 +37,37 @@ function run_test() { all_promises.push(promise); }); + // Test verification with an altered buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var operation = subtle.verify({ + hash: vector.hash, + get name() { + signature[0] = vector.signature[0]; + return "HMAC"; + } + }, vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature is not verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with altered signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); + }); + + all_promises.push(promise); + }); + // Test verification with an altered buffer after call testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) @@ -62,6 +93,37 @@ function run_test() { all_promises.push(promise); }); + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle.verify({ + hash: vector.hash, + get name() { + plaintext[0] = vector.plaintext[0]; + return "HMAC"; + } + }, vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful verification even if plaintext is altered after call. testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) @@ -81,7 +143,7 @@ function run_test() { }, function(err) { promise_test(function(test) { assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); }); all_promises.push(promise); diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.js index 037dbec1097ddc..57c9dc6f34790a 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.js @@ -40,6 +40,41 @@ function run_test() { all_promises.push(promise); }); + // Test verification with an altered buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var algorithmParams = { + length: vector.length, + get name() { + signature[0] = vector.signature[0]; + return vector.algorithm; + } + }; + if (vector.customization !== undefined) { + algorithmParams.customization = vector.customization; + } + var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature is not verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with altered signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); + }); + + all_promises.push(promise); + }); + // Test verification with an altered buffer after call testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) @@ -69,6 +104,41 @@ function run_test() { all_promises.push(promise); }); + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var algorithmParams = { + length: vector.length, + get name() { + plaintext[0] = vector.plaintext[0]; + return vector.algorithm; + } + }; + if (vector.customization !== undefined) { + algorithmParams.customization = vector.customization; + } + var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful verification even if plaintext is altered after call. testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify", "sign"]) @@ -92,7 +162,7 @@ function run_test() { }, function(err) { promise_test(function(test) { assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); }); all_promises.push(promise); diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js index e31d36362b0dc9..88143a33879ed7 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js @@ -55,6 +55,61 @@ function run_test() { all_promises.push(promise); }); + // Test verification with an altered buffer during call + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + promise_test(function (test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var operation = subtle + .verify( + { + get name() { + signature[0] = vector.signature[0]; + return vector.algorithmName; + }, + }, + vector.publicKey, + signature, + vector.data + ) + .then( + function (is_verified) { + assert_true(is_verified, 'Signature verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification with altered signature during call'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verification with altered signature during call'); + } + ); + + all_promises.push(promise); + }); + // Test verification with an altered buffer after call testVectors.forEach(function (vector) { var promise = importVectorKeys(vector, ['verify'], ['sign']).then( @@ -101,6 +156,61 @@ function run_test() { all_promises.push(promise); }); + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + promise_test(function (test) { + var plaintext = copyBuffer(vector.data); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle + .verify( + { + get name() { + plaintext[0] = vector.data[0]; + return vector.algorithmName; + }, + }, + vector.publicKey, + vector.signature, + plaintext + ) + .then( + function (is_verified) { + assert_true(is_verified, 'Signature verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' with altered plaintext during call'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' with altered plaintext during call'); + } + ); + + all_promises.push(promise); + }); + // Check for successful verification even if plaintext is altered after call. testVectors.forEach(function (vector) { var promise = importVectorKeys(vector, ['verify'], ['sign']).then( diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/rsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/rsa.js index 5abadd3d4b8629..f808714cfb11d4 100644 --- a/test/fixtures/wpt/WebCryptoAPI/sign_verify/rsa.js +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/rsa.js @@ -37,6 +37,37 @@ function run_test() { all_promises.push(promise); }); + // Test verification with an altered buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var operation = subtle.verify({ + ...vector.algorithm, + get name() { + signature[0] = vector.signature[0]; + return vector.algorithm.name; + } + }, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with altered signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); + }); + + all_promises.push(promise); + }); + // Test verification with an altered buffer after call testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify"], ["sign"]) @@ -62,6 +93,37 @@ function run_test() { all_promises.push(promise); }); + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle.verify({ + ...vector.algorithm, + get name() { + plaintext[0] = vector.plaintext[0]; + return vector.algorithm.name; + } + }, vector.publicKey, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + // Check for successful verification even if plaintext is altered after call. testVectors.forEach(function(vector) { var promise = importVectorKeys(vector, ["verify"], ["sign"]) diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 50173e71b1b9d7..db5222f4fefdca 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -96,7 +96,7 @@ "path": "web-locks" }, "WebCryptoAPI": { - "commit": "7cbe7e8ed962eac692ba4ad2e6ce3b9daafb65c0", + "commit": "42e47329fdc92c80d58c2816eb66cb2cf2b32a89", "path": "WebCryptoAPI" }, "webidl": {