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

Side by Side Diff: chrome/browser/sync/engine/syncapi.cc

Issue 7108067: [Sync] Ensure cryptographer ready before encrypting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/sync/engine/syncapi.h" 5 #include "chrome/browser/sync/engine/syncapi.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <bitset> 8 #include <bitset>
9 #include <iomanip> 9 #include <iomanip>
10 #include <list> 10 #include <list>
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 195 }
196 } 196 }
197 197
198 UserShare::UserShare() {} 198 UserShare::UserShare() {}
199 199
200 UserShare::~UserShare() {} 200 UserShare::~UserShare() {}
201 201
202 //////////////////////////////////// 202 ////////////////////////////////////
203 // BaseNode member definitions. 203 // BaseNode member definitions.
204 204
205 BaseNode::BaseNode() {} 205 BaseNode::BaseNode() : password_data_(new sync_pb::PasswordSpecificsData) {}
206 206
207 BaseNode::~BaseNode() {} 207 BaseNode::~BaseNode() {}
208 208
209 std::string BaseNode::GenerateSyncableHash( 209 std::string BaseNode::GenerateSyncableHash(
210 syncable::ModelType model_type, const std::string& client_tag) { 210 syncable::ModelType model_type, const std::string& client_tag) {
211 // blank PB with just the extension in it has termination symbol, 211 // blank PB with just the extension in it has termination symbol,
212 // handy for delimiter 212 // handy for delimiter
213 sync_pb::EntitySpecifics serialized_type; 213 sync_pb::EntitySpecifics serialized_type;
214 syncable::AddDefaultExtensionValue(model_type, &serialized_type); 214 syncable::AddDefaultExtensionValue(model_type, &serialized_type);
215 std::string hash_input; 215 std::string hash_input;
(...skipping 22 matching lines...) Expand all
238 } 238 }
239 239
240 bool BaseNode::DecryptIfNecessary() { 240 bool BaseNode::DecryptIfNecessary() {
241 if (GetIsFolder()) return true; // Ignore the top-level datatype folder. 241 if (GetIsFolder()) return true; // Ignore the top-level datatype folder.
242 const sync_pb::EntitySpecifics& specifics = 242 const sync_pb::EntitySpecifics& specifics =
243 GetEntry()->Get(syncable::SPECIFICS); 243 GetEntry()->Get(syncable::SPECIFICS);
244 if (specifics.HasExtension(sync_pb::password)) { 244 if (specifics.HasExtension(sync_pb::password)) {
245 // Passwords have their own legacy encryption structure. 245 // Passwords have their own legacy encryption structure.
246 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( 246 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics(
247 specifics, GetTransaction()->GetCryptographer())); 247 specifics, GetTransaction()->GetCryptographer()));
248 if (!data.get()) 248 if (!data.get()) {
249 LOG(ERROR) << "Failed to decrypt password specifics.";
249 return false; 250 return false;
251 }
250 password_data_.swap(data); 252 password_data_.swap(data);
251 return true; 253 return true;
252 } 254 }
253 255
254 // We assume any node with the encrypted field set has encrypted data. 256 // We assume any node with the encrypted field set has encrypted data.
255 if (!specifics.has_encrypted()) 257 if (!specifics.has_encrypted())
256 return true; 258 return true;
257 259
258 const sync_pb::EncryptedData& encrypted = 260 const sync_pb::EncryptedData& encrypted =
259 specifics.encrypted(); 261 specifics.encrypted();
260 std::string plaintext_data = GetTransaction()->GetCryptographer()-> 262 std::string plaintext_data = GetTransaction()->GetCryptographer()->
261 DecryptToString(encrypted); 263 DecryptToString(encrypted);
262 if (plaintext_data.length() == 0) 264 if (plaintext_data.length() == 0 ||
263 return false; 265 !unencrypted_data_.ParseFromString(plaintext_data)) {
264 if (!unencrypted_data_.ParseFromString(plaintext_data)) {
265 LOG(ERROR) << "Failed to decrypt encrypted node of type " << 266 LOG(ERROR) << "Failed to decrypt encrypted node of type " <<
266 syncable::ModelTypeToString(GetModelType()) << "."; 267 syncable::ModelTypeToString(GetModelType()) << ".";
267 return false; 268 return false;
268 } 269 }
269 return true; 270 return true;
270 } 271 }
271 272
272 const sync_pb::EntitySpecifics& BaseNode::GetUnencryptedSpecifics( 273 const sync_pb::EntitySpecifics& BaseNode::GetUnencryptedSpecifics(
273 const syncable::Entry* entry) const { 274 const syncable::Entry* entry) const {
274 const sync_pb::EntitySpecifics& specifics = entry->Get(SPECIFICS); 275 const sync_pb::EntitySpecifics& specifics = entry->Get(SPECIFICS);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 return GetEntitySpecifics().GetExtension(sync_pb::bookmark); 398 return GetEntitySpecifics().GetExtension(sync_pb::bookmark);
398 } 399 }
399 400
400 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { 401 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const {
401 DCHECK_EQ(syncable::NIGORI, GetModelType()); 402 DCHECK_EQ(syncable::NIGORI, GetModelType());
402 return GetEntitySpecifics().GetExtension(sync_pb::nigori); 403 return GetEntitySpecifics().GetExtension(sync_pb::nigori);
403 } 404 }
404 405
405 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { 406 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const {
406 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); 407 DCHECK_EQ(syncable::PASSWORDS, GetModelType());
407 DCHECK(password_data_.get());
408 return *password_data_; 408 return *password_data_;
409 } 409 }
410 410
411 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { 411 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const {
412 DCHECK_EQ(syncable::THEMES, GetModelType()); 412 DCHECK_EQ(syncable::THEMES, GetModelType());
413 return GetEntitySpecifics().GetExtension(sync_pb::theme); 413 return GetEntitySpecifics().GetExtension(sync_pb::theme);
414 } 414 }
415 415
416 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { 416 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const {
417 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); 417 DCHECK_EQ(syncable::TYPED_URLS, GetModelType());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 scoped_ptr<sync_pb::PasswordSpecificsData> old_plaintext( 564 scoped_ptr<sync_pb::PasswordSpecificsData> old_plaintext(
565 DecryptPasswordSpecifics(GetEntry()->Get(SPECIFICS), cryptographer)); 565 DecryptPasswordSpecifics(GetEntry()->Get(SPECIFICS), cryptographer));
566 if (old_plaintext.get() && 566 if (old_plaintext.get() &&
567 old_plaintext->SerializeAsString() == data.SerializeAsString() && 567 old_plaintext->SerializeAsString() == data.SerializeAsString() &&
568 cryptographer->CanDecryptUsingDefaultKey(old_ciphertext)) { 568 cryptographer->CanDecryptUsingDefaultKey(old_ciphertext)) {
569 return; 569 return;
570 } 570 }
571 571
572 sync_pb::PasswordSpecifics new_value; 572 sync_pb::PasswordSpecifics new_value;
573 if (!cryptographer->Encrypt(data, new_value.mutable_encrypted())) { 573 if (!cryptographer->Encrypt(data, new_value.mutable_encrypted())) {
574 NOTREACHED(); 574 LOG(ERROR) << "Failed to encrypt password, possibly due to sync node "
575 << "corruption";
576 return;
575 } 577 }
576 578
577 sync_pb::EntitySpecifics entity_specifics; 579 sync_pb::EntitySpecifics entity_specifics;
578 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value); 580 entity_specifics.MutableExtension(sync_pb::password)->CopyFrom(new_value);
579 SetEntitySpecifics(entity_specifics); 581 SetEntitySpecifics(entity_specifics);
580 } 582 }
581 583
582 void WriteNode::SetThemeSpecifics( 584 void WriteNode::SetThemeSpecifics(
583 const sync_pb::ThemeSpecifics& new_value) { 585 const sync_pb::ThemeSpecifics& new_value) {
584 sync_pb::EntitySpecifics entity_specifics; 586 sync_pb::EntitySpecifics entity_specifics;
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 return; 1824 return;
1823 } 1825 }
1824 1826
1825 nigori.CopyFrom(node.GetNigoriSpecifics()); 1827 nigori.CopyFrom(node.GetNigoriSpecifics());
1826 Cryptographer::UpdateResult result = cryptographer->Update(nigori); 1828 Cryptographer::UpdateResult result = cryptographer->Update(nigori);
1827 if (result == Cryptographer::NEEDS_PASSPHRASE) { 1829 if (result == Cryptographer::NEEDS_PASSPHRASE) {
1828 ObserverList<SyncManager::Observer> temp_obs_list; 1830 ObserverList<SyncManager::Observer> temp_obs_list;
1829 CopyObservers(&temp_obs_list); 1831 CopyObservers(&temp_obs_list);
1830 FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list, 1832 FOR_EACH_OBSERVER(SyncManager::Observer, temp_obs_list,
1831 OnPassphraseRequired(sync_api::REASON_DECRYPTION)); 1833 OnPassphraseRequired(sync_api::REASON_DECRYPTION));
1834 return;
1835 }
1836
1837 if (!cryptographer->is_ready()) {
1838 NOTREACHED() << "Cryptographer failed to initialize.";
1839 return;
1832 } 1840 }
1833 1841
1834 // Refresh list of encrypted datatypes. 1842 // Refresh list of encrypted datatypes.
1835 encrypted_types = GetEncryptedTypes(&trans); 1843 encrypted_types = GetEncryptedTypes(&trans);
1836 } 1844 }
1837 1845
1838
1839
1840 // Ensure any datatypes that need encryption are encrypted. 1846 // Ensure any datatypes that need encryption are encrypted.
1841 EncryptDataTypes(encrypted_types); 1847 EncryptDataTypes(encrypted_types);
1842 } 1848 }
1843 1849
1844 void SyncManager::SyncInternal::StartSyncingNormally() { 1850 void SyncManager::SyncInternal::StartSyncingNormally() {
1845 // Start the syncer thread. This won't actually 1851 // Start the syncer thread. This won't actually
1846 // result in any syncing until at least the 1852 // result in any syncing until at least the
1847 // DirectoryManager broadcasts the OPENED event, 1853 // DirectoryManager broadcasts the OPENED event,
1848 // and a valid server connection is detected. 1854 // and a valid server connection is detected.
1849 if (syncer_thread()) // NULL during certain unittests. 1855 if (syncer_thread()) // NULL during certain unittests.
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 } 2084 }
2079 2085
2080 void SyncManager::SyncInternal::EncryptDataTypes( 2086 void SyncManager::SyncInternal::EncryptDataTypes(
2081 const syncable::ModelTypeSet& encrypted_types) { 2087 const syncable::ModelTypeSet& encrypted_types) {
2082 VLOG(1) << "Attempting to encrypt datatypes " 2088 VLOG(1) << "Attempting to encrypt datatypes "
2083 << syncable::ModelTypeSetToString(encrypted_types); 2089 << syncable::ModelTypeSetToString(encrypted_types);
2084 2090
2085 WriteTransaction trans(GetUserShare()); 2091 WriteTransaction trans(GetUserShare());
2086 WriteNode node(&trans); 2092 WriteNode node(&trans);
2087 if (!node.InitByTagLookup(kNigoriTag)) { 2093 if (!node.InitByTagLookup(kNigoriTag)) {
2088 LOG(ERROR) << "Unable to set encrypted datatypes because Nigori node not " 2094 NOTREACHED() << "Unable to set encrypted datatypes because Nigori node not "
2089 << "found."; 2095 << "found.";
2090 NOTREACHED();
2091 return; 2096 return;
2092 } 2097 }
2093 2098
2094 Cryptographer* cryptographer = trans.GetCryptographer(); 2099 Cryptographer* cryptographer = trans.GetCryptographer();
2095 2100
2101 if (!cryptographer->is_ready()) {
2102 NOTREACHED() << "Attempting to encrypt datatypes when cryptographer not "
2103 << "ready.";
2104 return;
2105 }
2106
2096 // Update the Nigori node set of encrypted datatypes so other machines notice. 2107 // Update the Nigori node set of encrypted datatypes so other machines notice.
2097 // Note, we merge the current encrypted types with those requested. Once a 2108 // Note, we merge the current encrypted types with those requested. Once a
2098 // datatypes is marked as needing encryption, it is never unmarked. 2109 // datatypes is marked as needing encryption, it is never unmarked.
2099 sync_pb::NigoriSpecifics nigori; 2110 sync_pb::NigoriSpecifics nigori;
2100 nigori.CopyFrom(node.GetNigoriSpecifics()); 2111 nigori.CopyFrom(node.GetNigoriSpecifics());
2101 syncable::ModelTypeSet current_encrypted_types = GetEncryptedTypes(&trans); 2112 syncable::ModelTypeSet current_encrypted_types = GetEncryptedTypes(&trans);
2102 syncable::ModelTypeSet newly_encrypted_types; 2113 syncable::ModelTypeSet newly_encrypted_types;
2103 std::set_union(current_encrypted_types.begin(), current_encrypted_types.end(), 2114 std::set_union(current_encrypted_types.begin(), current_encrypted_types.end(),
2104 encrypted_types.begin(), encrypted_types.end(), 2115 encrypted_types.begin(), encrypted_types.end(),
2105 std::inserter(newly_encrypted_types, 2116 std::inserter(newly_encrypted_types,
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 void SyncManager::TriggerOnIncomingNotificationForTest( 3038 void SyncManager::TriggerOnIncomingNotificationForTest(
3028 const syncable::ModelTypeBitSet& model_types) { 3039 const syncable::ModelTypeBitSet& model_types) {
3029 syncable::ModelTypePayloadMap model_types_with_payloads = 3040 syncable::ModelTypePayloadMap model_types_with_payloads =
3030 syncable::ModelTypePayloadMapFromBitSet(model_types, 3041 syncable::ModelTypePayloadMapFromBitSet(model_types,
3031 std::string()); 3042 std::string());
3032 3043
3033 data_->OnIncomingNotification(model_types_with_payloads); 3044 data_->OnIncomingNotification(model_types_with_payloads);
3034 } 3045 }
3035 3046
3036 } // namespace sync_api 3047 } // namespace sync_api
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/sync/engine/syncapi_unittest.cc » ('j') | chrome/browser/sync/engine/syncapi_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698