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

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

Issue 10917246: [Sync] Add keystore encryption info to about:sync (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase + address 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 "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"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/time.h" 12 #include "base/time.h"
13 #include "base/tracked_objects.h" 13 #include "base/tracked_objects.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "sync/internal_api/public/read_node.h" 15 #include "sync/internal_api/public/read_node.h"
16 #include "sync/internal_api/public/read_transaction.h" 16 #include "sync/internal_api/public/read_transaction.h"
17 #include "sync/internal_api/public/user_share.h" 17 #include "sync/internal_api/public/user_share.h"
18 #include "sync/internal_api/public/util/experiments.h" 18 #include "sync/internal_api/public/util/experiments.h"
19 #include "sync/internal_api/public/write_node.h" 19 #include "sync/internal_api/public/write_node.h"
20 #include "sync/internal_api/public/write_transaction.h" 20 #include "sync/internal_api/public/write_transaction.h"
21 #include "sync/internal_api/public/util/sync_string_conversions.h" 21 #include "sync/internal_api/public/util/sync_string_conversions.h"
22 #include "sync/internal_api/public/util/time.h"
22 #include "sync/protocol/encryption.pb.h" 23 #include "sync/protocol/encryption.pb.h"
23 #include "sync/protocol/nigori_specifics.pb.h" 24 #include "sync/protocol/nigori_specifics.pb.h"
24 #include "sync/protocol/sync.pb.h" 25 #include "sync/protocol/sync.pb.h"
25 #include "sync/syncable/base_transaction.h" 26 #include "sync/syncable/base_transaction.h"
26 #include "sync/syncable/directory.h" 27 #include "sync/syncable/directory.h"
27 #include "sync/syncable/entry.h" 28 #include "sync/syncable/entry.h"
28 #include "sync/syncable/nigori_util.h" 29 #include "sync/syncable/nigori_util.h"
29 #include "sync/util/cryptographer.h" 30 #include "sync/util/cryptographer.h"
30 #include "sync/util/time.h"
31 31
32 namespace syncer { 32 namespace syncer {
33 33
34 namespace { 34 namespace {
35 35
36 // The maximum number of times we will automatically overwrite the nigori node 36 // The maximum number of times we will automatically overwrite the nigori node
37 // because the encryption keys don't match (per chrome instantiation). 37 // because the encryption keys don't match (per chrome instantiation).
38 // We protect ourselves against nigori rollbacks, but it's possible two 38 // We protect ourselves against nigori rollbacks, but it's possible two
39 // different clients might have contrasting view of what the nigori node state 39 // different clients might have contrasting view of what the nigori node state
40 // should be, in which case they might ping pong (see crbug.com/119207). 40 // should be, in which case they might ping pong (see crbug.com/119207).
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 UserShare* user_share, 120 UserShare* user_share,
121 Encryptor* encryptor, 121 Encryptor* encryptor,
122 const std::string& restored_key_for_bootstrapping, 122 const std::string& restored_key_for_bootstrapping,
123 const std::string& restored_keystore_key_for_bootstrapping) 123 const std::string& restored_keystore_key_for_bootstrapping)
124 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 124 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
125 user_share_(user_share), 125 user_share_(user_share),
126 vault_unsafe_(encryptor, SensitiveTypes()), 126 vault_unsafe_(encryptor, SensitiveTypes()),
127 encrypt_everything_(false), 127 encrypt_everything_(false),
128 passphrase_type_(IMPLICIT_PASSPHRASE), 128 passphrase_type_(IMPLICIT_PASSPHRASE),
129 keystore_key_(restored_keystore_key_for_bootstrapping), 129 keystore_key_(restored_keystore_key_for_bootstrapping),
130 nigori_overwrite_count_(0), 130 nigori_overwrite_count_(0) {
131 migration_time_ms_(0) {
132 // We only bootstrap the user provided passphrase. The keystore key is handled 131 // We only bootstrap the user provided passphrase. The keystore key is handled
133 // at Init time once we're sure the nigori is downloaded. 132 // at Init time once we're sure the nigori is downloaded.
134 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); 133 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping);
135 } 134 }
136 135
137 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} 136 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
138 137
139 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { 138 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
140 DCHECK(thread_checker_.CalledOnValidThread()); 139 DCHECK(thread_checker_.CalledOnValidThread());
141 DCHECK(!observers_.HasObserver(observer)); 140 DCHECK(!observers_.HasObserver(observer));
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 580
582 bool SyncEncryptionHandlerImpl::MigratedToKeystore() { 581 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
583 DCHECK(thread_checker_.CalledOnValidThread()); 582 DCHECK(thread_checker_.CalledOnValidThread());
584 ReadTransaction trans(FROM_HERE, user_share_); 583 ReadTransaction trans(FROM_HERE, user_share_);
585 ReadNode nigori_node(&trans); 584 ReadNode nigori_node(&trans);
586 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 585 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
587 return false; 586 return false;
588 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics()); 587 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
589 } 588 }
590 589
590 base::Time SyncEncryptionHandlerImpl::migration_time() const {
591 return migration_time_;
592 }
593
591 // This function iterates over all encrypted types. There are many scenarios in 594 // This function iterates over all encrypted types. There are many scenarios in
592 // which data for some or all types is not currently available. In that case, 595 // which data for some or all types is not currently available. In that case,
593 // the lookup of the root node will fail and we will skip encryption for that 596 // the lookup of the root node will fail and we will skip encryption for that
594 // type. 597 // type.
595 void SyncEncryptionHandlerImpl::ReEncryptEverything( 598 void SyncEncryptionHandlerImpl::ReEncryptEverything(
596 WriteTransaction* trans) { 599 WriteTransaction* trans) {
597 DCHECK(thread_checker_.CalledOnValidThread()); 600 DCHECK(thread_checker_.CalledOnValidThread());
598 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); 601 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
599 for (ModelTypeSet::Iterator iter = 602 for (ModelTypeSet::Iterator iter =
600 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); 603 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 664
662 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( 665 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
663 const sync_pb::NigoriSpecifics& nigori, 666 const sync_pb::NigoriSpecifics& nigori,
664 syncable::BaseTransaction* const trans) { 667 syncable::BaseTransaction* const trans) {
665 DCHECK(thread_checker_.CalledOnValidThread()); 668 DCHECK(thread_checker_.CalledOnValidThread());
666 DVLOG(1) << "Applying nigori node update."; 669 DVLOG(1) << "Applying nigori node update.";
667 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori, 670 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
668 trans); 671 trans);
669 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori); 672 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori);
670 if (is_nigori_migrated) { 673 if (is_nigori_migrated) {
671 migration_time_ms_ = nigori.keystore_migration_time(); 674 DCHECK(nigori.has_keystore_migration_time());
675 migration_time_ = ProtoTimeToTime(nigori.keystore_migration_time());
672 PassphraseType nigori_passphrase_type = 676 PassphraseType nigori_passphrase_type =
673 ProtoPassphraseTypeToEnum(nigori.passphrase_type()); 677 ProtoPassphraseTypeToEnum(nigori.passphrase_type());
674 678
675 // Only update the local passphrase state if it's a valid transition: 679 // Only update the local passphrase state if it's a valid transition:
676 // - implicit -> keystore 680 // - implicit -> keystore
677 // - implicit -> frozen implicit 681 // - implicit -> frozen implicit
678 // - implicit -> custom 682 // - implicit -> custom
679 // - keystore -> custom 683 // - keystore -> custom
680 // Note: frozen implicit -> custom is not technically a valid transition, 684 // Note: frozen implicit -> custom is not technically a valid transition,
681 // but we let it through here as well in case future versions do add support 685 // but we let it through here as well in case future versions do add support
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 DCHECK(thread_checker_.CalledOnValidThread()); 1133 DCHECK(thread_checker_.CalledOnValidThread());
1130 const sync_pb::NigoriSpecifics& old_nigori = 1134 const sync_pb::NigoriSpecifics& old_nigori =
1131 nigori_node->GetNigoriSpecifics(); 1135 nigori_node->GetNigoriSpecifics();
1132 Cryptographer* cryptographer = 1136 Cryptographer* cryptographer =
1133 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; 1137 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1134 1138
1135 if (!ShouldTriggerMigration(old_nigori, *cryptographer)) 1139 if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1136 return false; 1140 return false;
1137 1141
1138 DVLOG(1) << "Starting nigori migration to keystore support."; 1142 DVLOG(1) << "Starting nigori migration to keystore support.";
1139 if (migration_time_ms_ == 0)
1140 migration_time_ms_ = TimeToProtoTime(base::Time::Now());
1141 sync_pb::NigoriSpecifics migrated_nigori(old_nigori); 1143 sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1142 migrated_nigori.set_keystore_migration_time(migration_time_ms_);
1143 1144
1144 PassphraseType new_passphrase_type = passphrase_type_; 1145 PassphraseType new_passphrase_type = passphrase_type_;
1145 bool new_encrypt_everything = encrypt_everything_; 1146 bool new_encrypt_everything = encrypt_everything_;
1146 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) { 1147 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) {
1147 DVLOG(1) << "Switching to frozen implicit passphrase due to already having " 1148 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1148 << "full encryption."; 1149 << "full encryption.";
1149 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE; 1150 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE;
1150 migrated_nigori.clear_keystore_decryptor_token(); 1151 migrated_nigori.clear_keystore_decryptor_token();
1151 } else if (IsExplicitPassphrase(passphrase_type_)) { 1152 } else if (IsExplicitPassphrase(passphrase_type_)) {
1152 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to " 1153 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to "
(...skipping 23 matching lines...) Expand all
1176 keystore_key_, 1177 keystore_key_,
1177 migrated_nigori.mutable_keystore_decryptor_token())) { 1178 migrated_nigori.mutable_keystore_decryptor_token())) {
1178 LOG(ERROR) << "Failed to extract keystore decryptor token."; 1179 LOG(ERROR) << "Failed to extract keystore decryptor token.";
1179 return false; 1180 return false;
1180 } 1181 }
1181 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) { 1182 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) {
1182 LOG(ERROR) << "Failed to extract encryption keybag."; 1183 LOG(ERROR) << "Failed to extract encryption keybag.";
1183 return false; 1184 return false;
1184 } 1185 }
1185 1186
1187 if (migration_time_.is_null())
1188 migration_time_ = base::Time::Now();
1189 migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_));
1190
1186 DVLOG(1) << "Completing nigori migration to keystore support."; 1191 DVLOG(1) << "Completing nigori migration to keystore support.";
1187 nigori_node->SetNigoriSpecifics(migrated_nigori); 1192 nigori_node->SetNigoriSpecifics(migrated_nigori);
1193
1194 FOR_EACH_OBSERVER(
1195 SyncEncryptionHandler::Observer,
1196 observers_,
1197 OnCryptographerStateChanged(cryptographer));
1188 if (passphrase_type_ != new_passphrase_type) { 1198 if (passphrase_type_ != new_passphrase_type) {
1189 passphrase_type_ = new_passphrase_type; 1199 passphrase_type_ = new_passphrase_type;
1190 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 1200 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1191 OnPassphraseTypeChanged(passphrase_type_)); 1201 OnPassphraseTypeChanged(passphrase_type_));
1192 } 1202 }
1203
1193 if (new_encrypt_everything && !encrypt_everything_) { 1204 if (new_encrypt_everything && !encrypt_everything_) {
1194 EnableEncryptEverythingImpl(trans->GetWrappedTrans()); 1205 EnableEncryptEverythingImpl(trans->GetWrappedTrans());
1195 ReEncryptEverything(trans); 1206 ReEncryptEverything(trans);
1196 } 1207 }
1197 return true; 1208 return true;
1198 } 1209 }
1199 1210
1200 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor( 1211 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1201 const Cryptographer& cryptographer, 1212 const Cryptographer& cryptographer,
1202 const std::string& keystore_key, 1213 const std::string& keystore_key,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 SyncEncryptionHandler::Observer, 1297 SyncEncryptionHandler::Observer,
1287 observers_, 1298 observers_,
1288 OnCryptographerStateChanged(cryptographer)); 1299 OnCryptographerStateChanged(cryptographer));
1289 return true; 1300 return true;
1290 } 1301 }
1291 } 1302 }
1292 return false; 1303 return false;
1293 } 1304 }
1294 1305
1295 } // namespace browser_sync 1306 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698