OLD | NEW |
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 "base/base64.h" | 5 #include "base/base64.h" |
6 #include "chrome/browser/sync/util/cryptographer.h" | 6 #include "chrome/browser/sync/util/cryptographer.h" |
7 #include "chrome/browser/password_manager/encryptor.h" | 7 #include "chrome/browser/password_manager/encryptor.h" |
8 | 8 |
9 namespace browser_sync { | 9 namespace browser_sync { |
10 | 10 |
11 const char kNigoriTag[] = "google_chrome_nigori"; | 11 const char kNigoriTag[] = "google_chrome_nigori"; |
12 | 12 |
13 // We name a particular Nigori instance (ie. a triplet consisting of a hostname, | 13 // We name a particular Nigori instance (ie. a triplet consisting of a hostname, |
14 // a username, and a password) by calling Permute on this string. Since the | 14 // a username, and a password) by calling Permute on this string. Since the |
15 // output of Permute is always the same for a given triplet, clients will always | 15 // output of Permute is always the same for a given triplet, clients will always |
16 // assign the same name to a particular triplet. | 16 // assign the same name to a particular triplet. |
17 const char kNigoriKeyName[] = "nigori-key"; | 17 const char kNigoriKeyName[] = "nigori-key"; |
18 | 18 |
| 19 Cryptographer::Observer::~Observer() {} |
| 20 |
19 Cryptographer::Cryptographer() | 21 Cryptographer::Cryptographer() |
20 : default_nigori_(NULL), | 22 : default_nigori_(NULL), |
21 encrypt_everything_(false) { | 23 encrypt_everything_(false) { |
22 syncable::ModelTypeSet sensitive_types = SensitiveTypes(); | 24 syncable::ModelTypeSet sensitive_types = SensitiveTypes(); |
23 encrypted_types_.insert(sensitive_types.begin(), sensitive_types.end()); | 25 encrypted_types_.insert(sensitive_types.begin(), sensitive_types.end()); |
24 } | 26 } |
25 | 27 |
26 Cryptographer::~Cryptographer() {} | 28 Cryptographer::~Cryptographer() {} |
27 | 29 |
| 30 void Cryptographer::AddObserver(Observer* observer) { |
| 31 observers_.AddObserver(observer); |
| 32 } |
| 33 |
| 34 void Cryptographer::RemoveObserver(Observer* observer) { |
| 35 observers_.RemoveObserver(observer); |
| 36 } |
| 37 |
28 void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) { | 38 void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) { |
29 if (is_initialized()) { | 39 if (is_initialized()) { |
30 NOTREACHED(); | 40 NOTREACHED(); |
31 return; | 41 return; |
32 } | 42 } |
33 | 43 |
34 scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); | 44 scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); |
35 if (nigori.get()) | 45 if (nigori.get()) |
36 AddKeyImpl(nigori.release()); | 46 AddKeyImpl(nigori.release()); |
37 } | 47 } |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 syncable::ModelTypeSet types; | 277 syncable::ModelTypeSet types; |
268 // Both of these have their own encryption schemes, but we include them | 278 // Both of these have their own encryption schemes, but we include them |
269 // anyways. | 279 // anyways. |
270 types.insert(syncable::PASSWORDS); | 280 types.insert(syncable::PASSWORDS); |
271 types.insert(syncable::NIGORI); | 281 types.insert(syncable::NIGORI); |
272 return types; | 282 return types; |
273 } | 283 } |
274 | 284 |
275 void Cryptographer::UpdateEncryptedTypesFromNigori( | 285 void Cryptographer::UpdateEncryptedTypesFromNigori( |
276 const sync_pb::NigoriSpecifics& nigori) { | 286 const sync_pb::NigoriSpecifics& nigori) { |
277 encrypted_types_.clear(); | |
278 if (nigori.encrypt_everything()) { | 287 if (nigori.encrypt_everything()) { |
279 set_encrypt_everything(); | 288 set_encrypt_everything(); |
280 return; | 289 return; |
281 } | 290 } |
| 291 |
| 292 syncable::ModelTypeSet encrypted_types(SensitiveTypes()); |
282 if (nigori.encrypt_bookmarks()) | 293 if (nigori.encrypt_bookmarks()) |
283 encrypted_types_.insert(syncable::BOOKMARKS); | 294 encrypted_types.insert(syncable::BOOKMARKS); |
284 if (nigori.encrypt_preferences()) | 295 if (nigori.encrypt_preferences()) |
285 encrypted_types_.insert(syncable::PREFERENCES); | 296 encrypted_types.insert(syncable::PREFERENCES); |
286 if (nigori.encrypt_autofill_profile()) | 297 if (nigori.encrypt_autofill_profile()) |
287 encrypted_types_.insert(syncable::AUTOFILL_PROFILE); | 298 encrypted_types.insert(syncable::AUTOFILL_PROFILE); |
288 if (nigori.encrypt_autofill()) | 299 if (nigori.encrypt_autofill()) |
289 encrypted_types_.insert(syncable::AUTOFILL); | 300 encrypted_types.insert(syncable::AUTOFILL); |
290 if (nigori.encrypt_themes()) | 301 if (nigori.encrypt_themes()) |
291 encrypted_types_.insert(syncable::THEMES); | 302 encrypted_types.insert(syncable::THEMES); |
292 if (nigori.encrypt_typed_urls()) | 303 if (nigori.encrypt_typed_urls()) |
293 encrypted_types_.insert(syncable::TYPED_URLS); | 304 encrypted_types.insert(syncable::TYPED_URLS); |
294 if (nigori.encrypt_extension_settings()) | 305 if (nigori.encrypt_extension_settings()) |
295 encrypted_types_.insert(syncable::EXTENSION_SETTINGS); | 306 encrypted_types.insert(syncable::EXTENSION_SETTINGS); |
296 if (nigori.encrypt_extensions()) | 307 if (nigori.encrypt_extensions()) |
297 encrypted_types_.insert(syncable::EXTENSIONS); | 308 encrypted_types.insert(syncable::EXTENSIONS); |
298 if (nigori.encrypt_search_engines()) | 309 if (nigori.encrypt_search_engines()) |
299 encrypted_types_.insert(syncable::SEARCH_ENGINES); | 310 encrypted_types.insert(syncable::SEARCH_ENGINES); |
300 if (nigori.encrypt_sessions()) | 311 if (nigori.encrypt_sessions()) |
301 encrypted_types_.insert(syncable::SESSIONS); | 312 encrypted_types.insert(syncable::SESSIONS); |
302 if (nigori.encrypt_apps()) | 313 if (nigori.encrypt_apps()) |
303 encrypted_types_.insert(syncable::APPS); | 314 encrypted_types.insert(syncable::APPS); |
304 if (nigori.encrypt_app_notifications()) | 315 if (nigori.encrypt_app_notifications()) |
305 encrypted_types_.insert(syncable::APP_NOTIFICATIONS); | 316 encrypted_types.insert(syncable::APP_NOTIFICATIONS); |
306 | 317 |
307 // Note: the initial version with encryption did not support the | 318 // Note: the initial version with encryption did not support the |
308 // encrypt_everything field. If anything more than the sensitive types were | 319 // encrypt_everything field. If anything more than the sensitive types were |
309 // encrypted, it meant we were encrypting everything. | 320 // encrypted, it meant we were encrypting everything. |
310 syncable::ModelTypeSet sensitive_types = SensitiveTypes(); | |
311 encrypted_types_.insert(sensitive_types.begin(), sensitive_types.end()); | |
312 if (!nigori.has_encrypt_everything() && | 321 if (!nigori.has_encrypt_everything() && |
313 encrypted_types_.size() > sensitive_types.size()) { | 322 encrypted_types.size() > SensitiveTypes().size()) { |
314 set_encrypt_everything(); | 323 set_encrypt_everything(); |
| 324 return; |
315 } | 325 } |
| 326 |
| 327 SetEncryptedTypes(encrypted_types); |
316 } | 328 } |
317 | 329 |
318 void Cryptographer::UpdateNigoriFromEncryptedTypes( | 330 void Cryptographer::UpdateNigoriFromEncryptedTypes( |
319 sync_pb::NigoriSpecifics* nigori) const { | 331 sync_pb::NigoriSpecifics* nigori) const { |
320 nigori->set_encrypt_everything(encrypt_everything_); | 332 nigori->set_encrypt_everything(encrypt_everything_); |
321 nigori->set_encrypt_bookmarks( | 333 nigori->set_encrypt_bookmarks( |
322 encrypted_types_.count(syncable::BOOKMARKS) > 0); | 334 encrypted_types_.count(syncable::BOOKMARKS) > 0); |
323 nigori->set_encrypt_preferences( | 335 nigori->set_encrypt_preferences( |
324 encrypted_types_.count(syncable::PREFERENCES) > 0); | 336 encrypted_types_.count(syncable::PREFERENCES) > 0); |
325 nigori->set_encrypt_autofill_profile( | 337 nigori->set_encrypt_autofill_profile( |
326 encrypted_types_.count(syncable::AUTOFILL_PROFILE) > 0); | 338 encrypted_types_.count(syncable::AUTOFILL_PROFILE) > 0); |
327 nigori->set_encrypt_autofill(encrypted_types_.count(syncable::AUTOFILL) > 0); | 339 nigori->set_encrypt_autofill(encrypted_types_.count(syncable::AUTOFILL) > 0); |
328 nigori->set_encrypt_themes(encrypted_types_.count(syncable::THEMES) > 0); | 340 nigori->set_encrypt_themes(encrypted_types_.count(syncable::THEMES) > 0); |
329 nigori->set_encrypt_typed_urls( | 341 nigori->set_encrypt_typed_urls( |
330 encrypted_types_.count(syncable::TYPED_URLS) > 0); | 342 encrypted_types_.count(syncable::TYPED_URLS) > 0); |
331 nigori->set_encrypt_extension_settings( | 343 nigori->set_encrypt_extension_settings( |
332 encrypted_types_.count(syncable::EXTENSION_SETTINGS) > 0); | 344 encrypted_types_.count(syncable::EXTENSION_SETTINGS) > 0); |
333 nigori->set_encrypt_extensions( | 345 nigori->set_encrypt_extensions( |
334 encrypted_types_.count(syncable::EXTENSIONS) > 0); | 346 encrypted_types_.count(syncable::EXTENSIONS) > 0); |
335 nigori->set_encrypt_search_engines( | 347 nigori->set_encrypt_search_engines( |
336 encrypted_types_.count(syncable::SEARCH_ENGINES) > 0); | 348 encrypted_types_.count(syncable::SEARCH_ENGINES) > 0); |
337 nigori->set_encrypt_sessions(encrypted_types_.count(syncable::SESSIONS) > 0); | 349 nigori->set_encrypt_sessions(encrypted_types_.count(syncable::SESSIONS) > 0); |
338 nigori->set_encrypt_apps(encrypted_types_.count(syncable::APPS) > 0); | 350 nigori->set_encrypt_apps(encrypted_types_.count(syncable::APPS) > 0); |
339 nigori->set_encrypt_app_notifications( | 351 nigori->set_encrypt_app_notifications( |
340 encrypted_types_.count(syncable::APP_NOTIFICATIONS) > 0); | 352 encrypted_types_.count(syncable::APP_NOTIFICATIONS) > 0); |
341 } | 353 } |
342 | 354 |
343 void Cryptographer::set_encrypt_everything() { | 355 void Cryptographer::set_encrypt_everything() { |
| 356 if (encrypt_everything_) { |
| 357 DCHECK(encrypted_types_ == syncable::GetAllRealModelTypes()); |
| 358 return; |
| 359 } |
344 encrypt_everything_ = true; | 360 encrypt_everything_ = true; |
| 361 // Change |encrypted_types_| directly to avoid sending more than one |
| 362 // notification. |
345 encrypted_types_ = syncable::GetAllRealModelTypes(); | 363 encrypted_types_ = syncable::GetAllRealModelTypes(); |
| 364 EmitEncryptedTypesChangedNotification(); |
346 } | 365 } |
347 | 366 |
348 bool Cryptographer::encrypt_everything() const { | 367 bool Cryptographer::encrypt_everything() const { |
349 return encrypt_everything_; | 368 return encrypt_everything_; |
350 } | 369 } |
351 | 370 |
352 void Cryptographer::SetEncryptedTypes(syncable::ModelTypeSet new_types) { | 371 syncable::ModelTypeSet Cryptographer::GetEncryptedTypes() const { |
353 encrypted_types_.insert(new_types.begin(), new_types.end()); | 372 return encrypted_types_; |
354 } | 373 } |
355 | 374 |
356 syncable::ModelTypeSet Cryptographer::GetEncryptedTypes() const { | 375 void Cryptographer::SetEncryptedTypesForTest( |
357 return encrypted_types_; | 376 const syncable::ModelTypeSet& encrypted_types) { |
| 377 SetEncryptedTypes(encrypted_types); |
| 378 } |
| 379 |
| 380 void Cryptographer::SetEncryptedTypes( |
| 381 const syncable::ModelTypeSet& encrypted_types) { |
| 382 if (encrypted_types_ == encrypted_types) { |
| 383 return; |
| 384 } |
| 385 encrypted_types_ = encrypted_types; |
| 386 EmitEncryptedTypesChangedNotification(); |
| 387 } |
| 388 |
| 389 void Cryptographer::EmitEncryptedTypesChangedNotification() { |
| 390 FOR_EACH_OBSERVER( |
| 391 Observer, observers_, |
| 392 OnEncryptedTypesChanged(encrypted_types_, encrypt_everything_)); |
358 } | 393 } |
359 | 394 |
360 void Cryptographer::InstallKeys(const std::string& default_key_name, | 395 void Cryptographer::InstallKeys(const std::string& default_key_name, |
361 const sync_pb::NigoriKeyBag& bag) { | 396 const sync_pb::NigoriKeyBag& bag) { |
362 int key_size = bag.key_size(); | 397 int key_size = bag.key_size(); |
363 for (int i = 0; i < key_size; ++i) { | 398 for (int i = 0; i < key_size; ++i) { |
364 const sync_pb::NigoriKey key = bag.key(i); | 399 const sync_pb::NigoriKey key = bag.key(i); |
365 // Only use this key if we don't already know about it. | 400 // Only use this key if we don't already know about it. |
366 if (nigoris_.end() == nigoris_.find(key.name())) { | 401 if (nigoris_.end() == nigoris_.find(key.name())) { |
367 scoped_ptr<Nigori> new_nigori(new Nigori); | 402 scoped_ptr<Nigori> new_nigori(new Nigori); |
368 if (!new_nigori->InitByImport(key.user_key(), | 403 if (!new_nigori->InitByImport(key.user_key(), |
369 key.encryption_key(), | 404 key.encryption_key(), |
370 key.mac_key())) { | 405 key.mac_key())) { |
371 NOTREACHED(); | 406 NOTREACHED(); |
372 continue; | 407 continue; |
373 } | 408 } |
374 nigoris_[key.name()] = make_linked_ptr(new_nigori.release()); | 409 nigoris_[key.name()] = make_linked_ptr(new_nigori.release()); |
375 } | 410 } |
376 } | 411 } |
377 DCHECK(nigoris_.end() != nigoris_.find(default_key_name)); | 412 DCHECK(nigoris_.end() != nigoris_.find(default_key_name)); |
378 default_nigori_ = &*nigoris_.find(default_key_name); | 413 default_nigori_ = &*nigoris_.find(default_key_name); |
379 } | 414 } |
380 | 415 |
381 } // namespace browser_sync | 416 } // namespace browser_sync |
OLD | NEW |