// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sync/internal_api/sync_encryption_handler_impl.h"

#include <stdint.h>

#include <string>

#include "base/base64.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/tracked_objects.h"
#include "sync/internal_api/public/base/model_type_test_util.h"
#include "sync/internal_api/public/read_node.h"
#include "sync/internal_api/public/read_transaction.h"
#include "sync/internal_api/public/test/test_user_share.h"
#include "sync/internal_api/public/write_node.h"
#include "sync/internal_api/public/write_transaction.h"
#include "sync/protocol/nigori_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/syncable_write_transaction.h"
#include "sync/test/engine/test_id_factory.h"
#include "sync/test/fake_encryptor.h"
#include "sync/util/cryptographer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {

namespace {

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Mock;
using ::testing::SaveArg;
using ::testing::StrictMock;

// The raw keystore key the server sends.
static const char kRawKeystoreKey[] = "keystore_key";
// Base64 encoded version of |kRawKeystoreKey|.
static const char kKeystoreKey[] = "a2V5c3RvcmVfa2V5";

class SyncEncryptionHandlerObserverMock
    : public SyncEncryptionHandler::Observer {
 public:
  MOCK_METHOD2(OnPassphraseRequired,
               void(PassphraseRequiredReason,
                    const sync_pb::EncryptedData&));  // NOLINT
  MOCK_METHOD0(OnPassphraseAccepted, void());  // NOLINT
  MOCK_METHOD2(OnBootstrapTokenUpdated,
               void(const std::string&, BootstrapTokenType type));  // NOLINT
  MOCK_METHOD2(OnEncryptedTypesChanged,
               void(ModelTypeSet, bool));  // NOLINT
  MOCK_METHOD0(OnEncryptionComplete, void());  // NOLINT
  MOCK_METHOD1(OnCryptographerStateChanged, void(Cryptographer*));  // NOLINT
  MOCK_METHOD2(OnPassphraseTypeChanged, void(PassphraseType,
                                             base::Time));  // NOLINT
  MOCK_METHOD1(OnLocalSetPassphraseEncryption,
               void(const SyncEncryptionHandler::NigoriState&));  // NOLINT
};

google::protobuf::RepeatedPtrField<google::protobuf::string>
BuildEncryptionKeyProto(const std::string& encryption_key) {
  google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
  keys.Add()->assign(encryption_key);
  return keys;
}

}  // namespace

class SyncEncryptionHandlerImplTest : public ::testing::Test {
 public:
  SyncEncryptionHandlerImplTest() {}
  virtual ~SyncEncryptionHandlerImplTest() {}

  virtual void SetUp() {
    test_user_share_.SetUp();
    SetUpEncryption();
    CreateRootForType(NIGORI);
  }

  virtual void TearDown() {
    PumpLoop();
    test_user_share_.TearDown();
  }

 protected:
  void SetUpEncryption() {
    SetUpEncryptionWithKeyForBootstrapping(std::string());
  }

  void SetUpEncryptionWithKeyForBootstrapping(
      const std::string& key_for_bootstrapping) {
    encryption_handler_.reset(new SyncEncryptionHandlerImpl(
        user_share(), &encryptor_, key_for_bootstrapping,
        std::string() /* keystore key for bootstrapping */,
        PASSPHRASE_TRANSITION_DO_NOT_CLEAR_DATA));
    encryption_handler_->AddObserver(&observer_);
  }

  void CreateRootForType(ModelType model_type) {
    syncer::syncable::Directory* directory = user_share()->directory.get();

    std::string tag_name = ModelTypeToRootTag(model_type);

    syncable::WriteTransaction wtrans(FROM_HERE, syncable::UNITTEST, directory);
    syncable::MutableEntry node(&wtrans,
                                syncable::CREATE,
                                model_type,
                                wtrans.root_id(),
                                tag_name);
    node.PutUniqueServerTag(tag_name);
    node.PutIsDir(true);
    node.PutServerIsDir(false);
    node.PutIsUnsynced(false);
    node.PutIsUnappliedUpdate(false);
    node.PutServerVersion(20);
    node.PutBaseVersion(20);
    node.PutIsDel(false);
    node.PutId(ids_.MakeServer(tag_name));
    sync_pb::EntitySpecifics specifics;
    syncer::AddDefaultFieldValue(model_type, &specifics);
    node.PutSpecifics(specifics);
  }

  void PumpLoop() {
    base::RunLoop().RunUntilIdle();
  }

  // Getters for tests.
  UserShare* user_share() { return test_user_share_.user_share(); }
  SyncEncryptionHandlerImpl* encryption_handler() {
      return encryption_handler_.get();
  }
  SyncEncryptionHandlerObserverMock* observer() { return &observer_; }
  Cryptographer* GetCryptographer() {
    return encryption_handler_->GetCryptographerUnsafe();
  }

  void VerifyMigratedNigori(PassphraseType passphrase_type,
                            const std::string& passphrase) {
    VerifyMigratedNigoriWithTimestamp(0, passphrase_type, passphrase);
  }

