summaryrefslogtreecommitdiffstats
path: root/sync/util
diff options
context:
space:
mode:
authorzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-01 01:13:38 +0000
committerzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-01 01:13:38 +0000
commitdc58763688f198a48493bfb472d0d0f45f2b34be (patch)
tree2eb473939395a5b0aeac4171702069ec3eabebe3 /sync/util
parent8d3d7ea57ac19413cdbac93c60d9fdf9803f78e0 (diff)
downloadchromium_src-dc58763688f198a48493bfb472d0d0f45f2b34be.zip
chromium_src-dc58763688f198a48493bfb472d0d0f45f2b34be.tar.gz
chromium_src-dc58763688f198a48493bfb472d0d0f45f2b34be.tar.bz2
[Sync] Persist keystore key across restarts
Adds the preference for the bootstrap token and the bootstrapping functionality in the cryptographer so that we persist the keystore key across restarts. With this, we should only ever do one GetKey per client, and only on the first time that client signs in/restarts on a version with GetKey support (although it's not persisted across signouts/profile nukes) BUG=129665 TEST=unit_tests Review URL: https://chromiumcodereview.appspot.com/10540149 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149344 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/util')
-rw-r--r--sync/util/cryptographer.cc54
-rw-r--r--sync/util/cryptographer.h14
-rw-r--r--sync/util/cryptographer_unittest.cc31
-rw-r--r--sync/util/get_session_name.cc2
4 files changed, 83 insertions, 18 deletions
diff --git a/sync/util/cryptographer.cc b/sync/util/cryptographer.cc
index d63166b..c512ab6 100644
--- a/sync/util/cryptographer.cc
+++ b/sync/util/cryptographer.cc
@@ -49,7 +49,19 @@ void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) {
scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token));
if (nigori.get())
- AddKeyImpl(nigori.release());
+ 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);
}
bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const {
@@ -145,7 +157,7 @@ bool Cryptographer::AddKey(const KeyParams& params) {
NOTREACHED(); // Invalid username or password.
return false;
}
- return AddKeyImpl(nigori.release());
+ return AddKeyImpl(nigori.release(), false);
}
bool Cryptographer::AddKeyFromBootstrapToken(
@@ -154,10 +166,11 @@ bool Cryptographer::AddKeyFromBootstrapToken(
scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token));
if (!nigori.get())
return false;
- return AddKeyImpl(nigori.release());
+ return AddKeyImpl(nigori.release(), false);
}
-bool Cryptographer::AddKeyImpl(Nigori* initialized_nigori) {
+bool Cryptographer::AddKeyImpl(Nigori* initialized_nigori,
+ bool is_keystore_key) {
scoped_ptr<Nigori> nigori(initialized_nigori);
std::string name;
if (!nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) {
@@ -165,7 +178,10 @@ bool Cryptographer::AddKeyImpl(Nigori* initialized_nigori) {
return false;
}
nigoris_[name] = make_linked_ptr(nigori.release());
- default_nigori_ = &*nigoris_.find(name);
+ if (is_keystore_key)
+ keystore_nigori_ = &*nigoris_.find(name);
+ else
+ default_nigori_ = &*nigoris_.find(name);
return true;
}
@@ -222,6 +238,15 @@ bool Cryptographer::GetBootstrapToken(std::string* token) const {
return PackBootstrapToken(default_nigori_->second.get(), token);
}
+bool Cryptographer::GetKeystoreKeyBootstrapToken(
+ std::string* token) const {
+ DCHECK(token);
+ if (!HasKeystoreKey())
+ return false;
+
+ return PackBootstrapToken(keystore_nigori_->second.get(), token);
+}
+
bool Cryptographer::PackBootstrapToken(const Nigori* nigori,
std::string* pack_into) const {
DCHECK(pack_into);
@@ -314,18 +339,19 @@ bool Cryptographer::SetKeystoreKey(const std::string& keystore_key) {
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;
+ // 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 false;
+
+ return AddKeyImpl(nigori.release(), true);
}
-bool Cryptographer::HasKeystoreKey() {
+bool Cryptographer::HasKeystoreKey() const {
return keystore_nigori_ != NULL;
}
diff --git a/sync/util/cryptographer.h b/sync/util/cryptographer.h
index d664020..b9c0001 100644
--- a/sync/util/cryptographer.h
+++ b/sync/util/cryptographer.h
@@ -98,6 +98,10 @@ 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;
@@ -169,6 +173,9 @@ 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;
+
// Update the cryptographer based on the contents of the nigori specifics.
// This updates both the encryption keys and the set of encrypted types.
// Returns NEEDS_PASSPHRASE if was unable to decrypt the pending keys,
@@ -186,7 +193,7 @@ class Cryptographer {
// Returns true if we currently have a keystore-derived nigori, false
// otherwise.
- bool HasKeystoreKey();
+ bool HasKeystoreKey() const;
// The set of types that are always encrypted.
static ModelTypeSet SensitiveTypes();
@@ -232,8 +239,9 @@ class Cryptographer {
// Does not update the default nigori.
void InstallKeyBag(const sync_pb::NigoriKeyBag& bag);
- // Helper method to add a nigori as the new default nigori.
- bool AddKeyImpl(Nigori* nigori);
+ // 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);
// Functions to serialize + encrypt a Nigori object in an opaque format for
// persistence by sync infrastructure.
diff --git a/sync/util/cryptographer_unittest.cc b/sync/util/cryptographer_unittest.cc
index d729311..01190e9 100644
--- a/sync/util/cryptographer_unittest.cc
+++ b/sync/util/cryptographer_unittest.cc
@@ -147,6 +147,19 @@ 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
@@ -220,6 +233,24 @@ 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());
+}
+
TEST_F(SyncCryptographerTest, NigoriEncryptionTypes) {
Cryptographer cryptographer2(&encryptor_);
sync_pb::NigoriSpecifics nigori;
diff --git a/sync/util/get_session_name.cc b/sync/util/get_session_name.cc
index 8c86c5c..99a4ce0 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)