Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: chrome/browser/sync/engine/syncer_util.cc

Issue 6465005: [Sync] Initial support for encrypting any datatype (no UI hookup yet). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Rest of unit tests. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/engine/syncer_util.h" 5 #include "chrome/browser/sync/engine/syncer_util.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "chrome/browser/sync/engine/conflict_resolver.h" 11 #include "chrome/browser/sync/engine/conflict_resolver.h"
12 #include "chrome/browser/sync/engine/syncer_proto_util.h" 12 #include "chrome/browser/sync/engine/syncer_proto_util.h"
13 #include "chrome/browser/sync/engine/syncer_types.h" 13 #include "chrome/browser/sync/engine/syncer_types.h"
14 #include "chrome/browser/sync/engine/syncproto.h" 14 #include "chrome/browser/sync/engine/syncproto.h"
15 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 15 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
16 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" 16 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
17 #include "chrome/browser/sync/protocol/sync.pb.h" 17 #include "chrome/browser/sync/protocol/sync.pb.h"
18 #include "chrome/browser/sync/syncable/directory_manager.h" 18 #include "chrome/browser/sync/syncable/directory_manager.h"
19 #include "chrome/browser/sync/syncable/model_type.h" 19 #include "chrome/browser/sync/syncable/model_type.h"
20 #include "chrome/browser/sync/syncable/nigori_util.h"
20 #include "chrome/browser/sync/syncable/syncable.h" 21 #include "chrome/browser/sync/syncable/syncable.h"
21 #include "chrome/browser/sync/syncable/syncable_changes_version.h" 22 #include "chrome/browser/sync/syncable/syncable_changes_version.h"
22 23
23 using syncable::BASE_VERSION; 24 using syncable::BASE_VERSION;
24 using syncable::Blob; 25 using syncable::Blob;
25 using syncable::CHANGES_VERSION; 26 using syncable::CHANGES_VERSION;
26 using syncable::CREATE; 27 using syncable::CREATE;
27 using syncable::CREATE_NEW_UPDATE_ITEM; 28 using syncable::CREATE_NEW_UPDATE_ITEM;
28 using syncable::CTIME; 29 using syncable::CTIME;
29 using syncable::ComparePathNames; 30 using syncable::ComparePathNames;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 Directory::ChildHandles handles; 280 Directory::ChildHandles handles;
280 trans->directory()->GetChildHandles(trans, id, &handles); 281 trans->directory()->GetChildHandles(trans, id, &handles);
281 if (!handles.empty()) { 282 if (!handles.empty()) {
282 // If we have still-existing children, then we need to deal with 283 // If we have still-existing children, then we need to deal with
283 // them before we can process this change. 284 // them before we can process this change.
284 VLOG(1) << "Not deleting directory; it's not empty " << *entry; 285 VLOG(1) << "Not deleting directory; it's not empty " << *entry;
285 return CONFLICT; 286 return CONFLICT;
286 } 287 }
287 } 288 }
288 289
289 // We intercept updates to the Nigori node and update the Cryptographer here 290 // We intercept updates to the Nigori node, update the Cryptographer and
290 // because there is no Nigori ChangeProcessor. 291 // encrypt any unsynced changes here because there is no Nigori
292 // ChangeProcessor.
291 const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS); 293 const sync_pb::EntitySpecifics& specifics = entry->Get(SERVER_SPECIFICS);
292 if (specifics.HasExtension(sync_pb::nigori)) { 294 if (specifics.HasExtension(sync_pb::nigori)) {
293 const sync_pb::NigoriSpecifics& nigori = 295 const sync_pb::NigoriSpecifics& nigori =
294 specifics.GetExtension(sync_pb::nigori); 296 specifics.GetExtension(sync_pb::nigori);
295 if (!nigori.encrypted().blob().empty()) { 297 if (!nigori.encrypted().blob().empty()) {
296 if (cryptographer->CanDecrypt(nigori.encrypted())) { 298 if (cryptographer->CanDecrypt(nigori.encrypted())) {
297 cryptographer->SetKeys(nigori.encrypted()); 299 cryptographer->SetKeys(nigori.encrypted());
298 } else { 300 } else {
299 cryptographer->SetPendingKeys(nigori.encrypted()); 301 cryptographer->SetPendingKeys(nigori.encrypted());
300 } 302 }
301 } 303 }
304
305 // Make sure any unsynced changes are properly encrypted as necessary.
306 syncable::ModelTypeSet encrypted_types =
307 syncable::GetEncryptedDataTypesFromNigori(nigori);
308 if (!VerifyUnsyncedChangesAreEncrypted(trans, encrypted_types) &&
309 (!cryptographer->is_ready() ||
310 !syncable::ProcessUnsyncedChangesForEncryption(trans, encrypted_types,
311 cryptographer))) {
312 // We were unable to encrypt the changes, possibly due to a missing
313 // passphrase. We return conflict, even though the conflict is with the
314 // unsynced change and not the nigori node. We ensure foward progress
315 // because the cryptographer already has the pending keys set, so once
316 // the new passphrase is entered we should be able to encrypt properly.
317 // And, because this update will not be applied yet, next time around
318 // we will properly encrypt all appropriate unsynced data.
319 VLOG(1) << "Marking nigori node update as conflicting due to being unable"
320 << " to encrypt all necessary unsynced changes.";
321 return CONFLICT;
322 }
323
324 // Note that we don't bother to encrypt any synced data that now requires
325 // encryption. The machine that turned on encryption should encrypt
326 // everything itself. It's possible it could get interrupted during this
327 // process, but we currently reencrypt everything at startup as well,
328 // so as soon as a client is restarted with this datatype encrypted, all the
329 // data should be updated as necessary.
302 } 330 }
303 331
304 // Only apply updates that we can decrypt. Updates that can't be decrypted yet 332 // Only apply updates that we can decrypt. Updates that can't be decrypted yet
305 // will stay in conflict until the user provides a passphrase that lets the 333 // will stay in conflict until the user provides a passphrase that lets the
306 // Cryptographer decrypt them. 334 // Cryptographer decrypt them.
307 if (!entry->Get(SERVER_IS_DIR) && specifics.HasExtension(sync_pb::password)) { 335 if (!entry->Get(SERVER_IS_DIR)) {
308 const sync_pb::PasswordSpecifics& password = 336 if (specifics.has_encrypted() &&
309 specifics.GetExtension(sync_pb::password); 337 !cryptographer->CanDecrypt(specifics.encrypted())) {
310 if (!cryptographer->CanDecrypt(password.encrypted())) {
311 // We can't decrypt this node yet. 338 // We can't decrypt this node yet.
312 return CONFLICT; 339 return CONFLICT;
340 } else if (specifics.HasExtension(sync_pb::password)) {
341 // Passwords use their own legacy encryption scheme.
342 const sync_pb::PasswordSpecifics& password =
343 specifics.GetExtension(sync_pb::password);
344 if (!cryptographer->CanDecrypt(password.encrypted())) {
345 return CONFLICT;
346 }
313 } 347 }
314 } 348 }
315 349
316 SyncerUtil::UpdateLocalDataFromServerData(trans, entry); 350 SyncerUtil::UpdateLocalDataFromServerData(trans, entry);
317 351
318 return SUCCESS; 352 return SUCCESS;
319 } 353 }
320 354
321 namespace { 355 namespace {
322 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally, 356 // Helper to synthesize a new-style sync_pb::EntitySpecifics for use locally,
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 896
863 // |update_entry| is considered to be somewhere after |candidate|, so store 897 // |update_entry| is considered to be somewhere after |candidate|, so store
864 // it as the upper bound. 898 // it as the upper bound.
865 closest_sibling = candidate.Get(ID); 899 closest_sibling = candidate.Get(ID);
866 } 900 }
867 901
868 return closest_sibling; 902 return closest_sibling;
869 } 903 }
870 904
871 } // namespace browser_sync 905 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698