  void VerifyMigratedNigoriWithTimestamp(int64_t migration_time,
                                         PassphraseType passphrase_type,
                                         const std::string& passphrase) {
    ReadTransaction trans(FROM_HERE, user_share());
    ReadNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics();
    if (migration_time > 0)
      EXPECT_EQ(migration_time, nigori.keystore_migration_time());
    else
      EXPECT_TRUE(nigori.has_keystore_migration_time());
    EXPECT_TRUE(nigori.keybag_is_frozen());
    if (passphrase_type == CUSTOM_PASSPHRASE ||
        passphrase_type == FROZEN_IMPLICIT_PASSPHRASE) {
      EXPECT_TRUE(nigori.encrypt_everything());
      EXPECT_TRUE(nigori.keystore_decryptor_token().blob().empty());
      if (passphrase_type == CUSTOM_PASSPHRASE) {
        EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
                  nigori.passphrase_type());
        if (!encryption_handler()->custom_passphrase_time().is_null()) {
          EXPECT_EQ(nigori.custom_passphrase_time(),
                    TimeToProtoTime(
                        encryption_handler()->custom_passphrase_time()));
        }
      } else {
        EXPECT_EQ(sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE,
                  nigori.passphrase_type());
      }
    } else {
      EXPECT_FALSE(nigori.encrypt_everything());
      EXPECT_FALSE(nigori.keystore_decryptor_token().blob().empty());
      EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE,
                nigori.passphrase_type());
      Cryptographer keystore_cryptographer(&encryptor_);
      KeyParams params = {"localhost", "dummy", kKeystoreKey};
      keystore_cryptographer.AddKey(params);
      EXPECT_TRUE(keystore_cryptographer.CanDecryptUsingDefaultKey(
          nigori.keystore_decryptor_token()));
    }

    Cryptographer temp_cryptographer(&encryptor_);
    KeyParams params = {"localhost", "dummy", passphrase};
    temp_cryptographer.AddKey(params);
    EXPECT_TRUE(temp_cryptographer.CanDecryptUsingDefaultKey(
        nigori.encryption_keybag()));
  }

  sync_pb::NigoriSpecifics BuildMigratedNigori(
      PassphraseType passphrase_type,
      int64_t migration_time,
      const std::string& default_passphrase,
      const std::string& keystore_key) {
    DCHECK_NE(passphrase_type, IMPLICIT_PASSPHRASE);
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());

    std::string default_key = default_passphrase;
    if (default_key.empty()) {
      default_key = keystore_key;
    } else {
      KeyParams keystore_params = {"localhost", "dummy", keystore_key};
      other_cryptographer.AddKey(keystore_params);
    }
    KeyParams params = {"localhost", "dummy", default_key};
    other_cryptographer.AddKey(params);
    EXPECT_TRUE(other_cryptographer.is_ready());

    sync_pb::NigoriSpecifics nigori;
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(migration_time);

    if (passphrase_type == KEYSTORE_PASSPHRASE) {
      sync_pb::EncryptedData keystore_decryptor_token;
      EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
          other_cryptographer,
          keystore_key,
          &keystore_decryptor_token));
      nigori.mutable_keystore_decryptor_token()->CopyFrom(
          keystore_decryptor_token);
      nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    } else {
      nigori.set_encrypt_everything(true);
      nigori.set_passphrase_type(
          passphrase_type == CUSTOM_PASSPHRASE ?
              sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE :
              sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE);
    }
    return nigori;
  }

  // Build a migrated nigori node with the specified default passphrase
  // and keystore key and initialize the encryption handler with it.
  void InitKeystoreMigratedNigori(int64_t migration_time,
                                  const std::string& default_passphrase,
                                  const std::string& keystore_key) {
    {
      WriteTransaction trans(FROM_HERE, user_share());
      WriteNode nigori_node(&trans);
      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
      sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
          KEYSTORE_PASSPHRASE,
          migration_time,
          default_passphrase,
          keystore_key);
      nigori_node.SetNigoriSpecifics(nigori);
    }

    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AtLeast(1));
    EXPECT_CALL(*observer(),
                OnEncryptedTypesChanged(_, false));
    EXPECT_CALL(*observer(),
                OnEncryptionComplete()).Times(AtLeast(1));
    encryption_handler()->Init();
    EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
    EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
    EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
    Mock::VerifyAndClearExpectations(observer());
  }

  // Build a migrated nigori node with the specified default passphrase
  // as a custom passphrase.
  void InitCustomPassMigratedNigori(int64_t migration_time,
                                    const std::string& default_passphrase) {
    {
      WriteTransaction trans(FROM_HERE, user_share());
      WriteNode nigori_node(&trans);
      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
      sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
          CUSTOM_PASSPHRASE,
          migration_time,
          default_passphrase,
          kKeystoreKey);
      nigori_node.SetNigoriSpecifics(nigori);
    }

    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AtLeast(1));
    EXPECT_CALL(*observer(),
                OnEncryptedTypesChanged(_, true)).Times(AtLeast(1));
    EXPECT_CALL(*observer(),
                OnEncryptionComplete()).Times(AtLeast(1));
    encryption_handler()->Init();
    EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
    EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
    EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
    Mock::VerifyAndClearExpectations(observer());
  }

  // Build an unmigrated nigori node with the specified passphrase and type and
  // initialize the encryption handler with it.
  void InitUnmigratedNigori(const std::string& default_passphrase,
                            PassphraseType passphrase_type) {
    DCHECK_NE(passphrase_type, FROZEN_IMPLICIT_PASSPHRASE);
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    KeyParams default_key = {"localhost", "dummy", default_passphrase};
    other_cryptographer.AddKey(default_key);
    EXPECT_TRUE(other_cryptographer.is_ready());

    {
      WriteTransaction trans(FROM_HERE, user_share());
      WriteNode nigori_node(&trans);
      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
      sync_pb::NigoriSpecifics nigori;
      other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
      nigori.set_keybag_is_frozen(passphrase_type == CUSTOM_PASSPHRASE);
      nigori_node.SetNigoriSpecifics(nigori);
    }

    if (passphrase_type != IMPLICIT_PASSPHRASE) {
      EXPECT_CALL(*observer(),
                  OnPassphraseTypeChanged(passphrase_type, _));
    }
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AtLeast(1));
    EXPECT_CALL(*observer(),
                OnEncryptedTypesChanged(_, false));
    encryption_handler()->Init();
    EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
    EXPECT_EQ(encryption_handler()->GetPassphraseType(), passphrase_type);
    EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
    Mock::VerifyAndClearExpectations(observer());
  }

  // Verify we can restore the SyncEncryptionHandler state using a saved
  // |bootstrap_token| and |nigori_state|.
  //
  // |migration_time| is the time migration occurred.
  //
  // |passphrase| is the custom passphrase.
  void VerifyRestoreAfterCustomPassphrase(
      int64_t migration_time,
      const std::string& passphrase,
      const std::string& bootstrap_token,
      const SyncEncryptionHandler::NigoriState& nigori_state,
      PassphraseType passphrase_type) {
    TearDown();
    test_user_share_.SetUp();
    SetUpEncryptionWithKeyForBootstrapping(bootstrap_token);
    EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, true))
        .Times(AnyNumber());
    EXPECT_CALL(*observer(), OnPassphraseTypeChanged(passphrase_type, _));
    EXPECT_CALL(*observer(), OnEncryptionComplete());
    encryption_handler()->RestoreNigori(nigori_state);
    encryption_handler()->Init();
    Mock::VerifyAndClearExpectations(observer());
    VerifyMigratedNigoriWithTimestamp(migration_time, passphrase_type,
                                      passphrase);
  }

 protected:
  TestUserShare test_user_share_;
  FakeEncryptor encryptor_;
  scoped_ptr<SyncEncryptionHandlerImpl> encryption_handler_;
  StrictMock<SyncEncryptionHandlerObserverMock> observer_;
  TestIdFactory ids_;
  base::MessageLoop message_loop_;
};

// Verify that the encrypted types are being written to and read from the
// nigori node properly.
TEST_F(SyncEncryptionHandlerImplTest, NigoriEncryptionTypes) {
  sync_pb::NigoriSpecifics nigori;

  StrictMock<SyncEncryptionHandlerObserverMock> observer2;
  SyncEncryptionHandlerImpl handler2(user_share(), &encryptor_, std::string(),
                                     std::string() /* bootstrap tokens */,
                                     PASSPHRASE_TRANSITION_DO_NOT_CLEAR_DATA);
  handler2.AddObserver(&observer2);

  // Just set the sensitive types (shouldn't trigger any notifications).
  ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->MergeEncryptedTypes(
        encrypted_types,
        trans.GetWrappedTrans());
    encryption_handler()->UpdateNigoriFromEncryptedTypes(
        &nigori,
        trans.GetWrappedTrans());
    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
  }
  EXPECT_TRUE(encrypted_types.Equals(
      encryption_handler()->GetEncryptedTypesUnsafe()));
  EXPECT_TRUE(encrypted_types.Equals(
      handler2.GetEncryptedTypesUnsafe()));

  Mock::VerifyAndClearExpectations(observer());
  Mock::VerifyAndClearExpectations(&observer2);

  ModelTypeSet encrypted_user_types = EncryptableUserTypes();

  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(
                  HasModelTypes(encrypted_user_types), false));
  EXPECT_CALL(observer2,
              OnEncryptedTypesChanged(
                  HasModelTypes(encrypted_user_types), false));

  // Set all encrypted types
  encrypted_types = EncryptableUserTypes();
  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->MergeEncryptedTypes(
        encrypted_types,
        trans.GetWrappedTrans());
    encryption_handler()->UpdateNigoriFromEncryptedTypes(
        &nigori,
        trans.GetWrappedTrans());
    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
  }
  EXPECT_TRUE(encrypted_types.Equals(
      encryption_handler()->GetEncryptedTypesUnsafe()));
  EXPECT_TRUE(encrypted_types.Equals(handler2.GetEncryptedTypesUnsafe()));

  // Receiving an empty nigori should not reset any encrypted types or trigger
  // an observer notification.
  Mock::VerifyAndClearExpectations(observer());
  Mock::VerifyAndClearExpectations(&observer2);
  nigori = sync_pb::NigoriSpecifics();
  {
    WriteTransaction trans(FROM_HERE, user_share());
    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
  }
  EXPECT_TRUE(encrypted_types.Equals(
      encryption_handler()->GetEncryptedTypesUnsafe()));
}

// Verify the encryption handler processes the encrypt everything field
// properly.
TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingExplicit) {
  sync_pb::NigoriSpecifics nigori;
  nigori.set_encrypt_everything(true);

  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(
                  HasModelTypes(EncryptableUserTypes()), true));

  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  ModelTypeSet encrypted_types =
      encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.Equals(
      ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS)));

  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->UpdateEncryptedTypesFromNigori(
        nigori,
        trans.GetWrappedTrans());
  }

  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes()));

  // Receiving the nigori node again shouldn't trigger another notification.
  Mock::VerifyAndClearExpectations(observer());
  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->UpdateEncryptedTypesFromNigori(
        nigori,
        trans.GetWrappedTrans());
  }
}

// Verify the encryption handler can detect an implicit encrypt everything state
// (from clients that failed to write the encrypt everything field).
TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingImplicit) {
  sync_pb::NigoriSpecifics nigori;
  nigori.set_encrypt_bookmarks(true);  // Non-passwords = encrypt everything

  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(
                  HasModelTypes(EncryptableUserTypes()), true));

  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  ModelTypeSet encrypted_types =
      encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.Equals(
      ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS)));

  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->UpdateEncryptedTypesFromNigori(
        nigori,
        trans.GetWrappedTrans());
  }

  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes()));

  // Receiving a nigori node with encrypt everything explicitly set shouldn't
  // trigger another notification.
  Mock::VerifyAndClearExpectations(observer());
  nigori.set_encrypt_everything(true);
  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->UpdateEncryptedTypesFromNigori(
        nigori,
        trans.GetWrappedTrans());
  }
}

// Verify the encryption handler can deal with new versions treating new types
// as Sensitive, and that it does not consider this an implicit encrypt
// everything case.
TEST_F(SyncEncryptionHandlerImplTest, UnknownSensitiveTypes) {
  sync_pb::NigoriSpecifics nigori;
  nigori.set_encrypt_everything(false);
  nigori.set_encrypt_bookmarks(true);

  ModelTypeSet expected_encrypted_types =
      SyncEncryptionHandler::SensitiveTypes();
  expected_encrypted_types.Put(BOOKMARKS);

  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(
                  HasModelTypes(expected_encrypted_types), false));

  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  ModelTypeSet encrypted_types =
      encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.Equals(
      ModelTypeSet(PASSWORDS, WIFI_CREDENTIALS)));

  {
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->UpdateEncryptedTypesFromNigori(
        nigori,
        trans.GetWrappedTrans());
  }

  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
  EXPECT_TRUE(encrypted_types.Equals(
      ModelTypeSet(BOOKMARKS, PASSWORDS, WIFI_CREDENTIALS)));
}

// Receive an old nigori with old encryption keys and encrypted types. We should
// not revert our default key or encrypted types, and should post a task to
// overwrite the existing nigori with the correct data.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldNigori) {
  KeyParams old_key = {"localhost", "dummy", "old"};
  KeyParams current_key = {"localhost", "dummy", "cur"};

  // Data for testing encryption/decryption.
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  other_cryptographer.AddKey(old_key);
  sync_pb::EntitySpecifics other_encrypted_specifics;
  other_encrypted_specifics.mutable_bookmark()->set_title("title");
  other_cryptographer.Encrypt(
      other_encrypted_specifics,
      other_encrypted_specifics.mutable_encrypted());
  sync_pb::EntitySpecifics our_encrypted_specifics;
  our_encrypted_specifics.mutable_bookmark()->set_title("title2");
  ModelTypeSet encrypted_types = EncryptableUserTypes();

  // Set up the current encryption state (containing both keys and encrypt
  // everything).
  sync_pb::NigoriSpecifics current_nigori_specifics;
  GetCryptographer()->AddKey(old_key);
  GetCryptographer()->AddKey(current_key);
  GetCryptographer()->Encrypt(
      our_encrypted_specifics,
      our_encrypted_specifics.mutable_encrypted());
  GetCryptographer()->GetKeys(
      current_nigori_specifics.mutable_encryption_keybag());
  current_nigori_specifics.set_encrypt_everything(true);

  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(), OnEncryptedTypesChanged(
      HasModelTypes(EncryptableUserTypes()), true));
  {
    // Update the encryption handler.
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->ApplyNigoriUpdate(
        current_nigori_specifics,
        trans.GetWrappedTrans());
  }
  Mock::VerifyAndClearExpectations(observer());

  // Now set up the old nigori specifics and apply it on top.
  // Has an old set of keys, and no encrypted types.
  sync_pb::NigoriSpecifics old_nigori;
  other_cryptographer.GetKeys(old_nigori.mutable_encryption_keybag());

  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
  {
    // Update the encryption handler.
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->ApplyNigoriUpdate(
        old_nigori,
        trans.GetWrappedTrans());
  }
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_FALSE(GetCryptographer()->has_pending_keys());

  // Encryption handler should have posted a task to overwrite the old
  // specifics.
  PumpLoop();

  {
    // The cryptographer should be able to decrypt both sets of keys and still
    // be encrypting with the newest, and the encrypted types should be the
    // most recent.
    // In addition, the nigori node should match the current encryption state.
    ReadTransaction trans(FROM_HERE, user_share());
    ReadNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics();
    EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(
        our_encrypted_specifics.encrypted()));
    EXPECT_TRUE(GetCryptographer()->CanDecrypt(
        other_encrypted_specifics.encrypted()));
    EXPECT_TRUE(GetCryptographer()->CanDecrypt(nigori.encryption_keybag()));
    EXPECT_TRUE(nigori.encrypt_everything());
    EXPECT_TRUE(
        GetCryptographer()->CanDecryptUsingDefaultKey(
            nigori.encryption_keybag()));
  }
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
}

// Ensure setting the keystore key works, updates the bootstrap token, and
// triggers a non-backwards compatible migration. Then verify that the
// bootstrap token can be correctly parsed by the encryption handler at startup
// time.
TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreMigratesAndUpdatesBootstrap) {
  // Passing no keys should do nothing.
  EXPECT_CALL(*observer(), OnBootstrapTokenUpdated(_, _)).Times(0);
  {
    WriteTransaction trans(FROM_HERE, user_share());
    EXPECT_FALSE(GetCryptographer()->is_initialized());
    EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
    EXPECT_FALSE(encryption_handler()->SetKeystoreKeys(
        BuildEncryptionKeyProto(std::string()), trans.GetWrappedTrans()));
    EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
  }
  Mock::VerifyAndClearExpectations(observer());

  // Build a set of keystore keys.
  const char kRawOldKeystoreKey[] = "old_keystore_key";
  std::string old_keystore_key;
  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
  google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
  keys.Add()->assign(kRawOldKeystoreKey);
  keys.Add()->assign(kRawKeystoreKey);

  // Pass them to the encryption handler, triggering a migration and bootstrap
  // token update.
  std::string encoded_key;
  std::string keystore_bootstrap;
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_));
  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  EXPECT_CALL(*observer(), OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_,
                                      KEYSTORE_BOOTSTRAP_TOKEN)).
      WillOnce(SaveArg<0>(&keystore_bootstrap));
  {
    WriteTransaction trans(FROM_HERE, user_share());
    EXPECT_TRUE(
        encryption_handler()->SetKeystoreKeys(
            keys,
            trans.GetWrappedTrans()));
    EXPECT_FALSE(
        encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
    EXPECT_FALSE(GetCryptographer()->is_initialized());
  }
  PumpLoop();
  EXPECT_TRUE(GetCryptographer()->is_initialized());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);

  // Ensure the bootstrap is encoded properly (a base64 encoded encrypted blob
  // of list values containing the keystore keys).
  std::string decoded_bootstrap;
  ASSERT_TRUE(base::Base64Decode(keystore_bootstrap, &decoded_bootstrap));
  std::string decrypted_bootstrap;
  ASSERT_TRUE(
      GetCryptographer()->encryptor()->DecryptString(decoded_bootstrap,
                                                     &decrypted_bootstrap));
  JSONStringValueDeserializer json(decrypted_bootstrap);
  scoped_ptr<base::Value> deserialized_keystore_keys(
      json.Deserialize(NULL, NULL));
  ASSERT_TRUE(deserialized_keystore_keys.get());
  base::ListValue* keystore_list = NULL;
  deserialized_keystore_keys->GetAsList(&keystore_list);
  ASSERT_TRUE(keystore_list);
  ASSERT_EQ(2U, keystore_list->GetSize());
  std::string test_string;
  keystore_list->GetString(0, &test_string);
  ASSERT_EQ(old_keystore_key, test_string);
  keystore_list->GetString(1, &test_string);
  ASSERT_EQ(kKeystoreKey, test_string);


  // Now make sure a new encryption handler can correctly parse the bootstrap
  // token.
  SyncEncryptionHandlerImpl handler2(user_share(), &encryptor_,
                                     std::string(),  // Cryptographer bootstrap.
                                     keystore_bootstrap,
                                     PASSPHRASE_TRANSITION_DO_NOT_CLEAR_DATA);

  {
    WriteTransaction trans(FROM_HERE, user_share());
    EXPECT_FALSE(handler2.NeedKeystoreKey(trans.GetWrappedTrans()));
  }
}

// Ensure GetKeystoreDecryptor only updates the keystore decryptor token if it
// wasn't already set properly. Otherwise, the decryptor should remain the
// same.
TEST_F(SyncEncryptionHandlerImplTest, GetKeystoreDecryptor) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &encrypted));
  std::string serialized = encrypted.SerializeAsString();
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &encrypted));
  EXPECT_EQ(serialized, encrypted.SerializeAsString());
}

// Test that we don't attempt to migrate while an implicit passphrase is pending
// and that once we do decrypt pending keys we migrate the nigori. Once
// migrated, we should be in keystore passphrase state.
TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptImplicitPass) {
  const char kOtherKey[] = "other";
  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
    Mock::VerifyAndClearExpectations(observer());
  }
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    KeyParams other_key = {"localhost", "dummy", kOtherKey};
    other_cryptographer.AddKey(other_key);

    sync_pb::NigoriSpecifics nigori;
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(false);
    nigori.set_encrypt_everything(false);
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnPassphraseRequired(_, _));
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  encryption_handler()->SetDecryptionPassphrase(kOtherKey);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kOtherKey);
}

// Test that we don't attempt to migrate while a custom passphrase is pending,
// and that once we do decrypt pending keys we migrate the nigori. Once
// migrated, we should be in custom passphrase state with encrypt everything.
TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptCustomPass) {
  const char kOtherKey[] = "other";
  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
    Mock::VerifyAndClearExpectations(observer());
  }
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    KeyParams other_key = {"localhost", "dummy", kOtherKey};
    other_cryptographer.AddKey(other_key);

    sync_pb::NigoriSpecifics nigori;
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_encrypt_everything(false);
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnPassphraseRequired(_, _));
    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(2);
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  encryption_handler()->SetDecryptionPassphrase(kOtherKey);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  const base::Time migration_time = encryption_handler()->migration_time();
  EXPECT_EQ(CUSTOM_PASSPHRASE, encryption_handler()->GetPassphraseType());
  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kOtherKey);

  VerifyRestoreAfterCustomPassphrase(TimeToProtoTime(migration_time), kOtherKey,
                                     captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that we trigger a migration when we set the keystore key, had an
// implicit passphrase, and did not have encrypt everything. We should switch
// to KEYSTORE_PASSPHRASE.
TEST_F(SyncEncryptionHandlerImplTest, MigrateOnKeystoreKeyAvailableImplicit) {
  const char kCurKey[] = "cur";
  KeyParams current_key = {"localhost", "dummy", kCurKey};
  GetCryptographer()->AddKey(current_key);
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  Mock::VerifyAndClearExpectations(observer());

  {
    ReadTransaction trans(FROM_HERE, user_share());
    // Once we provide a keystore key, we should perform the migration.
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  // The actual migration gets posted, so run all pending tasks.
  PumpLoop();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(KEYSTORE_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);
}

// Test that we trigger a migration when we set the keystore key, had an
// implicit passphrase, and encrypt everything enabled. We should switch to
// FROZEN_IMPLICIT_PASSPHRASE.
TEST_F(SyncEncryptionHandlerImplTest,
       MigrateOnKeystoreKeyAvailableFrozenImplicit) {
  const char kCurKey[] = "cur";
  KeyParams current_key = {"localhost", "dummy", kCurKey};
  GetCryptographer()->AddKey(current_key);
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  Mock::VerifyAndClearExpectations(observer());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->EnableEncryptEverything();

  {
    ReadTransaction trans(FROM_HERE, user_share());
    // Once we provide a keystore key, we should perform the migration.
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));

  // The actual migration gets posted, so run all pending tasks.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  const base::Time migration_time = encryption_handler()->migration_time();
  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(FROZEN_IMPLICIT_PASSPHRASE, kCurKey);

  // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_,
  // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked
  // during a previous instance) so get it from the Cryptographer.
  std::string passphrase_bootstrap_token;
  GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token);
  VerifyRestoreAfterCustomPassphrase(
      TimeToProtoTime(migration_time), kCurKey, passphrase_bootstrap_token,
      captured_nigori_state, FROZEN_IMPLICIT_PASSPHRASE);
}

// Test that we trigger a migration when we set the keystore key, had a
// custom passphrase, and encrypt everything enabled. The passphrase state
// should remain as CUSTOM_PASSPHRASE, and encrypt everything stay the same.
TEST_F(SyncEncryptionHandlerImplTest,
       MigrateOnKeystoreKeyAvailableCustomWithEncryption) {
  const char kCurKey[] = "cur";
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  encryption_handler()->Init();
  encryption_handler()->SetEncryptionPassphrase(kCurKey, true);
  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->EnableEncryptEverything();
  Mock::VerifyAndClearExpectations(observer());

  SyncEncryptionHandler::NigoriState captured_nigori_state;
  {
    ReadTransaction trans(FROM_HERE, user_share());
    // Once we provide a keystore key, we should perform the migration.
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
        .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }

  // The actual migration gets posted, so run all pending tasks.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  const base::Time migration_time = encryption_handler()->migration_time();
  EXPECT_EQ(CUSTOM_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCurKey);

  VerifyRestoreAfterCustomPassphrase(TimeToProtoTime(migration_time), kCurKey,
                                     captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that we trigger a migration when we set the keystore key, had a
// custom passphrase, and did not have encrypt everything. The passphrase state
// should remain as CUSTOM_PASSPHRASE, and encrypt everything should be enabled.
TEST_F(SyncEncryptionHandlerImplTest,
       MigrateOnKeystoreKeyAvailableCustomNoEncryption) {
  const char kCurKey[] = "cur";
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  encryption_handler()->Init();
  encryption_handler()->SetEncryptionPassphrase(kCurKey, true);
  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
  Mock::VerifyAndClearExpectations(observer());

  {
    ReadTransaction trans(FROM_HERE, user_share());
    // Once we provide a keystore key, we should perform the migration.
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  // The actual migration gets posted, so run all pending tasks.
  PumpLoop();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  const base::Time migration_time = encryption_handler()->migration_time();
  EXPECT_EQ(CUSTOM_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCurKey);

  VerifyRestoreAfterCustomPassphrase(TimeToProtoTime(migration_time), kCurKey,
                                     captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that we can handle receiving a migrated nigori node in the
// KEYSTORE_PASS state, and use the keystore decryptor token to decrypt the
// keybag.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriKeystorePass) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  EXPECT_FALSE(GetCryptographer()->is_ready());
  EXPECT_NE(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);

  // Now build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer should be
  // initialized properly to decrypt both kCurKey and kKeystoreKey.
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(1);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);

    EXPECT_CALL(*observer(), OnPassphraseAccepted());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kCurKey);

  // Check that the cryptographer still encrypts with the current key.
  sync_pb::EncryptedData current_encrypted;
  other_cryptographer.EncryptString("string", &current_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));

  // Check that the cryptographer can decrypt keystore key based encryption.
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
}

// Test that we handle receiving migrated nigori's with
// FROZEN_IMPLICIT_PASSPHRASE state. We should be in a pending key state until
// we supply the pending frozen implicit passphrase key.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriFrozenImplicitPass) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnPassphraseRequired(_, _));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnEncryptedTypesChanged(_, true));
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.set_keybag_is_frozen(true);
    nigori.set_passphrase_type(
        sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE);
    nigori.set_keystore_migration_time(1);
    nigori.set_encrypt_everything(true);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());

  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  encryption_handler()->SetDecryptionPassphrase(kCurKey);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  VerifyMigratedNigoriWithTimestamp(1, FROZEN_IMPLICIT_PASSPHRASE, kCurKey);

  // Check that the cryptographer still encrypts with the current key.
  sync_pb::EncryptedData current_encrypted;
  other_cryptographer.EncryptString("string", &current_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));

  // Check that the cryptographer can decrypt keystore key based encryption.
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
}

// Test that we handle receiving migrated nigori's with
// CUSTOM_PASSPHRASE state. We should be in a pending key state until we
// provide the custom passphrase key.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriCustomPass) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());

  {
    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnPassphraseRequired(_, _));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnEncryptedTypesChanged(_, true));
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.set_keybag_is_frozen(true);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
    nigori.set_keystore_migration_time(1);
    nigori.set_encrypt_everything(true);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(CUSTOM_PASSPHRASE, encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());

  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  encryption_handler()->SetDecryptionPassphrase(kCurKey);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);

  // Check that the cryptographer still encrypts with the current key.
  sync_pb::EncryptedData current_encrypted;
  other_cryptographer.EncryptString("string", &current_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));

  // Check that the cryptographer can decrypt keystore key based encryption.
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
}

