function run_test(algorithmName) { var subtle = self.crypto.subtle; // Change to test prefixed implementations // Source file [algorithm_name]_vectors.js provides the getTestVectors method // for the algorithm that drives these tests. var testVectors = getTestVectors(algorithmName); testVectors.forEach(function(vector) { var algorithm = {name: vector.algorithmName}; // Test verification first, because signing tests rely on that working promise_test(async() => { let isVerified = false; let key; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); isVerified = await subtle.verify(algorithm, key, vector.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"); // Test verification with an altered buffer after 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); [isVerified] = await Promise.all([ subtle.verify(algorithm, key, signature, vector.data), signature[0] = 255 - signature[0] ]); } 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 after call"); // Check for successful verification even if data is altered after 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); [isVerified] = await Promise.all([ subtle.verify(algorithm, key, vector.signature, data), data[0] = 255 - data[0] ]); } 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 after call"); // Check for failures due to using privateKey to verify. promise_test(async() => { let isVerified = false; let key; try { key = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name); } catch (err) { if (err instanceof AssertionError) throw err; assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); }; assert_false(isVerified, "Signature verified"); }, vector.name + " using privateKey to verify"); // Check for failures due to using publicKey to sign. promise_test(async() => { let isVerified = false; let key; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); let signature = await subtle.sign(algorithm, key, vector.data); assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name); } catch (err) { if (err instanceof AssertionError) throw err; assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); }; }, vector.name + " using publicKey to sign"); // Check for failures due to no "verify" usage. promise_test(async() => { let isVerified = false; let key; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, []); isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) assert_unreached("Should have thrown error for no verify usage in " + vector.name); } catch (err) { if (err instanceof AssertionError) throw err; assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); }; assert_false(isVerified, "Signature verified"); }, vector.name + " no verify usage"); // Check for successful signing and verification. var algorithm = {name: vector.algorithmName}; promise_test(async() => { let isVerified = false; let privateKey, publicKey; let signature; 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); 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 + "''"); assert_false(signature === undefined, "sign error for test " + vector.name + ": '" + err.message + "'"); assert_unreached("verify error for test " + vector.name + ": " + err.message + "'"); }; assert_true(isVerified, "Round trip verification works"); }, vector.name + " round trip"); // Test signing with the wrong algorithm var algorithm = {name: vector.algorithmName}; promise_test(async() => { let wrongKey; try { wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) let signature = await subtle.sign(algorithm, wrongKey, vector.data); assert_unreached("Signing should not have succeeded for " + vector.name); } catch (err) { if (err instanceof AssertionError) throw err; assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); }; }, vector.name + " signing with wrong algorithm name"); // Test verification with the wrong algorithm var algorithm = {name: vector.algorithmName}; promise_test(async() => { let wrongKey; try { wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) let isVerified = await subtle.verify(algorithm, wrongKey, vector.signature, vector.data) assert_unreached("Verifying should not have succeeded for " + vector.name); } catch (err) { if (err instanceof AssertionError) throw err; assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); }; }, vector.name + " verifying with wrong algorithm name"); // Test verification fails with wrong signature var algorithm = {name: vector.algorithmName}; promise_test(async() => { let key; let isVerified = true; var signature = copyBuffer(vector.signature); signature[0] = 255 - signature[0]; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); isVerified = await subtle.verify(algorithm, 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_false(isVerified, "Signature verified"); }, vector.name + " verification failure due to altered signature"); // Test verification fails with short (odd length) signature promise_test(async() => { let key; let isVerified = true; var signature = vector.signature.slice(1); // Skip the first byte try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); isVerified = await subtle.verify(algorithm, 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_false(isVerified, "Signature verified"); }, vector.name + " verification failure due to shortened signature"); // Test verification fails with wrong data promise_test(async() => { let key; let isVerified = true; var data = copyBuffer(vector.data); data[0] = 255 - data[0]; try { key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); isVerified = await subtle.verify(algorithm, 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_false(isVerified, "Signature verified"); }, vector.name + " verification failure due to altered data"); // Test that generated keys are valid for signing and verifying. promise_test(async() => { let key = await subtle.generateKey(algorithm, false, ["sign", "verify"]); let signature = await subtle.sign(algorithm, key.privateKey, vector.data); let isVerified = await subtle.verify(algorithm, key.publicKey, signature, vector.data); assert_true(isVerified, "Verificaton failed."); }, "Sign and verify using generated " + vector.algorithmName + " keys."); }); // Returns a copy of the sourceBuffer it is sent. function copyBuffer(sourceBuffer) { var source = new Uint8Array(sourceBuffer); var copy = new Uint8Array(sourceBuffer.byteLength) for (var i=0; i