Bug 618389: reset and clear keys on changePassphrase. r=mconnor
authorRichard Newman <rnewman@mozilla.com>
Fri, 10 Dec 2010 16:53:40 -0800
changeset 59108 3608943f3475b2a39220ff1f637ed2d02f138013
parent 59095 d2f296b6504cfdfeaee060c85eac314f1e77bf8c
child 59109 ebdb460678416494d04679491e1041fa8ac673a5
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersmconnor
bugs618389
Bug 618389: reset and clear keys on changePassphrase. r=mconnor
services/sync/modules/service.js
services/sync/tests/unit/test_service_sync_remoteSetup.js
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -937,36 +937,38 @@ WeaveSvc.prototype = {
       this.wipeServer();
 
       this.logout();
 
       /* Set this so UI is updated on next run. */
       this.passphrase = newphrase;
       this.persistLogin();
 
+      /* We need to re-encrypt everything, so reset. */
+      this.resetClient();
+
       /* Login and sync. This also generates new keys. */
       this.login();
       this.sync(true);
       return true;
     }))(),
 
   startOver: function() {
     // Set a username error so the status message shows "set up..."
     Status.login = LOGIN_FAILED_NO_USERNAME;
     this.logout();
-    // Reset all engines.
+    
+    // Reset all engines and clear keys.
     this.resetClient();
+    
     // Reset Weave prefs.
     this._ignorePrefObserver = true;
     Svc.Prefs.resetBranch("");
     this._ignorePrefObserver = false;
     
-    // Clear keys.
-    CollectionKeys.clear();
-    
     Svc.Prefs.set("lastversion", WEAVE_VERSION);
     // Find weave logins and remove them.
     this.password = "";
     this.passphrase = "";
     Svc.Login.findLogins({}, PWDMGR_HOST, "", "").map(function(login) {
       Svc.Login.removeLogin(login);
     });
     Svc.Obs.notify("weave:service:start-over");
@@ -1976,16 +1978,19 @@ WeaveSvc.prototype = {
       }
       // Convert the array of names into engines
       else
         engines = Engines.get(engines);
 
       // Have each engine drop any temporary meta data
       for each (let engine in engines)
         engine.resetClient();
+      
+      // Delete our keys. We'll generate new ones if the server doesn't have any.
+      CollectionKeys.clear();
     }))(),
 
   /**
    * A hash of valid commands that the client knows about. The key is a command
    * and the value is a hash containing information about the command such as
    * number of arguments and description.
    */
   _commands: [
--- a/services/sync/tests/unit/test_service_sync_remoteSetup.js
+++ b/services/sync/tests/unit/test_service_sync_remoteSetup.js
@@ -24,21 +24,26 @@ function run_test() {
   function wasCalledHandler(wbo) {
     let handler = wbo.handler();
     return function() {
       wbo.wasCalled = true;
       handler.apply(this, arguments);
     };
   }
 
+  let keysWBO = new ServerWBO("keys");
+  let cryptoColl = new ServerCollection({keys: keysWBO});
+  let metaColl = new ServerCollection({global: meta_global});
   do_test_pending();
   let server = httpd_setup({
-    "/1.0/johndoe/storage/crypto/keys": upd("crypto", new ServerWBO("keys").handler()),
+    "/1.0/johndoe/storage/crypto/keys": upd("crypto", keysWBO.handler()),
+    "/1.0/johndoe/storage/crypto": upd("crypto", cryptoColl.handler()),
     "/1.0/johndoe/storage/clients": upd("clients", clients.handler()),
     "/1.0/johndoe/storage/meta/global": upd("meta", wasCalledHandler(meta_global)),
+    "/1.0/johndoe/storage/meta": upd("meta", wasCalledHandler(metaColl)),
     "/1.0/johndoe/info/collections": collectionsHelper.handler
   });
 
   try {
     _("Log in.");
     Weave.Service.serverURL = "http://localhost:8080/";
     Weave.Service.clusterURL = "http://localhost:8080/";
     
@@ -91,16 +96,32 @@ function run_test() {
     let pp = Weave.Service.passphrase;
     Weave.Service.passphrase = "notvalid";
     do_check_false(Weave.Service.verifyAndFetchSymmetricKeys());
     do_check_eq(Status.sync, CREDENTIALS_CHANGED);
     do_check_eq(Status.login, LOGIN_FAILED_INVALID_PASSPHRASE);
     Weave.Service.passphrase = pp;
     do_check_true(Weave.Service.verifyAndFetchSymmetricKeys());
     
+    // changePassphrase wipes our keys, and they're regenerated on next sync.
+    _("Checking changed passphrase.");
+    let existingDefault = CollectionKeys.keyForCollection();
+    let existingKeysPayload = keysWBO.payload;
+    let newPassphrase = "bbbbbabcdeabcdeabcdeabcdea";
+    Weave.Service.changePassphrase(newPassphrase);
+    
+    _("Local key cache is full, but different.");
+    do_check_true(!!CollectionKeys._default);
+    do_check_false(CollectionKeys._default.equals(existingDefault));
+    
+    _("Server has new keys.");
+    do_check_true(!!keysWBO.payload);
+    do_check_true(!!keysWBO.modified);
+    do_check_neq(keysWBO.payload, existingKeysPayload);
+
     // Try to screw up HMAC calculation.
     // Re-encrypt keys with a new random keybundle, and upload them to the
     // server, just as might happen with a second client.
     _("Attempting to screw up HMAC by re-encrypting keys.");
     let keys = CollectionKeys.asWBO();
     let b = new BulkKeyBundle("hmacerror", "hmacerror");
     b.generateRandom();
     collections.crypto = keys.modified = 100 + (Date.now()/1000);  // Future modification time.