Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / sync / internal_api / sync_encryption_handler_impl.cc
blob2d2b0cff7d951e0eb911af16b1524aed23eda614
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
3 // found in the LICENSE file.
5 #include "sync/internal_api/sync_encryption_handler_impl.h"
7 #include <queue>
8 #include <string>
10 #include "base/base64.h"
11 #include "base/bind.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h"
15 #include "base/time/time.h"
16 #include "base/tracked_objects.h"
17 #include "sync/internal_api/public/read_node.h"
18 #include "sync/internal_api/public/read_transaction.h"
19 #include "sync/internal_api/public/user_share.h"
20 #include "sync/internal_api/public/util/experiments.h"
21 #include "sync/internal_api/public/util/sync_string_conversions.h"
22 #include "sync/internal_api/public/write_node.h"
23 #include "sync/internal_api/public/write_transaction.h"
24 #include "sync/protocol/encryption.pb.h"
25 #include "sync/protocol/nigori_specifics.pb.h"
26 #include "sync/protocol/sync.pb.h"
27 #include "sync/syncable/directory.h"
28 #include "sync/syncable/entry.h"
29 #include "sync/syncable/mutable_entry.h"
30 #include "sync/syncable/nigori_util.h"
31 #include "sync/syncable/syncable_base_transaction.h"
32 #include "sync/syncable/syncable_model_neutral_write_transaction.h"
33 #include "sync/syncable/syncable_write_transaction.h"
34 #include "sync/util/cryptographer.h"
35 #include "sync/util/encryptor.h"
36 #include "sync/util/time.h"
38 namespace syncer {
40 namespace {
42 // The maximum number of times we will automatically overwrite the nigori node
43 // because the encryption keys don't match (per chrome instantiation).
44 // We protect ourselves against nigori rollbacks, but it's possible two
45 // different clients might have contrasting view of what the nigori node state
46 // should be, in which case they might ping pong (see crbug.com/119207).
47 static const int kNigoriOverwriteLimit = 10;
49 // Enumeration of nigori keystore migration results (for use in UMA stats).
50 enum NigoriMigrationResult {
51 FAILED_TO_SET_DEFAULT_KEYSTORE,
52 FAILED_TO_SET_NONDEFAULT_KEYSTORE,
53 FAILED_TO_EXTRACT_DECRYPTOR,
54 FAILED_TO_EXTRACT_KEYBAG,
55 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT,
56 MIGRATION_SUCCESS_KEYSTORE_DEFAULT,
57 MIGRATION_SUCCESS_FROZEN_IMPLICIT,
58 MIGRATION_SUCCESS_CUSTOM,
59 MIGRATION_RESULT_SIZE,
62 enum NigoriMigrationState {
63 MIGRATED,
64 NOT_MIGRATED_CRYPTO_NOT_READY,
65 NOT_MIGRATED_NO_KEYSTORE_KEY,
66 NOT_MIGRATED_UNKNOWN_REASON,
67 MIGRATION_STATE_SIZE,
70 // The new passphrase state is sufficient to determine whether a nigori node
71 // is migrated to support keystore encryption. In addition though, we also
72 // want to verify the conditions for proper keystore encryption functionality.
73 // 1. Passphrase type is set.
74 // 2. Frozen keybag is true
75 // 3. If passphrase state is keystore, keystore_decryptor_token is set.
76 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) {
77 if (!nigori.has_passphrase_type())
78 return false;
79 if (!nigori.keybag_is_frozen())
80 return false;
81 if (nigori.passphrase_type() ==
82 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)
83 return false;
84 if (nigori.passphrase_type() ==
85 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
86 nigori.keystore_decryptor_token().blob().empty())
87 return false;
88 return true;
91 PassphraseType ProtoPassphraseTypeToEnum(
92 sync_pb::NigoriSpecifics::PassphraseType type) {
93 switch(type) {
94 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE:
95 return IMPLICIT_PASSPHRASE;
96 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE:
97 return KEYSTORE_PASSPHRASE;
98 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE:
99 return CUSTOM_PASSPHRASE;
100 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE:
101 return FROZEN_IMPLICIT_PASSPHRASE;
102 default:
103 NOTREACHED();
104 return IMPLICIT_PASSPHRASE;
108 sync_pb::NigoriSpecifics::PassphraseType
109 EnumPassphraseTypeToProto(PassphraseType type) {
110 switch(type) {
111 case IMPLICIT_PASSPHRASE:
112 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
113 case KEYSTORE_PASSPHRASE:
114 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE;
115 case CUSTOM_PASSPHRASE:
116 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE;
117 case FROZEN_IMPLICIT_PASSPHRASE:
118 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE;
119 default:
120 NOTREACHED();
121 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
125 bool IsExplicitPassphrase(PassphraseType type) {
126 return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE;
129 // Keystore Bootstrap Token helper methods.
130 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
131 // strings, with the current keystore key as the last value in the list.
132 std::string PackKeystoreBootstrapToken(
133 const std::vector<std::string>& old_keystore_keys,
134 const std::string& current_keystore_key,
135 Encryptor* encryptor) {
136 if (current_keystore_key.empty())
137 return std::string();
139 base::ListValue keystore_key_values;
140 for (size_t i = 0; i < old_keystore_keys.size(); ++i)
141 keystore_key_values.AppendString(old_keystore_keys[i]);
142 keystore_key_values.AppendString(current_keystore_key);
144 // Update the bootstrap token.
145 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
146 // strings, with the current keystore key as the last value in the list.
147 std::string serialized_keystores;
148 JSONStringValueSerializer json(&serialized_keystores);
149 json.Serialize(keystore_key_values);
150 std::string encrypted_keystores;
151 encryptor->EncryptString(serialized_keystores,
152 &encrypted_keystores);
153 std::string keystore_bootstrap;
154 base::Base64Encode(encrypted_keystores, &keystore_bootstrap);
155 return keystore_bootstrap;
158 bool UnpackKeystoreBootstrapToken(
159 const std::string& keystore_bootstrap_token,
160 Encryptor* encryptor,
161 std::vector<std::string>* old_keystore_keys,
162 std::string* current_keystore_key) {
163 if (keystore_bootstrap_token.empty())
164 return false;
165 std::string base64_decoded_keystore_bootstrap;
166 if (!base::Base64Decode(keystore_bootstrap_token,
167 &base64_decoded_keystore_bootstrap)) {
168 return false;
170 std::string decrypted_keystore_bootstrap;
171 if (!encryptor->DecryptString(base64_decoded_keystore_bootstrap,
172 &decrypted_keystore_bootstrap)) {
173 return false;
176 JSONStringValueDeserializer json(decrypted_keystore_bootstrap);
177 scoped_ptr<base::Value> deserialized_keystore_keys(
178 json.Deserialize(NULL, NULL));
179 if (!deserialized_keystore_keys)
180 return false;
181 base::ListValue* internal_list_value = NULL;
182 if (!deserialized_keystore_keys->GetAsList(&internal_list_value))
183 return false;
184 int number_of_keystore_keys = internal_list_value->GetSize();
185 if (!internal_list_value->GetString(number_of_keystore_keys - 1,
186 current_keystore_key)) {
187 return false;
189 old_keystore_keys->resize(number_of_keystore_keys - 1);
190 for (int i = 0; i < number_of_keystore_keys - 1; ++i)
191 internal_list_value->GetString(i, &(*old_keystore_keys)[i]);
192 return true;
195 } // namespace
197 SyncEncryptionHandlerImpl::Vault::Vault(
198 Encryptor* encryptor,
199 ModelTypeSet encrypted_types)
200 : cryptographer(encryptor),
201 encrypted_types(encrypted_types) {
204 SyncEncryptionHandlerImpl::Vault::~Vault() {
207 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
208 UserShare* user_share,
209 Encryptor* encryptor,
210 const std::string& restored_key_for_bootstrapping,
211 const std::string& restored_keystore_key_for_bootstrapping,
212 PassphraseTransitionClearDataOption clear_data_option)
213 : user_share_(user_share),
214 vault_unsafe_(encryptor, SensitiveTypes()),
215 encrypt_everything_(false),
216 passphrase_type_(IMPLICIT_PASSPHRASE),
217 nigori_overwrite_count_(0),
218 clear_data_option_(clear_data_option),
219 weak_ptr_factory_(this) {
220 // Restore the cryptographer's previous keys. Note that we don't add the
221 // keystore keys into the cryptographer here, in case a migration was pending.
222 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping);
224 // If this fails, we won't have a valid keystore key, and will simply request
225 // new ones from the server on the next DownloadUpdates.
226 UnpackKeystoreBootstrapToken(
227 restored_keystore_key_for_bootstrapping,
228 encryptor,
229 &old_keystore_keys_,
230 &keystore_key_);
233 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
235 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
236 DCHECK(thread_checker_.CalledOnValidThread());
237 DCHECK(!observers_.HasObserver(observer));
238 observers_.AddObserver(observer);
241 void SyncEncryptionHandlerImpl::RemoveObserver(Observer* observer) {
242 DCHECK(thread_checker_.CalledOnValidThread());
243 DCHECK(observers_.HasObserver(observer));
244 observers_.RemoveObserver(observer);
247 void SyncEncryptionHandlerImpl::Init() {
248 DCHECK(thread_checker_.CalledOnValidThread());
249 WriteTransaction trans(FROM_HERE, user_share_);
250 WriteNode node(&trans);
252 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
253 return;
254 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(),
255 trans.GetWrappedTrans())) {
256 WriteEncryptionStateToNigori(&trans);
259 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType",
260 GetPassphraseType(),
261 PASSPHRASE_TYPE_SIZE);
263 bool has_pending_keys = UnlockVault(
264 trans.GetWrappedTrans()).cryptographer.has_pending_keys();
265 bool is_ready = UnlockVault(
266 trans.GetWrappedTrans()).cryptographer.is_ready();
267 // Log the state of the cryptographer regardless of migration state.
268 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready);
269 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys);
270 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
271 // This account has a nigori node that has been migrated to support
272 // keystore.
273 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
274 MIGRATED,
275 MIGRATION_STATE_SIZE);
276 if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) {
277 // If this is happening, it means the keystore decryptor is either
278 // undecryptable with the available keystore keys or does not match the
279 // nigori keybag's encryption key. Otherwise we're simply missing the
280 // keystore key.
281 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed",
282 !keystore_key_.empty());
284 } else if (!is_ready) {
285 // Migration cannot occur until the cryptographer is ready (initialized
286 // with GAIA password and any pending keys resolved).
287 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
288 NOT_MIGRATED_CRYPTO_NOT_READY,
289 MIGRATION_STATE_SIZE);
290 } else if (keystore_key_.empty()) {
291 // The client has no keystore key, either because it is not yet enabled or
292 // the server is not sending a valid keystore key.
293 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
294 NOT_MIGRATED_NO_KEYSTORE_KEY,
295 MIGRATION_STATE_SIZE);
296 } else {
297 // If the above conditions have been met and the nigori node is still not
298 // migrated, something failed in the migration process.
299 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
300 NOT_MIGRATED_UNKNOWN_REASON,
301 MIGRATION_STATE_SIZE);
305 // Always trigger an encrypted types and cryptographer state change event at
306 // init time so observers get the initial values.
307 FOR_EACH_OBSERVER(
308 Observer, observers_,
309 OnEncryptedTypesChanged(
310 UnlockVault(trans.GetWrappedTrans()).encrypted_types,
311 encrypt_everything_));
312 FOR_EACH_OBSERVER(
313 SyncEncryptionHandler::Observer,
314 observers_,
315 OnCryptographerStateChanged(
316 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer));
318 // If the cryptographer is not ready (either it has pending keys or we
319 // failed to initialize it), we don't want to try and re-encrypt the data.
320 // If we had encrypted types, the DataTypeManager will block, preventing
321 // sync from happening until the the passphrase is provided.
322 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
323 ReEncryptEverything(&trans);
326 void SyncEncryptionHandlerImpl::SetEncryptionPassphrase(
327 const std::string& passphrase,
328 bool is_explicit) {
329 DCHECK(thread_checker_.CalledOnValidThread());
330 // We do not accept empty passphrases.
331 if (passphrase.empty()) {
332 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
333 return;
336 // All accesses to the cryptographer are protected by a transaction.
337 WriteTransaction trans(FROM_HERE, user_share_);
338 KeyParams key_params = {"localhost", "dummy", passphrase};
339 WriteNode node(&trans);
340 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
341 NOTREACHED();
342 return;
345 Cryptographer* cryptographer =
346 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
348 // Once we've migrated to keystore, the only way to set a passphrase for
349 // encryption is to set a custom passphrase.
350 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
351 if (!is_explicit) {
352 // The user is setting a new implicit passphrase. At this point we don't
353 // care, so drop it on the floor. This is safe because if we have a
354 // migrated nigori node, then we don't need to create an initial
355 // encryption key.
356 LOG(WARNING) << "Ignoring new implicit passphrase. Keystore migration "
357 << "already performed.";
358 return;
360 // Will fail if we already have an explicit passphrase or we have pending
361 // keys.
362 SetCustomPassphrase(passphrase, &trans, &node);
364 // When keystore migration occurs, the "CustomEncryption" UMA stat must be
365 // logged as true.
366 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", true);
367 return;
370 std::string bootstrap_token;
371 sync_pb::EncryptedData pending_keys;
372 if (cryptographer->has_pending_keys())
373 pending_keys = cryptographer->GetPendingKeys();
374 bool success = false;
376 // There are six cases to handle here:
377 // 1. The user has no pending keys and is setting their current GAIA password
378 // as the encryption passphrase. This happens either during first time sync
379 // with a clean profile, or after re-authenticating on a profile that was
380 // already signed in with the cryptographer ready.
381 // 2. The user has no pending keys, and is overwriting an (already provided)
382 // implicit passphrase with an explicit (custom) passphrase.
383 // 3. The user has pending keys for an explicit passphrase that is somehow set
384 // to their current GAIA passphrase.
385 // 4. The user has pending keys encrypted with their current GAIA passphrase
386 // and the caller passes in the current GAIA passphrase.
387 // 5. The user has pending keys encrypted with an older GAIA passphrase
388 // and the caller passes in the current GAIA passphrase.
389 // 6. The user has previously done encryption with an explicit passphrase.
390 // Furthermore, we enforce the fact that the bootstrap encryption token will
391 // always be derived from the newest GAIA password if the account is using
392 // an implicit passphrase (even if the data is encrypted with an old GAIA
393 // password). If the account is using an explicit (custom) passphrase, the
394 // bootstrap token will be derived from the most recently provided explicit
395 // passphrase (that was able to decrypt the data).
396 if (!IsExplicitPassphrase(passphrase_type_)) {
397 if (!cryptographer->has_pending_keys()) {
398 if (cryptographer->AddKey(key_params)) {
399 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
400 // keys (1), or overwriting an implicit passphrase with a new explicit
401 // one (2) when there are no pending keys.
402 if (is_explicit) {
403 DVLOG(1) << "Setting explicit passphrase for encryption.";
404 passphrase_type_ = CUSTOM_PASSPHRASE;
405 custom_passphrase_time_ = base::Time::Now();
406 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
407 OnPassphraseTypeChanged(
408 passphrase_type_,
409 GetExplicitPassphraseTime()));
410 } else {
411 DVLOG(1) << "Setting implicit passphrase for encryption.";
413 cryptographer->GetBootstrapToken(&bootstrap_token);
415 // With M26, sync accounts can be in only one of two encryption states:
416 // 1) Encrypt only passwords with an implicit passphrase.
417 // 2) Encrypt all sync datatypes with an explicit passphrase.
418 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms,
419 // and keep track of an account's encryption state via the
420 // "CustomEncryption" histogram. See http://crbug.com/131478.
421 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", is_explicit);
423 success = true;
424 } else {
425 NOTREACHED() << "Failed to add key to cryptographer.";
426 success = false;
428 } else { // cryptographer->has_pending_keys() == true
429 if (is_explicit) {
430 // This can only happen if the nigori node is updated with a new
431 // implicit passphrase while a client is attempting to set a new custom
432 // passphrase (race condition).
433 DVLOG(1) << "Failing because an implicit passphrase is already set.";
434 success = false;
435 } else { // is_explicit == false
436 if (cryptographer->DecryptPendingKeys(key_params)) {
437 // Case 4. We successfully decrypted with the implicit GAIA passphrase
438 // passed in.
439 DVLOG(1) << "Implicit internal passphrase accepted for decryption.";
440 cryptographer->GetBootstrapToken(&bootstrap_token);
441 success = true;
442 } else {
443 // Case 5. Encryption was done with an old GAIA password, but we were
444 // provided with the current GAIA password. We need to generate a new
445 // bootstrap token to preserve it. We build a temporary cryptographer
446 // to allow us to extract these params without polluting our current
447 // cryptographer.
448 DVLOG(1) << "Implicit internal passphrase failed to decrypt, adding "
449 << "anyways as default passphrase and persisting via "
450 << "bootstrap token.";
451 Cryptographer temp_cryptographer(cryptographer->encryptor());
452 temp_cryptographer.AddKey(key_params);
453 temp_cryptographer.GetBootstrapToken(&bootstrap_token);
454 // We then set the new passphrase as the default passphrase of the
455 // real cryptographer, even though we have pending keys. This is safe,
456 // as although Cryptographer::is_initialized() will now be true,
457 // is_ready() will remain false due to having pending keys.
458 cryptographer->AddKey(key_params);
459 success = false;
461 } // is_explicit
462 } // cryptographer->has_pending_keys()
463 } else { // IsExplicitPassphrase(passphrase_type_) == true.
464 // Case 6. We do not want to override a previously set explicit passphrase,
465 // so we return a failure.
466 DVLOG(1) << "Failing because an explicit passphrase is already set.";
467 success = false;
470 DVLOG_IF(1, !success)
471 << "Failure in SetEncryptionPassphrase; notifying and returning.";
472 DVLOG_IF(1, success)
473 << "Successfully set encryption passphrase; updating nigori and "
474 "reencrypting.";
476 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
479 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
480 const std::string& passphrase) {
481 DCHECK(thread_checker_.CalledOnValidThread());
482 // We do not accept empty passphrases.
483 if (passphrase.empty()) {
484 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
485 return;
488 // All accesses to the cryptographer are protected by a transaction.
489 WriteTransaction trans(FROM_HERE, user_share_);
490 KeyParams key_params = {"localhost", "dummy", passphrase};
491 WriteNode node(&trans);
492 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) {
493 NOTREACHED();
494 return;
497 // Once we've migrated to keystore, we're only ever decrypting keys derived
498 // from an explicit passphrase. But, for clients without a keystore key yet
499 // (either not on by default or failed to download one), we still support
500 // decrypting with a gaia passphrase, and therefore bypass the
501 // DecryptPendingKeysWithExplicitPassphrase logic.
502 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
503 IsExplicitPassphrase(passphrase_type_)) {
504 DecryptPendingKeysWithExplicitPassphrase(passphrase, &trans, &node);
505 return;
508 Cryptographer* cryptographer =
509 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
510 if (!cryptographer->has_pending_keys()) {
511 // Note that this *can* happen in a rare situation where data is
512 // re-encrypted on another client while a SetDecryptionPassphrase() call is
513 // in-flight on this client. It is rare enough that we choose to do nothing.
514 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
515 << "were no pending keys.";
516 return;
519 std::string bootstrap_token;
520 sync_pb::EncryptedData pending_keys;
521 pending_keys = cryptographer->GetPendingKeys();
522 bool success = false;
524 // There are three cases to handle here:
525 // 7. We're using the current GAIA password to decrypt the pending keys. This
526 // happens when signing in to an account with a previously set implicit
527 // passphrase, where the data is already encrypted with the newest GAIA
528 // password.
529 // 8. The user is providing an old GAIA password to decrypt the pending keys.
530 // In this case, the user is using an implicit passphrase, but has changed
531 // their password since they last encrypted their data, and therefore
532 // their current GAIA password was unable to decrypt the data. This will
533 // happen when the user is setting up a new profile with a previously
534 // encrypted account (after changing passwords).
535 // 9. The user is providing a previously set explicit passphrase to decrypt
536 // the pending keys.
537 if (!IsExplicitPassphrase(passphrase_type_)) {
538 if (cryptographer->is_initialized()) {
539 // We only want to change the default encryption key to the pending
540 // one if the pending keybag already contains the current default.
541 // This covers the case where a different client re-encrypted
542 // everything with a newer gaia passphrase (and hence the keybag
543 // contains keys from all previously used gaia passphrases).
544 // Otherwise, we're in a situation where the pending keys are
545 // encrypted with an old gaia passphrase, while the default is the
546 // current gaia passphrase. In that case, we preserve the default.
547 Cryptographer temp_cryptographer(cryptographer->encryptor());
548 temp_cryptographer.SetPendingKeys(cryptographer->GetPendingKeys());
549 if (temp_cryptographer.DecryptPendingKeys(key_params)) {
550 // Check to see if the pending bag of keys contains the current
551 // default key.
552 sync_pb::EncryptedData encrypted;
553 cryptographer->GetKeys(&encrypted);
554 if (temp_cryptographer.CanDecrypt(encrypted)) {
555 DVLOG(1) << "Implicit user provided passphrase accepted for "
556 << "decryption, overwriting default.";
557 // Case 7. The pending keybag contains the current default. Go ahead
558 // and update the cryptographer, letting the default change.
559 cryptographer->DecryptPendingKeys(key_params);
560 cryptographer->GetBootstrapToken(&bootstrap_token);
561 success = true;
562 } else {
563 // Case 8. The pending keybag does not contain the current default
564 // encryption key. We decrypt the pending keys here, and in
565 // FinishSetPassphrase, re-encrypt everything with the current GAIA
566 // passphrase instead of the passphrase just provided by the user.
567 DVLOG(1) << "Implicit user provided passphrase accepted for "
568 << "decryption, restoring implicit internal passphrase "
569 << "as default.";
570 std::string bootstrap_token_from_current_key;
571 cryptographer->GetBootstrapToken(
572 &bootstrap_token_from_current_key);
573 cryptographer->DecryptPendingKeys(key_params);
574 // Overwrite the default from the pending keys.
575 cryptographer->AddKeyFromBootstrapToken(
576 bootstrap_token_from_current_key);
577 success = true;
579 } else { // !temp_cryptographer.DecryptPendingKeys(..)
580 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
581 success = false;
582 } // temp_cryptographer.DecryptPendingKeys(...)
583 } else { // cryptographer->is_initialized() == false
584 if (cryptographer->DecryptPendingKeys(key_params)) {
585 // This can happpen in two cases:
586 // - First time sync on android, where we'll never have a
587 // !user_provided passphrase.
588 // - This is a restart for a client that lost their bootstrap token.
589 // In both cases, we should go ahead and initialize the cryptographer
590 // and persist the new bootstrap token.
592 // Note: at this point, we cannot distinguish between cases 7 and 8
593 // above. This user provided passphrase could be the current or the
594 // old. But, as long as we persist the token, there's nothing more
595 // we can do.
596 cryptographer->GetBootstrapToken(&bootstrap_token);
597 DVLOG(1) << "Implicit user provided passphrase accepted, initializing"
598 << " cryptographer.";
599 success = true;
600 } else {
601 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
602 success = false;
604 } // cryptographer->is_initialized()
605 } else { // nigori_has_explicit_passphrase == true
606 // Case 9. Encryption was done with an explicit passphrase, and we decrypt
607 // with the passphrase provided by the user.
608 if (cryptographer->DecryptPendingKeys(key_params)) {
609 DVLOG(1) << "Explicit passphrase accepted for decryption.";
610 cryptographer->GetBootstrapToken(&bootstrap_token);
611 success = true;
612 } else {
613 DVLOG(1) << "Explicit passphrase failed to decrypt.";
614 success = false;
616 } // nigori_has_explicit_passphrase
618 DVLOG_IF(1, !success)
619 << "Failure in SetDecryptionPassphrase; notifying and returning.";
620 DVLOG_IF(1, success)
621 << "Successfully set decryption passphrase; updating nigori and "
622 "reencrypting.";
624 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
627 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
628 DCHECK(thread_checker_.CalledOnValidThread());
629 WriteTransaction trans(FROM_HERE, user_share_);
630 DVLOG(1) << "Enabling encrypt everything.";
631 if (encrypt_everything_)
632 return;
633 EnableEncryptEverythingImpl(trans.GetWrappedTrans());
634 WriteEncryptionStateToNigori(&trans);
635 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
636 ReEncryptEverything(&trans);
639 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
640 DCHECK(thread_checker_.CalledOnValidThread());
641 return encrypt_everything_;
644 PassphraseType SyncEncryptionHandlerImpl::GetPassphraseType() const {
645 DCHECK(thread_checker_.CalledOnValidThread());
646 return passphrase_type_;
649 // Note: this is called from within a syncable transaction, so we need to post
650 // tasks if we want to do any work that creates a new sync_api transaction.
651 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
652 const sync_pb::NigoriSpecifics& nigori,
653 syncable::BaseTransaction* const trans) {
654 DCHECK(thread_checker_.CalledOnValidThread());
655 DCHECK(trans);
656 if (!ApplyNigoriUpdateImpl(nigori, trans)) {
657 base::MessageLoop::current()->PostTask(
658 FROM_HERE,
659 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
660 weak_ptr_factory_.GetWeakPtr()));
663 FOR_EACH_OBSERVER(
664 SyncEncryptionHandler::Observer,
665 observers_,
666 OnCryptographerStateChanged(
667 &UnlockVaultMutable(trans)->cryptographer));
670 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
671 sync_pb::NigoriSpecifics* nigori,
672 syncable::BaseTransaction* const trans) const {
673 DCHECK(thread_checker_.CalledOnValidThread());
674 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types,
675 encrypt_everything_,
676 nigori);
679 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
680 syncable::BaseTransaction* const trans) const {
681 DCHECK(thread_checker_.CalledOnValidThread());
682 return keystore_key_.empty();
685 bool SyncEncryptionHandlerImpl::SetKeystoreKeys(
686 const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
687 syncable::BaseTransaction* const trans) {
688 DCHECK(thread_checker_.CalledOnValidThread());
689 if (keys.size() == 0)
690 return false;
691 // The last key in the vector is the current keystore key. The others are kept
692 // around for decryption only.
693 const std::string& raw_keystore_key = keys.Get(keys.size() - 1);
694 if (raw_keystore_key.empty())
695 return false;
697 // Note: in order to Pack the keys, they must all be base64 encoded (else
698 // JSON serialization fails).
699 base::Base64Encode(raw_keystore_key, &keystore_key_);
701 // Go through and save the old keystore keys. We always persist all keystore
702 // keys the server sends us.
703 old_keystore_keys_.resize(keys.size() - 1);
704 for (int i = 0; i < keys.size() - 1; ++i)
705 base::Base64Encode(keys.Get(i), &old_keystore_keys_[i]);
707 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
709 // Update the bootstrap token. If this fails, we persist an empty string,
710 // which will force us to download the keystore keys again on the next
711 // restart.
712 std::string keystore_bootstrap = PackKeystoreBootstrapToken(
713 old_keystore_keys_,
714 keystore_key_,
715 cryptographer->encryptor());
717 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
718 OnBootstrapTokenUpdated(keystore_bootstrap,
719 KEYSTORE_BOOTSTRAP_TOKEN));
720 DVLOG(1) << "Keystore bootstrap token updated.";
722 // If this is a first time sync, we get the encryption keys before we process
723 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
724 // once we have the nigori node.
725 syncable::Entry entry(trans, syncable::GET_TYPE_ROOT, NIGORI);
726 if (!entry.good())
727 return true;
729 const sync_pb::NigoriSpecifics& nigori =
730 entry.GetSpecifics().nigori();
731 if (cryptographer->has_pending_keys() &&
732 IsNigoriMigratedToKeystore(nigori) &&
733 !nigori.keystore_decryptor_token().blob().empty()) {
734 // If the nigori is already migrated and we have pending keys, we might
735 // be able to decrypt them using either the keystore decryptor token
736 // or the existing keystore keys.
737 DecryptPendingKeysWithKeystoreKey(keystore_key_,
738 nigori.keystore_decryptor_token(),
739 cryptographer);
742 // Note that triggering migration will have no effect if we're already
743 // properly migrated with the newest keystore keys.
744 if (ShouldTriggerMigration(nigori, *cryptographer)) {
745 base::MessageLoop::current()->PostTask(
746 FROM_HERE,
747 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
748 weak_ptr_factory_.GetWeakPtr()));
751 return true;
754 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes(
755 syncable::BaseTransaction* const trans) const {
756 return UnlockVault(trans).encrypted_types;
759 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
760 DCHECK(thread_checker_.CalledOnValidThread());
761 return &vault_unsafe_.cryptographer;
764 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
765 DCHECK(thread_checker_.CalledOnValidThread());
766 return vault_unsafe_.encrypted_types;
769 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
770 DCHECK(thread_checker_.CalledOnValidThread());
771 ReadTransaction trans(FROM_HERE, user_share_);
772 ReadNode nigori_node(&trans);
773 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
774 return false;
775 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
778 base::Time SyncEncryptionHandlerImpl::migration_time() const {
779 return migration_time_;
782 base::Time SyncEncryptionHandlerImpl::custom_passphrase_time() const {
783 return custom_passphrase_time_;
786 void SyncEncryptionHandlerImpl::RestoreNigori(
787 const SyncEncryptionHandler::NigoriState& nigori_state) {
788 DCHECK(thread_checker_.CalledOnValidThread());
789 WriteTransaction trans(FROM_HERE, user_share_);
791 // Verify we don't already have a nigori node.
792 WriteNode nigori_node(&trans);
793 BaseNode::InitByLookupResult init_result = nigori_node.InitTypeRoot(NIGORI);
794 DCHECK(init_result == BaseNode::INIT_FAILED_ENTRY_NOT_GOOD);
796 // Create one.
797 syncable::ModelNeutralMutableEntry model_neutral_mutable_entry(
798 trans.GetWrappedWriteTrans(), syncable::CREATE_NEW_TYPE_ROOT, NIGORI);
799 DCHECK(model_neutral_mutable_entry.good());
800 model_neutral_mutable_entry.PutServerIsDir(true);
801 model_neutral_mutable_entry.PutUniqueServerTag(ModelTypeToRootTag(NIGORI));
802 model_neutral_mutable_entry.PutIsUnsynced(true);
804 // Update it with the saved nigori specifics.
805 syncable::MutableEntry mutable_entry(trans.GetWrappedWriteTrans(),
806 syncable::GET_TYPE_ROOT, NIGORI);
807 DCHECK(mutable_entry.good());
808 sync_pb::EntitySpecifics specifics;
809 specifics.mutable_nigori()->CopyFrom(nigori_state.nigori_specifics);
810 mutable_entry.PutSpecifics(specifics);
812 // Update our state based on the saved nigori node.
813 ApplyNigoriUpdate(nigori_state.nigori_specifics, trans.GetWrappedTrans());
816 // This function iterates over all encrypted types. There are many scenarios in
817 // which data for some or all types is not currently available. In that case,
818 // the lookup of the root node will fail and we will skip encryption for that
819 // type.
820 void SyncEncryptionHandlerImpl::ReEncryptEverything(
821 WriteTransaction* trans) {
822 DCHECK(thread_checker_.CalledOnValidThread());
823 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
824 for (ModelTypeSet::Iterator iter =
825 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
826 iter.Good(); iter.Inc()) {
827 if (iter.Get() == PASSWORDS || IsControlType(iter.Get()))
828 continue; // These types handle encryption differently.
830 ReadNode type_root(trans);
831 if (type_root.InitTypeRoot(iter.Get()) != BaseNode::INIT_OK)
832 continue; // Don't try to reencrypt if the type's data is unavailable.
834 // Iterate through all children of this datatype.
835 std::queue<int64> to_visit;
836 int64 child_id = type_root.GetFirstChildId();
837 to_visit.push(child_id);
838 while (!to_visit.empty()) {
839 child_id = to_visit.front();
840 to_visit.pop();
841 if (child_id == kInvalidId)
842 continue;
844 WriteNode child(trans);
845 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK)
846 continue; // Possible for locally deleted items.
847 if (child.GetIsFolder()) {
848 to_visit.push(child.GetFirstChildId());
850 if (child.GetEntry()->GetUniqueServerTag().empty()) {
851 // Rewrite the specifics of the node with encrypted data if necessary
852 // (only rewrite the non-unique folders).
853 child.ResetFromSpecifics();
855 to_visit.push(child.GetSuccessorId());
859 // Passwords are encrypted with their own legacy scheme. Passwords are always
860 // encrypted so we don't need to check GetEncryptedTypes() here.
861 ReadNode passwords_root(trans);
862 if (passwords_root.InitTypeRoot(PASSWORDS) == BaseNode::INIT_OK) {
863 int64 child_id = passwords_root.GetFirstChildId();
864 while (child_id != kInvalidId) {
865 WriteNode child(trans);
866 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK)
867 break; // Possible if we failed to decrypt the data for some reason.
868 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
869 child_id = child.GetSuccessorId();
873 DVLOG(1) << "Re-encrypt everything complete.";
875 // NOTE: We notify from within a transaction.
876 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
877 OnEncryptionComplete());
880 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
881 const sync_pb::NigoriSpecifics& nigori,
882 syncable::BaseTransaction* const trans) {
883 DCHECK(thread_checker_.CalledOnValidThread());
884 DVLOG(1) << "Applying nigori node update.";
885 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
886 trans);
888 if (nigori.custom_passphrase_time() != 0) {
889 custom_passphrase_time_ =
890 ProtoTimeToTime(nigori.custom_passphrase_time());
892 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori);
893 if (is_nigori_migrated) {
894 migration_time_ = ProtoTimeToTime(nigori.keystore_migration_time());
895 PassphraseType nigori_passphrase_type =
896 ProtoPassphraseTypeToEnum(nigori.passphrase_type());
898 // Only update the local passphrase state if it's a valid transition:
899 // - implicit -> keystore
900 // - implicit -> frozen implicit
901 // - implicit -> custom
902 // - keystore -> custom
903 // Note: frozen implicit -> custom is not technically a valid transition,
904 // but we let it through here as well in case future versions do add support
905 // for this transition.
906 if (passphrase_type_ != nigori_passphrase_type &&
907 nigori_passphrase_type != IMPLICIT_PASSPHRASE &&
908 (passphrase_type_ == IMPLICIT_PASSPHRASE ||
909 nigori_passphrase_type == CUSTOM_PASSPHRASE)) {
910 DVLOG(1) << "Changing passphrase state from "
911 << PassphraseTypeToString(passphrase_type_)
912 << " to "
913 << PassphraseTypeToString(nigori_passphrase_type);
914 passphrase_type_ = nigori_passphrase_type;
915 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
916 OnPassphraseTypeChanged(
917 passphrase_type_,
918 GetExplicitPassphraseTime()));
920 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) {
921 // This is the case where another client that didn't support keystore
922 // encryption attempted to enable full encryption. We detect it
923 // and switch the passphrase type to frozen implicit passphrase instead
924 // due to full encryption not being compatible with keystore passphrase.
925 // Because the local passphrase type will not match the nigori passphrase
926 // type, we will trigger a rewrite and subsequently a re-migration.
927 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
928 << "due to full encryption.";
929 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE;
930 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
931 OnPassphraseTypeChanged(
932 passphrase_type_,
933 GetExplicitPassphraseTime()));
935 } else {
936 // It's possible that while we're waiting for migration a client that does
937 // not have keystore encryption enabled switches to a custom passphrase.
938 if (nigori.keybag_is_frozen() &&
939 passphrase_type_ != CUSTOM_PASSPHRASE) {
940 passphrase_type_ = CUSTOM_PASSPHRASE;
941 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
942 OnPassphraseTypeChanged(
943 passphrase_type_,
944 GetExplicitPassphraseTime()));
948 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
949 bool nigori_needs_new_keys = false;
950 if (!nigori.encryption_keybag().blob().empty()) {
951 // We only update the default key if this was a new explicit passphrase.
952 // Else, since it was decryptable, it must not have been a new key.
953 bool need_new_default_key = false;
954 if (is_nigori_migrated) {
955 need_new_default_key = IsExplicitPassphrase(
956 ProtoPassphraseTypeToEnum(nigori.passphrase_type()));
957 } else {
958 need_new_default_key = nigori.keybag_is_frozen();
960 if (!AttemptToInstallKeybag(nigori.encryption_keybag(),
961 need_new_default_key,
962 cryptographer)) {
963 // Check to see if we can decrypt the keybag using the keystore decryptor
964 // token.
965 cryptographer->SetPendingKeys(nigori.encryption_keybag());
966 if (!nigori.keystore_decryptor_token().blob().empty() &&
967 !keystore_key_.empty()) {
968 if (DecryptPendingKeysWithKeystoreKey(keystore_key_,
969 nigori.keystore_decryptor_token(),
970 cryptographer)) {
971 nigori_needs_new_keys =
972 cryptographer->KeybagIsStale(nigori.encryption_keybag());
973 } else {
974 LOG(ERROR) << "Failed to decrypt pending keys using keystore "
975 << "bootstrap key.";
978 } else {
979 // Keybag was installed. We write back our local keybag into the nigori
980 // node if the nigori node's keybag either contains less keys or
981 // has a different default key.
982 nigori_needs_new_keys =
983 cryptographer->KeybagIsStale(nigori.encryption_keybag());
985 } else {
986 // The nigori node has an empty encryption keybag. Attempt to write our
987 // local encryption keys into it.
988 LOG(WARNING) << "Nigori had empty encryption keybag.";
989 nigori_needs_new_keys = true;
992 // If we've completed a sync cycle and the cryptographer isn't ready
993 // yet or has pending keys, prompt the user for a passphrase.
994 if (cryptographer->has_pending_keys()) {
995 DVLOG(1) << "OnPassphraseRequired Sent";
996 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys();
997 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
998 OnPassphraseRequired(REASON_DECRYPTION,
999 pending_keys));
1000 } else if (!cryptographer->is_ready()) {
1001 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
1002 << "ready";
1003 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1004 OnPassphraseRequired(REASON_ENCRYPTION,
1005 sync_pb::EncryptedData()));
1008 // Check if the current local encryption state is stricter/newer than the
1009 // nigori state. If so, we need to overwrite the nigori node with the local
1010 // state.
1011 bool passphrase_type_matches = true;
1012 if (!is_nigori_migrated) {
1013 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE ||
1014 passphrase_type_ == IMPLICIT_PASSPHRASE);
1015 passphrase_type_matches =
1016 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_);
1017 } else {
1018 passphrase_type_matches =
1019 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) ==
1020 passphrase_type_);
1022 if (!passphrase_type_matches ||
1023 nigori.encrypt_everything() != encrypt_everything_ ||
1024 nigori_types_need_update ||
1025 nigori_needs_new_keys) {
1026 DVLOG(1) << "Triggering nigori rewrite.";
1027 return false;
1029 return true;
1032 void SyncEncryptionHandlerImpl::RewriteNigori() {
1033 DVLOG(1) << "Writing local encryption state into nigori.";
1034 DCHECK(thread_checker_.CalledOnValidThread());
1035 WriteTransaction trans(FROM_HERE, user_share_);
1036 WriteEncryptionStateToNigori(&trans);
1039 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
1040 WriteTransaction* trans) {
1041 DCHECK(thread_checker_.CalledOnValidThread());
1042 WriteNode nigori_node(trans);
1043 // This can happen in tests that don't have nigori nodes.
1044 if (nigori_node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK)
1045 return;
1047 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
1048 const Cryptographer& cryptographer =
1049 UnlockVault(trans->GetWrappedTrans()).cryptographer;
1051 // Will not do anything if we shouldn't or can't migrate. Otherwise
1052 // migrates, writing the full encryption state as it does.
1053 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) {
1054 if (cryptographer.is_ready() &&
1055 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
1056 // Does not modify the encrypted blob if the unencrypted data already
1057 // matches what is about to be written.
1058 sync_pb::EncryptedData original_keys = nigori.encryption_keybag();
1059 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1060 NOTREACHED();
1062 if (nigori.encryption_keybag().SerializeAsString() !=
1063 original_keys.SerializeAsString()) {
1064 // We've updated the nigori node's encryption keys. In order to prevent
1065 // a possible looping of two clients constantly overwriting each other,
1066 // we limit the absolute number of overwrites per client instantiation.
1067 nigori_overwrite_count_++;
1068 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
1069 nigori_overwrite_count_);
1072 // Note: we don't try to set keybag_is_frozen here since if that
1073 // is lost the user can always set it again (and we don't want to clobber
1074 // any migration state). The main goal at this point is to preserve
1075 // the encryption keys so all data remains decryptable.
1077 syncable::UpdateNigoriFromEncryptedTypes(
1078 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
1079 encrypt_everything_,
1080 &nigori);
1081 if (!custom_passphrase_time_.is_null()) {
1082 nigori.set_custom_passphrase_time(
1083 TimeToProtoTime(custom_passphrase_time_));
1086 // If nothing has changed, this is a no-op.
1087 nigori_node.SetNigoriSpecifics(nigori);
1091 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
1092 const sync_pb::NigoriSpecifics& nigori,
1093 syncable::BaseTransaction* const trans) {
1094 DCHECK(thread_checker_.CalledOnValidThread());
1095 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1096 if (nigori.encrypt_everything()) {
1097 EnableEncryptEverythingImpl(trans);
1098 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1099 return true;
1100 } else if (encrypt_everything_) {
1101 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1102 return false;
1105 ModelTypeSet nigori_encrypted_types;
1106 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori);
1107 nigori_encrypted_types.PutAll(SensitiveTypes());
1109 // If anything more than the sensitive types were encrypted, and
1110 // encrypt_everything is not explicitly set to false, we assume it means
1111 // a client intended to enable encrypt everything.
1112 if (!nigori.has_encrypt_everything() &&
1113 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) {
1114 if (!encrypt_everything_) {
1115 encrypt_everything_ = true;
1116 *encrypted_types = EncryptableUserTypes();
1117 FOR_EACH_OBSERVER(
1118 Observer, observers_,
1119 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1121 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1122 return false;
1125 MergeEncryptedTypes(nigori_encrypted_types, trans);
1126 return encrypted_types->Equals(nigori_encrypted_types);
1129 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
1130 const std::string& passphrase,
1131 WriteTransaction* trans,
1132 WriteNode* nigori_node) {
1133 DCHECK(thread_checker_.CalledOnValidThread());
1134 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics()));
1135 KeyParams key_params = {"localhost", "dummy", passphrase};
1137 if (passphrase_type_ != KEYSTORE_PASSPHRASE) {
1138 DVLOG(1) << "Failing to set a custom passphrase because one has already "
1139 << "been set.";
1140 FinishSetPassphrase(false, std::string(), trans, nigori_node);
1141 return;
1144 Cryptographer* cryptographer =
1145 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1146 if (cryptographer->has_pending_keys()) {
1147 // This theoretically shouldn't happen, because the only way to have pending
1148 // keys after migrating to keystore support is if a custom passphrase was
1149 // set, which should update passpshrase_state_ and should be caught by the
1150 // if statement above. For the sake of safety though, we check for it in
1151 // case a client is misbehaving.
1152 LOG(ERROR) << "Failing to set custom passphrase because of pending keys.";
1153 FinishSetPassphrase(false, std::string(), trans, nigori_node);
1154 return;
1157 std::string bootstrap_token;
1158 if (!cryptographer->AddKey(key_params)) {
1159 NOTREACHED() << "Failed to add key to cryptographer.";
1160 return;
1163 DVLOG(1) << "Setting custom passphrase.";
1164 cryptographer->GetBootstrapToken(&bootstrap_token);
1165 passphrase_type_ = CUSTOM_PASSPHRASE;
1166 custom_passphrase_time_ = base::Time::Now();
1167 FOR_EACH_OBSERVER(
1168 SyncEncryptionHandler::Observer, observers_,
1169 OnPassphraseTypeChanged(passphrase_type_, GetExplicitPassphraseTime()));
1170 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node);
1173 void SyncEncryptionHandlerImpl::NotifyObserversOfLocalCustomPassphrase(
1174 WriteTransaction* trans) {
1175 WriteNode nigori_node(trans);
1176 BaseNode::InitByLookupResult init_result = nigori_node.InitTypeRoot(NIGORI);
1177 DCHECK_EQ(init_result, BaseNode::INIT_OK);
1178 NigoriState nigori_state;
1179 nigori_state.nigori_specifics = nigori_node.GetNigoriSpecifics();
1180 DCHECK(nigori_state.nigori_specifics.passphrase_type() ==
1181 sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE ||
1182 nigori_state.nigori_specifics.passphrase_type() ==
1183 sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE);
1184 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1185 OnLocalSetPassphraseEncryption(nigori_state));
1188 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
1189 const std::string& passphrase,
1190 WriteTransaction* trans,
1191 WriteNode* nigori_node) {
1192 DCHECK(thread_checker_.CalledOnValidThread());
1193 DCHECK(IsExplicitPassphrase(passphrase_type_));
1194 KeyParams key_params = {"localhost", "dummy", passphrase};
1196 Cryptographer* cryptographer =
1197 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1198 if (!cryptographer->has_pending_keys()) {
1199 // Note that this *can* happen in a rare situation where data is
1200 // re-encrypted on another client while a SetDecryptionPassphrase() call is
1201 // in-flight on this client. It is rare enough that we choose to do nothing.
1202 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
1203 << "were no pending keys.";
1204 return;
1207 DCHECK(IsExplicitPassphrase(passphrase_type_));
1208 bool success = false;
1209 std::string bootstrap_token;
1210 if (cryptographer->DecryptPendingKeys(key_params)) {
1211 DVLOG(1) << "Explicit passphrase accepted for decryption.";
1212 cryptographer->GetBootstrapToken(&bootstrap_token);
1213 success = true;
1214 } else {
1215 DVLOG(1) << "Explicit passphrase failed to decrypt.";
1216 success = false;
1218 if (success && !keystore_key_.empty()) {
1219 // Should already be part of the encryption keybag, but we add it just
1220 // in case.
1221 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1222 cryptographer->AddNonDefaultKey(key_params);
1224 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node);
1227 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
1228 bool success,
1229 const std::string& bootstrap_token,
1230 WriteTransaction* trans,
1231 WriteNode* nigori_node) {
1232 DCHECK(thread_checker_.CalledOnValidThread());
1233 FOR_EACH_OBSERVER(
1234 SyncEncryptionHandler::Observer,
1235 observers_,
1236 OnCryptographerStateChanged(
1237 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
1239 // It's possible we need to change the bootstrap token even if we failed to
1240 // set the passphrase (for example if we need to preserve the new GAIA
1241 // passphrase).
1242 if (!bootstrap_token.empty()) {
1243 DVLOG(1) << "Passphrase bootstrap token updated.";
1244 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1245 OnBootstrapTokenUpdated(bootstrap_token,
1246 PASSPHRASE_BOOTSTRAP_TOKEN));
1249 const Cryptographer& cryptographer =
1250 UnlockVault(trans->GetWrappedTrans()).cryptographer;
1251 if (!success) {
1252 if (cryptographer.is_ready()) {
1253 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer "
1254 << "was ready.";
1255 } else if (cryptographer.has_pending_keys()) {
1256 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1257 OnPassphraseRequired(REASON_DECRYPTION,
1258 cryptographer.GetPendingKeys()));
1259 } else {
1260 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1261 OnPassphraseRequired(REASON_ENCRYPTION,
1262 sync_pb::EncryptedData()));
1264 return;
1266 DCHECK(success);
1267 DCHECK(cryptographer.is_ready());
1269 // Will do nothing if we're already properly migrated or unable to migrate
1270 // (in otherwords, if ShouldTriggerMigration is false).
1271 // Otherwise will update the nigori node with the current migrated state,
1272 // writing all encryption state as it does.
1273 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) {
1274 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics());
1275 // Does not modify nigori.encryption_keybag() if the original decrypted
1276 // data was the same.
1277 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1278 NOTREACHED();
1279 if (IsNigoriMigratedToKeystore(nigori)) {
1280 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_));
1281 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1282 << " passphrase.";
1283 } else {
1284 nigori.set_keybag_is_frozen(
1285 IsExplicitPassphrase(passphrase_type_));
1287 // If we set a new custom passphrase, store the timestamp.
1288 if (!custom_passphrase_time_.is_null()) {
1289 nigori.set_custom_passphrase_time(
1290 TimeToProtoTime(custom_passphrase_time_));
1292 nigori_node->SetNigoriSpecifics(nigori);
1295 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
1296 // checks the passphrase state after it has been set.
1297 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1298 OnPassphraseAccepted());
1300 // Does nothing if everything is already encrypted.
1301 // TODO(zea): If we just migrated and enabled encryption, this will be
1302 // redundant. Figure out a way to not do this unnecessarily.
1303 ReEncryptEverything(trans);
1306 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
1307 ModelTypeSet new_encrypted_types,
1308 syncable::BaseTransaction* const trans) {
1309 DCHECK(thread_checker_.CalledOnValidThread());
1311 // Only UserTypes may be encrypted.
1312 DCHECK(EncryptableUserTypes().HasAll(new_encrypted_types));
1314 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1315 if (!encrypted_types->HasAll(new_encrypted_types)) {
1316 *encrypted_types = new_encrypted_types;
1317 FOR_EACH_OBSERVER(
1318 Observer, observers_,
1319 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1323 SyncEncryptionHandlerImpl::Vault* SyncEncryptionHandlerImpl::UnlockVaultMutable(
1324 syncable::BaseTransaction* const trans) {
1325 DCHECK_EQ(user_share_->directory.get(), trans->directory());
1326 return &vault_unsafe_;
1329 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
1330 syncable::BaseTransaction* const trans) const {
1331 DCHECK_EQ(user_share_->directory.get(), trans->directory());
1332 return vault_unsafe_;
1335 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1336 const sync_pb::NigoriSpecifics& nigori,
1337 const Cryptographer& cryptographer) const {
1338 DCHECK(thread_checker_.CalledOnValidThread());
1339 // Don't migrate if there are pending encryption keys (because data
1340 // encrypted with the pending keys will not be decryptable).
1341 if (cryptographer.has_pending_keys())
1342 return false;
1343 if (IsNigoriMigratedToKeystore(nigori)) {
1344 // If the nigori is already migrated but does not reflect the explicit
1345 // passphrase state, remigrate. Similarly, if the nigori has an explicit
1346 // passphrase but does not have full encryption, or the nigori has an
1347 // implicit passphrase but does have full encryption, re-migrate.
1348 // Note that this is to defend against other clients without keystore
1349 // encryption enabled transitioning to states that are no longer valid.
1350 if (passphrase_type_ != KEYSTORE_PASSPHRASE &&
1351 nigori.passphrase_type() ==
1352 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) {
1353 return true;
1354 } else if (IsExplicitPassphrase(passphrase_type_) &&
1355 !encrypt_everything_) {
1356 return true;
1357 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE &&
1358 encrypt_everything_) {
1359 return true;
1360 } else if (
1361 cryptographer.is_ready() &&
1362 !cryptographer.CanDecryptUsingDefaultKey(nigori.encryption_keybag())) {
1363 // We need to overwrite the keybag. This might involve overwriting the
1364 // keystore decryptor too.
1365 return true;
1366 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) {
1367 // Check to see if a server key rotation has happened, but the nigori
1368 // node's keys haven't been rotated yet, and hence we should re-migrate.
1369 // Note that once a key rotation has been performed, we no longer
1370 // preserve backwards compatibility, and the keybag will therefore be
1371 // encrypted with the current keystore key.
1372 Cryptographer temp_cryptographer(cryptographer.encryptor());
1373 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1374 temp_cryptographer.AddKey(keystore_params);
1375 if (!temp_cryptographer.CanDecryptUsingDefaultKey(
1376 nigori.encryption_keybag())) {
1377 return true;
1380 return false;
1381 } else if (keystore_key_.empty()) {
1382 // If we haven't already migrated, we don't want to do anything unless
1383 // a keystore key is available (so that those clients without keystore
1384 // encryption enabled aren't forced into new states, e.g. frozen implicit
1385 // passphrase).
1386 return false;
1388 return true;
1391 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1392 WriteTransaction* trans,
1393 WriteNode* nigori_node) {
1394 DCHECK(thread_checker_.CalledOnValidThread());
1395 const sync_pb::NigoriSpecifics& old_nigori =
1396 nigori_node->GetNigoriSpecifics();
1397 Cryptographer* cryptographer =
1398 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1400 if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1401 return false;
1403 DVLOG(1) << "Starting nigori migration to keystore support.";
1404 sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1406 PassphraseType new_passphrase_type = passphrase_type_;
1407 bool new_encrypt_everything = encrypt_everything_;
1408 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) {
1409 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1410 << "full encryption.";
1411 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE;
1412 migrated_nigori.clear_keystore_decryptor_token();
1413 } else if (IsExplicitPassphrase(passphrase_type_)) {
1414 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to "
1415 << "explicit passphrase";
1416 new_encrypt_everything = true;
1417 migrated_nigori.clear_keystore_decryptor_token();
1418 } else {
1419 DCHECK(!encrypt_everything_);
1420 new_passphrase_type = KEYSTORE_PASSPHRASE;
1421 DVLOG(1) << "Switching to keystore passphrase state.";
1423 migrated_nigori.set_encrypt_everything(new_encrypt_everything);
1424 migrated_nigori.set_passphrase_type(
1425 EnumPassphraseTypeToProto(new_passphrase_type));
1426 migrated_nigori.set_keybag_is_frozen(true);
1428 if (!keystore_key_.empty()) {
1429 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1430 if ((old_keystore_keys_.size() > 0 &&
1431 new_passphrase_type == KEYSTORE_PASSPHRASE) ||
1432 !cryptographer->is_initialized()) {
1433 // Either at least one key rotation has been performed, so we no longer
1434 // care about backwards compatibility, or we're generating keystore-based
1435 // encryption keys without knowing the GAIA password (and therefore the
1436 // cryptographer is not initialized), so we can't support backwards
1437 // compatibility. Ensure the keystore key is the default key.
1438 DVLOG(1) << "Migrating keybag to keystore key.";
1439 bool cryptographer_was_ready = cryptographer->is_ready();
1440 if (!cryptographer->AddKey(key_params)) {
1441 LOG(ERROR) << "Failed to add keystore key as default key";
1442 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1443 FAILED_TO_SET_DEFAULT_KEYSTORE,
1444 MIGRATION_RESULT_SIZE);
1445 return false;
1447 if (!cryptographer_was_ready && cryptographer->is_ready()) {
1448 FOR_EACH_OBSERVER(
1449 SyncEncryptionHandler::Observer,
1450 observers_,
1451 OnPassphraseAccepted());
1453 } else {
1454 // We're in backwards compatible mode -- either the account has an
1455 // explicit passphrase, or we want to preserve the current GAIA-based key
1456 // as the default because we can (there have been no key rotations since
1457 // the migration).
1458 DVLOG(1) << "Migrating keybag while preserving old key";
1459 if (!cryptographer->AddNonDefaultKey(key_params)) {
1460 LOG(ERROR) << "Failed to add keystore key as non-default key.";
1461 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1462 FAILED_TO_SET_NONDEFAULT_KEYSTORE,
1463 MIGRATION_RESULT_SIZE);
1464 return false;
1468 if (!old_keystore_keys_.empty()) {
1469 // Go through and add all the old keystore keys as non default keys, so
1470 // they'll be preserved in the encryption_keybag when we next write the
1471 // nigori node.
1472 for (std::vector<std::string>::const_iterator iter =
1473 old_keystore_keys_.begin(); iter != old_keystore_keys_.end();
1474 ++iter) {
1475 KeyParams key_params = {"localhost", "dummy", *iter};
1476 cryptographer->AddNonDefaultKey(key_params);
1479 if (new_passphrase_type == KEYSTORE_PASSPHRASE &&
1480 !GetKeystoreDecryptor(
1481 *cryptographer,
1482 keystore_key_,
1483 migrated_nigori.mutable_keystore_decryptor_token())) {
1484 LOG(ERROR) << "Failed to extract keystore decryptor token.";
1485 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1486 FAILED_TO_EXTRACT_DECRYPTOR,
1487 MIGRATION_RESULT_SIZE);
1488 return false;
1490 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) {
1491 LOG(ERROR) << "Failed to extract encryption keybag.";
1492 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1493 FAILED_TO_EXTRACT_KEYBAG,
1494 MIGRATION_RESULT_SIZE);
1495 return false;
1498 if (migration_time_.is_null())
1499 migration_time_ = base::Time::Now();
1500 migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_));
1502 if (!custom_passphrase_time_.is_null()) {
1503 migrated_nigori.set_custom_passphrase_time(
1504 TimeToProtoTime(custom_passphrase_time_));
1507 FOR_EACH_OBSERVER(
1508 SyncEncryptionHandler::Observer,
1509 observers_,
1510 OnCryptographerStateChanged(cryptographer));
1511 if (passphrase_type_ != new_passphrase_type) {
1512 passphrase_type_ = new_passphrase_type;
1513 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1514 OnPassphraseTypeChanged(
1515 passphrase_type_,
1516 GetExplicitPassphraseTime()));
1519 if (new_encrypt_everything && !encrypt_everything_) {
1520 EnableEncryptEverythingImpl(trans->GetWrappedTrans());
1521 ReEncryptEverything(trans);
1522 } else if (!cryptographer->CanDecryptUsingDefaultKey(
1523 old_nigori.encryption_keybag())) {
1524 DVLOG(1) << "Rencrypting everything due to key rotation.";
1525 ReEncryptEverything(trans);
1528 DVLOG(1) << "Completing nigori migration to keystore support.";
1529 nigori_node->SetNigoriSpecifics(migrated_nigori);
1531 if (new_encrypt_everything &&
1532 (new_passphrase_type == FROZEN_IMPLICIT_PASSPHRASE ||
1533 new_passphrase_type == CUSTOM_PASSPHRASE)) {
1534 UpdateNigoriForTransitionToPassphraseEncryption(trans);
1535 NotifyObserversOfLocalCustomPassphrase(trans);
1538 switch (new_passphrase_type) {
1539 case KEYSTORE_PASSPHRASE:
1540 if (old_keystore_keys_.size() > 0) {
1541 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1542 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT,
1543 MIGRATION_RESULT_SIZE);
1544 } else {
1545 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1546 MIGRATION_SUCCESS_KEYSTORE_DEFAULT,
1547 MIGRATION_RESULT_SIZE);
1549 break;
1550 case FROZEN_IMPLICIT_PASSPHRASE:
1551 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1552 MIGRATION_SUCCESS_FROZEN_IMPLICIT,
1553 MIGRATION_RESULT_SIZE);
1554 break;
1555 case CUSTOM_PASSPHRASE:
1556 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1557 MIGRATION_SUCCESS_CUSTOM,
1558 MIGRATION_RESULT_SIZE);
1559 break;
1560 default:
1561 NOTREACHED();
1562 break;
1564 return true;
1567 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1568 const Cryptographer& cryptographer,
1569 const std::string& keystore_key,
1570 sync_pb::EncryptedData* encrypted_blob) {
1571 DCHECK(thread_checker_.CalledOnValidThread());
1572 DCHECK(!keystore_key.empty());
1573 DCHECK(cryptographer.is_ready());
1574 std::string serialized_nigori;
1575 serialized_nigori = cryptographer.GetDefaultNigoriKeyData();
1576 if (serialized_nigori.empty()) {
1577 LOG(ERROR) << "Failed to get cryptographer bootstrap token.";
1578 return false;
1580 Cryptographer temp_cryptographer(cryptographer.encryptor());
1581 KeyParams key_params = {"localhost", "dummy", keystore_key};
1582 if (!temp_cryptographer.AddKey(key_params))
1583 return false;
1584 if (!temp_cryptographer.EncryptString(serialized_nigori, encrypted_blob))
1585 return false;
1586 return true;
1589 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1590 const sync_pb::EncryptedData& keybag,
1591 bool update_default,
1592 Cryptographer* cryptographer) {
1593 if (!cryptographer->CanDecrypt(keybag))
1594 return false;
1595 cryptographer->InstallKeys(keybag);
1596 if (update_default)
1597 cryptographer->SetDefaultKey(keybag.key_name());
1598 return true;
1601 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1602 syncable::BaseTransaction* const trans) {
1603 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1604 if (encrypt_everything_) {
1605 DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1606 return;
1608 encrypt_everything_ = true;
1609 *encrypted_types = EncryptableUserTypes();
1610 FOR_EACH_OBSERVER(
1611 Observer, observers_,
1612 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1615 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1616 const std::string& keystore_key,
1617 const sync_pb::EncryptedData& keystore_decryptor_token,
1618 Cryptographer* cryptographer) {
1619 DCHECK(cryptographer->has_pending_keys());
1620 if (keystore_decryptor_token.blob().empty())
1621 return false;
1622 Cryptographer temp_cryptographer(cryptographer->encryptor());
1624 // First, go through and all all the old keystore keys to the temporary
1625 // cryptographer.
1626 for (size_t i = 0; i < old_keystore_keys_.size(); ++i) {
1627 KeyParams old_key_params = {"localhost", "dummy", old_keystore_keys_[i]};
1628 temp_cryptographer.AddKey(old_key_params);
1631 // Then add the current keystore key as the default key and see if we can
1632 // decrypt.
1633 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1634 if (temp_cryptographer.AddKey(keystore_params) &&
1635 temp_cryptographer.CanDecrypt(keystore_decryptor_token)) {
1636 // Someone else migrated the nigori for us! How generous! Go ahead and
1637 // install both the keystore key and the new default encryption key
1638 // (i.e. the one provided by the keystore decryptor token) into the
1639 // cryptographer.
1640 // The keystore decryptor token is a keystore key encrypted blob containing
1641 // the current serialized default encryption key (and as such should be
1642 // able to decrypt the nigori node's encryption keybag).
1643 // Note: it's possible a key rotation has happened since the migration, and
1644 // we're decrypting using an old keystore key. In that case we need to
1645 // ensure we re-encrypt using the newest key.
1646 DVLOG(1) << "Attempting to decrypt pending keys using "
1647 << "keystore decryptor token.";
1648 std::string serialized_nigori =
1649 temp_cryptographer.DecryptToString(keystore_decryptor_token);
1651 // This will decrypt the pending keys and add them if possible. The key
1652 // within |serialized_nigori| will be the default after.
1653 cryptographer->ImportNigoriKey(serialized_nigori);
1655 if (!temp_cryptographer.CanDecryptUsingDefaultKey(
1656 keystore_decryptor_token)) {
1657 // The keystore decryptor token was derived from an old keystore key.
1658 // A key rotation is necessary, so set the current keystore key as the
1659 // default key (which will trigger a re-migration).
1660 DVLOG(1) << "Pending keys based on old keystore key. Setting newest "
1661 << "keystore key as default.";
1662 cryptographer->AddKey(keystore_params);
1663 } else {
1664 // Theoretically the encryption keybag should already contain the keystore
1665 // key. We explicitly add it as a safety measure.
1666 DVLOG(1) << "Pending keys based on newest keystore key.";
1667 cryptographer->AddNonDefaultKey(keystore_params);
1669 if (cryptographer->is_ready()) {
1670 std::string bootstrap_token;
1671 cryptographer->GetBootstrapToken(&bootstrap_token);
1672 DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1673 FOR_EACH_OBSERVER(
1674 SyncEncryptionHandler::Observer,
1675 observers_,
1676 OnPassphraseAccepted());
1677 FOR_EACH_OBSERVER(
1678 SyncEncryptionHandler::Observer,
1679 observers_,
1680 OnBootstrapTokenUpdated(bootstrap_token,
1681 PASSPHRASE_BOOTSTRAP_TOKEN));
1682 FOR_EACH_OBSERVER(
1683 SyncEncryptionHandler::Observer,
1684 observers_,
1685 OnCryptographerStateChanged(cryptographer));
1686 return true;
1689 return false;
1692 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const {
1693 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE)
1694 return migration_time();
1695 else if (passphrase_type_ == CUSTOM_PASSPHRASE)
1696 return custom_passphrase_time();
1697 return base::Time();
1700 void SyncEncryptionHandlerImpl::UpdateNigoriForTransitionToPassphraseEncryption(
1701 WriteTransaction* trans) {
1702 DCHECK(trans);
1703 if (clear_data_option_ != PASSPHRASE_TRANSITION_CLEAR_DATA)
1704 return;
1705 // TODO(maniscalco): Update the Nigori node to record the fact the user has
1706 // begun the transition to passphrase encryption (crbug.com/505917).
1709 } // namespace browser_sync