| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/sync/core_impl/sync_encryption_handler_impl.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include <memory> | |
| 10 | |
| 11 #include "base/base64.h" | |
| 12 #include "base/json/json_string_value_serializer.h" | |
| 13 #include "base/run_loop.h" | |
| 14 #include "base/tracked_objects.h" | |
| 15 #include "components/sync/base/fake_encryptor.h" | |
| 16 #include "components/sync/base/model_type_test_util.h" | |
| 17 #include "components/sync/protocol/nigori_specifics.pb.h" | |
| 18 #include "components/sync/protocol/sync.pb.h" | |
| 19 #include "components/sync/syncable/entry.h" | |
| 20 #include "components/sync/syncable/mutable_entry.h" | |
| 21 #include "components/sync/syncable/read_node.h" | |
| 22 #include "components/sync/syncable/read_transaction.h" | |
| 23 #include "components/sync/syncable/syncable_write_transaction.h" | |
| 24 #include "components/sync/syncable/test_user_share.h" | |
| 25 #include "components/sync/syncable/write_node.h" | |
| 26 #include "components/sync/syncable/write_transaction.h" | |
| 27 #include "components/sync/test/engine/test_id_factory.h" | |
| 28 #include "testing/gmock/include/gmock/gmock.h" | |
| 29 #include "testing/gtest/include/gtest/gtest.h" | |
| 30 | |
| 31 namespace syncer { | |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 using ::testing::_; | |
| 36 using ::testing::AnyNumber; | |
| 37 using ::testing::AtLeast; | |
| 38 using ::testing::Mock; | |
| 39 using ::testing::SaveArg; | |
| 40 using ::testing::StrictMock; | |
| 41 | |
| 42 // The raw keystore key the server sends. | |
| 43 static const char kRawKeystoreKey[] = "keystore_key"; | |
| 44 // Base64 encoded version of |kRawKeystoreKey|. | |
| 45 static const char kKeystoreKey[] = "a2V5c3RvcmVfa2V5"; | |
| 46 | |
| 47 class SyncEncryptionHandlerObserverMock | |
| 48 : public SyncEncryptionHandler::Observer { | |
| 49 public: | |
| 50 MOCK_METHOD2(OnPassphraseRequired, | |
| 51 void(PassphraseRequiredReason, | |
| 52 const sync_pb::EncryptedData&)); // NOLINT | |
| 53 MOCK_METHOD0(OnPassphraseAccepted, void()); // NOLINT | |
| 54 MOCK_METHOD2(OnBootstrapTokenUpdated, | |
| 55 void(const std::string&, BootstrapTokenType type)); // NOLINT | |
| 56 MOCK_METHOD2(OnEncryptedTypesChanged, void(ModelTypeSet, bool)); // NOLINT | |
| 57 MOCK_METHOD0(OnEncryptionComplete, void()); // NOLINT | |
| 58 MOCK_METHOD1(OnCryptographerStateChanged, void(Cryptographer*)); // NOLINT | |
| 59 MOCK_METHOD2(OnPassphraseTypeChanged, | |
| 60 void(PassphraseType, | |
| 61 base::Time)); // NOLINT | |
| 62 MOCK_METHOD1(OnLocalSetPassphraseEncryption, | |
| 63 void(const SyncEncryptionHandler::NigoriState&)); // NOLINT | |
| 64 }; | |
| 65 | |
| 66 google::protobuf::RepeatedPtrField<google::protobuf::string> | |
| 67 BuildEncryptionKeyProto(const std::string& encryption_key) { | |
| 68 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 69 keys.Add()->assign(encryption_key); | |
| 70 return keys; | |
| 71 } | |
| 72 | |
| 73 } // namespace | |
| 74 | |
| 75 class SyncEncryptionHandlerImplTest : public ::testing::Test { | |
| 76 public: | |
| 77 SyncEncryptionHandlerImplTest() {} | |
| 78 virtual ~SyncEncryptionHandlerImplTest() {} | |
| 79 | |
| 80 virtual void SetUp() { | |
| 81 test_user_share_.SetUp(); | |
| 82 SetUpEncryption(); | |
| 83 CreateRootForType(NIGORI); | |
| 84 } | |
| 85 | |
| 86 virtual void TearDown() { | |
| 87 PumpLoop(); | |
| 88 test_user_share_.TearDown(); | |
| 89 } | |
| 90 | |
| 91 protected: | |
| 92 void SetUpEncryption() { | |
| 93 SetUpEncryptionWithKeyForBootstrapping(std::string()); | |
| 94 } | |
| 95 | |
| 96 void SetUpEncryptionWithKeyForBootstrapping( | |
| 97 const std::string& key_for_bootstrapping) { | |
| 98 encryption_handler_.reset(new SyncEncryptionHandlerImpl( | |
| 99 user_share(), &encryptor_, key_for_bootstrapping, | |
| 100 std::string() /* keystore key for bootstrapping */)); | |
| 101 encryption_handler_->AddObserver(&observer_); | |
| 102 } | |
| 103 | |
| 104 void CreateRootForType(ModelType model_type) { | |
| 105 syncable::Directory* directory = user_share()->directory.get(); | |
| 106 | |
| 107 std::string tag_name = ModelTypeToRootTag(model_type); | |
| 108 | |
| 109 syncable::WriteTransaction wtrans(FROM_HERE, syncable::UNITTEST, directory); | |
| 110 syncable::MutableEntry node(&wtrans, syncable::CREATE, model_type, | |
| 111 wtrans.root_id(), tag_name); | |
| 112 node.PutUniqueServerTag(tag_name); | |
| 113 node.PutIsDir(true); | |
| 114 node.PutServerIsDir(false); | |
| 115 node.PutIsUnsynced(false); | |
| 116 node.PutIsUnappliedUpdate(false); | |
| 117 node.PutServerVersion(20); | |
| 118 node.PutBaseVersion(20); | |
| 119 node.PutIsDel(false); | |
| 120 node.PutId(ids_.MakeServer(tag_name)); | |
| 121 sync_pb::EntitySpecifics specifics; | |
| 122 AddDefaultFieldValue(model_type, &specifics); | |
| 123 node.PutSpecifics(specifics); | |
| 124 } | |
| 125 | |
| 126 void PumpLoop() { base::RunLoop().RunUntilIdle(); } | |
| 127 | |
| 128 // Getters for tests. | |
| 129 UserShare* user_share() { return test_user_share_.user_share(); } | |
| 130 SyncEncryptionHandlerImpl* encryption_handler() { | |
| 131 return encryption_handler_.get(); | |
| 132 } | |
| 133 SyncEncryptionHandlerObserverMock* observer() { return &observer_; } | |
| 134 Cryptographer* GetCryptographer() { | |
| 135 return encryption_handler_->GetCryptographerUnsafe(); | |
| 136 } | |
| 137 | |
| 138 void VerifyMigratedNigori(PassphraseType passphrase_type, | |
| 139 const std::string& passphrase) { | |
| 140 VerifyMigratedNigoriWithTimestamp(0, passphrase_type, passphrase); | |
| 141 } | |
| 142 | |
| 143 void VerifyMigratedNigoriWithTimestamp(int64_t migration_time, | |
| 144 PassphraseType passphrase_type, | |
| 145 const std::string& passphrase) { | |
| 146 ReadTransaction trans(FROM_HERE, user_share()); | |
| 147 ReadNode nigori_node(&trans); | |
| 148 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 149 const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics(); | |
| 150 if (migration_time > 0) | |
| 151 EXPECT_EQ(migration_time, nigori.keystore_migration_time()); | |
| 152 else | |
| 153 EXPECT_TRUE(nigori.has_keystore_migration_time()); | |
| 154 EXPECT_TRUE(nigori.keybag_is_frozen()); | |
| 155 if (passphrase_type == PassphraseType::CUSTOM_PASSPHRASE || | |
| 156 passphrase_type == PassphraseType::FROZEN_IMPLICIT_PASSPHRASE) { | |
| 157 EXPECT_TRUE(nigori.encrypt_everything()); | |
| 158 EXPECT_TRUE(nigori.keystore_decryptor_token().blob().empty()); | |
| 159 if (passphrase_type == PassphraseType::CUSTOM_PASSPHRASE) { | |
| 160 EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE, | |
| 161 nigori.passphrase_type()); | |
| 162 if (!encryption_handler()->custom_passphrase_time().is_null()) { | |
| 163 EXPECT_EQ( | |
| 164 nigori.custom_passphrase_time(), | |
| 165 TimeToProtoTime(encryption_handler()->custom_passphrase_time())); | |
| 166 } | |
| 167 } else { | |
| 168 EXPECT_EQ(sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE, | |
| 169 nigori.passphrase_type()); | |
| 170 } | |
| 171 } else { | |
| 172 EXPECT_FALSE(nigori.encrypt_everything()); | |
| 173 EXPECT_FALSE(nigori.keystore_decryptor_token().blob().empty()); | |
| 174 EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE, | |
| 175 nigori.passphrase_type()); | |
| 176 Cryptographer keystore_cryptographer(&encryptor_); | |
| 177 KeyParams params = {"localhost", "dummy", kKeystoreKey}; | |
| 178 keystore_cryptographer.AddKey(params); | |
| 179 EXPECT_TRUE(keystore_cryptographer.CanDecryptUsingDefaultKey( | |
| 180 nigori.keystore_decryptor_token())); | |
| 181 } | |
| 182 | |
| 183 Cryptographer temp_cryptographer(&encryptor_); | |
| 184 KeyParams params = {"localhost", "dummy", passphrase}; | |
| 185 temp_cryptographer.AddKey(params); | |
| 186 EXPECT_TRUE(temp_cryptographer.CanDecryptUsingDefaultKey( | |
| 187 nigori.encryption_keybag())); | |
| 188 } | |
| 189 | |
| 190 sync_pb::NigoriSpecifics BuildMigratedNigori( | |
| 191 PassphraseType passphrase_type, | |
| 192 int64_t migration_time, | |
| 193 const std::string& default_passphrase, | |
| 194 const std::string& keystore_key) { | |
| 195 DCHECK_NE(passphrase_type, PassphraseType::IMPLICIT_PASSPHRASE); | |
| 196 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 197 | |
| 198 std::string default_key = default_passphrase; | |
| 199 if (default_key.empty()) { | |
| 200 default_key = keystore_key; | |
| 201 } else { | |
| 202 KeyParams keystore_params = {"localhost", "dummy", keystore_key}; | |
| 203 other_cryptographer.AddKey(keystore_params); | |
| 204 } | |
| 205 KeyParams params = {"localhost", "dummy", default_key}; | |
| 206 other_cryptographer.AddKey(params); | |
| 207 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 208 | |
| 209 sync_pb::NigoriSpecifics nigori; | |
| 210 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 211 nigori.set_keybag_is_frozen(true); | |
| 212 nigori.set_keystore_migration_time(migration_time); | |
| 213 | |
| 214 if (passphrase_type == PassphraseType::KEYSTORE_PASSPHRASE) { | |
| 215 sync_pb::EncryptedData keystore_decryptor_token; | |
| 216 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 217 other_cryptographer, keystore_key, &keystore_decryptor_token)); | |
| 218 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 219 keystore_decryptor_token); | |
| 220 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 221 } else { | |
| 222 nigori.set_encrypt_everything(true); | |
| 223 nigori.set_passphrase_type( | |
| 224 passphrase_type == PassphraseType::CUSTOM_PASSPHRASE | |
| 225 ? sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE | |
| 226 : sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE); | |
| 227 } | |
| 228 return nigori; | |
| 229 } | |
| 230 | |
| 231 void VerifyPassphraseType(PassphraseType passphrase_type) { | |
| 232 ReadTransaction trans(FROM_HERE, user_share()); | |
| 233 EXPECT_EQ(passphrase_type, | |
| 234 encryption_handler()->GetPassphraseType(trans.GetWrappedTrans())); | |
| 235 } | |
| 236 | |
| 237 // Build a migrated nigori node with the specified default passphrase | |
| 238 // and keystore key and initialize the encryption handler with it. | |
| 239 void InitKeystoreMigratedNigori(int64_t migration_time, | |
| 240 const std::string& default_passphrase, | |
| 241 const std::string& keystore_key) { | |
| 242 { | |
| 243 WriteTransaction trans(FROM_HERE, user_share()); | |
| 244 WriteNode nigori_node(&trans); | |
| 245 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 246 sync_pb::NigoriSpecifics nigori = | |
| 247 BuildMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, | |
| 248 migration_time, default_passphrase, keystore_key); | |
| 249 nigori_node.SetNigoriSpecifics(nigori); | |
| 250 } | |
| 251 | |
| 252 EXPECT_CALL(*observer(), OnPassphraseTypeChanged( | |
| 253 PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 254 EXPECT_CALL(*observer(), | |
| 255 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 256 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AtLeast(1)); | |
| 257 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 258 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(AtLeast(1)); | |
| 259 encryption_handler()->Init(); | |
| 260 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 261 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 262 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 263 Mock::VerifyAndClearExpectations(observer()); | |
| 264 } | |
| 265 | |
| 266 // Build a migrated nigori node with the specified default passphrase | |
| 267 // as a custom passphrase. | |
| 268 void InitCustomPassMigratedNigori(int64_t migration_time, | |
| 269 const std::string& default_passphrase) { | |
| 270 { | |
| 271 WriteTransaction trans(FROM_HERE, user_share()); | |
| 272 WriteNode nigori_node(&trans); | |
| 273 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 274 sync_pb::NigoriSpecifics nigori = | |
| 275 BuildMigratedNigori(PassphraseType::CUSTOM_PASSPHRASE, migration_time, | |
| 276 default_passphrase, kKeystoreKey); | |
| 277 nigori_node.SetNigoriSpecifics(nigori); | |
| 278 } | |
| 279 | |
| 280 EXPECT_CALL(*observer(), | |
| 281 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 282 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AtLeast(1)); | |
| 283 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)) | |
| 284 .Times(AtLeast(1)); | |
| 285 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(AtLeast(1)); | |
| 286 encryption_handler()->Init(); | |
| 287 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 288 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 289 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 290 Mock::VerifyAndClearExpectations(observer()); | |
| 291 } | |
| 292 | |
| 293 // Build an unmigrated nigori node with the specified passphrase and type and | |
| 294 // initialize the encryption handler with it. | |
| 295 void InitUnmigratedNigori(const std::string& default_passphrase, | |
| 296 PassphraseType passphrase_type) { | |
| 297 DCHECK_NE(passphrase_type, PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 298 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 299 KeyParams default_key = {"localhost", "dummy", default_passphrase}; | |
| 300 other_cryptographer.AddKey(default_key); | |
| 301 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 302 | |
| 303 { | |
| 304 WriteTransaction trans(FROM_HERE, user_share()); | |
| 305 WriteNode nigori_node(&trans); | |
| 306 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 307 sync_pb::NigoriSpecifics nigori; | |
| 308 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 309 nigori.set_keybag_is_frozen(passphrase_type == | |
| 310 PassphraseType::CUSTOM_PASSPHRASE); | |
| 311 nigori_node.SetNigoriSpecifics(nigori); | |
| 312 } | |
| 313 | |
| 314 if (passphrase_type != PassphraseType::IMPLICIT_PASSPHRASE) { | |
| 315 EXPECT_CALL(*observer(), OnPassphraseTypeChanged(passphrase_type, _)); | |
| 316 } | |
| 317 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AtLeast(1)); | |
| 318 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 319 encryption_handler()->Init(); | |
| 320 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 321 VerifyPassphraseType(passphrase_type); | |
| 322 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 323 Mock::VerifyAndClearExpectations(observer()); | |
| 324 } | |
| 325 | |
| 326 // Verify we can restore the SyncEncryptionHandler state using a saved | |
| 327 // |bootstrap_token| and |nigori_state|. | |
| 328 // | |
| 329 // |migration_time| is the time migration occurred. | |
| 330 // | |
| 331 // |passphrase| is the custom passphrase. | |
| 332 void VerifyRestoreAfterCustomPassphrase( | |
| 333 int64_t migration_time, | |
| 334 const std::string& passphrase, | |
| 335 const std::string& bootstrap_token, | |
| 336 const SyncEncryptionHandler::NigoriState& nigori_state, | |
| 337 PassphraseType passphrase_type) { | |
| 338 TearDown(); | |
| 339 test_user_share_.SetUp(); | |
| 340 SetUpEncryptionWithKeyForBootstrapping(bootstrap_token); | |
| 341 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 342 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)) | |
| 343 .Times(AnyNumber()); | |
| 344 EXPECT_CALL(*observer(), OnPassphraseTypeChanged(passphrase_type, _)); | |
| 345 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 346 encryption_handler()->RestoreNigori(nigori_state); | |
| 347 encryption_handler()->Init(); | |
| 348 Mock::VerifyAndClearExpectations(observer()); | |
| 349 VerifyMigratedNigoriWithTimestamp(migration_time, passphrase_type, | |
| 350 passphrase); | |
| 351 } | |
| 352 | |
| 353 protected: | |
| 354 TestUserShare test_user_share_; | |
| 355 FakeEncryptor encryptor_; | |
| 356 std::unique_ptr<SyncEncryptionHandlerImpl> encryption_handler_; | |
| 357 StrictMock<SyncEncryptionHandlerObserverMock> observer_; | |
| 358 TestIdFactory ids_; | |
| 359 base::MessageLoop message_loop_; | |
| 360 }; | |
| 361 | |
| 362 // Verify that the encrypted types are being written to and read from the | |
| 363 // nigori node properly. | |
| 364 TEST_F(SyncEncryptionHandlerImplTest, NigoriEncryptionTypes) { | |
| 365 sync_pb::NigoriSpecifics nigori; | |
| 366 | |
| 367 StrictMock<SyncEncryptionHandlerObserverMock> observer2; | |
| 368 SyncEncryptionHandlerImpl handler2(user_share(), &encryptor_, std::string(), | |
| 369 std::string() /* bootstrap tokens */); | |
| 370 handler2.AddObserver(&observer2); | |
| 371 | |
| 372 // Just set the sensitive types (shouldn't trigger any notifications). | |
| 373 ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); | |
| 374 { | |
| 375 WriteTransaction trans(FROM_HERE, user_share()); | |
| 376 encryption_handler()->MergeEncryptedTypes(encrypted_types, | |
| 377 trans.GetWrappedTrans()); | |
| 378 encryption_handler()->UpdateNigoriFromEncryptedTypes( | |
| 379 &nigori, trans.GetWrappedTrans()); | |
| 380 handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans()); | |
| 381 } | |
| 382 EXPECT_EQ(encrypted_types, encryption_handler()->GetEncryptedTypesUnsafe()); | |
| 383 EXPECT_EQ(encrypted_types, handler2.GetEncryptedTypesUnsafe()); | |
| 384 | |
| 385 Mock::VerifyAndClearExpectations(observer()); | |
| 386 Mock::VerifyAndClearExpectations(&observer2); | |
| 387 | |
| 388 ModelTypeSet encrypted_user_types = EncryptableUserTypes(); | |
| 389 | |
| 390 EXPECT_CALL(*observer(), OnEncryptedTypesChanged( | |
| 391 HasModelTypes(encrypted_user_types), false)); | |
| 392 EXPECT_CALL(observer2, OnEncryptedTypesChanged( | |
| 393 HasModelTypes(encrypted_user_types), false)); | |
| 394 | |
| 395 // Set all encrypted types | |
| 396 encrypted_types = EncryptableUserTypes(); | |
| 397 { | |
| 398 WriteTransaction trans(FROM_HERE, user_share()); | |
| 399 encryption_handler()->MergeEncryptedTypes(encrypted_types, | |
| 400 trans.GetWrappedTrans()); | |
| 401 encryption_handler()->UpdateNigoriFromEncryptedTypes( | |
| 402 &nigori, trans.GetWrappedTrans()); | |
| 403 handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans()); | |
| 404 } | |
| 405 EXPECT_EQ(encrypted_types, encryption_handler()->GetEncryptedTypesUnsafe()); | |
| 406 EXPECT_EQ(encrypted_types, handler2.GetEncryptedTypesUnsafe()); | |
| 407 | |
| 408 // Receiving an empty nigori should not reset any encrypted types or trigger | |
| 409 // an observer notification. | |
| 410 Mock::VerifyAndClearExpectations(observer()); | |
| 411 Mock::VerifyAndClearExpectations(&observer2); | |
| 412 nigori = sync_pb::NigoriSpecifics(); | |
| 413 { | |
| 414 WriteTransaction trans(FROM_HERE, user_share()); | |
| 415 handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans()); | |
| 416 } | |
| 417 EXPECT_EQ(encrypted_types, encryption_handler()->GetEncryptedTypesUnsafe()); | |
| 418 } | |
| 419 | |
| 420 // Verify the encryption handler processes the encrypt everything field | |
| 421 // properly. | |
| 422 TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingExplicit) { | |
| 423 sync_pb::NigoriSpecifics nigori; | |
| 424 nigori.set_encrypt_everything(true); | |
| 425 | |
| 426 EXPECT_CALL(*observer(), OnEncryptedTypesChanged( | |
| 427 HasModelTypes(EncryptableUserTypes()), true)); | |
| 428 | |
| 429 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 430 ModelTypeSet encrypted_types = | |
| 431 encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 432 EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS), encrypted_types); | |
| 433 | |
| 434 { | |
| 435 WriteTransaction trans(FROM_HERE, user_share()); | |
| 436 encryption_handler()->UpdateEncryptedTypesFromNigori( | |
| 437 nigori, trans.GetWrappedTrans()); | |
| 438 } | |
| 439 | |
| 440 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 441 encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 442 EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes())); | |
| 443 | |
| 444 // Receiving the nigori node again shouldn't trigger another notification. | |
| 445 Mock::VerifyAndClearExpectations(observer()); | |
| 446 { | |
| 447 WriteTransaction trans(FROM_HERE, user_share()); | |
| 448 encryption_handler()->UpdateEncryptedTypesFromNigori( | |
| 449 nigori, trans.GetWrappedTrans()); | |
| 450 } | |
| 451 } | |
| 452 | |
| 453 // Verify the encryption handler can detect an implicit encrypt everything state | |
| 454 // (from clients that failed to write the encrypt everything field). | |
| 455 TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingImplicit) { | |
| 456 sync_pb::NigoriSpecifics nigori; | |
| 457 nigori.set_encrypt_bookmarks(true); // Non-passwords = encrypt everything | |
| 458 | |
| 459 EXPECT_CALL(*observer(), OnEncryptedTypesChanged( | |
| 460 HasModelTypes(EncryptableUserTypes()), true)); | |
| 461 | |
| 462 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 463 ModelTypeSet encrypted_types = | |
| 464 encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 465 EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS), encrypted_types); | |
| 466 | |
| 467 { | |
| 468 WriteTransaction trans(FROM_HERE, user_share()); | |
| 469 encryption_handler()->UpdateEncryptedTypesFromNigori( | |
| 470 nigori, trans.GetWrappedTrans()); | |
| 471 } | |
| 472 | |
| 473 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 474 encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 475 EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes())); | |
| 476 | |
| 477 // Receiving a nigori node with encrypt everything explicitly set shouldn't | |
| 478 // trigger another notification. | |
| 479 Mock::VerifyAndClearExpectations(observer()); | |
| 480 nigori.set_encrypt_everything(true); | |
| 481 { | |
| 482 WriteTransaction trans(FROM_HERE, user_share()); | |
| 483 encryption_handler()->UpdateEncryptedTypesFromNigori( | |
| 484 nigori, trans.GetWrappedTrans()); | |
| 485 } | |
| 486 } | |
| 487 | |
| 488 // Verify the encryption handler can deal with new versions treating new types | |
| 489 // as Sensitive, and that it does not consider this an implicit encrypt | |
| 490 // everything case. | |
| 491 TEST_F(SyncEncryptionHandlerImplTest, UnknownSensitiveTypes) { | |
| 492 sync_pb::NigoriSpecifics nigori; | |
| 493 nigori.set_encrypt_everything(false); | |
| 494 nigori.set_encrypt_bookmarks(true); | |
| 495 | |
| 496 ModelTypeSet expected_encrypted_types = | |
| 497 SyncEncryptionHandler::SensitiveTypes(); | |
| 498 expected_encrypted_types.Put(BOOKMARKS); | |
| 499 | |
| 500 EXPECT_CALL(*observer(), OnEncryptedTypesChanged( | |
| 501 HasModelTypes(expected_encrypted_types), false)); | |
| 502 | |
| 503 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 504 ModelTypeSet encrypted_types = | |
| 505 encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 506 EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS), encrypted_types); | |
| 507 | |
| 508 { | |
| 509 WriteTransaction trans(FROM_HERE, user_share()); | |
| 510 encryption_handler()->UpdateEncryptedTypesFromNigori( | |
| 511 nigori, trans.GetWrappedTrans()); | |
| 512 } | |
| 513 | |
| 514 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 515 encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); | |
| 516 EXPECT_EQ(ModelTypeSet(BOOKMARKS, PASSWORDS, WIFI_CREDENTIALS), | |
| 517 encrypted_types); | |
| 518 } | |
| 519 | |
| 520 // Receive an old nigori with old encryption keys and encrypted types. We should | |
| 521 // not revert our default key or encrypted types, and should post a task to | |
| 522 // overwrite the existing nigori with the correct data. | |
| 523 TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldNigori) { | |
| 524 KeyParams old_key = {"localhost", "dummy", "old"}; | |
| 525 KeyParams current_key = {"localhost", "dummy", "cur"}; | |
| 526 | |
| 527 // Data for testing encryption/decryption. | |
| 528 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 529 other_cryptographer.AddKey(old_key); | |
| 530 sync_pb::EntitySpecifics other_encrypted_specifics; | |
| 531 other_encrypted_specifics.mutable_bookmark()->set_title("title"); | |
| 532 other_cryptographer.Encrypt(other_encrypted_specifics, | |
| 533 other_encrypted_specifics.mutable_encrypted()); | |
| 534 sync_pb::EntitySpecifics our_encrypted_specifics; | |
| 535 our_encrypted_specifics.mutable_bookmark()->set_title("title2"); | |
| 536 ModelTypeSet encrypted_types = EncryptableUserTypes(); | |
| 537 | |
| 538 // Set up the current encryption state (containing both keys and encrypt | |
| 539 // everything). | |
| 540 sync_pb::NigoriSpecifics current_nigori_specifics; | |
| 541 GetCryptographer()->AddKey(old_key); | |
| 542 GetCryptographer()->AddKey(current_key); | |
| 543 GetCryptographer()->Encrypt(our_encrypted_specifics, | |
| 544 our_encrypted_specifics.mutable_encrypted()); | |
| 545 GetCryptographer()->GetKeys( | |
| 546 current_nigori_specifics.mutable_encryption_keybag()); | |
| 547 current_nigori_specifics.set_encrypt_everything(true); | |
| 548 | |
| 549 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 550 EXPECT_CALL(*observer(), OnEncryptedTypesChanged( | |
| 551 HasModelTypes(EncryptableUserTypes()), true)); | |
| 552 { | |
| 553 // Update the encryption handler. | |
| 554 WriteTransaction trans(FROM_HERE, user_share()); | |
| 555 encryption_handler()->ApplyNigoriUpdate(current_nigori_specifics, | |
| 556 trans.GetWrappedTrans()); | |
| 557 } | |
| 558 Mock::VerifyAndClearExpectations(observer()); | |
| 559 | |
| 560 // Now set up the old nigori specifics and apply it on top. | |
| 561 // Has an old set of keys, and no encrypted types. | |
| 562 sync_pb::NigoriSpecifics old_nigori; | |
| 563 other_cryptographer.GetKeys(old_nigori.mutable_encryption_keybag()); | |
| 564 | |
| 565 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 566 { | |
| 567 // Update the encryption handler. | |
| 568 WriteTransaction trans(FROM_HERE, user_share()); | |
| 569 encryption_handler()->ApplyNigoriUpdate(old_nigori, | |
| 570 trans.GetWrappedTrans()); | |
| 571 } | |
| 572 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 573 EXPECT_FALSE(GetCryptographer()->has_pending_keys()); | |
| 574 | |
| 575 // Encryption handler should have posted a task to overwrite the old | |
| 576 // specifics. | |
| 577 PumpLoop(); | |
| 578 | |
| 579 { | |
| 580 // The cryptographer should be able to decrypt both sets of keys and still | |
| 581 // be encrypting with the newest, and the encrypted types should be the | |
| 582 // most recent. | |
| 583 // In addition, the nigori node should match the current encryption state. | |
| 584 ReadTransaction trans(FROM_HERE, user_share()); | |
| 585 ReadNode nigori_node(&trans); | |
| 586 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 587 const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics(); | |
| 588 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey( | |
| 589 our_encrypted_specifics.encrypted())); | |
| 590 EXPECT_TRUE( | |
| 591 GetCryptographer()->CanDecrypt(other_encrypted_specifics.encrypted())); | |
| 592 EXPECT_TRUE(GetCryptographer()->CanDecrypt(nigori.encryption_keybag())); | |
| 593 EXPECT_TRUE(nigori.encrypt_everything()); | |
| 594 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey( | |
| 595 nigori.encryption_keybag())); | |
| 596 } | |
| 597 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 598 } | |
| 599 | |
| 600 // Ensure setting the keystore key works, updates the bootstrap token, and | |
| 601 // triggers a non-backwards compatible migration. Then verify that the | |
| 602 // bootstrap token can be correctly parsed by the encryption handler at startup | |
| 603 // time. | |
| 604 TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreMigratesAndUpdatesBootstrap) { | |
| 605 // Passing no keys should do nothing. | |
| 606 EXPECT_CALL(*observer(), OnBootstrapTokenUpdated(_, _)).Times(0); | |
| 607 { | |
| 608 WriteTransaction trans(FROM_HERE, user_share()); | |
| 609 EXPECT_FALSE(GetCryptographer()->is_initialized()); | |
| 610 EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); | |
| 611 EXPECT_FALSE(encryption_handler()->SetKeystoreKeys( | |
| 612 BuildEncryptionKeyProto(std::string()), trans.GetWrappedTrans())); | |
| 613 EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); | |
| 614 } | |
| 615 Mock::VerifyAndClearExpectations(observer()); | |
| 616 | |
| 617 // Build a set of keystore keys. | |
| 618 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 619 std::string old_keystore_key; | |
| 620 base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key); | |
| 621 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 622 keys.Add()->assign(kRawOldKeystoreKey); | |
| 623 keys.Add()->assign(kRawKeystoreKey); | |
| 624 | |
| 625 // Pass them to the encryption handler, triggering a migration and bootstrap | |
| 626 // token update. | |
| 627 std::string encoded_key; | |
| 628 std::string keystore_bootstrap; | |
| 629 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 630 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)); | |
| 631 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 632 EXPECT_CALL(*observer(), | |
| 633 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 634 EXPECT_CALL(*observer(), OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)) | |
| 635 .WillOnce(SaveArg<0>(&keystore_bootstrap)); | |
| 636 { | |
| 637 WriteTransaction trans(FROM_HERE, user_share()); | |
| 638 EXPECT_TRUE( | |
| 639 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans())); | |
| 640 EXPECT_FALSE( | |
| 641 encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); | |
| 642 EXPECT_FALSE(GetCryptographer()->is_initialized()); | |
| 643 } | |
| 644 PumpLoop(); | |
| 645 EXPECT_TRUE(GetCryptographer()->is_initialized()); | |
| 646 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 647 | |
| 648 // Ensure the bootstrap is encoded properly (a base64 encoded encrypted blob | |
| 649 // of list values containing the keystore keys). | |
| 650 std::string decoded_bootstrap; | |
| 651 ASSERT_TRUE(base::Base64Decode(keystore_bootstrap, &decoded_bootstrap)); | |
| 652 std::string decrypted_bootstrap; | |
| 653 ASSERT_TRUE(GetCryptographer()->encryptor()->DecryptString( | |
| 654 decoded_bootstrap, &decrypted_bootstrap)); | |
| 655 JSONStringValueDeserializer json(decrypted_bootstrap); | |
| 656 std::unique_ptr<base::Value> deserialized_keystore_keys( | |
| 657 json.Deserialize(NULL, NULL)); | |
| 658 ASSERT_TRUE(deserialized_keystore_keys.get()); | |
| 659 base::ListValue* keystore_list = NULL; | |
| 660 deserialized_keystore_keys->GetAsList(&keystore_list); | |
| 661 ASSERT_TRUE(keystore_list); | |
| 662 ASSERT_EQ(2U, keystore_list->GetSize()); | |
| 663 std::string test_string; | |
| 664 keystore_list->GetString(0, &test_string); | |
| 665 ASSERT_EQ(old_keystore_key, test_string); | |
| 666 keystore_list->GetString(1, &test_string); | |
| 667 ASSERT_EQ(kKeystoreKey, test_string); | |
| 668 | |
| 669 // Now make sure a new encryption handler can correctly parse the bootstrap | |
| 670 // token. | |
| 671 SyncEncryptionHandlerImpl handler2(user_share(), &encryptor_, | |
| 672 std::string(), // Cryptographer bootstrap. | |
| 673 keystore_bootstrap); | |
| 674 | |
| 675 { | |
| 676 WriteTransaction trans(FROM_HERE, user_share()); | |
| 677 EXPECT_FALSE(handler2.NeedKeystoreKey(trans.GetWrappedTrans())); | |
| 678 } | |
| 679 } | |
| 680 | |
| 681 // Ensure GetKeystoreDecryptor only updates the keystore decryptor token if it | |
| 682 // wasn't already set properly. Otherwise, the decryptor should remain the | |
| 683 // same. | |
| 684 TEST_F(SyncEncryptionHandlerImplTest, GetKeystoreDecryptor) { | |
| 685 const char kCurKey[] = "cur"; | |
| 686 sync_pb::EncryptedData encrypted; | |
| 687 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 688 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 689 other_cryptographer.AddKey(cur_key); | |
| 690 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 691 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 692 other_cryptographer, kKeystoreKey, &encrypted)); | |
| 693 std::string serialized = encrypted.SerializeAsString(); | |
| 694 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 695 other_cryptographer, kKeystoreKey, &encrypted)); | |
| 696 EXPECT_EQ(serialized, encrypted.SerializeAsString()); | |
| 697 } | |
| 698 | |
| 699 // Test that we don't attempt to migrate while an implicit passphrase is pending | |
| 700 // and that once we do decrypt pending keys we migrate the nigori. Once | |
| 701 // migrated, we should be in keystore passphrase state. | |
| 702 TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptImplicitPass) { | |
| 703 const char kOtherKey[] = "other"; | |
| 704 { | |
| 705 EXPECT_CALL(*observer(), | |
| 706 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 707 ReadTransaction trans(FROM_HERE, user_share()); | |
| 708 encryption_handler()->SetKeystoreKeys( | |
| 709 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 710 Mock::VerifyAndClearExpectations(observer()); | |
| 711 } | |
| 712 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 713 | |
| 714 { | |
| 715 WriteTransaction trans(FROM_HERE, user_share()); | |
| 716 WriteNode nigori_node(&trans); | |
| 717 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 718 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 719 KeyParams other_key = {"localhost", "dummy", kOtherKey}; | |
| 720 other_cryptographer.AddKey(other_key); | |
| 721 | |
| 722 sync_pb::NigoriSpecifics nigori; | |
| 723 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 724 nigori.set_keybag_is_frozen(false); | |
| 725 nigori.set_encrypt_everything(false); | |
| 726 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 727 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 728 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 729 nigori_node.SetNigoriSpecifics(nigori); | |
| 730 } | |
| 731 // Run any tasks posted via AppplyNigoriUpdate. | |
| 732 PumpLoop(); | |
| 733 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 734 Mock::VerifyAndClearExpectations(observer()); | |
| 735 | |
| 736 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 737 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 738 EXPECT_CALL(*observer(), | |
| 739 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 740 EXPECT_CALL(*observer(), | |
| 741 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 742 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 743 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 744 encryption_handler()->SetDecryptionPassphrase(kOtherKey); | |
| 745 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 746 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 747 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kOtherKey); | |
| 748 } | |
| 749 | |
| 750 // Test that we don't attempt to migrate while a custom passphrase is pending, | |
| 751 // and that once we do decrypt pending keys we migrate the nigori. Once | |
| 752 // migrated, we should be in custom passphrase state with encrypt everything. | |
| 753 TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptCustomPass) { | |
| 754 const char kOtherKey[] = "other"; | |
| 755 { | |
| 756 EXPECT_CALL(*observer(), | |
| 757 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 758 ReadTransaction trans(FROM_HERE, user_share()); | |
| 759 encryption_handler()->SetKeystoreKeys( | |
| 760 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 761 Mock::VerifyAndClearExpectations(observer()); | |
| 762 } | |
| 763 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 764 | |
| 765 { | |
| 766 WriteTransaction trans(FROM_HERE, user_share()); | |
| 767 WriteNode nigori_node(&trans); | |
| 768 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 769 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 770 KeyParams other_key = {"localhost", "dummy", kOtherKey}; | |
| 771 other_cryptographer.AddKey(other_key); | |
| 772 | |
| 773 sync_pb::NigoriSpecifics nigori; | |
| 774 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 775 nigori.set_keybag_is_frozen(true); | |
| 776 nigori.set_encrypt_everything(false); | |
| 777 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 778 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 779 EXPECT_CALL(*observer(), | |
| 780 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 781 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 782 nigori_node.SetNigoriSpecifics(nigori); | |
| 783 } | |
| 784 // Run any tasks posted via AppplyNigoriUpdate. | |
| 785 PumpLoop(); | |
| 786 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 787 Mock::VerifyAndClearExpectations(observer()); | |
| 788 | |
| 789 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 790 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 791 std::string captured_bootstrap_token; | |
| 792 EXPECT_CALL(*observer(), | |
| 793 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 794 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 795 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 796 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 797 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 798 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 799 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(2); | |
| 800 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 801 encryption_handler()->SetDecryptionPassphrase(kOtherKey); | |
| 802 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 803 const base::Time migration_time = encryption_handler()->migration_time(); | |
| 804 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 805 VerifyMigratedNigori(PassphraseType::CUSTOM_PASSPHRASE, kOtherKey); | |
| 806 | |
| 807 VerifyRestoreAfterCustomPassphrase( | |
| 808 TimeToProtoTime(migration_time), kOtherKey, captured_bootstrap_token, | |
| 809 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 810 } | |
| 811 | |
| 812 // Test that we trigger a migration when we set the keystore key, had an | |
| 813 // implicit passphrase, and did not have encrypt everything. We should switch | |
| 814 // to PassphraseType::KEYSTORE_PASSPHRASE. | |
| 815 TEST_F(SyncEncryptionHandlerImplTest, MigrateOnKeystoreKeyAvailableImplicit) { | |
| 816 const char kCurKey[] = "cur"; | |
| 817 KeyParams current_key = {"localhost", "dummy", kCurKey}; | |
| 818 GetCryptographer()->AddKey(current_key); | |
| 819 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 820 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 821 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 822 encryption_handler()->Init(); | |
| 823 Mock::VerifyAndClearExpectations(observer()); | |
| 824 | |
| 825 { | |
| 826 ReadTransaction trans(FROM_HERE, user_share()); | |
| 827 // Once we provide a keystore key, we should perform the migration. | |
| 828 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 829 EXPECT_CALL(*observer(), | |
| 830 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 831 encryption_handler()->SetKeystoreKeys( | |
| 832 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 833 } | |
| 834 EXPECT_CALL(*observer(), | |
| 835 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 836 // The actual migration gets posted, so run all pending tasks. | |
| 837 PumpLoop(); | |
| 838 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 839 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 840 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 841 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kCurKey); | |
| 842 } | |
| 843 | |
| 844 // Test that we trigger a migration when we set the keystore key, had an | |
| 845 // implicit passphrase, and encrypt everything enabled. We should switch to | |
| 846 // PassphraseType::FROZEN_IMPLICIT_PASSPHRASE. | |
| 847 TEST_F(SyncEncryptionHandlerImplTest, | |
| 848 MigrateOnKeystoreKeyAvailableFrozenImplicit) { | |
| 849 const char kCurKey[] = "cur"; | |
| 850 KeyParams current_key = {"localhost", "dummy", kCurKey}; | |
| 851 GetCryptographer()->AddKey(current_key); | |
| 852 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 853 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 854 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 855 encryption_handler()->Init(); | |
| 856 Mock::VerifyAndClearExpectations(observer()); | |
| 857 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 858 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 859 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 860 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 861 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 862 encryption_handler()->EnableEncryptEverything(); | |
| 863 | |
| 864 { | |
| 865 ReadTransaction trans(FROM_HERE, user_share()); | |
| 866 // Once we provide a keystore key, we should perform the migration. | |
| 867 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 868 EXPECT_CALL(*observer(), | |
| 869 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 870 encryption_handler()->SetKeystoreKeys( | |
| 871 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 872 } | |
| 873 EXPECT_CALL(*observer(), OnPassphraseTypeChanged( | |
| 874 PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, _)); | |
| 875 | |
| 876 // The actual migration gets posted, so run all pending tasks. | |
| 877 PumpLoop(); | |
| 878 Mock::VerifyAndClearExpectations(observer()); | |
| 879 | |
| 880 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 881 const base::Time migration_time = encryption_handler()->migration_time(); | |
| 882 VerifyPassphraseType(PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 883 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 884 VerifyMigratedNigori(PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, kCurKey); | |
| 885 | |
| 886 // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_, | |
| 887 // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked | |
| 888 // during a previous instance) so get it from the Cryptographer. | |
| 889 std::string passphrase_bootstrap_token; | |
| 890 GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token); | |
| 891 VerifyRestoreAfterCustomPassphrase( | |
| 892 TimeToProtoTime(migration_time), kCurKey, passphrase_bootstrap_token, | |
| 893 captured_nigori_state, PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 894 } | |
| 895 | |
| 896 // Test that we trigger a migration when we set the keystore key, had a | |
| 897 // custom passphrase, and encrypt everything enabled. The passphrase state | |
| 898 // should remain as CUSTOM_PASSPHRASE, and encrypt everything stay the same. | |
| 899 TEST_F(SyncEncryptionHandlerImplTest, | |
| 900 MigrateOnKeystoreKeyAvailableCustomWithEncryption) { | |
| 901 const char kCurKey[] = "cur"; | |
| 902 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 903 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 904 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 905 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 906 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 907 EXPECT_CALL(*observer(), | |
| 908 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 909 std::string captured_bootstrap_token; | |
| 910 EXPECT_CALL(*observer(), | |
| 911 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 912 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 913 encryption_handler()->Init(); | |
| 914 encryption_handler()->SetEncryptionPassphrase(kCurKey, true); | |
| 915 EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); | |
| 916 Mock::VerifyAndClearExpectations(observer()); | |
| 917 | |
| 918 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 919 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 920 encryption_handler()->EnableEncryptEverything(); | |
| 921 Mock::VerifyAndClearExpectations(observer()); | |
| 922 | |
| 923 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 924 { | |
| 925 ReadTransaction trans(FROM_HERE, user_share()); | |
| 926 // Once we provide a keystore key, we should perform the migration. | |
| 927 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 928 EXPECT_CALL(*observer(), | |
| 929 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 930 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 931 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 932 encryption_handler()->SetKeystoreKeys( | |
| 933 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 934 } | |
| 935 | |
| 936 // The actual migration gets posted, so run all pending tasks. | |
| 937 PumpLoop(); | |
| 938 Mock::VerifyAndClearExpectations(observer()); | |
| 939 | |
| 940 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 941 const base::Time migration_time = encryption_handler()->migration_time(); | |
| 942 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 943 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 944 VerifyMigratedNigori(PassphraseType::CUSTOM_PASSPHRASE, kCurKey); | |
| 945 | |
| 946 VerifyRestoreAfterCustomPassphrase( | |
| 947 TimeToProtoTime(migration_time), kCurKey, captured_bootstrap_token, | |
| 948 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 949 } | |
| 950 | |
| 951 // Test that we trigger a migration when we set the keystore key, had a | |
| 952 // custom passphrase, and did not have encrypt everything. The passphrase state | |
| 953 // should remain as PassphraseType::CUSTOM_PASSPHRASE, and encrypt everything | |
| 954 // should be enabled. | |
| 955 TEST_F(SyncEncryptionHandlerImplTest, | |
| 956 MigrateOnKeystoreKeyAvailableCustomNoEncryption) { | |
| 957 const char kCurKey[] = "cur"; | |
| 958 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 959 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 960 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 961 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 962 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 963 EXPECT_CALL(*observer(), | |
| 964 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 965 std::string captured_bootstrap_token; | |
| 966 EXPECT_CALL(*observer(), | |
| 967 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 968 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 969 encryption_handler()->Init(); | |
| 970 encryption_handler()->SetEncryptionPassphrase(kCurKey, true); | |
| 971 EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); | |
| 972 Mock::VerifyAndClearExpectations(observer()); | |
| 973 | |
| 974 { | |
| 975 ReadTransaction trans(FROM_HERE, user_share()); | |
| 976 // Once we provide a keystore key, we should perform the migration. | |
| 977 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 978 EXPECT_CALL(*observer(), | |
| 979 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 980 encryption_handler()->SetKeystoreKeys( | |
| 981 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 982 } | |
| 983 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 984 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 985 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 986 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 987 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 988 // The actual migration gets posted, so run all pending tasks. | |
| 989 PumpLoop(); | |
| 990 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 991 const base::Time migration_time = encryption_handler()->migration_time(); | |
| 992 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 993 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 994 VerifyMigratedNigori(PassphraseType::CUSTOM_PASSPHRASE, kCurKey); | |
| 995 | |
| 996 VerifyRestoreAfterCustomPassphrase( | |
| 997 TimeToProtoTime(migration_time), kCurKey, captured_bootstrap_token, | |
| 998 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 999 } | |
| 1000 | |
| 1001 // Test that we can handle receiving a migrated nigori node in the | |
| 1002 // KEYSTORE_PASS state, and use the keystore decryptor token to decrypt the | |
| 1003 // keybag. | |
| 1004 TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriKeystorePass) { | |
| 1005 const char kCurKey[] = "cur"; | |
| 1006 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1007 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1008 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1009 other_cryptographer.AddKey(cur_key); | |
| 1010 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1011 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1012 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1013 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1014 EXPECT_FALSE(GetCryptographer()->is_ready()); | |
| 1015 { | |
| 1016 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1017 EXPECT_NE(encryption_handler()->GetPassphraseType(trans.GetWrappedTrans()), | |
| 1018 PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1019 } | |
| 1020 // Now build a nigori node with the generated keystore decryptor token and | |
| 1021 // initialize the encryption handler with it. The cryptographer should be | |
| 1022 // initialized properly to decrypt both kCurKey and kKeystoreKey. | |
| 1023 { | |
| 1024 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1025 WriteNode nigori_node(&trans); | |
| 1026 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1027 sync_pb::NigoriSpecifics nigori; | |
| 1028 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1029 keystore_decryptor_token); | |
| 1030 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1031 nigori.set_keybag_is_frozen(true); | |
| 1032 nigori.set_keystore_migration_time(1); | |
| 1033 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1034 | |
| 1035 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1036 EXPECT_CALL(*observer(), | |
| 1037 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1038 EXPECT_CALL(*observer(), | |
| 1039 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1040 EXPECT_CALL(*observer(), OnPassphraseTypeChanged( | |
| 1041 PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1042 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1043 encryption_handler()->SetKeystoreKeys( | |
| 1044 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1045 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1046 nigori_node.SetNigoriSpecifics(nigori); | |
| 1047 } | |
| 1048 // Run any tasks posted via AppplyNigoriUpdate. | |
| 1049 PumpLoop(); | |
| 1050 Mock::VerifyAndClearExpectations(observer()); | |
| 1051 | |
| 1052 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1053 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1054 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1055 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1056 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::KEYSTORE_PASSPHRASE, | |
| 1057 kCurKey); | |
| 1058 | |
| 1059 // Check that the cryptographer still encrypts with the current key. | |
| 1060 sync_pb::EncryptedData current_encrypted; | |
| 1061 other_cryptographer.EncryptString("string", ¤t_encrypted); | |
| 1062 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); | |
| 1063 | |
| 1064 // Check that the cryptographer can decrypt keystore key based encryption. | |
| 1065 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1066 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1067 keystore_cryptographer.AddKey(keystore_key); | |
| 1068 sync_pb::EncryptedData keystore_encrypted; | |
| 1069 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1070 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1071 } | |
| 1072 | |
| 1073 // Test that we handle receiving migrated nigori's with | |
| 1074 // PassphraseType::FROZEN_IMPLICIT_PASSPHRASE state. We should be in a pending | |
| 1075 // key state until | |
| 1076 // we supply the pending frozen implicit passphrase key. | |
| 1077 TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriFrozenImplicitPass) { | |
| 1078 const char kCurKey[] = "cur"; | |
| 1079 sync_pb::EncryptedData encrypted; | |
| 1080 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1081 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1082 other_cryptographer.AddKey(cur_key); | |
| 1083 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1084 | |
| 1085 { | |
| 1086 EXPECT_CALL(*observer(), | |
| 1087 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1088 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1089 encryption_handler()->SetKeystoreKeys( | |
| 1090 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1091 } | |
| 1092 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1093 | |
| 1094 { | |
| 1095 EXPECT_CALL( | |
| 1096 *observer(), | |
| 1097 OnPassphraseTypeChanged(PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, _)); | |
| 1098 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1099 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1100 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 1101 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1102 WriteNode nigori_node(&trans); | |
| 1103 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1104 sync_pb::NigoriSpecifics nigori; | |
| 1105 nigori.set_keybag_is_frozen(true); | |
| 1106 nigori.set_passphrase_type( | |
| 1107 sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE); | |
| 1108 nigori.set_keystore_migration_time(1); | |
| 1109 nigori.set_encrypt_everything(true); | |
| 1110 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1111 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1112 nigori_node.SetNigoriSpecifics(nigori); | |
| 1113 } | |
| 1114 // Run any tasks posted via AppplyNigoriUpdate. | |
| 1115 PumpLoop(); | |
| 1116 Mock::VerifyAndClearExpectations(observer()); | |
| 1117 | |
| 1118 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1119 VerifyPassphraseType(PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 1120 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1121 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1122 | |
| 1123 EXPECT_CALL(*observer(), | |
| 1124 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1125 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1126 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1127 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1128 encryption_handler()->SetDecryptionPassphrase(kCurKey); | |
| 1129 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1130 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1131 VerifyMigratedNigoriWithTimestamp( | |
| 1132 1, PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, kCurKey); | |
| 1133 | |
| 1134 // Check that the cryptographer still encrypts with the current key. | |
| 1135 sync_pb::EncryptedData current_encrypted; | |
| 1136 other_cryptographer.EncryptString("string", ¤t_encrypted); | |
| 1137 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); | |
| 1138 | |
| 1139 // Check that the cryptographer can decrypt keystore key based encryption. | |
| 1140 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1141 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1142 keystore_cryptographer.AddKey(keystore_key); | |
| 1143 sync_pb::EncryptedData keystore_encrypted; | |
| 1144 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1145 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1146 } | |
| 1147 | |
| 1148 // Test that we handle receiving migrated nigori's with | |
| 1149 // PassphraseType::CUSTOM_PASSPHRASE state. We should be in a pending key state | |
| 1150 // until we | |
| 1151 // provide the custom passphrase key. | |
| 1152 TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriCustomPass) { | |
| 1153 const char kCurKey[] = "cur"; | |
| 1154 sync_pb::EncryptedData encrypted; | |
| 1155 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1156 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1157 other_cryptographer.AddKey(cur_key); | |
| 1158 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1159 | |
| 1160 { | |
| 1161 EXPECT_CALL(*observer(), | |
| 1162 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1163 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1164 encryption_handler()->SetKeystoreKeys( | |
| 1165 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1166 } | |
| 1167 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1168 | |
| 1169 { | |
| 1170 EXPECT_CALL(*observer(), | |
| 1171 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 1172 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1173 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1174 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 1175 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1176 WriteNode nigori_node(&trans); | |
| 1177 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1178 sync_pb::NigoriSpecifics nigori; | |
| 1179 nigori.set_keybag_is_frozen(true); | |
| 1180 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); | |
| 1181 nigori.set_keystore_migration_time(1); | |
| 1182 nigori.set_encrypt_everything(true); | |
| 1183 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1184 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1185 nigori_node.SetNigoriSpecifics(nigori); | |
| 1186 } | |
| 1187 // Run any tasks posted via AppplyNigoriUpdate. | |
| 1188 PumpLoop(); | |
| 1189 Mock::VerifyAndClearExpectations(observer()); | |
| 1190 | |
| 1191 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1192 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1193 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1194 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1195 | |
| 1196 EXPECT_CALL(*observer(), | |
| 1197 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1198 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1199 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1200 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1201 encryption_handler()->SetDecryptionPassphrase(kCurKey); | |
| 1202 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1203 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1204 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::CUSTOM_PASSPHRASE, | |
| 1205 kCurKey); | |
| 1206 | |
| 1207 // Check that the cryptographer still encrypts with the current key. | |
| 1208 sync_pb::EncryptedData current_encrypted; | |
| 1209 other_cryptographer.EncryptString("string", ¤t_encrypted); | |
| 1210 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); | |
| 1211 | |
| 1212 // Check that the cryptographer can decrypt keystore key based encryption. | |
| 1213 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1214 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1215 keystore_cryptographer.AddKey(keystore_key); | |
| 1216 sync_pb::EncryptedData keystore_encrypted; | |
| 1217 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1218 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1219 } | |
| 1220 | |
| 1221 // Test that if we have a migrated nigori with a custom passphrase, then receive | |
| 1222 // and old implicit passphrase nigori, we properly overwrite it with the current | |
| 1223 // state. | |
| 1224 TEST_F(SyncEncryptionHandlerImplTest, ReceiveUnmigratedNigoriAfterMigration) { | |
| 1225 const char kOldKey[] = "old"; | |
| 1226 const char kCurKey[] = "cur"; | |
| 1227 sync_pb::EncryptedData encrypted; | |
| 1228 KeyParams old_key = {"localhost", "dummy", kOldKey}; | |
| 1229 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1230 GetCryptographer()->AddKey(old_key); | |
| 1231 GetCryptographer()->AddKey(cur_key); | |
| 1232 | |
| 1233 // Build a migrated nigori with full encryption. | |
| 1234 const int64_t migration_time = 1; | |
| 1235 { | |
| 1236 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1237 WriteNode nigori_node(&trans); | |
| 1238 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1239 sync_pb::NigoriSpecifics nigori; | |
| 1240 GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag()); | |
| 1241 nigori.set_keybag_is_frozen(true); | |
| 1242 nigori.set_keystore_migration_time(1); | |
| 1243 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); | |
| 1244 nigori.set_encrypt_everything(true); | |
| 1245 nigori_node.SetNigoriSpecifics(nigori); | |
| 1246 } | |
| 1247 | |
| 1248 EXPECT_CALL(*observer(), | |
| 1249 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 1250 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1251 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)).Times(2); | |
| 1252 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1253 encryption_handler()->Init(); | |
| 1254 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1255 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1256 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1257 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1258 VerifyMigratedNigoriWithTimestamp(migration_time, | |
| 1259 PassphraseType::CUSTOM_PASSPHRASE, kCurKey); | |
| 1260 | |
| 1261 { | |
| 1262 EXPECT_CALL(*observer(), | |
| 1263 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1264 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1265 encryption_handler()->SetKeystoreKeys( | |
| 1266 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1267 } | |
| 1268 Mock::VerifyAndClearExpectations(observer()); | |
| 1269 | |
| 1270 // Now build an old unmigrated nigori node with old encrypted types. We should | |
| 1271 // properly overwrite it with the migrated + encrypt everything state. | |
| 1272 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1273 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 1274 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 1275 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 1276 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1277 { | |
| 1278 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1279 other_cryptographer.AddKey(old_key); | |
| 1280 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1281 WriteNode nigori_node(&trans); | |
| 1282 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1283 sync_pb::NigoriSpecifics nigori; | |
| 1284 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1285 nigori.set_keybag_is_frozen(false); | |
| 1286 nigori.set_encrypt_everything(false); | |
| 1287 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1288 nigori_node.SetNigoriSpecifics(nigori); | |
| 1289 } | |
| 1290 PumpLoop(); | |
| 1291 | |
| 1292 // Verify we're still migrated and have proper encryption state. | |
| 1293 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1294 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1295 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1296 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1297 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::CUSTOM_PASSPHRASE, | |
| 1298 kCurKey); | |
| 1299 | |
| 1300 // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_, | |
| 1301 // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked | |
| 1302 // during a previous instance) so get it from the Cryptographer. | |
| 1303 std::string passphrase_bootstrap_token; | |
| 1304 GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token); | |
| 1305 VerifyRestoreAfterCustomPassphrase( | |
| 1306 migration_time, kCurKey, passphrase_bootstrap_token, | |
| 1307 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 1308 } | |
| 1309 | |
| 1310 // Test that if we have a migrated nigori with a custom passphrase, then receive | |
| 1311 // a migrated nigori with a keystore passphrase, we properly overwrite it with | |
| 1312 // the current state. | |
| 1313 TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldMigratedNigori) { | |
| 1314 const char kOldKey[] = "old"; | |
| 1315 const char kCurKey[] = "cur"; | |
| 1316 sync_pb::EncryptedData encrypted; | |
| 1317 KeyParams old_key = {"localhost", "dummy", kOldKey}; | |
| 1318 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1319 GetCryptographer()->AddKey(old_key); | |
| 1320 GetCryptographer()->AddKey(cur_key); | |
| 1321 | |
| 1322 // Build a migrated nigori with full encryption. | |
| 1323 { | |
| 1324 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1325 WriteNode nigori_node(&trans); | |
| 1326 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1327 sync_pb::NigoriSpecifics nigori; | |
| 1328 GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag()); | |
| 1329 nigori.set_keybag_is_frozen(true); | |
| 1330 nigori.set_keystore_migration_time(1); | |
| 1331 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); | |
| 1332 nigori.set_encrypt_everything(true); | |
| 1333 nigori_node.SetNigoriSpecifics(nigori); | |
| 1334 } | |
| 1335 | |
| 1336 EXPECT_CALL(*observer(), | |
| 1337 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 1338 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1339 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)).Times(2); | |
| 1340 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1341 encryption_handler()->Init(); | |
| 1342 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1343 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1344 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1345 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1346 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::CUSTOM_PASSPHRASE, | |
| 1347 kCurKey); | |
| 1348 | |
| 1349 { | |
| 1350 EXPECT_CALL(*observer(), | |
| 1351 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1352 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1353 encryption_handler()->SetKeystoreKeys( | |
| 1354 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1355 } | |
| 1356 Mock::VerifyAndClearExpectations(observer()); | |
| 1357 | |
| 1358 // Now build an old keystore nigori node with old encrypted types. We should | |
| 1359 // properly overwrite it with the migrated + encrypt everything state. | |
| 1360 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1361 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 1362 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 1363 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 1364 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1365 const int64_t migration_time = 1; | |
| 1366 { | |
| 1367 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1368 WriteNode nigori_node(&trans); | |
| 1369 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1370 sync_pb::NigoriSpecifics nigori; | |
| 1371 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1372 other_cryptographer.AddKey(old_key); | |
| 1373 encryption_handler()->GetKeystoreDecryptor( | |
| 1374 other_cryptographer, kKeystoreKey, | |
| 1375 nigori.mutable_keystore_decryptor_token()); | |
| 1376 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1377 nigori.set_keybag_is_frozen(true); | |
| 1378 nigori.set_encrypt_everything(false); | |
| 1379 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1380 nigori.set_keystore_migration_time(migration_time); | |
| 1381 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1382 nigori_node.SetNigoriSpecifics(nigori); | |
| 1383 } | |
| 1384 PumpLoop(); | |
| 1385 | |
| 1386 // Verify we're still migrated and have proper encryption state. | |
| 1387 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1388 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1389 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1390 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1391 VerifyMigratedNigoriWithTimestamp(migration_time, | |
| 1392 PassphraseType::CUSTOM_PASSPHRASE, kCurKey); | |
| 1393 | |
| 1394 // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_, | |
| 1395 // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked | |
| 1396 // during a previous instance) so get it from the Cryptographer. | |
| 1397 std::string passphrase_bootstrap_token; | |
| 1398 GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token); | |
| 1399 VerifyRestoreAfterCustomPassphrase( | |
| 1400 migration_time, kCurKey, passphrase_bootstrap_token, | |
| 1401 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 1402 } | |
| 1403 | |
| 1404 // Test that if we receive the keystore key after receiving a migrated nigori | |
| 1405 // node, we properly use the keystore decryptor token to decrypt the keybag. | |
| 1406 TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreAfterReceivingMigratedNigori) { | |
| 1407 const char kCurKey[] = "cur"; | |
| 1408 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1409 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1410 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1411 other_cryptographer.AddKey(cur_key); | |
| 1412 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1413 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1414 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1415 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 1416 EXPECT_FALSE(GetCryptographer()->is_ready()); | |
| 1417 { | |
| 1418 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1419 EXPECT_NE(encryption_handler()->GetPassphraseType(trans.GetWrappedTrans()), | |
| 1420 PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1421 } | |
| 1422 // Now build a nigori node with the generated keystore decryptor token and | |
| 1423 // initialize the encryption handler with it. The cryptographer should be | |
| 1424 // initialized properly to decrypt both kCurKey and kKeystoreKey. | |
| 1425 { | |
| 1426 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1427 WriteNode nigori_node(&trans); | |
| 1428 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1429 sync_pb::NigoriSpecifics nigori; | |
| 1430 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1431 keystore_decryptor_token); | |
| 1432 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1433 nigori.set_keybag_is_frozen(true); | |
| 1434 nigori.set_keystore_migration_time(1); | |
| 1435 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1436 | |
| 1437 EXPECT_CALL(*observer(), OnPassphraseTypeChanged( | |
| 1438 PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1439 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1440 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1441 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1442 nigori_node.SetNigoriSpecifics(nigori); | |
| 1443 } | |
| 1444 // Run any tasks posted via AppplyNigoriUpdate. | |
| 1445 PumpLoop(); | |
| 1446 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1447 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1448 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1449 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1450 Mock::VerifyAndClearExpectations(observer()); | |
| 1451 | |
| 1452 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1453 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1454 EXPECT_CALL(*observer(), | |
| 1455 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1456 { | |
| 1457 EXPECT_CALL(*observer(), | |
| 1458 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1459 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1460 encryption_handler()->SetKeystoreKeys( | |
| 1461 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1462 } | |
| 1463 PumpLoop(); | |
| 1464 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1465 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1466 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1467 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1468 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::KEYSTORE_PASSPHRASE, | |
| 1469 kCurKey); | |
| 1470 | |
| 1471 // Check that the cryptographer still encrypts with the current key. | |
| 1472 sync_pb::EncryptedData current_encrypted; | |
| 1473 other_cryptographer.EncryptString("string", ¤t_encrypted); | |
| 1474 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); | |
| 1475 | |
| 1476 // Check that the cryptographer can decrypt keystore key based encryption. | |
| 1477 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1478 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1479 keystore_cryptographer.AddKey(keystore_key); | |
| 1480 sync_pb::EncryptedData keystore_encrypted; | |
| 1481 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1482 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1483 } | |
| 1484 | |
| 1485 // Test that after receiving a migrated nigori and decrypting it using the | |
| 1486 // keystore key, we can then switch to a custom passphrase. The nigori should | |
| 1487 // remain migrated and encrypt everything should be enabled. | |
| 1488 TEST_F(SyncEncryptionHandlerImplTest, SetCustomPassAfterMigration) { | |
| 1489 const char kOldKey[] = "old"; | |
| 1490 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1491 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1492 KeyParams cur_key = {"localhost", "dummy", kOldKey}; | |
| 1493 other_cryptographer.AddKey(cur_key); | |
| 1494 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1495 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1496 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1497 | |
| 1498 // Build a nigori node with the generated keystore decryptor token and | |
| 1499 // initialize the encryption handler with it. The cryptographer should be | |
| 1500 // initialized properly to decrypt both kOldKey and kKeystoreKey. | |
| 1501 const int64_t migration_time = 1; | |
| 1502 { | |
| 1503 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1504 WriteNode nigori_node(&trans); | |
| 1505 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1506 sync_pb::NigoriSpecifics nigori; | |
| 1507 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1508 keystore_decryptor_token); | |
| 1509 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1510 nigori.set_keybag_is_frozen(true); | |
| 1511 nigori.set_keystore_migration_time(migration_time); | |
| 1512 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1513 nigori_node.SetNigoriSpecifics(nigori); | |
| 1514 EXPECT_CALL(*observer(), | |
| 1515 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1516 encryption_handler()->SetKeystoreKeys( | |
| 1517 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1518 } | |
| 1519 | |
| 1520 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1521 EXPECT_CALL(*observer(), | |
| 1522 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1523 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1524 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 1525 EXPECT_CALL(*observer(), | |
| 1526 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1527 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1528 encryption_handler()->Init(); | |
| 1529 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1530 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1531 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1532 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1533 Mock::VerifyAndClearExpectations(observer()); | |
| 1534 | |
| 1535 const char kNewKey[] = "new_key"; | |
| 1536 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1537 EXPECT_CALL(*observer(), | |
| 1538 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 1539 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 1540 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 1541 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 1542 std::string captured_bootstrap_token; | |
| 1543 EXPECT_CALL(*observer(), | |
| 1544 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 1545 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 1546 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1547 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 1548 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(2); | |
| 1549 encryption_handler()->SetEncryptionPassphrase(kNewKey, true); | |
| 1550 Mock::VerifyAndClearExpectations(observer()); | |
| 1551 | |
| 1552 EXPECT_FALSE(captured_bootstrap_token.empty()); | |
| 1553 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1554 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1555 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1556 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1557 EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); | |
| 1558 VerifyMigratedNigoriWithTimestamp(migration_time, | |
| 1559 PassphraseType::CUSTOM_PASSPHRASE, kNewKey); | |
| 1560 | |
| 1561 // Check that the cryptographer can decrypt the old key. | |
| 1562 sync_pb::EncryptedData old_encrypted; | |
| 1563 other_cryptographer.EncryptString("string", &old_encrypted); | |
| 1564 EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted)); | |
| 1565 | |
| 1566 // Check that the cryptographer can decrypt keystore key based encryption. | |
| 1567 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1568 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1569 keystore_cryptographer.AddKey(keystore_key); | |
| 1570 sync_pb::EncryptedData keystore_encrypted; | |
| 1571 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1572 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1573 | |
| 1574 // Check the the cryptographer is encrypting with the new key. | |
| 1575 KeyParams new_key = {"localhost", "dummy", kNewKey}; | |
| 1576 Cryptographer new_cryptographer(GetCryptographer()->encryptor()); | |
| 1577 new_cryptographer.AddKey(new_key); | |
| 1578 sync_pb::EncryptedData new_encrypted; | |
| 1579 new_cryptographer.EncryptString("string", &new_encrypted); | |
| 1580 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted)); | |
| 1581 | |
| 1582 // Now verify that we can restore the current state using the captured | |
| 1583 // bootstrap token and nigori state. | |
| 1584 VerifyRestoreAfterCustomPassphrase( | |
| 1585 migration_time, kNewKey, captured_bootstrap_token, captured_nigori_state, | |
| 1586 PassphraseType::CUSTOM_PASSPHRASE); | |
| 1587 } | |
| 1588 | |
| 1589 // Test that if a client without a keystore key (e.g. one without keystore | |
| 1590 // encryption enabled) receives a migrated nigori and then attempts to set a | |
| 1591 // custom passphrase, it also enables encrypt everything. The nigori node | |
| 1592 // should remain migrated. | |
| 1593 TEST_F(SyncEncryptionHandlerImplTest, | |
| 1594 SetCustomPassAfterMigrationNoKeystoreKey) { | |
| 1595 const char kOldKey[] = "old"; | |
| 1596 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1597 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1598 KeyParams cur_key = {"localhost", "dummy", kOldKey}; | |
| 1599 other_cryptographer.AddKey(cur_key); | |
| 1600 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1601 other_cryptographer.AddNonDefaultKey(keystore_key); | |
| 1602 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1603 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1604 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1605 | |
| 1606 // Build a nigori node with the generated keystore decryptor token and | |
| 1607 // initialize the encryption handler with it. The cryptographer will have | |
| 1608 // pending keys until we provide the decryption passphrase. | |
| 1609 const int64_t migration_time = 1; | |
| 1610 { | |
| 1611 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1612 WriteNode nigori_node(&trans); | |
| 1613 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1614 sync_pb::NigoriSpecifics nigori; | |
| 1615 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1616 keystore_decryptor_token); | |
| 1617 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1618 nigori.set_keybag_is_frozen(true); | |
| 1619 nigori.set_keystore_migration_time(migration_time); | |
| 1620 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1621 nigori_node.SetNigoriSpecifics(nigori); | |
| 1622 } | |
| 1623 | |
| 1624 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1625 EXPECT_CALL(*observer(), | |
| 1626 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1627 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1628 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 1629 encryption_handler()->Init(); | |
| 1630 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1631 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1632 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1633 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1634 Mock::VerifyAndClearExpectations(observer()); | |
| 1635 | |
| 1636 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1637 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1638 EXPECT_CALL(*observer(), | |
| 1639 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1640 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1641 encryption_handler()->SetDecryptionPassphrase(kOldKey); | |
| 1642 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1643 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1644 Mock::VerifyAndClearExpectations(observer()); | |
| 1645 | |
| 1646 const char kNewKey[] = "new_key"; | |
| 1647 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1648 EXPECT_CALL(*observer(), | |
| 1649 OnPassphraseTypeChanged(PassphraseType::CUSTOM_PASSPHRASE, _)); | |
| 1650 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 1651 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 1652 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 1653 std::string captured_bootstrap_token; | |
| 1654 EXPECT_CALL(*observer(), | |
| 1655 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 1656 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 1657 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1658 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 1659 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(2); | |
| 1660 encryption_handler()->SetEncryptionPassphrase(kNewKey, true); | |
| 1661 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1662 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1663 VerifyPassphraseType(PassphraseType::CUSTOM_PASSPHRASE); | |
| 1664 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1665 EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); | |
| 1666 VerifyMigratedNigoriWithTimestamp(migration_time, | |
| 1667 PassphraseType::CUSTOM_PASSPHRASE, kNewKey); | |
| 1668 | |
| 1669 // Check that the cryptographer can decrypt the old key. | |
| 1670 sync_pb::EncryptedData old_encrypted; | |
| 1671 other_cryptographer.EncryptString("string", &old_encrypted); | |
| 1672 EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted)); | |
| 1673 | |
| 1674 // Check that the cryptographer can still decrypt keystore key based | |
| 1675 // encryption (should have been extracted from the encryption keybag). | |
| 1676 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1677 keystore_cryptographer.AddKey(keystore_key); | |
| 1678 sync_pb::EncryptedData keystore_encrypted; | |
| 1679 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1680 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1681 | |
| 1682 // Check the the cryptographer is encrypting with the new key. | |
| 1683 KeyParams new_key = {"localhost", "dummy", kNewKey}; | |
| 1684 Cryptographer new_cryptographer(GetCryptographer()->encryptor()); | |
| 1685 new_cryptographer.AddKey(new_key); | |
| 1686 sync_pb::EncryptedData new_encrypted; | |
| 1687 new_cryptographer.EncryptString("string", &new_encrypted); | |
| 1688 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted)); | |
| 1689 | |
| 1690 // Now verify that we can restore the current state using the captured | |
| 1691 // bootstrap token and nigori state. | |
| 1692 VerifyRestoreAfterCustomPassphrase( | |
| 1693 migration_time, kNewKey, captured_bootstrap_token, captured_nigori_state, | |
| 1694 PassphraseType::CUSTOM_PASSPHRASE); | |
| 1695 } | |
| 1696 | |
| 1697 // Test that if a client without a keystore key (e.g. one without keystore | |
| 1698 // encryption enabled) receives a migrated nigori and then attempts to set a | |
| 1699 // new implicit passphrase, we do not modify the nigori node (the implicit | |
| 1700 // passphrase is dropped). | |
| 1701 TEST_F(SyncEncryptionHandlerImplTest, | |
| 1702 SetImplicitPassAfterMigrationNoKeystoreKey) { | |
| 1703 const char kOldKey[] = "old"; | |
| 1704 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1705 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1706 KeyParams cur_key = {"localhost", "dummy", kOldKey}; | |
| 1707 other_cryptographer.AddKey(cur_key); | |
| 1708 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1709 other_cryptographer.AddNonDefaultKey(keystore_key); | |
| 1710 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1711 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1712 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1713 | |
| 1714 // Build a nigori node with the generated keystore decryptor token and | |
| 1715 // initialize the encryption handler with it. The cryptographer will have | |
| 1716 // pending keys until we provide the decryption passphrase. | |
| 1717 { | |
| 1718 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1719 WriteNode nigori_node(&trans); | |
| 1720 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1721 sync_pb::NigoriSpecifics nigori; | |
| 1722 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1723 keystore_decryptor_token); | |
| 1724 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1725 nigori.set_keybag_is_frozen(true); | |
| 1726 nigori.set_keystore_migration_time(1); | |
| 1727 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1728 nigori_node.SetNigoriSpecifics(nigori); | |
| 1729 } | |
| 1730 | |
| 1731 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1732 EXPECT_CALL(*observer(), | |
| 1733 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1734 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1735 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 1736 encryption_handler()->Init(); | |
| 1737 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1738 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1739 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1740 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1741 Mock::VerifyAndClearExpectations(observer()); | |
| 1742 | |
| 1743 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1744 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1745 EXPECT_CALL(*observer(), | |
| 1746 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1747 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1748 encryption_handler()->SetDecryptionPassphrase(kOldKey); | |
| 1749 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1750 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1751 Mock::VerifyAndClearExpectations(observer()); | |
| 1752 | |
| 1753 // Should get dropped on the floor silently. | |
| 1754 const char kNewKey[] = "new_key"; | |
| 1755 encryption_handler()->SetEncryptionPassphrase(kNewKey, false); | |
| 1756 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1757 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1758 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1759 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1760 VerifyMigratedNigoriWithTimestamp(1, PassphraseType::KEYSTORE_PASSPHRASE, | |
| 1761 kOldKey); | |
| 1762 | |
| 1763 // Check that the cryptographer can decrypt the old key. | |
| 1764 sync_pb::EncryptedData old_encrypted; | |
| 1765 other_cryptographer.EncryptString("string", &old_encrypted); | |
| 1766 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(old_encrypted)); | |
| 1767 | |
| 1768 // Check that the cryptographer can still decrypt keystore key based | |
| 1769 // encryption (due to extracting the keystore key from the encryption keybag). | |
| 1770 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1771 keystore_cryptographer.AddKey(keystore_key); | |
| 1772 sync_pb::EncryptedData keystore_encrypted; | |
| 1773 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1774 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1775 | |
| 1776 // Check the the cryptographer does not have the new key. | |
| 1777 KeyParams new_key = {"localhost", "dummy", kNewKey}; | |
| 1778 Cryptographer new_cryptographer(GetCryptographer()->encryptor()); | |
| 1779 new_cryptographer.AddKey(new_key); | |
| 1780 sync_pb::EncryptedData new_encrypted; | |
| 1781 new_cryptographer.EncryptString("string", &new_encrypted); | |
| 1782 EXPECT_FALSE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted)); | |
| 1783 } | |
| 1784 | |
| 1785 // Test that if a client without a keystore key (e.g. one without keystore | |
| 1786 // encryption enabled) receives a migrated nigori in keystore passphrase state | |
| 1787 // and then attempts to enable encrypt everything, we switch to a custom | |
| 1788 // passphrase. The nigori should remain migrated. | |
| 1789 TEST_F(SyncEncryptionHandlerImplTest, | |
| 1790 MigrateOnEncryptEverythingKeystorePassphrase) { | |
| 1791 const char kCurKey[] = "cur"; | |
| 1792 sync_pb::EncryptedData keystore_decryptor_token; | |
| 1793 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1794 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1795 other_cryptographer.AddKey(cur_key); | |
| 1796 KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey}; | |
| 1797 other_cryptographer.AddNonDefaultKey(keystore_key); | |
| 1798 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1799 EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( | |
| 1800 other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); | |
| 1801 | |
| 1802 // Build a nigori node with the generated keystore decryptor token and | |
| 1803 // initialize the encryption handler with it. The cryptographer will have | |
| 1804 // pending keys until we provide the decryption passphrase. | |
| 1805 const int64_t migration_time = 1; | |
| 1806 { | |
| 1807 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1808 WriteNode nigori_node(&trans); | |
| 1809 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1810 sync_pb::NigoriSpecifics nigori; | |
| 1811 nigori.mutable_keystore_decryptor_token()->CopyFrom( | |
| 1812 keystore_decryptor_token); | |
| 1813 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1814 nigori.set_keybag_is_frozen(true); | |
| 1815 nigori.set_keystore_migration_time(migration_time); | |
| 1816 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1817 nigori_node.SetNigoriSpecifics(nigori); | |
| 1818 } | |
| 1819 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 1820 EXPECT_CALL(*observer(), | |
| 1821 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1822 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1823 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 1824 encryption_handler()->Init(); | |
| 1825 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1826 EXPECT_TRUE(GetCryptographer()->has_pending_keys()); | |
| 1827 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1828 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1829 Mock::VerifyAndClearExpectations(observer()); | |
| 1830 | |
| 1831 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1832 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1833 std::string captured_bootstrap_token; | |
| 1834 EXPECT_CALL(*observer(), | |
| 1835 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 1836 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 1837 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1838 encryption_handler()->SetDecryptionPassphrase(kCurKey); | |
| 1839 Mock::VerifyAndClearExpectations(observer()); | |
| 1840 | |
| 1841 EXPECT_CALL(*observer(), OnPassphraseTypeChanged( | |
| 1842 PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, _)); | |
| 1843 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1844 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 1845 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 1846 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 1847 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 1848 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1849 encryption_handler()->EnableEncryptEverything(); | |
| 1850 Mock::VerifyAndClearExpectations(observer()); | |
| 1851 | |
| 1852 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1853 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1854 VerifyPassphraseType(PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 1855 EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1856 VerifyMigratedNigoriWithTimestamp( | |
| 1857 1, PassphraseType::FROZEN_IMPLICIT_PASSPHRASE, kCurKey); | |
| 1858 | |
| 1859 // Check that the cryptographer is encrypting using the frozen current key. | |
| 1860 sync_pb::EncryptedData current_encrypted; | |
| 1861 other_cryptographer.EncryptString("string", ¤t_encrypted); | |
| 1862 EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); | |
| 1863 | |
| 1864 // Check that the cryptographer can still decrypt keystore key based | |
| 1865 // encryption (due to extracting the keystore key from the encryption keybag). | |
| 1866 Cryptographer keystore_cryptographer(GetCryptographer()->encryptor()); | |
| 1867 keystore_cryptographer.AddKey(keystore_key); | |
| 1868 sync_pb::EncryptedData keystore_encrypted; | |
| 1869 keystore_cryptographer.EncryptString("string", &keystore_encrypted); | |
| 1870 EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted)); | |
| 1871 | |
| 1872 VerifyRestoreAfterCustomPassphrase( | |
| 1873 migration_time, kCurKey, captured_bootstrap_token, captured_nigori_state, | |
| 1874 PassphraseType::FROZEN_IMPLICIT_PASSPHRASE); | |
| 1875 } | |
| 1876 | |
| 1877 // If we receive a nigori migrated and with a KEYSTORE_PASSPHRASE type, but | |
| 1878 // using an old default key (i.e. old GAIA password), we should overwrite the | |
| 1879 // nigori, updating the keybag and keystore decryptor. | |
| 1880 TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriWithOldPassphrase) { | |
| 1881 const char kOldKey[] = "old"; | |
| 1882 const char kCurKey[] = "cur"; | |
| 1883 sync_pb::EncryptedData encrypted; | |
| 1884 KeyParams old_key = {"localhost", "dummy", kOldKey}; | |
| 1885 KeyParams cur_key = {"localhost", "dummy", kCurKey}; | |
| 1886 GetCryptographer()->AddKey(old_key); | |
| 1887 GetCryptographer()->AddKey(cur_key); | |
| 1888 | |
| 1889 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1890 other_cryptographer.AddKey(old_key); | |
| 1891 EXPECT_TRUE(other_cryptographer.is_ready()); | |
| 1892 | |
| 1893 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1894 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 1895 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1896 encryption_handler()->Init(); | |
| 1897 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1898 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1899 | |
| 1900 { | |
| 1901 EXPECT_CALL(*observer(), | |
| 1902 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1903 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1904 encryption_handler()->SetKeystoreKeys( | |
| 1905 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 1906 } | |
| 1907 EXPECT_CALL(*observer(), | |
| 1908 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 1909 PumpLoop(); | |
| 1910 Mock::VerifyAndClearExpectations(observer()); | |
| 1911 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1912 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1913 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kCurKey); | |
| 1914 | |
| 1915 // Now build an old keystore passphrase nigori node. | |
| 1916 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1917 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1918 { | |
| 1919 WriteTransaction trans(FROM_HERE, user_share()); | |
| 1920 WriteNode nigori_node(&trans); | |
| 1921 ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); | |
| 1922 sync_pb::NigoriSpecifics nigori; | |
| 1923 Cryptographer other_cryptographer(GetCryptographer()->encryptor()); | |
| 1924 other_cryptographer.AddKey(old_key); | |
| 1925 encryption_handler()->GetKeystoreDecryptor( | |
| 1926 other_cryptographer, kKeystoreKey, | |
| 1927 nigori.mutable_keystore_decryptor_token()); | |
| 1928 other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); | |
| 1929 nigori.set_keybag_is_frozen(true); | |
| 1930 nigori.set_encrypt_everything(false); | |
| 1931 nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); | |
| 1932 nigori.set_keystore_migration_time(1); | |
| 1933 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 1934 nigori_node.SetNigoriSpecifics(nigori); | |
| 1935 } | |
| 1936 PumpLoop(); | |
| 1937 | |
| 1938 // Verify we're still migrated and have proper encryption state. | |
| 1939 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1940 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1941 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1942 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1943 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kCurKey); | |
| 1944 } | |
| 1945 | |
| 1946 // Trigger a key rotation upon receiving new keys if we already had a keystore | |
| 1947 // migrated nigori with the gaia key as the default (still in backwards | |
| 1948 // compatible mode). | |
| 1949 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefault) { | |
| 1950 // Destroy the existing nigori node so we init without a nigori node. | |
| 1951 TearDown(); | |
| 1952 test_user_share_.SetUp(); | |
| 1953 SetUpEncryption(); | |
| 1954 | |
| 1955 const char kOldGaiaKey[] = "old_gaia_key"; | |
| 1956 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 1957 std::string old_keystore_key; | |
| 1958 base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key); | |
| 1959 { | |
| 1960 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1961 EXPECT_CALL(*observer(), | |
| 1962 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1963 encryption_handler()->SetKeystoreKeys( | |
| 1964 BuildEncryptionKeyProto(kRawOldKeystoreKey), trans.GetWrappedTrans()); | |
| 1965 } | |
| 1966 PumpLoop(); | |
| 1967 Mock::VerifyAndClearExpectations(observer()); | |
| 1968 | |
| 1969 // Then init the nigori node with a backwards compatible set of keys. | |
| 1970 CreateRootForType(NIGORI); | |
| 1971 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 1972 InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key); | |
| 1973 | |
| 1974 // Now set some new keystore keys. | |
| 1975 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 1976 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 1977 { | |
| 1978 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 1979 keys.Add()->assign(kRawOldKeystoreKey); | |
| 1980 keys.Add()->assign(kRawKeystoreKey); | |
| 1981 EXPECT_CALL(*observer(), | |
| 1982 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 1983 ReadTransaction trans(FROM_HERE, user_share()); | |
| 1984 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 1985 } | |
| 1986 // Pump for any posted tasks. | |
| 1987 PumpLoop(); | |
| 1988 Mock::VerifyAndClearExpectations(observer()); | |
| 1989 | |
| 1990 // Verify we're still migrated and have proper encryption state. We should | |
| 1991 // have rotated the keybag so that it's now encrypted with the newest keystore | |
| 1992 // key (instead of the old gaia key). | |
| 1993 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 1994 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 1995 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 1996 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 1997 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 1998 } | |
| 1999 | |
| 2000 // Trigger a key rotation upon receiving new keys if we already had a keystore | |
| 2001 // migrated nigori with the keystore key as the default. | |
| 2002 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysKeystoreDefault) { | |
| 2003 // Destroy the existing nigori node so we init without a nigori node. | |
| 2004 TearDown(); | |
| 2005 test_user_share_.SetUp(); | |
| 2006 SetUpEncryption(); | |
| 2007 | |
| 2008 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2009 std::string old_keystore_key; | |
| 2010 base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key); | |
| 2011 { | |
| 2012 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2013 EXPECT_CALL(*observer(), | |
| 2014 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2015 encryption_handler()->SetKeystoreKeys( | |
| 2016 BuildEncryptionKeyProto(kRawOldKeystoreKey), trans.GetWrappedTrans()); | |
| 2017 } | |
| 2018 PumpLoop(); | |
| 2019 Mock::VerifyAndClearExpectations(observer()); | |
| 2020 | |
| 2021 // Then init the nigori node with a non-backwards compatible set of keys. | |
| 2022 CreateRootForType(NIGORI); | |
| 2023 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 2024 InitKeystoreMigratedNigori(1, old_keystore_key, old_keystore_key); | |
| 2025 | |
| 2026 // Now set some new keystore keys. | |
| 2027 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2028 EXPECT_CALL(*observer(), OnEncryptionComplete()); | |
| 2029 { | |
| 2030 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2031 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2032 keys.Add()->assign(kRawKeystoreKey); | |
| 2033 EXPECT_CALL(*observer(), | |
| 2034 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2035 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2036 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2037 } | |
| 2038 // Pump for any posted tasks. | |
| 2039 PumpLoop(); | |
| 2040 Mock::VerifyAndClearExpectations(observer()); | |
| 2041 | |
| 2042 // Verify we're still migrated and have proper encryption state. We should | |
| 2043 // have rotated the keybag so that it's now encrypted with the newest keystore | |
| 2044 // key (instead of the old gaia key). | |
| 2045 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 2046 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 2047 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 2048 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 2049 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 2050 } | |
| 2051 | |
| 2052 // Trigger a key rotation upon when a pending gaia passphrase is resolved. | |
| 2053 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysAfterPendingGaiaResolved) { | |
| 2054 const char kOldGaiaKey[] = "old_gaia_key"; | |
| 2055 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2056 | |
| 2057 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 2058 InitUnmigratedNigori(kOldGaiaKey, PassphraseType::IMPLICIT_PASSPHRASE); | |
| 2059 | |
| 2060 { | |
| 2061 // Pass multiple keystore keys, signaling a rotation has happened. | |
| 2062 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2063 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2064 keys.Add()->assign(kRawKeystoreKey); | |
| 2065 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2066 EXPECT_CALL(*observer(), | |
| 2067 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2068 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2069 } | |
| 2070 PumpLoop(); | |
| 2071 Mock::VerifyAndClearExpectations(observer()); | |
| 2072 | |
| 2073 // Resolve the pending keys. This should trigger the key rotation. | |
| 2074 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2075 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 2076 EXPECT_CALL(*observer(), | |
| 2077 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 2078 EXPECT_CALL(*observer(), | |
| 2079 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 2080 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(AtLeast(1)); | |
| 2081 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 2082 encryption_handler()->SetDecryptionPassphrase(kOldGaiaKey); | |
| 2083 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 2084 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 2085 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 2086 } | |
| 2087 | |
| 2088 // When signing in for the first time, make sure we can rotate keys if we | |
| 2089 // already have a keystore migrated nigori. | |
| 2090 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefaultOnInit) { | |
| 2091 // Destroy the existing nigori node so we init without a nigori node. | |
| 2092 TearDown(); | |
| 2093 test_user_share_.SetUp(); | |
| 2094 SetUpEncryption(); | |
| 2095 | |
| 2096 const char kOldGaiaKey[] = "old_gaia_key"; | |
| 2097 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2098 std::string old_keystore_key; | |
| 2099 base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key); | |
| 2100 | |
| 2101 // Set two keys, signaling that a rotation has been performed. No nigori | |
| 2102 // node is present yet, so we can't rotate. | |
| 2103 { | |
| 2104 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2105 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2106 keys.Add()->assign(kRawKeystoreKey); | |
| 2107 EXPECT_CALL(*observer(), | |
| 2108 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2109 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2110 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2111 } | |
| 2112 | |
| 2113 // Then init the nigori node with an old set of keys. | |
| 2114 CreateRootForType(NIGORI); | |
| 2115 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 2116 InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key); | |
| 2117 PumpLoop(); | |
| 2118 Mock::VerifyAndClearExpectations(observer()); | |
| 2119 | |
| 2120 // Verify we're still migrated and have proper encryption state. We should | |
| 2121 // have rotated the keybag so that it's now encrypted with the newest keystore | |
| 2122 // key (instead of the old gaia key). | |
| 2123 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 2124 EXPECT_TRUE(GetCryptographer()->is_ready()); | |
| 2125 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 2126 EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); | |
| 2127 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 2128 } | |
| 2129 | |
| 2130 // Trigger a key rotation when a migrated nigori (with an old keystore key) is | |
| 2131 // applied. | |
| 2132 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysWhenMigratedNigoriArrives) { | |
| 2133 const char kOldGaiaKey[] = "old_gaia_key"; | |
| 2134 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2135 std::string old_keystore_key; | |
| 2136 base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key); | |
| 2137 | |
| 2138 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 2139 InitUnmigratedNigori(kOldGaiaKey, PassphraseType::IMPLICIT_PASSPHRASE); | |
| 2140 | |
| 2141 { | |
| 2142 // Pass multiple keystore keys, signaling a rotation has happened. | |
| 2143 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2144 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2145 keys.Add()->assign(kRawKeystoreKey); | |
| 2146 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2147 EXPECT_CALL(*observer(), | |
| 2148 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2149 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2150 } | |
| 2151 PumpLoop(); | |
| 2152 Mock::VerifyAndClearExpectations(observer()); | |
| 2153 | |
| 2154 // Now simulate downloading a nigori node that was migrated before the | |
| 2155 // keys were rotated, and hence still encrypt with the old gaia key. | |
| 2156 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2157 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 2158 EXPECT_CALL(*observer(), | |
| 2159 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 2160 EXPECT_CALL(*observer(), | |
| 2161 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 2162 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(AtLeast(1)); | |
| 2163 { | |
| 2164 sync_pb::NigoriSpecifics nigori = BuildMigratedNigori( | |
| 2165 PassphraseType::KEYSTORE_PASSPHRASE, 1, kOldGaiaKey, old_keystore_key); | |
| 2166 // Update the encryption handler. | |
| 2167 WriteTransaction trans(FROM_HERE, user_share()); | |
| 2168 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 2169 } | |
| 2170 EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); | |
| 2171 PumpLoop(); | |
| 2172 | |
| 2173 EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); | |
| 2174 VerifyPassphraseType(PassphraseType::KEYSTORE_PASSPHRASE); | |
| 2175 VerifyMigratedNigori(PassphraseType::KEYSTORE_PASSPHRASE, kKeystoreKey); | |
| 2176 } | |
| 2177 | |
| 2178 // Verify that performing a migration while having more than one keystore key | |
| 2179 // preserves a custom passphrase. | |
| 2180 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysUnmigratedCustomPassphrase) { | |
| 2181 const char kCustomPass[] = "custom_passphrase"; | |
| 2182 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2183 | |
| 2184 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 2185 InitUnmigratedNigori(kCustomPass, PassphraseType::CUSTOM_PASSPHRASE); | |
| 2186 | |
| 2187 { | |
| 2188 // Pass multiple keystore keys, signaling a rotation has happened. | |
| 2189 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2190 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2191 keys.Add()->assign(kRawKeystoreKey); | |
| 2192 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2193 EXPECT_CALL(*observer(), | |
| 2194 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2195 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2196 } | |
| 2197 PumpLoop(); | |
| 2198 Mock::VerifyAndClearExpectations(observer()); | |
| 2199 | |
| 2200 // Pass the decryption passphrase. This will also trigger the migration, | |
| 2201 // but should not overwrite the default key. | |
| 2202 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2203 EXPECT_CALL(*observer(), OnPassphraseAccepted()); | |
| 2204 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true)); | |
| 2205 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 2206 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 2207 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 2208 EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(AnyNumber()); | |
| 2209 std::string captured_bootstrap_token; | |
| 2210 EXPECT_CALL(*observer(), | |
| 2211 OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) | |
| 2212 .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token)); | |
| 2213 encryption_handler()->SetDecryptionPassphrase(kCustomPass); | |
| 2214 Mock::VerifyAndClearExpectations(observer()); | |
| 2215 | |
| 2216 VerifyMigratedNigori(PassphraseType::CUSTOM_PASSPHRASE, kCustomPass); | |
| 2217 | |
| 2218 const base::Time migration_time = encryption_handler()->migration_time(); | |
| 2219 VerifyRestoreAfterCustomPassphrase( | |
| 2220 TimeToProtoTime(migration_time), kCustomPass, captured_bootstrap_token, | |
| 2221 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 2222 } | |
| 2223 | |
| 2224 // Verify that a key rotation done after we've migrated a custom passphrase | |
| 2225 // nigori node preserves the custom passphrase. | |
| 2226 TEST_F(SyncEncryptionHandlerImplTest, RotateKeysMigratedCustomPassphrase) { | |
| 2227 const char kCustomPass[] = "custom_passphrase"; | |
| 2228 const char kRawOldKeystoreKey[] = "old_keystore_key"; | |
| 2229 | |
| 2230 KeyParams custom_key = {"localhost", "dummy", kCustomPass}; | |
| 2231 GetCryptographer()->AddKey(custom_key); | |
| 2232 | |
| 2233 const int64_t migration_time = 1; | |
| 2234 InitCustomPassMigratedNigori(migration_time, kCustomPass); | |
| 2235 VerifyMigratedNigoriWithTimestamp( | |
| 2236 migration_time, PassphraseType::CUSTOM_PASSPHRASE, kCustomPass); | |
| 2237 | |
| 2238 SyncEncryptionHandler::NigoriState captured_nigori_state; | |
| 2239 { | |
| 2240 // Pass multiple keystore keys, signaling a rotation has happened. | |
| 2241 google::protobuf::RepeatedPtrField<google::protobuf::string> keys; | |
| 2242 keys.Add()->assign(kRawOldKeystoreKey); | |
| 2243 keys.Add()->assign(kRawKeystoreKey); | |
| 2244 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2245 EXPECT_CALL(*observer(), | |
| 2246 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2247 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2248 EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_)) | |
| 2249 .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); | |
| 2250 encryption_handler()->SetKeystoreKeys(keys, trans.GetWrappedTrans()); | |
| 2251 } | |
| 2252 PumpLoop(); | |
| 2253 Mock::VerifyAndClearExpectations(observer()); | |
| 2254 | |
| 2255 VerifyMigratedNigoriWithTimestamp( | |
| 2256 migration_time, PassphraseType::CUSTOM_PASSPHRASE, kCustomPass); | |
| 2257 | |
| 2258 // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_, | |
| 2259 // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked | |
| 2260 // during a previous instance) so get it from the Cryptographer. | |
| 2261 std::string passphrase_bootstrap_token; | |
| 2262 GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token); | |
| 2263 VerifyRestoreAfterCustomPassphrase( | |
| 2264 migration_time, kCustomPass, passphrase_bootstrap_token, | |
| 2265 captured_nigori_state, PassphraseType::CUSTOM_PASSPHRASE); | |
| 2266 } | |
| 2267 | |
| 2268 // Verify that the client can gracefully handle a nigori node that is missing | |
| 2269 // the keystore migration time field. | |
| 2270 TEST_F(SyncEncryptionHandlerImplTest, MissingKeystoreMigrationTime) { | |
| 2271 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2272 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 2273 EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); | |
| 2274 encryption_handler()->Init(); | |
| 2275 Mock::VerifyAndClearExpectations(observer()); | |
| 2276 | |
| 2277 // Now simulate downloading a nigori node that that is missing the keystore | |
| 2278 // migration time. It should be interpreted properly, and the passphrase type | |
| 2279 // should switch to keystore passphrase. | |
| 2280 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2281 EXPECT_CALL(*observer(), OnPassphraseRequired(_, _)); | |
| 2282 EXPECT_CALL(*observer(), | |
| 2283 OnPassphraseTypeChanged(PassphraseType::KEYSTORE_PASSPHRASE, _)); | |
| 2284 { | |
| 2285 sync_pb::NigoriSpecifics nigori = BuildMigratedNigori( | |
| 2286 PassphraseType::KEYSTORE_PASSPHRASE, 1, kKeystoreKey, kKeystoreKey); | |
| 2287 nigori.clear_keystore_migration_time(); | |
| 2288 // Update the encryption handler. | |
| 2289 WriteTransaction trans(FROM_HERE, user_share()); | |
| 2290 encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans()); | |
| 2291 } | |
| 2292 Mock::VerifyAndClearExpectations(observer()); | |
| 2293 | |
| 2294 // Now provide the keystore key to fully initialize the cryptographer. | |
| 2295 EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); | |
| 2296 EXPECT_CALL(*observer(), | |
| 2297 OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN)); | |
| 2298 { | |
| 2299 ReadTransaction trans(FROM_HERE, user_share()); | |
| 2300 encryption_handler()->SetKeystoreKeys( | |
| 2301 BuildEncryptionKeyProto(kRawKeystoreKey), trans.GetWrappedTrans()); | |
| 2302 } | |
| 2303 } | |
| 2304 | |
| 2305 } // namespace syncer | |
| OLD | NEW |