Index: chrome/browser/sync/engine/syncer_util.cc |
diff --git a/chrome/browser/sync/engine/syncer_util.cc b/chrome/browser/sync/engine/syncer_util.cc |
index ba9d3a2026cdf0ed87d1f10109fb0856e004fcbb..9f96d11f8c6e744f7e95b66f74a12f48b30e477d 100644 |
--- a/chrome/browser/sync/engine/syncer_util.cc |
+++ b/chrome/browser/sync/engine/syncer_util.cc |
@@ -17,6 +17,7 @@ |
#include "chrome/browser/sync/protocol/sync.pb.h" |
#include "chrome/browser/sync/syncable/directory_manager.h" |
#include "chrome/browser/sync/syncable/model_type.h" |
+#include "chrome/browser/sync/syncable/nigori_util.h" |
#include "chrome/browser/sync/syncable/syncable.h" |
#include "chrome/browser/sync/syncable/syncable_changes_version.h" |
@@ -286,8 +287,9 @@ UpdateAttemptResponse SyncerUtil::AttemptToUpdateEntry( |
} |
} |
- // We intercept updates to the Nigori node and update the Cryptographer here |
- // because there is no Nigori ChangeProcessor. |
+ // We intercept updates to the Nigori node, update the Cryptographer and |
+ // encrypt any unsynced changes here because there is no Nigori |
+ // ChangeProcessor. |
const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS); |
if (specifics.HasExtension(sync_pb::nigori)) { |
const sync_pb::NigoriSpecifics& nigori = |
@@ -299,17 +301,40 @@ UpdateAttemptResponse SyncerUtil::AttemptToUpdateEntry( |
cryptographer->SetPendingKeys(nigori.encrypted()); |
} |
} |
+ |
+ // Make sure any unsynced changes are properly encrypted as necessary. |
+ syncable::ModelTypeSet encrypted_types = |
+ syncable::GetEncryptedDatatypesFromNigori(nigori); |
+ if (!syncable::ProcessUnsyncedChangesForEncryption(trans, encrypted_types, |
+ cryptographer)) { |
+ // We were unable to encrypt the changes, possibly due to a missing |
+ // passphrase. |
+ return CONFLICT; |
+ } |
+ |
+ // Note that we don't bother to encrypt any synced data that now requires |
+ // encryption. The machine that turned on encryption should encrypt |
+ // everything itself. It's possible it could get interrupted during this |
+ // process, but we currently reencrypt everything at startup as well, |
+ // so as soon as a client is restarted with this datatype encrypted, all the |
+ // data should be updated as necessary. |
} |
// Only apply updates that we can decrypt. Updates that can't be decrypted yet |
// will stay in conflict until the user provides a passphrase that lets the |
// Cryptographer decrypt them. |
- if (!entry->Get(SERVER_IS_DIR) && specifics.HasExtension(sync_pb::password)) { |
- const sync_pb::PasswordSpecifics& password = |
- specifics.GetExtension(sync_pb::password); |
- if (!cryptographer->CanDecrypt(password.encrypted())) { |
+ if (!entry->Get(SERVER_IS_DIR)) { |
+ if (specifics.has_encrypted() && |
+ !cryptographer->CanDecrypt(specifics.encrypted())) { |
// We can't decrypt this node yet. |
return CONFLICT; |
+ } else if (specifics.HasExtension(sync_pb::password)) { |
+ // Passwords use their own legacy encryption scheme. |
+ const sync_pb::PasswordSpecifics& password = |
+ specifics.GetExtension(sync_pb::password); |
+ if (!cryptographer->CanDecrypt(password.encrypted())) { |
+ return CONFLICT; |
+ } |
} |
} |