// Test that if we have a migrated nigori with a custom passphrase, then receive
// and old implicit passphrase nigori, we properly overwrite it with the current
// state.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveUnmigratedNigoriAfterMigration) {
  const char kOldKey[] = "old";
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  KeyParams old_key = {"localhost", "dummy", kOldKey};
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  GetCryptographer()->AddKey(old_key);
  GetCryptographer()->AddKey(cur_key);

  // Build a migrated nigori with full encryption.
  const int64_t migration_time = 1;
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(1);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
    nigori.set_encrypt_everything(true);
    nigori_node.SetNigoriSpecifics(nigori);
  }

  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true)).Times(2);
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE, kCurKey);

  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  Mock::VerifyAndClearExpectations(observer());

  // Now build an old unmigrated nigori node with old encrypted types. We should
  // properly overwrite it with the migrated + encrypt everything state.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  {
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    other_cryptographer.AddKey(old_key);
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(false);
    nigori.set_encrypt_everything(false);
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  PumpLoop();

  // Verify we're still migrated and have proper encryption state.
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);

  // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_,
  // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked
  // during a previous instance) so get it from the Cryptographer.
  std::string passphrase_bootstrap_token;
  GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token);
  VerifyRestoreAfterCustomPassphrase(migration_time, kCurKey,
                                     passphrase_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that if we have a migrated nigori with a custom passphrase, then receive
// a migrated nigori with a keystore passphrase, we properly overwrite it with
// the current state.
TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldMigratedNigori) {
  const char kOldKey[] = "old";
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  KeyParams old_key = {"localhost", "dummy", kOldKey};
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  GetCryptographer()->AddKey(old_key);
  GetCryptographer()->AddKey(cur_key);

  // Build a migrated nigori with full encryption.
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(1);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
    nigori.set_encrypt_everything(true);
    nigori_node.SetNigoriSpecifics(nigori);
  }

  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true)).Times(2);
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);

  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  Mock::VerifyAndClearExpectations(observer());

  // Now build an old keystore nigori node with old encrypted types. We should
  // properly overwrite it with the migrated + encrypt everything state.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  const int64_t migration_time = 1;
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    other_cryptographer.AddKey(old_key);
    encryption_handler()->GetKeystoreDecryptor(
        other_cryptographer,
        kKeystoreKey,
        nigori.mutable_keystore_decryptor_token());
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_encrypt_everything(false);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori.set_keystore_migration_time(migration_time);
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  PumpLoop();

  // Verify we're still migrated and have proper encryption state.
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE, kCurKey);

  // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_,
  // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked
  // during a previous instance) so get it from the Cryptographer.
  std::string passphrase_bootstrap_token;
  GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token);
  VerifyRestoreAfterCustomPassphrase(migration_time, kCurKey,
                                     passphrase_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that if we receive the keystore key after receiving a migrated nigori
// node, we properly use the keystore decryptor token to decrypt the keybag.
TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreAfterReceivingMigratedNigori) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  EXPECT_FALSE(GetCryptographer()->is_ready());
  EXPECT_NE(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);

  // Now build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer should be
  // initialized properly to decrypt both kCurKey and kKeystoreKey.
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(1);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);

    EXPECT_CALL(*observer(),
                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(),
                OnPassphraseRequired(_, _));
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  // Run any tasks posted via AppplyNigoriUpdate.
  PumpLoop();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  PumpLoop();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kCurKey);

  // Check that the cryptographer still encrypts with the current key.
  sync_pb::EncryptedData current_encrypted;
  other_cryptographer.EncryptString("string", &current_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));

  // Check that the cryptographer can decrypt keystore key based encryption.
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
}

// Test that after receiving a migrated nigori and decrypting it using the
// keystore key, we can then switch to a custom passphrase. The nigori should
// remain migrated and encrypt everything should be enabled.
TEST_F(SyncEncryptionHandlerImplTest, SetCustomPassAfterMigration) {
  const char kOldKey[] = "old";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kOldKey};
  other_cryptographer.AddKey(cur_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));

  // Build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer should be
  // initialized properly to decrypt both kOldKey and kKeystoreKey.
  const int64_t migration_time = 1;
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(migration_time);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori_node.SetNigoriSpecifics(nigori);
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }

  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  const char kNewKey[] = "new_key";
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(2);
  encryption_handler()->SetEncryptionPassphrase(kNewKey, true);
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_FALSE(captured_bootstrap_token.empty());
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE, kNewKey);

  // Check that the cryptographer can decrypt the old key.
  sync_pb::EncryptedData old_encrypted;
  other_cryptographer.EncryptString("string", &old_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted));

  // Check that the cryptographer can decrypt keystore key based encryption.
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));

  // Check the the cryptographer is encrypting with the new key.
  KeyParams new_key = {"localhost", "dummy", kNewKey};
  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
  new_cryptographer.AddKey(new_key);
  sync_pb::EncryptedData new_encrypted;
  new_cryptographer.EncryptString("string", &new_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));

  // Now verify that we can restore the current state using the captured
  // bootstrap token and nigori state.
  VerifyRestoreAfterCustomPassphrase(migration_time, kNewKey,
                                     captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that if a client without a keystore key (e.g. one without keystore
// encryption enabled) receives a migrated nigori and then attempts to set a
// custom passphrase, it also enables encrypt everything. The nigori node
// should remain migrated.
TEST_F(SyncEncryptionHandlerImplTest,
       SetCustomPassAfterMigrationNoKeystoreKey) {
  const char kOldKey[] = "old";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kOldKey};
  other_cryptographer.AddKey(cur_key);
  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
  other_cryptographer.AddNonDefaultKey(keystore_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));

  // Build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer will have
  // pending keys until we provide the decryption passphrase.
  const int64_t migration_time = 1;
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(migration_time);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori_node.SetNigoriSpecifics(nigori);
  }

  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->SetDecryptionPassphrase(kOldKey);
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  const char kNewKey[] = "new_key";
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(2);
  encryption_handler()->SetEncryptionPassphrase(kNewKey, true);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE, kNewKey);

  // Check that the cryptographer can decrypt the old key.
  sync_pb::EncryptedData old_encrypted;
  other_cryptographer.EncryptString("string", &old_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted));

  // Check that the cryptographer can still decrypt keystore key based
  // encryption (should have been extracted from the encryption keybag).
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));

  // Check the the cryptographer is encrypting with the new key.
  KeyParams new_key = {"localhost", "dummy", kNewKey};
  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
  new_cryptographer.AddKey(new_key);
  sync_pb::EncryptedData new_encrypted;
  new_cryptographer.EncryptString("string", &new_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));

  // Now verify that we can restore the current state using the captured
  // bootstrap token and nigori state.
  VerifyRestoreAfterCustomPassphrase(migration_time, kNewKey,
                                     captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Test that if a client without a keystore key (e.g. one without keystore
// encryption enabled) receives a migrated nigori and then attempts to set a
// new implicit passphrase, we do not modify the nigori node (the implicit
// passphrase is dropped).
TEST_F(SyncEncryptionHandlerImplTest,
       SetImplicitPassAfterMigrationNoKeystoreKey) {
  const char kOldKey[] = "old";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kOldKey};
  other_cryptographer.AddKey(cur_key);
  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
  other_cryptographer.AddNonDefaultKey(keystore_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));

  // Build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer will have
  // pending keys until we provide the decryption passphrase.
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(1);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori_node.SetNigoriSpecifics(nigori);
  }

  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->SetDecryptionPassphrase(kOldKey);
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  // Should get dropped on the floor silently.
  const char kNewKey[] = "new_key";
  encryption_handler()->SetEncryptionPassphrase(kNewKey, false);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kOldKey);

  // Check that the cryptographer can decrypt the old key.
  sync_pb::EncryptedData old_encrypted;
  other_cryptographer.EncryptString("string", &old_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(old_encrypted));

  // Check that the cryptographer can still decrypt keystore key based
  // encryption (due to extracting the keystore key from the encryption keybag).
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));

  // Check the the cryptographer does not have the new key.
  KeyParams new_key = {"localhost", "dummy", kNewKey};
  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
  new_cryptographer.AddKey(new_key);
  sync_pb::EncryptedData new_encrypted;
  new_cryptographer.EncryptString("string", &new_encrypted);
  EXPECT_FALSE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));
}

