successes.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. function run_test(algorithmNames, slowTest) {
  2. var subtle = crypto.subtle; // Change to test prefixed implementations
  3. setup({explicit_timeout: true});
  4. // These tests check that generateKey successfully creates keys
  5. // when provided any of a wide set of correct parameters
  6. // and that they can be exported afterwards.
  7. //
  8. // There are a lot of combinations of possible parameters,
  9. // resulting in a very large number of tests
  10. // performed.
  11. // Setup: define the correct behaviors that should be sought, and create
  12. // helper functions that generate all possible test parameters for
  13. // different situations.
  14. var allTestVectors = [ // Parameters that should work for generateKey
  15. {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
  16. {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
  17. {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []},
  18. {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []},
  19. {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []},
  20. {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
  21. {name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
  22. {name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]},
  23. {name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
  24. {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
  25. {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
  26. {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]},
  27. {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
  28. {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]},
  29. ];
  30. var testVectors = [];
  31. if (algorithmNames && !Array.isArray(algorithmNames)) {
  32. algorithmNames = [algorithmNames];
  33. };
  34. allTestVectors.forEach(function(vector) {
  35. if (!algorithmNames || algorithmNames.includes(vector.name)) {
  36. testVectors.push(vector);
  37. }
  38. });
  39. function parameterString(algorithm, extractable, usages) {
  40. var result = "(" +
  41. objectToString(algorithm) + ", " +
  42. objectToString(extractable) + ", " +
  43. objectToString(usages) +
  44. ")";
  45. return result;
  46. }
  47. // Test that a given combination of parameters is successful
  48. function testSuccess(algorithm, extractable, usages, resultType, testTag) {
  49. // algorithm, extractable, and usages are the generateKey parameters
  50. // resultType is the expected result, either the CryptoKey object or "CryptoKeyPair"
  51. // testTag is a string to prepend to the test name.
  52. promise_test(function(test) {
  53. return subtle.generateKey(algorithm, extractable, usages)
  54. .then(function(result) {
  55. if (resultType === "CryptoKeyPair") {
  56. assert_goodCryptoKey(result.privateKey, algorithm, extractable, usages, "private");
  57. assert_goodCryptoKey(result.publicKey, algorithm, true, usages, "public");
  58. } else {
  59. assert_goodCryptoKey(result, algorithm, extractable, usages, "secret");
  60. }
  61. return result;
  62. }, function(err) {
  63. assert_unreached("generateKey threw an unexpected error: " + err.toString());
  64. })
  65. .then(async function (result) {
  66. if (resultType === "CryptoKeyPair") {
  67. await Promise.all([
  68. subtle.exportKey('jwk', result.publicKey),
  69. subtle.exportKey('spki', result.publicKey),
  70. result.publicKey.algorithm.name.startsWith('RSA') ? undefined : subtle.exportKey('raw', result.publicKey),
  71. ...(extractable ? [
  72. subtle.exportKey('jwk', result.privateKey),
  73. subtle.exportKey('pkcs8', result.privateKey),
  74. ] : [])
  75. ]);
  76. } else {
  77. if (extractable) {
  78. await Promise.all([
  79. subtle.exportKey('raw', result),
  80. subtle.exportKey('jwk', result),
  81. ]);
  82. }
  83. }
  84. }, function(err) {
  85. assert_unreached("exportKey threw an unexpected error: " + err.toString());
  86. })
  87. }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages));
  88. }
  89. // Test all valid sets of parameters for successful
  90. // key generation.
  91. testVectors.forEach(function(vector) {
  92. allNameVariants(vector.name, slowTest).forEach(function(name) {
  93. allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
  94. allValidUsages(vector.usages, false, vector.mandatoryUsages).forEach(function(usages) {
  95. [false, true].forEach(function(extractable) {
  96. subsetTest(testSuccess, algorithm, extractable, usages, vector.resultType, "Success");
  97. });
  98. });
  99. });
  100. });
  101. });
  102. }