233 lines
12 KiB
JavaScript
233 lines
12 KiB
JavaScript
|
|
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<source.byteLength; i++) {
|
|
copy[i] = source[i];
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
return;
|
|
}
|