cache crypto meta objects
authorDan Mills <thunder@mozilla.com>
Sat, 08 Nov 2008 20:24:12 -0800
changeset 45034 a01d3667e8e1d5e6d1201c901d13199475c538e5
parent 45032 afb7841de5f0fe5ca5c8b50595c545d08b4320ef
child 45035 f450255dc71031083768b341e9c4bd6fabfb93ae
push idunknown
push userunknown
push dateunknown
cache crypto meta objects
services/sync/modules/base_records/crypto.js
--- a/services/sync/modules/base_records/crypto.js
+++ b/services/sync/modules/base_records/crypto.js
@@ -29,17 +29,17 @@
  * 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 = ['CryptoWrapper', 'CryptoMeta'];
+const EXPORTED_SYMBOLS = ['CryptoWrapper', 'CryptoMeta', 'CryptoMetas'];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://weave/Observers.js");
 Cu.import("resource://weave/Preferences.js");
@@ -48,16 +48,18 @@ Cu.import("resource://weave/constants.js
 Cu.import("resource://weave/util.js");
 Cu.import("resource://weave/async.js");
 Cu.import("resource://weave/crypto.js");
 Cu.import("resource://weave/base_records/wbo.js");
 Cu.import("resource://weave/base_records/keys.js");
 
 Function.prototype.async = Async.sugar;
 
+Utils.lazy(this, 'CryptoMetas', RecordManager);
+
 // fixme: global, ugh
 let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
 let crypto = Cc["@labs.mozilla.com/Weave/Crypto;1"].createInstance(Ci.IWeaveCrypto);
 
 function CryptoWrapper(uri, authenticator) {
   this._CryptoWrap_init(uri, authenticator);
 }
 CryptoWrapper.prototype = {
@@ -82,38 +84,39 @@ CryptoWrapper.prototype = {
   },
 
   _encrypt: function CryptoWrap__encrypt(passphrase) {
     let self = yield;
 
     let pubkey = yield PubKeys.getDefaultKey(self.cb);
     let privkey = yield PrivKeys.get(self.cb, pubkey.privateKeyUri);
 
-    let meta = new CryptoMeta(this.encryption); // FIXME: cache!
-    yield meta.get(self.cb);
+    let meta = yield CryptoMetas.get(self.cb, this.encryption);
     let symkey = yield meta.getKey(self.cb, privkey, passphrase);
 
+    // note: we wrap the cleartext payload in an array because
+    // when it's a simple string nsIJSON returns null
     this.payload = crypto.encrypt(json.encode([this.cleartext]), symkey, meta.bulkIV);
 
     self.done();
   },
   encrypt: function CryptoWrap_encrypt(onComplete, passphrase) {
     this._encrypt.async(this, onComplete, passphrase);
   },
 
   _decrypt: function CryptoWrap__decrypt(passphrase) {
     let self = yield;
 
     let pubkey = yield PubKeys.getDefaultKey(self.cb);
     let privkey = yield PrivKeys.get(self.cb, pubkey.privateKeyUri);
 
-    let meta = new CryptoMeta(this.encryption); // FIXME: cache!
-    yield meta.get(self.cb);
+    let meta = yield CryptoMetas.get(self.cb, this.encryption);
     let symkey = yield meta.getKey(self.cb, privkey, passphrase);
 
+    // note: payload is wrapped in an array, see _encrypt
     this.cleartext = json.decode(crypto.decrypt(this.payload, symkey, meta.bulkIV))[0];
 
     self.done(this.cleartext);
   },
   decrypt: function CryptoWrap_decrypt(onComplete, passphrase) {
     this._decrypt.async(this, onComplete, passphrase);
   }
 };
@@ -189,82 +192,84 @@ CryptoMeta.prototype = {
     this.payload.keyring[new_pubkey.uri.spec] =
       crypto.wrapSymmetricKey(symkey, new_pubkey.keyData);
   },
   addUnwrappedKey: function CryptoMeta_addUnwrappedKey(onComplete, new_pubkey, symkey) {
     this._addUnwrappedKey.async(this, onComplete, new_pubkey, symkey);
   }
 };
 
-function CryptoMetaManager() {
+function RecordManager() {
   this._init();
 }
-CryptoMetaManager.prototype = {
-  _init: function CryptoMetaMgr__init() {
-    this._log = Log4Moz.repository.getLogger("CryptoMetaMgr");
+RecordManager.prototype = {
+  _recordType: CryptoMeta,
+  _logName: "RecordMgr",
+
+  _init: function RegordMgr__init() {
+    this._log = Log4Moz.repository.getLogger(this._logName);
     this._records = {};
     this._aliases = {};
   },
 
-  _import: function CryptoMetaMgr__import(url) {
+  _import: function RegordMgr__import(url) {
     let self = yield;
 
     this._log.trace("Importing record: " + (url.spec? url.spec : url));
 
     try {
-      let rec = new CryptoMeta(url);
+      let rec = new this._recordType(url);
       yield rec.get(self.cb);
       this.set(url, rec);
       self.done(rec);
     } catch (e) {
       this._log.debug("Failed to import record: " + e);
       self.done(null);
     }
   },
-  import: function CryptoMetaMgr_import(onComplete, url) {
+  import: function RegordMgr_import(onComplete, url) {
     this._import.async(this, onComplete, url);
   },
 
-  _get: function CryptoMetaMgr__get(url) {
+  _get: function RegordMgr__get(url) {
     let self = yield;
 
     let rec = null;
     if (url in this._aliases)
       url = this._aliases[url];
     if (url in this._records)
-      rec = this._keys[url];
+      rec = this._records[url];
 
-    if (!key)
+    if (!rec)
       rec = yield this.import(self.cb, url);
 
     self.done(rec);
   },
-  get: function KeyMgr_get(onComplete, url) {
+  get: function RegordMgr_get(onComplete, url) {
     this._get.async(this, onComplete, url);
   },
 
-  set: function KeyMgr_set(url, key) {
-    this._keys[url] = key;
-    return key;
+  set: function RegordMgr_set(url, record) {
+    this._records[url] = record;
   },
 
-  contains: function KeyMgr_contains(url) {
-    let key = null;
+  contains: function RegordMgr_contains(url) {
+    let record = null;
     if (url in this._aliases)
       url = this._aliases[url];
-    if (url in this._keys)
+    if (url in this._records)
       return true;
     return false;
   },
 
-  del: function KeyMgr_del(url) {
-    delete this._keys[url];
+  del: function RegordMgr_del(url) {
+    delete this._records[url];
   },
-  getAlias: function KeyMgr_getAlias(alias) {
+  getAlias: function RegordMgr_getAlias(alias) {
     return this._aliases[alias];
   },
-  setAlias: function KeyMgr_setAlias(url, alias) {
+  setAlias: function RegordMgr_setAlias(url, alias) {
     this._aliases[alias] = url;
   },
-  delAlias: function KeyMgr_delAlias(alias) {
+  delAlias: function RegordMgr_delAlias(alias) {
     delete this._aliases[alias];
   }
 };