OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |