--- a/services/sync/modules-testing/fakeservices.js
+++ b/services/sync/modules-testing/fakeservices.js
@@ -8,16 +8,17 @@ this.EXPORTED_SYMBOLS = [
"FakeCryptoService",
"FakeFilesystemService",
"FakeGUIDService",
"fakeSHA256HMAC",
];
var {utils: Cu} = Components;
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/util.js");
var btoa = Cu.import("resource://gre/modules/Log.jsm").btoa;
this.FakeFilesystemService = function FakeFilesystemService(contents) {
this.fakeContents = contents;
let self = this;
@@ -90,18 +91,18 @@ this.FakeGUIDService = function FakeGUID
/*
* Mock implementation of WeaveCrypto. It does not encrypt or
* decrypt, merely returning the input verbatim.
*/
this.FakeCryptoService = function FakeCryptoService() {
this.counter = 0;
- delete Svc.Crypto; // get rid of the getter first
- Svc.Crypto = this;
+ delete Weave.Crypto; // get rid of the getter first
+ Weave.Crypto = this;
CryptoWrapper.prototype.ciphertextHMAC = function ciphertextHMAC(keyBundle) {
return fakeSHA256HMAC(this.ciphertext);
};
}
FakeCryptoService.prototype = {
encrypt: function encrypt(clearText, symmetricKey, iv) {
--- a/services/sync/modules/keys.js
+++ b/services/sync/modules/keys.js
@@ -8,16 +8,17 @@ this.EXPORTED_SYMBOLS = [
"BulkKeyBundle",
"SyncKeyBundle"
];
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://gre/modules/Log.jsm");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/util.js");
/**
* Represents a pair of keys.
*
* Each key stored in a key bundle is 256 bits. One key is used for symmetric
* encryption. The other is used for HMAC.
*
@@ -102,18 +103,18 @@ KeyBundle.prototype = {
get sha256HMACHasher() {
return this._sha256HMACHasher;
},
/**
* Populate this key pair with 2 new, randomly generated keys.
*/
generateRandom: function generateRandom() {
- let generatedHMAC = Svc.Crypto.generateRandomKey();
- let generatedEncr = Svc.Crypto.generateRandomKey();
+ let generatedHMAC = Weave.Crypto.generateRandomKey();
+ let generatedEncr = Weave.Crypto.generateRandomKey();
this.keyPairB64 = [generatedEncr, generatedHMAC];
},
};
/**
* Represents a KeyBundle associated with a collection.
*
--- a/services/sync/modules/main.js
+++ b/services/sync/modules/main.js
@@ -1,29 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = ["Weave"];
+const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
this.Weave = {};
-Components.utils.import("resource://services-sync/constants.js", Weave);
+Cu.import("resource://services-sync/constants.js", Weave);
var lazies = {
"service.js": ["Service"],
"status.js": ["Status"],
"util.js": ["Utils", "Svc"]
};
function lazyImport(module, dest, props) {
function getter(prop) {
return function() {
let ns = {};
- Components.utils.import(module, ns);
+ Cu.import(module, ns);
delete dest[prop];
return dest[prop] = ns[prop];
};
}
props.forEach(function(prop) { dest.__defineGetter__(prop, getter(prop)); });
}
for (let mod in lazies) {
lazyImport("resource://services-sync/" + mod, Weave, lazies[mod]);
}
+
+XPCOMUtils.defineLazyGetter(Weave, "Crypto", function() {
+ let { WeaveCrypto } = Cu.import("resource://services-crypto/WeaveCrypto.js", {});
+ return new WeaveCrypto();
+});
--- a/services/sync/modules/record.js
+++ b/services/sync/modules/record.js
@@ -16,16 +16,17 @@ var Cr = Components.results;
var Cu = Components.utils;
const CRYPTO_COLLECTION = "crypto";
const KEYS_WBO = "keys";
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/keys.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/resource.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-common/async.js");
this.WBORecord = function WBORecord(collection, id) {
this.data = {};
this.payload = {};
this.collection = collection; // Optional.
@@ -134,19 +135,19 @@ CryptoWrapper.prototype = {
*
* Optional key bundle overrides the collection key lookup.
*/
encrypt: function encrypt(keyBundle) {
if (!keyBundle) {
throw new Error("A key bundle must be supplied to encrypt.");
}
- this.IV = Svc.Crypto.generateRandomIV();
- this.ciphertext = Svc.Crypto.encrypt(JSON.stringify(this.cleartext),
- keyBundle.encryptionKeyB64, this.IV);
+ this.IV = Weave.Crypto.generateRandomIV();
+ this.ciphertext = Weave.Crypto.encrypt(JSON.stringify(this.cleartext),
+ keyBundle.encryptionKeyB64, this.IV);
this.hmac = this.ciphertextHMAC(keyBundle);
this.cleartext = null;
},
// Optional key bundle.
decrypt: function decrypt(keyBundle) {
if (!this.ciphertext) {
throw "No ciphertext: nothing to decrypt?";
@@ -159,18 +160,18 @@ CryptoWrapper.prototype = {
// Authenticate the encrypted blob with the expected HMAC
let computedHMAC = this.ciphertextHMAC(keyBundle);
if (computedHMAC != this.hmac) {
Utils.throwHMACMismatch(this.hmac, computedHMAC);
}
// Handle invalid data here. Elsewhere we assume that cleartext is an object.
- let cleartext = Svc.Crypto.decrypt(this.ciphertext,
- keyBundle.encryptionKeyB64, this.IV);
+ let cleartext = Weave.Crypto.decrypt(this.ciphertext,
+ keyBundle.encryptionKeyB64, this.IV);
let json_result = JSON.parse(cleartext);
if (json_result && (json_result instanceof Object)) {
this.cleartext = json_result;
this.ciphertext = null;
} else {
throw "Decryption failed: result is <" + json_result + ">, not an object.";
}
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -20,16 +20,17 @@ const KEYS_WBO = "keys";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/async.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/engines/clients.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/resource.js");
Cu.import("resource://services-sync/rest.js");
Cu.import("resource://services-sync/stages/enginesync.js");
Cu.import("resource://services-sync/stages/declined.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/telemetry.js");
@@ -148,17 +149,17 @@ Sync11Service.prototype = {
this.metaURL = this.storageURL + "meta/global";
this.cryptoKeysURL = this.storageURL + CRYPTO_COLLECTION + "/" + KEYS_WBO;
},
_checkCrypto: function _checkCrypto() {
let ok = false;
try {
- let iv = Svc.Crypto.generateRandomIV();
+ let iv = Weave.Crypto.generateRandomIV();
if (iv.length == 24)
ok = true;
} catch (e) {
this._log.debug("Crypto check failed: " + e);
}
return ok;
--- a/services/sync/modules/util.js
+++ b/services/sync/modules/util.js
@@ -636,21 +636,12 @@ XPCOMUtils.defineLazyGetter(Utils, "_utf
/*
* Commonly-used services
*/
this.Svc = {};
Svc.Prefs = new Preferences(PREFS_BRANCH);
Svc.Obs = Observers;
-Svc.__defineGetter__("Crypto", function() {
- let cryptoSvc;
- let ns = {};
- Cu.import("resource://services-crypto/WeaveCrypto.js", ns);
- cryptoSvc = new ns.WeaveCrypto();
- delete Svc.Crypto;
- return Svc.Crypto = cryptoSvc;
-});
-
Svc.Obs.add("xpcom-shutdown", function() {
for (let name in Svc)
delete Svc[name];
});
--- a/services/sync/tests/unit/test_bookmark_order.js
+++ b/services/sync/tests/unit/test_bookmark_order.js
@@ -1,14 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
_("Making sure after processing incoming bookmarks, they show up in the right order");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/engines/bookmarks.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services/sync/utils.js");
function run_test() {
Svc.Prefs.set("log.logger.engine.bookmarks", "Trace");
initTestLogging("Trace");
Log.repository.getLogger("Sqlite").level = Log.Level.Info;
@@ -38,18 +39,18 @@ function serverForFoo(engine) {
},
},
crypto: {
keys: encryptPayload({
id: "keys",
// Generate a fake default key bundle to avoid resetting the client
// before the first sync.
default: [
- Svc.Crypto.generateRandomKey(),
- Svc.Crypto.generateRandomKey(),
+ Weave.Crypto.generateRandomKey(),
+ Weave.Crypto.generateRandomKey(),
],
}),
},
[engine.name]: {},
});
}
async function resolveConflict(engine, collection, timestamp, buildTree,
--- a/services/sync/tests/unit/test_corrupt_keys.js
+++ b/services/sync/tests/unit/test_corrupt_keys.js
@@ -1,14 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/engines/tabs.js");
Cu.import("resource://services-sync/engines/history.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services/sync/utils.js");
@@ -40,18 +41,18 @@ add_task(async function test_locally_cha
await configureIdentity({ username: "johndoe" }, server);
// We aren't doing a .login yet, so fudge the cluster URL.
Service.clusterURL = Service.identity._token.endpoint;
Service.engineManager.register(HistoryEngine);
Service.engineManager.unregister("addons");
function corrupt_local_keys() {
- Service.collectionKeys._default.keyPair = [Svc.Crypto.generateRandomKey(),
- Svc.Crypto.generateRandomKey()];
+ Service.collectionKeys._default.keyPair = [Weave.Crypto.generateRandomKey(),
+ Weave.Crypto.generateRandomKey()];
}
_("Setting meta.");
// Bump version on the server.
let m = new WBORecord("meta", "global");
m.payload = {"syncID": "foooooooooooooooooooooooooo",
"storageVersion": STORAGE_VERSION};
--- a/services/sync/tests/unit/test_keys.js
+++ b/services/sync/tests/unit/test_keys.js
@@ -1,13 +1,14 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/keys.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/browserid_identity.js");
Cu.import("resource://testing-common/services/sync/utils.js");
var collectionKeys = new CollectionKeyManager();
function sha256HMAC(message, key) {
@@ -178,20 +179,20 @@ add_task(async function test_ensureLogge
/*
* Build a test version of storage/crypto/keys.
* Encrypt it with the sync key.
* Pass it into the CollectionKeyManager.
*/
log.info("Building storage keys...");
let storage_keys = new CryptoWrapper("crypto", "keys");
- let default_key64 = Svc.Crypto.generateRandomKey();
- let default_hmac64 = Svc.Crypto.generateRandomKey();
- let bookmarks_key64 = Svc.Crypto.generateRandomKey();
- let bookmarks_hmac64 = Svc.Crypto.generateRandomKey();
+ let default_key64 = Weave.Crypto.generateRandomKey();
+ let default_hmac64 = Weave.Crypto.generateRandomKey();
+ let bookmarks_key64 = Weave.Crypto.generateRandomKey();
+ let bookmarks_hmac64 = Weave.Crypto.generateRandomKey();
storage_keys.cleartext = {
"default": [default_key64, default_hmac64],
"collections": {"bookmarks": [bookmarks_key64, bookmarks_hmac64]},
};
storage_keys.modified = Date.now() / 1000;
storage_keys.id = "keys";
--- a/services/sync/tests/unit/test_syncengine_sync.js
+++ b/services/sync/tests/unit/test_syncengine_sync.js
@@ -1,13 +1,14 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js");
+Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/resource.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services/sync/rotaryengine.js");
Cu.import("resource://testing-common/services/sync/utils.js");
@@ -1082,18 +1083,18 @@ add_task(async function test_processInco
collection._wbos.nojson2 = new ServerWBO("nojson2", "This is invalid JSON");
collection._wbos.scotsman = new ServerWBO(
"scotsman", encryptPayload({id: "scotsman",
denomination: "Flying Scotsman"}));
collection._wbos.nodecrypt = new ServerWBO("nodecrypt", "Decrypt this!");
collection._wbos.nodecrypt2 = new ServerWBO("nodecrypt2", "Decrypt this!");
// Patch the fake crypto service to throw on the record above.
- Svc.Crypto._decrypt = Svc.Crypto.decrypt;
- Svc.Crypto.decrypt = function(ciphertext) {
+ Weave.Crypto._decrypt = Weave.Crypto.decrypt;
+ Weave.Crypto.decrypt = function(ciphertext) {
if (ciphertext == "Decrypt this!") {
throw "Derp! Cipher finalized failed. Im ur crypto destroyin ur recordz.";
}
return this._decrypt.apply(this, arguments);
};
// Some broken records also exist locally.
let engine = makeRotaryEngine();
--- a/toolkit/components/extensions/ExtensionStorageSync.jsm
+++ b/toolkit/components/extensions/ExtensionStorageSync.jsm
@@ -68,25 +68,28 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "Log",
"resource://gre/modules/Log.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Observers",
"resource://services-common/observers.js");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
"resource://gre/modules/Sqlite.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Svc",
- "resource://services-sync/util.js");
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource://services-sync/util.js");
XPCOMUtils.defineLazyPreferenceGetter(this, "prefPermitsStorageSync",
STORAGE_SYNC_ENABLED_PREF, true);
XPCOMUtils.defineLazyPreferenceGetter(this, "prefStorageSyncServerURL",
STORAGE_SYNC_SERVER_URL_PREF,
KINTO_DEFAULT_SERVER_URL);
+XPCOMUtils.defineLazyGetter(this, "WeaveCrypto", function() {
+ let {WeaveCrypto} = Cu.import("resource://services-crypto/WeaveCrypto.js", {});
+ return new WeaveCrypto();
+});
+
const {
runSafeSyncWithoutClone,
} = ExtensionUtils;
// Map of Extensions to Set<Contexts> to track contexts that are still
// "live" and use storage.sync.
const extensionContexts = new Map();
// Borrow logger from Sync.
@@ -175,19 +178,19 @@ class EncryptionRemoteTransformer {
if (record.ciphertext) {
throw new Error("Attempt to reencrypt??");
}
let id = await this.getEncodedRecordId(record);
if (!id) {
throw new Error("Record ID is missing or invalid");
}
- let IV = Svc.Crypto.generateRandomIV();
- let ciphertext = Svc.Crypto.encrypt(JSON.stringify(record),
- keyBundle.encryptionKeyB64, IV);
+ let IV = WeaveCrypto.generateRandomIV();
+ let ciphertext = WeaveCrypto.encrypt(JSON.stringify(record),
+ keyBundle.encryptionKeyB64, IV);
let hmac = ciphertextHMAC(keyBundle, id, IV, ciphertext);
const encryptedResult = {ciphertext, IV, hmac, id};
// Copy over the _status field, so that we handle concurrency
// headers (If-Match, If-None-Match) correctly.
// DON'T copy over "deleted" status, because then we'd leak
// plaintext deletes.
encryptedResult._status = record._status == "deleted" ? "updated" : record._status;
@@ -210,18 +213,18 @@ class EncryptionRemoteTransformer {
// Authenticate the encrypted blob with the expected HMAC
let computedHMAC = ciphertextHMAC(keyBundle, record.id, record.IV, record.ciphertext);
if (computedHMAC != record.hmac) {
Utils.throwHMACMismatch(record.hmac, computedHMAC);
}
// Handle invalid data here. Elsewhere we assume that cleartext is an object.
- let cleartext = Svc.Crypto.decrypt(record.ciphertext,
- keyBundle.encryptionKeyB64, record.IV);
+ let cleartext = WeaveCrypto.decrypt(record.ciphertext,
+ keyBundle.encryptionKeyB64, record.IV);
let jsonResult = JSON.parse(cleartext);
if (!jsonResult || typeof jsonResult !== "object") {
throw new Error("Decryption failed: result is <" + jsonResult + ">, not an object.");
}
if (record.hasOwnProperty("last_modified")) {
jsonResult.last_modified = record.last_modified;
}