Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Unified Diff: sync/engine/apply_control_data_updates_unittest.cc

Issue 10905191: [Sync] Add keystore migration conflict support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sync/engine/apply_control_data_updates.cc ('k') | sync/engine/syncer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sync/engine/apply_control_data_updates_unittest.cc
diff --git a/sync/engine/apply_control_data_updates_unittest.cc b/sync/engine/apply_control_data_updates_unittest.cc
index 7f1a9fad6e238141526b521613048207adc2c47b..aa00865be8bb65a279583764708203364db7398e 100644
--- a/sync/engine/apply_control_data_updates_unittest.cc
+++ b/sync/engine/apply_control_data_updates_unittest.cc
@@ -56,59 +56,17 @@ class ApplyControlDataUpdatesTest : public SyncerCommandTest {
DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest);
};
+// Verify that applying a nigori node sets initial sync ended properly,
+// updates the set of encrypted types, and updates the cryptographer.
TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) {
// Storing the cryptographer separately is bad, but for this test we
// know it's safe.
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
- encrypted_types.Put(PASSWORDS);
+ encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
- // We start with initial_sync_ended == false. This is wrong, since would have
- // no nigori node if that were the case. Howerver, it makes it easier to
- // verify that ApplyControlDataUpdates sets initial_sync_ended correctly.
- EXPECT_FALSE(directory()->initial_sync_ended_types().Has(NIGORI));
-
- {
- syncable::ReadTransaction trans(FROM_HERE, directory());
- cryptographer = directory()->GetCryptographer(&trans);
- EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
- .Equals(encrypted_types));
- }
-
- // Nigori node updates should update the Cryptographer.
- Cryptographer other_cryptographer(cryptographer->encryptor());
- KeyParams params = {"localhost", "dummy", "foobar"};
- other_cryptographer.AddKey(params);
-
- sync_pb::EntitySpecifics specifics;
- sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori();
- other_cryptographer.GetKeys(nigori->mutable_encryption_keybag());
- nigori->set_encrypt_everything(true);
- entry_factory_->CreateUnappliedNewItem(
- ModelTypeToRootTag(NIGORI), specifics, true);
- EXPECT_FALSE(cryptographer->has_pending_keys());
-
- ApplyControlDataUpdates(directory());
-
- EXPECT_FALSE(cryptographer->is_ready());
- EXPECT_TRUE(cryptographer->has_pending_keys());
- {
- syncable::ReadTransaction trans(FROM_HERE, directory());
- EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
- .Equals(ModelTypeSet::All()));
- EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
- }
-}
-
-TEST_F(ApplyControlDataUpdatesTest, NigoriUpdateForDisabledTypes) {
- // Storing the cryptographer separately is bad, but for this test we
- // know it's safe.
- Cryptographer* cryptographer;
- ModelTypeSet encrypted_types;
- encrypted_types.Put(PASSWORDS);
-
- // We start with initial_sync_ended == false. This is wrong, since would have
- // no nigori node if that were the case. Howerver, it makes it easier to
+ // We start with initial_sync_ended == false. This is wrong, since we would
+ // have no nigori node if that were the case. However, it makes it easier to
// verify that ApplyControlDataUpdates sets initial_sync_ended correctly.
EXPECT_FALSE(directory()->initial_sync_ended_types().Has(NIGORI));
@@ -154,7 +112,7 @@ TEST_F(ApplyControlDataUpdatesTest, EncryptUnsyncedChanges) {
// know it's safe.
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
- encrypted_types.Put(PASSWORDS);
+ encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
@@ -258,12 +216,16 @@ TEST_F(ApplyControlDataUpdatesTest, EncryptUnsyncedChanges) {
}
}
+// Create some local unsynced and unencrypted changes. Receive a new nigori
+// node enabling their encryption but also introducing pending keys. Ensure
+// we apply the update properly without encrypting the unsynced changes or
+// breaking.
TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) {
// Storing the cryptographer separately is bad, but for this test we
// know it's safe.
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
- encrypted_types.Put(PASSWORDS);
+ encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
@@ -344,4 +306,566 @@ TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) {
}
}
+// Verify we handle a nigori node conflict by merging encryption keys and
+// types, but preserve the custom passphrase state of the server.
+// Initial sync ended should be set.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictPendingKeysServerEncryptEverythingCustom) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams other_params = {"localhost", "dummy", "foobar"};
+ KeyParams local_params = {"localhost", "dummy", "local"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up a temporary cryptographer to generate new keys with.
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(other_params);
+
+ // Create server specifics with pending keys, new encrypted types,
+ // and a custom passphrase (unmigrated).
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(true);
+ server_nigori->set_keybag_is_frozen(true);
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Initialize the local cryptographer with the local keys.
+ cryptographer->AddKey(local_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with the local encryption keys and default encrypted
+ // types.
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(false);
+ local_nigori->set_keybag_is_frozen(true);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_FALSE(cryptographer->is_ready());
+ EXPECT_TRUE(cryptographer->is_initialized());
+ EXPECT_TRUE(cryptographer->has_pending_keys());
+ EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// Verify we handle a nigori node conflict by merging encryption keys and
+// types, but preserve the custom passphrase state of the server.
+// Initial sync ended should be set.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictPendingKeysLocalEncryptEverythingCustom) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams other_params = {"localhost", "dummy", "foobar"};
+ KeyParams local_params = {"localhost", "dummy", "local"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up a temporary cryptographer to generate new keys with.
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(other_params);
+
+ // Create server specifics with pending keys, new encrypted types,
+ // and a custom passphrase (unmigrated).
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(false);
+ server_nigori->set_keybag_is_frozen(false);
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Initialize the local cryptographer with the local keys.
+ cryptographer->AddKey(local_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with the local encryption keys and default encrypted
+ // types.
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(true);
+ local_nigori->set_keybag_is_frozen(true);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_FALSE(cryptographer->is_ready());
+ EXPECT_TRUE(cryptographer->is_initialized());
+ EXPECT_TRUE(cryptographer->has_pending_keys());
+ EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// If the conflicting nigori has a subset of the local keys, the conflict
+// resolution should preserve the full local keys. Initial sync ended should be
+// set.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictOldKeys) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams old_params = {"localhost", "dummy", "old"};
+ KeyParams new_params = {"localhost", "dummy", "new"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up the cryptographer with old keys
+ cryptographer->AddKey(old_params);
+
+ // Create server specifics with old keys and new encrypted types.
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ cryptographer->GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(true);
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Add the new keys to the cryptogrpaher
+ cryptographer->AddKey(new_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with the superset of keys.
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(false);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_TRUE(cryptographer->is_ready());
+ EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// If both nigoris are migrated, but we also set a custom passphrase locally,
+// the local nigori should be preserved.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictBothMigratedLocalCustom) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams old_params = {"localhost", "dummy", "old"};
+ KeyParams new_params = {"localhost", "dummy", "new"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up the cryptographer with new keys
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(old_params);
+
+ // Create server specifics with a migrated keystore passphrase type.
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(false);
+ server_nigori->set_keybag_is_frozen(true);
+ server_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
+ server_nigori->mutable_keystore_decryptor_token();
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Add the new keys to the cryptographer.
+ cryptographer->AddKey(old_params);
+ cryptographer->AddKey(new_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with a migrated custom passphrase type
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(true);
+ local_nigori->set_keybag_is_frozen(true);
+ local_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_TRUE(cryptographer->is_ready());
+ EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().passphrase_type());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// If both nigoris are migrated, but a custom passphrase with a new key was
+// set remotely, the remote nigori should be preserved.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictBothMigratedServerCustom) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams old_params = {"localhost", "dummy", "old"};
+ KeyParams new_params = {"localhost", "dummy", "new"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up the cryptographer with both new keys and old keys.
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(old_params);
+ other_cryptographer.AddKey(new_params);
+
+ // Create server specifics with a migrated custom passphrase type.
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(true);
+ server_nigori->set_keybag_is_frozen(true);
+ server_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Add the old keys to the cryptographer.
+ cryptographer->AddKey(old_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with a migrated keystore passphrase type
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(false);
+ local_nigori->set_keybag_is_frozen(true);
+ local_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
+ server_nigori->mutable_keystore_decryptor_token();
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_TRUE(cryptographer->is_initialized());
+ EXPECT_TRUE(cryptographer->has_pending_keys());
+ EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().passphrase_type());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// If the local nigori is migrated but the server is not, preserve the local
+// nigori.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictLocalMigrated) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams old_params = {"localhost", "dummy", "old"};
+ KeyParams new_params = {"localhost", "dummy", "new"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up the cryptographer with both new keys and old keys.
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(old_params);
+
+ // Create server specifics with an unmigrated implicit passphrase type.
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(true);
+ server_nigori->set_keybag_is_frozen(false);
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Add the old keys to the cryptographer.
+ cryptographer->AddKey(old_params);
+ cryptographer->AddKey(new_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with a migrated custom passphrase type
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(true);
+ local_nigori->set_keybag_is_frozen(true);
+ local_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_TRUE(cryptographer->is_ready());
+ EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encrypt_everything());
+ EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().passphrase_type());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
+ .Equals(ModelTypeSet::All()));
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
+// If the server nigori is migrated but the local is not, preserve the server
+// nigori.
+TEST_F(ApplyControlDataUpdatesTest,
+ NigoriConflictServerMigrated) {
+ Cryptographer* cryptographer;
+ ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
+ KeyParams old_params = {"localhost", "dummy", "old"};
+ KeyParams new_params = {"localhost", "dummy", "new"};
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ EXPECT_TRUE(encrypted_types.Equals(
+ directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
+ }
+
+ // Set up the cryptographer with both new keys and old keys.
+ Cryptographer other_cryptographer(cryptographer->encryptor());
+ other_cryptographer.AddKey(old_params);
+
+ // Create server specifics with an migrated keystore passphrase type.
+ sync_pb::EntitySpecifics server_specifics;
+ sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
+ other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
+ server_nigori->set_encrypt_everything(false);
+ server_nigori->set_keybag_is_frozen(true);
+ server_nigori->set_passphrase_type(
+ sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
+ server_nigori->mutable_keystore_decryptor_token();
+ int64 nigori_handle =
+ entry_factory_->CreateUnappliedNewItem(kNigoriTag,
+ server_specifics,
+ true);
+
+ // Add the old keys to the cryptographer.
+ cryptographer->AddKey(old_params);
+ cryptographer->AddKey(new_params);
+ EXPECT_TRUE(cryptographer->is_ready());
+
+ // Set up a local nigori with a migrated custom passphrase type
+ sync_pb::EntitySpecifics local_specifics;
+ sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
+ cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
+ local_nigori->set_encrypt_everything(false);
+ local_nigori->set_keybag_is_frozen(false);
+ ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
+ nigori_handle, local_specifics));
+ // Apply the update locally so that UpdateFromEncryptedTypes knows what state
+ // to use.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ cryptographer = directory()->GetCryptographer(&trans);
+ directory()->GetNigoriHandler()->ApplyNigoriUpdate(
+ *local_nigori,
+ &trans);
+ }
+
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+ ApplyControlDataUpdates(directory());
+ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
+ EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
+
+ EXPECT_TRUE(cryptographer->is_ready());
+ // Note: we didn't overwrite the encryption keybag with the local keys. The
+ // sync encryption handler will do that when it detects that the new
+ // keybag is out of date (and update the keystore bootstrap if necessary).
+ EXPECT_FALSE(cryptographer->CanDecryptUsingDefaultKey(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(cryptographer->CanDecrypt(
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().encryption_keybag()));
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().keybag_is_frozen());
+ EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().has_keystore_decryptor_token());
+ EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE,
+ entry_factory_->GetLocalSpecificsForItem(nigori_handle).
+ nigori().passphrase_type());
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
+ }
+}
+
} // namespace syncer
« no previous file with comments | « sync/engine/apply_control_data_updates.cc ('k') | sync/engine/syncer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698