mirror of
https://github.com/servo/servo.git
synced 2025-08-10 16:05:43 +01:00
Update web-platform-tests to revision dc5cbf088edcdb266541d4e5a76149a2c6e716a0
This commit is contained in:
parent
1d40075f03
commit
079092dfea
2381 changed files with 90360 additions and 17722 deletions
479
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/ecdsa.js
Normal file
479
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/ecdsa.js
Normal file
|
@ -0,0 +1,479 @@
|
|||
|
||||
function run_test() {
|
||||
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();
|
||||
|
||||
// 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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, vector.publicKey, vector.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");
|
||||
|
||||
}, 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 after call
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
var algorithm = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
var signature = copyBuffer(vector.signature);
|
||||
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 + "'");
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
// 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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
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 failures due to using privateKey to verify.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
var algorithm = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(algorithm, vector.privateKey, vector.signature, vector.plaintext)
|
||||
.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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(algorithm, vector.publicKey, vector.plaintext)
|
||||
.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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
// Can we verify the signature?
|
||||
return subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext)
|
||||
.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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
return importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.sign(algorithm, wrongKey, 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;
|
||||
}, 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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, wrongKey, 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;
|
||||
}, 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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
var signature = copyBuffer(vector.signature);
|
||||
signature[0] = 255 - signature[0];
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.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 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 wrong hash
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
var hashName = "SHA-1";
|
||||
if (vector.hashName === "SHA-1") {
|
||||
hashName = "SHA-256"
|
||||
}
|
||||
var algorithm = {name: vector.algorithmName, hash: hashName};
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.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 wrong hash");
|
||||
|
||||
}, 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 wrong hash");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Test verification fails with bad hash name
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
// use the wrong name for the hash
|
||||
var hashName = vector.hashName.substring(0, 3) + vector.hashName.substring(4);
|
||||
var algorithm = {name: vector.algorithmName, hash: hashName};
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_unreached("Verification should throw an error");
|
||||
}, function(err) {
|
||||
assert_equals(err.name, "NotSupportedError", "Correctly throws NotSupportedError for illegal hash name")
|
||||
});
|
||||
|
||||
return operation;
|
||||
}, vector.name + " verification failure due to bad hash 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 + " verification failure due to bad hash name");
|
||||
});
|
||||
|
||||
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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
var signature = vector.signature.slice(1); // Skip the first byte
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.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 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 = {name: vector.algorithmName, hash: vector.hashName};
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
return;
|
||||
|
||||
// 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, namedCurve: vector.namedCurve}, 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, namedCurve: vector.namedCurve}, false, privateKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.privateKey = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([publicPromise, privatePromise]);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("ecdsa_vectors.js");
|
||||
importScripts("ecdsa.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
// ecdsa_vectors.js
|
||||
|
||||
// Data for testing ECDSA with every curve currently in the WebCryptoAPI recommendation.
|
||||
|
||||
// The following function returns an array of test vectors
|
||||
// for the subtleCrypto encrypt method.
|
||||
//
|
||||
// Each test vector has the following fields:
|
||||
// name - a unique name for this vector
|
||||
// publicKeyBuffer - an arrayBuffer with the key data
|
||||
// publicKeyFormat - "spki" "jwk"
|
||||
// publicKey - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// privateKeyBuffer - an arrayBuffer with the key data
|
||||
// privateKeyFormat - "pkcs8" or "jwk"
|
||||
// privateKey - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// algorithmName - the name of the AlgorithmIdentifier parameter to provide to encrypt
|
||||
// namedCurve - the curve used
|
||||
// hashName - the hash function to sign with
|
||||
// plaintext - the text to encrypt
|
||||
// signature - the expected signature
|
||||
function getTestVectors() {
|
||||
var pkcs8 = {
|
||||
"P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 230, 238, 207, 158, 98, 108, 202, 142, 24, 7, 155, 146, 197, 238, 38, 158, 84, 202, 18, 142, 175, 212, 137, 71, 255, 81, 171, 160, 10, 192, 229, 214, 161, 68, 3, 66, 0, 4, 10, 5, 30, 56, 111, 103, 196, 166, 225, 229, 203, 238, 125, 55, 116, 91, 88, 142, 190, 114, 15, 117, 89, 22, 40, 111, 150, 41, 105, 122, 57, 23, 17, 216, 106, 234, 201, 103, 8, 210, 58, 38, 35, 216, 198, 237, 187, 84, 217, 164, 63, 100, 6, 105, 49, 128, 15, 53, 29, 158, 117, 235, 238, 30]),
|
||||
"P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 2, 169, 160, 216, 153, 239, 168, 126, 117, 100, 17, 9, 7, 233, 216, 44, 33, 189, 98, 101, 163, 122, 189, 154, 111, 219, 15, 128, 236, 132, 77, 211, 161, 66, 83, 32, 214, 125, 220, 48, 245, 219, 116, 239, 185, 162, 230, 97, 161, 100, 3, 98, 0, 4, 29, 49, 157, 105, 45, 202, 95, 87, 84, 186, 123, 50, 193, 22, 66, 198, 216, 210, 180, 251, 130, 73, 195, 242, 20, 215, 30, 144, 181, 37, 41, 102, 217, 127, 123, 235, 31, 170, 177, 228, 243, 226, 96, 85, 73, 194, 238, 219, 82, 3, 41, 179, 190, 166, 181, 229, 86, 36, 161, 81, 80, 161, 105, 102, 99, 95, 25, 22, 239, 4, 221, 117, 142, 105, 64, 157, 6, 51, 203, 75, 37, 153, 65, 121, 178, 42, 118, 156, 116, 52, 54, 145, 14, 121, 153, 81]),
|
||||
"P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 83, 62, 97, 143, 152, 234, 209, 181, 19, 236, 136, 120, 200, 130, 13, 55, 122, 54, 216, 240, 63, 43, 160, 70, 201, 49, 130, 90, 61, 53, 135, 48, 192, 178, 96, 51, 219, 183, 247, 228, 163, 212, 67, 74, 3, 94, 36, 183, 7, 249, 18, 71, 102, 23, 110, 26, 240, 184, 93, 242, 46, 170, 186, 156, 37, 161, 129, 137, 3, 129, 134, 0, 4, 0, 166, 222, 236, 251, 72, 145, 23, 241, 228, 28, 196, 160, 100, 7, 61, 134, 115, 8, 110, 81, 219, 37, 8, 110, 141, 183, 100, 212, 239, 246, 10, 173, 99, 88, 253, 207, 150, 122, 198, 132, 89, 39, 94, 42, 128, 79, 142, 238, 183, 228, 196, 40, 75, 20, 81, 192, 165, 234, 118, 254, 112, 7, 172, 5, 71, 1, 197, 237, 218, 249, 168, 158, 124, 79, 220, 201, 36, 199, 55, 216, 245, 133, 218, 151, 3, 169, 84, 194, 59, 231, 193, 74, 175, 166, 102, 84, 178, 86, 119, 10, 147, 142, 127, 38, 231, 0, 198, 3, 147, 28, 123, 208, 189, 181, 208, 99, 44, 125, 30, 171, 70, 111, 9, 217, 118, 194, 74, 50, 62, 27, 124])
|
||||
};
|
||||
|
||||
var spki = {
|
||||
"P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 10, 5, 30, 56, 111, 103, 196, 166, 225, 229, 203, 238, 125, 55, 116, 91, 88, 142, 190, 114, 15, 117, 89, 22, 40, 111, 150, 41, 105, 122, 57, 23, 17, 216, 106, 234, 201, 103, 8, 210, 58, 38, 35, 216, 198, 237, 187, 84, 217, 164, 63, 100, 6, 105, 49, 128, 15, 53, 29, 158, 117, 235, 238, 30]),
|
||||
"P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 29, 49, 157, 105, 45, 202, 95, 87, 84, 186, 123, 50, 193, 22, 66, 198, 216, 210, 180, 251, 130, 73, 195, 242, 20, 215, 30, 144, 181, 37, 41, 102, 217, 127, 123, 235, 31, 170, 177, 228, 243, 226, 96, 85, 73, 194, 238, 219, 82, 3, 41, 179, 190, 166, 181, 229, 86, 36, 161, 81, 80, 161, 105, 102, 99, 95, 25, 22, 239, 4, 221, 117, 142, 105, 64, 157, 6, 51, 203, 75, 37, 153, 65, 121, 178, 42, 118, 156, 116, 52, 54, 145, 14, 121, 153, 81]),
|
||||
"P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 166, 222, 236, 251, 72, 145, 23, 241, 228, 28, 196, 160, 100, 7, 61, 134, 115, 8, 110, 81, 219, 37, 8, 110, 141, 183, 100, 212, 239, 246, 10, 173, 99, 88, 253, 207, 150, 122, 198, 132, 89, 39, 94, 42, 128, 79, 142, 238, 183, 228, 196, 40, 75, 20, 81, 192, 165, 234, 118, 254, 112, 7, 172, 5, 71, 1, 197, 237, 218, 249, 168, 158, 124, 79, 220, 201, 36, 199, 55, 216, 245, 133, 218, 151, 3, 169, 84, 194, 59, 231, 193, 74, 175, 166, 102, 84, 178, 86, 119, 10, 147, 142, 127, 38, 231, 0, 198, 3, 147, 28, 123, 208, 189, 181, 208, 99, 44, 125, 30, 171, 70, 111, 9, 217, 118, 194, 74, 50, 62, 27, 124])
|
||||
};
|
||||
|
||||
// plaintext
|
||||
var plaintext = new Uint8Array([95, 77, 186, 79, 50, 12, 12, 232, 118, 114, 90, 252, 229, 251, 210, 91, 248, 62, 90, 113, 37, 160, 140, 175, 231, 60, 62, 186, 196, 33, 119, 157, 249, 213, 93, 24, 12, 58, 233, 148, 38, 69, 225, 216, 47, 238, 140, 157, 41, 75, 60, 177, 160, 138, 153, 49, 32, 27, 60, 14, 129, 252, 71, 202, 207, 131, 21, 162, 175, 102, 50, 65, 19, 195, 182, 98, 48, 195, 70, 8, 196, 244, 89, 54, 52, 206, 2, 178, 103, 54, 34, 119, 240, 168, 64, 202, 116, 188, 61, 26, 98, 54, 149, 44, 94, 215, 170, 248, 168, 254, 203, 221, 250, 117, 132, 230, 151, 140, 234, 93, 42, 91, 159, 183, 241, 180, 140, 139, 11, 229, 138, 48, 82, 2, 117, 77, 131, 118, 16, 115, 116, 121, 60, 240, 38, 170, 238, 83, 0, 114, 125, 131, 108, 215, 30, 113, 179, 69, 221, 178, 228, 68, 70, 255, 197, 185, 1, 99, 84, 19, 137, 13, 145, 14, 163, 128, 152, 74, 144, 25, 16, 49, 50, 63, 22, 219, 204, 157, 107, 225, 104, 184, 72, 133, 56, 76, 160, 62, 18, 96, 10, 193, 194, 72, 2, 138, 243, 114, 108, 201, 52, 99, 136, 46, 168, 192, 42, 171]);
|
||||
|
||||
// For verification tests.
|
||||
var signatures = {
|
||||
"P-256": {
|
||||
"SHA-1": new Uint8Array([172, 224, 125, 170, 52, 83, 158, 179, 85, 149, 130, 217, 59, 201, 0, 251, 237, 196, 51, 243, 218, 231, 211, 136, 157, 249, 219, 16, 140, 178, 145, 16, 177, 104, 68, 179, 88, 49, 219, 184, 212, 202, 109, 248, 110, 64, 202, 129, 7, 173, 226, 88, 194, 69, 164, 158, 120, 120, 128, 3, 115, 14, 181, 197]),
|
||||
"SHA-256": new Uint8Array([83, 223, 63, 226, 42, 29, 106, 105, 225, 145, 197, 180, 118, 154, 109, 110, 66, 67, 47, 251, 53, 190, 203, 65, 207, 36, 19, 57, 49, 122, 124, 118, 59, 74, 222, 134, 42, 235, 180, 229, 134, 24, 205, 81, 171, 156, 100, 218, 127, 242, 126, 53, 27, 77, 249, 101, 157, 132, 244, 30, 67, 30, 64, 12]),
|
||||
"SHA-384": new Uint8Array([235, 111, 173, 249, 151, 252, 218, 129, 123, 117, 136, 26, 162, 115, 247, 110, 169, 145, 95, 189, 228, 98, 32, 82, 34, 94, 154, 197, 47, 83, 124, 137, 215, 71, 222, 247, 135, 22, 221, 238, 77, 247, 223, 194, 42, 158, 175, 224, 76, 182, 56, 138, 97, 196, 238, 109, 42, 102, 13, 71, 1, 43, 56, 92]),
|
||||
"SHA-512": new Uint8Array([74, 201, 175, 173, 69, 107, 160, 142, 203, 41, 225, 5, 73, 146, 6, 40, 93, 130, 129, 35, 156, 171, 190, 161, 12, 10, 234, 123, 7, 5, 112, 97, 57, 183, 15, 52, 94, 215, 79, 255, 175, 222, 66, 234, 253, 180, 62, 161, 7, 11, 249, 37, 118, 185, 13, 102, 67, 84, 101, 189, 73, 132, 110, 206])
|
||||
},
|
||||
"P-384": {
|
||||
"SHA-1": new Uint8Array([101, 254, 7, 14, 195, 234, 195, 82, 80, 208, 11, 158, 230, 219, 77, 45, 173, 213, 243, 187, 185, 196, 149, 200, 103, 29, 42, 13, 43, 153, 20, 159, 178, 79, 136, 175, 7, 78, 11, 144, 50, 104, 179, 208, 237, 95, 14, 20, 104, 87, 150, 178, 143, 227, 75, 45, 142, 220, 223, 16, 132, 91, 36, 207, 121, 179, 54, 39, 216, 189, 44, 129, 98, 28, 181, 30, 3, 12, 33, 164, 58, 187, 10, 135, 64, 250, 194, 111, 133, 34, 230, 131, 195, 103, 172, 150]),
|
||||
"SHA-256": new Uint8Array([75, 194, 223, 234, 59, 205, 164, 251, 180, 253, 146, 123, 3, 15, 155, 128, 177, 245, 210, 173, 155, 183, 170, 6, 41, 56, 105, 87, 113, 32, 178, 177, 208, 239, 17, 204, 217, 254, 208, 113, 74, 171, 54, 190, 246, 57, 40, 247, 132, 245, 60, 126, 9, 223, 147, 233, 179, 229, 176, 200, 131, 207, 114, 9, 81, 180, 254, 35, 130, 199, 132, 46, 220, 252, 212, 93, 149, 106, 114, 210, 154, 64, 48, 160, 56, 169, 0, 230, 247, 221, 133, 122, 86, 80, 211, 232]),
|
||||
"SHA-384": new Uint8Array([13, 217, 194, 199, 240, 182, 244, 217, 50, 130, 84, 169, 2, 232, 115, 116, 179, 192, 146, 25, 94, 107, 226, 26, 161, 166, 220, 216, 235, 166, 15, 123, 11, 56, 196, 0, 109, 250, 33, 70, 212, 233, 253, 35, 220, 51, 97, 121, 151, 64, 23, 73, 58, 31, 79, 116, 238, 207, 228, 85, 190, 61, 169, 237, 153, 100, 29, 129, 97, 13, 254, 180, 104, 182, 7, 218, 148, 29, 87, 20, 231, 181, 26, 238, 44, 69, 170, 14, 156, 77, 160, 33, 178, 55, 0, 144]),
|
||||
"SHA-512": new Uint8Array([114, 251, 219, 54, 159, 211, 76, 28, 84, 38, 77, 7, 244, 250, 205, 105, 176, 46, 66, 6, 248, 168, 187, 37, 155, 136, 42, 48, 92, 86, 253, 226, 211, 81, 7, 228, 147, 197, 60, 214, 180, 175, 11, 49, 48, 111, 77, 3, 253, 67, 207, 199, 98, 161, 3, 14, 23, 163, 215, 117, 69, 58, 18, 18, 177, 66, 159, 123, 61, 147, 6, 106, 95, 66, 161, 11, 19, 140, 209, 119, 220, 9, 97, 110, 130, 125, 89, 136, 34, 215, 141, 70, 39, 183, 84, 230])
|
||||
},
|
||||
"P-521": {
|
||||
"SHA-1": new Uint8Array([1, 120, 26, 23, 166, 14, 67, 18, 105, 96, 253, 57, 110, 18, 16, 145, 108, 33, 21, 202, 68, 40, 217, 104, 56, 156, 75, 70, 193, 85, 54, 116, 206, 147, 123, 142, 33, 112, 12, 230, 9, 50, 174, 15, 87, 92, 161, 135, 221, 89, 119, 32, 219, 131, 158, 177, 242, 12, 126, 51, 148, 120, 117, 89, 220, 213, 0, 32, 126, 87, 13, 245, 199, 228, 173, 159, 192, 165, 247, 32, 101, 233, 206, 28, 158, 61, 18, 202, 94, 109, 217, 244, 79, 225, 40, 86, 27, 117, 244, 34, 108, 79, 173, 242, 61, 131, 83, 108, 198, 105, 234, 64, 152, 227, 115, 182, 203, 145, 156, 139, 92, 252, 5, 5, 166, 125, 150, 178, 118, 164, 106, 61]),
|
||||
"SHA-256": new Uint8Array([1, 116, 219, 167, 123, 20, 215, 63, 102, 245, 113, 103, 134, 163, 229, 168, 215, 201, 49, 68, 94, 109, 50, 10, 146, 41, 217, 97, 216, 161, 179, 239, 209, 26, 94, 163, 60, 121, 73, 90, 197, 153, 187, 182, 138, 100, 26, 132, 157, 88, 216, 62, 248, 84, 204, 38, 95, 166, 201, 23, 223, 246, 238, 67, 90, 103, 1, 179, 213, 82, 125, 172, 32, 251, 10, 112, 51, 195, 254, 121, 116, 78, 172, 239, 123, 63, 252, 39, 182, 77, 200, 99, 248, 111, 66, 152, 44, 178, 34, 146, 69, 254, 157, 228, 138, 165, 158, 182, 83, 212, 73, 112, 134, 217, 17, 165, 189, 39, 14, 149, 197, 30, 126, 152, 247, 165, 134, 63, 199, 251, 6, 92]),
|
||||
"SHA-384": new Uint8Array([1, 247, 125, 177, 229, 19, 120, 225, 23, 197, 184, 190, 200, 160, 63, 150, 87, 210, 68, 197, 78, 131, 121, 8, 191, 113, 1, 37, 95, 65, 81, 82, 93, 158, 137, 207, 127, 84, 99, 27, 51, 104, 145, 157, 56, 36, 255, 159, 127, 120, 254, 129, 35, 154, 26, 159, 222, 43, 122, 131, 233, 92, 166, 160, 202, 17, 1, 185, 139, 29, 164, 237, 0, 236, 118, 147, 103, 233, 149, 139, 128, 71, 212, 127, 146, 171, 139, 255, 150, 241, 51, 11, 249, 72, 201, 34, 9, 1, 27, 140, 219, 180, 150, 212, 100, 219, 185, 22, 114, 14, 183, 2, 189, 173, 146, 140, 153, 185, 128, 183, 101, 4, 224, 173, 28, 18, 180, 168, 87, 49, 199, 12]),
|
||||
"SHA-512": new Uint8Array([0, 178, 202, 175, 103, 152, 81, 154, 157, 54, 219, 250, 254, 120, 107, 47, 186, 28, 194, 172, 185, 149, 147, 193, 119, 179, 110, 58, 28, 238, 183, 2, 39, 90, 226, 60, 252, 202, 10, 173, 120, 246, 182, 222, 230, 180, 113, 139, 149, 208, 209, 167, 21, 170, 51, 120, 71, 14, 80, 181, 22, 193, 142, 15, 51, 5, 1, 240, 7, 30, 106, 50, 134, 127, 167, 15, 105, 92, 211, 156, 78, 135, 225, 66, 185, 228, 19, 77, 56, 116, 11, 214, 254, 227, 84, 165, 117, 22, 126, 19, 82, 78, 148, 131, 38, 55, 145, 15, 225, 30, 83, 168, 95, 178, 27, 145, 173, 184, 27, 177, 119, 156, 78, 43, 139, 200, 124, 113, 125, 195, 80, 132])
|
||||
}
|
||||
}
|
||||
|
||||
// Old ASN.1 signatures below.
|
||||
// var signatures = {
|
||||
// "P-256": {
|
||||
// "SHA-1": new Uint8Array([48, 70, 2, 33, 0, 189, 178, 29, 63, 162, 177, 41, 146, 224, 212, 75, 195, 12, 201, 193, 68, 61, 21, 122, 25, 40, 54, 22, 203, 197, 247, 160, 97, 3, 157, 35, 146, 2, 33, 0, 202, 253, 208, 131, 220, 167, 213, 121, 60, 56, 76, 111, 93, 197, 64, 54, 149, 82, 23, 255, 65, 206, 208, 154, 16, 52, 250, 3, 135, 178, 223, 248]),
|
||||
// "SHA-256": new Uint8Array([48, 68, 2, 32, 91, 78, 119, 119, 168, 102, 87, 56, 106, 33, 140, 190, 53, 232, 207, 81, 251, 156, 33, 85, 156, 6, 1, 183, 61, 254, 248, 113, 89, 191, 223, 202, 2, 32, 9, 130, 207, 194, 45, 48, 4, 134, 19, 133, 121, 124, 93, 141, 29, 63, 26, 0, 167, 132, 123, 80, 240, 184, 69, 182, 18, 111, 211, 211, 139, 209]),
|
||||
// "SHA-384": new Uint8Array([48, 69, 2, 32, 62, 124, 63, 100, 198, 132, 82, 37, 86, 53, 94, 121, 230, 167, 204, 146, 92, 56, 129, 66, 185, 242, 140, 181, 218, 239, 217, 133, 15, 166, 13, 86, 2, 33, 0, 164, 128, 5, 101, 173, 76, 227, 174, 140, 27, 28, 83, 80, 176, 202, 44, 0, 137, 37, 16, 150, 14, 29, 149, 22, 134, 1, 2, 45, 15, 91, 154]),
|
||||
// "SHA-512": new Uint8Array([48, 70, 2, 33, 0, 163, 149, 177, 250, 180, 46, 8, 35, 168, 219, 191, 25, 152, 174, 171, 100, 155, 171, 41, 170, 10, 113, 108, 160, 26, 11, 161, 69, 216, 74, 105, 155, 2, 33, 0, 236, 60, 103, 71, 26, 48, 70, 157, 54, 252, 27, 92, 152, 227, 103, 164, 153, 71, 71, 155, 103, 109, 38, 163, 158, 118, 238, 66, 50, 43, 29, 14])
|
||||
// },
|
||||
// "P-384": {
|
||||
// "SHA-1": new Uint8Array([48, 100, 2, 48, 95, 88, 156, 202, 5, 12, 93, 174, 109, 126, 105, 41, 101, 6, 111, 143, 36, 14, 7, 57, 84, 139, 59, 112, 224, 57, 250, 236, 77, 184, 59, 102, 21, 149, 236, 134, 202, 147, 140, 244, 27, 204, 55, 75, 109, 245, 40, 218, 2, 48, 25, 244, 151, 221, 217, 106, 152, 238, 40, 59, 188, 50, 235, 147, 226, 44, 121, 16, 69, 231, 204, 59, 42, 174, 23, 80, 130, 170, 204, 34, 208, 154, 135, 143, 164, 94, 62, 226, 14, 100, 213, 229, 40, 176, 31, 148, 125, 75]),
|
||||
// "SHA-256": new Uint8Array([48, 102, 2, 49, 0, 171, 16, 188, 253, 115, 108, 16, 69, 39, 187, 21, 188, 22, 86, 146, 2, 212, 145, 7, 120, 218, 186, 149, 139, 205, 55, 114, 208, 25, 183, 127, 2, 198, 234, 151, 193, 94, 12, 173, 170, 234, 130, 83, 193, 214, 110, 108, 72, 2, 49, 0, 136, 132, 142, 128, 157, 111, 141, 240, 49, 203, 203, 32, 121, 165, 57, 138, 81, 95, 64, 235, 251, 241, 59, 203, 214, 169, 17, 153, 112, 115, 91, 51, 66, 206, 172, 143, 39, 0, 217, 68, 242, 172, 86, 155, 174, 24, 39, 155]),
|
||||
// "SHA-384": new Uint8Array([48, 102, 2, 49, 0, 227, 80, 5, 74, 3, 89, 195, 243, 249, 127, 97, 9, 62, 159, 116, 170, 52, 181, 161, 160, 213, 16, 10, 137, 120, 40, 244, 151, 155, 52, 2, 111, 41, 199, 65, 146, 146, 121, 176, 101, 240, 37, 147, 163, 92, 102, 70, 79, 2, 49, 0, 223, 182, 48, 0, 17, 216, 189, 37, 249, 104, 74, 195, 177, 87, 106, 14, 127, 86, 0, 139, 238, 6, 13, 130, 146, 12, 26, 166, 204, 169, 194, 27, 81, 170, 212, 2, 128, 235, 59, 159, 120, 79, 141, 151, 188, 132, 170, 70]),
|
||||
// "SHA-512": new Uint8Array([48, 102, 2, 49, 0, 188, 136, 210, 146, 118, 251, 132, 224, 144, 121, 109, 86, 162, 216, 12, 148, 108, 169, 42, 79, 32, 152, 167, 20, 173, 176, 28, 67, 219, 93, 52, 167, 76, 140, 102, 244, 118, 146, 193, 134, 116, 26, 83, 43, 230, 241, 215, 135, 2, 49, 0, 178, 120, 154, 88, 189, 55, 9, 240, 26, 169, 201, 53, 83, 207, 11, 6, 83, 54, 194, 126, 249, 188, 189, 32, 88, 190, 228, 166, 66, 104, 103, 243, 64, 214, 153, 84, 80, 175, 20, 205, 9, 85, 74, 233, 90, 184, 240, 153])
|
||||
// },
|
||||
// "P-521": {
|
||||
// "SHA-1": new Uint8Array([48, 129, 136, 2, 66, 1, 0, 159, 229, 63, 6, 27, 187, 208, 6, 90, 246, 116, 10, 87, 207, 237, 166, 143, 68, 223, 98, 232, 90, 95, 143, 20, 240, 164, 112, 19, 199, 4, 203, 196, 231, 179, 203, 229, 64, 51, 58, 224, 124, 97, 41, 235, 202, 28, 201, 52, 61, 76, 166, 233, 197, 247, 58, 37, 115, 146, 150, 142, 108, 176, 94, 2, 66, 1, 4, 164, 11, 249, 164, 172, 86, 59, 39, 111, 61, 210, 100, 176, 168, 243, 146, 236, 28, 21, 25, 97, 28, 56, 201, 159, 24, 97, 217, 178, 5, 13, 221, 64, 6, 39, 168, 54, 129, 3, 86, 157, 104, 87, 241, 92, 158, 142, 170, 27, 126, 138, 255, 44, 33, 161, 49, 192, 230, 186, 70, 42, 189, 124, 5]),
|
||||
// "SHA-256": new Uint8Array([48, 129, 134, 2, 65, 115, 189, 109, 44, 118, 67, 34, 176, 16, 126, 246, 157, 34, 188, 209, 65, 231, 207, 180, 139, 53, 97, 110, 157, 19, 55, 35, 134, 90, 160, 20, 252, 130, 210, 179, 22, 76, 3, 142, 212, 71, 48, 251, 64, 18, 148, 199, 234, 163, 193, 120, 13, 153, 63, 174, 253, 58, 34, 130, 88, 138, 194, 248, 173, 53, 2, 65, 63, 0, 229, 139, 245, 33, 197, 245, 98, 139, 59, 87, 144, 16, 220, 183, 237, 125, 136, 134, 143, 146, 195, 0, 209, 105, 217, 20, 121, 76, 64, 87, 232, 86, 87, 136, 117, 237, 39, 83, 248, 3, 50, 236, 152, 121, 37, 116, 93, 91, 241, 235, 152, 95, 177, 217, 45, 247, 66, 193, 248, 131, 205, 132, 74]),
|
||||
// "SHA-384": new Uint8Array([48, 129, 136, 2, 66, 0, 252, 248, 24, 253, 24, 36, 120, 84, 72, 47, 246, 13, 78, 112, 200, 131, 7, 131, 73, 235, 36, 93, 54, 219, 233, 242, 85, 1, 198, 187, 17, 17, 109, 13, 47, 204, 137, 224, 17, 6, 225, 178, 133, 98, 248, 53, 151, 33, 230, 160, 42, 208, 30, 230, 154, 108, 227, 123, 216, 215, 35, 179, 17, 91, 187, 2, 66, 1, 110, 43, 180, 40, 222, 59, 177, 3, 70, 177, 175, 118, 222, 31, 1, 46, 196, 237, 187, 15, 96, 241, 216, 136, 195, 194, 45, 163, 194, 92, 159, 179, 101, 194, 90, 141, 78, 28, 31, 199, 233, 228, 180, 223, 23, 171, 62, 247, 157, 62, 126, 90, 198, 132, 197, 34, 140, 227, 79, 190, 153, 137, 225, 226, 32]),
|
||||
// "SHA-512": new Uint8Array([48, 129, 136, 2, 66, 0, 228, 69, 122, 14, 172, 82, 52, 181, 42, 214, 42, 107, 227, 154, 253, 177, 145, 236, 231, 251, 71, 46, 202, 46, 59, 63, 76, 195, 63, 130, 8, 50, 116, 179, 181, 203, 234, 27, 203, 55, 188, 239, 122, 107, 167, 163, 190, 141, 174, 35, 22, 176, 173, 157, 212, 49, 21, 69, 72, 100, 78, 131, 147, 57, 223, 2, 66, 1, 107, 241, 89, 194, 8, 164, 44, 33, 11, 173, 236, 115, 153, 16, 90, 155, 164, 247, 232, 18, 226, 223, 62, 75, 246, 178, 66, 176, 51, 74, 161, 74, 76, 14, 227, 217, 19, 114, 36, 76, 168, 151, 191, 20, 58, 179, 162, 205, 140, 156, 227, 88, 59, 161, 245, 61, 170, 211, 254, 99, 120, 17, 174, 175, 52])
|
||||
// }
|
||||
// };
|
||||
|
||||
var vectors = [];
|
||||
["P-256", "P-384", "P-521"].forEach(function(curveName) {
|
||||
["SHA-1", "SHA-256", "SHA-384", "SHA-512"].forEach(function(hashName) {
|
||||
var vector = {
|
||||
name: "ECDSA " + curveName + " with " + hashName,
|
||||
publicKeyBuffer: spki[curveName],
|
||||
publicKeyFormat: "spki",
|
||||
publicKey: null,
|
||||
privateKeyBuffer: pkcs8[curveName],
|
||||
privateKeyFormat: "pkcs8",
|
||||
privateKey: null,
|
||||
algorithmName: "ECDSA",
|
||||
namedCurve: curveName,
|
||||
hashName: hashName,
|
||||
plaintext: plaintext,
|
||||
signature: signatures[curveName][hashName]
|
||||
};
|
||||
|
||||
vectors.push(vector);
|
||||
})
|
||||
});
|
||||
|
||||
return vectors;
|
||||
}
|
347
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/hmac.js
Normal file
347
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/hmac.js
Normal file
|
@ -0,0 +1,347 @@
|
|||
|
||||
function run_test() {
|
||||
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 hmac_vectors.js provides the getTestVectors method
|
||||
// for the algorithm that drives these tests.
|
||||
var testVectors = getTestVectors();
|
||||
|
||||
// Test verification first, because signing tests rely on that working
|
||||
testVectors.forEach(function(vector) {
|
||||
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)
|
||||
.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 after call
|
||||
testVectors.forEach(function(vector) {
|
||||
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)
|
||||
.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 + "'");
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
// Check for successful verification even if plaintext is altered after call.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify", "sign"])
|
||||
.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)
|
||||
.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");
|
||||
});
|
||||
|
||||
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(vector) {
|
||||
promise_test(function(test) {
|
||||
return subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, vector.plaintext)
|
||||
.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) {
|
||||
promise_test(function(test) {
|
||||
return subtle.sign({name: "HMAC", hash: vector.hash}, vector.key, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
// Can we get the verify the new signature?
|
||||
return subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Round trip verifies");
|
||||
return signature;
|
||||
}, function(err) {
|
||||
assert_unreached("verify 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: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"])
|
||||
.then(function(wrongKey) {
|
||||
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)
|
||||
.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: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"])
|
||||
.then(function(wrongKey) {
|
||||
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)
|
||||
.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);
|
||||
});
|
||||
|
||||
// Verification should fail if the plaintext is changed
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify", "sign"])
|
||||
.then(function(vector) {
|
||||
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)
|
||||
.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 failure due to wrong 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 wrong plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Verification should fail if the signature is changed
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify", "sign"])
|
||||
.then(function(vector) {
|
||||
var 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)
|
||||
.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 failure due to wrong 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 wrong signature");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Verification should fail if the signature is wrong length
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify", "sign"])
|
||||
.then(function(vector) {
|
||||
var 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)
|
||||
.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 failure due to short 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 short signature");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
|
||||
Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
return;
|
||||
|
||||
// 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, keyUsages) {
|
||||
if (vector.key !== null) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(vector);
|
||||
});
|
||||
} else {
|
||||
return subtle.importKey("raw", vector.keyBuffer, {name: "HMAC", hash: vector.hash}, false, keyUsages)
|
||||
.then(function(key) {
|
||||
vector.key = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("hmac_vectors.js");
|
||||
importScripts("hmac.js");
|
||||
|
||||
run_test();
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
function getTestVectors() {
|
||||
var plaintext = new Uint8Array([95, 77, 186, 79, 50, 12, 12, 232, 118, 114, 90, 252, 229, 251, 210, 91, 248, 62, 90, 113, 37, 160, 140, 175, 231, 60, 62, 186, 196, 33, 119, 157, 249, 213, 93, 24, 12, 58, 233, 148, 38, 69, 225, 216, 47, 238, 140, 157, 41, 75, 60, 177, 160, 138, 153, 49, 32, 27, 60, 14, 129, 252, 71, 202, 207, 131, 21, 162, 175, 102, 50, 65, 19, 195, 182, 98, 48, 195, 70, 8, 196, 244, 89, 54, 52, 206, 2, 178, 103, 54, 34, 119, 240, 168, 64, 202, 116, 188, 61, 26, 98, 54, 149, 44, 94, 215, 170, 248, 168, 254, 203, 221, 250, 117, 132, 230, 151, 140, 234, 93, 42, 91, 159, 183, 241, 180, 140, 139, 11, 229, 138, 48, 82, 2, 117, 77, 131, 118, 16, 115, 116, 121, 60, 240, 38, 170, 238, 83, 0, 114, 125, 131, 108, 215, 30, 113, 179, 69, 221, 178, 228, 68, 70, 255, 197, 185, 1, 99, 84, 19, 137, 13, 145, 14, 163, 128, 152, 74, 144, 25, 16, 49, 50, 63, 22, 219, 204, 157, 107, 225, 104, 184, 72, 133, 56, 76, 160, 62, 18, 96, 10, 193, 194, 72, 2, 138, 243, 114, 108, 201, 52, 99, 136, 46, 168, 192, 42, 171]);
|
||||
|
||||
var raw = {
|
||||
"SHA-1": new Uint8Array([71, 162, 7, 70, 209, 113, 121, 219, 101, 224, 167, 157, 237, 255, 199, 253, 241, 129, 8, 27]),
|
||||
"SHA-256": new Uint8Array([229, 136, 236, 8, 17, 70, 61, 118, 114, 65, 223, 16, 116, 180, 122, 228, 7, 27, 81, 242, 206, 54, 83, 123, 166, 156, 205, 195, 253, 194, 183, 168]),
|
||||
"SHA-384": new Uint8Array([107, 29, 162, 142, 171, 31, 88, 42, 217, 113, 142, 255, 224, 94, 35, 213, 253, 44, 152, 119, 162, 217, 68, 63, 144, 190, 192, 147, 190, 206, 46, 167, 210, 53, 76, 208, 189, 197, 225, 71, 210, 233, 0, 147, 115, 73, 68, 136]),
|
||||
"SHA-512": new Uint8Array([93, 204, 53, 148, 67, 170, 246, 82, 250, 19, 117, 214, 179, 230, 31, 220, 242, 155, 180, 162, 139, 213, 211, 220, 250, 64, 248, 47, 144, 107, 178, 128, 4, 85, 219, 3, 181, 211, 31, 185, 114, 161, 90, 109, 1, 3, 162, 78, 86, 209, 86, 161, 25, 192, 229, 161, 233, 42, 68, 195, 197, 101, 124, 249])
|
||||
};
|
||||
|
||||
var signatures = {
|
||||
"SHA-1": new Uint8Array([5, 51, 144, 42, 153, 248, 82, 78, 229, 10, 240, 29, 56, 222, 220, 225, 51, 217, 140, 160]),
|
||||
"SHA-256": new Uint8Array([133, 164, 12, 234, 46, 7, 140, 40, 39, 163, 149, 63, 251, 102, 194, 123, 41, 26, 71, 43, 13, 112, 160, 0, 11, 69, 216, 35, 128, 62, 235, 84]),
|
||||
"SHA-384": new Uint8Array([33, 124, 61, 80, 240, 186, 154, 109, 110, 174, 30, 253, 215, 165, 24, 254, 46, 56, 128, 181, 130, 164, 13, 6, 30, 144, 153, 193, 224, 38, 239, 88, 130, 84, 139, 93, 92, 236, 221, 85, 152, 217, 155, 107, 111, 48, 87, 255]),
|
||||
"SHA-512": new Uint8Array([97, 251, 39, 140, 63, 251, 12, 206, 43, 241, 207, 114, 61, 223, 216, 239, 31, 147, 28, 12, 97, 140, 37, 144, 115, 36, 96, 89, 57, 227, 249, 162, 198, 244, 175, 105, 11, 218, 52, 7, 220, 47, 87, 112, 246, 160, 164, 75, 149, 77, 100, 163, 50, 227, 238, 8, 33, 171, 248, 43, 127, 62, 153, 193])
|
||||
};
|
||||
|
||||
// Each test vector has the following fields:
|
||||
// name - a unique name for this vector
|
||||
// keyBuffer - an arrayBuffer with the key data
|
||||
// key - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it!
|
||||
// hashName - the hash function to sign with
|
||||
// plaintext - the text to encrypt
|
||||
// signature - the expected signature
|
||||
var vectors = [];
|
||||
Object.keys(raw).forEach(function(hashName) {
|
||||
vectors.push({
|
||||
name: "HMAC with " + hashName,
|
||||
hash: hashName,
|
||||
keyBuffer: raw[hashName],
|
||||
key: null,
|
||||
plaintext: plaintext,
|
||||
signature: signatures[hashName]
|
||||
});
|
||||
});
|
||||
|
||||
return vectors;
|
||||
}
|
399
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/rsa.js
Normal file
399
tests/wpt/web-platform-tests/WebCryptoAPI/sign_verify/rsa.js
Normal file
|
@ -0,0 +1,399 @@
|
|||
|
||||
function run_test() {
|
||||
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();
|
||||
|
||||
// Test verification first, because signing tests rely on that working
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.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");
|
||||
|
||||
}, 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 after 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(vector.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 + "'");
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
// Check for successful verification even if plaintext is altered after call.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var plaintext = copyBuffer(vector.plaintext);
|
||||
var operation = subtle.verify(vector.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 failures due to using privateKey to verify.
|
||||
testVectors.forEach(function(vector) {
|
||||
var promise = importVectorKeys(vector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(vector.algorithm, vector.privateKey, vector.signature, vector.plaintext)
|
||||
.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) {
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(vector.algorithm, vector.publicKey, vector.plaintext)
|
||||
.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) {
|
||||
promise_test(function(test) {
|
||||
return subtle.verify(vector.algorithm, vector.publicKey, vector.signature, vector.plaintext)
|
||||
.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) {
|
||||
promise_test(function(test) {
|
||||
return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
// Can we verify the new signature?
|
||||
return subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_true(is_verified, "Round trip verifies");
|
||||
return signature;
|
||||
}, function(err) {
|
||||
assert_unreached("verify error for test " + vector.name + ": " + err.message + "'");
|
||||
});
|
||||
})
|
||||
.then(function(priorSignature) {
|
||||
// Will a second signing give us different signature? It should for PSS with non-empty salt
|
||||
return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext)
|
||||
.then(function(signature) {
|
||||
if ("saltLength" in vector.algorithm && vector.algorithm.saltLength > 0) {
|
||||
assert_false(equalBuffers(priorSignature, signature), "Two signings with a salt give different signatures")
|
||||
} else {
|
||||
assert_true(equalBuffers(priorSignature, signature), "Two signings with empty salt give same signature")
|
||||
}
|
||||
}, function(err) {
|
||||
assert_unreached("second time 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 alteredVector = Object.assign({}, vector);
|
||||
alteredVector.algorithm = Object.assign({}, vector.algorithm);
|
||||
if (vector.algorithm.name === "RSA-PSS") {
|
||||
alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5";
|
||||
} else {
|
||||
alteredVector.algorithm.name = "RSA-PSS";
|
||||
}
|
||||
|
||||
var promise = importVectorKeys(alteredVector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.sign(vector.algorithm, alteredVector.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;
|
||||
}, 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");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Test verification with the wrong algorithm
|
||||
testVectors.forEach(function(vector) {
|
||||
// Want to get the key for the wrong algorithm
|
||||
var alteredVector = Object.assign({}, vector);
|
||||
alteredVector.algorithm = Object.assign({}, vector.algorithm);
|
||||
if (vector.algorithm.name === "RSA-PSS") {
|
||||
alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5";
|
||||
} else {
|
||||
alteredVector.algorithm.name = "RSA-PSS";
|
||||
}
|
||||
|
||||
var promise = importVectorKeys(alteredVector, ["verify"], ["sign"])
|
||||
.then(function(vectors) {
|
||||
// Some tests are sign only
|
||||
if (!("signature" in vector)) {
|
||||
return;
|
||||
}
|
||||
promise_test(function(test) {
|
||||
var operation = subtle.verify(vector.algorithm, alteredVector.publicKey, vector.signature, vector.plaintext)
|
||||
.then(function(is_verified) {
|
||||
assert_unreached("Verification 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 + " verification 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 + " verification with wrong algorithm name");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Verification should fail with wrong signature
|
||||
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, vector.publicKey, signature, vector.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 with 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 with altered signature");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
// Verification should fail with wrong plaintext
|
||||
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, 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 with 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 with altered plaintext");
|
||||
});
|
||||
|
||||
all_promises.push(promise);
|
||||
});
|
||||
|
||||
|
||||
Promise.all(all_promises)
|
||||
.then(function() {done();})
|
||||
.catch(function() {done();})
|
||||
|
||||
// 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.algorithm.name, hash: vector.hash}, 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.algorithm.name, hash: vector.hash}, false, privateKeyUsages)
|
||||
.then(function(key) {
|
||||
vector.privateKey = key;
|
||||
return vector;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([publicPromise, privatePromise]);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
function equalBuffers(a, b) {
|
||||
if (a.byteLength !== b.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var aBytes = new Uint8Array(a);
|
||||
var bBytes = new Uint8Array(b);
|
||||
|
||||
for (var i=0; i<a.byteLength; i++) {
|
||||
if (aBytes[i] !== bBytes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("rsa_pkcs_vectors.js");
|
||||
importScripts("rsa.js");
|
||||
|
||||
run_test();
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,5 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
importScripts("rsa_pss_vectors.js");
|
||||
importScripts("rsa.js");
|
||||
|
||||
run_test();
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: sign() and verify() Using ECDSA</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-sign">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-verify">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="ecdsa_vectors.js"></script>
|
||||
<script src="ecdsa.js"></script>
|
||||
|
||||
<h1>sign and verify Tests for ECDSA</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: sign() and verify() Using HMAC</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-sign">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-verify">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="hmac_vectors.js"></script>
|
||||
<script src="hmac.js"></script>
|
||||
|
||||
<h1>sign and verify Tests for HMAC</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: sign() and verify() Using RSASSA-PKCS1-v1_5</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-sign">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-verify">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="rsa_pkcs_vectors.js"></script>
|
||||
<script src="rsa.js"></script>
|
||||
|
||||
<h1>sign and verify Tests for RSASSA-PKCS1-v1_5</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<meta name="timeout" content="long">
|
||||
<title>WebCryptoAPI: sign() and verify() Using RSA-PSS</title>
|
||||
<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-sign">
|
||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#SubtleCrypto-method-verify">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="rsa_pss_vectors.js"></script>
|
||||
<script src="rsa.js"></script>
|
||||
|
||||
<h1>sign and verify Tests for RSA-PSS</h1>
|
||||
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
run_test();
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue