diff options
Diffstat (limited to 'sync')
26 files changed, 237 insertions, 197 deletions
diff --git a/sync/engine/download_updates_command.cc b/sync/engine/download_updates_command.cc index fea8f88..e1ba189 100644 --- a/sync/engine/download_updates_command.cc +++ b/sync/engine/download_updates_command.cc @@ -11,8 +11,8 @@ #include "sync/engine/syncer_proto_util.h" #include "sync/internal_api/public/base/model_type_state_map.h" #include "sync/syncable/directory.h" +#include "sync/syncable/nigori_handler.h" #include "sync/syncable/read_transaction.h" -#include "sync/util/cryptographer.h" using sync_pb::DebugInfo; @@ -38,13 +38,14 @@ SyncerError HandleGetEncryptionKeyResponse( return SERVER_RESPONSE_VALIDATION_FAILED; } syncable::ReadTransaction trans(FROM_HERE, dir); - Cryptographer* cryptographer = dir->GetCryptographer(&trans); - success = cryptographer->SetKeystoreKey( - update_response.get_updates().encryption_key()); + syncable::NigoriHandler* nigori_handler = dir->GetNigoriHandler(); + success = nigori_handler->SetKeystoreKey( + update_response.get_updates().encryption_key(), + &trans); DVLOG(1) << "GetUpdates returned encryption key of length " << update_response.get_updates().encryption_key().length() - << ". Cryptographer keystore key " + << ". Nigori keystore key " << (success ? "" : "not ") << "updated."; return (success ? SYNCER_OK : SERVER_RESPONSE_VALIDATION_FAILED); } @@ -91,9 +92,8 @@ SyncerError DownloadUpdatesCommand::ExecuteImpl(SyncSession* session) { if (session->context()->keystore_encryption_enabled()) { syncable::Directory* dir = session->context()->directory(); syncable::ReadTransaction trans(FROM_HERE, dir); - Cryptographer* cryptographer = - session->context()->directory()->GetCryptographer(&trans); - need_encryption_key = !cryptographer->HasKeystoreKey(); + syncable::NigoriHandler* nigori_handler = dir->GetNigoriHandler(); + need_encryption_key = nigori_handler->NeedKeystoreKey(&trans); get_updates->set_need_encryption_key(need_encryption_key); } diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc index df587a7..34ed1fd 100644 --- a/sync/engine/syncer_unittest.cc +++ b/sync/engine/syncer_unittest.cc @@ -4094,7 +4094,7 @@ TEST_F(SyncerTest, ConfigureFailsDontApplyUpdates) { TEST_F(SyncerTest, GetKeySuccess) { { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - EXPECT_FALSE(GetCryptographer(&rtrans)->HasKeystoreKey()); + EXPECT_TRUE(directory()->GetNigoriHandler()->NeedKeystoreKey(&rtrans)); } SyncShareConfigure(); @@ -4102,14 +4102,14 @@ TEST_F(SyncerTest, GetKeySuccess) { EXPECT_EQ(session_->status_controller().last_get_key_result(), SYNCER_OK); { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - EXPECT_TRUE(GetCryptographer(&rtrans)->HasKeystoreKey()); + EXPECT_FALSE(directory()->GetNigoriHandler()->NeedKeystoreKey(&rtrans)); } } TEST_F(SyncerTest, GetKeyEmpty) { { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - EXPECT_FALSE(GetCryptographer(&rtrans)->HasKeystoreKey()); + EXPECT_TRUE(directory()->GetNigoriHandler()->NeedKeystoreKey(&rtrans)); } mock_server_->SetKeystoreKey(""); @@ -4118,7 +4118,7 @@ TEST_F(SyncerTest, GetKeyEmpty) { EXPECT_NE(session_->status_controller().last_get_key_result(), SYNCER_OK); { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - EXPECT_FALSE(GetCryptographer(&rtrans)->HasKeystoreKey()); + EXPECT_TRUE(directory()->GetNigoriHandler()->NeedKeystoreKey(&rtrans)); } } diff --git a/sync/internal_api/debug_info_event_listener.cc b/sync/internal_api/debug_info_event_listener.cc index f59a2fa..9ca4973 100644 --- a/sync/internal_api/debug_info_event_listener.cc +++ b/sync/internal_api/debug_info_event_listener.cc @@ -68,8 +68,13 @@ void DebugInfoEventListener::OnPassphraseAccepted() { } void DebugInfoEventListener::OnBootstrapTokenUpdated( - const std::string& bootstrap_token) { - CreateAndAddEvent(sync_pb::DebugEventInfo::BOOTSTRAP_TOKEN_UPDATED); + const std::string& bootstrap_token, BootstrapTokenType type) { + if (type == PASSPHRASE_BOOTSTRAP_TOKEN) { + CreateAndAddEvent(sync_pb::DebugEventInfo::BOOTSTRAP_TOKEN_UPDATED); + return; + } + DCHECK_EQ(type, KEYSTORE_BOOTSTRAP_TOKEN); + CreateAndAddEvent(sync_pb::DebugEventInfo::KEYSTORE_TOKEN_UPDATED); } void DebugInfoEventListener::OnStopSyncingPermanently() { diff --git a/sync/internal_api/debug_info_event_listener.h b/sync/internal_api/debug_info_event_listener.h index b4ace66..bf99925 100644 --- a/sync/internal_api/debug_info_event_listener.h +++ b/sync/internal_api/debug_info_event_listener.h @@ -50,7 +50,8 @@ class DebugInfoEventListener : public SyncManager::Observer, const sync_pb::EncryptedData& pending_keys) OVERRIDE; virtual void OnPassphraseAccepted() OVERRIDE; virtual void OnBootstrapTokenUpdated( - const std::string& bootstrap_token) OVERRIDE; + const std::string& bootstrap_token, + BootstrapTokenType type) OVERRIDE; virtual void OnEncryptedTypesChanged( ModelTypeSet encrypted_types, bool encrypt_everything) OVERRIDE; diff --git a/sync/internal_api/js_sync_encryption_handler_observer.cc b/sync/internal_api/js_sync_encryption_handler_observer.cc index 2db5475..88c59dd 100644 --- a/sync/internal_api/js_sync_encryption_handler_observer.cc +++ b/sync/internal_api/js_sync_encryption_handler_observer.cc @@ -49,13 +49,15 @@ void JsSyncEncryptionHandlerObserver::OnPassphraseAccepted() { } void JsSyncEncryptionHandlerObserver::OnBootstrapTokenUpdated( - const std::string& boostrap_token) { + const std::string& boostrap_token, + BootstrapTokenType type) { if (!event_handler_.IsInitialized()) { return; } DictionaryValue details; details.SetString("bootstrapToken", "<redacted>"); - HandleJsEvent(FROM_HERE, "OnBootstrapTokenUpdated", JsEventDetails(&details)); + details.SetString("type", BootstrapTokenTypeToString(type)); + HandleJsEvent(FROM_HERE, "onBootstrapTokenUpdated", JsEventDetails(&details)); } void JsSyncEncryptionHandlerObserver::OnEncryptedTypesChanged( diff --git a/sync/internal_api/js_sync_encryption_handler_observer.h b/sync/internal_api/js_sync_encryption_handler_observer.h index 6099517..9fe458e 100644 --- a/sync/internal_api/js_sync_encryption_handler_observer.h +++ b/sync/internal_api/js_sync_encryption_handler_observer.h @@ -36,7 +36,8 @@ class JsSyncEncryptionHandlerObserver : public SyncEncryptionHandler::Observer { const sync_pb::EncryptedData& pending_keys) OVERRIDE; virtual void OnPassphraseAccepted() OVERRIDE; virtual void OnBootstrapTokenUpdated( - const std::string& bootstrap_token) OVERRIDE; + const std::string& bootstrap_token, + BootstrapTokenType type) OVERRIDE; virtual void OnEncryptedTypesChanged( ModelTypeSet encrypted_types, bool encrypt_everything) OVERRIDE; diff --git a/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc b/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc index d42f0e5..719744c 100644 --- a/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc +++ b/sync/internal_api/js_sync_encryption_handler_observer_unittest.cc @@ -93,19 +93,18 @@ TEST_F(JsSyncEncryptionHandlerObserverTest, OnPassphraseRequired) { PumpLoop(); } -TEST_F(JsSyncEncryptionHandlerObserverTest, SensitiveNotifiations) { - DictionaryValue redacted_token_details; - redacted_token_details.SetString("token", "<redacted>"); - DictionaryValue redacted_bootstrap_token_details; - redacted_bootstrap_token_details.SetString("bootstrapToken", "<redacted>"); +TEST_F(JsSyncEncryptionHandlerObserverTest, OnBootstrapTokenUpdated) { + DictionaryValue bootstrap_token_details; + bootstrap_token_details.SetString("bootstrapToken", "<redacted>"); + bootstrap_token_details.SetString("type", "PASSPHRASE_BOOTSTRAP_TOKEN"); EXPECT_CALL(mock_js_event_handler_, HandleJsEvent( - "OnBootstrapTokenUpdated", - HasDetailsAsDictionary(redacted_bootstrap_token_details))); + "onBootstrapTokenUpdated", + HasDetailsAsDictionary(bootstrap_token_details))); js_sync_encryption_handler_observer_.OnBootstrapTokenUpdated( - "sensitive_token"); + "sensitive_token", PASSPHRASE_BOOTSTRAP_TOKEN); PumpLoop(); } diff --git a/sync/internal_api/public/sync_encryption_handler.h b/sync/internal_api/public/sync_encryption_handler.h index eefffdf..88ec7a2 100644 --- a/sync/internal_api/public/sync_encryption_handler.h +++ b/sync/internal_api/public/sync_encryption_handler.h @@ -38,6 +38,12 @@ enum PassphraseState { CUSTOM_PASSPHRASE = 3, // User-provided passphrase. }; +// Enum used to distinguish which bootstrap encryption token is being updated. +enum BootstrapTokenType { + PASSPHRASE_BOOTSTRAP_TOKEN, + KEYSTORE_BOOTSTRAP_TOKEN +}; + // Sync's encryption handler. Handles tracking encrypted types, ensuring the // cryptographer encrypts with the proper key and has the most recent keybag, // and keeps the nigori node up to date. @@ -77,7 +83,8 @@ class SyncEncryptionHandler { // with explicit passphrases, it will be the most recently seen custom // passphrase. virtual void OnBootstrapTokenUpdated( - const std::string& bootstrap_token) = 0; + const std::string& bootstrap_token, + BootstrapTokenType type) = 0; // Called when the set of encrypted types or the encrypt // everything flag has been changed. Note that encryption isn't diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index dfd3cb3..3a87440 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -387,10 +387,6 @@ class SyncManager { // Status-related getter. May be called on any thread. virtual SyncStatus GetDetailedStatus() const = 0; - // Extracts the keystore encryption bootstrap token if a keystore key existed. - // Returns true if bootstrap token successfully extracted, false otherwise. - virtual bool GetKeystoreKeyBootstrapToken(std::string* token) = 0; - // Call periodically from a database-safe thread to persist recent changes // to the syncapi model. virtual void SaveChanges() = 0; diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h index 9661659..939435c 100644 --- a/sync/internal_api/public/test/fake_sync_manager.h +++ b/sync/internal_api/public/test/fake_sync_manager.h @@ -114,7 +114,6 @@ class FakeSyncManager : public SyncManager { virtual void AddObserver(Observer* observer) OVERRIDE; virtual void RemoveObserver(Observer* observer) OVERRIDE; virtual SyncStatus GetDetailedStatus() const OVERRIDE; - virtual bool GetKeystoreKeyBootstrapToken(std::string* token) OVERRIDE; virtual void SaveChanges() OVERRIDE; virtual void StopSyncingForShutdown(const base::Closure& callback) OVERRIDE; virtual void ShutdownOnSyncThread() OVERRIDE; diff --git a/sync/internal_api/public/util/sync_string_conversions.cc b/sync/internal_api/public/util/sync_string_conversions.cc index 7e404b7..fec2720 100644 --- a/sync/internal_api/public/util/sync_string_conversions.cc +++ b/sync/internal_api/public/util/sync_string_conversions.cc @@ -44,4 +44,14 @@ const char* PassphraseStateToString(PassphraseState state) { } } +const char* BootstrapTokenTypeToString(BootstrapTokenType type) { + switch (type) { + ENUM_CASE(PASSPHRASE_BOOTSTRAP_TOKEN); + ENUM_CASE(KEYSTORE_BOOTSTRAP_TOKEN); + default: + NOTREACHED(); + return "INVALID_BOOTSTRAP_TOKEN_TYPE"; + } +} + } // namespace syncer diff --git a/sync/internal_api/public/util/sync_string_conversions.h b/sync/internal_api/public/util/sync_string_conversions.h index 9430e38..81a0b4b 100644 --- a/sync/internal_api/public/util/sync_string_conversions.h +++ b/sync/internal_api/public/util/sync_string_conversions.h @@ -17,6 +17,8 @@ const char* PassphraseRequiredReasonToString( PassphraseRequiredReason reason); const char* PassphraseStateToString(PassphraseState state); + +const char* BootstrapTokenTypeToString(BootstrapTokenType type); } #endif // SYNC_INTERNAL_API_PUBLIC_UTIL_SYNC_STRING_CONVERSIONS_H_ diff --git a/sync/internal_api/sync_encryption_handler_impl.cc b/sync/internal_api/sync_encryption_handler_impl.cc index c632ba57..82149b1 100644 --- a/sync/internal_api/sync_encryption_handler_impl.cc +++ b/sync/internal_api/sync_encryption_handler_impl.cc @@ -49,13 +49,19 @@ SyncEncryptionHandlerImpl::Vault::~Vault() { SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( UserShare* user_share, - Encryptor* encryptor) + Encryptor* encryptor, + const std::string& restored_key_for_bootstrapping, + const std::string& restored_keystore_key_for_bootstrapping) : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), user_share_(user_share), vault_unsafe_(encryptor, SensitiveTypes()), encrypt_everything_(false), passphrase_state_(IMPLICIT_PASSPHRASE), + keystore_key_(restored_keystore_key_for_bootstrapping), nigori_overwrite_count_(0) { + // We only bootstrap the user provided passphrase. The keystore key is handled + // at Init time once we're sure the nigori is downloaded. + vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); } SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} @@ -424,6 +430,27 @@ void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes( nigori); } +bool SyncEncryptionHandlerImpl::NeedKeystoreKey( + syncable::BaseTransaction* const trans) const { + return keystore_key_.empty(); +} + +bool SyncEncryptionHandlerImpl::SetKeystoreKey( + const std::string& key, + syncable::BaseTransaction* const trans) { + if (!keystore_key_.empty() || key.empty()) + return false; + keystore_key_ = key; + + // TODO(zea): trigger migration if necessary. + + DVLOG(1) << "Keystore bootstrap token updated."; + FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, + OnBootstrapTokenUpdated(key, + KEYSTORE_BOOTSTRAP_TOKEN)); + return true; +} + ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes( syncable::BaseTransaction* const trans) const { return UnlockVault(trans).encrypted_types; @@ -688,7 +715,8 @@ void SyncEncryptionHandlerImpl::FinishSetPassphrase( if (!bootstrap_token.empty()) { DVLOG(1) << "Passphrase bootstrap token updated."; FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, - OnBootstrapTokenUpdated(bootstrap_token)); + OnBootstrapTokenUpdated(bootstrap_token, + PASSPHRASE_BOOTSTRAP_TOKEN)); } const Cryptographer& cryptographer = @@ -711,6 +739,8 @@ void SyncEncryptionHandlerImpl::FinishSetPassphrase( DCHECK(cryptographer.is_ready()); + // TODO(zea): trigger migration if necessary. + sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics()); // Does not modify specifics.encrypted() if the original decrypted data was // the same. diff --git a/sync/internal_api/sync_encryption_handler_impl.h b/sync/internal_api/sync_encryption_handler_impl.h index 8f3b7ac..1b0b648 100644 --- a/sync/internal_api/sync_encryption_handler_impl.h +++ b/sync/internal_api/sync_encryption_handler_impl.h @@ -44,8 +44,11 @@ class SyncEncryptionHandlerImpl : public SyncEncryptionHandler, public syncable::NigoriHandler { public: - SyncEncryptionHandlerImpl(UserShare* user_share, - Encryptor* encryptor); + SyncEncryptionHandlerImpl( + UserShare* user_share, + Encryptor* encryptor, + const std::string& restored_key_for_bootstrapping, + const std::string& restored_keystore_key_for_bootstrapping); virtual ~SyncEncryptionHandlerImpl(); // SyncEncryptionHandler implementation. @@ -67,6 +70,11 @@ class SyncEncryptionHandlerImpl virtual void UpdateNigoriFromEncryptedTypes( sync_pb::NigoriSpecifics* nigori, syncable::BaseTransaction* const trans) const OVERRIDE; + virtual bool NeedKeystoreKey( + syncable::BaseTransaction* const trans) const OVERRIDE; + virtual bool SetKeystoreKey( + const std::string& key, + syncable::BaseTransaction* const trans) OVERRIDE; // Can be called from any thread. virtual ModelTypeSet GetEncryptedTypes( syncable::BaseTransaction* const trans) const OVERRIDE; @@ -182,6 +190,9 @@ class SyncEncryptionHandlerImpl // keys stored in the nigori node. PassphraseState passphrase_state_; + // The keystore key provided by the server. + std::string keystore_key_; + // The number of times we've automatically (i.e. not via SetPassphrase or // conflict resolver) updated the nigori's encryption keys in this chrome // instantiation. diff --git a/sync/internal_api/sync_encryption_handler_impl_unittest.cc b/sync/internal_api/sync_encryption_handler_impl_unittest.cc index c6ea24f..f1472c2 100644 --- a/sync/internal_api/sync_encryption_handler_impl_unittest.cc +++ b/sync/internal_api/sync_encryption_handler_impl_unittest.cc @@ -40,7 +40,8 @@ class SyncEncryptionHandlerObserverMock void(PassphraseRequiredReason, const sync_pb::EncryptedData&)); // NOLINT MOCK_METHOD0(OnPassphraseAccepted, void()); // NOLINT - MOCK_METHOD1(OnBootstrapTokenUpdated, void(const std::string&)); // NOLINT + MOCK_METHOD2(OnBootstrapTokenUpdated, + void(const std::string&, BootstrapTokenType type)); // NOLINT MOCK_METHOD2(OnEncryptedTypesChanged, void(ModelTypeSet, bool)); // NOLINT MOCK_METHOD0(OnEncryptionComplete, void()); // NOLINT @@ -67,10 +68,10 @@ class SyncEncryptionHandlerImplTest : public ::testing::Test { protected: void SetUpEncryption() { - ReadTransaction trans(FROM_HERE, user_share()); encryption_handler_.reset( new SyncEncryptionHandlerImpl(user_share(), - &encryptor_)); + &encryptor_, + "", "" /* bootstrap tokens */)); encryption_handler_->AddObserver(&observer_); } @@ -128,7 +129,8 @@ TEST_F(SyncEncryptionHandlerImplTest, NigoriEncryptionTypes) { StrictMock<SyncEncryptionHandlerObserverMock> observer2; SyncEncryptionHandlerImpl handler2(user_share(), - &encryptor_); + &encryptor_, + "", "" /* bootstrap tokens */); handler2.AddObserver(&observer2); // Just set the sensitive types (shouldn't trigger any notifications). @@ -414,4 +416,25 @@ TEST_F(SyncEncryptionHandlerImplTest, ReceiveOldNigori) { EXPECT_TRUE(encryption_handler()->EncryptEverythingEnabled()); } +// Ensure setting the keystore key works, updates the bootstrap token, and +// doesn't modify the cryptographer. +TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreUpdatedBoostrapToken) { + WriteTransaction trans(FROM_HERE, user_share()); + EXPECT_CALL(*observer(), OnBootstrapTokenUpdated(_, _)).Times(0); + EXPECT_FALSE(GetCryptographer()->is_initialized()); + EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); + EXPECT_FALSE(encryption_handler()->SetKeystoreKey("", + trans.GetWrappedTrans())); + EXPECT_TRUE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); + Mock::VerifyAndClearExpectations(observer()); + + const char kValidKey[] = "keystore_key"; + EXPECT_CALL(*observer(), + OnBootstrapTokenUpdated(kValidKey, KEYSTORE_BOOTSTRAP_TOKEN)); + EXPECT_TRUE(encryption_handler()->SetKeystoreKey(kValidKey, + trans.GetWrappedTrans())); + EXPECT_FALSE(encryption_handler()->NeedKeystoreKey(trans.GetWrappedTrans())); + EXPECT_FALSE(GetCryptographer()->is_initialized()); +} + } // namespace syncer diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 13f2ae4..a0fa57c 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -385,7 +385,9 @@ void SyncManagerImpl::Init( sync_encryption_handler_.reset(new SyncEncryptionHandlerImpl( &share_, - encryptor)); + encryptor, + restored_key_for_bootstrapping, + restored_keystore_key_for_bootstrapping)); sync_encryption_handler_->AddObserver(this); sync_encryption_handler_->AddObserver(&debug_info_event_listener_); sync_encryption_handler_->AddObserver(&js_sync_encryption_handler_observer_); @@ -465,15 +467,6 @@ void SyncManagerImpl::Init( UpdateCredentials(credentials); - // Cryptographer should only be accessed while holding a - // transaction. Grabbing the user share for the transaction - // checks the initialization state, so this must come after - // |initialized_| is set to true. - ReadTransaction trans(FROM_HERE, GetUserShare()); - trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping); - trans.GetCryptographer()->BootstrapKeystoreKey( - restored_keystore_key_for_bootstrapping); - FOR_EACH_OBSERVER(SyncManager::Observer, observers_, OnInitializationComplete( MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), @@ -539,7 +532,8 @@ void SyncManagerImpl::OnPassphraseAccepted() { } void SyncManagerImpl::OnBootstrapTokenUpdated( - const std::string& bootstrap_token) { + const std::string& bootstrap_token, + BootstrapTokenType type) { // Does nothing. } @@ -688,11 +682,6 @@ void SyncManagerImpl::UnregisterInvalidationHandler( invalidator_->UnregisterHandler(handler); } -bool SyncManagerImpl::GetKeystoreKeyBootstrapToken(std::string* token) { - ReadTransaction trans(FROM_HERE, GetUserShare()); - return trans.GetCryptographer()->GetKeystoreKeyBootstrapToken(token); -} - void SyncManagerImpl::AddObserver(SyncManager::Observer* observer) { DCHECK(thread_checker_.CalledOnValidThread()); observers_.AddObserver(observer); diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h index 7fa917e7..90b5753 100644 --- a/sync/internal_api/sync_manager_impl.h +++ b/sync/internal_api/sync_manager_impl.h @@ -106,7 +106,6 @@ class SyncManagerImpl : public SyncManager, virtual void AddObserver(SyncManager::Observer* observer) OVERRIDE; virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE; virtual SyncStatus GetDetailedStatus() const OVERRIDE; - virtual bool GetKeystoreKeyBootstrapToken(std::string* token) OVERRIDE; virtual void SaveChanges() OVERRIDE; virtual void StopSyncingForShutdown(const base::Closure& callback) OVERRIDE; virtual void ShutdownOnSyncThread() OVERRIDE; @@ -121,7 +120,8 @@ class SyncManagerImpl : public SyncManager, const sync_pb::EncryptedData& pending_keys) OVERRIDE; virtual void OnPassphraseAccepted() OVERRIDE; virtual void OnBootstrapTokenUpdated( - const std::string& bootstrap_token) OVERRIDE; + const std::string& bootstrap_token, + BootstrapTokenType type) OVERRIDE; virtual void OnEncryptedTypesChanged( ModelTypeSet encrypted_types, bool encrypt_everything) OVERRIDE; diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc index 2d133a1..ec08939 100644 --- a/sync/internal_api/sync_manager_impl_unittest.cc +++ b/sync/internal_api/sync_manager_impl_unittest.cc @@ -693,7 +693,8 @@ class SyncEncryptionHandlerObserverMock void(PassphraseRequiredReason, const sync_pb::EncryptedData&)); // NOLINT MOCK_METHOD0(OnPassphraseAccepted, void()); // NOLINT - MOCK_METHOD1(OnBootstrapTokenUpdated, void(const std::string&)); // NOLINT + MOCK_METHOD2(OnBootstrapTokenUpdated, + void(const std::string&, BootstrapTokenType type)); // NOLINT MOCK_METHOD2(OnEncryptedTypesChanged, void(ModelTypeSet, bool)); // NOLINT MOCK_METHOD0(OnEncryptionComplete, void()); // NOLINT @@ -1501,7 +1502,8 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithData) { // Trigger's a ReEncryptEverything with new passphrase. testing::Mock::VerifyAndClearExpectations(&encryption_observer_); - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1529,7 +1531,8 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithData) { // Calling EncryptDataTypes with an empty encrypted types should not trigger // a reencryption and should just notify immediately. testing::Mock::VerifyAndClearExpectations(&encryption_observer_); - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)).Times(0); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)).Times(0); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()).Times(0); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()).Times(0); sync_manager_.GetEncryptionHandler()->EnableEncryptEverything(); @@ -1540,7 +1543,8 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithData) { // (case 1 in SyncManager::SyncInternal::SetEncryptionPassphrase) TEST_F(SyncManagerTest, SetInitialGaiaPass) { EXPECT_FALSE(SetUpEncryption(DONT_WRITE_NIGORI, UNINITIALIZED)); - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1574,7 +1578,8 @@ TEST_F(SyncManagerTest, UpdateGaiaPass) { cryptographer->GetBootstrapToken(&bootstrap_token); verifier.Bootstrap(bootstrap_token); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1621,7 +1626,8 @@ TEST_F(SyncManagerTest, SetPassphraseWithPassword) { data.set_password_value("secret"); password_node.SetPasswordSpecifics(data); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1678,7 +1684,8 @@ TEST_F(SyncManagerTest, SupplyPendingGAIAPass) { EXPECT_TRUE(cryptographer->has_pending_keys()); node.SetNigoriSpecifics(nigori); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1732,7 +1739,8 @@ TEST_F(SyncManagerTest, SupplyPendingOldGAIAPass) { // The bootstrap token should have been updated. Save it to ensure it's based // on the new GAIA password. std::string bootstrap_token; - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)) + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)) .WillOnce(SaveArg<0>(&bootstrap_token)); EXPECT_CALL(encryption_observer_, OnPassphraseRequired(_,_)); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1754,7 +1762,8 @@ TEST_F(SyncManagerTest, SupplyPendingOldGAIAPass) { other_cryptographer.GetKeys(&encrypted); EXPECT_TRUE(cryptographer->CanDecrypt(encrypted)); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1807,7 +1816,8 @@ TEST_F(SyncManagerTest, SupplyPendingExplicitPass) { nigori.set_using_explicit_passphrase(true); node.SetNigoriSpecifics(nigori); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1850,7 +1860,8 @@ TEST_F(SyncManagerTest, SupplyPendingGAIAPassUserProvided) { cryptographer->SetPendingKeys(nigori.encrypted()); EXPECT_FALSE(cryptographer->is_ready()); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -1882,7 +1893,8 @@ TEST_F(SyncManagerTest, SetPassphraseWithEmptyPasswordNode) { EXPECT_EQ(WriteNode::INIT_SUCCESS, result); node_id = password_node.GetId(); } - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -2108,7 +2120,8 @@ TEST_F(SyncManagerTest, UpdateEntryWithEncryption) { // Set a new passphrase. Should set is_unsynced. testing::Mock::VerifyAndClearExpectations(&encryption_observer_); - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); @@ -2306,7 +2319,8 @@ TEST_F(SyncManagerTest, UpdatePasswordNewPassphrase) { // Set a new passphrase. Should set is_unsynced. testing::Mock::VerifyAndClearExpectations(&encryption_observer_); - EXPECT_CALL(encryption_observer_, OnBootstrapTokenUpdated(_)); + EXPECT_CALL(encryption_observer_, + OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(encryption_observer_, OnPassphraseAccepted()); EXPECT_CALL(encryption_observer_, OnEncryptionComplete()); EXPECT_CALL(encryption_observer_, OnCryptographerStateChanged(_)); diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc index 299bb41..b0b43cb 100644 --- a/sync/internal_api/test/fake_sync_manager.cc +++ b/sync/internal_api/test/fake_sync_manager.cc @@ -229,10 +229,6 @@ SyncStatus FakeSyncManager::GetDetailedStatus() const { return SyncStatus(); } -bool FakeSyncManager::GetKeystoreKeyBootstrapToken(std::string* token) { - return false; -} - void FakeSyncManager::SaveChanges() { // Do nothing. } diff --git a/sync/protocol/client_debug_info.proto b/sync/protocol/client_debug_info.proto index ceaf023..9792aaa 100644 --- a/sync/protocol/client_debug_info.proto +++ b/sync/protocol/client_debug_info.proto @@ -63,6 +63,8 @@ message DebugEventInfo { BOOTSTRAP_TOKEN_UPDATED = 9; // A new cryptographer bootstrap token was // generated. PASSPHRASE_STATE_CHANGED = 10; // The encryption passphrase state changed. + KEYSTORE_TOKEN_UPDATED = 11; // A new keystore encryption token was + // persisted. } // In a given |DebugEventInfo| only one of the following would be set. optional EventType type = 1; diff --git a/sync/syncable/nigori_handler.h b/sync/syncable/nigori_handler.h index 9ea1b0e..c47efa9 100644 --- a/sync/syncable/nigori_handler.h +++ b/sync/syncable/nigori_handler.h @@ -35,6 +35,16 @@ class NigoriHandler { sync_pb::NigoriSpecifics* nigori, syncable::BaseTransaction* const trans) const = 0; + // Whether a keystore key needs to be requested from the sync server. + virtual bool NeedKeystoreKey( + syncable::BaseTransaction* const trans) const = 0; + + // Set the keystore key the server returned for this account. + // Returns true on success, false otherwise. + virtual bool SetKeystoreKey( + const std::string& key, + syncable::BaseTransaction* const trans) = 0; + // Returns the set of currently encrypted types. virtual ModelTypeSet GetEncryptedTypes( syncable::BaseTransaction* const trans) const = 0; diff --git a/sync/test/fake_sync_encryption_handler.cc b/sync/test/fake_sync_encryption_handler.cc index fd41a5c..1dbdf8b 100644 --- a/sync/test/fake_sync_encryption_handler.cc +++ b/sync/test/fake_sync_encryption_handler.cc @@ -57,6 +57,25 @@ void FakeSyncEncryptionHandler::UpdateNigoriFromEncryptedTypes( nigori); } +bool FakeSyncEncryptionHandler::NeedKeystoreKey( + syncable::BaseTransaction* const trans) const { + return keystore_key_.empty(); +} + +bool FakeSyncEncryptionHandler::SetKeystoreKey( + const std::string& key, + syncable::BaseTransaction* const trans) { + if (!keystore_key_.empty() || key.empty()) + return false; + keystore_key_ = key; + + DVLOG(1) << "Keystore bootstrap token updated."; + FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, + OnBootstrapTokenUpdated(key, + KEYSTORE_BOOTSTRAP_TOKEN)); + return true; +} + ModelTypeSet FakeSyncEncryptionHandler::GetEncryptedTypes( syncable::BaseTransaction* const trans) const { return encrypted_types_; diff --git a/sync/test/fake_sync_encryption_handler.h b/sync/test/fake_sync_encryption_handler.h index 7899854..082f607 100644 --- a/sync/test/fake_sync_encryption_handler.h +++ b/sync/test/fake_sync_encryption_handler.h @@ -46,6 +46,11 @@ class FakeSyncEncryptionHandler : public SyncEncryptionHandler, virtual void UpdateNigoriFromEncryptedTypes( sync_pb::NigoriSpecifics* nigori, syncable::BaseTransaction* const trans) const OVERRIDE; + virtual bool NeedKeystoreKey( + syncable::BaseTransaction* const trans) const OVERRIDE; + virtual bool SetKeystoreKey( + const std::string& key, + syncable::BaseTransaction* const trans) OVERRIDE; virtual ModelTypeSet GetEncryptedTypes( syncable::BaseTransaction* const trans) const OVERRIDE; @@ -59,6 +64,7 @@ class FakeSyncEncryptionHandler : public SyncEncryptionHandler, FakeEncryptor encryptor_; Cryptographer cryptographer_; + std::string keystore_key_; }; } // namespace syncer diff --git a/sync/util/cryptographer.cc b/sync/util/cryptographer.cc index 92f9795..202480d 100644 --- a/sync/util/cryptographer.cc +++ b/sync/util/cryptographer.cc @@ -22,9 +22,7 @@ const char kNigoriTag[] = "google_chrome_nigori"; const char kNigoriKeyName[] = "nigori-key"; Cryptographer::Cryptographer(Encryptor* encryptor) - : encryptor_(encryptor), - default_nigori_(NULL), - keystore_nigori_(NULL) { + : encryptor_(encryptor) { DCHECK(encryptor); } @@ -39,19 +37,7 @@ void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) { scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); if (nigori.get()) - AddKeyImpl(nigori.release(), false); -} - -void Cryptographer::BootstrapKeystoreKey( - const std::string& restored_bootstrap_token) { - if (keystore_nigori_) { - NOTREACHED(); - return; - } - - scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); - if (nigori.get()) - AddKeyImpl(nigori.release(), true); + AddKeyImpl(nigori.Pass()); } bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const { @@ -60,17 +46,24 @@ bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const { bool Cryptographer::CanDecryptUsingDefaultKey( const sync_pb::EncryptedData& data) const { - return default_nigori_ && (data.key_name() == default_nigori_->first); + return !default_nigori_name_.empty() && + data.key_name() == default_nigori_name_; } bool Cryptographer::Encrypt( const ::google::protobuf::MessageLite& message, sync_pb::EncryptedData* encrypted) const { DCHECK(encrypted); - if (!default_nigori_) { + if (default_nigori_name_.empty()) { LOG(ERROR) << "Cryptographer not ready, failed to encrypt."; return false; } + NigoriMap::const_iterator default_nigori = + nigoris_.find(default_nigori_name_); + if (default_nigori == nigoris_.end()) { + LOG(ERROR) << "Corrupt default key."; + return false; + } std::string serialized; if (!message.SerializeToString(&serialized)) { @@ -86,9 +79,9 @@ bool Cryptographer::Encrypt( } } - encrypted->set_key_name(default_nigori_->first); - if (!default_nigori_->second->Encrypt(serialized, - encrypted->mutable_blob())) { + encrypted->set_key_name(default_nigori_name_); + if (!default_nigori->second->Encrypt(serialized, + encrypted->mutable_blob())) { LOG(ERROR) << "Failed to encrypt data."; return false; } @@ -147,7 +140,7 @@ bool Cryptographer::AddKey(const KeyParams& params) { NOTREACHED(); // Invalid username or password. return false; } - return AddKeyImpl(nigori.release(), false); + return AddKeyImpl(nigori.Pass()); } bool Cryptographer::AddKeyFromBootstrapToken( @@ -156,22 +149,17 @@ bool Cryptographer::AddKeyFromBootstrapToken( scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); if (!nigori.get()) return false; - return AddKeyImpl(nigori.release(), false); + return AddKeyImpl(nigori.Pass()); } -bool Cryptographer::AddKeyImpl(Nigori* initialized_nigori, - bool is_keystore_key) { - scoped_ptr<Nigori> nigori(initialized_nigori); +bool Cryptographer::AddKeyImpl(scoped_ptr<Nigori> initialized_nigori) { std::string name; - if (!nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) { + if (!initialized_nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) { NOTREACHED(); return false; } - nigoris_[name] = make_linked_ptr(nigori.release()); - if (is_keystore_key) - keystore_nigori_ = &*nigoris_.find(name); - else - default_nigori_ = &*nigoris_.find(name); + nigoris_[name] = make_linked_ptr(initialized_nigori.release()); + default_nigori_name_ = name; return true; } @@ -186,7 +174,7 @@ void Cryptographer::InstallKeys(const sync_pb::EncryptedData& encrypted) { void Cryptographer::SetDefaultKey(const std::string& key_name) { DCHECK(nigoris_.end() != nigoris_.find(key_name)); - default_nigori_ = &*nigoris_.find(key_name); + default_nigori_name_ = key_name; } void Cryptographer::SetPendingKeys(const sync_pb::EncryptedData& encrypted) { @@ -220,8 +208,7 @@ bool Cryptographer::DecryptPendingKeys(const KeyParams& params) { } InstallKeyBag(bag); const std::string& new_default_key_name = pending_keys_->key_name(); - DCHECK(nigoris_.end() != nigoris_.find(new_default_key_name)); - default_nigori_ = &*nigoris_.find(new_default_key_name); + SetDefaultKey(new_default_key_name); pending_keys_.reset(); return true; } @@ -231,16 +218,11 @@ bool Cryptographer::GetBootstrapToken(std::string* token) const { if (!is_initialized()) return false; - return PackBootstrapToken(default_nigori_->second.get(), token); -} - -bool Cryptographer::GetKeystoreKeyBootstrapToken( - std::string* token) const { - DCHECK(token); - if (!HasKeystoreKey()) + NigoriMap::const_iterator default_nigori = + nigoris_.find(default_nigori_name_); + if (default_nigori == nigoris_.end()) return false; - - return PackBootstrapToken(keystore_nigori_->second.get(), token); + return PackBootstrapToken(default_nigori->second.get(), token); } bool Cryptographer::PackBootstrapToken(const Nigori* nigori, @@ -307,27 +289,6 @@ Nigori* Cryptographer::UnpackBootstrapToken(const std::string& token) const { return nigori.release(); } -bool Cryptographer::SetKeystoreKey(const std::string& keystore_key) { - if (keystore_key.empty()) - return false; - KeyParams params = {"localhost", "dummy", keystore_key}; - - // Create the new Nigori and make it the default keystore encryptor. - scoped_ptr<Nigori> nigori(new Nigori); - if (!nigori->InitByDerivation(params.hostname, - params.username, - params.password)) { - NOTREACHED(); // Invalid username or password. - return false; - } - - return AddKeyImpl(nigori.release(), true); -} - -bool Cryptographer::HasKeystoreKey() const { - return keystore_nigori_ != NULL; -} - void Cryptographer::InstallKeyBag(const sync_pb::NigoriKeyBag& bag) { int key_size = bag.key_size(); for (int i = 0; i < key_size; ++i) { diff --git a/sync/util/cryptographer.h b/sync/util/cryptographer.h index 77a164f..99ae7d2 100644 --- a/sync/util/cryptographer.h +++ b/sync/util/cryptographer.h @@ -63,10 +63,6 @@ class Cryptographer { // never call Bootstrap at all. void Bootstrap(const std::string& restored_bootstrap_token); - // Bootstrap the keystore key. - void BootstrapKeystoreKey( - const std::string& restored_keystore_bootstrap_token); - // Returns whether we can decrypt |encrypted| using the keys we currently know // about. bool CanDecrypt(const sync_pb::EncryptedData& encrypted) const; @@ -135,11 +131,14 @@ class Cryptographer { // correspond to a nigori that has already been installed into the keybag. void SetDefaultKey(const std::string& key_name); - bool is_initialized() const { return !nigoris_.empty() && default_nigori_; } + bool is_initialized() const { + return !nigoris_.empty() && !default_nigori_name_.empty(); + } // Returns whether this Cryptographer is ready to encrypt and decrypt data. - bool is_ready() const { return is_initialized() && - has_pending_keys() == false; } + bool is_ready() const { + return is_initialized() && !has_pending_keys(); + } // Returns whether there is a pending set of keys that needs to be decrypted. bool has_pending_keys() const { return NULL != pending_keys_.get(); } @@ -149,18 +148,6 @@ class Cryptographer { // can't be created (i.e. if this Cryptograhper doesn't have valid keys). bool GetBootstrapToken(std::string* token) const; - // Obtain the bootstrap token based on the keystore encryption key. - bool GetKeystoreKeyBootstrapToken(std::string* token) const; - - // Set the keystore-derived nigori from the provided key. - // Returns true if we succesfully create the keystore derived nigori from the - // provided key, false otherwise. - bool SetKeystoreKey(const std::string& keystore_key); - - // Returns true if we currently have a keystore-derived nigori, false - // otherwise. - bool HasKeystoreKey() const; - Encryptor* encryptor() const { return encryptor_; } private: @@ -173,9 +160,8 @@ class Cryptographer { // Does not update the default nigori. void InstallKeyBag(const sync_pb::NigoriKeyBag& bag); - // Helper method to add a nigori as either the new default nigori or the new - // keystore nigori. - bool AddKeyImpl(Nigori* nigori, bool is_keystore_key); + // Helper method to add a nigori as the default key. + bool AddKeyImpl(scoped_ptr<Nigori> nigori); // Functions to serialize + encrypt a Nigori object in an opaque format for // persistence by sync infrastructure. @@ -184,9 +170,11 @@ class Cryptographer { Encryptor* const encryptor_; - NigoriMap nigoris_; // The Nigoris we know about, mapped by key name. - NigoriMap::value_type* default_nigori_; // The Nigori used for encryption. - NigoriMap::value_type* keystore_nigori_; // Nigori generated from keystore. + // The Nigoris we know about, mapped by key name. + NigoriMap nigoris_; + // The key name associated with the default nigori. If non-empty, must + // correspond to a nigori within |nigoris_|. + std::string default_nigori_name_; scoped_ptr<sync_pb::EncryptedData> pending_keys_; diff --git a/sync/util/cryptographer_unittest.cc b/sync/util/cryptographer_unittest.cc index 09fb63f..1e06b86 100644 --- a/sync/util/cryptographer_unittest.cc +++ b/sync/util/cryptographer_unittest.cc @@ -138,19 +138,6 @@ TEST_F(SyncCryptographerTest, AddKeySetsDefault) { EXPECT_EQ(encrypted3.key_name(), encrypted4.key_name()); } -// Ensure setting the keystore key works and doesn't modify the default nigori. -TEST_F(SyncCryptographerTest, SetKeystore) { - EXPECT_FALSE(cryptographer_.is_initialized()); - EXPECT_FALSE(cryptographer_.HasKeystoreKey()); - - EXPECT_FALSE(cryptographer_.SetKeystoreKey("")); - EXPECT_FALSE(cryptographer_.HasKeystoreKey()); - - EXPECT_TRUE(cryptographer_.SetKeystoreKey("keystore_key")); - EXPECT_TRUE(cryptographer_.HasKeystoreKey()); - EXPECT_FALSE(cryptographer_.is_initialized()); -} - // Crashes, Bug 55178. #if defined(OS_WIN) #define MAYBE_EncryptExportDecrypt DISABLED_EncryptExportDecrypt @@ -224,22 +211,4 @@ TEST_F(SyncCryptographerTest, MAYBE_PackUnpack) { EXPECT_EQ(expected_mac, mac_key); } -// Test that bootstrapping the keystore key works and doesn't affect the default -// nigori. -TEST_F(SyncCryptographerTest, BootstrapKeystore) { - std::string token; - cryptographer_.GetKeystoreKeyBootstrapToken(&token); - EXPECT_TRUE(token.empty()); - - cryptographer_.SetKeystoreKey("keystore_key"); - cryptographer_.GetKeystoreKeyBootstrapToken(&token); - EXPECT_FALSE(token.empty()); - - Cryptographer cryptographer2(&encryptor_); - EXPECT_FALSE(cryptographer2.HasKeystoreKey()); - cryptographer2.BootstrapKeystoreKey(token); - EXPECT_TRUE(cryptographer2.HasKeystoreKey()); - EXPECT_FALSE(cryptographer2.is_initialized()); -} - } // namespace syncer |