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

Side by Side Diff: sync/internal_api/sync_encryption_handler_impl.cc

Issue 10824410: [Sync] Refactor passphrase state handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 4 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 "sync/internal_api/sync_encryption_handler_impl.h" 5 #include "sync/internal_api/sync_encryption_handler_impl.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 22 matching lines...) Expand all
33 // because the encryption keys don't match (per chrome instantiation). 33 // because the encryption keys don't match (per chrome instantiation).
34 // We protect ourselves against nigori rollbacks, but it's possible two 34 // We protect ourselves against nigori rollbacks, but it's possible two
35 // different clients might have contrasting view of what the nigori node state 35 // different clients might have contrasting view of what the nigori node state
36 // should be, in which case they might ping pong (see crbug.com/119207). 36 // should be, in which case they might ping pong (see crbug.com/119207).
37 static const int kNigoriOverwriteLimit = 10; 37 static const int kNigoriOverwriteLimit = 10;
38 } 38 }
39 39
40 SyncEncryptionHandlerImpl::Vault::Vault( 40 SyncEncryptionHandlerImpl::Vault::Vault(
41 Encryptor* encryptor, 41 Encryptor* encryptor,
42 ModelTypeSet encrypted_types) 42 ModelTypeSet encrypted_types)
43 : cryptographer(encryptor), 43 : cryptographer(encryptor),
44 encrypted_types(encrypted_types) { 44 encrypted_types(encrypted_types) {
45 } 45 }
46 46
47 SyncEncryptionHandlerImpl::Vault::~Vault() { 47 SyncEncryptionHandlerImpl::Vault::~Vault() {
48 } 48 }
49 49
50 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( 50 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
51 UserShare* user_share, 51 UserShare* user_share,
52 Encryptor* encryptor) 52 Encryptor* encryptor)
53 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 53 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
54 user_share_(user_share), 54 user_share_(user_share),
55 vault_unsafe_(encryptor, SensitiveTypes()), 55 vault_unsafe_(encryptor, SensitiveTypes()),
56 encrypt_everything_(false), 56 encrypt_everything_(false),
57 explicit_passphrase_(false), 57 passphrase_state_(IMPLICIT_PASSPHRASE),
58 nigori_overwrite_count_(0) { 58 nigori_overwrite_count_(0) {
59 } 59 }
60 60
61 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} 61 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
62 62
63 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { 63 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
64 DCHECK(thread_checker_.CalledOnValidThread()); 64 DCHECK(thread_checker_.CalledOnValidThread());
65 DCHECK(!observers_.HasObserver(observer)); 65 DCHECK(!observers_.HasObserver(observer));
66 observers_.AddObserver(observer); 66 observers_.AddObserver(observer);
67 } 67 }
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 WriteEncryptionStateToNigori(&trans); 383 WriteEncryptionStateToNigori(&trans);
384 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) 384 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
385 ReEncryptEverything(&trans); 385 ReEncryptEverything(&trans);
386 } 386 }
387 387
388 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const { 388 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
389 DCHECK(thread_checker_.CalledOnValidThread()); 389 DCHECK(thread_checker_.CalledOnValidThread());
390 return encrypt_everything_; 390 return encrypt_everything_;
391 } 391 }
392 392
393 bool SyncEncryptionHandlerImpl::IsUsingExplicitPassphrase() const { 393 PassphraseState SyncEncryptionHandlerImpl::GetPassphraseState() const {
394 // TODO(zea): this is called from the UI thread, so we have to have a 394 DCHECK(thread_checker_.CalledOnValidThread());
395 // transaction while accessing it. Add an OnPassphraseTypeChanged observer 395 return passphrase_state_;
396 // and have the SBH cache the value on the UI thread.
397 ReadTransaction trans(FROM_HERE, user_share_);
398 return explicit_passphrase_;
399 } 396 }
400 397
401 // Note: this is called from within a syncable transaction, so we need to post 398 // Note: this is called from within a syncable transaction, so we need to post
402 // tasks if we want to do any work that creates a new sync_api transaction. 399 // tasks if we want to do any work that creates a new sync_api transaction.
403 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate( 400 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
404 const sync_pb::NigoriSpecifics& nigori, 401 const sync_pb::NigoriSpecifics& nigori,
405 syncable::BaseTransaction* const trans) { 402 syncable::BaseTransaction* const trans) {
406 DCHECK(thread_checker_.CalledOnValidThread()); 403 DCHECK(thread_checker_.CalledOnValidThread());
407 DCHECK(trans); 404 DCHECK(trans);
408 if (!ApplyNigoriUpdateImpl(nigori, trans)) { 405 if (!ApplyNigoriUpdateImpl(nigori, trans)) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 507
511 // NOTE: We notify from within a transaction. 508 // NOTE: We notify from within a transaction.
512 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 509 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
513 OnEncryptionComplete()); 510 OnEncryptionComplete());
514 } 511 }
515 512
516 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( 513 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
517 const sync_pb::NigoriSpecifics& nigori, 514 const sync_pb::NigoriSpecifics& nigori,
518 syncable::BaseTransaction* const trans) { 515 syncable::BaseTransaction* const trans) {
519 DCHECK(thread_checker_.CalledOnValidThread()); 516 DCHECK(thread_checker_.CalledOnValidThread());
517 DVLOG(1) << "Applying nigori node update.";
520 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori, 518 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
521 trans); 519 trans);
522 if (nigori.using_explicit_passphrase()) 520 if (nigori.using_explicit_passphrase() &&
523 explicit_passphrase_ = true; 521 passphrase_state_ != CUSTOM_PASSPHRASE) {
522 passphrase_state_ = CUSTOM_PASSPHRASE;
523 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
524 OnPassphraseStateChanged(passphrase_state_));
525 }
524 526
525 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; 527 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
526 bool nigori_needs_new_keys = false; 528 bool nigori_needs_new_keys = false;
527 if (!nigori.encrypted().blob().empty()) { 529 if (!nigori.encrypted().blob().empty()) {
528 if (cryptographer->CanDecrypt(nigori.encrypted())) { 530 if (cryptographer->CanDecrypt(nigori.encrypted())) {
529 cryptographer->InstallKeys(nigori.encrypted()); 531 cryptographer->InstallKeys(nigori.encrypted());
530 // We only update the default passphrase if this was a new explicit 532 // We only update the default passphrase if this was a new explicit
531 // passphrase. Else, since it was decryptable, it must not have been a new 533 // passphrase. Else, since it was decryptable, it must not have been a new
532 // key. 534 // key.
533 if (nigori.using_explicit_passphrase()) 535 if (nigori.using_explicit_passphrase())
(...skipping 26 matching lines...) Expand all
560 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " 562 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
561 << "ready"; 563 << "ready";
562 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 564 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
563 OnPassphraseRequired(REASON_ENCRYPTION, 565 OnPassphraseRequired(REASON_ENCRYPTION,
564 sync_pb::EncryptedData())); 566 sync_pb::EncryptedData()));
565 } 567 }
566 568
567 // Check if the current local encryption state is stricter/newer than the 569 // Check if the current local encryption state is stricter/newer than the
568 // nigori state. If so, we need to overwrite the nigori node with the local 570 // nigori state. If so, we need to overwrite the nigori node with the local
569 // state. 571 // state.
570 if (nigori.using_explicit_passphrase() != explicit_passphrase_ || 572 bool explicit_passphrase = passphrase_state_ == CUSTOM_PASSPHRASE;
573 if (nigori.using_explicit_passphrase() != explicit_passphrase ||
571 nigori.encrypt_everything() != encrypt_everything_ || 574 nigori.encrypt_everything() != encrypt_everything_ ||
572 nigori_types_need_update || 575 nigori_types_need_update ||
573 nigori_needs_new_keys) { 576 nigori_needs_new_keys) {
574 return false; 577 return false;
575 } 578 }
576 return true; 579 return true;
577 } 580 }
578 581
579 void SyncEncryptionHandlerImpl::RewriteNigori() { 582 void SyncEncryptionHandlerImpl::RewriteNigori() {
580 DVLOG(1) << "Overwriting stale nigori node."; 583 DVLOG(1) << "Overwriting stale nigori node.";
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 FOR_EACH_OBSERVER( 679 FOR_EACH_OBSERVER(
677 SyncEncryptionHandler::Observer, 680 SyncEncryptionHandler::Observer,
678 observers_, 681 observers_,
679 OnCryptographerStateChanged( 682 OnCryptographerStateChanged(
680 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer)); 683 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
681 684
682 // It's possible we need to change the bootstrap token even if we failed to 685 // It's possible we need to change the bootstrap token even if we failed to
683 // set the passphrase (for example if we need to preserve the new GAIA 686 // set the passphrase (for example if we need to preserve the new GAIA
684 // passphrase). 687 // passphrase).
685 if (!bootstrap_token.empty()) { 688 if (!bootstrap_token.empty()) {
686 DVLOG(1) << "Bootstrap token updated."; 689 DVLOG(1) << "Passphrase bootstrap token updated.";
687 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 690 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
688 OnBootstrapTokenUpdated(bootstrap_token)); 691 OnBootstrapTokenUpdated(bootstrap_token));
689 } 692 }
690 693
691 const Cryptographer& cryptographer = 694 const Cryptographer& cryptographer =
692 UnlockVault(trans->GetWrappedTrans()).cryptographer; 695 UnlockVault(trans->GetWrappedTrans()).cryptographer;
693 if (!success) { 696 if (!success) {
694 if (cryptographer.is_ready()) { 697 if (cryptographer.is_ready()) {
695 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer " 698 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer "
696 << "was ready."; 699 << "was ready.";
697 } else if (cryptographer.has_pending_keys()) { 700 } else if (cryptographer.has_pending_keys()) {
698 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 701 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
699 OnPassphraseRequired(REASON_DECRYPTION, 702 OnPassphraseRequired(REASON_DECRYPTION,
700 cryptographer.GetPendingKeys())); 703 cryptographer.GetPendingKeys()));
701 } else { 704 } else {
702 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 705 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
703 OnPassphraseRequired(REASON_ENCRYPTION, 706 OnPassphraseRequired(REASON_ENCRYPTION,
704 sync_pb::EncryptedData())); 707 sync_pb::EncryptedData()));
705 } 708 }
706 return; 709 return;
707 } 710 }
708 711
709 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
710 OnPassphraseAccepted());
711 DCHECK(cryptographer.is_ready()); 712 DCHECK(cryptographer.is_ready());
712 713
713 sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics()); 714 sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics());
714 // Does not modify specifics.encrypted() if the original decrypted data was 715 // Does not modify specifics.encrypted() if the original decrypted data was
715 // the same. 716 // the same.
716 if (!cryptographer.GetKeys(specifics.mutable_encrypted())) 717 if (!cryptographer.GetKeys(specifics.mutable_encrypted()))
717 NOTREACHED(); 718 NOTREACHED();
718 explicit_passphrase_ = is_explicit; 719 if (is_explicit && passphrase_state_ != CUSTOM_PASSPHRASE) {
720 passphrase_state_ = CUSTOM_PASSPHRASE;
721 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
722 OnPassphraseStateChanged(passphrase_state_));
723 }
719 specifics.set_using_explicit_passphrase(is_explicit); 724 specifics.set_using_explicit_passphrase(is_explicit);
720 nigori_node->SetNigoriSpecifics(specifics); 725 nigori_node->SetNigoriSpecifics(specifics);
721 726
727 // Must do this after OnPassphraseStateChanged, in order to ensure the PSS
728 // checks the passphrase state after it has been set.
729 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
730 OnPassphraseAccepted());
731
722 // Does nothing if everything is already encrypted. 732 // Does nothing if everything is already encrypted.
723 ReEncryptEverything(trans); 733 ReEncryptEverything(trans);
724 } 734 }
725 735
726 void SyncEncryptionHandlerImpl::MergeEncryptedTypes( 736 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
727 ModelTypeSet new_encrypted_types, 737 ModelTypeSet new_encrypted_types,
728 syncable::BaseTransaction* const trans) { 738 syncable::BaseTransaction* const trans) {
729 DCHECK(thread_checker_.CalledOnValidThread()); 739 DCHECK(thread_checker_.CalledOnValidThread());
730 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types; 740 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
731 if (!encrypted_types->HasAll(new_encrypted_types)) { 741 if (!encrypted_types->HasAll(new_encrypted_types)) {
(...skipping 10 matching lines...) Expand all
742 return &vault_unsafe_; 752 return &vault_unsafe_;
743 } 753 }
744 754
745 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault( 755 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
746 syncable::BaseTransaction* const trans) const { 756 syncable::BaseTransaction* const trans) const {
747 DCHECK_EQ(user_share_->directory.get(), trans->directory()); 757 DCHECK_EQ(user_share_->directory.get(), trans->directory());
748 return vault_unsafe_; 758 return vault_unsafe_;
749 } 759 }
750 760
751 } // namespace browser_sync 761 } // namespace browser_sync
OLDNEW
« no previous file with comments | « sync/internal_api/sync_encryption_handler_impl.h ('k') | sync/internal_api/sync_encryption_handler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698