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

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

Issue 302173004: sync: Specialize functions that fetch type root (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: s/GET_BY_SERVER_TAG_DEPRECATED/GET_BY_SERVER_TAG/ Created 6 years, 6 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/base64.h" 10 #include "base/base64.h"
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 DCHECK(thread_checker_.CalledOnValidThread()); 241 DCHECK(thread_checker_.CalledOnValidThread());
242 DCHECK(observers_.HasObserver(observer)); 242 DCHECK(observers_.HasObserver(observer));
243 observers_.RemoveObserver(observer); 243 observers_.RemoveObserver(observer);
244 } 244 }
245 245
246 void SyncEncryptionHandlerImpl::Init() { 246 void SyncEncryptionHandlerImpl::Init() {
247 DCHECK(thread_checker_.CalledOnValidThread()); 247 DCHECK(thread_checker_.CalledOnValidThread());
248 WriteTransaction trans(FROM_HERE, user_share_); 248 WriteTransaction trans(FROM_HERE, user_share_);
249 WriteNode node(&trans); 249 WriteNode node(&trans);
250 250
251 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 251 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
252 return; 252 return;
253 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(), 253 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(),
254 trans.GetWrappedTrans())) { 254 trans.GetWrappedTrans())) {
255 WriteEncryptionStateToNigori(&trans); 255 WriteEncryptionStateToNigori(&trans);
256 } 256 }
257 257
258 bool has_pending_keys = UnlockVault( 258 bool has_pending_keys = UnlockVault(
259 trans.GetWrappedTrans()).cryptographer.has_pending_keys(); 259 trans.GetWrappedTrans()).cryptographer.has_pending_keys();
260 bool is_ready = UnlockVault( 260 bool is_ready = UnlockVault(
261 trans.GetWrappedTrans()).cryptographer.is_ready(); 261 trans.GetWrappedTrans()).cryptographer.is_ready();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 // We do not accept empty passphrases. 325 // We do not accept empty passphrases.
326 if (passphrase.empty()) { 326 if (passphrase.empty()) {
327 NOTREACHED() << "Cannot encrypt with an empty passphrase."; 327 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
328 return; 328 return;
329 } 329 }
330 330
331 // All accesses to the cryptographer are protected by a transaction. 331 // All accesses to the cryptographer are protected by a transaction.
332 WriteTransaction trans(FROM_HERE, user_share_); 332 WriteTransaction trans(FROM_HERE, user_share_);
333 KeyParams key_params = {"localhost", "dummy", passphrase}; 333 KeyParams key_params = {"localhost", "dummy", passphrase};
334 WriteNode node(&trans); 334 WriteNode node(&trans);
335 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 335 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
336 NOTREACHED(); 336 NOTREACHED();
337 return; 337 return;
338 } 338 }
339 339
340 Cryptographer* cryptographer = 340 Cryptographer* cryptographer =
341 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer; 341 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
342 342
343 // Once we've migrated to keystore, the only way to set a passphrase for 343 // Once we've migrated to keystore, the only way to set a passphrase for
344 // encryption is to set a custom passphrase. 344 // encryption is to set a custom passphrase.
345 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) { 345 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 // We do not accept empty passphrases. 477 // We do not accept empty passphrases.
478 if (passphrase.empty()) { 478 if (passphrase.empty()) {
479 NOTREACHED() << "Cannot decrypt with an empty passphrase."; 479 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
480 return; 480 return;
481 } 481 }
482 482
483 // All accesses to the cryptographer are protected by a transaction. 483 // All accesses to the cryptographer are protected by a transaction.
484 WriteTransaction trans(FROM_HERE, user_share_); 484 WriteTransaction trans(FROM_HERE, user_share_);
485 KeyParams key_params = {"localhost", "dummy", passphrase}; 485 KeyParams key_params = {"localhost", "dummy", passphrase};
486 WriteNode node(&trans); 486 WriteNode node(&trans);
487 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 487 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
488 NOTREACHED(); 488 NOTREACHED();
489 return; 489 return;
490 } 490 }
491 491
492 // Once we've migrated to keystore, we're only ever decrypting keys derived 492 // Once we've migrated to keystore, we're only ever decrypting keys derived
493 // from an explicit passphrase. But, for clients without a keystore key yet 493 // from an explicit passphrase. But, for clients without a keystore key yet
494 // (either not on by default or failed to download one), we still support 494 // (either not on by default or failed to download one), we still support
495 // decrypting with a gaia passphrase, and therefore bypass the 495 // decrypting with a gaia passphrase, and therefore bypass the
496 // DecryptPendingKeysWithExplicitPassphrase logic. 496 // DecryptPendingKeysWithExplicitPassphrase logic.
497 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) && 497 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 cryptographer->encryptor()); 710 cryptographer->encryptor());
711 DCHECK_EQ(keystore_bootstrap.empty(), keystore_key_.empty()); 711 DCHECK_EQ(keystore_bootstrap.empty(), keystore_key_.empty());
712 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 712 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
713 OnBootstrapTokenUpdated(keystore_bootstrap, 713 OnBootstrapTokenUpdated(keystore_bootstrap,
714 KEYSTORE_BOOTSTRAP_TOKEN)); 714 KEYSTORE_BOOTSTRAP_TOKEN));
715 DVLOG(1) << "Keystore bootstrap token updated."; 715 DVLOG(1) << "Keystore bootstrap token updated.";
716 716
717 // If this is a first time sync, we get the encryption keys before we process 717 // If this is a first time sync, we get the encryption keys before we process
718 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked 718 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
719 // once we have the nigori node. 719 // once we have the nigori node.
720 syncable::Entry entry(trans, syncable::GET_BY_SERVER_TAG, kNigoriTag); 720 syncable::Entry entry(trans, syncable::GET_TYPE_ROOT, NIGORI);
721 if (!entry.good()) 721 if (!entry.good())
722 return true; 722 return true;
723 723
724 const sync_pb::NigoriSpecifics& nigori = 724 const sync_pb::NigoriSpecifics& nigori =
725 entry.GetSpecifics().nigori(); 725 entry.GetSpecifics().nigori();
726 if (cryptographer->has_pending_keys() && 726 if (cryptographer->has_pending_keys() &&
727 IsNigoriMigratedToKeystore(nigori) && 727 IsNigoriMigratedToKeystore(nigori) &&
728 !nigori.keystore_decryptor_token().blob().empty()) { 728 !nigori.keystore_decryptor_token().blob().empty()) {
729 // If the nigori is already migrated and we have pending keys, we might 729 // If the nigori is already migrated and we have pending keys, we might
730 // be able to decrypt them using either the keystore decryptor token 730 // be able to decrypt them using either the keystore decryptor token
(...skipping 27 matching lines...) Expand all
758 758
759 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() { 759 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
760 DCHECK(thread_checker_.CalledOnValidThread()); 760 DCHECK(thread_checker_.CalledOnValidThread());
761 return vault_unsafe_.encrypted_types; 761 return vault_unsafe_.encrypted_types;
762 } 762 }
763 763
764 bool SyncEncryptionHandlerImpl::MigratedToKeystore() { 764 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
765 DCHECK(thread_checker_.CalledOnValidThread()); 765 DCHECK(thread_checker_.CalledOnValidThread());
766 ReadTransaction trans(FROM_HERE, user_share_); 766 ReadTransaction trans(FROM_HERE, user_share_);
767 ReadNode nigori_node(&trans); 767 ReadNode nigori_node(&trans);
768 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 768 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
769 return false; 769 return false;
770 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics()); 770 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
771 } 771 }
772 772
773 base::Time SyncEncryptionHandlerImpl::migration_time() const { 773 base::Time SyncEncryptionHandlerImpl::migration_time() const {
774 return migration_time_; 774 return migration_time_;
775 } 775 }
776 776
777 base::Time SyncEncryptionHandlerImpl::custom_passphrase_time() const { 777 base::Time SyncEncryptionHandlerImpl::custom_passphrase_time() const {
778 return custom_passphrase_time_; 778 return custom_passphrase_time_;
779 } 779 }
780 780
781 // This function iterates over all encrypted types. There are many scenarios in 781 // This function iterates over all encrypted types. There are many scenarios in
782 // which data for some or all types is not currently available. In that case, 782 // which data for some or all types is not currently available. In that case,
783 // the lookup of the root node will fail and we will skip encryption for that 783 // the lookup of the root node will fail and we will skip encryption for that
784 // type. 784 // type.
785 void SyncEncryptionHandlerImpl::ReEncryptEverything( 785 void SyncEncryptionHandlerImpl::ReEncryptEverything(
786 WriteTransaction* trans) { 786 WriteTransaction* trans) {
787 DCHECK(thread_checker_.CalledOnValidThread()); 787 DCHECK(thread_checker_.CalledOnValidThread());
788 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); 788 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
789 for (ModelTypeSet::Iterator iter = 789 for (ModelTypeSet::Iterator iter =
790 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); 790 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
791 iter.Good(); iter.Inc()) { 791 iter.Good(); iter.Inc()) {
792 if (iter.Get() == PASSWORDS || IsControlType(iter.Get())) 792 if (iter.Get() == PASSWORDS || IsControlType(iter.Get()))
793 continue; // These types handle encryption differently. 793 continue; // These types handle encryption differently.
794 794
795 ReadNode type_root(trans); 795 ReadNode type_root(trans);
796 std::string tag = ModelTypeToRootTag(iter.Get()); 796 if (type_root.InitTypeRoot(iter.Get()) != BaseNode::INIT_OK)
797 if (type_root.InitByTagLookup(tag) != BaseNode::INIT_OK)
798 continue; // Don't try to reencrypt if the type's data is unavailable. 797 continue; // Don't try to reencrypt if the type's data is unavailable.
799 798
800 // Iterate through all children of this datatype. 799 // Iterate through all children of this datatype.
801 std::queue<int64> to_visit; 800 std::queue<int64> to_visit;
802 int64 child_id = type_root.GetFirstChildId(); 801 int64 child_id = type_root.GetFirstChildId();
803 to_visit.push(child_id); 802 to_visit.push(child_id);
804 while (!to_visit.empty()) { 803 while (!to_visit.empty()) {
805 child_id = to_visit.front(); 804 child_id = to_visit.front();
806 to_visit.pop(); 805 to_visit.pop();
807 if (child_id == kInvalidId) 806 if (child_id == kInvalidId)
(...skipping 10 matching lines...) Expand all
818 // (only rewrite the non-unique folders). 817 // (only rewrite the non-unique folders).
819 child.ResetFromSpecifics(); 818 child.ResetFromSpecifics();
820 } 819 }
821 to_visit.push(child.GetSuccessorId()); 820 to_visit.push(child.GetSuccessorId());
822 } 821 }
823 } 822 }
824 823
825 // Passwords are encrypted with their own legacy scheme. Passwords are always 824 // Passwords are encrypted with their own legacy scheme. Passwords are always
826 // encrypted so we don't need to check GetEncryptedTypes() here. 825 // encrypted so we don't need to check GetEncryptedTypes() here.
827 ReadNode passwords_root(trans); 826 ReadNode passwords_root(trans);
828 std::string passwords_tag = ModelTypeToRootTag(PASSWORDS); 827 if (passwords_root.InitTypeRoot(PASSWORDS) == BaseNode::INIT_OK) {
829 if (passwords_root.InitByTagLookup(passwords_tag) ==
830 BaseNode::INIT_OK) {
831 int64 child_id = passwords_root.GetFirstChildId(); 828 int64 child_id = passwords_root.GetFirstChildId();
832 while (child_id != kInvalidId) { 829 while (child_id != kInvalidId) {
833 WriteNode child(trans); 830 WriteNode child(trans);
834 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK) { 831 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK) {
835 NOTREACHED(); 832 NOTREACHED();
836 return; 833 return;
837 } 834 }
838 child.SetPasswordSpecifics(child.GetPasswordSpecifics()); 835 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
839 child_id = child.GetSuccessorId(); 836 child_id = child.GetSuccessorId();
840 } 837 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 DCHECK(thread_checker_.CalledOnValidThread()); 1002 DCHECK(thread_checker_.CalledOnValidThread());
1006 WriteTransaction trans(FROM_HERE, user_share_); 1003 WriteTransaction trans(FROM_HERE, user_share_);
1007 WriteEncryptionStateToNigori(&trans); 1004 WriteEncryptionStateToNigori(&trans);
1008 } 1005 }
1009 1006
1010 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori( 1007 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
1011 WriteTransaction* trans) { 1008 WriteTransaction* trans) {
1012 DCHECK(thread_checker_.CalledOnValidThread()); 1009 DCHECK(thread_checker_.CalledOnValidThread());
1013 WriteNode nigori_node(trans); 1010 WriteNode nigori_node(trans);
1014 // This can happen in tests that don't have nigori nodes. 1011 // This can happen in tests that don't have nigori nodes.
1015 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 1012 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
1016 return; 1013 return;
1017 1014
1018 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics(); 1015 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
1019 const Cryptographer& cryptographer = 1016 const Cryptographer& cryptographer =
1020 UnlockVault(trans->GetWrappedTrans()).cryptographer; 1017 UnlockVault(trans->GetWrappedTrans()).cryptographer;
1021 1018
1022 // Will not do anything if we shouldn't or can't migrate. Otherwise 1019 // Will not do anything if we shouldn't or can't migrate. Otherwise
1023 // migrates, writing the full encryption state as it does. 1020 // migrates, writing the full encryption state as it does.
1024 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) { 1021 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) {
1025 if (cryptographer.is_ready() && 1022 if (cryptographer.is_ready() &&
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 1638
1642 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const { 1639 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const {
1643 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE) 1640 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE)
1644 return migration_time(); 1641 return migration_time();
1645 else if (passphrase_type_ == CUSTOM_PASSPHRASE) 1642 else if (passphrase_type_ == CUSTOM_PASSPHRASE)
1646 return custom_passphrase_time(); 1643 return custom_passphrase_time();
1647 return base::Time(); 1644 return base::Time();
1648 } 1645 }
1649 1646
1650 } // namespace browser_sync 1647 } // namespace browser_sync
OLDNEW
« no previous file with comments | « sync/internal_api/sync_backup_manager_unittest.cc ('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