Automatic update from web-platform-tests WebCryptoAPI: Refactor helpers to a shared helper file (#58555) -- wpt-commits: 15f291dc857ea27aa701f61fa21f54505ee2373d wpt-pr: 58555
1039 lines
32 KiB
JavaScript
1039 lines
32 KiB
JavaScript
function run_test() {
|
|
setup({ explicit_done: true });
|
|
|
|
var subtle = self.crypto.subtle; // Change to test prefixed implementations
|
|
|
|
// When are all these tests really done? When all the promises they use have resolved.
|
|
var all_promises = [];
|
|
|
|
// Source file [algorithm_name]_vectors.js provides the getTestVectors method
|
|
// for the algorithm that drives these tests.
|
|
var testVectors = getTestVectors();
|
|
var invalidTestVectors = getInvalidTestVectors();
|
|
|
|
// Test verification first, because signing tests rely on that working
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, vector.publicKey, vector.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');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' + vector.name + ' verification');
|
|
}
|
|
);
|
|
|
|
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(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var signature = copyBuffer(vector.signature);
|
|
var operation = subtle
|
|
.verify(algorithm, 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 +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
signature[0] = 255 - signature[0];
|
|
return operation;
|
|
}, vector.name + ' verification with altered signature after 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 after call');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification with a transferred 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);
|
|
var operation = subtle
|
|
.verify(
|
|
{
|
|
get name() {
|
|
signature.buffer.transfer();
|
|
return vector.algorithmName;
|
|
},
|
|
},
|
|
vector.publicKey,
|
|
signature,
|
|
vector.data
|
|
)
|
|
.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;
|
|
}, vector.name + ' verification with transferred 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 transferred signature during call');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification with a transferred buffer after call
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var signature = copyBuffer(vector.signature);
|
|
var operation = subtle
|
|
.verify(algorithm, 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 +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
signature.buffer.transfer();
|
|
return operation;
|
|
}, vector.name + ' verification with transferred signature after call');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' verification with transferred signature after call');
|
|
}
|
|
);
|
|
|
|
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(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var plaintext = copyBuffer(vector.data);
|
|
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 +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
plaintext[0] = 255 - plaintext[0];
|
|
return operation;
|
|
}, vector.name + ' with altered plaintext after call');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' with altered plaintext after call');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for failed verification if plaintext is transferred during call.
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
promise_test(function (test) {
|
|
var plaintext = copyBuffer(vector.data);
|
|
var operation = subtle
|
|
.verify(
|
|
{
|
|
get name() {
|
|
plaintext.buffer.transfer();
|
|
return vector.algorithmName;
|
|
},
|
|
},
|
|
vector.publicKey,
|
|
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;
|
|
}, vector.name + ' with transferred plaintext during call');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' with transferred plaintext during call');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for successful verification even if plaintext is transferred after call.
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var plaintext = copyBuffer(vector.data);
|
|
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 +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
plaintext.buffer.transfer();
|
|
return operation;
|
|
}, vector.name + ' with transferred plaintext after call');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' with transferred plaintext after call');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for failures due to using privateKey to verify.
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
return subtle
|
|
.verify(algorithm, vector.privateKey, vector.signature, vector.data)
|
|
.then(
|
|
function (plaintext) {
|
|
assert_unreached(
|
|
'Should have thrown error for using privateKey to verify in ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
},
|
|
function (err) {
|
|
assert_equals(
|
|
err.name,
|
|
'InvalidAccessError',
|
|
"Should throw InvalidAccessError instead of '" +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
}, vector.name + ' using privateKey to verify');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' using privateKey to verify');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for failures due to using publicKey to sign.
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
return subtle.sign(algorithm, vector.publicKey, vector.data).then(
|
|
function (signature) {
|
|
assert_unreached(
|
|
'Should have thrown error for using publicKey to sign in ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
},
|
|
function (err) {
|
|
assert_equals(
|
|
err.name,
|
|
'InvalidAccessError',
|
|
"Should throw InvalidAccessError instead of '" +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
}, vector.name + ' using publicKey to sign');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' using publicKey to sign');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for failures due to no "verify" usage.
|
|
testVectors.forEach(function (originalVector) {
|
|
var vector = Object.assign({}, originalVector);
|
|
|
|
var promise = importVectorKeys(vector, [], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
return subtle
|
|
.verify(algorithm, vector.publicKey, vector.signature, vector.data)
|
|
.then(
|
|
function (plaintext) {
|
|
assert_unreached(
|
|
'Should have thrown error for no verify usage in ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
},
|
|
function (err) {
|
|
assert_equals(
|
|
err.name,
|
|
'InvalidAccessError',
|
|
"Should throw InvalidAccessError instead of '" +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
}, vector.name + ' no verify usage');
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' + vector.name + ' no verify usage');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Check for successful signing and verification.
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
return subtle.sign(algorithm, vector.privateKey, vector.data).then(
|
|
function (signature) {
|
|
// Can we verify the signature?
|
|
return subtle
|
|
.verify(algorithm, vector.publicKey, signature, vector.data)
|
|
.then(
|
|
function (is_verified) {
|
|
assert_true(is_verified, 'Round trip verification works');
|
|
return signature;
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'verify error for test ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'sign error for test ' + vector.name + ": '" + err.message + "'"
|
|
);
|
|
}
|
|
);
|
|
}, vector.name + ' round trip');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested signing or verifying
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' + vector.name + ' round trip');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test signing with the wrong algorithm
|
|
testVectors.forEach(function (vector) {
|
|
// Want to get the key for the wrong algorithm
|
|
var promise = subtle
|
|
.generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify'])
|
|
.then(
|
|
function (wrongKey) {
|
|
var algorithm = vector.algorithmName;
|
|
return importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.sign(algorithm, wrongKey, vector.data)
|
|
.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;
|
|
}, vector.name + ' signing with wrong algorithm name');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' signing with wrong algorithm name');
|
|
}
|
|
);
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'Generate wrong key for test ' +
|
|
vector.name +
|
|
" failed: '" +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}, 'generate wrong key step: ' +
|
|
vector.name +
|
|
' signing with wrong algorithm name');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification with the wrong algorithm
|
|
testVectors.forEach(function (vector) {
|
|
// Want to get the key for the wrong algorithm
|
|
var promise = subtle
|
|
.generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify'])
|
|
.then(
|
|
function (wrongKey) {
|
|
return importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, wrongKey, vector.signature, vector.data)
|
|
.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;
|
|
}, vector.name + ' verifying with wrong algorithm name');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' verifying with wrong algorithm name');
|
|
}
|
|
);
|
|
},
|
|
function (err) {
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'Generate wrong key for test ' +
|
|
vector.name +
|
|
" failed: '" +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}, 'generate wrong key step: ' +
|
|
vector.name +
|
|
' verifying with wrong algorithm name');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification fails with wrong signature
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
var signature = copyBuffer(vector.signature);
|
|
signature[0] = 255 - signature[0];
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, vector.publicKey, signature, vector.data)
|
|
.then(
|
|
function (is_verified) {
|
|
assert_false(is_verified, 'Signature NOT verified');
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'Verification should not throw error ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
return operation;
|
|
}, vector.name + ' verification failure due to altered signature');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' verification failure due to altered signature');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification fails with short (odd length) signature
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
var signature = vector.signature.slice(1); // Skip the first byte
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, vector.publicKey, signature, vector.data)
|
|
.then(
|
|
function (is_verified) {
|
|
assert_false(is_verified, 'Signature NOT verified');
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'Verification should not throw error ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
return operation;
|
|
}, vector.name + ' verification failure due to shortened signature');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' verification failure due to shortened signature');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test verification fails with wrong plaintext
|
|
testVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
var plaintext = copyBuffer(vector.data);
|
|
plaintext[0] = 255 - plaintext[0];
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, vector.publicKey, vector.signature, plaintext)
|
|
.then(
|
|
function (is_verified) {
|
|
assert_false(is_verified, 'Signature NOT verified');
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'Verification should not throw error ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
return operation;
|
|
}, vector.name + ' verification failure due to altered plaintext');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' +
|
|
vector.name +
|
|
' verification failure due to altered plaintext');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
// Test invalid signatures
|
|
invalidTestVectors.forEach(function (vector) {
|
|
var promise = importVectorKeys(vector, ['verify'], ['sign']).then(
|
|
function (vectors) {
|
|
var algorithm = vector.algorithmName;
|
|
promise_test(function (test) {
|
|
var operation = subtle
|
|
.verify(algorithm, vector.publicKey, vector.signature, vector.data)
|
|
.then(
|
|
function (is_verified) {
|
|
assert_false(is_verified, 'Signature unexpectedly verified');
|
|
},
|
|
function (err) {
|
|
assert_unreached(
|
|
'Verification should not throw error ' +
|
|
vector.name +
|
|
': ' +
|
|
err.message +
|
|
"'"
|
|
);
|
|
}
|
|
);
|
|
|
|
return operation;
|
|
}, vector.name + ' verification');
|
|
},
|
|
function (err) {
|
|
// We need a failed test if the importVectorKey operation fails, so
|
|
// we know we never tested verification.
|
|
promise_test(function (test) {
|
|
assert_unreached(
|
|
'importVectorKeys failed for ' +
|
|
vector.name +
|
|
". Message: ''" +
|
|
err.message +
|
|
"''"
|
|
);
|
|
}, 'importVectorKeys step: ' + vector.name + ' verification');
|
|
}
|
|
);
|
|
|
|
all_promises.push(promise);
|
|
});
|
|
|
|
promise_test(function () {
|
|
return Promise.all(all_promises)
|
|
.then(function () {
|
|
done();
|
|
})
|
|
.catch(function () {
|
|
done();
|
|
});
|
|
}, 'setup');
|
|
|
|
// A test vector has all needed fields for signing and verifying, EXCEPT that the
|
|
// key field may be null. This function replaces that null with the Correct
|
|
// CryptoKey object.
|
|
//
|
|
// Returns a Promise that yields an updated vector on success.
|
|
function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) {
|
|
var publicPromise, privatePromise;
|
|
|
|
if (vector.publicKey !== null) {
|
|
publicPromise = new Promise(function (resolve, reject) {
|
|
resolve(vector);
|
|
});
|
|
} else {
|
|
publicPromise = subtle
|
|
.importKey(
|
|
vector.publicKeyFormat,
|
|
vector.publicKeyBuffer,
|
|
{ name: vector.algorithmName },
|
|
false,
|
|
publicKeyUsages
|
|
)
|
|
.then(function (key) {
|
|
vector.publicKey = key;
|
|
return vector;
|
|
}); // Returns a copy of the sourceBuffer it is sent.
|
|
}
|
|
|
|
if (vector.privateKey !== null) {
|
|
privatePromise = new Promise(function (resolve, reject) {
|
|
resolve(vector);
|
|
});
|
|
} else {
|
|
privatePromise = subtle
|
|
.importKey(
|
|
vector.privateKeyFormat,
|
|
vector.privateKeyBuffer,
|
|
{ name: vector.algorithmName },
|
|
false,
|
|
privateKeyUsages
|
|
)
|
|
.then(function (key) {
|
|
vector.privateKey = key;
|
|
return vector;
|
|
});
|
|
}
|
|
|
|
return Promise.all([publicPromise, privatePromise]);
|
|
}
|
|
|
|
return;
|
|
}
|