tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

eddsa.js (12164B)


      1 function run_test(algorithmName) {
      2  var subtle = self.crypto.subtle; // Change to test prefixed implementations
      3 
      4  // Source file [algorithm_name]_vectors.js provides the getTestVectors method
      5  // for the algorithm that drives these tests.
      6  var testVectors = getTestVectors(algorithmName);
      7 
      8  testVectors.forEach(function(vector) {
      9      var algorithm = {name: vector.algorithmName};
     10 
     11      // Test verification first, because signing tests rely on that working
     12      promise_test(async() => {
     13          let isVerified = false;
     14          let key;
     15          try {
     16              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
     17              isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data)
     18          } catch (err) {
     19              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
     20              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
     21          };
     22          assert_true(isVerified, "Signature verified");
     23      }, vector.name + " verification");
     24 
     25      // Test verification with an altered buffer after call
     26      promise_test(async() => {
     27          let isVerified = false;
     28          let key;
     29          try {
     30              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
     31              var signature = copyBuffer(vector.signature);
     32              [isVerified] = await Promise.all([
     33                  subtle.verify(algorithm, key, signature, vector.data),
     34                  signature[0] = 255 - signature[0]
     35              ]);
     36          } catch (err) {
     37              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
     38              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
     39          };
     40          assert_true(isVerified, "Signature verified");
     41      }, vector.name + " verification with altered signature after call");
     42 
     43      // Check for successful verification even if data is altered after call.
     44      promise_test(async() => {
     45          let isVerified = false;
     46          let key;
     47          try {
     48              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
     49              var data = copyBuffer(vector.data);
     50              [isVerified] = await Promise.all([
     51                  subtle.verify(algorithm, key, vector.signature, data),
     52                  data[0] = 255 - data[0]
     53              ]);
     54          } catch (err) {
     55              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
     56              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
     57          };
     58          assert_true(isVerified, "Signature verified");
     59      }, vector.name + " with altered data after call");
     60 
     61      // Check for failures due to using privateKey to verify.
     62      promise_test(async() => {
     63          let isVerified = false;
     64          let key;
     65          try {
     66              key = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]);
     67              isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data)
     68              assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name);
     69          } catch (err) {
     70              if (err instanceof AssertionError)
     71                  throw err;
     72              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
     73              assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
     74          };
     75          assert_false(isVerified, "Signature verified");
     76      }, vector.name + " using privateKey to verify");
     77 
     78      // Check for failures due to using publicKey to sign.
     79      promise_test(async() => {
     80          let isVerified = false;
     81          let key;
     82          try {
     83              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
     84              let signature = await subtle.sign(algorithm, key, vector.data);
     85              assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name);
     86          } catch (err) {
     87              if (err instanceof AssertionError)
     88                  throw err;
     89              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
     90              assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
     91          };
     92      }, vector.name + " using publicKey to sign");
     93 
     94      // Check for failures due to no "verify" usage.
     95      promise_test(async() => {
     96          let isVerified = false;
     97          let key;
     98          try {
     99              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, []);
    100              isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data)
    101              assert_unreached("Should have thrown error for no verify usage in " + vector.name);
    102          } catch (err) {
    103              if (err instanceof AssertionError)
    104                  throw err;
    105              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
    106              assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'");
    107          };
    108          assert_false(isVerified, "Signature verified");
    109      }, vector.name + " no verify usage");
    110 
    111      // Check for successful signing and verification.
    112      var algorithm = {name: vector.algorithmName};
    113      promise_test(async() => {
    114          let isVerified = false;
    115          let privateKey, publicKey;
    116          let signature;
    117          try {
    118              privateKey = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]);
    119              publicKey = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
    120              signature = await subtle.sign(algorithm, privateKey, vector.data);
    121              isVerified = await subtle.verify(algorithm, publicKey, vector.signature, vector.data)
    122          } catch (err) {
    123              assert_false(publicKey === undefined || privateKey === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
    124              assert_false(signature === undefined, "sign error for test " + vector.name + ": '" + err.message + "'");
    125              assert_unreached("verify error for test " + vector.name + ": " + err.message + "'");
    126          };
    127          assert_true(isVerified, "Round trip verification works");
    128      }, vector.name + " round trip");
    129 
    130      // Test signing with the wrong algorithm
    131      var algorithm = {name: vector.algorithmName};
    132      promise_test(async() => {
    133          let wrongKey;
    134          try {
    135              wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"])
    136              let signature = await subtle.sign(algorithm, wrongKey, vector.data);
    137              assert_unreached("Signing should not have succeeded for " + vector.name);
    138          } catch (err) {
    139              if (err instanceof AssertionError)
    140                  throw err;
    141              assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'");
    142              assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'");
    143          };
    144      }, vector.name + " signing with wrong algorithm name");
    145 
    146      // Test verification with the wrong algorithm
    147      var algorithm = {name: vector.algorithmName};
    148      promise_test(async() => {
    149          let wrongKey;
    150          try {
    151              wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"])
    152              let isVerified = await subtle.verify(algorithm, wrongKey, vector.signature, vector.data)
    153              assert_unreached("Verifying should not have succeeded for " + vector.name);
    154          } catch (err) {
    155              if (err instanceof AssertionError)
    156                  throw err;
    157              assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'");
    158              assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'");
    159          };
    160      }, vector.name + " verifying with wrong algorithm name");
    161 
    162      // Test verification fails with wrong signature
    163      var algorithm = {name: vector.algorithmName};
    164      promise_test(async() => {
    165          let key;
    166          let isVerified = true;
    167          var signature = copyBuffer(vector.signature);
    168          signature[0] = 255 - signature[0];
    169          try {
    170              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
    171              isVerified = await subtle.verify(algorithm, key, signature, vector.data)
    172          } catch (err) {
    173              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
    174              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
    175          };
    176          assert_false(isVerified, "Signature verified");
    177      }, vector.name + " verification failure due to altered signature");
    178 
    179      // Test verification fails with short (odd length) signature
    180      promise_test(async() => {
    181          let key;
    182          let isVerified = true;
    183          var signature = vector.signature.slice(1); // Skip the first byte
    184          try {
    185              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
    186              isVerified = await subtle.verify(algorithm, key, signature, vector.data)
    187          } catch (err) {
    188              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
    189              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
    190          };
    191          assert_false(isVerified, "Signature verified");
    192      }, vector.name + " verification failure due to shortened signature");
    193 
    194      // Test verification fails with wrong data
    195      promise_test(async() => {
    196          let key;
    197          let isVerified = true;
    198          var data = copyBuffer(vector.data);
    199          data[0] = 255 - data[0];
    200          try {
    201              key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]);
    202              isVerified = await subtle.verify(algorithm, key, vector.signature, data)
    203          } catch (err) {
    204              assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''");
    205              assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'");
    206          };
    207          assert_false(isVerified, "Signature verified");
    208      }, vector.name + " verification failure due to altered data");
    209 
    210      // Test that generated keys are valid for signing and verifying.
    211      promise_test(async() => {
    212          let key = await subtle.generateKey(algorithm, false, ["sign", "verify"]);
    213          let signature = await subtle.sign(algorithm, key.privateKey, vector.data);
    214          let isVerified = await subtle.verify(algorithm, key.publicKey, signature, vector.data);
    215          assert_true(isVerified, "Verificaton failed.");
    216      }, "Sign and verify using generated " + vector.algorithmName + " keys.");
    217  });
    218 
    219  // Returns a copy of the sourceBuffer it is sent.
    220  function copyBuffer(sourceBuffer) {
    221      var source = new Uint8Array(sourceBuffer);
    222      var copy = new Uint8Array(sourceBuffer.byteLength)
    223 
    224      for (var i=0; i<source.byteLength; i++) {
    225          copy[i] = source[i];
    226      }
    227 
    228      return copy;
    229  }
    230 
    231  return;
    232 }