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"
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"
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
{
64 NOT_MIGRATED_CRYPTO_NOT_READY
,
65 NOT_MIGRATED_NO_KEYSTORE_KEY
,
66 NOT_MIGRATED_UNKNOWN_REASON
,
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 state is set.
74 // 2. Migration time is set.
75 // 3. Frozen keybag is true
76 // 4. If passphrase state is keystore, keystore_decryptor_token is set.
77 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics
& nigori
) {
78 if (!nigori
.has_passphrase_type())
80 if (!nigori
.has_keystore_migration_time())
82 if (!nigori
.keybag_is_frozen())
84 if (nigori
.passphrase_type() ==
85 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
)
87 if (nigori
.passphrase_type() ==
88 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
&&
89 nigori
.keystore_decryptor_token().blob().empty())
91 if (!nigori
.has_keystore_migration_time())
96 PassphraseType
ProtoPassphraseTypeToEnum(
97 sync_pb::NigoriSpecifics::PassphraseType type
) {
99 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
:
100 return IMPLICIT_PASSPHRASE
;
101 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
:
102 return KEYSTORE_PASSPHRASE
;
103 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE
:
104 return CUSTOM_PASSPHRASE
;
105 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE
:
106 return FROZEN_IMPLICIT_PASSPHRASE
;
109 return IMPLICIT_PASSPHRASE
;
113 sync_pb::NigoriSpecifics::PassphraseType
114 EnumPassphraseTypeToProto(PassphraseType type
) {
116 case IMPLICIT_PASSPHRASE
:
117 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
;
118 case KEYSTORE_PASSPHRASE
:
119 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
;
120 case CUSTOM_PASSPHRASE
:
121 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE
;
122 case FROZEN_IMPLICIT_PASSPHRASE
:
123 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE
;
126 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
;
130 bool IsExplicitPassphrase(PassphraseType type
) {
131 return type
== CUSTOM_PASSPHRASE
|| type
== FROZEN_IMPLICIT_PASSPHRASE
;
134 // Keystore Bootstrap Token helper methods.
135 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
136 // strings, with the current keystore key as the last value in the list.
137 std::string
PackKeystoreBootstrapToken(
138 const std::vector
<std::string
>& old_keystore_keys
,
139 const std::string
& current_keystore_key
,
140 Encryptor
* encryptor
) {
141 if (current_keystore_key
.empty())
142 return std::string();
144 base::ListValue keystore_key_values
;
145 for (size_t i
= 0; i
< old_keystore_keys
.size(); ++i
)
146 keystore_key_values
.AppendString(old_keystore_keys
[i
]);
147 keystore_key_values
.AppendString(current_keystore_key
);
149 // Update the bootstrap token.
150 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
151 // strings, with the current keystore key as the last value in the list.
152 std::string serialized_keystores
;
153 JSONStringValueSerializer
json(&serialized_keystores
);
154 json
.Serialize(keystore_key_values
);
155 std::string encrypted_keystores
;
156 encryptor
->EncryptString(serialized_keystores
,
157 &encrypted_keystores
);
158 std::string keystore_bootstrap
;
159 base::Base64Encode(encrypted_keystores
, &keystore_bootstrap
);
160 return keystore_bootstrap
;
163 bool UnpackKeystoreBootstrapToken(
164 const std::string
& keystore_bootstrap_token
,
165 Encryptor
* encryptor
,
166 std::vector
<std::string
>* old_keystore_keys
,
167 std::string
* current_keystore_key
) {
168 if (keystore_bootstrap_token
.empty())
170 std::string base64_decoded_keystore_bootstrap
;
171 if (!base::Base64Decode(keystore_bootstrap_token
,
172 &base64_decoded_keystore_bootstrap
)) {
175 std::string decrypted_keystore_bootstrap
;
176 if (!encryptor
->DecryptString(base64_decoded_keystore_bootstrap
,
177 &decrypted_keystore_bootstrap
)) {
181 JSONStringValueDeserializer
json(decrypted_keystore_bootstrap
);
182 scoped_ptr
<base::Value
> deserialized_keystore_keys(
183 json
.Deserialize(NULL
, NULL
));
184 if (!deserialized_keystore_keys
)
186 base::ListValue
* internal_list_value
= NULL
;
187 if (!deserialized_keystore_keys
->GetAsList(&internal_list_value
))
189 int number_of_keystore_keys
= internal_list_value
->GetSize();
190 if (!internal_list_value
->GetString(number_of_keystore_keys
- 1,
191 current_keystore_key
)) {
194 old_keystore_keys
->resize(number_of_keystore_keys
- 1);
195 for (int i
= 0; i
< number_of_keystore_keys
- 1; ++i
)
196 internal_list_value
->GetString(i
, &(*old_keystore_keys
)[i
]);
202 SyncEncryptionHandlerImpl::Vault::Vault(
203 Encryptor
* encryptor
,
204 ModelTypeSet encrypted_types
)
205 : cryptographer(encryptor
),
206 encrypted_types(encrypted_types
) {
209 SyncEncryptionHandlerImpl::Vault::~Vault() {
212 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
213 UserShare
* user_share
,
214 Encryptor
* encryptor
,
215 const std::string
& restored_key_for_bootstrapping
,
216 const std::string
& restored_keystore_key_for_bootstrapping
)
217 : user_share_(user_share
),
218 vault_unsafe_(encryptor
, SensitiveTypes()),
219 encrypt_everything_(false),
220 passphrase_type_(IMPLICIT_PASSPHRASE
),
221 nigori_overwrite_count_(0),
222 weak_ptr_factory_(this) {
223 // Restore the cryptographer's previous keys. Note that we don't add the
224 // keystore keys into the cryptographer here, in case a migration was pending.
225 vault_unsafe_
.cryptographer
.Bootstrap(restored_key_for_bootstrapping
);
227 // If this fails, we won't have a valid keystore key, and will simply request
228 // new ones from the server on the next DownloadUpdates.
229 UnpackKeystoreBootstrapToken(
230 restored_keystore_key_for_bootstrapping
,
236 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
238 void SyncEncryptionHandlerImpl::AddObserver(Observer
* observer
) {
239 DCHECK(thread_checker_
.CalledOnValidThread());
240 DCHECK(!observers_
.HasObserver(observer
));
241 observers_
.AddObserver(observer
);
244 void SyncEncryptionHandlerImpl::RemoveObserver(Observer
* observer
) {
245 DCHECK(thread_checker_
.CalledOnValidThread());
246 DCHECK(observers_
.HasObserver(observer
));
247 observers_
.RemoveObserver(observer
);
250 void SyncEncryptionHandlerImpl::Init() {
251 DCHECK(thread_checker_
.CalledOnValidThread());
252 WriteTransaction
trans(FROM_HERE
, user_share_
);
253 WriteNode
node(&trans
);
255 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
257 if (!ApplyNigoriUpdateImpl(node
.GetNigoriSpecifics(),
258 trans
.GetWrappedTrans())) {
259 WriteEncryptionStateToNigori(&trans
);
262 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType",
264 PASSPHRASE_TYPE_SIZE
);
266 bool has_pending_keys
= UnlockVault(
267 trans
.GetWrappedTrans()).cryptographer
.has_pending_keys();
268 bool is_ready
= UnlockVault(
269 trans
.GetWrappedTrans()).cryptographer
.is_ready();
270 // Log the state of the cryptographer regardless of migration state.
271 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready
);
272 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys
);
273 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics())) {
274 // This account has a nigori node that has been migrated to support
276 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
278 MIGRATION_STATE_SIZE
);
279 if (has_pending_keys
&& passphrase_type_
== KEYSTORE_PASSPHRASE
) {
280 // If this is happening, it means the keystore decryptor is either
281 // undecryptable with the available keystore keys or does not match the
282 // nigori keybag's encryption key. Otherwise we're simply missing the
284 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed",
285 !keystore_key_
.empty());
287 } else if (!is_ready
) {
288 // Migration cannot occur until the cryptographer is ready (initialized
289 // with GAIA password and any pending keys resolved).
290 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
291 NOT_MIGRATED_CRYPTO_NOT_READY
,
292 MIGRATION_STATE_SIZE
);
293 } else if (keystore_key_
.empty()) {
294 // The client has no keystore key, either because it is not yet enabled or
295 // the server is not sending a valid keystore key.
296 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
297 NOT_MIGRATED_NO_KEYSTORE_KEY
,
298 MIGRATION_STATE_SIZE
);
300 // If the above conditions have been met and the nigori node is still not
301 // migrated, something failed in the migration process.
302 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
303 NOT_MIGRATED_UNKNOWN_REASON
,
304 MIGRATION_STATE_SIZE
);
308 // Always trigger an encrypted types and cryptographer state change event at
309 // init time so observers get the initial values.
311 Observer
, observers_
,
312 OnEncryptedTypesChanged(
313 UnlockVault(trans
.GetWrappedTrans()).encrypted_types
,
314 encrypt_everything_
));
316 SyncEncryptionHandler::Observer
,
318 OnCryptographerStateChanged(
319 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
));
321 // If the cryptographer is not ready (either it has pending keys or we
322 // failed to initialize it), we don't want to try and re-encrypt the data.
323 // If we had encrypted types, the DataTypeManager will block, preventing
324 // sync from happening until the the passphrase is provided.
325 if (UnlockVault(trans
.GetWrappedTrans()).cryptographer
.is_ready())
326 ReEncryptEverything(&trans
);
329 void SyncEncryptionHandlerImpl::SetEncryptionPassphrase(
330 const std::string
& passphrase
,
332 DCHECK(thread_checker_
.CalledOnValidThread());
333 // We do not accept empty passphrases.
334 if (passphrase
.empty()) {
335 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
339 // All accesses to the cryptographer are protected by a transaction.
340 WriteTransaction
trans(FROM_HERE
, user_share_
);
341 KeyParams key_params
= {"localhost", "dummy", passphrase
};
342 WriteNode
node(&trans
);
343 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
) {
348 Cryptographer
* cryptographer
=
349 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
;
351 // Once we've migrated to keystore, the only way to set a passphrase for
352 // encryption is to set a custom passphrase.
353 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics())) {
355 // The user is setting a new implicit passphrase. At this point we don't
356 // care, so drop it on the floor. This is safe because if we have a
357 // migrated nigori node, then we don't need to create an initial
359 LOG(WARNING
) << "Ignoring new implicit passphrase. Keystore migration "
360 << "already performed.";
363 // Will fail if we already have an explicit passphrase or we have pending
365 SetCustomPassphrase(passphrase
, &trans
, &node
);
367 // When keystore migration occurs, the "CustomEncryption" UMA stat must be
369 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", true);
373 std::string bootstrap_token
;
374 sync_pb::EncryptedData pending_keys
;
375 if (cryptographer
->has_pending_keys())
376 pending_keys
= cryptographer
->GetPendingKeys();
377 bool success
= false;
379 // There are six cases to handle here:
380 // 1. The user has no pending keys and is setting their current GAIA password
381 // as the encryption passphrase. This happens either during first time sync
382 // with a clean profile, or after re-authenticating on a profile that was
383 // already signed in with the cryptographer ready.
384 // 2. The user has no pending keys, and is overwriting an (already provided)
385 // implicit passphrase with an explicit (custom) passphrase.
386 // 3. The user has pending keys for an explicit passphrase that is somehow set
387 // to their current GAIA passphrase.
388 // 4. The user has pending keys encrypted with their current GAIA passphrase
389 // and the caller passes in the current GAIA passphrase.
390 // 5. The user has pending keys encrypted with an older GAIA passphrase
391 // and the caller passes in the current GAIA passphrase.
392 // 6. The user has previously done encryption with an explicit passphrase.
393 // Furthermore, we enforce the fact that the bootstrap encryption token will
394 // always be derived from the newest GAIA password if the account is using
395 // an implicit passphrase (even if the data is encrypted with an old GAIA
396 // password). If the account is using an explicit (custom) passphrase, the
397 // bootstrap token will be derived from the most recently provided explicit
398 // passphrase (that was able to decrypt the data).
399 if (!IsExplicitPassphrase(passphrase_type_
)) {
400 if (!cryptographer
->has_pending_keys()) {
401 if (cryptographer
->AddKey(key_params
)) {
402 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
403 // keys (1), or overwriting an implicit passphrase with a new explicit
404 // one (2) when there are no pending keys.
406 DVLOG(1) << "Setting explicit passphrase for encryption.";
407 passphrase_type_
= CUSTOM_PASSPHRASE
;
408 custom_passphrase_time_
= base::Time::Now();
409 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
410 OnPassphraseTypeChanged(
412 GetExplicitPassphraseTime()));
414 DVLOG(1) << "Setting implicit passphrase for encryption.";
416 cryptographer
->GetBootstrapToken(&bootstrap_token
);
418 // With M26, sync accounts can be in only one of two encryption states:
419 // 1) Encrypt only passwords with an implicit passphrase.
420 // 2) Encrypt all sync datatypes with an explicit passphrase.
421 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms,
422 // and keep track of an account's encryption state via the
423 // "CustomEncryption" histogram. See http://crbug.com/131478.
424 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", is_explicit
);
428 NOTREACHED() << "Failed to add key to cryptographer.";
431 } else { // cryptographer->has_pending_keys() == true
433 // This can only happen if the nigori node is updated with a new
434 // implicit passphrase while a client is attempting to set a new custom
435 // passphrase (race condition).
436 DVLOG(1) << "Failing because an implicit passphrase is already set.";
438 } else { // is_explicit == false
439 if (cryptographer
->DecryptPendingKeys(key_params
)) {
440 // Case 4. We successfully decrypted with the implicit GAIA passphrase
442 DVLOG(1) << "Implicit internal passphrase accepted for decryption.";
443 cryptographer
->GetBootstrapToken(&bootstrap_token
);
446 // Case 5. Encryption was done with an old GAIA password, but we were
447 // provided with the current GAIA password. We need to generate a new
448 // bootstrap token to preserve it. We build a temporary cryptographer
449 // to allow us to extract these params without polluting our current
451 DVLOG(1) << "Implicit internal passphrase failed to decrypt, adding "
452 << "anyways as default passphrase and persisting via "
453 << "bootstrap token.";
454 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
455 temp_cryptographer
.AddKey(key_params
);
456 temp_cryptographer
.GetBootstrapToken(&bootstrap_token
);
457 // We then set the new passphrase as the default passphrase of the
458 // real cryptographer, even though we have pending keys. This is safe,
459 // as although Cryptographer::is_initialized() will now be true,
460 // is_ready() will remain false due to having pending keys.
461 cryptographer
->AddKey(key_params
);
465 } // cryptographer->has_pending_keys()
466 } else { // IsExplicitPassphrase(passphrase_type_) == true.
467 // Case 6. We do not want to override a previously set explicit passphrase,
468 // so we return a failure.
469 DVLOG(1) << "Failing because an explicit passphrase is already set.";
473 DVLOG_IF(1, !success
)
474 << "Failure in SetEncryptionPassphrase; notifying and returning.";
476 << "Successfully set encryption passphrase; updating nigori and "
479 FinishSetPassphrase(success
, bootstrap_token
, &trans
, &node
);
482 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
483 const std::string
& passphrase
) {
484 DCHECK(thread_checker_
.CalledOnValidThread());
485 // We do not accept empty passphrases.
486 if (passphrase
.empty()) {
487 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
491 // All accesses to the cryptographer are protected by a transaction.
492 WriteTransaction
trans(FROM_HERE
, user_share_
);
493 KeyParams key_params
= {"localhost", "dummy", passphrase
};
494 WriteNode
node(&trans
);
495 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
) {
500 // Once we've migrated to keystore, we're only ever decrypting keys derived
501 // from an explicit passphrase. But, for clients without a keystore key yet
502 // (either not on by default or failed to download one), we still support
503 // decrypting with a gaia passphrase, and therefore bypass the
504 // DecryptPendingKeysWithExplicitPassphrase logic.
505 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics()) &&
506 IsExplicitPassphrase(passphrase_type_
)) {
507 DecryptPendingKeysWithExplicitPassphrase(passphrase
, &trans
, &node
);
511 Cryptographer
* cryptographer
=
512 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
;
513 if (!cryptographer
->has_pending_keys()) {
514 // Note that this *can* happen in a rare situation where data is
515 // re-encrypted on another client while a SetDecryptionPassphrase() call is
516 // in-flight on this client. It is rare enough that we choose to do nothing.
517 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
518 << "were no pending keys.";
522 std::string bootstrap_token
;
523 sync_pb::EncryptedData pending_keys
;
524 pending_keys
= cryptographer
->GetPendingKeys();
525 bool success
= false;
527 // There are three cases to handle here:
528 // 7. We're using the current GAIA password to decrypt the pending keys. This
529 // happens when signing in to an account with a previously set implicit
530 // passphrase, where the data is already encrypted with the newest GAIA
532 // 8. The user is providing an old GAIA password to decrypt the pending keys.
533 // In this case, the user is using an implicit passphrase, but has changed
534 // their password since they last encrypted their data, and therefore
535 // their current GAIA password was unable to decrypt the data. This will
536 // happen when the user is setting up a new profile with a previously
537 // encrypted account (after changing passwords).
538 // 9. The user is providing a previously set explicit passphrase to decrypt
540 if (!IsExplicitPassphrase(passphrase_type_
)) {
541 if (cryptographer
->is_initialized()) {
542 // We only want to change the default encryption key to the pending
543 // one if the pending keybag already contains the current default.
544 // This covers the case where a different client re-encrypted
545 // everything with a newer gaia passphrase (and hence the keybag
546 // contains keys from all previously used gaia passphrases).
547 // Otherwise, we're in a situation where the pending keys are
548 // encrypted with an old gaia passphrase, while the default is the
549 // current gaia passphrase. In that case, we preserve the default.
550 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
551 temp_cryptographer
.SetPendingKeys(cryptographer
->GetPendingKeys());
552 if (temp_cryptographer
.DecryptPendingKeys(key_params
)) {
553 // Check to see if the pending bag of keys contains the current
555 sync_pb::EncryptedData encrypted
;
556 cryptographer
->GetKeys(&encrypted
);
557 if (temp_cryptographer
.CanDecrypt(encrypted
)) {
558 DVLOG(1) << "Implicit user provided passphrase accepted for "
559 << "decryption, overwriting default.";
560 // Case 7. The pending keybag contains the current default. Go ahead
561 // and update the cryptographer, letting the default change.
562 cryptographer
->DecryptPendingKeys(key_params
);
563 cryptographer
->GetBootstrapToken(&bootstrap_token
);
566 // Case 8. The pending keybag does not contain the current default
567 // encryption key. We decrypt the pending keys here, and in
568 // FinishSetPassphrase, re-encrypt everything with the current GAIA
569 // passphrase instead of the passphrase just provided by the user.
570 DVLOG(1) << "Implicit user provided passphrase accepted for "
571 << "decryption, restoring implicit internal passphrase "
573 std::string bootstrap_token_from_current_key
;
574 cryptographer
->GetBootstrapToken(
575 &bootstrap_token_from_current_key
);
576 cryptographer
->DecryptPendingKeys(key_params
);
577 // Overwrite the default from the pending keys.
578 cryptographer
->AddKeyFromBootstrapToken(
579 bootstrap_token_from_current_key
);
582 } else { // !temp_cryptographer.DecryptPendingKeys(..)
583 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
585 } // temp_cryptographer.DecryptPendingKeys(...)
586 } else { // cryptographer->is_initialized() == false
587 if (cryptographer
->DecryptPendingKeys(key_params
)) {
588 // This can happpen in two cases:
589 // - First time sync on android, where we'll never have a
590 // !user_provided passphrase.
591 // - This is a restart for a client that lost their bootstrap token.
592 // In both cases, we should go ahead and initialize the cryptographer
593 // and persist the new bootstrap token.
595 // Note: at this point, we cannot distinguish between cases 7 and 8
596 // above. This user provided passphrase could be the current or the
597 // old. But, as long as we persist the token, there's nothing more
599 cryptographer
->GetBootstrapToken(&bootstrap_token
);
600 DVLOG(1) << "Implicit user provided passphrase accepted, initializing"
601 << " cryptographer.";
604 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
607 } // cryptographer->is_initialized()
608 } else { // nigori_has_explicit_passphrase == true
609 // Case 9. Encryption was done with an explicit passphrase, and we decrypt
610 // with the passphrase provided by the user.
611 if (cryptographer
->DecryptPendingKeys(key_params
)) {
612 DVLOG(1) << "Explicit passphrase accepted for decryption.";
613 cryptographer
->GetBootstrapToken(&bootstrap_token
);
616 DVLOG(1) << "Explicit passphrase failed to decrypt.";
619 } // nigori_has_explicit_passphrase
621 DVLOG_IF(1, !success
)
622 << "Failure in SetDecryptionPassphrase; notifying and returning.";
624 << "Successfully set decryption passphrase; updating nigori and "
627 FinishSetPassphrase(success
, bootstrap_token
, &trans
, &node
);
630 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
631 DCHECK(thread_checker_
.CalledOnValidThread());
632 WriteTransaction
trans(FROM_HERE
, user_share_
);
633 DVLOG(1) << "Enabling encrypt everything.";
634 if (encrypt_everything_
)
636 EnableEncryptEverythingImpl(trans
.GetWrappedTrans());
637 WriteEncryptionStateToNigori(&trans
);
638 if (UnlockVault(trans
.GetWrappedTrans()).cryptographer
.is_ready())
639 ReEncryptEverything(&trans
);
642 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
643 DCHECK(thread_checker_
.CalledOnValidThread());
644 return encrypt_everything_
;
647 PassphraseType
SyncEncryptionHandlerImpl::GetPassphraseType() const {
648 DCHECK(thread_checker_
.CalledOnValidThread());
649 return passphrase_type_
;
652 // Note: this is called from within a syncable transaction, so we need to post
653 // tasks if we want to do any work that creates a new sync_api transaction.
654 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
655 const sync_pb::NigoriSpecifics
& nigori
,
656 syncable::BaseTransaction
* const trans
) {
657 DCHECK(thread_checker_
.CalledOnValidThread());
659 if (!ApplyNigoriUpdateImpl(nigori
, trans
)) {
660 base::MessageLoop::current()->PostTask(
662 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori
,
663 weak_ptr_factory_
.GetWeakPtr()));
667 SyncEncryptionHandler::Observer
,
669 OnCryptographerStateChanged(
670 &UnlockVaultMutable(trans
)->cryptographer
));
673 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
674 sync_pb::NigoriSpecifics
* nigori
,
675 syncable::BaseTransaction
* const trans
) const {
676 DCHECK(thread_checker_
.CalledOnValidThread());
677 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans
).encrypted_types
,
682 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
683 syncable::BaseTransaction
* const trans
) const {
684 DCHECK(thread_checker_
.CalledOnValidThread());
685 return keystore_key_
.empty();
688 bool SyncEncryptionHandlerImpl::SetKeystoreKeys(
689 const google::protobuf::RepeatedPtrField
<google::protobuf::string
>& keys
,
690 syncable::BaseTransaction
* const trans
) {
691 DCHECK(thread_checker_
.CalledOnValidThread());
692 if (keys
.size() == 0)
694 // The last key in the vector is the current keystore key. The others are kept
695 // around for decryption only.
696 const std::string
& raw_keystore_key
= keys
.Get(keys
.size() - 1);
697 if (raw_keystore_key
.empty())
700 // Note: in order to Pack the keys, they must all be base64 encoded (else
701 // JSON serialization fails).
702 base::Base64Encode(raw_keystore_key
, &keystore_key_
);
704 // Go through and save the old keystore keys. We always persist all keystore
705 // keys the server sends us.
706 old_keystore_keys_
.resize(keys
.size() - 1);
707 for (int i
= 0; i
< keys
.size() - 1; ++i
)
708 base::Base64Encode(keys
.Get(i
), &old_keystore_keys_
[i
]);
710 Cryptographer
* cryptographer
= &UnlockVaultMutable(trans
)->cryptographer
;
712 // Update the bootstrap token. If this fails, we persist an empty string,
713 // which will force us to download the keystore keys again on the next
715 std::string keystore_bootstrap
= PackKeystoreBootstrapToken(
718 cryptographer
->encryptor());
719 DCHECK_EQ(keystore_bootstrap
.empty(), keystore_key_
.empty());
720 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
721 OnBootstrapTokenUpdated(keystore_bootstrap
,
722 KEYSTORE_BOOTSTRAP_TOKEN
));
723 DVLOG(1) << "Keystore bootstrap token updated.";
725 // If this is a first time sync, we get the encryption keys before we process
726 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
727 // once we have the nigori node.
728 syncable::Entry
entry(trans
, syncable::GET_TYPE_ROOT
, NIGORI
);
732 const sync_pb::NigoriSpecifics
& nigori
=
733 entry
.GetSpecifics().nigori();
734 if (cryptographer
->has_pending_keys() &&
735 IsNigoriMigratedToKeystore(nigori
) &&
736 !nigori
.keystore_decryptor_token().blob().empty()) {
737 // If the nigori is already migrated and we have pending keys, we might
738 // be able to decrypt them using either the keystore decryptor token
739 // or the existing keystore keys.
740 DecryptPendingKeysWithKeystoreKey(keystore_key_
,
741 nigori
.keystore_decryptor_token(),
745 // Note that triggering migration will have no effect if we're already
746 // properly migrated with the newest keystore keys.
747 if (ShouldTriggerMigration(nigori
, *cryptographer
)) {
748 base::MessageLoop::current()->PostTask(
750 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori
,
751 weak_ptr_factory_
.GetWeakPtr()));
757 ModelTypeSet
SyncEncryptionHandlerImpl::GetEncryptedTypes(
758 syncable::BaseTransaction
* const trans
) const {
759 return UnlockVault(trans
).encrypted_types
;
762 Cryptographer
* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
763 DCHECK(thread_checker_
.CalledOnValidThread());
764 return &vault_unsafe_
.cryptographer
;
767 ModelTypeSet
SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
768 DCHECK(thread_checker_
.CalledOnValidThread());
769 return vault_unsafe_
.encrypted_types
;
772 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
773 DCHECK(thread_checker_
.CalledOnValidThread());
774 ReadTransaction
trans(FROM_HERE
, user_share_
);
775 ReadNode
nigori_node(&trans
);
776 if (nigori_node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
778 return IsNigoriMigratedToKeystore(nigori_node
.GetNigoriSpecifics());
781 base::Time
SyncEncryptionHandlerImpl::migration_time() const {
782 return migration_time_
;
785 base::Time
SyncEncryptionHandlerImpl::custom_passphrase_time() const {
786 return custom_passphrase_time_
;
789 void SyncEncryptionHandlerImpl::RestoreNigori(
790 const SyncEncryptionHandler::NigoriState
& nigori_state
) {
791 DCHECK(thread_checker_
.CalledOnValidThread());
792 WriteTransaction
trans(FROM_HERE
, user_share_
);
794 // Verify we don't already have a nigori node.
795 WriteNode
nigori_node(&trans
);
796 BaseNode::InitByLookupResult init_result
= nigori_node
.InitTypeRoot(NIGORI
);
797 DCHECK(init_result
== BaseNode::INIT_FAILED_ENTRY_NOT_GOOD
);
800 syncable::ModelNeutralMutableEntry
model_neutral_mutable_entry(
801 trans
.GetWrappedWriteTrans(), syncable::CREATE_NEW_TYPE_ROOT
, NIGORI
);
802 DCHECK(model_neutral_mutable_entry
.good());
803 model_neutral_mutable_entry
.PutServerIsDir(true);
804 model_neutral_mutable_entry
.PutUniqueServerTag(ModelTypeToRootTag(NIGORI
));
805 model_neutral_mutable_entry
.PutIsUnsynced(true);
807 // Update it with the saved nigori specifics.
808 syncable::MutableEntry
mutable_entry(trans
.GetWrappedWriteTrans(),
809 syncable::GET_TYPE_ROOT
, NIGORI
);
810 DCHECK(mutable_entry
.good());
811 sync_pb::EntitySpecifics specifics
;
812 specifics
.mutable_nigori()->CopyFrom(nigori_state
.nigori_specifics
);
813 mutable_entry
.PutSpecifics(specifics
);
815 // Update our state based on the saved nigori node.
816 ApplyNigoriUpdate(nigori_state
.nigori_specifics
, trans
.GetWrappedTrans());
819 // This function iterates over all encrypted types. There are many scenarios in
820 // which data for some or all types is not currently available. In that case,
821 // the lookup of the root node will fail and we will skip encryption for that
823 void SyncEncryptionHandlerImpl::ReEncryptEverything(
824 WriteTransaction
* trans
) {
825 DCHECK(thread_checker_
.CalledOnValidThread());
826 DCHECK(UnlockVault(trans
->GetWrappedTrans()).cryptographer
.is_ready());
827 for (ModelTypeSet::Iterator iter
=
828 UnlockVault(trans
->GetWrappedTrans()).encrypted_types
.First();
829 iter
.Good(); iter
.Inc()) {
830 if (iter
.Get() == PASSWORDS
|| IsControlType(iter
.Get()))
831 continue; // These types handle encryption differently.
833 ReadNode
type_root(trans
);
834 if (type_root
.InitTypeRoot(iter
.Get()) != BaseNode::INIT_OK
)
835 continue; // Don't try to reencrypt if the type's data is unavailable.
837 // Iterate through all children of this datatype.
838 std::queue
<int64
> to_visit
;
839 int64 child_id
= type_root
.GetFirstChildId();
840 to_visit
.push(child_id
);
841 while (!to_visit
.empty()) {
842 child_id
= to_visit
.front();
844 if (child_id
== kInvalidId
)
847 WriteNode
child(trans
);
848 if (child
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
849 continue; // Possible for locally deleted items.
850 if (child
.GetIsFolder()) {
851 to_visit
.push(child
.GetFirstChildId());
853 if (child
.GetEntry()->GetUniqueServerTag().empty()) {
854 // Rewrite the specifics of the node with encrypted data if necessary
855 // (only rewrite the non-unique folders).
856 child
.ResetFromSpecifics();
858 to_visit
.push(child
.GetSuccessorId());
862 // Passwords are encrypted with their own legacy scheme. Passwords are always
863 // encrypted so we don't need to check GetEncryptedTypes() here.
864 ReadNode
passwords_root(trans
);
865 if (passwords_root
.InitTypeRoot(PASSWORDS
) == BaseNode::INIT_OK
) {
866 int64 child_id
= passwords_root
.GetFirstChildId();
867 while (child_id
!= kInvalidId
) {
868 WriteNode
child(trans
);
869 if (child
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
870 break; // Possible if we failed to decrypt the data for some reason.
871 child
.SetPasswordSpecifics(child
.GetPasswordSpecifics());
872 child_id
= child
.GetSuccessorId();
876 DVLOG(1) << "Re-encrypt everything complete.";
878 // NOTE: We notify from within a transaction.
879 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
880 OnEncryptionComplete());
883 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
884 const sync_pb::NigoriSpecifics
& nigori
,
885 syncable::BaseTransaction
* const trans
) {
886 DCHECK(thread_checker_
.CalledOnValidThread());
887 DVLOG(1) << "Applying nigori node update.";
888 bool nigori_types_need_update
= !UpdateEncryptedTypesFromNigori(nigori
,
891 if (nigori
.custom_passphrase_time() != 0) {
892 custom_passphrase_time_
=
893 ProtoTimeToTime(nigori
.custom_passphrase_time());
895 bool is_nigori_migrated
= IsNigoriMigratedToKeystore(nigori
);
896 if (is_nigori_migrated
) {
897 DCHECK(nigori
.has_keystore_migration_time());
898 migration_time_
= ProtoTimeToTime(nigori
.keystore_migration_time());
899 PassphraseType nigori_passphrase_type
=
900 ProtoPassphraseTypeToEnum(nigori
.passphrase_type());
902 // Only update the local passphrase state if it's a valid transition:
903 // - implicit -> keystore
904 // - implicit -> frozen implicit
905 // - implicit -> custom
906 // - keystore -> custom
907 // Note: frozen implicit -> custom is not technically a valid transition,
908 // but we let it through here as well in case future versions do add support
909 // for this transition.
910 if (passphrase_type_
!= nigori_passphrase_type
&&
911 nigori_passphrase_type
!= IMPLICIT_PASSPHRASE
&&
912 (passphrase_type_
== IMPLICIT_PASSPHRASE
||
913 nigori_passphrase_type
== CUSTOM_PASSPHRASE
)) {
914 DVLOG(1) << "Changing passphrase state from "
915 << PassphraseTypeToString(passphrase_type_
)
917 << PassphraseTypeToString(nigori_passphrase_type
);
918 passphrase_type_
= nigori_passphrase_type
;
919 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
920 OnPassphraseTypeChanged(
922 GetExplicitPassphraseTime()));
924 if (passphrase_type_
== KEYSTORE_PASSPHRASE
&& encrypt_everything_
) {
925 // This is the case where another client that didn't support keystore
926 // encryption attempted to enable full encryption. We detect it
927 // and switch the passphrase type to frozen implicit passphrase instead
928 // due to full encryption not being compatible with keystore passphrase.
929 // Because the local passphrase type will not match the nigori passphrase
930 // type, we will trigger a rewrite and subsequently a re-migration.
931 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
932 << "due to full encryption.";
933 passphrase_type_
= FROZEN_IMPLICIT_PASSPHRASE
;
934 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
935 OnPassphraseTypeChanged(
937 GetExplicitPassphraseTime()));
940 // It's possible that while we're waiting for migration a client that does
941 // not have keystore encryption enabled switches to a custom passphrase.
942 if (nigori
.keybag_is_frozen() &&
943 passphrase_type_
!= CUSTOM_PASSPHRASE
) {
944 passphrase_type_
= CUSTOM_PASSPHRASE
;
945 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
946 OnPassphraseTypeChanged(
948 GetExplicitPassphraseTime()));
952 Cryptographer
* cryptographer
= &UnlockVaultMutable(trans
)->cryptographer
;
953 bool nigori_needs_new_keys
= false;
954 if (!nigori
.encryption_keybag().blob().empty()) {
955 // We only update the default key if this was a new explicit passphrase.
956 // Else, since it was decryptable, it must not have been a new key.
957 bool need_new_default_key
= false;
958 if (is_nigori_migrated
) {
959 need_new_default_key
= IsExplicitPassphrase(
960 ProtoPassphraseTypeToEnum(nigori
.passphrase_type()));
962 need_new_default_key
= nigori
.keybag_is_frozen();
964 if (!AttemptToInstallKeybag(nigori
.encryption_keybag(),
965 need_new_default_key
,
967 // Check to see if we can decrypt the keybag using the keystore decryptor
969 cryptographer
->SetPendingKeys(nigori
.encryption_keybag());
970 if (!nigori
.keystore_decryptor_token().blob().empty() &&
971 !keystore_key_
.empty()) {
972 if (DecryptPendingKeysWithKeystoreKey(keystore_key_
,
973 nigori
.keystore_decryptor_token(),
975 nigori_needs_new_keys
=
976 cryptographer
->KeybagIsStale(nigori
.encryption_keybag());
978 LOG(ERROR
) << "Failed to decrypt pending keys using keystore "
983 // Keybag was installed. We write back our local keybag into the nigori
984 // node if the nigori node's keybag either contains less keys or
985 // has a different default key.
986 nigori_needs_new_keys
=
987 cryptographer
->KeybagIsStale(nigori
.encryption_keybag());
990 // The nigori node has an empty encryption keybag. Attempt to write our
991 // local encryption keys into it.
992 LOG(WARNING
) << "Nigori had empty encryption keybag.";
993 nigori_needs_new_keys
= true;
996 // If we've completed a sync cycle and the cryptographer isn't ready
997 // yet or has pending keys, prompt the user for a passphrase.
998 if (cryptographer
->has_pending_keys()) {
999 DVLOG(1) << "OnPassphraseRequired Sent";
1000 sync_pb::EncryptedData pending_keys
= cryptographer
->GetPendingKeys();
1001 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1002 OnPassphraseRequired(REASON_DECRYPTION
,
1004 } else if (!cryptographer
->is_ready()) {
1005 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
1007 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1008 OnPassphraseRequired(REASON_ENCRYPTION
,
1009 sync_pb::EncryptedData()));
1012 // Check if the current local encryption state is stricter/newer than the
1013 // nigori state. If so, we need to overwrite the nigori node with the local
1015 bool passphrase_type_matches
= true;
1016 if (!is_nigori_migrated
) {
1017 DCHECK(passphrase_type_
== CUSTOM_PASSPHRASE
||
1018 passphrase_type_
== IMPLICIT_PASSPHRASE
);
1019 passphrase_type_matches
=
1020 nigori
.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_
);
1022 passphrase_type_matches
=
1023 (ProtoPassphraseTypeToEnum(nigori
.passphrase_type()) ==
1026 if (!passphrase_type_matches
||
1027 nigori
.encrypt_everything() != encrypt_everything_
||
1028 nigori_types_need_update
||
1029 nigori_needs_new_keys
) {
1030 DVLOG(1) << "Triggering nigori rewrite.";
1036 void SyncEncryptionHandlerImpl::RewriteNigori() {
1037 DVLOG(1) << "Writing local encryption state into nigori.";
1038 DCHECK(thread_checker_
.CalledOnValidThread());
1039 WriteTransaction
trans(FROM_HERE
, user_share_
);
1040 WriteEncryptionStateToNigori(&trans
);
1043 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
1044 WriteTransaction
* trans
) {
1045 DCHECK(thread_checker_
.CalledOnValidThread());
1046 WriteNode
nigori_node(trans
);
1047 // This can happen in tests that don't have nigori nodes.
1048 if (nigori_node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
1051 sync_pb::NigoriSpecifics nigori
= nigori_node
.GetNigoriSpecifics();
1052 const Cryptographer
& cryptographer
=
1053 UnlockVault(trans
->GetWrappedTrans()).cryptographer
;
1055 // Will not do anything if we shouldn't or can't migrate. Otherwise
1056 // migrates, writing the full encryption state as it does.
1057 if (!AttemptToMigrateNigoriToKeystore(trans
, &nigori_node
)) {
1058 if (cryptographer
.is_ready() &&
1059 nigori_overwrite_count_
< kNigoriOverwriteLimit
) {
1060 // Does not modify the encrypted blob if the unencrypted data already
1061 // matches what is about to be written.
1062 sync_pb::EncryptedData original_keys
= nigori
.encryption_keybag();
1063 if (!cryptographer
.GetKeys(nigori
.mutable_encryption_keybag()))
1066 if (nigori
.encryption_keybag().SerializeAsString() !=
1067 original_keys
.SerializeAsString()) {
1068 // We've updated the nigori node's encryption keys. In order to prevent
1069 // a possible looping of two clients constantly overwriting each other,
1070 // we limit the absolute number of overwrites per client instantiation.
1071 nigori_overwrite_count_
++;
1072 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
1073 nigori_overwrite_count_
);
1076 // Note: we don't try to set keybag_is_frozen here since if that
1077 // is lost the user can always set it again (and we don't want to clobber
1078 // any migration state). The main goal at this point is to preserve
1079 // the encryption keys so all data remains decryptable.
1081 syncable::UpdateNigoriFromEncryptedTypes(
1082 UnlockVault(trans
->GetWrappedTrans()).encrypted_types
,
1083 encrypt_everything_
,
1085 if (!custom_passphrase_time_
.is_null()) {
1086 nigori
.set_custom_passphrase_time(
1087 TimeToProtoTime(custom_passphrase_time_
));
1090 // If nothing has changed, this is a no-op.
1091 nigori_node
.SetNigoriSpecifics(nigori
);
1095 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
1096 const sync_pb::NigoriSpecifics
& nigori
,
1097 syncable::BaseTransaction
* const trans
) {
1098 DCHECK(thread_checker_
.CalledOnValidThread());
1099 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1100 if (nigori
.encrypt_everything()) {
1101 EnableEncryptEverythingImpl(trans
);
1102 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1104 } else if (encrypt_everything_
) {
1105 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1109 ModelTypeSet nigori_encrypted_types
;
1110 nigori_encrypted_types
= syncable::GetEncryptedTypesFromNigori(nigori
);
1111 nigori_encrypted_types
.PutAll(SensitiveTypes());
1113 // If anything more than the sensitive types were encrypted, and
1114 // encrypt_everything is not explicitly set to false, we assume it means
1115 // a client intended to enable encrypt everything.
1116 if (!nigori
.has_encrypt_everything() &&
1117 !Difference(nigori_encrypted_types
, SensitiveTypes()).Empty()) {
1118 if (!encrypt_everything_
) {
1119 encrypt_everything_
= true;
1120 *encrypted_types
= EncryptableUserTypes();
1122 Observer
, observers_
,
1123 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1125 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1129 MergeEncryptedTypes(nigori_encrypted_types
, trans
);
1130 return encrypted_types
->Equals(nigori_encrypted_types
);
1133 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
1134 const std::string
& passphrase
,
1135 WriteTransaction
* trans
,
1136 WriteNode
* nigori_node
) {
1137 DCHECK(thread_checker_
.CalledOnValidThread());
1138 DCHECK(IsNigoriMigratedToKeystore(nigori_node
->GetNigoriSpecifics()));
1139 KeyParams key_params
= {"localhost", "dummy", passphrase
};
1141 if (passphrase_type_
!= KEYSTORE_PASSPHRASE
) {
1142 DVLOG(1) << "Failing to set a custom passphrase because one has already "
1144 FinishSetPassphrase(false, std::string(), trans
, nigori_node
);
1148 Cryptographer
* cryptographer
=
1149 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1150 if (cryptographer
->has_pending_keys()) {
1151 // This theoretically shouldn't happen, because the only way to have pending
1152 // keys after migrating to keystore support is if a custom passphrase was
1153 // set, which should update passpshrase_state_ and should be caught by the
1154 // if statement above. For the sake of safety though, we check for it in
1155 // case a client is misbehaving.
1156 LOG(ERROR
) << "Failing to set custom passphrase because of pending keys.";
1157 FinishSetPassphrase(false, std::string(), trans
, nigori_node
);
1161 std::string bootstrap_token
;
1162 if (!cryptographer
->AddKey(key_params
)) {
1163 NOTREACHED() << "Failed to add key to cryptographer.";
1167 DVLOG(1) << "Setting custom passphrase.";
1168 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1169 passphrase_type_
= CUSTOM_PASSPHRASE
;
1170 custom_passphrase_time_
= base::Time::Now();
1172 SyncEncryptionHandler::Observer
, observers_
,
1173 OnPassphraseTypeChanged(passphrase_type_
, GetExplicitPassphraseTime()));
1174 FinishSetPassphrase(true, bootstrap_token
, trans
, nigori_node
);
1177 void SyncEncryptionHandlerImpl::NotifyObserversOfLocalCustomPassphrase(
1178 WriteTransaction
* trans
) {
1179 WriteNode
nigori_node(trans
);
1180 BaseNode::InitByLookupResult init_result
= nigori_node
.InitTypeRoot(NIGORI
);
1181 DCHECK_EQ(init_result
, BaseNode::INIT_OK
);
1182 NigoriState nigori_state
;
1183 nigori_state
.nigori_specifics
= nigori_node
.GetNigoriSpecifics();
1184 DCHECK(nigori_state
.nigori_specifics
.passphrase_type() ==
1185 sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE
||
1186 nigori_state
.nigori_specifics
.passphrase_type() ==
1187 sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE
);
1188 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1189 OnLocalSetPassphraseEncryption(nigori_state
));
1192 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
1193 const std::string
& passphrase
,
1194 WriteTransaction
* trans
,
1195 WriteNode
* nigori_node
) {
1196 DCHECK(thread_checker_
.CalledOnValidThread());
1197 DCHECK(IsExplicitPassphrase(passphrase_type_
));
1198 KeyParams key_params
= {"localhost", "dummy", passphrase
};
1200 Cryptographer
* cryptographer
=
1201 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1202 if (!cryptographer
->has_pending_keys()) {
1203 // Note that this *can* happen in a rare situation where data is
1204 // re-encrypted on another client while a SetDecryptionPassphrase() call is
1205 // in-flight on this client. It is rare enough that we choose to do nothing.
1206 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
1207 << "were no pending keys.";
1211 DCHECK(IsExplicitPassphrase(passphrase_type_
));
1212 bool success
= false;
1213 std::string bootstrap_token
;
1214 if (cryptographer
->DecryptPendingKeys(key_params
)) {
1215 DVLOG(1) << "Explicit passphrase accepted for decryption.";
1216 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1219 DVLOG(1) << "Explicit passphrase failed to decrypt.";
1222 if (success
&& !keystore_key_
.empty()) {
1223 // Should already be part of the encryption keybag, but we add it just
1225 KeyParams key_params
= {"localhost", "dummy", keystore_key_
};
1226 cryptographer
->AddNonDefaultKey(key_params
);
1228 FinishSetPassphrase(success
, bootstrap_token
, trans
, nigori_node
);
1231 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
1233 const std::string
& bootstrap_token
,
1234 WriteTransaction
* trans
,
1235 WriteNode
* nigori_node
) {
1236 DCHECK(thread_checker_
.CalledOnValidThread());
1238 SyncEncryptionHandler::Observer
,
1240 OnCryptographerStateChanged(
1241 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
));
1243 // It's possible we need to change the bootstrap token even if we failed to
1244 // set the passphrase (for example if we need to preserve the new GAIA
1246 if (!bootstrap_token
.empty()) {
1247 DVLOG(1) << "Passphrase bootstrap token updated.";
1248 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1249 OnBootstrapTokenUpdated(bootstrap_token
,
1250 PASSPHRASE_BOOTSTRAP_TOKEN
));
1253 const Cryptographer
& cryptographer
=
1254 UnlockVault(trans
->GetWrappedTrans()).cryptographer
;
1256 if (cryptographer
.is_ready()) {
1257 LOG(ERROR
) << "Attempt to change passphrase failed while cryptographer "
1259 } else if (cryptographer
.has_pending_keys()) {
1260 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1261 OnPassphraseRequired(REASON_DECRYPTION
,
1262 cryptographer
.GetPendingKeys()));
1264 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1265 OnPassphraseRequired(REASON_ENCRYPTION
,
1266 sync_pb::EncryptedData()));
1271 DCHECK(cryptographer
.is_ready());
1273 // Will do nothing if we're already properly migrated or unable to migrate
1274 // (in otherwords, if ShouldTriggerMigration is false).
1275 // Otherwise will update the nigori node with the current migrated state,
1276 // writing all encryption state as it does.
1277 if (!AttemptToMigrateNigoriToKeystore(trans
, nigori_node
)) {
1278 sync_pb::NigoriSpecifics
nigori(nigori_node
->GetNigoriSpecifics());
1279 // Does not modify nigori.encryption_keybag() if the original decrypted
1280 // data was the same.
1281 if (!cryptographer
.GetKeys(nigori
.mutable_encryption_keybag()))
1283 if (IsNigoriMigratedToKeystore(nigori
)) {
1284 DCHECK(keystore_key_
.empty() || IsExplicitPassphrase(passphrase_type_
));
1285 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1288 nigori
.set_keybag_is_frozen(
1289 IsExplicitPassphrase(passphrase_type_
));
1291 // If we set a new custom passphrase, store the timestamp.
1292 if (!custom_passphrase_time_
.is_null()) {
1293 nigori
.set_custom_passphrase_time(
1294 TimeToProtoTime(custom_passphrase_time_
));
1296 nigori_node
->SetNigoriSpecifics(nigori
);
1299 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
1300 // checks the passphrase state after it has been set.
1301 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1302 OnPassphraseAccepted());
1304 // Does nothing if everything is already encrypted.
1305 // TODO(zea): If we just migrated and enabled encryption, this will be
1306 // redundant. Figure out a way to not do this unnecessarily.
1307 ReEncryptEverything(trans
);
1310 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
1311 ModelTypeSet new_encrypted_types
,
1312 syncable::BaseTransaction
* const trans
) {
1313 DCHECK(thread_checker_
.CalledOnValidThread());
1315 // Only UserTypes may be encrypted.
1316 DCHECK(EncryptableUserTypes().HasAll(new_encrypted_types
));
1318 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1319 if (!encrypted_types
->HasAll(new_encrypted_types
)) {
1320 *encrypted_types
= new_encrypted_types
;
1322 Observer
, observers_
,
1323 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1327 SyncEncryptionHandlerImpl::Vault
* SyncEncryptionHandlerImpl::UnlockVaultMutable(
1328 syncable::BaseTransaction
* const trans
) {
1329 DCHECK_EQ(user_share_
->directory
.get(), trans
->directory());
1330 return &vault_unsafe_
;
1333 const SyncEncryptionHandlerImpl::Vault
& SyncEncryptionHandlerImpl::UnlockVault(
1334 syncable::BaseTransaction
* const trans
) const {
1335 DCHECK_EQ(user_share_
->directory
.get(), trans
->directory());
1336 return vault_unsafe_
;
1339 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1340 const sync_pb::NigoriSpecifics
& nigori
,
1341 const Cryptographer
& cryptographer
) const {
1342 DCHECK(thread_checker_
.CalledOnValidThread());
1343 // Don't migrate if there are pending encryption keys (because data
1344 // encrypted with the pending keys will not be decryptable).
1345 if (cryptographer
.has_pending_keys())
1347 if (IsNigoriMigratedToKeystore(nigori
)) {
1348 // If the nigori is already migrated but does not reflect the explicit
1349 // passphrase state, remigrate. Similarly, if the nigori has an explicit
1350 // passphrase but does not have full encryption, or the nigori has an
1351 // implicit passphrase but does have full encryption, re-migrate.
1352 // Note that this is to defend against other clients without keystore
1353 // encryption enabled transitioning to states that are no longer valid.
1354 if (passphrase_type_
!= KEYSTORE_PASSPHRASE
&&
1355 nigori
.passphrase_type() ==
1356 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
) {
1358 } else if (IsExplicitPassphrase(passphrase_type_
) &&
1359 !encrypt_everything_
) {
1361 } else if (passphrase_type_
== KEYSTORE_PASSPHRASE
&&
1362 encrypt_everything_
) {
1365 cryptographer
.is_ready() &&
1366 !cryptographer
.CanDecryptUsingDefaultKey(nigori
.encryption_keybag())) {
1367 // We need to overwrite the keybag. This might involve overwriting the
1368 // keystore decryptor too.
1370 } else if (old_keystore_keys_
.size() > 0 && !keystore_key_
.empty()) {
1371 // Check to see if a server key rotation has happened, but the nigori
1372 // node's keys haven't been rotated yet, and hence we should re-migrate.
1373 // Note that once a key rotation has been performed, we no longer
1374 // preserve backwards compatibility, and the keybag will therefore be
1375 // encrypted with the current keystore key.
1376 Cryptographer
temp_cryptographer(cryptographer
.encryptor());
1377 KeyParams keystore_params
= {"localhost", "dummy", keystore_key_
};
1378 temp_cryptographer
.AddKey(keystore_params
);
1379 if (!temp_cryptographer
.CanDecryptUsingDefaultKey(
1380 nigori
.encryption_keybag())) {
1385 } else if (keystore_key_
.empty()) {
1386 // If we haven't already migrated, we don't want to do anything unless
1387 // a keystore key is available (so that those clients without keystore
1388 // encryption enabled aren't forced into new states, e.g. frozen implicit
1395 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1396 WriteTransaction
* trans
,
1397 WriteNode
* nigori_node
) {
1398 DCHECK(thread_checker_
.CalledOnValidThread());
1399 const sync_pb::NigoriSpecifics
& old_nigori
=
1400 nigori_node
->GetNigoriSpecifics();
1401 Cryptographer
* cryptographer
=
1402 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1404 if (!ShouldTriggerMigration(old_nigori
, *cryptographer
))
1407 DVLOG(1) << "Starting nigori migration to keystore support.";
1408 sync_pb::NigoriSpecifics
migrated_nigori(old_nigori
);
1410 PassphraseType new_passphrase_type
= passphrase_type_
;
1411 bool new_encrypt_everything
= encrypt_everything_
;
1412 if (encrypt_everything_
&& !IsExplicitPassphrase(passphrase_type_
)) {
1413 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1414 << "full encryption.";
1415 new_passphrase_type
= FROZEN_IMPLICIT_PASSPHRASE
;
1416 migrated_nigori
.clear_keystore_decryptor_token();
1417 } else if (IsExplicitPassphrase(passphrase_type_
)) {
1418 DVLOG_IF(1, !encrypt_everything_
) << "Enabling encrypt everything due to "
1419 << "explicit passphrase";
1420 new_encrypt_everything
= true;
1421 migrated_nigori
.clear_keystore_decryptor_token();
1423 DCHECK(!encrypt_everything_
);
1424 new_passphrase_type
= KEYSTORE_PASSPHRASE
;
1425 DVLOG(1) << "Switching to keystore passphrase state.";
1427 migrated_nigori
.set_encrypt_everything(new_encrypt_everything
);
1428 migrated_nigori
.set_passphrase_type(
1429 EnumPassphraseTypeToProto(new_passphrase_type
));
1430 migrated_nigori
.set_keybag_is_frozen(true);
1432 if (!keystore_key_
.empty()) {
1433 KeyParams key_params
= {"localhost", "dummy", keystore_key_
};
1434 if ((old_keystore_keys_
.size() > 0 &&
1435 new_passphrase_type
== KEYSTORE_PASSPHRASE
) ||
1436 !cryptographer
->is_initialized()) {
1437 // Either at least one key rotation has been performed, so we no longer
1438 // care about backwards compatibility, or we're generating keystore-based
1439 // encryption keys without knowing the GAIA password (and therefore the
1440 // cryptographer is not initialized), so we can't support backwards
1441 // compatibility. Ensure the keystore key is the default key.
1442 DVLOG(1) << "Migrating keybag to keystore key.";
1443 bool cryptographer_was_ready
= cryptographer
->is_ready();
1444 if (!cryptographer
->AddKey(key_params
)) {
1445 LOG(ERROR
) << "Failed to add keystore key as default key";
1446 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1447 FAILED_TO_SET_DEFAULT_KEYSTORE
,
1448 MIGRATION_RESULT_SIZE
);
1451 if (!cryptographer_was_ready
&& cryptographer
->is_ready()) {
1453 SyncEncryptionHandler::Observer
,
1455 OnPassphraseAccepted());
1458 // We're in backwards compatible mode -- either the account has an
1459 // explicit passphrase, or we want to preserve the current GAIA-based key
1460 // as the default because we can (there have been no key rotations since
1462 DVLOG(1) << "Migrating keybag while preserving old key";
1463 if (!cryptographer
->AddNonDefaultKey(key_params
)) {
1464 LOG(ERROR
) << "Failed to add keystore key as non-default key.";
1465 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1466 FAILED_TO_SET_NONDEFAULT_KEYSTORE
,
1467 MIGRATION_RESULT_SIZE
);
1472 if (!old_keystore_keys_
.empty()) {
1473 // Go through and add all the old keystore keys as non default keys, so
1474 // they'll be preserved in the encryption_keybag when we next write the
1476 for (std::vector
<std::string
>::const_iterator iter
=
1477 old_keystore_keys_
.begin(); iter
!= old_keystore_keys_
.end();
1479 KeyParams key_params
= {"localhost", "dummy", *iter
};
1480 cryptographer
->AddNonDefaultKey(key_params
);
1483 if (new_passphrase_type
== KEYSTORE_PASSPHRASE
&&
1484 !GetKeystoreDecryptor(
1487 migrated_nigori
.mutable_keystore_decryptor_token())) {
1488 LOG(ERROR
) << "Failed to extract keystore decryptor token.";
1489 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1490 FAILED_TO_EXTRACT_DECRYPTOR
,
1491 MIGRATION_RESULT_SIZE
);
1494 if (!cryptographer
->GetKeys(migrated_nigori
.mutable_encryption_keybag())) {
1495 LOG(ERROR
) << "Failed to extract encryption keybag.";
1496 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1497 FAILED_TO_EXTRACT_KEYBAG
,
1498 MIGRATION_RESULT_SIZE
);
1502 if (migration_time_
.is_null())
1503 migration_time_
= base::Time::Now();
1504 migrated_nigori
.set_keystore_migration_time(TimeToProtoTime(migration_time_
));
1506 if (!custom_passphrase_time_
.is_null()) {
1507 migrated_nigori
.set_custom_passphrase_time(
1508 TimeToProtoTime(custom_passphrase_time_
));
1512 SyncEncryptionHandler::Observer
,
1514 OnCryptographerStateChanged(cryptographer
));
1515 if (passphrase_type_
!= new_passphrase_type
) {
1516 passphrase_type_
= new_passphrase_type
;
1517 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1518 OnPassphraseTypeChanged(
1520 GetExplicitPassphraseTime()));
1523 if (new_encrypt_everything
&& !encrypt_everything_
) {
1524 EnableEncryptEverythingImpl(trans
->GetWrappedTrans());
1525 ReEncryptEverything(trans
);
1526 } else if (!cryptographer
->CanDecryptUsingDefaultKey(
1527 old_nigori
.encryption_keybag())) {
1528 DVLOG(1) << "Rencrypting everything due to key rotation.";
1529 ReEncryptEverything(trans
);
1532 DVLOG(1) << "Completing nigori migration to keystore support.";
1533 nigori_node
->SetNigoriSpecifics(migrated_nigori
);
1535 if (new_encrypt_everything
&&
1536 (new_passphrase_type
== FROZEN_IMPLICIT_PASSPHRASE
||
1537 new_passphrase_type
== CUSTOM_PASSPHRASE
))
1538 NotifyObserversOfLocalCustomPassphrase(trans
);
1540 switch (new_passphrase_type
) {
1541 case KEYSTORE_PASSPHRASE
:
1542 if (old_keystore_keys_
.size() > 0) {
1543 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1544 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT
,
1545 MIGRATION_RESULT_SIZE
);
1547 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1548 MIGRATION_SUCCESS_KEYSTORE_DEFAULT
,
1549 MIGRATION_RESULT_SIZE
);
1552 case FROZEN_IMPLICIT_PASSPHRASE
:
1553 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1554 MIGRATION_SUCCESS_FROZEN_IMPLICIT
,
1555 MIGRATION_RESULT_SIZE
);
1557 case CUSTOM_PASSPHRASE
:
1558 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1559 MIGRATION_SUCCESS_CUSTOM
,
1560 MIGRATION_RESULT_SIZE
);
1569 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1570 const Cryptographer
& cryptographer
,
1571 const std::string
& keystore_key
,
1572 sync_pb::EncryptedData
* encrypted_blob
) {
1573 DCHECK(thread_checker_
.CalledOnValidThread());
1574 DCHECK(!keystore_key
.empty());
1575 DCHECK(cryptographer
.is_ready());
1576 std::string serialized_nigori
;
1577 serialized_nigori
= cryptographer
.GetDefaultNigoriKeyData();
1578 if (serialized_nigori
.empty()) {
1579 LOG(ERROR
) << "Failed to get cryptographer bootstrap token.";
1582 Cryptographer
temp_cryptographer(cryptographer
.encryptor());
1583 KeyParams key_params
= {"localhost", "dummy", keystore_key
};
1584 if (!temp_cryptographer
.AddKey(key_params
))
1586 if (!temp_cryptographer
.EncryptString(serialized_nigori
, encrypted_blob
))
1591 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1592 const sync_pb::EncryptedData
& keybag
,
1593 bool update_default
,
1594 Cryptographer
* cryptographer
) {
1595 if (!cryptographer
->CanDecrypt(keybag
))
1597 cryptographer
->InstallKeys(keybag
);
1599 cryptographer
->SetDefaultKey(keybag
.key_name());
1603 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1604 syncable::BaseTransaction
* const trans
) {
1605 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1606 if (encrypt_everything_
) {
1607 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1610 encrypt_everything_
= true;
1611 *encrypted_types
= EncryptableUserTypes();
1613 Observer
, observers_
,
1614 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1617 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1618 const std::string
& keystore_key
,
1619 const sync_pb::EncryptedData
& keystore_decryptor_token
,
1620 Cryptographer
* cryptographer
) {
1621 DCHECK(cryptographer
->has_pending_keys());
1622 if (keystore_decryptor_token
.blob().empty())
1624 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
1626 // First, go through and all all the old keystore keys to the temporary
1628 for (size_t i
= 0; i
< old_keystore_keys_
.size(); ++i
) {
1629 KeyParams old_key_params
= {"localhost", "dummy", old_keystore_keys_
[i
]};
1630 temp_cryptographer
.AddKey(old_key_params
);
1633 // Then add the current keystore key as the default key and see if we can
1635 KeyParams keystore_params
= {"localhost", "dummy", keystore_key_
};
1636 if (temp_cryptographer
.AddKey(keystore_params
) &&
1637 temp_cryptographer
.CanDecrypt(keystore_decryptor_token
)) {
1638 // Someone else migrated the nigori for us! How generous! Go ahead and
1639 // install both the keystore key and the new default encryption key
1640 // (i.e. the one provided by the keystore decryptor token) into the
1642 // The keystore decryptor token is a keystore key encrypted blob containing
1643 // the current serialized default encryption key (and as such should be
1644 // able to decrypt the nigori node's encryption keybag).
1645 // Note: it's possible a key rotation has happened since the migration, and
1646 // we're decrypting using an old keystore key. In that case we need to
1647 // ensure we re-encrypt using the newest key.
1648 DVLOG(1) << "Attempting to decrypt pending keys using "
1649 << "keystore decryptor token.";
1650 std::string serialized_nigori
=
1651 temp_cryptographer
.DecryptToString(keystore_decryptor_token
);
1653 // This will decrypt the pending keys and add them if possible. The key
1654 // within |serialized_nigori| will be the default after.
1655 cryptographer
->ImportNigoriKey(serialized_nigori
);
1657 if (!temp_cryptographer
.CanDecryptUsingDefaultKey(
1658 keystore_decryptor_token
)) {
1659 // The keystore decryptor token was derived from an old keystore key.
1660 // A key rotation is necessary, so set the current keystore key as the
1661 // default key (which will trigger a re-migration).
1662 DVLOG(1) << "Pending keys based on old keystore key. Setting newest "
1663 << "keystore key as default.";
1664 cryptographer
->AddKey(keystore_params
);
1666 // Theoretically the encryption keybag should already contain the keystore
1667 // key. We explicitly add it as a safety measure.
1668 DVLOG(1) << "Pending keys based on newest keystore key.";
1669 cryptographer
->AddNonDefaultKey(keystore_params
);
1671 if (cryptographer
->is_ready()) {
1672 std::string bootstrap_token
;
1673 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1674 DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1676 SyncEncryptionHandler::Observer
,
1678 OnPassphraseAccepted());
1680 SyncEncryptionHandler::Observer
,
1682 OnBootstrapTokenUpdated(bootstrap_token
,
1683 PASSPHRASE_BOOTSTRAP_TOKEN
));
1685 SyncEncryptionHandler::Observer
,
1687 OnCryptographerStateChanged(cryptographer
));
1694 base::Time
SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const {
1695 if (passphrase_type_
== FROZEN_IMPLICIT_PASSPHRASE
)
1696 return migration_time();
1697 else if (passphrase_type_
== CUSTOM_PASSPHRASE
)
1698 return custom_passphrase_time();
1699 return base::Time();
1702 } // namespace browser_sync