// Test that if a client without a keystore key (e.g. one without keystore
// encryption enabled) receives a migrated nigori in keystore passphrase state
// and then attempts to enable encrypt everything, we switch to a custom
// passphrase. The nigori should remain migrated.
TEST_F(SyncEncryptionHandlerImplTest,
       MigrateOnEncryptEverythingKeystorePassphrase) {
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData keystore_decryptor_token;
  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  other_cryptographer.AddKey(cur_key);
  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
  other_cryptographer.AddNonDefaultKey(keystore_key);
  EXPECT_TRUE(other_cryptographer.is_ready());
  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
      other_cryptographer,
      kKeystoreKey,
      &keystore_decryptor_token));

  // Build a nigori node with the generated keystore decryptor token and
  // initialize the encryption handler with it. The cryptographer will have
  // pending keys until we provide the decryption passphrase.
  const int64_t migration_time = 1;
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    nigori.mutable_keystore_decryptor_token()->CopyFrom(
        keystore_decryptor_token);
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_keystore_migration_time(migration_time);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori_node.SetNigoriSpecifics(nigori);
  }
  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  encryption_handler()->Init();
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->SetDecryptionPassphrase(kCurKey);
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
  encryption_handler()->EnableEncryptEverything();
  Mock::VerifyAndClearExpectations(observer());

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
            encryption_handler()->GetPassphraseType());
  EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigoriWithTimestamp(1, FROZEN_IMPLICIT_PASSPHRASE, kCurKey);

  // Check that the cryptographer is encrypting using the frozen current key.
  sync_pb::EncryptedData current_encrypted;
  other_cryptographer.EncryptString("string", &current_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));

  // Check that the cryptographer can still decrypt keystore key based
  // encryption (due to extracting the keystore key from the encryption keybag).
  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
  keystore_cryptographer.AddKey(keystore_key);
  sync_pb::EncryptedData keystore_encrypted;
  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));

  VerifyRestoreAfterCustomPassphrase(
      migration_time, kCurKey, captured_bootstrap_token, captured_nigori_state,
      FROZEN_IMPLICIT_PASSPHRASE);
}

// If we receive a nigori migrated and with a KEYSTORE_PASSPHRASE type, but
// using an old default key (i.e. old GAIA password), we should overwrite the
// nigori, updating the keybag and keystore decryptor.
TEST_F(SyncEncryptionHandlerImplTest,
       ReceiveMigratedNigoriWithOldPassphrase) {
  const char kOldKey[] = "old";
  const char kCurKey[] = "cur";
  sync_pb::EncryptedData encrypted;
  KeyParams old_key = {"localhost", "dummy", kOldKey};
  KeyParams cur_key = {"localhost", "dummy", kCurKey};
  GetCryptographer()->AddKey(old_key);
  GetCryptographer()->AddKey(cur_key);

  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
  other_cryptographer.AddKey(old_key);
  EXPECT_TRUE(other_cryptographer.is_ready());

  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete());
  encryption_handler()->Init();
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());

  {
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);

  // Now build an old keystore passphrase nigori node.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  {
    WriteTransaction trans(FROM_HERE, user_share());
    WriteNode nigori_node(&trans);
    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
    sync_pb::NigoriSpecifics nigori;
    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
    other_cryptographer.AddKey(old_key);
    encryption_handler()->GetKeystoreDecryptor(
        other_cryptographer,
        kKeystoreKey,
        nigori.mutable_keystore_decryptor_token());
    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
    nigori.set_keybag_is_frozen(true);
    nigori.set_encrypt_everything(false);
    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
    nigori.set_keystore_migration_time(1);
    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
    nigori_node.SetNigoriSpecifics(nigori);
  }
  PumpLoop();

  // Verify we're still migrated and have proper encryption state.
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);
}

// Trigger a key rotation upon receiving new keys if we already had a keystore
// migrated nigori with the gaia key as the default (still in backwards
// compatible mode).
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefault) {
  // Destroy the existing nigori node so we init without a nigori node.
  TearDown();
  test_user_share_.SetUp();
  SetUpEncryption();

  const char kOldGaiaKey[] = "old_gaia_key";
  const char kRawOldKeystoreKey[] = "old_keystore_key";
  std::string old_keystore_key;
  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
  {
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
      encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                                kRawOldKeystoreKey),
                                            trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Then init the nigori node with a backwards compatible set of keys.
  CreateRootForType(NIGORI);
  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key);

  // Now set some new keystore keys.
  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  {
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  // Pump for any posted tasks.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Verify we're still migrated and have proper encryption state. We should
  // have rotated the keybag so that it's now encrypted with the newest keystore
  // key (instead of the old gaia key).
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
}

// Trigger a key rotation upon receiving new keys if we already had a keystore
// migrated nigori with the keystore key as the default.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysKeystoreDefault) {
  // Destroy the existing nigori node so we init without a nigori node.
  TearDown();
  test_user_share_.SetUp();
  SetUpEncryption();

  const char kRawOldKeystoreKey[] = "old_keystore_key";
  std::string old_keystore_key;
  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
  {
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
      encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                                kRawOldKeystoreKey),
                                            trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Then init the nigori node with a non-backwards compatible set of keys.
  CreateRootForType(NIGORI);
  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  InitKeystoreMigratedNigori(1, old_keystore_key, old_keystore_key);

  // Now set some new keystore keys.
  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(), OnEncryptionComplete());
  {
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  // Pump for any posted tasks.
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Verify we're still migrated and have proper encryption state. We should
  // have rotated the keybag so that it's now encrypted with the newest keystore
  // key (instead of the old gaia key).
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
}

// Trigger a key rotation upon when a pending gaia passphrase is resolved.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysAfterPendingGaiaResolved) {
  const char kOldGaiaKey[] = "old_gaia_key";
  const char kRawOldKeystoreKey[] = "old_keystore_key";

  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
  InitUnmigratedNigori(kOldGaiaKey, IMPLICIT_PASSPHRASE);

  {
    // Pass multiple keystore keys, signaling a rotation has happened.
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Resolve the pending keys. This should trigger the key rotation.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(AtLeast(1));
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  encryption_handler()->SetDecryptionPassphrase(kOldGaiaKey);
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
}

