diff options
42 files changed, 288 insertions, 77 deletions
diff --git a/chrome/browser/sync/about_sync_util.cc b/chrome/browser/sync/about_sync_util.cc index b0a56dcd..c0487ad 100644 --- a/chrome/browser/sync/about_sync_util.cc +++ b/chrome/browser/sync/about_sync_util.cc @@ -197,6 +197,7 @@ scoped_ptr<DictionaryValue> ConstructAboutInformation( ListValue* section_last_session = AddSection( stats_list, "Status from Last Completed Session"); StringSyncStat session_source(section_last_session, "Sync Source"); + StringSyncStat get_key_result(section_last_session, "GetKey Step Result"); StringSyncStat download_result(section_last_session, "Download Step Result"); StringSyncStat commit_result(section_last_session, "Commit Step Result"); @@ -297,6 +298,9 @@ scoped_ptr<DictionaryValue> ConstructAboutInformation( if (snapshot.is_initialized()) { session_source.SetValue( syncer::GetUpdatesSourceString(snapshot.source().updates_source)); + get_key_result.SetValue( + GetSyncerErrorString( + snapshot.model_neutral_state().last_get_key_result)); download_result.SetValue( GetSyncerErrorString( snapshot.model_neutral_state().last_download_updates_result)); diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index 295bb8c..8c0d8c7 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -992,6 +992,8 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) { options.chrome_sync_notification_bridge, options.sync_notifier_factory->CreateSyncNotifier())), options.restored_key_for_bootstrapping, + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncKeystoreEncryption), scoped_ptr<InternalComponentsFactory>( options.internal_components_factory), &encryptor_, diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 7bc6ab8..e9ab9c9 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc @@ -197,6 +197,10 @@ void SyncTest::AddTestSwitches(CommandLine* cl) { // Disable non-essential access of external network resources. if (!cl->HasSwitch(switches::kDisableBackgroundNetworking)) cl->AppendSwitch(switches::kDisableBackgroundNetworking); + + // TODO(sync): remove this once keystore encryption is enabled by default. + if (!cl->HasSwitch(switches::kSyncKeystoreEncryption)) + cl->AppendSwitch(switches::kSyncKeystoreEncryption); } void SyncTest::AddOptionalTypesToCommandLine(CommandLine* cl) {} diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 77dfee8..3204947 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1240,6 +1240,9 @@ const char kSyncAllowInsecureXmppConnection[] = // Invalidates any login info passed into sync's XMPP connection. const char kSyncInvalidateXmppLogin[] = "sync-invalidate-xmpp-login"; +// Enable support for keystore key based encryption. +const char kSyncKeystoreEncryption[] = "sync-keystore-encryption"; + // Overrides the default notification method for sync. const char kSyncNotificationMethod[] = "sync-notification-method"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 192f0d2..6fad18d 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -328,6 +328,7 @@ extern const char kSuggestionNtpGaussianFilter[]; extern const char kSuggestionNtpLinearFilter[]; extern const char kSyncAllowInsecureXmppConnection[]; extern const char kSyncInvalidateXmppLogin[]; +extern const char kSyncKeystoreEncryption[]; extern const char kSyncNotificationMethod[]; extern const char kSyncNotificationHostPort[]; extern const char kSyncServiceURL[]; diff --git a/net/tools/testserver/chromiumsync.py b/net/tools/testserver/chromiumsync.py index d789bcb..24325f5 100644 --- a/net/tools/testserver/chromiumsync.py +++ b/net/tools/testserver/chromiumsync.py @@ -13,6 +13,7 @@ import copy import operator import pickle import random +import string import sys import threading import time @@ -97,6 +98,9 @@ ROOT_ID = '0' # Jan 1 1970, 00:00:00, non-dst. UNIX_TIME_EPOCH = (1970, 1, 1, 0, 0, 0, 3, 1, 0) +# The number of characters in the server-generated encryption key. +KEYSTORE_KEY_LENGTH = 16 + class Error(Exception): """Error class for this module.""" @@ -468,6 +472,9 @@ class SyncDataModel(object): self.induced_error_frequency = 0 self.sync_count_before_errors = 0 + self._key = ''.join(random.choice(string.ascii_uppercase + string.digits) + for x in xrange(KEYSTORE_KEY_LENGTH)) + def _SaveEntry(self, entry): """Insert or update an entry in the change log, and give it a new version. @@ -664,6 +671,11 @@ class SyncDataModel(object): # batch, even if that item was filtered out. return (batch[-1].version, filtered, len(new_changes) - len(batch)) + def GetKey(self): + """Returns the encryption key for this account.""" + print "Returning encryption key: %s" % self._key + return self._key + def _CopyOverImmutableFields(self, entry): """Preserve immutable fields by copying pre-commit state. @@ -1043,7 +1055,7 @@ class TestServer(object): def HandleSetInducedError(self, path): query = urlparse.urlparse(path)[4] self.account_lock.acquire() - code = 200; + code = 200 response = 'Success' error = sync_pb2.ClientToServerResponse.Error() try: @@ -1132,8 +1144,8 @@ class TestServer(object): response.error_code = sync_enums_pb2.SyncEnums.SUCCESS self.CheckStoreBirthday(request) response.store_birthday = self.account.store_birthday - self.CheckTransientError(); - self.CheckSendError(); + self.CheckTransientError() + self.CheckSendError() print_context('->') @@ -1262,3 +1274,6 @@ class TestServer(object): reply = update_response.entries.add() reply.CopyFrom(entry) update_sieve.SaveProgress(new_timestamp, update_response) + + if update_request.need_encryption_key: + update_response.encryption_key = self.account.GetKey() diff --git a/net/tools/testserver/chromiumsync_test.py b/net/tools/testserver/chromiumsync_test.py index 2485b0f..e680d41 100755 --- a/net/tools/testserver/chromiumsync_test.py +++ b/net/tools/testserver/chromiumsync_test.py @@ -600,6 +600,12 @@ class SyncDataModelTest(unittest.TestCase): len(changes)) self.assertEqual(version2, version) + def testGetKey(self): + key1 = self.model.GetKey() + key2 = self.model.GetKey() + self.assertTrue(len(key1) > 0) + self.assertEqual(key1, key2) + if __name__ == '__main__': unittest.main() diff --git a/sync/engine/download_updates_command.cc b/sync/engine/download_updates_command.cc index e7e1b08..65677fb 100644 --- a/sync/engine/download_updates_command.cc +++ b/sync/engine/download_updates_command.cc @@ -11,6 +11,7 @@ #include "sync/engine/syncer_proto_util.h" #include "sync/internal_api/public/base/model_type_payload_map.h" #include "sync/syncable/directory.h" +#include "sync/syncable/read_transaction.h" using sync_pb::DebugInfo; @@ -25,6 +26,30 @@ DownloadUpdatesCommand::DownloadUpdatesCommand( DownloadUpdatesCommand::~DownloadUpdatesCommand() {} +namespace { + +SyncerError HandleGetEncryptionKeyResponse( + const sync_pb::ClientToServerResponse& update_response, + syncable::Directory* dir) { + bool success = false; + if (!update_response.get_updates().has_encryption_key()) { + LOG(ERROR) << "Failed to receive encryption key from server."; + 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()); + + DVLOG(1) << "GetUpdates returned encryption key of length " + << update_response.get_updates().encryption_key().length() + << ". Cryptographer keystore key " + << (success ? "" : "not ") << "updated."; + return (success ? SYNCER_OK : SERVER_RESPONSE_VALIDATION_FAILED); +} + +} // namespace + SyncerError DownloadUpdatesCommand::ExecuteImpl(SyncSession* session) { sync_pb::ClientToServerMessage client_to_server_message; sync_pb::ClientToServerResponse update_response; @@ -61,6 +86,17 @@ SyncerError DownloadUpdatesCommand::ExecuteImpl(SyncSession* session) { } } + bool need_encryption_key = false; + 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(); + get_updates->set_need_encryption_key(need_encryption_key); + + } + // We want folders for our associated types, always. If we were to set // this to false, the server would send just the non-container items // (e.g. Bookmark URLs but not their containing folders). @@ -102,6 +138,12 @@ SyncerError DownloadUpdatesCommand::ExecuteImpl(SyncSession* session) { << " updates and indicated " << update_response.get_updates().changes_remaining() << " updates left on server."; + + if (need_encryption_key) { + status->set_last_get_key_result( + HandleGetEncryptionKeyResponse(update_response, dir)); + } + return result; } diff --git a/sync/engine/sync_scheduler.h b/sync/engine/sync_scheduler.h index c8226f4..8967a83 100644 --- a/sync/engine/sync_scheduler.h +++ b/sync/engine/sync_scheduler.h @@ -26,16 +26,11 @@ namespace syncer { struct ServerConnectionEvent; struct ConfigurationParams { - enum KeystoreKeyStatus { - KEYSTORE_KEY_UNNECESSARY, - KEYSTORE_KEY_NEEDED - }; ConfigurationParams(); ConfigurationParams( const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, const ModelTypeSet& types_to_download, const ModelSafeRoutingInfo& routing_info, - KeystoreKeyStatus keystore_key_status, const base::Closure& ready_task); ~ConfigurationParams(); @@ -45,8 +40,6 @@ struct ConfigurationParams { ModelTypeSet types_to_download; // The new routing info (superset of types to be downloaded). ModelSafeRoutingInfo routing_info; - // Whether we need to perform a GetKey command. - KeystoreKeyStatus keystore_key_status; // Callback to invoke on configuration completion. base::Closure ready_task; }; diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc index 72f8243..ec7143d 100644 --- a/sync/engine/sync_scheduler_impl.cc +++ b/sync/engine/sync_scheduler_impl.cc @@ -65,18 +65,15 @@ bool IsActionableError( } // namespace ConfigurationParams::ConfigurationParams() - : source(GetUpdatesCallerInfo::UNKNOWN), - keystore_key_status(KEYSTORE_KEY_UNNECESSARY) {} + : source(GetUpdatesCallerInfo::UNKNOWN) {} ConfigurationParams::ConfigurationParams( const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, const ModelTypeSet& types_to_download, const ModelSafeRoutingInfo& routing_info, - KeystoreKeyStatus keystore_key_status, const base::Closure& ready_task) : source(source), types_to_download(types_to_download), routing_info(routing_info), - keystore_key_status(keystore_key_status), ready_task(ready_task) { DCHECK(!ready_task.is_null()); } @@ -353,12 +350,6 @@ bool SyncSchedulerImpl::ScheduleConfiguration( &restricted_workers); session_context_->set_routing_info(params.routing_info); - if (params.keystore_key_status == ConfigurationParams::KEYSTORE_KEY_NEEDED) { - // TODO(zea): implement in such a way that we can handle failures and the - // subsequent retrys the scheduler might perform. See crbug.com/129665. - NOTIMPLEMENTED(); - } - // Only reconfigure if we have types to download. if (!params.types_to_download.Empty()) { DCHECK(!restricted_routes.empty()); diff --git a/sync/engine/sync_scheduler_unittest.cc b/sync/engine/sync_scheduler_unittest.cc index 7581c4dc..2b9ea87 100644 --- a/sync/engine/sync_scheduler_unittest.cc +++ b/sync/engine/sync_scheduler_unittest.cc @@ -120,7 +120,8 @@ class SyncSchedulerTest : public testing::Test { context_.reset(new SyncSessionContext( connection_.get(), directory(), workers, &extensions_activity_monitor_, throttled_data_type_tracker_.get(), - std::vector<SyncEngineEventListener*>(), NULL, NULL)); + std::vector<SyncEngineEventListener*>(), NULL, NULL, + true /* enable keystore encryption */)); context_->set_routing_info(routing_info); context_->set_notifications_enabled(true); context_->set_account_name("Test"); @@ -312,7 +313,6 @@ TEST_F(SyncSchedulerTest, Config) { GetUpdatesCallerInfo::RECONFIGURATION, model_types, TypesToRoutingInfo(model_types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(1, counter.times_called()); @@ -346,7 +346,6 @@ TEST_F(SyncSchedulerTest, ConfigWithBackingOff) { GetUpdatesCallerInfo::RECONFIGURATION, model_types, TypesToRoutingInfo(model_types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(0, counter.times_called()); @@ -389,7 +388,6 @@ TEST_F(SyncSchedulerTest, NudgeWithConfigWithBackingOff) { GetUpdatesCallerInfo::RECONFIGURATION, model_types, TypesToRoutingInfo(model_types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(0, counter.times_called()); @@ -730,7 +728,6 @@ TEST_F(SyncSchedulerTest, ThrottlingDoesThrottle) { GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(0, counter.times_called()); @@ -784,7 +781,6 @@ TEST_F(SyncSchedulerTest, ConfigurationMode) { GetUpdatesCallerInfo::RECONFIGURATION, config_types, TypesToRoutingInfo(config_types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(1, counter.times_called()); @@ -848,6 +844,17 @@ TEST_F(BackoffTriggersSyncSchedulerTest, FailDownloadTwice) { EXPECT_TRUE(RunAndGetBackoff()); } +// Have the syncer fail to get the encryption key yet succeed in downloading +// updates. Expect this will leave the scheduler in backoff. +TEST_F(BackoffTriggersSyncSchedulerTest, FailGetEncryptionKey) { + EXPECT_CALL(*syncer(), SyncShare(_,_,_)) + .WillOnce(Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed)) + .WillRepeatedly(DoAll( + Invoke(sessions::test_util::SimulateGetEncryptionKeyFailed), + QuitLoopNowAction())); + EXPECT_TRUE(RunAndGetBackoff()); +} + // Test that no polls or extraneous nudges occur when in backoff. TEST_F(SyncSchedulerTest, BackoffDropsJobs) { SyncShareRecords r; @@ -899,7 +906,6 @@ TEST_F(SyncSchedulerTest, BackoffDropsJobs) { GetUpdatesCallerInfo::RECONFIGURATION, types, TypesToRoutingInfo(types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_FALSE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(0, counter.times_called()); @@ -1074,7 +1080,6 @@ TEST_F(SyncSchedulerTest, SyncerSteps) { GetUpdatesCallerInfo::RECONFIGURATION, model_types, TypesToRoutingInfo(model_types), - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY, base::Bind(&CallbackCounter::Callback, base::Unretained(&counter))); ASSERT_TRUE(scheduler()->ScheduleConfiguration(params)); ASSERT_EQ(1, counter.times_called()); diff --git a/sync/engine/sync_scheduler_whitebox_unittest.cc b/sync/engine/sync_scheduler_whitebox_unittest.cc index b035686..f6f88c2 100644 --- a/sync/engine/sync_scheduler_whitebox_unittest.cc +++ b/sync/engine/sync_scheduler_whitebox_unittest.cc @@ -50,7 +50,8 @@ class SyncSchedulerWhiteboxTest : public testing::Test { connection_.get(), dir_maker_.directory(), workers, &extensions_activity_monitor_, throttled_data_type_tracker_.get(), - std::vector<SyncEngineEventListener*>(), NULL, NULL)); + std::vector<SyncEngineEventListener*>(), NULL, NULL, + true /* enable keystore encryption */)); context_->set_notifications_enabled(true); context_->set_account_name("Test"); scheduler_.reset( diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc index 053fc1d..7372f68 100644 --- a/sync/engine/syncer_unittest.cc +++ b/sync/engine/syncer_unittest.cc @@ -238,7 +238,8 @@ class SyncerTest : public testing::Test, new SyncSessionContext( mock_server_.get(), directory(), workers, &extensions_activity_monitor_, throttled_data_type_tracker_.get(), - listeners, NULL, &traffic_recorder_)); + listeners, NULL, &traffic_recorder_, + true /* enable keystore encryption */)); context_->set_routing_info(routing_info); ASSERT_FALSE(context_->resolver()); syncer_ = new Syncer(); @@ -252,6 +253,8 @@ class SyncerTest : public testing::Test, root_id_ = TestIdFactory::root(); parent_id_ = ids_.MakeServer("parent id"); child_id_ = ids_.MakeServer("child id"); + directory()->set_store_birthday(mock_server_->store_birthday()); + mock_server_->SetKeystoreKey("encryption_key"); } virtual void TearDown() { @@ -2307,7 +2310,6 @@ class EntryCreatedInNewFolderTest : public SyncerTest { }; TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) { - directory()->set_store_birthday(mock_server_->store_birthday()); { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), @@ -4167,6 +4169,37 @@ TEST_F(SyncerTest, ConfigureFailsDontApplyUpdates) { EXPECT_FALSE(initial_sync_ended_for_type(BOOKMARKS)); } +TEST_F(SyncerTest, GetKeySuccess) { + { + syncable::ReadTransaction rtrans(FROM_HERE, directory()); + EXPECT_FALSE(cryptographer(&rtrans)->HasKeystoreKey()); + } + + SyncShareConfigure(); + + EXPECT_EQ(session_->status_controller().last_get_key_result(), SYNCER_OK); + { + syncable::ReadTransaction rtrans(FROM_HERE, directory()); + EXPECT_TRUE(cryptographer(&rtrans)->HasKeystoreKey()); + } +} + +TEST_F(SyncerTest, GetKeyEmpty) { + { + syncable::ReadTransaction rtrans(FROM_HERE, directory()); + EXPECT_FALSE(cryptographer(&rtrans)->HasKeystoreKey()); + } + + mock_server_->SetKeystoreKey(""); + SyncShareConfigure(); + + EXPECT_NE(session_->status_controller().last_get_key_result(), SYNCER_OK); + { + syncable::ReadTransaction rtrans(FROM_HERE, directory()); + EXPECT_FALSE(cryptographer(&rtrans)->HasKeystoreKey()); + } +} + // Test what happens if a client deletes, then recreates, an object very // quickly. It is possible that the deletion gets sent as a commit, and // the undelete happens during the commit request. The principle here diff --git a/sync/internal_api/internal_components_factory_impl.cc b/sync/internal_api/internal_components_factory_impl.cc index 062ee0b..3342d09 100644 --- a/sync/internal_api/internal_components_factory_impl.cc +++ b/sync/internal_api/internal_components_factory_impl.cc @@ -29,12 +29,14 @@ InternalComponentsFactoryImpl::BuildContext( ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, sessions::DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) { + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) { return scoped_ptr<sessions::SyncSessionContext>( new sessions::SyncSessionContext( connection_manager, directory, workers, monitor, throttled_data_type_tracker, listeners, debug_info_getter, - traffic_recorder)); + traffic_recorder, + keystore_encryption_enabled)); } scoped_ptr<syncable::DirectoryBackingStore> diff --git a/sync/internal_api/public/internal_components_factory.h b/sync/internal_api/public/internal_components_factory.h index 40c703e..145c225 100644 --- a/sync/internal_api/public/internal_components_factory.h +++ b/sync/internal_api/public/internal_components_factory.h @@ -51,7 +51,8 @@ class InternalComponentsFactory { ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, sessions::DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) = 0; + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) = 0; virtual scoped_ptr<syncable::DirectoryBackingStore> BuildDirectoryBackingStore( diff --git a/sync/internal_api/public/internal_components_factory_impl.h b/sync/internal_api/public/internal_components_factory_impl.h index d15287a..c8f76ed 100644 --- a/sync/internal_api/public/internal_components_factory_impl.h +++ b/sync/internal_api/public/internal_components_factory_impl.h @@ -29,7 +29,8 @@ class InternalComponentsFactoryImpl : public InternalComponentsFactory { ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, sessions::DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) OVERRIDE; + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) OVERRIDE; virtual scoped_ptr<syncable::DirectoryBackingStore> BuildDirectoryBackingStore( diff --git a/sync/internal_api/public/sessions/model_neutral_state.cc b/sync/internal_api/public/sessions/model_neutral_state.cc index b25d3c7..9ae8436 100644 --- a/sync/internal_api/public/sessions/model_neutral_state.cc +++ b/sync/internal_api/public/sessions/model_neutral_state.cc @@ -15,6 +15,7 @@ ModelNeutralState::ModelNeutralState() num_reflected_updates_downloaded_total(0), num_local_overwrites(0), num_server_overwrites(0), + last_get_key_result(UNSET), last_download_updates_result(UNSET), commit_result(UNSET), conflicts_resolved(false), diff --git a/sync/internal_api/public/sessions/model_neutral_state.h b/sync/internal_api/public/sessions/model_neutral_state.h index 6b0cec8..c1d8862 100644 --- a/sync/internal_api/public/sessions/model_neutral_state.h +++ b/sync/internal_api/public/sessions/model_neutral_state.h @@ -48,7 +48,9 @@ struct ModelNeutralState { // Any protocol errors that we received during this sync session. SyncProtocolError sync_protocol_error; - // Records the most recent results of PostCommit and GetUpdates commands. + // Records the most recent results of GetKey, PostCommit and GetUpdates + // commands. + SyncerError last_get_key_result; SyncerError last_download_updates_result; SyncerError commit_result; diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index 2cbbd5c..93c3787b 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -359,6 +359,10 @@ class SyncManager { // |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent // HTTP header. Used internally when collecting stats to classify clients. // |sync_notifier| is owned and used to listen for notifications. + // |restored_key_for_bootstrapping| is the key used to boostrap the + // cryptographer + // |keystore_encryption_enabled| determines whether we enable the keystore + // encryption functionality in the cryptographer/nigori. // |report_unrecoverable_error_function| may be NULL. // // TODO(akalin): Replace the |post_factory| parameter with a @@ -377,6 +381,7 @@ class SyncManager { const SyncCredentials& credentials, scoped_ptr<SyncNotifier> sync_notifier, const std::string& restored_key_for_bootstrapping, + bool keystore_encryption_enabled, scoped_ptr<InternalComponentsFactory> internal_components_factory, Encryptor* encryptor, UnrecoverableErrorHandler* unrecoverable_error_handler, diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h index 015605f..b33b27d 100644 --- a/sync/internal_api/public/test/fake_sync_manager.h +++ b/sync/internal_api/public/test/fake_sync_manager.h @@ -67,6 +67,7 @@ class FakeSyncManager : public SyncManager { const SyncCredentials& credentials, scoped_ptr<SyncNotifier> sync_notifier, const std::string& restored_key_for_bootstrapping, + bool keystore_encryption_enabled, scoped_ptr<InternalComponentsFactory> internal_components_factory, Encryptor* encryptor, UnrecoverableErrorHandler* unrecoverable_error_handler, diff --git a/sync/internal_api/public/test/test_internal_components_factory.h b/sync/internal_api/public/test/test_internal_components_factory.h index 3755447..a97164d 100644 --- a/sync/internal_api/public/test/test_internal_components_factory.h +++ b/sync/internal_api/public/test/test_internal_components_factory.h @@ -34,7 +34,8 @@ class TestInternalComponentsFactory : public InternalComponentsFactory { ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, sessions::DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) OVERRIDE; + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) OVERRIDE; virtual scoped_ptr<syncable::DirectoryBackingStore> BuildDirectoryBackingStore( diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 7e173d1..e069df4 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -351,15 +351,9 @@ void SyncManagerImpl::ConfigureSyncer( return; } - // TODO(zea): set this based on whether cryptographer has keystore - // encryption key or not (requires opening a transaction). crbug.com/129665. - ConfigurationParams::KeystoreKeyStatus keystore_key_status = - ConfigurationParams::KEYSTORE_KEY_UNNECESSARY; - ConfigurationParams params(GetSourceFromReason(reason), types_to_config, new_routing_info, - keystore_key_status, ready_task); scheduler_->Start(SyncScheduler::CONFIGURATION_MODE); @@ -382,6 +376,7 @@ bool SyncManagerImpl::Init( const SyncCredentials& credentials, scoped_ptr<SyncNotifier> sync_notifier, const std::string& restored_key_for_bootstrapping, + bool keystore_encryption_enabled, scoped_ptr<InternalComponentsFactory> internal_components_factory, Encryptor* encryptor, UnrecoverableErrorHandler* unrecoverable_error_handler, @@ -469,7 +464,8 @@ bool SyncManagerImpl::Init( &throttled_data_type_tracker_, listeners, &debug_info_event_listener_, - &traffic_recorder_).Pass(); + &traffic_recorder_, + keystore_encryption_enabled).Pass(); session_context_->set_account_name(credentials.email); scheduler_ = internal_components_factory->BuildScheduler( name_, session_context_.get()).Pass(); diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h index 190f77d..3ce4679 100644 --- a/sync/internal_api/sync_manager_impl.h +++ b/sync/internal_api/sync_manager_impl.h @@ -71,6 +71,7 @@ class SyncManagerImpl : public SyncManager, const SyncCredentials& credentials, scoped_ptr<SyncNotifier> sync_notifier, const std::string& restored_key_for_bootstrapping, + bool keystore_encryption_enabled, scoped_ptr<InternalComponentsFactory> internal_components_factory, Encryptor* encryptor, UnrecoverableErrorHandler* unrecoverable_error_handler, diff --git a/sync/internal_api/syncapi_unittest.cc b/sync/internal_api/syncapi_unittest.cc index e43a2e2..d0ec527 100644 --- a/sync/internal_api/syncapi_unittest.cc +++ b/sync/internal_api/syncapi_unittest.cc @@ -764,6 +764,7 @@ class SyncManagerTest : public testing::Test, credentials, scoped_ptr<SyncNotifier>(sync_notifier_mock_), "", + true, // enable keystore encryption scoped_ptr<InternalComponentsFactory>(GetFactory()), &encryptor_, &handler_, diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc index 1af7fac..a507239 100644 --- a/sync/internal_api/test/fake_sync_manager.cc +++ b/sync/internal_api/test/fake_sync_manager.cc @@ -62,6 +62,7 @@ bool FakeSyncManager::Init( const SyncCredentials& credentials, scoped_ptr<SyncNotifier> sync_notifier, const std::string& restored_key_for_bootstrapping, + bool keystore_encryption_enabled, scoped_ptr<InternalComponentsFactory> internal_components_factory, Encryptor* encryptor, UnrecoverableErrorHandler* unrecoverable_error_handler, diff --git a/sync/internal_api/test/test_internal_components_factory.cc b/sync/internal_api/test/test_internal_components_factory.cc index ac3f8a8..cffaedb 100644 --- a/sync/internal_api/test/test_internal_components_factory.cc +++ b/sync/internal_api/test/test_internal_components_factory.cc @@ -32,7 +32,8 @@ TestInternalComponentsFactory::BuildContext( ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, sessions::DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) { + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) { // Tests don't wire up listeners. std::vector<SyncEngineEventListener*> empty_listeners; @@ -40,7 +41,9 @@ TestInternalComponentsFactory::BuildContext( new sessions::SyncSessionContext( connection_manager, directory, workers, monitor, throttled_data_type_tracker, empty_listeners, debug_info_getter, - traffic_recorder)); + traffic_recorder, + keystore_encryption_enabled)); + } scoped_ptr<syncable::DirectoryBackingStore> diff --git a/sync/protocol/sync.proto b/sync/protocol/sync.proto index ec9a1d2..8f44823 100644 --- a/sync/protocol/sync.proto +++ b/sync/protocol/sync.proto @@ -446,6 +446,14 @@ message GetUpdatesMessage { // delimited by a length prefix, which is encoded as a varint. optional bool streaming = 7 [default = false]; + // Whether the client needs the server to provide an encryption key for this + // account. + // Note: this should typically only be set on the first GetUpdates a client + // requests. Clients are expected to persist the encryption key from then on. + // The allowed frequency for requesting encryption keys is much lower than + // other datatypes, so repeated usage will likely result in throttling. + optional bool need_encryption_key = 8 [default = false]; + // Whether to create the mobile bookmarks folder if it's not // already created. Should be set to true only by mobile clients. optional bool create_mobile_bookmarks_folder = 1000 [default = false]; @@ -572,6 +580,10 @@ message GetUpdatesResponse { // Progress markers in the context of a response will never have the // |timestamp_token_for_migration| field set. repeated DataTypeProgressMarker new_progress_marker = 5; + + // The current encryption key associated with this account. Only set if the + // GetUpdatesMessage in the request had need_encryption_key == true. + optional bytes encryption_key = 6; }; // The metadata response for GetUpdatesMessage. This response is sent when @@ -625,25 +637,6 @@ message ClientToServerResponse { optional CommitResponse commit = 1; optional GetUpdatesResponse get_updates = 2; optional AuthenticateResponse authenticate = 3; - // DEPRECATED - this field was never used in production. - // optional ClearUserDataResponse clear_user_data = 9; - optional GetUpdatesMetadataResponse stream_metadata = 10; - // If GetUpdatesStreamingResponse is contained in the ClientToServerResponse, - // none of the other fields (error_code and etc) will be set. - optional GetUpdatesStreamingResponse stream_data = 11; - - message Error { - optional SyncEnums.ErrorType error_type = 1 [default = UNKNOWN]; - optional string error_description = 2; - optional string url = 3; - optional SyncEnums.Action action = 4 [default = UNKNOWN_ACTION]; - - // Currently only meaningful if |error_type| is throttled. If this field - // is absent then the whole client (all datatypes) is throttled. - repeated int32 error_data_type_ids = 5; - } - - optional Error error = 13; // Up until protocol_version 24, the default was SUCCESS which made it // impossible to add new enum values since older clients would parse any @@ -663,9 +656,27 @@ message ClientToServerResponse { optional ClientCommand client_command = 7; optional ProfilingData profiling_data = 8; + // DEPRECATED - this field was never used in production. + // optional ClearUserDataResponse clear_user_data = 9; + optional GetUpdatesMetadataResponse stream_metadata = 10; + // If GetUpdatesStreamingResponse is contained in the ClientToServerResponse, + // none of the other fields (error_code and etc) will be set. + optional GetUpdatesStreamingResponse stream_data = 11; // The data types whose storage has been migrated. Present when the value of // error_code is MIGRATION_DONE. repeated int32 migrated_data_type_id = 12; + + message Error { + optional SyncEnums.ErrorType error_type = 1 [default = UNKNOWN]; + optional string error_description = 2; + optional string url = 3; + optional SyncEnums.Action action = 4 [default = UNKNOWN_ACTION]; + + // Currently only meaningful if |error_type| is throttled. If this field + // is absent then the whole client (all datatypes) is throttled. + repeated int32 error_data_type_ids = 5; + } + optional Error error = 13; }; diff --git a/sync/sessions/status_controller.cc b/sync/sessions/status_controller.cc index 3694fe4..61b1094 100644 --- a/sync/sessions/status_controller.cc +++ b/sync/sessions/status_controller.cc @@ -142,6 +142,10 @@ void StatusController::set_sync_protocol_error( model_neutral_.sync_protocol_error = error; } +void StatusController::set_last_get_key_result(const SyncerError result) { + model_neutral_.last_get_key_result = result; +} + void StatusController::set_last_download_updates_result( const SyncerError result) { model_neutral_.last_download_updates_result = result; @@ -151,6 +155,10 @@ void StatusController::set_commit_result(const SyncerError result) { model_neutral_.commit_result = result; } +SyncerError StatusController::last_get_key_result() const { + return model_neutral_.last_get_key_result; +} + void StatusController::update_conflicts_resolved(bool resolved) { model_neutral_.conflicts_resolved |= resolved; } diff --git a/sync/sessions/status_controller.h b/sync/sessions/status_controller.h index 8542b48..752d07d 100644 --- a/sync/sessions/status_controller.h +++ b/sync/sessions/status_controller.h @@ -149,6 +149,8 @@ class StatusController { return model_neutral_; } + SyncerError last_get_key_result() const; + // A toolbelt full of methods for updating counters and flags. void set_num_server_changes_remaining(int64 changes_remaining); void set_num_successful_bookmark_commits(int value); @@ -161,6 +163,7 @@ class StatusController { void increment_num_local_overwrites(); void increment_num_server_overwrites(); void set_sync_protocol_error(const SyncProtocolError& error); + void set_last_get_key_result(const SyncerError result); void set_last_download_updates_result(const SyncerError result); void set_commit_result(const SyncerError result); diff --git a/sync/sessions/sync_session.cc b/sync/sessions/sync_session.cc index 7af4c50..f432978 100644 --- a/sync/sessions/sync_session.cc +++ b/sync/sessions/sync_session.cc @@ -241,17 +241,17 @@ std::set<ModelSafeGroup> namespace { // Return true if the command in question was attempted and did not complete // successfully. -// bool IsError(SyncerError error) { return error != UNSET && error != SYNCER_OK; } // Returns false iff one of the command results had an error. bool HadErrors(const ModelNeutralState& state) { + const bool get_key_error = IsError(state.last_get_key_result); const bool download_updates_error = IsError(state.last_download_updates_result); const bool commit_error = IsError(state.commit_result); - return download_updates_error || commit_error; + return get_key_error || download_updates_error || commit_error; } } // namespace @@ -261,7 +261,8 @@ bool SyncSession::Succeeded() const { bool SyncSession::SuccessfullyReachedServer() const { const ModelNeutralState& state = status_controller_->model_neutral_state(); - bool reached_server = state.last_download_updates_result == SYNCER_OK; + bool reached_server = state.last_get_key_result == SYNCER_OK || + state.last_download_updates_result == SYNCER_OK; // It's possible that we reached the server on one attempt, then had an error // on the next (or didn't perform some of the server-communicating commands). // We want to verify that, for all commands attempted, we successfully spoke diff --git a/sync/sessions/sync_session_context.cc b/sync/sessions/sync_session_context.cc index 7b6349b..fa946d0 100644 --- a/sync/sessions/sync_session_context.cc +++ b/sync/sessions/sync_session_context.cc @@ -22,7 +22,8 @@ SyncSessionContext::SyncSessionContext( ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder) + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled) : resolver_(NULL), connection_manager_(connection_manager), directory_(directory), @@ -32,7 +33,8 @@ SyncSessionContext::SyncSessionContext( max_commit_batch_size_(kDefaultMaxCommitBatchSize), throttled_data_type_tracker_(throttled_data_type_tracker), debug_info_getter_(debug_info_getter), - traffic_recorder_(traffic_recorder) { + traffic_recorder_(traffic_recorder), + keystore_encryption_enabled_(keystore_encryption_enabled) { std::vector<SyncEngineEventListener*>::const_iterator it; for (it = listeners.begin(); it != listeners.end(); ++it) listeners_.AddObserver(*it); diff --git a/sync/sessions/sync_session_context.h b/sync/sessions/sync_session_context.h index 400a6aa..3f01150 100644 --- a/sync/sessions/sync_session_context.h +++ b/sync/sessions/sync_session_context.h @@ -56,7 +56,9 @@ class SyncSessionContext { ThrottledDataTypeTracker* throttled_data_type_tracker, const std::vector<SyncEngineEventListener*>& listeners, DebugInfoGetter* debug_info_getter, - TrafficRecorder* traffic_recorder); + TrafficRecorder* traffic_recorder, + bool keystore_encryption_enabled); + ~SyncSessionContext(); ConflictResolver* resolver() { return resolver_; } @@ -118,6 +120,10 @@ class SyncSessionContext { return traffic_recorder_; } + bool keystore_encryption_enabled() const { + return keystore_encryption_enabled_; + } + private: // Rather than force clients to set and null-out various context members, we // extend our encapsulation boundary to scoped helpers that take care of this @@ -162,6 +168,11 @@ class SyncSessionContext { TrafficRecorder* traffic_recorder_; + // Temporary variable while keystore encryption is behind a flag. True if + // we should attempt performing keystore encryption related work, false if + // the experiment is not enabled. + bool keystore_encryption_enabled_; + DISALLOW_COPY_AND_ASSIGN(SyncSessionContext); }; diff --git a/sync/sessions/sync_session_unittest.cc b/sync/sessions/sync_session_unittest.cc index bd17d359..ae2922d 100644 --- a/sync/sessions/sync_session_unittest.cc +++ b/sync/sessions/sync_session_unittest.cc @@ -67,7 +67,8 @@ class SyncSessionTest : public testing::Test, throttled_data_type_tracker_.get(), std::vector<SyncEngineEventListener*>(), NULL, - NULL)); + NULL, + true /* enable keystore encryption */)); context_->set_routing_info(routes_); session_.reset(MakeSession()); diff --git a/sync/sessions/test_util.cc b/sync/sessions/test_util.cc index 875d133..ef734b7 100644 --- a/sync/sessions/test_util.cc +++ b/sync/sessions/test_util.cc @@ -14,8 +14,17 @@ void SimulateHasMoreToSync(sessions::SyncSession* session, ASSERT_TRUE(session->HasMoreToSync()); } +void SimulateGetEncryptionKeyFailed(sessions::SyncSession* session, + SyncerStep begin, SyncerStep end) { + session->mutable_status_controller()->set_last_get_key_result( + SERVER_RESPONSE_VALIDATION_FAILED); + session->mutable_status_controller()->set_last_download_updates_result( + SYNCER_OK); +} + void SimulateDownloadUpdatesFailed(sessions::SyncSession* session, SyncerStep begin, SyncerStep end) { + session->mutable_status_controller()->set_last_get_key_result(SYNCER_OK); session->mutable_status_controller()->set_last_download_updates_result( SERVER_RETURN_TRANSIENT_ERROR); } @@ -40,6 +49,7 @@ void SimulateSuccess(sessions::SyncSession* session, ASSERT_EQ(0U, session->status_controller().num_server_changes_remaining()); session->SetFinished(); if (end == SYNCER_END) { + session->mutable_status_controller()->set_last_get_key_result(SYNCER_OK); session->mutable_status_controller()->set_last_download_updates_result( SYNCER_OK); session->mutable_status_controller()->set_commit_result(SYNCER_OK); diff --git a/sync/sessions/test_util.h b/sync/sessions/test_util.h index 9cfe9e2..a6fa431 100644 --- a/sync/sessions/test_util.h +++ b/sync/sessions/test_util.h @@ -17,6 +17,8 @@ namespace test_util { void SimulateHasMoreToSync(sessions::SyncSession* session, SyncerStep begin, SyncerStep end); +void SimulateGetEncryptionKeyFailed(sessions::SyncSession* session, + SyncerStep begin, SyncerStep end); void SimulateDownloadUpdatesFailed(sessions::SyncSession* session, SyncerStep begin, SyncerStep end); void SimulateCommitFailed(sessions::SyncSession* session, diff --git a/sync/test/engine/mock_connection_manager.cc b/sync/test/engine/mock_connection_manager.cc index 5b5174d..3739bf3 100644 --- a/sync/test/engine/mock_connection_manager.cc +++ b/sync/test/engine/mock_connection_manager.cc @@ -11,6 +11,7 @@ #include "base/location.h" #include "base/stringprintf.h" #include "sync/engine/syncer_proto_util.h" +#include "sync/test/engine/test_id_factory.h" #include "sync/protocol/bookmark_specifics.pb.h" #include "sync/syncable/directory.h" #include "sync/syncable/write_transaction.h" @@ -427,7 +428,7 @@ void MockConnectionManager::ProcessGetUpdates( if (!updates->entries(i).deleted()) { ModelType entry_type = GetModelType(updates->entries(i)); EXPECT_TRUE( - IsModelTypePresentInSpecifics(gu.from_progress_marker(), entry_type)) + IsModelTypePresentInSpecifics(gu.from_progress_marker(), entry_type)) << "Syncer did not request updates being provided by the test."; } } @@ -447,9 +448,19 @@ void MockConnectionManager::ProcessGetUpdates( } } + // Fill the keystore key if requested. + if (gu.need_encryption_key()) + response->mutable_get_updates()->set_encryption_key(keystore_key_); + update_queue_.pop_front(); } +void MockConnectionManager::SetKeystoreKey(const std::string& key) { + // Note: this is not a thread-safe set, ok for now. NOT ok if tests + // run the syncer on the background thread while this method is called. + keystore_key_ = key; +} + bool MockConnectionManager::ShouldConflictThisCommit() { bool conflict = false; if (conflict_all_commits_) { diff --git a/sync/test/engine/mock_connection_manager.h b/sync/test/engine/mock_connection_manager.h index eb98471..5aabe7f 100644 --- a/sync/test/engine/mock_connection_manager.h +++ b/sync/test/engine/mock_connection_manager.h @@ -122,6 +122,8 @@ class MockConnectionManager : public ServerConnectionManager { void FailNextPostBufferToPathCall() { countdown_to_postbuffer_fail_ = 1; } void FailNthPostBufferToPathCall(int n) { countdown_to_postbuffer_fail_ = n; } + void SetKeystoreKey(const std::string& key); + void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_ = true; } // Simple inspectors. @@ -302,8 +304,8 @@ class MockConnectionManager : public ServerConnectionManager { base::Closure mid_commit_callback_; MidCommitObserver* mid_commit_observer_; - // The clear data response we'll return in the next response - sync_pb::SyncEnums::ErrorType clear_user_data_response_errortype_; + // The keystore key we return for a GetUpdates with need_encryption_key set. + std::string keystore_key_; // The AUTHENTICATE response we'll return for auth requests. sync_pb::AuthenticateResponse auth_response_; diff --git a/sync/test/engine/syncer_command_test.h b/sync/test/engine/syncer_command_test.h index 0c0185e..803ef18 100644 --- a/sync/test/engine/syncer_command_test.h +++ b/sync/test/engine/syncer_command_test.h @@ -127,7 +127,8 @@ class SyncerCommandTestBase : public testing::Test, throttled_data_type_tracker_.get(), std::vector<SyncEngineEventListener*>(), &mock_debug_info_getter_, - &traffic_recorder_)); + &traffic_recorder_, + true /* enable keystore encryption*/ )); context_->set_account_name(directory()->name()); ClearSession(); } diff --git a/sync/tools/sync_client.cc b/sync/tools/sync_client.cc index 4da8cc1..357b694 100644 --- a/sync/tools/sync_client.cc +++ b/sync/tools/sync_client.cc @@ -362,6 +362,7 @@ int SyncClientMain(int argc, char* argv[]) { scoped_ptr<SyncNotifier>( sync_notifier_factory.CreateSyncNotifier()), kRestoredKeyForBootstrapping, + true, // enable keystore encryption scoped_ptr<InternalComponentsFactory>( new InternalComponentsFactoryImpl()), &null_encryptor, diff --git a/sync/util/cryptographer.cc b/sync/util/cryptographer.cc index 2c0d794..d63166b 100644 --- a/sync/util/cryptographer.cc +++ b/sync/util/cryptographer.cc @@ -25,6 +25,7 @@ Cryptographer::Observer::~Observer() {} Cryptographer::Cryptographer(Encryptor* encryptor) : encryptor_(encryptor), default_nigori_(NULL), + keystore_nigori_(NULL), encrypted_types_(SensitiveTypes()), encrypt_everything_(false) { DCHECK(encryptor); @@ -308,6 +309,26 @@ Cryptographer::UpdateResult Cryptographer::Update( return Cryptographer::SUCCESS; } +bool Cryptographer::SetKeystoreKey(const std::string& keystore_key) { + if (keystore_key.empty()) + return false; + KeyParams params = {"localhost", "dummy", keystore_key}; + + // AddKey updates the default nigori, so we save the current default and + // make sure the keystore_nigori_ gets updated instead. + NigoriMap::value_type* old_default = default_nigori_; + if (AddKey(params)) { + keystore_nigori_ = default_nigori_; + default_nigori_ = old_default; + return true; + } + return false; +} + +bool Cryptographer::HasKeystoreKey() { + return keystore_nigori_ != NULL; +} + // Static ModelTypeSet Cryptographer::SensitiveTypes() { // Both of these have their own encryption schemes, but we include them diff --git a/sync/util/cryptographer.h b/sync/util/cryptographer.h index f02875a..d664020 100644 --- a/sync/util/cryptographer.h +++ b/sync/util/cryptographer.h @@ -179,6 +179,15 @@ class Cryptographer { // stored in the |pending_keys_|. UpdateResult Update(const sync_pb::NigoriSpecifics& nigori); + // 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(); + // The set of types that are always encrypted. static ModelTypeSet SensitiveTypes(); @@ -237,6 +246,7 @@ class Cryptographer { 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. scoped_ptr<sync_pb::EncryptedData> pending_keys_; diff --git a/sync/util/get_session_name.cc b/sync/util/get_session_name.cc index 99a4ce0..8c86c5c 100644 --- a/sync/util/get_session_name.cc +++ b/sync/util/get_session_name.cc @@ -43,7 +43,7 @@ std::string GetSessionNameSynchronously() { #elif defined(OS_LINUX) session_name = base::GetLinuxDistro(); #elif defined(OS_MACOSX) - session_name = internal::GetHardwareModelName(); +// session_name = internal::GetHardwareModelName(); #elif defined(OS_WIN) session_name = internal::GetComputerName(); #elif defined(OS_ANDROID) |