12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/sync_encryption_handler_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_string_value_serializer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type_test_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/read_node.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/read_transaction.h"
179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "sync/internal_api/public/test/test_user_share.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_node.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/write_transaction.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/nigori_specifics.pb.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/entry.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/mutable_entry.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/syncable/syncable_write_transaction.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/test_id_factory.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/fake_encryptor.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/util/cryptographer.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AnyNumber;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::AtLeast;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Mock;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SaveArg;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrictMock;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The raw keystore key the server sends.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kRawKeystoreKey[] = "keystore_key";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base64 encoded version of |kRawKeystoreKey|.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kKeystoreKey[] = "a2V5c3RvcmVfa2V5";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncEncryptionHandlerObserverMock
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public SyncEncryptionHandler::Observer {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnPassphraseRequired,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               void(PassphraseRequiredReason,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const sync_pb::EncryptedData&));  // NOLINT
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(OnPassphraseAccepted, void());  // NOLINT
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnBootstrapTokenUpdated,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               void(const std::string&, BootstrapTokenType type));  // NOLINT
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnEncryptedTypesChanged,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               void(ModelTypeSet, bool));  // NOLINT
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(OnEncryptionComplete, void());  // NOLINT
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnCryptographerStateChanged, void(Cryptographer*));  // NOLINT
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnPassphraseTypeChanged, void(PassphraseType,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             base::Time));  // NOLINT
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)google::protobuf::RepeatedPtrField<google::protobuf::string>
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BuildEncryptionKeyProto(std::string encryption_key) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keys.Add()->assign(encryption_key);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keys;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncEncryptionHandlerImplTest : public ::testing::Test {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncEncryptionHandlerImplTest() {}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SyncEncryptionHandlerImplTest() {}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_user_share_.SetUp();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUpEncryption();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateRootForType(NIGORI);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PumpLoop();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_user_share_.TearDown();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUpEncryption() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler_.reset(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new SyncEncryptionHandlerImpl(user_share(),
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &encryptor_,
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      std::string(),
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      std::string() /* bootstrap tokens */));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler_->AddObserver(&observer_);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateRootForType(ModelType model_type) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::syncable::Directory* directory = user_share()->directory.get();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string tag_name = ModelTypeToRootTag(model_type);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncable::WriteTransaction wtrans(FROM_HERE, syncable::UNITTEST, directory);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncable::MutableEntry node(&wtrans,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                syncable::CREATE,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                model_type,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                wtrans.root_id(),
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                tag_name);
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutUniqueServerTag(tag_name);
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutIsDir(true);
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutServerIsDir(false);
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutIsUnsynced(false);
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutIsUnappliedUpdate(false);
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutServerVersion(20);
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutBaseVersion(20);
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutIsDel(false);
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutId(ids_.MakeServer(tag_name));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::EntitySpecifics specifics;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::AddDefaultFieldValue(model_type, &specifics);
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    node.PutSpecifics(specifics);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PumpLoop() {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_loop_.RunUntilIdle();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Getters for tests.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UserShare* user_share() { return test_user_share_.user_share(); }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncEncryptionHandlerImpl* encryption_handler() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return encryption_handler_.get();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncEncryptionHandlerObserverMock* observer() { return &observer_; }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer* GetCryptographer() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return encryption_handler_->GetCryptographerUnsafe();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyMigratedNigori(PassphraseType passphrase_type,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& passphrase) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VerifyMigratedNigoriWithTimestamp(0, passphrase_type, passphrase);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyMigratedNigoriWithTimestamp(
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int64 migration_time,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PassphraseType passphrase_type,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& passphrase) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadNode nigori_node(&trans);
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (migration_time > 0)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(migration_time, nigori.keystore_migration_time());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(nigori.has_keystore_migration_time());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(nigori.keybag_is_frozen());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (passphrase_type == CUSTOM_PASSPHRASE ||
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        passphrase_type == FROZEN_IMPLICIT_PASSPHRASE) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(nigori.encrypt_everything());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(nigori.keystore_decryptor_token().blob().empty());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (passphrase_type == CUSTOM_PASSPHRASE) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  nigori.passphrase_type());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!encryption_handler()->custom_passphrase_time().is_null()) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          EXPECT_EQ(nigori.custom_passphrase_time(),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    TimeToProtoTime(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        encryption_handler()->custom_passphrase_time()));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  nigori.passphrase_type());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(nigori.encrypt_everything());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(nigori.keystore_decryptor_token().blob().empty());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nigori.passphrase_type());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Cryptographer keystore_cryptographer(&encryptor_);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      KeyParams params = {"localhost", "dummy", kKeystoreKey};
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keystore_cryptographer.AddKey(params);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(keystore_cryptographer.CanDecryptUsingDefaultKey(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          nigori.keystore_decryptor_token()));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer temp_cryptographer(&encryptor_);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KeyParams params = {"localhost", "dummy", passphrase};
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    temp_cryptographer.AddKey(params);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(temp_cryptographer.CanDecryptUsingDefaultKey(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori.encryption_keybag()));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::NigoriSpecifics BuildMigratedNigori(
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PassphraseType passphrase_type,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 migration_time,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& default_passphrase,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& keystore_key) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_NE(passphrase_type, IMPLICIT_PASSPHRASE);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string default_key = default_passphrase;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (default_key.empty()) {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_key = keystore_key;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      KeyParams keystore_params = {"localhost", "dummy", keystore_key};
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      other_cryptographer.AddKey(keystore_params);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyParams params = {"localhost", "dummy", default_key};
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    other_cryptographer.AddKey(params);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(other_cryptographer.is_ready());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nigori.set_keybag_is_frozen(true);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    nigori.set_keystore_migration_time(migration_time);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (passphrase_type == KEYSTORE_PASSPHRASE) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::EncryptedData keystore_decryptor_token;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          other_cryptographer,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          keystore_key,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &keystore_decryptor_token));
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori.mutable_keystore_decryptor_token()->CopyFrom(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          keystore_decryptor_token);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori.set_encrypt_everything(true);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori.set_passphrase_type(
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          passphrase_type == CUSTOM_PASSPHRASE ?
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE :
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return nigori;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Build a migrated nigori node with the specified default passphrase
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and keystore key and initialize the encryption handler with it.
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitKeystoreMigratedNigori(int64 migration_time,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::string& default_passphrase,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::string& keystore_key) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteTransaction trans(FROM_HERE, user_share());
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteNode nigori_node(&trans);
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          KEYSTORE_PASSPHRASE,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          migration_time,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default_passphrase,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          keystore_key);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori_node.SetNigoriSpecifics(nigori);
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AtLeast(1));
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnEncryptedTypesChanged(_, false));
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnEncryptionComplete()).Times(AtLeast(1));
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->Init();
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(observer());
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Build a migrated nigori node with the specified default passphrase
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as a custom passphrase.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitCustomPassMigratedNigori(int64 migration_time,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::string& default_passphrase) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteTransaction trans(FROM_HERE, user_share());
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteNode nigori_node(&trans);
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CUSTOM_PASSPHRASE,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          migration_time,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          default_passphrase,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kKeystoreKey);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori_node.SetNigoriSpecifics(nigori);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AtLeast(1));
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnEncryptedTypesChanged(_, true)).Times(AtLeast(1));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnEncryptionComplete()).Times(AtLeast(1));
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->Init();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(observer());
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Build an unmigrated nigori node with the specified passphrase and type and
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initialize the encryption handler with it.
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitUnmigratedNigori(const std::string& default_passphrase,
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            PassphraseType passphrase_type) {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_NE(passphrase_type, FROZEN_IMPLICIT_PASSPHRASE);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyParams default_key = {"localhost", "dummy", default_passphrase};
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    other_cryptographer.AddKey(default_key);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(other_cryptographer.is_ready());
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteTransaction trans(FROM_HERE, user_share());
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteNode nigori_node(&trans);
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_pb::NigoriSpecifics nigori;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori.set_keybag_is_frozen(passphrase_type == CUSTOM_PASSPHRASE);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nigori_node.SetNigoriSpecifics(nigori);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (passphrase_type != IMPLICIT_PASSPHRASE) {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(*observer(),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  OnPassphraseTypeChanged(passphrase_type, _));
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AtLeast(1));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnEncryptedTypesChanged(_, false));
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->Init();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(encryption_handler()->GetPassphraseType(), passphrase_type);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(observer());
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUserShare test_user_share_;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeEncryptor encryptor_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncEncryptionHandlerImpl> encryption_handler_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StrictMock<SyncEncryptionHandlerObserverMock> observer_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestIdFactory ids_;
340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop message_loop_;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that the encrypted types are being written to and read from the
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nigori node properly.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, NigoriEncryptionTypes) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics nigori;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StrictMock<SyncEncryptionHandlerObserverMock> observer2;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncEncryptionHandlerImpl handler2(user_share(),
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &encryptor_,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     std::string(),
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     std::string() /* bootstrap tokens */);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler2.AddObserver(&observer2);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just set the sensitive types (shouldn't trigger any notifications).
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->MergeEncryptedTypes(
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        encrypted_types,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateNigoriFromEncryptedTypes(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &nigori,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe()));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      handler2.GetEncryptedTypesUnsafe()));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer2);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_user_types = EncryptableUserTypes();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HasModelTypes(encrypted_user_types), false));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(observer2,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HasModelTypes(encrypted_user_types), false));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set all encrypted types
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypted_types = EncryptableUserTypes();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->MergeEncryptedTypes(
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        encrypted_types,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateNigoriFromEncryptedTypes(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &nigori,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe()));
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(handler2.GetEncryptedTypesUnsafe()));
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Receiving an empty nigori should not reset any encrypted types or trigger
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an observer notification.
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer2);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori = sync_pb::NigoriSpecifics();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler2.UpdateEncryptedTypesFromNigori(nigori, trans.GetWrappedTrans());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe()));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the encryption handler processes the encrypt everything field
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// properly.
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingExplicit) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics nigori;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori.set_encrypt_everything(true);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HasModelTypes(EncryptableUserTypes()), true));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_types =
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(ModelTypeSet(PASSWORDS)));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateEncryptedTypesFromNigori(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes()));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Receiving the nigori node again shouldn't trigger another notification.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateEncryptedTypesFromNigori(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the encryption handler can detect an implicit encrypt everything state
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (from clients that failed to write the encrypt everything field).
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, EncryptEverythingImplicit) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics nigori;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori.set_encrypt_bookmarks(true);  // Non-passwords = encrypt everything
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HasModelTypes(EncryptableUserTypes()), true));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_types =
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(ModelTypeSet(PASSWORDS)));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateEncryptedTypesFromNigori(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.HasAll(EncryptableUserTypes()));
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Receiving a nigori node with encrypt everything explicitly set shouldn't
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // trigger another notification.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori.set_encrypt_everything(true);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateEncryptedTypesFromNigori(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the encryption handler can deal with new versions treating new types
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as Sensitive, and that it does not consider this an implicit encrypt
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything case.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, UnknownSensitiveTypes) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics nigori;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori.set_encrypt_everything(false);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nigori.set_encrypt_bookmarks(true);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet expected_encrypted_types =
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncEncryptionHandler::SensitiveTypes();
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_encrypted_types.Put(BOOKMARKS);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  HasModelTypes(expected_encrypted_types), false));
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_types =
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      encryption_handler()->GetEncryptedTypesUnsafe();
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(ModelTypeSet(PASSWORDS)));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->UpdateEncryptedTypesFromNigori(
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encrypted_types.Equals(ModelTypeSet(BOOKMARKS, PASSWORDS)));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Receive an old nigori with old encryption keys and encrypted types. We should
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not revert our default key or encrypted types, and should post a task to
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// overwrite the existing nigori with the correct data.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldNigori) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams old_key = {"localhost", "dummy", "old"};
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams current_key = {"localhost", "dummy", "cur"};
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Data for testing encryption/decryption.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(old_key);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EntitySpecifics other_encrypted_specifics;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_encrypted_specifics.mutable_bookmark()->set_title("title");
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.Encrypt(
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_encrypted_specifics,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_encrypted_specifics.mutable_encrypted());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EntitySpecifics our_encrypted_specifics;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_encrypted_specifics.mutable_bookmark()->set_title("title2");
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ModelTypeSet encrypted_types = EncryptableUserTypes();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up the current encryption state (containing both keys and encrypt
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // everything).
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics current_nigori_specifics;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(old_key);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(current_key);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->Encrypt(
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_encrypted_specifics,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_encrypted_specifics.mutable_encrypted());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->GetKeys(
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_nigori_specifics.mutable_encryption_keybag());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_nigori_specifics.set_encrypt_everything(true);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptedTypesChanged(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasModelTypes(EncryptableUserTypes()), true));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the encryption handler.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_nigori_specifics,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now set up the old nigori specifics and apply it on top.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Has an old set of keys, and no encrypted types.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::NigoriSpecifics old_nigori;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.GetKeys(old_nigori.mutable_encryption_keybag());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the encryption handler.
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_nigori,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trans.GetWrappedTrans());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetCryptographer()->has_pending_keys());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Encryption handler should have posted a task to overwrite the old
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specifics.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The cryptographer should be able to decrypt both sets of keys and still
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be encrypting with the newest, and the encrypted types should be the
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // most recent.
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In addition, the nigori node should match the current encryption state.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadNode nigori_node(&trans);
59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const sync_pb::NigoriSpecifics& nigori = nigori_node.GetNigoriSpecifics();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        our_encrypted_specifics.encrypted()));
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(GetCryptographer()->CanDecrypt(
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_encrypted_specifics.encrypted()));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(GetCryptographer()->CanDecrypt(nigori.encryption_keybag()));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(nigori.encrypt_everything());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetCryptographer()->CanDecryptUsingDefaultKey(
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            nigori.encryption_keybag()));
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure setting the keystore key works, updates the bootstrap token, and
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// triggers a non-backwards compatible migration. Then verify that the
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// bootstrap token can be correctly parsed by the encryption handler at startup
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// time.
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreMigratesAndUpdatesBootstrap) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Passing no keys should do nothing.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(), OnBootstrapTokenUpdated(_, _)).Times(0);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(GetCryptographer()->is_initialized());
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(encryption_handler()->SetKeystoreKeys(
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BuildEncryptionKeyProto(std::string()), trans.GetWrappedTrans()));
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Build a set of keystore keys.
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string old_keystore_key;
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keys.Add()->assign(kRawOldKeystoreKey);
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keys.Add()->assign(kRawKeystoreKey);
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pass them to the encryption handler, triggering a migration and bootstrap
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // token update.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string encoded_key;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string keystore_bootstrap;
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_));
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnBootstrapTokenUpdated(_,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      KEYSTORE_BOOTSTRAP_TOKEN)).
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WillOnce(SaveArg<0>(&keystore_bootstrap));
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        encryption_handler()->SetKeystoreKeys(
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            keys,
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            trans.GetWrappedTrans()));
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans()));
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(GetCryptographer()->is_initialized());
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_initialized());
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure the bootstrap is encoded properly (a base64 encoded encrypted blob
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // of list values containing the keystore keys).
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string decoded_bootstrap;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(base::Base64Decode(keystore_bootstrap, &decoded_bootstrap));
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string decrypted_bootstrap;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetCryptographer()->encryptor()->DecryptString(decoded_bootstrap,
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     &decrypted_bootstrap));
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JSONStringValueSerializer json(decrypted_bootstrap);
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> deserialized_keystore_keys(
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      json.Deserialize(NULL, NULL));
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(deserialized_keystore_keys.get());
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* keystore_list = NULL;
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  deserialized_keystore_keys->GetAsList(&keystore_list);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(keystore_list);
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2U, keystore_list->GetSize());
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string test_string;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keystore_list->GetString(0, &test_string);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(old_keystore_key, test_string);
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keystore_list->GetString(1, &test_string);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kKeystoreKey, test_string);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now make sure a new encryption handler can correctly parse the bootstrap
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // token.
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncEncryptionHandlerImpl handler2(user_share(),
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     &encryptor_,
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     std::string(),  // Cryptographer bootstrap.
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     keystore_bootstrap);
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(handler2.NeedKeystoreKey(trans.GetWrappedTrans()));
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure GetKeystoreDecryptor only updates the keystore decryptor token if it
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wasn't already set properly. Otherwise, the decryptor should remain the
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// same.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, GetKeystoreDecryptor) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &encrypted));
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string serialized = encrypted.SerializeAsString();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &encrypted));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(serialized, encrypted.SerializeAsString());
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't attempt to migrate while an implicit passphrase is pending
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and that once we do decrypt pending keys we migrate the nigori. Once
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// migrated, we should be in keystore passphrase state.
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptImplicitPass) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOtherKey[] = "other";
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Mock::VerifyAndClearExpectations(observer());
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KeyParams other_key = {"localhost", "dummy", kOtherKey};
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.AddKey(other_key);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(false);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(false);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseRequired(_, _));
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kOtherKey);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kOtherKey);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't attempt to migrate while a custom passphrase is pending,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and that once we do decrypt pending keys we migrate the nigori. Once
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// migrated, we should be in custom passphrase state with encrypt everything.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, MigrateOnDecryptCustomPass) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOtherKey[] = "other";
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Mock::VerifyAndClearExpectations(observer());
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
79046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KeyParams other_key = {"localhost", "dummy", kOtherKey};
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.AddKey(other_key);
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(false);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseRequired(_, _));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete()).Times(2);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kOtherKey);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CUSTOM_PASSPHRASE, encryption_handler()->GetPassphraseType());
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kOtherKey);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we trigger a migration when we set the keystore key, had an
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implicit passphrase, and did not have encrypt everything. We should switch
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to KEYSTORE_PASSPHRASE.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, MigrateOnKeystoreKeyAvailableImplicit) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams current_key = {"localhost", "dummy", kCurKey};
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(current_key);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once we provide a keystore key, we should perform the migration.
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual migration gets posted, so run all pending tasks.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(KEYSTORE_PASSPHRASE,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we trigger a migration when we set the keystore key, had an
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implicit passphrase, and encrypt everything enabled. We should switch to
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FROZEN_IMPLICIT_PASSPHRASE.
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MigrateOnKeystoreKeyAvailableFrozenImplicit) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams current_key = {"localhost", "dummy", kCurKey};
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(current_key);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->EnableEncryptEverything();
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once we provide a keystore key, we should perform the migration.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual migration gets posted, so run all pending tasks.
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(FROZEN_IMPLICIT_PASSPHRASE, kCurKey);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we trigger a migration when we set the keystore key, had a
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// custom passphrase, and encrypt everything enabled. The passphrase state
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should remain as CUSTOM_PASSPHRASE, and encrypt everything stay the same.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MigrateOnKeystoreKeyAvailableCustomWithEncryption) {
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseRequired(_, _));
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetEncryptionPassphrase(kCurKey, true);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->EnableEncryptEverything();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once we provide a keystore key, we should perform the migration.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual migration gets posted, so run all pending tasks.
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CUSTOM_PASSPHRASE,
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCurKey);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we trigger a migration when we set the keystore key, had a
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// custom passphrase, and did not have encrypt everything. The passphrase state
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should remain as CUSTOM_PASSPHRASE, and encrypt everything should be enabled.
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MigrateOnKeystoreKeyAvailableCustomNoEncryption) {
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseRequired(_, _));
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetEncryptionPassphrase(kCurKey, true);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once we provide a keystore key, we should perform the migration.
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual migration gets posted, so run all pending tasks.
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CUSTOM_PASSPHRASE,
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCurKey);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we can handle receiving a migrated nigori node in the
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// KEYSTORE_PASS state, and use the keystore decryptor token to decrypt the
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// keybag.
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriKeystorePass) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetCryptographer()->is_ready());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now build a nigori node with the generated keystore decryptor token and
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer should be
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized properly to decrypt both kCurKey and kKeystoreKey.
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
103846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(), OnPassphraseAccepted());
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kCurKey);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer still encrypts with the current key.
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData current_encrypted;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &current_encrypted);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt keystore key based encryption.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we handle receiving migrated nigori's with
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FROZEN_IMPLICIT_PASSPHRASE state. We should be in a pending key state until
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we supply the pending frozen implicit passphrase key.
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriFrozenImplicitPass) {
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseRequired(_, _));
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnEncryptedTypesChanged(_, true));
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
111846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE);
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(true);
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kCurKey);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, FROZEN_IMPLICIT_PASSPHRASE, kCurKey);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer still encrypts with the current key.
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData current_encrypted;
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &current_encrypted);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt keystore key based encryption.
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we handle receiving migrated nigori's with
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CUSTOM_PASSPHRASE state. We should be in a pending key state until we
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provide the custom passphrase key.
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriCustomPass) {
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseRequired(_, _));
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnEncryptedTypesChanged(_, true));
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
119846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(true);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CUSTOM_PASSPHRASE, encryption_handler()->GetPassphraseType());
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kCurKey);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer still encrypts with the current key.
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData current_encrypted;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &current_encrypted);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt keystore key based encryption.
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we have a migrated nigori with a custom passphrase, then receive
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and old implicit passphrase nigori, we properly overwrite it with the current
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// state.
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveUnmigratedNigoriAfterMigration) {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams old_key = {"localhost", "dummy", kOldKey};
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(old_key);
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(cur_key);
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a migrated nigori with full encryption.
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
126046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag());
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(true);
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true)).Times(2);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now build an old unmigrated nigori node with old encrypted types. We should
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // properly overwrite it with the migrated + encrypt everything state.
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.AddKey(old_key);
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
130546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(false);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(false);
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify we're still migrated and have proper encryption state.
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we have a migrated nigori with a custom passphrase, then receive
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a migrated nigori with a keystore passphrase, we properly overwrite it with
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the current state.
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldMigratedNigori) {
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams old_key = {"localhost", "dummy", kOldKey};
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(old_key);
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(cur_key);
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a migrated nigori with full encryption.
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
133946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetCryptographer()->GetKeys(nigori.mutable_encryption_keybag());
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(true);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true)).Times(2);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now build an old keystore nigori node with old encrypted types. We should
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // properly overwrite it with the migrated + encrypt everything state.
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
138246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.AddKey(old_key);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->GetKeystoreDecryptor(
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_cryptographer,
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kKeystoreKey,
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori.mutable_keystore_decryptor_token());
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(false);
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify we're still migrated and have proper encryption state.
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCurKey);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we receive the keystore key after receiving a migrated nigori
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// node, we properly use the keystore decryptor token to decrypt the keybag.
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreAfterReceivingMigratedNigori) {
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetCryptographer()->is_ready());
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now build a nigori node with the generated keystore decryptor token and
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer should be
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized properly to decrypt both kCurKey and kKeystoreKey.
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
143146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnPassphraseRequired(_, _));
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run any tasks posted via AppplyNigoriUpdate.
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kCurKey);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer still encrypts with the current key.
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData current_encrypted;
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &current_encrypted);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt keystore key based encryption.
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that after receiving a migrated nigori and decrypting it using the
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// keystore key, we can then switch to a custom passphrase. The nigori should
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// remain migrated and encrypt everything should be enabled.
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, SetCustomPassAfterMigration) {
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kOldKey};
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a nigori node with the generated keystore decryptor token and
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer should be
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized properly to decrypt both kOldKey and kKeystoreKey.
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
151246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kNewKey[] = "new_key";
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete()).Times(2);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetEncryptionPassphrase(kNewKey, true);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kNewKey);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt the old key.
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData old_encrypted;
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &old_encrypted);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted));
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt keystore key based encryption.
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key =  {"localhost", "dummy", kKeystoreKey};
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the the cryptographer is encrypting with the new key.
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams new_key = {"localhost", "dummy", kNewKey};
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.AddKey(new_key);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData new_encrypted;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.EncryptString("string", &new_encrypted);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if a client without a keystore key (e.g. one without keystore
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption enabled) receives a migrated nigori and then attempts to set a
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// custom passphrase, it also enables encrypt everything. The nigori node
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should remain migrated.
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       SetCustomPassAfterMigrationNoKeystoreKey) {
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kOldKey};
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddNonDefaultKey(keystore_key);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a nigori node with the generated keystore decryptor token and
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer will have
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending keys until we provide the decryption passphrase.
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
161446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseRequired(_, _));
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kOldKey);
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kNewKey[] = "new_key";
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(CUSTOM_PASSPHRASE, _));
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete()).Times(2);
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetEncryptionPassphrase(kNewKey, true);
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), CUSTOM_PASSPHRASE);
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null());
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kNewKey);
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt the old key.
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData old_encrypted;
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &old_encrypted);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted));
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can still decrypt keystore key based
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encryption (should have been extracted from the encryption keybag).
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the the cryptographer is encrypting with the new key.
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams new_key = {"localhost", "dummy", kNewKey};
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.AddKey(new_key);
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData new_encrypted;
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.EncryptString("string", &new_encrypted);
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if a client without a keystore key (e.g. one without keystore
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption enabled) receives a migrated nigori and then attempts to set a
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// new implicit passphrase, we do not modify the nigori node (the implicit
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passphrase is dropped).
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       SetImplicitPassAfterMigrationNoKeystoreKey) {
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kOldKey};
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddNonDefaultKey(keystore_key);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a nigori node with the generated keystore decryptor token and
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer will have
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending keys until we provide the decryption passphrase.
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
172146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseRequired(_, _));
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kOldKey);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should get dropped on the floor silently.
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kNewKey[] = "new_key";
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetEncryptionPassphrase(kNewKey, false);
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, KEYSTORE_PASSPHRASE, kOldKey);
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can decrypt the old key.
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData old_encrypted;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &old_encrypted);
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(old_encrypted));
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can still decrypt keystore key based
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encryption (due to extracting the keystore key from the encryption keybag).
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the the cryptographer does not have the new key.
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams new_key = {"localhost", "dummy", kNewKey};
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer new_cryptographer(GetCryptographer()->encryptor());
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.AddKey(new_key);
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData new_encrypted;
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_cryptographer.EncryptString("string", &new_encrypted);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetCryptographer()->CanDecryptUsingDefaultKey(new_encrypted));
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if a client without a keystore key (e.g. one without keystore
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption enabled) receives a migrated nigori in keystore passphrase state
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and then attempts to enable encrypt everything, we switch to a custom
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passphrase. The nigori should remain migrated.
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MigrateOnEncryptEverythingKeystorePassphrase) {
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_decryptor_token;
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(cur_key);
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams keystore_key = {"localhost", "dummy", kKeystoreKey};
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddNonDefaultKey(keystore_key);
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor(
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_cryptographer,
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKeystoreKey,
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &keystore_decryptor_token));
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a nigori node with the generated keystore decryptor token and
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialize the encryption handler with it. The cryptographer will have
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending keys until we provide the decryption passphrase.
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
181646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.mutable_keystore_decryptor_token()->CopyFrom(
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keystore_decryptor_token);
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseRequired(_, _));
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->has_pending_keys());
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseAccepted());
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kCurKey);
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnPassphraseTypeChanged(FROZEN_IMPLICIT_PASSPHRASE, _));
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, true));
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->EnableEncryptEverything();
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FROZEN_IMPLICIT_PASSPHRASE,
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            encryption_handler()->GetPassphraseType());
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled());
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, FROZEN_IMPLICIT_PASSPHRASE, kCurKey);
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer is encrypting using the frozen current key.
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData current_encrypted;
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.EncryptString("string", &current_encrypted);
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted));
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the cryptographer can still decrypt keystore key based
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encryption (due to extracting the keystore key from the encryption keybag).
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer keystore_cryptographer(GetCryptographer()->encryptor());
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.AddKey(keystore_key);
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData keystore_encrypted;
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_cryptographer.EncryptString("string", &keystore_encrypted);
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->CanDecrypt(keystore_encrypted));
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If we receive a nigori migrated and with a KEYSTORE_PASSPHRASE type, but
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using an old default key (i.e. old GAIA password), we should overwrite the
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nigori, updating the keybag and keystore decryptor.
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest,
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ReceiveMigratedNigoriWithOldPassphrase) {
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kOldKey[] = "old";
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCurKey[] = "cur";
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::EncryptedData encrypted;
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams old_key = {"localhost", "dummy", kOldKey};
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyParams cur_key = {"localhost", "dummy", kCurKey};
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(old_key);
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCryptographer()->AddKey(cur_key);
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cryptographer other_cryptographer(GetCryptographer()->encryptor());
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_cryptographer.AddKey(old_key);
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(other_cryptographer.is_ready());
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptedTypesChanged(_, false));
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnEncryptionComplete());
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  encryption_handler()->Init();
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*observer(),
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              kRawKeystoreKey),
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now build an old keystore passphrase nigori node.
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*observer(),
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteNode nigori_node(&trans);
193446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK);
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::NigoriSpecifics nigori;
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Cryptographer other_cryptographer(GetCryptographer()->encryptor());
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.AddKey(old_key);
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->GetKeystoreDecryptor(
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_cryptographer,
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kKeystoreKey,
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nigori.mutable_keystore_decryptor_token());
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    other_cryptographer.GetKeys(nigori.mutable_encryption_keybag());
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keybag_is_frozen(true);
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_encrypt_everything(false);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori.set_keystore_migration_time(1);
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(nigori, trans.GetWrappedTrans());
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nigori_node.SetNigoriSpecifics(nigori);
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PumpLoop();
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify we're still migrated and have proper encryption state.
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kCurKey);
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Trigger a key rotation upon receiving new keys if we already had a keystore
19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// migrated nigori with the gaia key as the default (still in backwards
19622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// compatible mode).
19632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefault) {
19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Destroy the existing nigori node so we init without a nigori node.
19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TearDown();
19662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_user_share_.SetUp();
19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpEncryption();
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kOldGaiaKey[] = "old_gaia_key";
19702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string old_keystore_key;
19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
19732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
19742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
19762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
19772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
19782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                kRawOldKeystoreKey),
19792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            trans.GetWrappedTrans());
19802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
19822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then init the nigori node with a backwards compatible set of keys.
19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateRootForType(NIGORI);
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key);
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now set some new keystore keys.
19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
19912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
20002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pump for any posted tasks.
20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify we're still migrated and have proper encryption state. We should
20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have rotated the keybag so that it's now encrypted with the newest keystore
20082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key (instead of the old gaia key).
20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
20102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Trigger a key rotation upon receiving new keys if we already had a keystore
20172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// migrated nigori with the keystore key as the default.
20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysKeystoreDefault) {
20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Destroy the existing nigori node so we init without a nigori node.
20202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TearDown();
20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_user_share_.SetUp();
20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpEncryption();
20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string old_keystore_key;
20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
20292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
20302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
20312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      encryption_handler()->SetKeystoreKeys(BuildEncryptionKeyProto(
20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                kRawOldKeystoreKey),
20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            trans.GetWrappedTrans());
20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
20362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
20372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then init the nigori node with a non-backwards compatible set of keys.
20392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateRootForType(NIGORI);
20402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
20412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitKeystoreMigratedNigori(1, old_keystore_key, old_keystore_key);
20422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now set some new keystore keys.
20442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber());
20452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnEncryptionComplete());
20462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
20472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
20482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
20502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
20512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
20522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
20532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
20542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
20552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pump for any posted tasks.
20572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
20582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
20592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify we're still migrated and have proper encryption state. We should
20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have rotated the keybag so that it's now encrypted with the newest keystore
20622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key (instead of the old gaia key).
20632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
20642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
20682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Trigger a key rotation upon when a pending gaia passphrase is resolved.
20712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysAfterPendingGaiaResolved) {
20722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kOldGaiaKey[] = "old_gaia_key";
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitUnmigratedNigori(kOldGaiaKey, IMPLICIT_PASSPHRASE);
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass multiple keystore keys, signaling a rotation has happened.
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
20822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
20832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
20852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
20862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
20872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
20882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
20912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Resolve the pending keys. This should trigger the key rotation.
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseAccepted());
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnEncryptionComplete()).Times(AtLeast(1));
21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kOldGaiaKey);
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// When signing in for the first time, make sure we can rotate keys if we
21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// already have a keystore migrated nigori.
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysGaiaDefaultOnInit) {
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Destroy the existing nigori node so we init without a nigori node.
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TearDown();
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_user_share_.SetUp();
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpEncryption();
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kOldGaiaKey[] = "old_gaia_key";
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string old_keystore_key;
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set two keys, signaling that a rotation has been performed. No nigori
21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // node is present yet, so we can't rotate.
21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then init the nigori node with an old set of keys.
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateRootForType(NIGORI);
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseAccepted());
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitKeystoreMigratedNigori(1, kOldGaiaKey, old_keystore_key);
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify we're still migrated and have proper encryption state. We should
21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // have rotated the keybag so that it's now encrypted with the newest keystore
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key (instead of the old gaia key).
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(GetCryptographer()->is_ready());
21482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(encryption_handler()->GetPassphraseType(), KEYSTORE_PASSPHRASE);
21492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(encryption_handler()->EncryptEverythingEnabled());
21502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
21512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Trigger a key rotation when a migrated nigori (with an old keystore key) is
21542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// applied.
21552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysWhenMigratedNigoriArrives) {
21562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kOldGaiaKey[] = "old_gaia_key";
21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
21582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string old_keystore_key;
21592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Base64Encode(kRawOldKeystoreKey, &old_keystore_key);
21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
21622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitUnmigratedNigori(kOldGaiaKey, IMPLICIT_PASSPHRASE);
21632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
21652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass multiple keystore keys, signaling a rotation has happened.
21662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
21672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
21692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
21712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
21732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
21742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now simulate downloading a nigori node that was migrated before the
21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // keys were rotated, and hence still encrypt with the old gaia key.
21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseAccepted());
21842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseTypeChanged(KEYSTORE_PASSPHRASE, _));
21862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
21882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnEncryptionComplete()).Times(AtLeast(1));
21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
21912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::NigoriSpecifics nigori = BuildMigratedNigori(
21922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        KEYSTORE_PASSPHRASE,
21932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1,
21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kOldGaiaKey,
21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        old_keystore_key);
21962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update the encryption handler.
21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WriteTransaction trans(FROM_HERE, user_share());
21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->ApplyNigoriUpdate(
21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        nigori,
22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        trans.GetWrappedTrans());
22012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(encryption_handler()->MigratedToKeystore());
22032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
22042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(encryption_handler()->MigratedToKeystore());
22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(KEYSTORE_PASSPHRASE, encryption_handler()->GetPassphraseType());
22072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(KEYSTORE_PASSPHRASE, kKeystoreKey);
22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verify that performing a migration while having more than one keystore key
22112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// preserves a custom passphrase.
22122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysUnmigratedCustomPassphrase) {
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kCustomPass[] = "custom_passphrase";
22142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
22152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(), OnPassphraseRequired(_, _));
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitUnmigratedNigori(kCustomPass, CUSTOM_PASSPHRASE);
22182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
22202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass multiple keystore keys, signaling a rotation has happened.
22212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
22222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
22232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
22242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
22252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
22262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
22272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
22282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
22292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
22312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
22322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pass the decryption passphrase. This will also trigger the migration,
22342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // but should not overwrite the default key.
22352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
22362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnCryptographerStateChanged(_)).Times(AnyNumber());
22372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
22382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnPassphraseAccepted());
22392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
22402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnEncryptedTypesChanged(_, true));
22412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
22422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnEncryptionComplete()).Times(AnyNumber());
22432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*observer(),
22442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN));
22452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  encryption_handler()->SetDecryptionPassphrase(kCustomPass);
22462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
22472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigori(CUSTOM_PASSPHRASE, kCustomPass);
22492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verify that a key rotation done after we've migrated a custom passphrase
22522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// nigori node preserves the custom passphrase.
22532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncEncryptionHandlerImplTest, RotateKeysMigratedCustomPassphrase) {
22542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kCustomPass[] = "custom_passphrase";
22552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kRawOldKeystoreKey[] = "old_keystore_key";
22562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  KeyParams custom_key = {"localhost", "dummy", kCustomPass};
22582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetCryptographer()->AddKey(custom_key);
22592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitCustomPassMigratedNigori(1, kCustomPass);
22612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCustomPass);
22622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
22642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass multiple keystore keys, signaling a rotation has happened.
22652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    google::protobuf::RepeatedPtrField<google::protobuf::string> keys;
22662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawOldKeystoreKey);
22672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keys.Add()->assign(kRawKeystoreKey);
22682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReadTransaction trans(FROM_HERE, user_share());
22692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
22702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnBootstrapTokenUpdated(_, KEYSTORE_BOOTSTRAP_TOKEN));
22712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*observer(),
22722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnCryptographerStateChanged(_)).Times(AnyNumber());
22732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    encryption_handler()->SetKeystoreKeys(keys,
22742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          trans.GetWrappedTrans());
22752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PumpLoop();
22772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(observer());
22782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyMigratedNigoriWithTimestamp(1, CUSTOM_PASSPHRASE, kCustomPass);
22802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
2283