// When signing in for the first time, make sure we can rotate keys if we
// already have a keystore migrated nigori.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefaultOnInit) {
  // Destroy the existing nigori node so we init without a nigori node.
  TearDown();
  test_user_share_.SetUp();
  SetUpEncryption();

  const char kOldGaiaKey[] = "old_gaia_key";
  const char kRawOldKeystoreKey[] = "old_keystore_key";
  std::string old_keystore_key;
  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);

  // Set two keys, signaling that a rotation has been performed. No nigori
  // node is present yet, so we can't rotate.
  {
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }

  // Then init the nigori node with an old set of keys.
  CreateRootForType(NIGORI);
  EXPECT_CALL(*observer(), OnPassphraseAccepted());
  InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key);
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Verify we're still migrated and have proper encryption state. We should
  // have rotated the keybag so that it's now encrypted with the newest keystore
  // key (instead of the old gaia key).
  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_TRUE(GetCryptographer()->is_ready());
  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
  EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
}

// Trigger a key rotation when a migrated nigori (with an old keystore key) is
// applied.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysWhenMigratedNigoriArrives) {
  const char kOldGaiaKey[] = "old_gaia_key";
  const char kRawOldKeystoreKey[] = "old_keystore_key";
  std::string old_keystore_key;
  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);

  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
  InitUnmigratedNigori(kOldGaiaKey, IMPLICIT_PASSPHRASE);

  {
    // Pass multiple keystore keys, signaling a rotation has happened.
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Now simulate downloading a nigori node that was migrated before the
  // keys were rotated, and hence still encrypt with the old gaia key.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(AtLeast(1));
  {
    sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
        KEYSTORE_PASSPHRASE,
        1,
        kOldGaiaKey,
        old_keystore_key);
    // Update the encryption handler.
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->ApplyNigoriUpdate(
        nigori,
        trans.GetWrappedTrans());
  }
  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
  PumpLoop();

  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
}

// Verify that performing a migration while having more than one keystore key
// preserves a custom passphrase.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysUnmigratedCustomPassphrase) {
  const char kCustomPass[] = "custom_passphrase";
  const char kRawOldKeystoreKey[] = "old_keystore_key";

  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
  InitUnmigratedNigori(kCustomPass, CUSTOM_PASSPHRASE);

  {
    // Pass multiple keystore keys, signaling a rotation has happened.
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  // Pass the decryption passphrase. This will also trigger the migration,
  // but should not overwrite the default key.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseAccepted());
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, true));
  SyncEncryptionHandler::NigoriState captured_nigori_state;
  EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
      .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
  EXPECT_CALL(*observer(),
              OnEncryptionComplete()).Times(AnyNumber());
  std::string captured_bootstrap_token;
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN))
      .WillOnce(testing::SaveArg<0>(&captured_bootstrap_token));
  encryption_handler()->SetDecryptionPassphrase(kCustomPass);
  Mock::VerifyAndClearExpectations(observer());

  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCustomPass);

  const base::Time migration_time = encryption_handler()->migration_time();
  VerifyRestoreAfterCustomPassphrase(TimeToProtoTime(migration_time),
                                     kCustomPass, captured_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Verify that a key rotation done after we've migrated a custom passphrase
// nigori node preserves the custom passphrase.
TEST_F(SyncEncryptionHandlerImplTest, RotateKeysMigratedCustomPassphrase) {
  const char kCustomPass[] = "custom_passphrase";
  const char kRawOldKeystoreKey[] = "old_keystore_key";

  KeyParams custom_key = {"localhost", "dummy", kCustomPass};
  GetCryptographer()->AddKey(custom_key);

  const int64_t migration_time = 1;
  InitCustomPassMigratedNigori(migration_time, kCustomPass);
  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE,
                                    kCustomPass);

  SyncEncryptionHandler::NigoriState captured_nigori_state;
  {
    // Pass multiple keystore keys, signaling a rotation has happened.
    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
    keys.Add()->assign(kRawOldKeystoreKey);
    keys.Add()->assign(kRawKeystoreKey);
    ReadTransaction trans(FROM_HERE, user_share());
    EXPECT_CALL(*observer(),
                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
    EXPECT_CALL(*observer(),
                OnCryptographerStateChanged(_)).Times(AnyNumber());
    EXPECT_CALL(*observer(), OnLocalSetPassphraseEncryption(_))
        .WillOnce(testing::SaveArg<0>(&captured_nigori_state));
    encryption_handler()->SetKeystoreKeys(keys,
                                          trans.GetWrappedTrans());
  }
  PumpLoop();
  Mock::VerifyAndClearExpectations(observer());

  VerifyMigratedNigoriWithTimestamp(migration_time, CUSTOM_PASSPHRASE,
                                    kCustomPass);

  // We need the passphrase bootstrap token, but OnBootstrapTokenUpdated(_,
  // PASSPHRASE_BOOTSTRAP_TOKEN) has not been invoked (because it was invoked
  // during a previous instance) so get it from the Cryptographer.
  std::string passphrase_bootstrap_token;
  GetCryptographer()->GetBootstrapToken(&passphrase_bootstrap_token);
  VerifyRestoreAfterCustomPassphrase(migration_time, kCustomPass,
                                     passphrase_bootstrap_token,
                                     captured_nigori_state, CUSTOM_PASSPHRASE);
}

// Verify that the client can gracefully handle a nigori node that is missing
// the keystore migration time field.
TEST_F(SyncEncryptionHandlerImplTest, MissingKeystoreMigrationTime) {
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnEncryptedTypesChanged(_, false));
  encryption_handler()->Init();
  Mock::VerifyAndClearExpectations(observer());

  // Now simulate downloading a nigori node that that is missing the keystore
  // migration time. It should be interpreted properly, and the passphrase type
  // should switch to keystore passphrase.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnPassphraseRequired(_, _));
  EXPECT_CALL(*observer(),
              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
  {
    sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
        KEYSTORE_PASSPHRASE,
        1,
        kKeystoreKey,
        kKeystoreKey);
    nigori.clear_keystore_migration_time();
    // Update the encryption handler.
    WriteTransaction trans(FROM_HERE, user_share());
    encryption_handler()->ApplyNigoriUpdate(
        nigori,
        trans.GetWrappedTrans());
  }
  Mock::VerifyAndClearExpectations(observer());

  // Now provide the keystore key to fully initialize the cryptographer.
  EXPECT_CALL(*observer(),
              OnCryptographerStateChanged(_)).Times(AnyNumber());
  EXPECT_CALL(*observer(),
              OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
  {
    ReadTransaction trans(FROM_HERE, user_share());
    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
                                              kRawKeystoreKey),
                                          trans.GetWrappedTrans());
  }
}

}  // namespace syncer
