From 10c44ccccd1e449f418a96992910ce1274692a87 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Wed, 6 Oct 2010 17:57:15 +0200 Subject: [PATCH 01/16] Backed out changeset 4ad5b1467331 Bug 583209 - Use ctypes.libraryName and don't use a full path to load libnss3 from weavecrypto. --- services/crypto/WeaveCrypto.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/services/crypto/WeaveCrypto.js b/services/crypto/WeaveCrypto.js index 81859c56e892..2939a527416c 100644 --- a/services/crypto/WeaveCrypto.js +++ b/services/crypto/WeaveCrypto.js @@ -107,12 +107,34 @@ WeaveCrypto.prototype = { Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); // Open the NSS library. - let path = ctypes.libraryName("nss3"); - - this.log("Using NSS library " + path); + let nssfile = Services.dirsvc.get("GreD", Ci.nsILocalFile); + let os = Services.appinfo.OS; + switch (os) { + case "WINNT": + case "WINMO": + case "WINCE": + nssfile.append("nss3.dll"); + break; + case "Darwin": + nssfile.append("libnss3.dylib"); + break; + case "Linux": + case "SunOS": + case "WebOS": // Palm Pre + nssfile.append("libnss3.so"); + break; + case "Android": + // Android uses a $GREDIR/lib/ subdir. + nssfile.append("lib"); + nssfile.append("libnss3.so"); + break; + default: + throw Components.Exception("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); + } + this.log("Using NSS library " + nssfile.path); // XXX really want to be able to pass specific dlopen flags here. - let nsslib = ctypes.open(path); + let nsslib = ctypes.open(nssfile.path); this.log("Initializing NSS types and function declarations..."); From 61d949b8384b3f59b58af26485c64f3e94fed111 Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Mon, 11 Oct 2010 12:46:53 -0400 Subject: [PATCH 02/16] Bug 599928 - Need a single pref to toggle logging [r=mconnor] --- services/sync/modules/service.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/services/sync/modules/service.js b/services/sync/modules/service.js index cc0a0ea3ee0a..c16b10a5fe40 100644 --- a/services/sync/modules/service.js +++ b/services/sync/modules/service.js @@ -357,22 +357,26 @@ WeaveSvc.prototype = { dapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.dump")]; root.addAppender(dapp); - let verbose = Svc.Directory.get("ProfD", Ci.nsIFile); - verbose.QueryInterface(Ci.nsILocalFile); - verbose.append("weave"); - verbose.append("logs"); - verbose.append("verbose-log.txt"); - if (!verbose.exists()) - verbose.create(verbose.NORMAL_FILE_TYPE, PERMS_FILE); - - let maxSize = 65536; // 64 * 1024 (64KB) - this._debugApp = new Log4Moz.RotatingFileAppender(verbose, formatter, maxSize); - this._debugApp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.debugLog")]; - root.addAppender(this._debugApp); + let enabled = Svc.Prefs.get("log.appender.debugLog.enabled", false); + if (enabled) { + let verbose = Svc.Directory.get("ProfD", Ci.nsIFile); + verbose.QueryInterface(Ci.nsILocalFile); + verbose.append("weave"); + verbose.append("logs"); + verbose.append("verbose-log.txt"); + if (!verbose.exists()) + verbose.create(verbose.NORMAL_FILE_TYPE, PERMS_FILE); + + let maxSize = 65536; // 64 * 1024 (64KB) + this._debugApp = new Log4Moz.RotatingFileAppender(verbose, formatter, maxSize); + this._debugApp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.debugLog")]; + root.addAppender(this._debugApp); + } }, clearLogs: function WeaveSvc_clearLogs() { - this._debugApp.clear(); + if (this._debugApp) + this._debugApp.clear(); }, /** From 36d5e5299f91ec9463ffe3298b862dc001a7c7ce Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 14 Oct 2010 07:12:19 +0200 Subject: [PATCH 03/16] Bug 597404 - History sync: Null id for anno! (invalid uri) [r=mconnor] Don't fail history sync when the places DB contains invalid URIs. --- services/sync/modules/engines/history.js | 9 ++++++++- services/sync/tests/unit/test_history_store.js | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/services/sync/modules/engines/history.js b/services/sync/modules/engines/history.js index 5519ef724ad4..c7c3f027d65f 100644 --- a/services/sync/modules/engines/history.js +++ b/services/sync/modules/engines/history.js @@ -48,12 +48,19 @@ Cu.import("resource://services-sync/stores.js"); Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/type_records/history.js"); Cu.import("resource://services-sync/util.js"); +Cu.import("resource://services-sync/log4moz.js"); // Create some helper functions to handle GUIDs function setGUID(uri, guid) { if (arguments.length == 1) guid = Utils.makeGUID(); - Utils.anno(uri, GUID_ANNO, guid, "WITH_HISTORY"); + + try { + Utils.anno(uri, GUID_ANNO, guid, "WITH_HISTORY"); + } catch (ex) { + let log = Log4Moz.repository.getLogger("Engine.History"); + log.warn("Couldn't annotate URI " + uri + ": " + ex); + } return guid; } function GUIDForUri(uri, create) { diff --git a/services/sync/tests/unit/test_history_store.js b/services/sync/tests/unit/test_history_store.js index 8e182b1fead4..40edec2d4291 100644 --- a/services/sync/tests/unit/test_history_store.js +++ b/services/sync/tests/unit/test_history_store.js @@ -113,6 +113,14 @@ function run_test() { do_check_eq(queryres[0].time, TIMESTAMP3); do_check_eq(queryres[0].title, "The bird is the word!"); + _("Make sure we handle invalid URLs in places databases gracefully."); + let query = "INSERT INTO moz_places " + + "(url, title, rev_host, visit_count, last_visit_date) " + + "VALUES ('invalid-uri', 'Invalid URI', '.', 1, " + TIMESTAMP3 + ")"; + let stmt = Utils.createStatement(Svc.History.DBConnection, query); + let result = Utils.queryAsync(stmt); + do_check_eq([id for (id in store.getAllIDs())].length, 3); + _("Remove a record from the store."); store.remove({id: fxguid}); do_check_false(store.itemExists(fxguid)); From 7696d8b879dc9fd840c4eb3a179baa81cf97fe8c Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 14 Oct 2010 10:59:08 +0200 Subject: [PATCH 04/16] Bug 603502 - Syncing an account with email will generate a nonsensical device name [r=mconnor] --- services/sync/modules/engines/clients.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/sync/modules/engines/clients.js b/services/sync/modules/engines/clients.js index 193fddcfb21b..b4c85e60e741 100644 --- a/services/sync/modules/engines/clients.js +++ b/services/sync/modules/engines/clients.js @@ -129,7 +129,7 @@ ClientEngine.prototype = { // Generate a client name if we don't have a useful one yet let user = Svc.Env.get("USER") || Svc.Env.get("USERNAME") || - Svc.Prefs.get("username"); + Svc.Prefs.get("account") || Svc.Prefs.get("username"); let brand = new StringBundle("chrome://branding/locale/brand.properties"); let app = brand.get("brandShortName"); From 5d0af86da923333ac6d29db2e27f86543e6d067f Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 14 Oct 2010 21:17:35 +0200 Subject: [PATCH 05/16] Bug 562431 - Rewrite WeaveCrypto as a .jsm [r=mconnor] --HG-- rename : services/crypto/WeaveCrypto.js => services/crypto/modules/WeaveCrypto.js --- services/crypto/{ => modules}/WeaveCrypto.js | 23 ++++--------------- services/sync/Weave.js | 16 ++++++++----- services/sync/modules/util.js | 21 ++++++++++++----- services/sync/tests/unit/test_crypto_crypt.js | 2 +- 4 files changed, 30 insertions(+), 32 deletions(-) rename services/crypto/{ => modules}/WeaveCrypto.js (98%) diff --git a/services/crypto/WeaveCrypto.js b/services/crypto/modules/WeaveCrypto.js similarity index 98% rename from services/crypto/WeaveCrypto.js rename to services/crypto/modules/WeaveCrypto.js index 2939a527416c..55d3b7d279dd 100644 --- a/services/crypto/WeaveCrypto.js +++ b/services/crypto/modules/WeaveCrypto.js @@ -34,26 +34,21 @@ * * ***** END LICENSE BLOCK ***** */ +const EXPORTED_SYMBOLS = ["WeaveCrypto"]; const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -try { - Components.utils.import("resource://gre/modules/Services.jsm"); - Components.utils.import("resource://gre/modules/ctypes.jsm"); -} -catch(ex) {} +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/ctypes.jsm"); function WeaveCrypto() { this.init(); } WeaveCrypto.prototype = { - classDescription: "WeaveCrypto", - contractID: "@labs.mozilla.com/Weave/Crypto;2", - classID: Components.ID("{7fa20841-c90e-4432-a1a1-ba3b20cb6b37}"), QueryInterface: XPCOMUtils.generateQI([Ci.IWeaveCrypto]), prefBranch : null, @@ -1004,7 +999,7 @@ WeaveCrypto.prototype = { byteCompress : function (jsString, charArray) { let intArray = ctypes.cast(charArray, ctypes.uint8_t.array(charArray.length)); for (let i = 0; i < jsString.length; i++) - intArray[i] = jsString.charCodeAt(i); + intArray[i] = jsString.charCodeAt(i) % 256; // convert to bytes }, // Expand a normal C string (1-byte chars) into a JS string (2-byte chars) @@ -1124,13 +1119,3 @@ WeaveCrypto.prototype = { } } }; - -// Gecko <2.0 -let component = typeof Services == "undefined" || typeof ctypes == "undefined" ? [] : [WeaveCrypto]; -function NSGetModule (compMgr, fileSpec) { - return XPCOMUtils.generateModule(component); -} - -// Gecko >=2.0 -if (typeof XPCOMUtils.generateNSGetFactory == "function") - const NSGetFactory = XPCOMUtils.generateNSGetFactory([WeaveCrypto]); diff --git a/services/sync/Weave.js b/services/sync/Weave.js index a4645d7bf451..dbe4608fb2be 100644 --- a/services/sync/Weave.js +++ b/services/sync/Weave.js @@ -83,12 +83,16 @@ WeaveService.prototype = { .QueryInterface(Ci.nsIResProtocolHandler); // Only create alias if resource://services-sync doesn't already exist. - if (resProt.hasSubstitution("services-sync")) - return; - - let uri = ioService.newURI("resource:///modules/services-sync/", - null, null); - resProt.setSubstitution("services-sync", uri); + if (!resProt.hasSubstitution("services-sync")) { + let uri = ioService.newURI("resource:///modules/services-sync/", + null, null); + resProt.setSubstitution("services-sync", uri); + } + if (!resProt.hasSubstitution("services-crypto")) { + let uri = ioService.newURI("resource:///modules/services-crypto/", + null, null); + resProt.setSubstitution("services-crypto", uri); + } } }; diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index 0de51b54a6a4..78af94fd6541 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -997,11 +997,6 @@ let FakeSvc = { } }; -// Use the binary WeaveCrypto (;1) if the js-ctypes version (;2) fails to load -// by adding an alias on FakeSvc from ;2 to ;1 -Utils.lazySvc(FakeSvc, "@labs.mozilla.com/Weave/Crypto;2", - "@labs.mozilla.com/Weave/Crypto;1", "IWeaveCrypto"); - /* * Commonly-used services */ @@ -1019,7 +1014,6 @@ this.__defineGetter__("_sessionCID", function() { [["Annos", "@mozilla.org/browser/annotation-service;1", "nsIAnnotationService"], ["AppInfo", "@mozilla.org/xre/app-info;1", "nsIXULAppInfo"], ["Bookmark", "@mozilla.org/browser/nav-bookmarks-service;1", "nsINavBookmarksService"], - ["Crypto", "@labs.mozilla.com/Weave/Crypto;2", "IWeaveCrypto"], ["Directory", "@mozilla.org/file/directory_service;1", "nsIProperties"], ["Env", "@mozilla.org/process/environment;1", "nsIEnvironment"], ["Favicon", "@mozilla.org/browser/favicon-service;1", "nsIFaviconService"], @@ -1041,6 +1035,21 @@ this.__defineGetter__("_sessionCID", function() { ["Session", this._sessionCID, "nsISessionStore"], ].forEach(function(lazy) Utils.lazySvc(Svc, lazy[0], lazy[1], lazy[2])); +Svc.__defineGetter__("Crypto", function() { + let cryptoSvc; + try { + let ns = {}; + Cu.import("resource://services-crypto/WeaveCrypto.js", ns); + cryptoSvc = new ns.WeaveCrypto(); + } catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]. + getService(Ci.IWeaveCrypto); + } + delete Svc.Crypto; + return Svc.Crypto = cryptoSvc; +}); + let Str = {}; ["errors", "sync"] .forEach(function(lazy) Utils.lazy2(Str, lazy, Utils.lazyStrings(lazy))); diff --git a/services/sync/tests/unit/test_crypto_crypt.js b/services/sync/tests/unit/test_crypto_crypt.js index 46cdc37d8d70..a42eb3aeccbf 100644 --- a/services/sync/tests/unit/test_crypto_crypt.js +++ b/services/sync/tests/unit/test_crypto_crypt.js @@ -119,7 +119,7 @@ function run_test() { do_check_eq(cipherText, "T6fik9Ros+DB2ablH9zZ8FWZ0xm/szSwJjIHZu7sjPs="); var badkey = "badkeybadkeybadkeybadk=="; - var badiv = "badivbadivbadivbadivbad=="; + var badiv = "badivbadivbadivbadivbad="; var badcipher = "crapinputcrapinputcrapinputcrapinputcrapinp="; var failure; From 9d3f32839349f26fa17a5984f52c5dee76785299 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 14 Oct 2010 21:17:55 +0200 Subject: [PATCH 06/16] Bug 562431 - Move tests for WeaveCrypto to services/crypto/ [r=mconnor] --HG-- rename : services/sync/tests/unit/test_crypto_crypt.js => services/crypto/tests/unit/test_crypto_crypt.js rename : services/sync/tests/unit/test_crypto_keypair.js => services/crypto/tests/unit/test_crypto_keypair.js rename : services/sync/tests/unit/test_crypto_random.js => services/crypto/tests/unit/test_crypto_random.js rename : services/sync/tests/unit/test_crypto_rewrap.js => services/crypto/tests/unit/test_crypto_rewrap.js rename : services/sync/tests/unit/test_crypto_verify.js => services/crypto/tests/unit/test_crypto_verify.js --- services/crypto/tests/unit/head_helpers.js | 66 +++++++++++++++++++ .../tests/unit/test_crypto_crypt.js | 12 +++- .../tests/unit/test_crypto_keypair.js | 12 +++- .../tests/unit/test_crypto_random.js | 12 +++- .../tests/unit/test_crypto_rewrap.js | 12 +++- .../tests/unit/test_crypto_verify.js | 12 +++- 6 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 services/crypto/tests/unit/head_helpers.js rename services/{sync => crypto}/tests/unit/test_crypto_crypt.js (94%) rename services/{sync => crypto}/tests/unit/test_crypto_keypair.js (87%) rename services/{sync => crypto}/tests/unit/test_crypto_random.js (88%) rename services/{sync => crypto}/tests/unit/test_crypto_rewrap.js (81%) rename services/{sync => crypto}/tests/unit/test_crypto_verify.js (72%) diff --git a/services/crypto/tests/unit/head_helpers.js b/services/crypto/tests/unit/head_helpers.js new file mode 100644 index 000000000000..611554892004 --- /dev/null +++ b/services/crypto/tests/unit/head_helpers.js @@ -0,0 +1,66 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +try { + // In the context of xpcshell tests, there won't be a default AppInfo + Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo); +} +catch(ex) { + +// Make sure to provide the right OS so crypto loads the right binaries +let OS = "XPCShell"; +if ("@mozilla.org/windows-registry-key;1" in Cc) + OS = "WINNT"; +else if ("nsILocalFileMac" in Ci) + OS = "Darwin"; +else + OS = "Linux"; + +let XULAppInfo = { + vendor: "Mozilla", + name: "XPCShell", + ID: "{3e3ba16c-1675-4e88-b9c8-afef81b3d2ef}", + version: "1", + appBuildID: "20100621", + platformVersion: "", + platformBuildID: "20100621", + inSafeMode: false, + logConsoleErrors: true, + OS: OS, + XPCOMABI: "noarch-spidermonkey", + QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, Ci.nsIXULRuntime]) +}; + +let XULAppInfoFactory = { + createInstance: function (outer, iid) { + if (outer != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + return XULAppInfo.QueryInterface(iid); + } +}; + +let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); +registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"), + "XULAppInfo", "@mozilla.org/xre/app-info;1", + XULAppInfoFactory); + +} + +// Provide resource://services-crypto if it isn't already available +let weaveService = Cc["@mozilla.org/weave/service;1"].getService(); +weaveService.wrappedJSObject.addResourceAlias(); + +/** + * Print some debug message to the console. All arguments will be printed, + * separated by spaces. + * + * @param [arg0, arg1, arg2, ...] + * Any number of arguments to print out + * @usage _("Hello World") -> prints "Hello World" + * @usage _(1, 2, 3) -> prints "1 2 3" + */ +let _ = function(some, debug, text, to) print(Array.slice(arguments).join(" ")); diff --git a/services/sync/tests/unit/test_crypto_crypt.js b/services/crypto/tests/unit/test_crypto_crypt.js similarity index 94% rename from services/sync/tests/unit/test_crypto_crypt.js rename to services/crypto/tests/unit/test_crypto_crypt.js index a42eb3aeccbf..dc53002dab7d 100644 --- a/services/sync/tests/unit/test_crypto_crypt.js +++ b/services/crypto/tests/unit/test_crypto_crypt.js @@ -1,8 +1,14 @@ -Cu.import("resource://services-sync/util.js"); +let cryptoSvc; +try { + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); +} catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] + .getService(Ci.IWeaveCrypto); +} function run_test() { - let cryptoSvc = Svc.Crypto; - // First, do a normal run with expected usage... Generate a random key and // iv, encrypt and decrypt a string. var iv = cryptoSvc.generateRandomIV(); diff --git a/services/sync/tests/unit/test_crypto_keypair.js b/services/crypto/tests/unit/test_crypto_keypair.js similarity index 87% rename from services/sync/tests/unit/test_crypto_keypair.js rename to services/crypto/tests/unit/test_crypto_keypair.js index 024e297a9d68..8ea7907f6370 100644 --- a/services/sync/tests/unit/test_crypto_keypair.js +++ b/services/crypto/tests/unit/test_crypto_keypair.js @@ -1,8 +1,14 @@ -Cu.import("resource://services-sync/util.js"); +let cryptoSvc; +try { + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); +} catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] + .getService(Ci.IWeaveCrypto); +} function run_test() { - let cryptoSvc = Svc.Crypto; - var salt = cryptoSvc.generateRandomBytes(16); do_check_eq(salt.length, 24); diff --git a/services/sync/tests/unit/test_crypto_random.js b/services/crypto/tests/unit/test_crypto_random.js similarity index 88% rename from services/sync/tests/unit/test_crypto_random.js rename to services/crypto/tests/unit/test_crypto_random.js index 4eeff02b7f81..ab85169be6b9 100644 --- a/services/sync/tests/unit/test_crypto_random.js +++ b/services/crypto/tests/unit/test_crypto_random.js @@ -1,8 +1,14 @@ -Cu.import("resource://services-sync/util.js"); +let cryptoSvc; +try { + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); +} catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] + .getService(Ci.IWeaveCrypto); +} function run_test() { - let cryptoSvc = Svc.Crypto; - // Test salt generation. var salt; diff --git a/services/sync/tests/unit/test_crypto_rewrap.js b/services/crypto/tests/unit/test_crypto_rewrap.js similarity index 81% rename from services/sync/tests/unit/test_crypto_rewrap.js rename to services/crypto/tests/unit/test_crypto_rewrap.js index bc2aa01d2192..d9568d6e66aa 100644 --- a/services/sync/tests/unit/test_crypto_rewrap.js +++ b/services/crypto/tests/unit/test_crypto_rewrap.js @@ -1,8 +1,14 @@ -Cu.import("resource://services-sync/util.js"); +let cryptoSvc; +try { + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); +} catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] + .getService(Ci.IWeaveCrypto); +} function run_test() { - let cryptoSvc = Svc.Crypto; - var salt = cryptoSvc.generateRandomBytes(16); var iv = cryptoSvc.generateRandomIV(); var symKey = cryptoSvc.generateRandomKey(); diff --git a/services/sync/tests/unit/test_crypto_verify.js b/services/crypto/tests/unit/test_crypto_verify.js similarity index 72% rename from services/sync/tests/unit/test_crypto_verify.js rename to services/crypto/tests/unit/test_crypto_verify.js index eefbd3a23ef0..5475503e69da 100644 --- a/services/sync/tests/unit/test_crypto_verify.js +++ b/services/crypto/tests/unit/test_crypto_verify.js @@ -1,8 +1,14 @@ -Cu.import("resource://services-sync/util.js"); +let cryptoSvc; +try { + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); +} catch (ex) { + // Fallback to binary WeaveCrypto + cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] + .getService(Ci.IWeaveCrypto); +} function run_test() { - let cryptoSvc = Svc.Crypto; - var salt = cryptoSvc.generateRandomBytes(16); var iv = cryptoSvc.generateRandomIV(); From 1fd27817dfe6f03959de5bb17c661d2dd9c8a831 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 14 Oct 2010 21:22:29 +0200 Subject: [PATCH 07/16] Bug 570619 - Move crypto off the main thread [r=mconnor,sdwilsh] Provide a ThreadedCrypto object that defers method calls to another thread while keeping the synchronous API. --- services/crypto/modules/WeaveCrypto.js | 92 ++++++----- services/crypto/modules/threaded.js | 150 ++++++++++++++++++ services/crypto/tests/unit/head_helpers.js | 2 + .../crypto/tests/unit/test_crypto_crypt.js | 4 +- .../crypto/tests/unit/test_crypto_keypair.js | 4 +- .../crypto/tests/unit/test_crypto_random.js | 4 +- .../crypto/tests/unit/test_crypto_rewrap.js | 4 +- .../crypto/tests/unit/test_crypto_verify.js | 4 +- services/sync/modules/util.js | 4 +- 9 files changed, 213 insertions(+), 55 deletions(-) create mode 100644 services/crypto/modules/threaded.js diff --git a/services/crypto/modules/WeaveCrypto.js b/services/crypto/modules/WeaveCrypto.js index 55d3b7d279dd..ae7dbf819f8a 100644 --- a/services/crypto/modules/WeaveCrypto.js +++ b/services/crypto/modules/WeaveCrypto.js @@ -71,6 +71,12 @@ WeaveCrypto.prototype = { } }, + // This is its own method so that it can be overridden. + // (Components.Exception isn't thread-safe for instance) + makeException : function makeException(message, result) { + return Components.Exception(message, result); + }, + init : function() { try { // Preferences. Add observer so we get notified of changes. @@ -124,7 +130,7 @@ WeaveCrypto.prototype = { nssfile.append("libnss3.so"); break; default: - throw Components.Exception("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); + throw this.makeException("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); } this.log("Using NSS library " + nssfile.path); @@ -524,31 +530,31 @@ WeaveCrypto.prototype = { let mechanism = this.nss.PK11_AlgtagToMechanism(this.algorithm); mechanism = this.nss.PK11_GetPadMechanism(mechanism); if (mechanism == this.nss.CKM_INVALID_MECHANISM) - throw Components.Exception("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE); + throw this.makeException("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE); let ctx, symKey, slot, ivParam; try { ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address()); if (ivParam.isNull()) - throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE); + throw this.makeException("can't convert IV to param", Cr.NS_ERROR_FAILURE); slot = this.nss.PK11_GetInternalKeySlot(); if (slot.isNull()) - throw Components.Exception("can't get internal key slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("can't get internal key slot", Cr.NS_ERROR_FAILURE); symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null); if (symKey.isNull()) - throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); ctx = this.nss.PK11_CreateContextBySymKey(mechanism, operation, symKey, ivParam); if (ctx.isNull()) - throw Components.Exception("couldn't create context for symkey", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't create context for symkey", Cr.NS_ERROR_FAILURE); let maxOutputSize = output.length; let tmpOutputSize = new ctypes.int(); // Note 1: NSS uses a signed int here... if (this.nss.PK11_CipherOp(ctx, output, tmpOutputSize.address(), maxOutputSize, input, input.length)) - throw Components.Exception("cipher operation failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("cipher operation failed", Cr.NS_ERROR_FAILURE); let actualOutputSize = tmpOutputSize.value; let finalOutput = output.addressOfElement(actualOutputSize); @@ -559,7 +565,7 @@ WeaveCrypto.prototype = { // cipher operation. You'd think it would be called PK11_CipherOpFinal... let tmpOutputSize2 = new ctypes.unsigned_int(); // Note 2: ...but an unsigned here! if (this.nss.PK11_DigestFinal(ctx, finalOutput, tmpOutputSize2.address(), maxOutputSize)) - throw Components.Exception("cipher finalize failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("cipher finalize failed", Cr.NS_ERROR_FAILURE); actualOutputSize += tmpOutputSize2.value; let newOutput = ctypes.cast(output, ctypes.unsigned_char.array(actualOutputSize)); @@ -598,7 +604,7 @@ WeaveCrypto.prototype = { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // Generate the keypair. privKey = this.nss.PK11_GenerateKeyPairWithFlags(slot, @@ -607,18 +613,18 @@ WeaveCrypto.prototype = { pubKey.address(), attrFlags, null); if (privKey.isNull()) - throw Components.Exception("keypair generation failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("keypair generation failed", Cr.NS_ERROR_FAILURE); let s = this.nss.PK11_SetPrivateKeyNickname(privKey, "Weave User PrivKey"); if (s) - throw Components.Exception("key nickname failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("key nickname failed", Cr.NS_ERROR_FAILURE); let wrappedPrivateKey = this._wrapPrivateKey(privKey, passphrase, salt, iv); out_wrappedPrivateKey.value = wrappedPrivateKey; // outparam let derKey = this.nss.SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey); if (derKey.isNull()) - throw Components.Exception("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); let encodedPublicKey = this.encodeBase64(derKey.contents.data, derKey.contents.len); out_encodedPublicKey.value = encodedPublicKey; // outparam @@ -658,27 +664,27 @@ WeaveCrypto.prototype = { break; default: - throw Components.Exception("unknown algorithm", Cr.NS_ERROR_FAILURE); + throw this.makeException("unknown algorithm", Cr.NS_ERROR_FAILURE); } let slot, randKey, keydata; try { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); randKey = this.nss.PK11_KeyGen(slot, keygenMech, null, keySize, null); if (randKey.isNull()) - throw Components.Exception("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE); // Slightly odd API, this call just prepares the key value for // extraction, we get the actual bits from the call to PK11_GetKeyData(). if (this.nss.PK11_ExtractKeyValue(randKey)) - throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); keydata = this.nss.PK11_GetKeyData(randKey); if (keydata.isNull()) - throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); return this.encodeBase64(keydata.contents.data, keydata.contents.len); } catch (e) { @@ -709,7 +715,7 @@ WeaveCrypto.prototype = { // Temporary buffer to hold the generated data. let scratch = new ctypes.ArrayType(ctypes.unsigned_char, byteCount)(); if (this.nss.PK11_GenerateRandom(scratch, byteCount)) - throw Components.Exception("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE); return this.encodeBase64(scratch.address(), scratch.length); }, @@ -732,7 +738,7 @@ WeaveCrypto.prototype = { try { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // ImportSymKey wants a mechanism, from which it derives the key type. let keyMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); @@ -741,7 +747,7 @@ WeaveCrypto.prototype = { // really matter because we're just going to wrap it up and not use it. symKey = this.nss.PK11_ImportSymKey(slot, keyMech, this.nss.PK11_OriginUnwrap, this.nss.CKA_ENCRYPT, symKeyData.address(), null); if (symKey.isNull()) - throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); // Step 3. Put the public key bits into a P11 key object. @@ -749,11 +755,11 @@ WeaveCrypto.prototype = { // pubKey = SECKEY_ImportDERPublicKey(&pubKeyData, CKK_RSA); pubKeyInfo = this.nss.SECKEY_DecodeDERSubjectPublicKeyInfo(pubKeyData.address()); if (pubKeyInfo.isNull()) - throw Components.Exception("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); pubKey = this.nss.SECKEY_ExtractPublicKey(pubKeyInfo); if (pubKey.isNull()) - throw Components.Exception("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Wrap the symmetric key with the public key. @@ -761,7 +767,7 @@ WeaveCrypto.prototype = { let s = this.nss.PK11_PubWrapSymKey(wrapMech, pubKey, symKey, wrappedKey.address()); if (s) - throw Components.Exception("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE); // Step 5. Base64 encode the wrapped key, cleanup, and return to caller. return this.encodeBase64(wrappedKey.data, wrappedKey.len); @@ -801,16 +807,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw Components.Exception("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw this.makeException("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw Components.Exception("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // Normally, one wants to associate a private key with a public key. // P11_UnwrapPrivKey() passes its keyID arg to PK11_MakeIDFromPubKey(), @@ -831,7 +837,7 @@ WeaveCrypto.prototype = { privKeyUsage.addressOfElement(0), privKeyUsageLength, null); // wincx if (privKey.isNull()) - throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Unwrap the symmetric key with the user's private key. @@ -840,15 +846,15 @@ WeaveCrypto.prototype = { symKey = this.nss.PK11_PubUnwrapSymKey(privKey, wrappedSymKey.address(), wrapMech, this.nss.CKA_DECRYPT, 0); if (symKey.isNull()) - throw Components.Exception("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE); // Step 5. Base64 encode the unwrapped key, cleanup, and return to caller. if (this.nss.PK11_ExtractKeyValue(symKey)) - throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); symKeyData = this.nss.PK11_GetKeyData(symKey); if (symKeyData.isNull()) - throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); return this.encodeBase64(symKeyData.contents.data, symKeyData.contents.len); } catch (e) { @@ -888,16 +894,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); let keyID = ivItem.address(); @@ -911,7 +917,7 @@ WeaveCrypto.prototype = { privKeyUsage.addressOfElement(0), privKeyUsageLength, null); // wincx if (privKey.isNull()) - throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Rewrap the private key with the new passphrase. return this._wrapPrivateKey(privKey, newPassphrase, salt, iv); @@ -950,16 +956,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); let keyID = ivItem.address(); @@ -1053,15 +1059,15 @@ WeaveCrypto.prototype = { algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg, keyLength, iterations, saltItem.address()); if (algid.isNull()) - throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null); if (symKey.isNull()) - throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); } catch (e) { this.log("_deriveKeyFromPassphrase: failed: " + e); throw e; @@ -1089,11 +1095,11 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw Components.Exception("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw this.makeException("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE); let ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw Components.Exception("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Use a buffer to hold the wrapped key. NSS says about 1200 bytes for // a 2048-bit RSA key, so a 4096 byte buffer should be plenty. @@ -1105,7 +1111,7 @@ WeaveCrypto.prototype = { wrapMech, ivParam, wrappedKey.address(), null); if (s) - throw Components.Exception("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw this.makeException("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE); return this.encodeBase64(wrappedKey.data, wrappedKey.len); } catch (e) { diff --git a/services/crypto/modules/threaded.js b/services/crypto/modules/threaded.js new file mode 100644 index 000000000000..691f2d3408a7 --- /dev/null +++ b/services/crypto/modules/threaded.js @@ -0,0 +1,150 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Firefox Sync. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Philipp von Weitershausen + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const EXPORTED_SYMBOLS = ["ThreadedCrypto"]; + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://services-sync/ext/Sync.js"); +Cu.import("resource://services-crypto/WeaveCrypto.js"); + +/* + * Execute a function in a thread. + */ +function Runner(func, thisObj, returnval, error) { + this.func = func; + this.thisObj = thisObj; + this.returnval = returnval; + this.error = error; +} +Runner.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]), + + run: function run() { + let ex = this.error; + if (ex) { + this.func.throw(ex); + } else { + this.func.call(this.thisObj, this.returnval); + } + } +}; + +/* + * Execute a function in a thread and notify a callback on another thread + * afterward. + */ +function CallbackRunner(func, thisObj, args, callback, cbThread) { + this.func = func; + this.thisObj = thisObj; + this.args = args; + this.callback = callback; + this.cbThread = cbThread; +} +CallbackRunner.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]), + + run: function run() { + let returnval, error; + try { + returnval = this.func.apply(this.thisObj, this.args); + } catch(ex) { + error = ex; + } + this.cbThread.dispatch(new Runner(this.callback, this.thisObj, + returnval, error), + Ci.nsIThread.DISPATCH_NORMAL); + } +}; + +/* + * Implementation of IWeaveCrypto that defers method calls to another thread + * but keeps the synchronous API. (Don't ask...) + */ +function ThreadedCrypto() { + this.backgroundThread = Services.tm.newThread(0); + this.crypto = new WeaveCrypto(); + + // Components.Exception isn't thread-safe. + this.crypto.makeException = function makeException(message, result) { + return result; + }; + + // Make sure to kill the thread before XPCOM shuts down. + Services.obs.addObserver(this, "profile-before-change", true); +} +ThreadedCrypto.deferToThread = function deferToThread(methodname) { + return function threadMethod() { + // Dispatch method call to background thread. + let args = Array.slice(arguments); + return Sync(function(callback) { + let runner = new CallbackRunner(this.crypto[methodname], this.crypto, + args, callback, Services.tm.mainThread); + this.backgroundThread.dispatch(runner, Ci.nsIThread.DISPATCH_NORMAL); + }, this)(); + }; +}; +ThreadedCrypto.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.IWeaveCrypto, + Ci.nsISupportsWeakReference]), + + observe: function observe() { + this.backgroundThread.shutdown(); + }, + + get algorithm() this.crypto.algorithm, + set algorithm(value) this.crypto.algorithm = value, + + get keypairBits() this.crypto.keypairBits, + set keypairBits(value) this.crypto.keypairBits = value, + + encrypt: ThreadedCrypto.deferToThread("encrypt"), + decrypt: ThreadedCrypto.deferToThread("decrypt"), + generateKeypair: ThreadedCrypto.deferToThread("generateKeypair"), + generateRandomKey: ThreadedCrypto.deferToThread("generateRandomKey"), + generateRandomIV: ThreadedCrypto.deferToThread("generateRandomIV"), + generateRandomBytes: ThreadedCrypto.deferToThread("generateRandomBytes"), + wrapSymmetricKey: ThreadedCrypto.deferToThread("wrapSymmetricKey"), + unwrapSymmetricKey: ThreadedCrypto.deferToThread("unwrapSymmetricKey"), + rewrapPrivateKey: ThreadedCrypto.deferToThread("rewrapPrivateKey"), + verifyPassphrase: ThreadedCrypto.deferToThread("verifyPassphrase") +}; diff --git a/services/crypto/tests/unit/head_helpers.js b/services/crypto/tests/unit/head_helpers.js index 611554892004..86e12ab7eac9 100644 --- a/services/crypto/tests/unit/head_helpers.js +++ b/services/crypto/tests/unit/head_helpers.js @@ -11,6 +11,8 @@ try { } catch(ex) { +do_get_profile(); + // Make sure to provide the right OS so crypto loads the right binaries let OS = "XPCShell"; if ("@mozilla.org/windows-registry-key;1" in Cc) diff --git a/services/crypto/tests/unit/test_crypto_crypt.js b/services/crypto/tests/unit/test_crypto_crypt.js index dc53002dab7d..d8104cbee16b 100644 --- a/services/crypto/tests/unit/test_crypto_crypt.js +++ b/services/crypto/tests/unit/test_crypto_crypt.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/WeaveCrypto.js"); - cryptoSvc = new WeaveCrypto(); + Components.utils.import("resource://services-crypto/threaded.js"); + cryptoSvc = new ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_keypair.js b/services/crypto/tests/unit/test_crypto_keypair.js index 8ea7907f6370..258f473319ab 100644 --- a/services/crypto/tests/unit/test_crypto_keypair.js +++ b/services/crypto/tests/unit/test_crypto_keypair.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/WeaveCrypto.js"); - cryptoSvc = new WeaveCrypto(); + Components.utils.import("resource://services-crypto/threaded.js"); + cryptoSvc = new ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_random.js b/services/crypto/tests/unit/test_crypto_random.js index ab85169be6b9..105c743f644d 100644 --- a/services/crypto/tests/unit/test_crypto_random.js +++ b/services/crypto/tests/unit/test_crypto_random.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/WeaveCrypto.js"); - cryptoSvc = new WeaveCrypto(); + Components.utils.import("resource://services-crypto/threaded.js"); + cryptoSvc = new ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_rewrap.js b/services/crypto/tests/unit/test_crypto_rewrap.js index d9568d6e66aa..67fb6ccf0206 100644 --- a/services/crypto/tests/unit/test_crypto_rewrap.js +++ b/services/crypto/tests/unit/test_crypto_rewrap.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/WeaveCrypto.js"); - cryptoSvc = new WeaveCrypto(); + Components.utils.import("resource://services-crypto/threaded.js"); + cryptoSvc = new ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_verify.js b/services/crypto/tests/unit/test_crypto_verify.js index 5475503e69da..6acdaff8deae 100644 --- a/services/crypto/tests/unit/test_crypto_verify.js +++ b/services/crypto/tests/unit/test_crypto_verify.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/WeaveCrypto.js"); - cryptoSvc = new WeaveCrypto(); + Components.utils.import("resource://services-crypto/threaded.js"); + cryptoSvc = new ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index 78af94fd6541..5e24fb4f26e5 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -1039,8 +1039,8 @@ Svc.__defineGetter__("Crypto", function() { let cryptoSvc; try { let ns = {}; - Cu.import("resource://services-crypto/WeaveCrypto.js", ns); - cryptoSvc = new ns.WeaveCrypto(); + Cu.import("resource://services-crypto/threaded.js", ns); + cryptoSvc = new ns.ThreadedCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]. From 93677ce05043ef28454aae6d276518f007049d3f Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 15 Oct 2010 11:45:31 +0200 Subject: [PATCH 08/16] Bug 583209 - Use ctypes.libraryName and don't use a full path to load libnss3 from weavecrypto. [r=dwitte] --- services/crypto/modules/WeaveCrypto.js | 39 +++++++++----------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/services/crypto/modules/WeaveCrypto.js b/services/crypto/modules/WeaveCrypto.js index ae7dbf819f8a..de16f36437b6 100644 --- a/services/crypto/modules/WeaveCrypto.js +++ b/services/crypto/modules/WeaveCrypto.js @@ -108,34 +108,21 @@ WeaveCrypto.prototype = { Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); // Open the NSS library. - let nssfile = Services.dirsvc.get("GreD", Ci.nsILocalFile); - let os = Services.appinfo.OS; - switch (os) { - case "WINNT": - case "WINMO": - case "WINCE": - nssfile.append("nss3.dll"); - break; - case "Darwin": - nssfile.append("libnss3.dylib"); - break; - case "Linux": - case "SunOS": - case "WebOS": // Palm Pre - nssfile.append("libnss3.so"); - break; - case "Android": - // Android uses a $GREDIR/lib/ subdir. - nssfile.append("lib"); - nssfile.append("libnss3.so"); - break; - default: - throw this.makeException("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); - } - this.log("Using NSS library " + nssfile.path); + let path = ctypes.libraryName("nss3"); // XXX really want to be able to pass specific dlopen flags here. - let nsslib = ctypes.open(nssfile.path); + var nsslib; + try { + this.log("Trying NSS library without path"); + nsslib = ctypes.open(path); + } catch(e) { + // In case opening the library without a full path fails, + // try again with a full path. + let file = Services.dirsvc.get("GreD", Ci.nsILocalFile); + file.append(path); + this.log("Trying again with path " + file.path); + nsslib = ctypes.open(file.path); + } this.log("Initializing NSS types and function declarations..."); From 4ecbe2537766ef94807bf4f002017f43952d41ec Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Tue, 19 Oct 2010 00:10:22 +0200 Subject: [PATCH 09/16] Bug 604565 - Attempt to make tests hang less on OS X. [r=mconnor] Reduce amount of pointless network calls by not registering any engines for tests that provide their own fake engine implementations anyway. --- .../sync/tests/unit/test_service_sync_checkServerError.js | 4 +++- .../tests/unit/test_service_sync_updateEnabledEngines.js | 6 +++++- services/sync/tests/unit/test_service_wipeClient.js | 5 ++++- services/sync/tests/unit/test_service_wipeServer.js | 4 +++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/services/sync/tests/unit/test_service_sync_checkServerError.js b/services/sync/tests/unit/test_service_sync_checkServerError.js index dc1459380f6e..f05e7b97824f 100644 --- a/services/sync/tests/unit/test_service_sync_checkServerError.js +++ b/services/sync/tests/unit/test_service_sync_checkServerError.js @@ -1,9 +1,11 @@ -Cu.import("resource://services-sync/service.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/status.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/util.js"); +Svc.DefaultPrefs.set("registerEngines", ""); +Cu.import("resource://services-sync/service.js"); + initTestLogging(); function CatapultEngine() { diff --git a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js index 92f960f1d094..50b506f2a27f 100644 --- a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js +++ b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js @@ -1,4 +1,3 @@ -Cu.import("resource://services-sync/service.js"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/constants.js"); @@ -6,6 +5,11 @@ Cu.import("resource://services-sync/base_records/crypto.js"); Cu.import("resource://services-sync/base_records/keys.js"); Cu.import("resource://services-sync/base_records/wbo.js"); +Svc.DefaultPrefs.set("registerEngines", ""); +Cu.import("resource://services-sync/service.js"); + +initTestLogging(); + function SteamEngine() { SyncEngine.call(this, "Steam"); } diff --git a/services/sync/tests/unit/test_service_wipeClient.js b/services/sync/tests/unit/test_service_wipeClient.js index 0859f380ebfe..1f4af8718834 100644 --- a/services/sync/tests/unit/test_service_wipeClient.js +++ b/services/sync/tests/unit/test_service_wipeClient.js @@ -1,5 +1,8 @@ -Cu.import("resource://services-sync/service.js"); Cu.import("resource://services-sync/engines.js"); +Cu.import("resource://services-sync/util.js"); + +Svc.DefaultPrefs.set("registerEngines", ""); +Cu.import("resource://services-sync/service.js"); function CanDecryptEngine() { diff --git a/services/sync/tests/unit/test_service_wipeServer.js b/services/sync/tests/unit/test_service_wipeServer.js index 906560f62263..9d65409c549a 100644 --- a/services/sync/tests/unit/test_service_wipeServer.js +++ b/services/sync/tests/unit/test_service_wipeServer.js @@ -1,9 +1,11 @@ Cu.import("resource://services-sync/util.js"); -Cu.import("resource://services-sync/service.js"); Cu.import("resource://services-sync/base_records/crypto.js"); Cu.import("resource://services-sync/base_records/keys.js"); Cu.import("resource://services-sync/resource.js"); +Svc.DefaultPrefs.set("registerEngines", ""); +Cu.import("resource://services-sync/service.js"); + function FakeCollection() { this.deleted = false; } From fa6d8f23241df9f74f9be42de291a815420e7591 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 21 Oct 2010 13:47:47 +0200 Subject: [PATCH 10/16] Bug 604565 - Disable intermittently failing xpcshell tests on OSX debug builds. [r=mconnor] --HG-- rename : services/sync/tests/unit/head_appinfo.js => services/sync/tests/unit/head_appinfo.js.in --- .../tests/unit/{head_appinfo.js => head_appinfo.js.in} | 9 +++++++++ .../tests/unit/test_service_sync_checkServerError.js | 3 +++ .../tests/unit/test_service_sync_updateEnabledEngines.js | 3 +++ services/sync/tests/unit/test_syncengine_sync.js | 3 +++ 4 files changed, 18 insertions(+) rename services/sync/tests/unit/{head_appinfo.js => head_appinfo.js.in} (91%) diff --git a/services/sync/tests/unit/head_appinfo.js b/services/sync/tests/unit/head_appinfo.js.in similarity index 91% rename from services/sync/tests/unit/head_appinfo.js rename to services/sync/tests/unit/head_appinfo.js.in index 278ee6dc0a12..8fa133ae0e8f 100644 --- a/services/sync/tests/unit/head_appinfo.js +++ b/services/sync/tests/unit/head_appinfo.js.in @@ -62,3 +62,12 @@ registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}" // Provide resource://services-sync if it isn't already available let weaveService = Cc["@mozilla.org/weave/service;1"].getService(); weaveService.wrappedJSObject.addResourceAlias(); + + +// Some tests hang on OSX debug builds. See bug 604565. +let DISABLE_TESTS_BUG_604565 = false; +#ifdef XP_MACOSX +#ifdef MOZ_DEBUG_SYMBOLS +DISABLE_TESTS_BUG_604565 = true; +#endif +#endif diff --git a/services/sync/tests/unit/test_service_sync_checkServerError.js b/services/sync/tests/unit/test_service_sync_checkServerError.js index f05e7b97824f..5f69a1a91348 100644 --- a/services/sync/tests/unit/test_service_sync_checkServerError.js +++ b/services/sync/tests/unit/test_service_sync_checkServerError.js @@ -132,6 +132,9 @@ function test_overQuota() { } function run_test() { + if (DISABLE_TESTS_BUG_604565) + return; + test_backoff500(); test_backoff503(); test_overQuota(); diff --git a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js index 50b506f2a27f..b6e7b89f220a 100644 --- a/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js +++ b/services/sync/tests/unit/test_service_sync_updateEnabledEngines.js @@ -342,6 +342,9 @@ function test_dependentEnginesDisabledLocally() { } function run_test() { + if (DISABLE_TESTS_BUG_604565) + return; + test_newAccount(); test_enabledLocally(); test_disabledLocally(); diff --git a/services/sync/tests/unit/test_syncengine_sync.js b/services/sync/tests/unit/test_syncengine_sync.js index 257ddee3772b..6aeb566311ce 100644 --- a/services/sync/tests/unit/test_syncengine_sync.js +++ b/services/sync/tests/unit/test_syncengine_sync.js @@ -1150,6 +1150,9 @@ function test_canDecrypt_true() { function run_test() { + if (DISABLE_TESTS_BUG_604565) + return; + test_syncStartup_emptyOrOutdatedGlobalsResetsSync(); test_syncStartup_metaGet404(); test_syncStartup_failedMetaGet(); From a211e4fae18e0d27165aade6b890cb6fcaa4aa11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Wed, 27 Oct 2010 17:32:14 -0400 Subject: [PATCH 11/16] Bug 593823: put tabs on top by default for Linux, r=gavin, a=beltzner for b7 --- browser/base/content/browser.xul | 5 ----- 1 file changed, 5 deletions(-) diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 53858613f3b3..d629ad790fc4 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -826,12 +826,7 @@ #ifdef WINCE defaulticonsize="small" iconsize="small" #endif -#ifdef XP_WIN tabsontop="true" -#endif -#ifdef XP_MACOSX - tabsontop="true" -#endif persist="tabsontop"> Date: Thu, 28 Oct 2010 15:59:30 -0700 Subject: [PATCH 12/16] Bug 548949 - make CSP parse hostless schemes properly, r=dveditz, a=jst --- content/base/src/CSPUtils.jsm | 47 +++++++++++++++---------- content/base/test/unit/test_csputils.js | 12 +++++++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/content/base/src/CSPUtils.jsm b/content/base/src/CSPUtils.jsm index 3722c7d74768..0afb96d240a0 100644 --- a/content/base/src/CSPUtils.jsm +++ b/content/base/src/CSPUtils.jsm @@ -380,8 +380,7 @@ CSPRep.prototype = { }, /** - * Generates string representation of the policy. Should be fairly similar - * to the original. + * Generates canonical string representation of the policy. */ toString: function csp_toString() { @@ -607,8 +606,7 @@ CSPSourceList.prototype = { }, /** - * Generates string representation of the Source List. - * Should be fairly similar to the original. + * Generates canonical string representation of the Source List. */ toString: function() { @@ -639,7 +637,7 @@ CSPSourceList.prototype = { }, /** - * Makes a new instance that resembles this object. + * Makes a new deep copy of this object. * @returns * a new CSPSourceList */ @@ -951,7 +949,7 @@ CSPSource.fromString = function(aStr, self, enforceSelfChecks) { // Allow scheme-only sources! These default to wildcard host/port, // especially since host and port don't always matter. // Example: "javascript:" and "data:" - if (!sObj._host) sObj._host = "*"; + if (!sObj._host) sObj._host = CSPHost.fromString("*"); if (!sObj._port) sObj._port = "*"; } else { // some host was defined. @@ -1050,8 +1048,7 @@ CSPSource.prototype = { }, /** - * Generates string representation of the Source. - * Should be fairly similar to the original. + * Generates canonical string representation of the Source. */ toString: function() { @@ -1069,7 +1066,7 @@ CSPSource.prototype = { }, /** - * Makes a new instance that resembles this object. + * Makes a new deep copy of this object. * @returns * a new CSPSource */ @@ -1172,13 +1169,28 @@ CSPSource.prototype = { return null; } + // NOTE: Both sources must have a host, if they don't, something funny is + // going on. The fromString() factory method should have set the host to + // * if there's no host specified in the input. Regardless, if a host is + // not present either the scheme is hostless or any host should be allowed. + // This means we can use the other source's host as the more restrictive + // host expression, or if neither are present, we can use "*", but the + // error should still be reported. + // host - if (!this._host) - newSource._host = that._host; - else if (!that._host) - newSource._host = this._host; - else // both this and that have hosts + if (this._host && that._host) { newSource._host = this._host.intersectWith(that._host); + } else if (this._host) { + CSPError("intersecting source with undefined host: " + that.toString()); + newSource._host = this._host.clone(); + } else if (that._host) { + CSPError("intersecting source with undefined host: " + this.toString()); + newSource._host = that._host.clone(); + } else { + CSPError("intersecting two sources with undefined hosts: " + + this.toString() + " and " + that.toString()); + newSource._host = CSPHost.fromString("*"); + } return newSource; }, @@ -1266,8 +1278,7 @@ CSPHost.fromString = function(aStr) { CSPHost.prototype = { /** - * Generates string representation of the Source. - * Should be fairly similar to the original. + * Generates canonical string representation of the Host. */ toString: function() { @@ -1275,7 +1286,7 @@ CSPHost.prototype = { }, /** - * Makes a new instance that resembles this object. + * Makes a new deep copy of this object. * @returns * a new CSPHost */ @@ -1297,7 +1308,7 @@ CSPHost.prototype = { */ permits: function(aHost) { - if (!aHost) return false; + if (!aHost) aHost = CSPHost.fromString("*"); if (!(aHost instanceof CSPHost)) { // -- compare CSPHost to String diff --git a/content/base/test/unit/test_csputils.js b/content/base/test/unit/test_csputils.js index 2a9a8755755f..75683b8977cb 100644 --- a/content/base/test/unit/test_csputils.js +++ b/content/base/test/unit/test_csputils.js @@ -35,6 +35,7 @@ //load('CSPUtils.jsm'); Components.utils.import('resource://gre/modules/CSPUtils.jsm'); +Components.utils.import('resource://gre/modules/NetUtil.jsm'); // load the HTTP server do_load_httpd_js(); @@ -190,6 +191,7 @@ test( //"funny characters (#) should not work for host."); do_check_eq(null, CSPSource.fromString("a#2-c.com")); + //print(" --- Stop ignoring errors that print ---\n"); //"failed to parse host with port."); @@ -229,6 +231,16 @@ test( do_check_true(src.permits("https://foobar.com")); //"src should reject other hosts" do_check_false(src.permits("https://a.com")); + + src = CSPSource.create("javascript:", "https://foobar.com:443"); + //"hostless schemes should be parseable." + var aUri = NetUtil.newURI("javascript:alert('foo');"); + do_check_true(src.permits(aUri)); + //"src should reject other hosts" + do_check_false(src.permits("https://a.com")); + //"nothing else should be allowed" + do_check_false(src.permits("https://foobar.com")); + }); ///////////////////// Test the source list ////////////////////// From 72f5932f4230d1d32dc3552f1151bd9d1a81dc29 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 28 Oct 2010 17:05:53 -0700 Subject: [PATCH 13/16] Backed out changeset fb506072dca8 due to crashes Bug 570619 - Move crypto off the main thread --- services/crypto/modules/WeaveCrypto.js | 92 +++++------ services/crypto/modules/threaded.js | 150 ------------------ services/crypto/tests/unit/head_helpers.js | 2 - .../crypto/tests/unit/test_crypto_crypt.js | 4 +- .../crypto/tests/unit/test_crypto_keypair.js | 4 +- .../crypto/tests/unit/test_crypto_random.js | 4 +- .../crypto/tests/unit/test_crypto_rewrap.js | 4 +- .../crypto/tests/unit/test_crypto_verify.js | 4 +- services/sync/modules/util.js | 4 +- 9 files changed, 55 insertions(+), 213 deletions(-) delete mode 100644 services/crypto/modules/threaded.js diff --git a/services/crypto/modules/WeaveCrypto.js b/services/crypto/modules/WeaveCrypto.js index ae7dbf819f8a..55d3b7d279dd 100644 --- a/services/crypto/modules/WeaveCrypto.js +++ b/services/crypto/modules/WeaveCrypto.js @@ -71,12 +71,6 @@ WeaveCrypto.prototype = { } }, - // This is its own method so that it can be overridden. - // (Components.Exception isn't thread-safe for instance) - makeException : function makeException(message, result) { - return Components.Exception(message, result); - }, - init : function() { try { // Preferences. Add observer so we get notified of changes. @@ -130,7 +124,7 @@ WeaveCrypto.prototype = { nssfile.append("libnss3.so"); break; default: - throw this.makeException("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); + throw Components.Exception("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED); } this.log("Using NSS library " + nssfile.path); @@ -530,31 +524,31 @@ WeaveCrypto.prototype = { let mechanism = this.nss.PK11_AlgtagToMechanism(this.algorithm); mechanism = this.nss.PK11_GetPadMechanism(mechanism); if (mechanism == this.nss.CKM_INVALID_MECHANISM) - throw this.makeException("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE); + throw Components.Exception("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE); let ctx, symKey, slot, ivParam; try { ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address()); if (ivParam.isNull()) - throw this.makeException("can't convert IV to param", Cr.NS_ERROR_FAILURE); + throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE); slot = this.nss.PK11_GetInternalKeySlot(); if (slot.isNull()) - throw this.makeException("can't get internal key slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("can't get internal key slot", Cr.NS_ERROR_FAILURE); symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null); if (symKey.isNull()) - throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE); ctx = this.nss.PK11_CreateContextBySymKey(mechanism, operation, symKey, ivParam); if (ctx.isNull()) - throw this.makeException("couldn't create context for symkey", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't create context for symkey", Cr.NS_ERROR_FAILURE); let maxOutputSize = output.length; let tmpOutputSize = new ctypes.int(); // Note 1: NSS uses a signed int here... if (this.nss.PK11_CipherOp(ctx, output, tmpOutputSize.address(), maxOutputSize, input, input.length)) - throw this.makeException("cipher operation failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("cipher operation failed", Cr.NS_ERROR_FAILURE); let actualOutputSize = tmpOutputSize.value; let finalOutput = output.addressOfElement(actualOutputSize); @@ -565,7 +559,7 @@ WeaveCrypto.prototype = { // cipher operation. You'd think it would be called PK11_CipherOpFinal... let tmpOutputSize2 = new ctypes.unsigned_int(); // Note 2: ...but an unsigned here! if (this.nss.PK11_DigestFinal(ctx, finalOutput, tmpOutputSize2.address(), maxOutputSize)) - throw this.makeException("cipher finalize failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("cipher finalize failed", Cr.NS_ERROR_FAILURE); actualOutputSize += tmpOutputSize2.value; let newOutput = ctypes.cast(output, ctypes.unsigned_char.array(actualOutputSize)); @@ -604,7 +598,7 @@ WeaveCrypto.prototype = { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // Generate the keypair. privKey = this.nss.PK11_GenerateKeyPairWithFlags(slot, @@ -613,18 +607,18 @@ WeaveCrypto.prototype = { pubKey.address(), attrFlags, null); if (privKey.isNull()) - throw this.makeException("keypair generation failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("keypair generation failed", Cr.NS_ERROR_FAILURE); let s = this.nss.PK11_SetPrivateKeyNickname(privKey, "Weave User PrivKey"); if (s) - throw this.makeException("key nickname failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("key nickname failed", Cr.NS_ERROR_FAILURE); let wrappedPrivateKey = this._wrapPrivateKey(privKey, passphrase, salt, iv); out_wrappedPrivateKey.value = wrappedPrivateKey; // outparam let derKey = this.nss.SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey); if (derKey.isNull()) - throw this.makeException("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); let encodedPublicKey = this.encodeBase64(derKey.contents.data, derKey.contents.len); out_encodedPublicKey.value = encodedPublicKey; // outparam @@ -664,27 +658,27 @@ WeaveCrypto.prototype = { break; default: - throw this.makeException("unknown algorithm", Cr.NS_ERROR_FAILURE); + throw Components.Exception("unknown algorithm", Cr.NS_ERROR_FAILURE); } let slot, randKey, keydata; try { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); randKey = this.nss.PK11_KeyGen(slot, keygenMech, null, keySize, null); if (randKey.isNull()) - throw this.makeException("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE); // Slightly odd API, this call just prepares the key value for // extraction, we get the actual bits from the call to PK11_GetKeyData(). if (this.nss.PK11_ExtractKeyValue(randKey)) - throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); keydata = this.nss.PK11_GetKeyData(randKey); if (keydata.isNull()) - throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); return this.encodeBase64(keydata.contents.data, keydata.contents.len); } catch (e) { @@ -715,7 +709,7 @@ WeaveCrypto.prototype = { // Temporary buffer to hold the generated data. let scratch = new ctypes.ArrayType(ctypes.unsigned_char, byteCount)(); if (this.nss.PK11_GenerateRandom(scratch, byteCount)) - throw this.makeException("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE); return this.encodeBase64(scratch.address(), scratch.length); }, @@ -738,7 +732,7 @@ WeaveCrypto.prototype = { try { slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // ImportSymKey wants a mechanism, from which it derives the key type. let keyMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); @@ -747,7 +741,7 @@ WeaveCrypto.prototype = { // really matter because we're just going to wrap it up and not use it. symKey = this.nss.PK11_ImportSymKey(slot, keyMech, this.nss.PK11_OriginUnwrap, this.nss.CKA_ENCRYPT, symKeyData.address(), null); if (symKey.isNull()) - throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE); // Step 3. Put the public key bits into a P11 key object. @@ -755,11 +749,11 @@ WeaveCrypto.prototype = { // pubKey = SECKEY_ImportDERPublicKey(&pubKeyData, CKK_RSA); pubKeyInfo = this.nss.SECKEY_DecodeDERSubjectPublicKeyInfo(pubKeyData.address()); if (pubKeyInfo.isNull()) - throw this.makeException("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); pubKey = this.nss.SECKEY_ExtractPublicKey(pubKeyInfo); if (pubKey.isNull()) - throw this.makeException("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Wrap the symmetric key with the public key. @@ -767,7 +761,7 @@ WeaveCrypto.prototype = { let s = this.nss.PK11_PubWrapSymKey(wrapMech, pubKey, symKey, wrappedKey.address()); if (s) - throw this.makeException("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE); // Step 5. Base64 encode the wrapped key, cleanup, and return to caller. return this.encodeBase64(wrappedKey.data, wrappedKey.len); @@ -807,16 +801,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw this.makeException("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw Components.Exception("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw this.makeException("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); // Normally, one wants to associate a private key with a public key. // P11_UnwrapPrivKey() passes its keyID arg to PK11_MakeIDFromPubKey(), @@ -837,7 +831,7 @@ WeaveCrypto.prototype = { privKeyUsage.addressOfElement(0), privKeyUsageLength, null); // wincx if (privKey.isNull()) - throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Unwrap the symmetric key with the user's private key. @@ -846,15 +840,15 @@ WeaveCrypto.prototype = { symKey = this.nss.PK11_PubUnwrapSymKey(privKey, wrappedSymKey.address(), wrapMech, this.nss.CKA_DECRYPT, 0); if (symKey.isNull()) - throw this.makeException("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE); // Step 5. Base64 encode the unwrapped key, cleanup, and return to caller. if (this.nss.PK11_ExtractKeyValue(symKey)) - throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); symKeyData = this.nss.PK11_GetKeyData(symKey); if (symKeyData.isNull()) - throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); return this.encodeBase64(symKeyData.contents.data, symKeyData.contents.len); } catch (e) { @@ -894,16 +888,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); let keyID = ivItem.address(); @@ -917,7 +911,7 @@ WeaveCrypto.prototype = { privKeyUsage.addressOfElement(0), privKeyUsageLength, null); // wincx if (privKey.isNull()) - throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); // Step 4. Rewrap the private key with the new passphrase. return this._wrapPrivateKey(privKey, newPassphrase, salt, iv); @@ -956,16 +950,16 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Step 3. Unwrap the private key with the key from the passphrase. slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); let keyID = ivItem.address(); @@ -1059,15 +1053,15 @@ WeaveCrypto.prototype = { algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg, keyLength, iterations, saltItem.address()); if (algid.isNull()) - throw this.makeException("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); slot = this.nss.PK11_GetInternalSlot(); if (slot.isNull()) - throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); + throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE); symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null); if (symKey.isNull()) - throw this.makeException("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); } catch (e) { this.log("_deriveKeyFromPassphrase: failed: " + e); throw e; @@ -1095,11 +1089,11 @@ WeaveCrypto.prototype = { let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); if (wrapMech == this.nss.CKM_INVALID_MECHANISM) - throw this.makeException("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE); + throw Components.Exception("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE); let ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); if (ivParam.isNull()) - throw this.makeException("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); // Use a buffer to hold the wrapped key. NSS says about 1200 bytes for // a 2048-bit RSA key, so a 4096 byte buffer should be plenty. @@ -1111,7 +1105,7 @@ WeaveCrypto.prototype = { wrapMech, ivParam, wrappedKey.address(), null); if (s) - throw this.makeException("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE); + throw Components.Exception("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE); return this.encodeBase64(wrappedKey.data, wrappedKey.len); } catch (e) { diff --git a/services/crypto/modules/threaded.js b/services/crypto/modules/threaded.js deleted file mode 100644 index 691f2d3408a7..000000000000 --- a/services/crypto/modules/threaded.js +++ /dev/null @@ -1,150 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Firefox Sync. - * - * The Initial Developer of the Original Code is - * Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Philipp von Weitershausen - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const EXPORTED_SYMBOLS = ["ThreadedCrypto"]; - -const Cu = Components.utils; -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://services-sync/ext/Sync.js"); -Cu.import("resource://services-crypto/WeaveCrypto.js"); - -/* - * Execute a function in a thread. - */ -function Runner(func, thisObj, returnval, error) { - this.func = func; - this.thisObj = thisObj; - this.returnval = returnval; - this.error = error; -} -Runner.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]), - - run: function run() { - let ex = this.error; - if (ex) { - this.func.throw(ex); - } else { - this.func.call(this.thisObj, this.returnval); - } - } -}; - -/* - * Execute a function in a thread and notify a callback on another thread - * afterward. - */ -function CallbackRunner(func, thisObj, args, callback, cbThread) { - this.func = func; - this.thisObj = thisObj; - this.args = args; - this.callback = callback; - this.cbThread = cbThread; -} -CallbackRunner.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]), - - run: function run() { - let returnval, error; - try { - returnval = this.func.apply(this.thisObj, this.args); - } catch(ex) { - error = ex; - } - this.cbThread.dispatch(new Runner(this.callback, this.thisObj, - returnval, error), - Ci.nsIThread.DISPATCH_NORMAL); - } -}; - -/* - * Implementation of IWeaveCrypto that defers method calls to another thread - * but keeps the synchronous API. (Don't ask...) - */ -function ThreadedCrypto() { - this.backgroundThread = Services.tm.newThread(0); - this.crypto = new WeaveCrypto(); - - // Components.Exception isn't thread-safe. - this.crypto.makeException = function makeException(message, result) { - return result; - }; - - // Make sure to kill the thread before XPCOM shuts down. - Services.obs.addObserver(this, "profile-before-change", true); -} -ThreadedCrypto.deferToThread = function deferToThread(methodname) { - return function threadMethod() { - // Dispatch method call to background thread. - let args = Array.slice(arguments); - return Sync(function(callback) { - let runner = new CallbackRunner(this.crypto[methodname], this.crypto, - args, callback, Services.tm.mainThread); - this.backgroundThread.dispatch(runner, Ci.nsIThread.DISPATCH_NORMAL); - }, this)(); - }; -}; -ThreadedCrypto.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.IWeaveCrypto, - Ci.nsISupportsWeakReference]), - - observe: function observe() { - this.backgroundThread.shutdown(); - }, - - get algorithm() this.crypto.algorithm, - set algorithm(value) this.crypto.algorithm = value, - - get keypairBits() this.crypto.keypairBits, - set keypairBits(value) this.crypto.keypairBits = value, - - encrypt: ThreadedCrypto.deferToThread("encrypt"), - decrypt: ThreadedCrypto.deferToThread("decrypt"), - generateKeypair: ThreadedCrypto.deferToThread("generateKeypair"), - generateRandomKey: ThreadedCrypto.deferToThread("generateRandomKey"), - generateRandomIV: ThreadedCrypto.deferToThread("generateRandomIV"), - generateRandomBytes: ThreadedCrypto.deferToThread("generateRandomBytes"), - wrapSymmetricKey: ThreadedCrypto.deferToThread("wrapSymmetricKey"), - unwrapSymmetricKey: ThreadedCrypto.deferToThread("unwrapSymmetricKey"), - rewrapPrivateKey: ThreadedCrypto.deferToThread("rewrapPrivateKey"), - verifyPassphrase: ThreadedCrypto.deferToThread("verifyPassphrase") -}; diff --git a/services/crypto/tests/unit/head_helpers.js b/services/crypto/tests/unit/head_helpers.js index 86e12ab7eac9..611554892004 100644 --- a/services/crypto/tests/unit/head_helpers.js +++ b/services/crypto/tests/unit/head_helpers.js @@ -11,8 +11,6 @@ try { } catch(ex) { -do_get_profile(); - // Make sure to provide the right OS so crypto loads the right binaries let OS = "XPCShell"; if ("@mozilla.org/windows-registry-key;1" in Cc) diff --git a/services/crypto/tests/unit/test_crypto_crypt.js b/services/crypto/tests/unit/test_crypto_crypt.js index d8104cbee16b..dc53002dab7d 100644 --- a/services/crypto/tests/unit/test_crypto_crypt.js +++ b/services/crypto/tests/unit/test_crypto_crypt.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/threaded.js"); - cryptoSvc = new ThreadedCrypto(); + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_keypair.js b/services/crypto/tests/unit/test_crypto_keypair.js index 258f473319ab..8ea7907f6370 100644 --- a/services/crypto/tests/unit/test_crypto_keypair.js +++ b/services/crypto/tests/unit/test_crypto_keypair.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/threaded.js"); - cryptoSvc = new ThreadedCrypto(); + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_random.js b/services/crypto/tests/unit/test_crypto_random.js index 105c743f644d..ab85169be6b9 100644 --- a/services/crypto/tests/unit/test_crypto_random.js +++ b/services/crypto/tests/unit/test_crypto_random.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/threaded.js"); - cryptoSvc = new ThreadedCrypto(); + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_rewrap.js b/services/crypto/tests/unit/test_crypto_rewrap.js index 67fb6ccf0206..d9568d6e66aa 100644 --- a/services/crypto/tests/unit/test_crypto_rewrap.js +++ b/services/crypto/tests/unit/test_crypto_rewrap.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/threaded.js"); - cryptoSvc = new ThreadedCrypto(); + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/crypto/tests/unit/test_crypto_verify.js b/services/crypto/tests/unit/test_crypto_verify.js index 6acdaff8deae..5475503e69da 100644 --- a/services/crypto/tests/unit/test_crypto_verify.js +++ b/services/crypto/tests/unit/test_crypto_verify.js @@ -1,7 +1,7 @@ let cryptoSvc; try { - Components.utils.import("resource://services-crypto/threaded.js"); - cryptoSvc = new ThreadedCrypto(); + Components.utils.import("resource://services-crypto/WeaveCrypto.js"); + cryptoSvc = new WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index 5e24fb4f26e5..78af94fd6541 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -1039,8 +1039,8 @@ Svc.__defineGetter__("Crypto", function() { let cryptoSvc; try { let ns = {}; - Cu.import("resource://services-crypto/threaded.js", ns); - cryptoSvc = new ns.ThreadedCrypto(); + Cu.import("resource://services-crypto/WeaveCrypto.js", ns); + cryptoSvc = new ns.WeaveCrypto(); } catch (ex) { // Fallback to binary WeaveCrypto cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]. From 3df95ee0501b76c7cb4f78e7e92f7f2ace6720a2 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 28 Oct 2010 17:19:28 -0700 Subject: [PATCH 14/16] Bug 604565 - Disable another intermittently failing xpcshell tests on OSX debug build [r=mconnor] --- services/sync/tests/unit/test_service_sync_remoteSetup.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/sync/tests/unit/test_service_sync_remoteSetup.js b/services/sync/tests/unit/test_service_sync_remoteSetup.js index 9e73b550b4f0..a40359357021 100644 --- a/services/sync/tests/unit/test_service_sync_remoteSetup.js +++ b/services/sync/tests/unit/test_service_sync_remoteSetup.js @@ -3,6 +3,9 @@ Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/log4moz.js"); function run_test() { + if (DISABLE_TESTS_BUG_604565) + return; + let logger = Log4Moz.repository.rootLogger; Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender()); From bbab689d6480722b73a0721bb73d3e56448a3c98 Mon Sep 17 00:00:00 2001 From: David Mandelin Date: Thu, 28 Oct 2010 17:44:24 -0700 Subject: [PATCH 15/16] Backed out changeset c133d3c084c0: now we want to measure if not doing sync stuff on background thread reduces crashes. --- js/src/jsstr.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index b3beae68ffdb..925bf319fe6b 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -104,18 +104,6 @@ js_GetStringChars(JSContext *cx, JSString *str) void JSString::flatten() { - // Diagnostic: serialize all calls to this function to see - // if concurrent calls are crashing us. - JS_LOCK_RUNTIME(asCell()->compartment()->rt); - // The main body of this function can be executed only if - // the string is a rope. With multiple threads, it's possible - // we waited while another one ran, and the string has - // already been flattened for us. - if (!isRope()) { - JS_UNLOCK_RUNTIME(asCell()->compartment()->rt); - return; - } - JSString *topNode; jschar *chars; size_t capacity; @@ -193,8 +181,6 @@ JSString::flatten() /* Set null terminator. */ chars[pos] = 0; topNode->initFlatMutable(chars, pos, capacity); - - JS_UNLOCK_RUNTIME(asCell()->compartment()->rt); } #ifdef JS_TRACER From 82f4d08a277412b03167e66e93e4ac62b242a4c1 Mon Sep 17 00:00:00 2001 From: Brad Lassey Date: Thu, 28 Oct 2010 22:45:02 -0400 Subject: [PATCH 16/16] bug 606317 - Android crash only : Crash [@ libc.so@0x11cd0 ] occurs after opening an .ics r=doug a=blocking-fennec --- uriloader/exthandler/android/nsMIMEInfoAndroid.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp index 44745d3bba06..3281c0c1a02e 100644 --- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp @@ -168,11 +168,7 @@ NS_IMETHODIMP nsMIMEInfoAndroid::GetPreferredApplicationHandler(nsIHandlerApp** aApp) { *aApp = mPrefApp; - if (*aApp) { - nsAutoString appName; - (*aApp)->GetName(appName); - } - + NS_IF_ADDREF(*aApp); return NS_OK; }