diff options
author | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-02 03:47:31 +0000 |
---|---|---|
committer | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-02 03:47:31 +0000 |
commit | eb1829899a437482e4f1da1179c83364a5d2197d (patch) | |
tree | 3a9b8001d7ab5e4d0dd017d01cdd632ea9d2e333 /chrome/browser/sync/profile_sync_service.cc | |
parent | 826884b21c8a853722f49a8229577f565fff0e60 (diff) | |
download | chromium_src-eb1829899a437482e4f1da1179c83364a5d2197d.zip chromium_src-eb1829899a437482e4f1da1179c83364a5d2197d.tar.gz chromium_src-eb1829899a437482e4f1da1179c83364a5d2197d.tar.bz2 |
[Sync] Ensure we always re-encrypt with newest gaia password if available.
Previously we would only re-encrypt an account that had implicit passphrases if,
on a password change, the client was already signed in. Otherwise, for example
if the user signs in to a new client, we would disregard the current credentials
because they are unable to decrypt the existing encrypted data (based on the old
gaia password).
This change ensures we do not throw away the old credentials. If we have pending
keys, we go ahead and generate new encryption keys based on the new credentials
and set those keys as the default. In addition, we persist the keys in the
bootstrap token for the cryptographer. In this way, the bootstrap token for
accounts using implicit passphrases will always correspond to the encryption
keys derived from the most recent gaia password.
Once the user supplies the old gaia password (which they will be prompted for
due to the cryptographer having pending keys), we will install it, but then
restore the encryption keys based on the current gaia password as the default.
This decision is made based on whether the pending keybag contains the current
default key or not. If it does, then the keybag must be newer than our data,
and we let it overwrite the default. If it does not, then our current key
is the newest, and we persist the current default.
In order to support this change, we plumb from the setup flow whether a
passphrase originates from the user or from an internal source (the
signin successful notification). In this way we can differentiate the current
implicit passphrase from an older user provided one.
BUG=104508
TEST=sync_unit_tests. All existing passphrase tests. Manually signing into
a clean account, setting up sync, signing out, changing the password, then
signing in to a new client. The new client should prompt for the old password,
but once provided should re-encrypt all data with the new password.
Subsequent new clients should not prompt for any old password.
Review URL: http://codereview.chromium.org/9309022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120157 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync/profile_sync_service.cc')
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 111c72b..20d6572 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -810,7 +810,9 @@ void ProfileSyncService::OnPassphraseRequired( cached_passphrases_.gaia_passphrase.clear(); DVLOG(1) << "Attempting gaia passphrase."; // SetPassphrase will re-cache this passphrase if the syncer isn't ready. - SetPassphrase(gaia_passphrase, false); + SetPassphrase(gaia_passphrase, IMPLICIT, + (cached_passphrases_.user_provided_gaia ? + USER_PROVIDED : INTERNAL)); return; } @@ -821,7 +823,7 @@ void ProfileSyncService::OnPassphraseRequired( cached_passphrases_.explicit_passphrase.clear(); DVLOG(1) << "Attempting explicit passphrase."; // SetPassphrase will re-cache this passphrase if the syncer isn't ready. - SetPassphrase(explicit_passphrase, true); + SetPassphrase(explicit_passphrase, EXPLICIT, USER_PROVIDED); return; } @@ -1288,15 +1290,27 @@ void ProfileSyncService::DeactivateDataType(syncable::ModelType type) { } void ProfileSyncService::SetPassphrase(const std::string& passphrase, - bool is_explicit) { + PassphraseType type, + PassphraseSource source) { + DCHECK(source == USER_PROVIDED || type == IMPLICIT); if (ShouldPushChanges() || IsPassphraseRequired()) { - DVLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit"); - backend_->SetPassphrase(passphrase, is_explicit); + DVLOG(1) << "Setting " << (type == EXPLICIT ? "explicit" : "implicit") + << " passphrase."; + backend_->SetPassphrase(passphrase, + type == EXPLICIT, + source == USER_PROVIDED); } else { - if (is_explicit) { + if (type == EXPLICIT) { + NOTREACHED() << "SetPassphrase should only be called after the backend " + << "is initialized."; cached_passphrases_.explicit_passphrase = passphrase; } else { cached_passphrases_.gaia_passphrase = passphrase; + cached_passphrases_.user_provided_gaia = (source == USER_PROVIDED); + DVLOG(1) << "Caching " + << (cached_passphrases_.user_provided_gaia ? "user provided" : + "internal") + << " gaia passphrase."; } } } @@ -1437,13 +1451,12 @@ void ProfileSyncService::Observe(int type, // want to suppress start up anymore. sync_prefs_.SetStartSuppressed(false); - // We pass 'false' to SetPassphrase to denote that this is an implicit - // request and shouldn't override an explicit one. Thus, we either - // update the implicit passphrase (idempotent if the passphrase didn't - // actually change), or the user has an explicit passphrase set so this - // becomes a no-op. + // Because we specify IMPLICIT to SetPassphrase, we know it won't override + // an explicit one. Thus, we either update the implicit passphrase + // (idempotent if the passphrase didn't actually change), or the user has + // an explicit passphrase set so this becomes a no-op. if (!successful->password.empty()) - SetPassphrase(successful->password, false); + SetPassphrase(successful->password, IMPLICIT, INTERNAL); break; } case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |