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

Side by Side Diff: sync/engine/apply_control_data_updates_unittest.cc

Issue 10905191: [Sync] Add keystore migration conflict support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add more comments Created 8 years, 3 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/format_macros.h" 5 #include "base/format_macros.h"
6 #include "base/location.h" 6 #include "base/location.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/stringprintf.h" 8 #include "base/stringprintf.h"
9 #include "sync/engine/apply_control_data_updates.h" 9 #include "sync/engine/apply_control_data_updates.h"
10 #include "sync/engine/syncer.h" 10 #include "sync/engine/syncer.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 syncable::ReadTransaction trans(FROM_HERE, directory()); 50 syncable::ReadTransaction trans(FROM_HERE, directory());
51 } 51 }
52 52
53 TestIdFactory id_factory_; 53 TestIdFactory id_factory_;
54 scoped_ptr<TestEntryFactory> entry_factory_; 54 scoped_ptr<TestEntryFactory> entry_factory_;
55 private: 55 private:
56 DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest); 56 DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest);
57 }; 57 };
58 58
59 // Verify that applying a nigori node updates sets initial sync ended properly
rlarocque 2012/09/13 22:10:51 typo: "updates sets". Add comma after properly.
Nicolas Zea 2012/09/13 22:50:14 Done.
60 // updates the set of encrypted types, and updates the cryptographer.
59 TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) { 61 TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) {
60 // Storing the cryptographer separately is bad, but for this test we 62 // Storing the cryptographer separately is bad, but for this test we
61 // know it's safe. 63 // know it's safe.
62 Cryptographer* cryptographer; 64 Cryptographer* cryptographer;
63 ModelTypeSet encrypted_types; 65 ModelTypeSet encrypted_types;
64 encrypted_types.Put(PASSWORDS); 66 encrypted_types.Put(PASSWORDS);
65 67
66 // We start with initial_sync_ended == false. This is wrong, since would have 68 // We start with initial_sync_ended == false. This is wrong, since we would
67 // no nigori node if that were the case. Howerver, it makes it easier to 69 // have no nigori node if that were the case. However, it makes it easier to
68 // verify that ApplyControlDataUpdates sets initial_sync_ended correctly. 70 // verify that ApplyControlDataUpdates sets initial_sync_ended correctly.
69 EXPECT_FALSE(directory()->initial_sync_ended_types().Has(NIGORI)); 71 EXPECT_FALSE(directory()->initial_sync_ended_types().Has(NIGORI));
70 72
71 {
72 syncable::ReadTransaction trans(FROM_HERE, directory());
73 cryptographer = directory()->GetCryptographer(&trans);
74 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
75 .Equals(encrypted_types));
76 }
77
78 // Nigori node updates should update the Cryptographer.
79 Cryptographer other_cryptographer(cryptographer->encryptor());
80 KeyParams params = {"localhost", "dummy", "foobar"};
81 other_cryptographer.AddKey(params);
82
83 sync_pb::EntitySpecifics specifics;
84 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori();
85 other_cryptographer.GetKeys(nigori->mutable_encryption_keybag());
86 nigori->set_encrypt_everything(true);
87 entry_factory_->CreateUnappliedNewItem(
88 ModelTypeToRootTag(NIGORI), specifics, true);
89 EXPECT_FALSE(cryptographer->has_pending_keys());
90
91 ApplyControlDataUpdates(directory());
92
93 EXPECT_FALSE(cryptographer->is_ready());
94 EXPECT_TRUE(cryptographer->has_pending_keys());
95 {
96 syncable::ReadTransaction trans(FROM_HERE, directory());
97 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
98 .Equals(ModelTypeSet::All()));
99 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
100 }
101 }
102
103 TEST_F(ApplyControlDataUpdatesTest, NigoriUpdateForDisabledTypes) {
104 // Storing the cryptographer separately is bad, but for this test we
105 // know it's safe.
106 Cryptographer* cryptographer;
107 ModelTypeSet encrypted_types;
108 encrypted_types.Put(PASSWORDS);
109
110 // We start with initial_sync_ended == false. This is wrong, since would have
111 // no nigori node if that were the case. Howerver, it makes it easier to
112 // verify that ApplyControlDataUpdates sets initial_sync_ended correctly.
113 EXPECT_FALSE(directory()->initial_sync_ended_types().Has(NIGORI));
114
115 { 73 {
116 syncable::ReadTransaction trans(FROM_HERE, directory()); 74 syncable::ReadTransaction trans(FROM_HERE, directory());
117 cryptographer = directory()->GetCryptographer(&trans); 75 cryptographer = directory()->GetCryptographer(&trans);
118 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans) 76 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
119 .Equals(encrypted_types)); 77 .Equals(encrypted_types));
120 } 78 }
121 79
122 // Nigori node updates should update the Cryptographer. 80 // Nigori node updates should update the Cryptographer.
123 Cryptographer other_cryptographer(cryptographer->encryptor()); 81 Cryptographer other_cryptographer(cryptographer->encryptor());
124 KeyParams params = {"localhost", "dummy", "foobar"}; 82 KeyParams params = {"localhost", "dummy", "foobar"};
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans) 209 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
252 .Equals(ModelTypeSet::All())); 210 .Equals(ModelTypeSet::All()));
253 EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); 211 EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
254 212
255 Syncer::UnsyncedMetaHandles handles; 213 Syncer::UnsyncedMetaHandles handles;
256 GetUnsyncedEntries(&trans, &handles); 214 GetUnsyncedEntries(&trans, &handles);
257 EXPECT_EQ(2*batch_s+1, handles.size()); 215 EXPECT_EQ(2*batch_s+1, handles.size());
258 } 216 }
259 } 217 }
260 218
219 // Create some local unsynced and unencrypted changes. Receive a new nigori
220 // node enabling their encryption but also introducing pending keys. Ensure
221 // we apply the update properly without encrypting the unsynced changes or
222 // breaking.
261 TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) { 223 TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) {
262 // Storing the cryptographer separately is bad, but for this test we 224 // Storing the cryptographer separately is bad, but for this test we
263 // know it's safe. 225 // know it's safe.
264 Cryptographer* cryptographer; 226 Cryptographer* cryptographer;
265 ModelTypeSet encrypted_types; 227 ModelTypeSet encrypted_types;
266 encrypted_types.Put(PASSWORDS); 228 encrypted_types.Put(PASSWORDS);
267 { 229 {
268 syncable::ReadTransaction trans(FROM_HERE, directory()); 230 syncable::ReadTransaction trans(FROM_HERE, directory());
269 cryptographer = directory()->GetCryptographer(&trans); 231 cryptographer = directory()->GetCryptographer(&trans);
270 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans) 232 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 .Equals(ModelTypeSet::All())); 299 .Equals(ModelTypeSet::All()));
338 EXPECT_FALSE(cryptographer->is_ready()); 300 EXPECT_FALSE(cryptographer->is_ready());
339 EXPECT_TRUE(cryptographer->has_pending_keys()); 301 EXPECT_TRUE(cryptographer->has_pending_keys());
340 302
341 Syncer::UnsyncedMetaHandles handles; 303 Syncer::UnsyncedMetaHandles handles;
342 GetUnsyncedEntries(&trans, &handles); 304 GetUnsyncedEntries(&trans, &handles);
343 EXPECT_EQ(2*batch_s+1, handles.size()); 305 EXPECT_EQ(2*batch_s+1, handles.size());
344 } 306 }
345 } 307 }
346 308
309 // Verify we handle a nigori node conflict by merging encryption keys and
310 // types, but preserve the custom passphrase state of the server.
311 // Initial sync ended should be set.
312 TEST_F(ApplyControlDataUpdatesTest,
313 NigoriConflictPendingKeysServerEncryptEverythingCustom) {
314 Cryptographer* cryptographer;
315 ModelTypeSet encrypted_types(PASSWORDS);
rlarocque 2012/09/13 22:10:51 Consider using SensitiveTypes() here.
Nicolas Zea 2012/09/13 22:50:14 Done.
316 KeyParams other_params = {"localhost", "dummy", "foobar"};
317 KeyParams local_params = {"localhost", "dummy", "local"};
318 {
319 syncable::ReadTransaction trans(FROM_HERE, directory());
320 cryptographer = directory()->GetCryptographer(&trans);
321 EXPECT_TRUE(encrypted_types.Equals(
322 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
323 }
324
325 // Set up a temporary cryptographer to generate new keys with.
326 Cryptographer other_cryptographer(cryptographer->encryptor());
327 other_cryptographer.AddKey(other_params);
328
329 // Create server specifics with pending keys, new encrypted types,
330 // and a custom passphrase (unmigrated).
331 sync_pb::EntitySpecifics server_specifics;
332 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
333 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
334 server_nigori->set_encrypt_everything(true);
335 server_nigori->set_keybag_is_frozen(true);
336 int64 nigori_handle =
337 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
338 server_specifics,
339 true);
340
341 // Initialize the local cryptographer with the local keys.
342 cryptographer->AddKey(local_params);
343 EXPECT_TRUE(cryptographer->is_ready());
344
345 // Set up a local nigori with the local encryptio keys and default encrypted
rlarocque 2012/09/13 22:10:51 encryptio
Nicolas Zea 2012/09/13 22:50:14 Done.
346 // types.
347 sync_pb::EntitySpecifics local_specifics;
348 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
349 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
350 local_nigori->set_encrypt_everything(false);
351 local_nigori->set_keybag_is_frozen(true);
352 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
353 nigori_handle, LOCAL_SPECIFICS, local_specifics));
354 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
355 // to use.
356 {
357 syncable::ReadTransaction trans(FROM_HERE, directory());
358 cryptographer = directory()->GetCryptographer(&trans);
359 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
360 *local_nigori,
361 &trans);
362 }
363
364 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
365 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
366 ApplyControlDataUpdates(directory());
367 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
368 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
369
370 EXPECT_FALSE(cryptographer->is_ready());
371 EXPECT_TRUE(cryptographer->is_initialized());
372 EXPECT_TRUE(cryptographer->has_pending_keys());
373 EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
374 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
375 nigori().encryption_keybag()));
376 EXPECT_TRUE(entry_factory_->GetSpecificsForItem(
377 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
378 EXPECT_TRUE(
379 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
380 nigori().encrypt_everything());
381 {
382 syncable::ReadTransaction trans(FROM_HERE, directory());
383 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
384 .Equals(ModelTypeSet::All()));
385 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
386 }
387 }
388
389 // Verify we handle a nigori node conflict by merging encryption keys and
390 // types, but preserve the custom passphrase state of the server.
391 // Initial sync ended should be set.
392 TEST_F(ApplyControlDataUpdatesTest,
393 NigoriConflictPendingKeysLocalEncryptEverythingCustom) {
394 Cryptographer* cryptographer;
395 ModelTypeSet encrypted_types(PASSWORDS);
396 KeyParams other_params = {"localhost", "dummy", "foobar"};
397 KeyParams local_params = {"localhost", "dummy", "local"};
398 {
399 syncable::ReadTransaction trans(FROM_HERE, directory());
400 cryptographer = directory()->GetCryptographer(&trans);
401 EXPECT_TRUE(encrypted_types.Equals(
402 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
403 }
404
405 // Set up a temporary cryptographer to generate new keys with.
406 Cryptographer other_cryptographer(cryptographer->encryptor());
407 other_cryptographer.AddKey(other_params);
408
409 // Create server specifics with pending keys, new encrypted types,
410 // and a custom passphrase (unmigrated).
411 sync_pb::EntitySpecifics server_specifics;
412 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
413 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
414 server_nigori->set_encrypt_everything(false);
415 server_nigori->set_keybag_is_frozen(false);
416 int64 nigori_handle =
417 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
418 server_specifics,
419 true);
420
421 // Initialize the local cryptographer with the local keys.
422 cryptographer->AddKey(local_params);
423 EXPECT_TRUE(cryptographer->is_ready());
424
425 // Set up a local nigori with the local encryptio keys and default encrypted
rlarocque 2012/09/13 22:10:51 Typo here, too.
Nicolas Zea 2012/09/13 22:50:14 Done.
426 // types.
427 sync_pb::EntitySpecifics local_specifics;
428 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
429 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
430 local_nigori->set_encrypt_everything(true);
431 local_nigori->set_keybag_is_frozen(true);
432 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
433 nigori_handle, LOCAL_SPECIFICS, local_specifics));
434 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
435 // to use.
436 {
437 syncable::ReadTransaction trans(FROM_HERE, directory());
438 cryptographer = directory()->GetCryptographer(&trans);
439 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
440 *local_nigori,
441 &trans);
442 }
443
444 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
445 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
446 ApplyControlDataUpdates(directory());
447 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
448 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
449
450 EXPECT_FALSE(cryptographer->is_ready());
451 EXPECT_TRUE(cryptographer->is_initialized());
452 EXPECT_TRUE(cryptographer->has_pending_keys());
453 EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
454 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
455 nigori().encryption_keybag()));
456 EXPECT_FALSE(entry_factory_->GetSpecificsForItem(
457 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
458 EXPECT_TRUE(
459 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
460 nigori().encrypt_everything());
461 {
462 syncable::ReadTransaction trans(FROM_HERE, directory());
463 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
464 .Equals(ModelTypeSet::All()));
465 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
466 }
467 }
468
469 // If the conflicting nigori has a subset of the local keys, the conflict
470 // resolution should preserve the full local keys. Initial sync ended should be
471 // set.
472 TEST_F(ApplyControlDataUpdatesTest,
473 NigoriConflictOldKeys) {
474 Cryptographer* cryptographer;
475 ModelTypeSet encrypted_types(PASSWORDS);
476 KeyParams old_params = {"localhost", "dummy", "old"};
477 KeyParams new_params = {"localhost", "dummy", "new"};
478 {
479 syncable::ReadTransaction trans(FROM_HERE, directory());
480 cryptographer = directory()->GetCryptographer(&trans);
481 EXPECT_TRUE(encrypted_types.Equals(
482 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
483 }
484
485 // Set up the cryptographer with old keys
486 cryptographer->AddKey(old_params);
487
488 // Create server specifics with old keys and new encrypted types.
489 sync_pb::EntitySpecifics server_specifics;
490 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
491 cryptographer->GetKeys(server_nigori->mutable_encryption_keybag());
492 server_nigori->set_encrypt_everything(true);
493 int64 nigori_handle =
494 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
495 server_specifics,
496 true);
497
498 // Add the new keys to the cryptogrpaher
499 cryptographer->AddKey(new_params);
500 EXPECT_TRUE(cryptographer->is_ready());
501
502 // Set up a local nigori with the superset of keys.
503 sync_pb::EntitySpecifics local_specifics;
504 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
505 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
506 local_nigori->set_encrypt_everything(false);
507 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
508 nigori_handle, LOCAL_SPECIFICS, local_specifics));
509 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
510 // to use.
511 {
512 syncable::ReadTransaction trans(FROM_HERE, directory());
513 cryptographer = directory()->GetCryptographer(&trans);
514 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
515 *local_nigori,
516 &trans);
517 }
518
519 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
520 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
521 ApplyControlDataUpdates(directory());
522 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
523 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
524
525 EXPECT_TRUE(cryptographer->is_ready());
526 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
527 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
528 nigori().encryption_keybag()));
529 EXPECT_FALSE(entry_factory_->GetSpecificsForItem(
530 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
531 EXPECT_TRUE(
532 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
533 nigori().encrypt_everything());
534 {
535 syncable::ReadTransaction trans(FROM_HERE, directory());
536 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
537 .Equals(ModelTypeSet::All()));
538 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
539 }
540 }
541
542 // If both nigoris are migrated, but we also set a custom passphrase locally,
rlarocque 2012/09/13 22:10:51 Are you testing the other side of the if branch an
Nicolas Zea 2012/09/13 22:50:14 Yes, BothMigratedServerCustom hits that case.
543 // the local nigori should be preserved.
544 TEST_F(ApplyControlDataUpdatesTest,
545 NigoriConflictBothMigratedLocalCustom) {
546 Cryptographer* cryptographer;
547 ModelTypeSet encrypted_types(PASSWORDS);
548 KeyParams old_params = {"localhost", "dummy", "old"};
549 KeyParams new_params = {"localhost", "dummy", "new"};
550 {
551 syncable::ReadTransaction trans(FROM_HERE, directory());
552 cryptographer = directory()->GetCryptographer(&trans);
553 EXPECT_TRUE(encrypted_types.Equals(
554 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
555 }
556
557 // Set up the cryptographer with new keys
558 Cryptographer other_cryptographer(cryptographer->encryptor());
559 other_cryptographer.AddKey(old_params);
560
561 // Create server specifics with a migrated keystore passphrase type.
562 sync_pb::EntitySpecifics server_specifics;
563 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
564 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
565 server_nigori->set_encrypt_everything(false);
566 server_nigori->set_keybag_is_frozen(true);
567 server_nigori->set_passphrase_type(
568 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
569 server_nigori->mutable_keystore_decryptor_token();
570 int64 nigori_handle =
571 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
572 server_specifics,
573 true);
574
575 // Add the new keys to the cryptographer.
576 cryptographer->AddKey(old_params);
577 cryptographer->AddKey(new_params);
578 EXPECT_TRUE(cryptographer->is_ready());
579
580 // Set up a local nigori with a migrated custom passphrase type
581 sync_pb::EntitySpecifics local_specifics;
582 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
583 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
584 local_nigori->set_encrypt_everything(true);
585 local_nigori->set_keybag_is_frozen(true);
586 local_nigori->set_passphrase_type(
587 sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
588 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
589 nigori_handle, LOCAL_SPECIFICS, local_specifics));
590 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
591 // to use.
592 {
593 syncable::ReadTransaction trans(FROM_HERE, directory());
594 cryptographer = directory()->GetCryptographer(&trans);
595 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
596 *local_nigori,
597 &trans);
598 }
599
600 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
601 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
602 ApplyControlDataUpdates(directory());
603 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
604 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
605
606 EXPECT_TRUE(cryptographer->is_ready());
607 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
608 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
609 nigori().encryption_keybag()));
610 EXPECT_TRUE(entry_factory_->GetSpecificsForItem(
611 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
612 EXPECT_TRUE(
613 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
614 nigori().encrypt_everything());
615 EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
616 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
617 nigori().passphrase_type());
618 {
619 syncable::ReadTransaction trans(FROM_HERE, directory());
620 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
621 .Equals(ModelTypeSet::All()));
622 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
623 }
624 }
625
626 // If both nigoris are migrated, but a custom passphrase with a new key was
627 // set remotely, the remote nigori should be preserved.
628 TEST_F(ApplyControlDataUpdatesTest,
629 NigoriConflictBothMigratedServerCustom) {
630 Cryptographer* cryptographer;
631 ModelTypeSet encrypted_types(PASSWORDS);
632 KeyParams old_params = {"localhost", "dummy", "old"};
633 KeyParams new_params = {"localhost", "dummy", "new"};
634 {
635 syncable::ReadTransaction trans(FROM_HERE, directory());
636 cryptographer = directory()->GetCryptographer(&trans);
637 EXPECT_TRUE(encrypted_types.Equals(
638 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
639 }
640
641 // Set up the cryptographer with both new keys and old keys.
642 Cryptographer other_cryptographer(cryptographer->encryptor());
643 other_cryptographer.AddKey(old_params);
644 other_cryptographer.AddKey(new_params);
645
646 // Create server specifics with a migrated custom passphrase type.
647 sync_pb::EntitySpecifics server_specifics;
648 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
649 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
650 server_nigori->set_encrypt_everything(true);
651 server_nigori->set_keybag_is_frozen(true);
652 server_nigori->set_passphrase_type(
653 sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
654 int64 nigori_handle =
655 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
656 server_specifics,
657 true);
658
659 // Add the old keys to the cryptographer.
660 cryptographer->AddKey(old_params);
661 EXPECT_TRUE(cryptographer->is_ready());
662
663 // Set up a local nigori with a migrated keystore passphrase type
664 sync_pb::EntitySpecifics local_specifics;
665 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
666 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
667 local_nigori->set_encrypt_everything(false);
668 local_nigori->set_keybag_is_frozen(true);
669 local_nigori->set_passphrase_type(
670 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
671 server_nigori->mutable_keystore_decryptor_token();
672 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
673 nigori_handle, LOCAL_SPECIFICS, local_specifics));
674 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
675 // to use.
676 {
677 syncable::ReadTransaction trans(FROM_HERE, directory());
678 cryptographer = directory()->GetCryptographer(&trans);
679 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
680 *local_nigori,
681 &trans);
682 }
683
684 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
685 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
686 ApplyControlDataUpdates(directory());
687 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
688 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
689
690 EXPECT_TRUE(cryptographer->is_initialized());
691 EXPECT_TRUE(cryptographer->has_pending_keys());
692 EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
693 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
694 nigori().encryption_keybag()));
695 EXPECT_TRUE(entry_factory_->GetSpecificsForItem(
696 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
697 EXPECT_TRUE(
698 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
699 nigori().encrypt_everything());
700 EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
701 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
702 nigori().passphrase_type());
703 {
704 syncable::ReadTransaction trans(FROM_HERE, directory());
705 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
706 .Equals(ModelTypeSet::All()));
707 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
708 }
709 }
710
711 // If the local nigori is migrated but the server is not, preserve the local
712 // nigori.
713 TEST_F(ApplyControlDataUpdatesTest,
714 NigoriConflictLocalMigrated) {
715 Cryptographer* cryptographer;
716 ModelTypeSet encrypted_types(PASSWORDS);
717 KeyParams old_params = {"localhost", "dummy", "old"};
718 KeyParams new_params = {"localhost", "dummy", "new"};
719 {
720 syncable::ReadTransaction trans(FROM_HERE, directory());
721 cryptographer = directory()->GetCryptographer(&trans);
722 EXPECT_TRUE(encrypted_types.Equals(
723 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
724 }
725
726 // Set up the cryptographer with both new keys and old keys.
727 Cryptographer other_cryptographer(cryptographer->encryptor());
728 other_cryptographer.AddKey(old_params);
729
730 // Create server specifics with an unmigrated implicit passphrase type.
731 sync_pb::EntitySpecifics server_specifics;
732 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
733 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
734 server_nigori->set_encrypt_everything(true);
735 server_nigori->set_keybag_is_frozen(false);
736 int64 nigori_handle =
737 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
738 server_specifics,
739 true);
740
741 // Add the old keys to the cryptographer.
742 cryptographer->AddKey(old_params);
743 cryptographer->AddKey(new_params);
744 EXPECT_TRUE(cryptographer->is_ready());
745
746 // Set up a local nigori with a migrated custom passphrase type
747 sync_pb::EntitySpecifics local_specifics;
748 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
749 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
750 local_nigori->set_encrypt_everything(true);
751 local_nigori->set_keybag_is_frozen(true);
752 local_nigori->set_passphrase_type(
753 sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
754 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
755 nigori_handle, LOCAL_SPECIFICS, local_specifics));
756 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
757 // to use.
758 {
759 syncable::ReadTransaction trans(FROM_HERE, directory());
760 cryptographer = directory()->GetCryptographer(&trans);
761 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
762 *local_nigori,
763 &trans);
764 }
765
766 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
767 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
768 ApplyControlDataUpdates(directory());
769 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
770 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
771
772 EXPECT_TRUE(cryptographer->is_ready());
773 EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
774 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
775 nigori().encryption_keybag()));
776 EXPECT_TRUE(entry_factory_->GetSpecificsForItem(
777 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
778 EXPECT_TRUE(
779 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
780 nigori().encrypt_everything());
781 EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
782 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
783 nigori().passphrase_type());
784 {
785 syncable::ReadTransaction trans(FROM_HERE, directory());
786 EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
787 .Equals(ModelTypeSet::All()));
788 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
789 }
790 }
791
792 // If the server nigori is migrated but the local is not, preserve the server
793 // nigori.
794 TEST_F(ApplyControlDataUpdatesTest,
795 NigoriConflictServerMigrated) {
796 Cryptographer* cryptographer;
797 ModelTypeSet encrypted_types(PASSWORDS);
798 KeyParams old_params = {"localhost", "dummy", "old"};
799 KeyParams new_params = {"localhost", "dummy", "new"};
800 {
801 syncable::ReadTransaction trans(FROM_HERE, directory());
802 cryptographer = directory()->GetCryptographer(&trans);
803 EXPECT_TRUE(encrypted_types.Equals(
804 directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
805 }
806
807 // Set up the cryptographer with both new keys and old keys.
808 Cryptographer other_cryptographer(cryptographer->encryptor());
809 other_cryptographer.AddKey(old_params);
810
811 // Create server specifics with an migrated keystore passphrase type.
812 sync_pb::EntitySpecifics server_specifics;
813 sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
814 other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
815 server_nigori->set_encrypt_everything(false);
816 server_nigori->set_keybag_is_frozen(true);
817 server_nigori->set_passphrase_type(
818 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
819 server_nigori->mutable_keystore_decryptor_token();
820 int64 nigori_handle =
821 entry_factory_->CreateUnappliedNewItem(kNigoriTag,
822 server_specifics,
823 true);
824
825 // Add the old keys to the cryptographer.
826 cryptographer->AddKey(old_params);
827 cryptographer->AddKey(new_params);
828 EXPECT_TRUE(cryptographer->is_ready());
829
830 // Set up a local nigori with a migrated custom passphrase type
831 sync_pb::EntitySpecifics local_specifics;
832 sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
833 cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
834 local_nigori->set_encrypt_everything(false);
835 local_nigori->set_keybag_is_frozen(false);
836 ASSERT_TRUE(entry_factory_->SetSpecificsForItem(
837 nigori_handle, LOCAL_SPECIFICS, local_specifics));
838 // Apply the update locally so that UpdateFromEncryptedTypes knows what state
839 // to use.
840 {
841 syncable::ReadTransaction trans(FROM_HERE, directory());
842 cryptographer = directory()->GetCryptographer(&trans);
843 directory()->GetNigoriHandler()->ApplyNigoriUpdate(
844 *local_nigori,
845 &trans);
846 }
847
848 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
849 EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
850 ApplyControlDataUpdates(directory());
851 EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
852 EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
853
854 EXPECT_TRUE(cryptographer->is_ready());
855 // Note: we didn't overwrite the encryption keybag with the local keys. The
856 // sync encryption handler will do that when it detects that the new
857 // keybag is out of date (and update the keystore bootstrap if necessary).
858 EXPECT_FALSE(cryptographer->CanDecryptUsingDefaultKey(
859 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
860 nigori().encryption_keybag()));
861 EXPECT_TRUE(cryptographer->CanDecrypt(
862 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
863 nigori().encryption_keybag()));
864 EXPECT_TRUE(entry_factory_->GetSpecificsForItem(
865 nigori_handle, LOCAL_SPECIFICS).nigori().keybag_is_frozen());
866 EXPECT_TRUE(
867 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
868 nigori().has_keystore_decryptor_token());
869 EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE,
870 entry_factory_->GetSpecificsForItem(nigori_handle, LOCAL_SPECIFICS).
871 nigori().passphrase_type());
872 {
873 syncable::ReadTransaction trans(FROM_HERE, directory());
874 EXPECT_TRUE(directory()->initial_sync_ended_types().Has(NIGORI));
875 }
876 }
877
347 } // namespace syncer 878 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698