Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/services/sync/tests/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  test_corrupt_keys.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */


const { Weave } = ChromeUtils.importESModule(
  "resource://services-sync/main.sys.mjs"
);
const { HistoryEngine } = ChromeUtils.importESModule(
  "resource://services-sync/engines/history.sys.mjs"
);
const { CryptoWrapper, WBORecord } = ChromeUtils.importESModule(
  "resource://services-sync/record.sys.mjs"
);
const { Service } = ChromeUtils.importESModule(
  "resource://services-sync/service.sys.mjs"
);

add_task(async function test_locally_changed_keys() {
  enableValidationPrefs();

  let hmacErrorCount = 0;
  function counting(f) {
    return async function () {
      hmacErrorCount++;
      return f.call(this);
    };
  }

  Service.handleHMACEvent = counting(Service.handleHMACEvent);

  let server = new SyncServer();
  let johndoe = server.registerUser("johndoe""password");
  johndoe.createContents({
    meta: {},
    crypto: {},
    clients: {},
  });
  server.start();

  try {
    Svc.PrefBranch.setStringPref("registerEngines""Tab");

    await configureIdentity({ username: "johndoe" }, server);
    // We aren't doing a .login yet, so fudge the cluster URL.
    Service.clusterURL = Service.identity._token.endpoint;

    await Service.engineManager.register(HistoryEngine);
    // Disable addon sync because AddonManager won't be initialized here.
    await Service.engineManager.unregister("addons");
    await Service.engineManager.unregister("extension-storage");

    async function corrupt_local_keys() {
      Service.collectionKeys._default.keyPair = [
        await Weave.Crypto.generateRandomKey(),
        await Weave.Crypto.generateRandomKey(),
      ];
    }

    _("Setting meta.");

    // Bump version on the server.
    let m = new WBORecord("meta""global");
    m.payload = {
      syncID: "foooooooooooooooooooooooooo",
      storageVersion: STORAGE_VERSION,
    };
    await m.upload(Service.resource(Service.metaURL));

    _(
      "New meta/global: " +
        JSON.stringify(johndoe.collection("meta").wbo("global"))
    );

    // Upload keys.
    await generateNewKeys(Service.collectionKeys);
    let serverKeys = Service.collectionKeys.asWBO("crypto""keys");
    await serverKeys.encrypt(Service.identity.syncKeyBundle);
    Assert.ok(
      (await serverKeys.upload(Service.resource(Service.cryptoKeysURL))).success
    );

    // Check that login works.
    Assert.ok(await Service.login());
    Assert.ok(Service.isLoggedIn);

    // Sync should upload records.
    await sync_and_validate_telem();

    // Tabs exist.
    _("Tabs modified: " + johndoe.modified("tabs"));
    Assert.ok(johndoe.modified("tabs") > 0);

    // Let's create some server side history records.
    let liveKeys = Service.collectionKeys.keyForCollection("history");
    _("Keys now: " + liveKeys.keyPair);
    let visitType = Ci.nsINavHistoryService.TRANSITION_LINK;
    let history = johndoe.createCollection("history");
    for (let i = 0; i < 5; i++) {
      let id = "record-no--" + i;
      let modified = Date.now() / 1000 - 60 * (i + 10);

      let w = new CryptoWrapper("history""id");
      w.cleartext = {
        id,
        histUri: "http://foo/bar?" + id,
        title: id,
        sortindex: i,
        visits: [{ date: (modified - 5) * 1000000, type: visitType }],
        deleted: false,
      };
      await w.encrypt(liveKeys);

      let payload = { ciphertext: w.ciphertext, IV: w.IV, hmac: w.hmac };
      history.insert(id, payload, modified);
    }

    history.timestamp = Date.now() / 1000;
    let old_key_time = johndoe.modified("crypto");
    _("Old key time: " + old_key_time);

    // Check that we can decrypt one.
    let rec = new CryptoWrapper("history""record-no--0");
    await rec.fetch(
      Service.resource(Service.storageURL + "history/record-no--0")
    );
    _(JSON.stringify(rec));
    Assert.ok(!!(await rec.decrypt(liveKeys)));

    Assert.equal(hmacErrorCount, 0);

    // Fill local key cache with bad data.
    await corrupt_local_keys();
    _(
      "Keys now: " + Service.collectionKeys.keyForCollection("history").keyPair
    );

    Assert.equal(hmacErrorCount, 0);

    _("HMAC error count: " + hmacErrorCount);
    // Now syncing should succeed, after one HMAC error.
    await sync_and_validate_telem(ping => {
      Assert.equal(
        ping.engines.find(e => e.name == "history").incoming.applied,
        5
      );
    });

    Assert.equal(hmacErrorCount, 1);
    _(
      "Keys now: " + Service.collectionKeys.keyForCollection("history").keyPair
    );

    // And look! We downloaded history!
    Assert.ok(
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--0")
    );
    Assert.ok(
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--1")
    );
    Assert.ok(
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--2")
    );
    Assert.ok(
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--3")
    );
    Assert.ok(
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--4")
    );
    Assert.equal(hmacErrorCount, 1);

    _("Busting some new server values.");
    // Now what happens if we corrupt the HMAC on the server?
    for (let i = 5; i < 10; i++) {
      let id = "record-no--" + i;
      let modified = 1 + Date.now() / 1000;

      let w = new CryptoWrapper("history""id");
      w.cleartext = {
        id,
        histUri: "http://foo/bar?" + id,
        title: id,
        sortindex: i,
        visits: [{ date: (modified - 5) * 1000000, type: visitType }],
        deleted: false,
      };
      await w.encrypt(Service.collectionKeys.keyForCollection("history"));
      w.hmac = w.hmac.toUpperCase();

      let payload = { ciphertext: w.ciphertext, IV: w.IV, hmac: w.hmac };
      history.insert(id, payload, modified);
    }
    history.timestamp = Date.now() / 1000;

    _("Server key time hasn't changed.");
    Assert.equal(johndoe.modified("crypto"), old_key_time);

    _("Resetting HMAC error timer.");
    Service.lastHMACEvent = 0;

    _("Syncing...");
    await sync_and_validate_telem(ping => {
      Assert.equal(
        ping.engines.find(e => e.name == "history").incoming.failed,
        5
      );
    });

    _(
      "Keys now: " + Service.collectionKeys.keyForCollection("history").keyPair
    );
    _(
      "Server keys have been updated, and we skipped over 5 more HMAC errors without adjusting history."
    );
    Assert.ok(johndoe.modified("crypto") > old_key_time);
    Assert.equal(hmacErrorCount, 6);
    Assert.equal(
      false,
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--5")
    );
    Assert.equal(
      false,
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--6")
    );
    Assert.equal(
      false,
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--7")
    );
    Assert.equal(
      false,
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--8")
    );
    Assert.equal(
      false,
      await PlacesUtils.history.hasVisits("http://foo/bar?record-no--9")
    );
  } finally {
    for (const pref of Svc.PrefBranch.getChildList("")) {
      Svc.PrefBranch.clearUserPref(pref);
    }
    await promiseStopServer(server);
  }
});

function run_test() {
  Log.repository.rootLogger.addAppender(new Log.DumpAppender());
  validate_all_future_pings();

  run_next_test();
}

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.