tor-browser

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

test_keys.js (7356B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const { Weave } = ChromeUtils.importESModule(
      5  "resource://services-sync/main.sys.mjs"
      6 );
      7 const { CollectionKeyManager, CryptoWrapper } = ChromeUtils.importESModule(
      8  "resource://services-sync/record.sys.mjs"
      9 );
     10 
     11 var collectionKeys = new CollectionKeyManager();
     12 
     13 function do_check_keypair_eq(a, b) {
     14  Assert.equal(2, a.length);
     15  Assert.equal(2, b.length);
     16  Assert.equal(a[0], b[0]);
     17  Assert.equal(a[1], b[1]);
     18 }
     19 
     20 add_test(function test_set_invalid_values() {
     21  _("Ensure that setting invalid encryption and HMAC key values is caught.");
     22 
     23  let bundle = new BulkKeyBundle("foo");
     24 
     25  let thrown = false;
     26  try {
     27    bundle.encryptionKey = null;
     28  } catch (ex) {
     29    thrown = true;
     30    Assert.equal(ex.message.indexOf("Encryption key can only be set to"), 0);
     31  } finally {
     32    Assert.ok(thrown);
     33    thrown = false;
     34  }
     35 
     36  try {
     37    bundle.encryptionKey = ["trollololol"];
     38  } catch (ex) {
     39    thrown = true;
     40    Assert.equal(ex.message.indexOf("Encryption key can only be set to"), 0);
     41  } finally {
     42    Assert.ok(thrown);
     43    thrown = false;
     44  }
     45 
     46  try {
     47    bundle.hmacKey = Utils.generateRandomBytesLegacy(15);
     48  } catch (ex) {
     49    thrown = true;
     50    Assert.equal(ex.message.indexOf("HMAC key must be at least 128"), 0);
     51  } finally {
     52    Assert.ok(thrown);
     53    thrown = false;
     54  }
     55 
     56  try {
     57    bundle.hmacKey = null;
     58  } catch (ex) {
     59    thrown = true;
     60    Assert.equal(ex.message.indexOf("HMAC key can only be set to string"), 0);
     61  } finally {
     62    Assert.ok(thrown);
     63    thrown = false;
     64  }
     65 
     66  try {
     67    bundle.hmacKey = ["trollolol"];
     68  } catch (ex) {
     69    thrown = true;
     70    Assert.equal(ex.message.indexOf("HMAC key can only be set to"), 0);
     71  } finally {
     72    Assert.ok(thrown);
     73    thrown = false;
     74  }
     75 
     76  try {
     77    bundle.hmacKey = Utils.generateRandomBytesLegacy(15);
     78  } catch (ex) {
     79    thrown = true;
     80    Assert.equal(ex.message.indexOf("HMAC key must be at least 128"), 0);
     81  } finally {
     82    Assert.ok(thrown);
     83    thrown = false;
     84  }
     85 
     86  run_next_test();
     87 });
     88 
     89 add_task(async function test_ensureLoggedIn() {
     90  let log = Log.repository.getLogger("Test");
     91  Log.repository.rootLogger.addAppender(new Log.DumpAppender());
     92 
     93  await configureIdentity();
     94 
     95  let keyBundle = Weave.Service.identity.syncKeyBundle;
     96 
     97  /*
     98   * Build a test version of storage/crypto/keys.
     99   * Encrypt it with the sync key.
    100   * Pass it into the CollectionKeyManager.
    101   */
    102 
    103  log.info("Building storage keys...");
    104  let storage_keys = new CryptoWrapper("crypto", "keys");
    105  let default_key64 = await Weave.Crypto.generateRandomKey();
    106  let default_hmac64 = await Weave.Crypto.generateRandomKey();
    107  let bookmarks_key64 = await Weave.Crypto.generateRandomKey();
    108  let bookmarks_hmac64 = await Weave.Crypto.generateRandomKey();
    109 
    110  storage_keys.cleartext = {
    111    default: [default_key64, default_hmac64],
    112    collections: { bookmarks: [bookmarks_key64, bookmarks_hmac64] },
    113  };
    114  storage_keys.modified = Date.now() / 1000;
    115  storage_keys.id = "keys";
    116 
    117  log.info("Encrypting storage keys...");
    118 
    119  // Use passphrase (sync key) itself to encrypt the key bundle.
    120  await storage_keys.encrypt(keyBundle);
    121 
    122  // Sanity checking.
    123  Assert.equal(null, storage_keys.cleartext);
    124  Assert.notEqual(null, storage_keys.ciphertext);
    125 
    126  log.info("Updating collection keys.");
    127 
    128  // updateContents decrypts the object, releasing the payload for us to use.
    129  // Returns true, because the default key has changed.
    130  Assert.ok(await collectionKeys.updateContents(keyBundle, storage_keys));
    131  let payload = storage_keys.cleartext;
    132 
    133  _("CK: " + JSON.stringify(collectionKeys._collections));
    134 
    135  // Test that the CollectionKeyManager returns a similar WBO.
    136  let wbo = collectionKeys.asWBO("crypto", "keys");
    137 
    138  _("WBO: " + JSON.stringify(wbo));
    139  _("WBO cleartext: " + JSON.stringify(wbo.cleartext));
    140 
    141  // Check the individual contents.
    142  Assert.equal(wbo.collection, "crypto");
    143  Assert.equal(wbo.id, "keys");
    144  Assert.equal(undefined, wbo.modified);
    145  Assert.equal(collectionKeys.lastModified, storage_keys.modified);
    146  Assert.ok(!!wbo.cleartext.default);
    147  do_check_keypair_eq(payload.default, wbo.cleartext.default);
    148  do_check_keypair_eq(
    149    payload.collections.bookmarks,
    150    wbo.cleartext.collections.bookmarks
    151  );
    152 
    153  Assert.ok("bookmarks" in collectionKeys._collections);
    154  Assert.equal(false, "tabs" in collectionKeys._collections);
    155 
    156  _("Updating contents twice with the same data doesn't proceed.");
    157  await storage_keys.encrypt(keyBundle);
    158  Assert.equal(
    159    false,
    160    await collectionKeys.updateContents(keyBundle, storage_keys)
    161  );
    162 
    163  /*
    164   * Test that we get the right keys out when we ask for
    165   * a collection's tokens.
    166   */
    167  let b1 = new BulkKeyBundle("bookmarks");
    168  b1.keyPairB64 = [bookmarks_key64, bookmarks_hmac64];
    169  let b2 = collectionKeys.keyForCollection("bookmarks");
    170  do_check_keypair_eq(b1.keyPair, b2.keyPair);
    171 
    172  // Check key equality.
    173  Assert.ok(b1.equals(b2));
    174  Assert.ok(b2.equals(b1));
    175 
    176  b1 = new BulkKeyBundle("[default]");
    177  b1.keyPairB64 = [default_key64, default_hmac64];
    178 
    179  Assert.ok(!b1.equals(b2));
    180  Assert.ok(!b2.equals(b1));
    181 
    182  b2 = collectionKeys.keyForCollection(null);
    183  do_check_keypair_eq(b1.keyPair, b2.keyPair);
    184 
    185  /*
    186   * Checking for update times.
    187   */
    188  let info_collections = {};
    189  Assert.ok(collectionKeys.updateNeeded(info_collections));
    190  info_collections.crypto = 5000;
    191  Assert.ok(!collectionKeys.updateNeeded(info_collections));
    192  info_collections.crypto = 1 + Date.now() / 1000; // Add one in case computers are fast!
    193  Assert.ok(collectionKeys.updateNeeded(info_collections));
    194 
    195  collectionKeys.lastModified = null;
    196  Assert.ok(collectionKeys.updateNeeded({}));
    197 
    198  /*
    199   * Check _compareKeyBundleCollections.
    200   */
    201  async function newBundle(name) {
    202    let r = new BulkKeyBundle(name);
    203    await r.generateRandom();
    204    return r;
    205  }
    206  let k1 = await newBundle("k1");
    207  let k2 = await newBundle("k2");
    208  let k3 = await newBundle("k3");
    209  let k4 = await newBundle("k4");
    210  let k5 = await newBundle("k5");
    211  let coll1 = { foo: k1, bar: k2 };
    212  let coll2 = { foo: k1, bar: k2 };
    213  let coll3 = { foo: k1, bar: k3 };
    214  let coll4 = { foo: k4 };
    215  let coll5 = { baz: k5, bar: k2 };
    216  let coll6 = {};
    217 
    218  let d1 = collectionKeys._compareKeyBundleCollections(coll1, coll2); // []
    219  let d2 = collectionKeys._compareKeyBundleCollections(coll1, coll3); // ["bar"]
    220  let d3 = collectionKeys._compareKeyBundleCollections(coll3, coll2); // ["bar"]
    221  let d4 = collectionKeys._compareKeyBundleCollections(coll1, coll4); // ["bar", "foo"]
    222  let d5 = collectionKeys._compareKeyBundleCollections(coll5, coll2); // ["baz", "foo"]
    223  let d6 = collectionKeys._compareKeyBundleCollections(coll6, coll1); // ["bar", "foo"]
    224  let d7 = collectionKeys._compareKeyBundleCollections(coll5, coll5); // []
    225  let d8 = collectionKeys._compareKeyBundleCollections(coll6, coll6); // []
    226 
    227  Assert.ok(d1.same);
    228  Assert.ok(!d2.same);
    229  Assert.ok(!d3.same);
    230  Assert.ok(!d4.same);
    231  Assert.ok(!d5.same);
    232  Assert.ok(!d6.same);
    233  Assert.ok(d7.same);
    234  Assert.ok(d8.same);
    235 
    236  Assert.deepEqual(d1.changed, []);
    237  Assert.deepEqual(d2.changed, ["bar"]);
    238  Assert.deepEqual(d3.changed, ["bar"]);
    239  Assert.deepEqual(d4.changed, ["bar", "foo"]);
    240  Assert.deepEqual(d5.changed, ["baz", "foo"]);
    241  Assert.deepEqual(d6.changed, ["bar", "foo"]);
    242 });