summaryrefslogtreecommitdiffstats
path: root/sync
diff options
context:
space:
mode:
authorzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 23:48:12 +0000
committerzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 23:48:12 +0000
commitde71c08fd406870753176a90f9fb84e3dbd645fa (patch)
tree2592190f8f028689a16e96ccf0e2ee2543456b74 /sync
parent118cfe57fe9e79b863f53be8500229adaf329334 (diff)
downloadchromium_src-de71c08fd406870753176a90f9fb84e3dbd645fa.zip
chromium_src-de71c08fd406870753176a90f9fb84e3dbd645fa.tar.gz
chromium_src-de71c08fd406870753176a90f9fb84e3dbd645fa.tar.bz2
[Sync] Move keystore key handling to SyncEncryptionHandlerImpl
The cryptographer has no notion of keystore keys, and we now persist the keystore key by reusing the OnBoostrapTokenUpdated method (which now takes an enum as an extra param specifying the type of token). BUG=129665 Review URL: https://chromiumcodereview.appspot.com/10878015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154007 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
-rw-r--r--sync/engine/download_updates_command.cc16
-rw-r--r--sync/engine/syncer_unittest.cc8
-rw-r--r--sync/internal_api/debug_info_event_listener.cc9
-rw-r--r--sync/internal_api/debug_info_event_listener.h3
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer.cc6
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer.h3
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer_unittest.cc15
-rw-r--r--sync/internal_api/public/sync_encryption_handler.h9
-rw-r--r--sync/internal_api/public/sync_manager.h4
-rw-r--r--sync/internal_api/public/test/fake_sync_manager.h1
-rw-r--r--sync/internal_api/public/util/sync_string_conversions.cc10
-rw-r--r--sync/internal_api/public/util/sync_string_conversions.h2
-rw-r--r--sync/internal_api/sync_encryption_handler_impl.cc34
-rw-r--r--sync/internal_api/sync_encryption_handler_impl.h15
-rw-r--r--sync/internal_api/sync_encryption_handler_impl_unittest.cc31
-rw-r--r--sync/internal_api/sync_manager_impl.cc21
-rw-r--r--sync/internal_api/sync_manager_impl.h4
-rw-r--r--sync/internal_api/sync_manager_impl_unittest.cc42
-rw-r--r--sync/internal_api/test/fake_sync_manager.cc4
-rw-r--r--sync/protocol/client_debug_info.proto2
-rw-r--r--sync/syncable/nigori_handler.h10
-rw-r--r--sync/test/fake_sync_encryption_handler.cc19
-rw-r--r--sync/test/fake_sync_encryption_handler.h6
-rw-r--r--sync/util/cryptographer.cc91
-rw-r--r--sync/util/cryptographer.h38
-rw-r--r--sync/util/cryptographer_unittest.cc31
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