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/nigori_util.h"
30 #include "sync/syncable/syncable_base_transaction.h"
31 #include "sync/util/cryptographer.h"
32 #include "sync/util/encryptor.h"
33 #include "sync/util/time.h"
39 // The maximum number of times we will automatically overwrite the nigori node
40 // because the encryption keys don't match (per chrome instantiation).
41 // We protect ourselves against nigori rollbacks, but it's possible two
42 // different clients might have contrasting view of what the nigori node state
43 // should be, in which case they might ping pong (see crbug.com/119207).
44 static const int kNigoriOverwriteLimit
= 10;
46 // Enumeration of nigori keystore migration results (for use in UMA stats).
47 enum NigoriMigrationResult
{
48 FAILED_TO_SET_DEFAULT_KEYSTORE
,
49 FAILED_TO_SET_NONDEFAULT_KEYSTORE
,
50 FAILED_TO_EXTRACT_DECRYPTOR
,
51 FAILED_TO_EXTRACT_KEYBAG
,
52 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT
,
53 MIGRATION_SUCCESS_KEYSTORE_DEFAULT
,
54 MIGRATION_SUCCESS_FROZEN_IMPLICIT
,
55 MIGRATION_SUCCESS_CUSTOM
,
56 MIGRATION_RESULT_SIZE
,
59 enum NigoriMigrationState
{
61 NOT_MIGRATED_CRYPTO_NOT_READY
,
62 NOT_MIGRATED_NO_KEYSTORE_KEY
,
63 NOT_MIGRATED_UNKNOWN_REASON
,
67 // The new passphrase state is sufficient to determine whether a nigori node
68 // is migrated to support keystore encryption. In addition though, we also
69 // want to verify the conditions for proper keystore encryption functionality.
70 // 1. Passphrase state is set.
71 // 2. Migration time is set.
72 // 3. Frozen keybag is true
73 // 4. If passphrase state is keystore, keystore_decryptor_token is set.
74 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics
& nigori
) {
75 if (!nigori
.has_passphrase_type())
77 if (!nigori
.has_keystore_migration_time())
79 if (!nigori
.keybag_is_frozen())
81 if (nigori
.passphrase_type() ==
82 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
)
84 if (nigori
.passphrase_type() ==
85 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
&&
86 nigori
.keystore_decryptor_token().blob().empty())
88 if (!nigori
.has_keystore_migration_time())
93 PassphraseType
ProtoPassphraseTypeToEnum(
94 sync_pb::NigoriSpecifics::PassphraseType type
) {
96 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
:
97 return IMPLICIT_PASSPHRASE
;
98 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
:
99 return KEYSTORE_PASSPHRASE
;
100 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE
:
101 return CUSTOM_PASSPHRASE
;
102 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE
:
103 return FROZEN_IMPLICIT_PASSPHRASE
;
106 return IMPLICIT_PASSPHRASE
;
110 sync_pb::NigoriSpecifics::PassphraseType
111 EnumPassphraseTypeToProto(PassphraseType type
) {
113 case IMPLICIT_PASSPHRASE
:
114 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
;
115 case KEYSTORE_PASSPHRASE
:
116 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
;
117 case CUSTOM_PASSPHRASE
:
118 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE
;
119 case FROZEN_IMPLICIT_PASSPHRASE
:
120 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE
;
123 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE
;
127 bool IsExplicitPassphrase(PassphraseType type
) {
128 return type
== CUSTOM_PASSPHRASE
|| type
== FROZEN_IMPLICIT_PASSPHRASE
;
131 // Keystore Bootstrap Token helper methods.
132 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
133 // strings, with the current keystore key as the last value in the list.
134 std::string
PackKeystoreBootstrapToken(
135 const std::vector
<std::string
>& old_keystore_keys
,
136 const std::string
& current_keystore_key
,
137 Encryptor
* encryptor
) {
138 if (current_keystore_key
.empty())
139 return std::string();
141 base::ListValue keystore_key_values
;
142 for (size_t i
= 0; i
< old_keystore_keys
.size(); ++i
)
143 keystore_key_values
.AppendString(old_keystore_keys
[i
]);
144 keystore_key_values
.AppendString(current_keystore_key
);
146 // Update the bootstrap token.
147 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key
148 // strings, with the current keystore key as the last value in the list.
149 std::string serialized_keystores
;
150 JSONStringValueSerializer
json(&serialized_keystores
);
151 json
.Serialize(keystore_key_values
);
152 std::string encrypted_keystores
;
153 encryptor
->EncryptString(serialized_keystores
,
154 &encrypted_keystores
);
155 std::string keystore_bootstrap
;
156 base::Base64Encode(encrypted_keystores
, &keystore_bootstrap
);
157 return keystore_bootstrap
;
160 bool UnpackKeystoreBootstrapToken(
161 const std::string
& keystore_bootstrap_token
,
162 Encryptor
* encryptor
,
163 std::vector
<std::string
>* old_keystore_keys
,
164 std::string
* current_keystore_key
) {
165 if (keystore_bootstrap_token
.empty())
167 std::string base64_decoded_keystore_bootstrap
;
168 if (!base::Base64Decode(keystore_bootstrap_token
,
169 &base64_decoded_keystore_bootstrap
)) {
172 std::string decrypted_keystore_bootstrap
;
173 if (!encryptor
->DecryptString(base64_decoded_keystore_bootstrap
,
174 &decrypted_keystore_bootstrap
)) {
177 JSONStringValueSerializer
json(&decrypted_keystore_bootstrap
);
178 scoped_ptr
<base::Value
> deserialized_keystore_keys(
179 json
.Deserialize(NULL
, NULL
));
180 if (!deserialized_keystore_keys
)
182 base::ListValue
* internal_list_value
= NULL
;
183 if (!deserialized_keystore_keys
->GetAsList(&internal_list_value
))
185 int number_of_keystore_keys
= internal_list_value
->GetSize();
186 if (!internal_list_value
->GetString(number_of_keystore_keys
- 1,
187 current_keystore_key
)) {
190 old_keystore_keys
->resize(number_of_keystore_keys
- 1);
191 for (int i
= 0; i
< number_of_keystore_keys
- 1; ++i
)
192 internal_list_value
->GetString(i
, &(*old_keystore_keys
)[i
]);
198 SyncEncryptionHandlerImpl::Vault::Vault(
199 Encryptor
* encryptor
,
200 ModelTypeSet encrypted_types
)
201 : cryptographer(encryptor
),
202 encrypted_types(encrypted_types
) {
205 SyncEncryptionHandlerImpl::Vault::~Vault() {
208 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
209 UserShare
* user_share
,
210 Encryptor
* encryptor
,
211 const std::string
& restored_key_for_bootstrapping
,
212 const std::string
& restored_keystore_key_for_bootstrapping
)
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 weak_ptr_factory_(this) {
219 // Restore the cryptographer's previous keys. Note that we don't add the
220 // keystore keys into the cryptographer here, in case a migration was pending.
221 vault_unsafe_
.cryptographer
.Bootstrap(restored_key_for_bootstrapping
);
223 // If this fails, we won't have a valid keystore key, and will simply request
224 // new ones from the server on the next DownloadUpdates.
225 UnpackKeystoreBootstrapToken(
226 restored_keystore_key_for_bootstrapping
,
232 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
234 void SyncEncryptionHandlerImpl::AddObserver(Observer
* observer
) {
235 DCHECK(thread_checker_
.CalledOnValidThread());
236 DCHECK(!observers_
.HasObserver(observer
));
237 observers_
.AddObserver(observer
);
240 void SyncEncryptionHandlerImpl::RemoveObserver(Observer
* observer
) {
241 DCHECK(thread_checker_
.CalledOnValidThread());
242 DCHECK(observers_
.HasObserver(observer
));
243 observers_
.RemoveObserver(observer
);
246 void SyncEncryptionHandlerImpl::Init() {
247 DCHECK(thread_checker_
.CalledOnValidThread());
248 WriteTransaction
trans(FROM_HERE
, user_share_
);
249 WriteNode
node(&trans
);
251 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
253 if (!ApplyNigoriUpdateImpl(node
.GetNigoriSpecifics(),
254 trans
.GetWrappedTrans())) {
255 WriteEncryptionStateToNigori(&trans
);
258 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType",
260 PASSPHRASE_TYPE_SIZE
);
262 bool has_pending_keys
= UnlockVault(
263 trans
.GetWrappedTrans()).cryptographer
.has_pending_keys();
264 bool is_ready
= UnlockVault(
265 trans
.GetWrappedTrans()).cryptographer
.is_ready();
266 // Log the state of the cryptographer regardless of migration state.
267 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready
);
268 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys
);
269 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics())) {
270 // This account has a nigori node that has been migrated to support
272 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
274 MIGRATION_STATE_SIZE
);
275 if (has_pending_keys
&& passphrase_type_
== KEYSTORE_PASSPHRASE
) {
276 // If this is happening, it means the keystore decryptor is either
277 // undecryptable with the available keystore keys or does not match the
278 // nigori keybag's encryption key. Otherwise we're simply missing the
280 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed",
281 !keystore_key_
.empty());
283 } else if (!is_ready
) {
284 // Migration cannot occur until the cryptographer is ready (initialized
285 // with GAIA password and any pending keys resolved).
286 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
287 NOT_MIGRATED_CRYPTO_NOT_READY
,
288 MIGRATION_STATE_SIZE
);
289 } else if (keystore_key_
.empty()) {
290 // The client has no keystore key, either because it is not yet enabled or
291 // the server is not sending a valid keystore key.
292 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
293 NOT_MIGRATED_NO_KEYSTORE_KEY
,
294 MIGRATION_STATE_SIZE
);
296 // If the above conditions have been met and the nigori node is still not
297 // migrated, something failed in the migration process.
298 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
299 NOT_MIGRATED_UNKNOWN_REASON
,
300 MIGRATION_STATE_SIZE
);
304 // Always trigger an encrypted types and cryptographer state change event at
305 // init time so observers get the initial values.
307 Observer
, observers_
,
308 OnEncryptedTypesChanged(
309 UnlockVault(trans
.GetWrappedTrans()).encrypted_types
,
310 encrypt_everything_
));
312 SyncEncryptionHandler::Observer
,
314 OnCryptographerStateChanged(
315 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
));
317 // If the cryptographer is not ready (either it has pending keys or we
318 // failed to initialize it), we don't want to try and re-encrypt the data.
319 // If we had encrypted types, the DataTypeManager will block, preventing
320 // sync from happening until the the passphrase is provided.
321 if (UnlockVault(trans
.GetWrappedTrans()).cryptographer
.is_ready())
322 ReEncryptEverything(&trans
);
325 void SyncEncryptionHandlerImpl::SetEncryptionPassphrase(
326 const std::string
& passphrase
,
328 DCHECK(thread_checker_
.CalledOnValidThread());
329 // We do not accept empty passphrases.
330 if (passphrase
.empty()) {
331 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
335 // All accesses to the cryptographer are protected by a transaction.
336 WriteTransaction
trans(FROM_HERE
, user_share_
);
337 KeyParams key_params
= {"localhost", "dummy", passphrase
};
338 WriteNode
node(&trans
);
339 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
) {
344 Cryptographer
* cryptographer
=
345 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
;
347 // Once we've migrated to keystore, the only way to set a passphrase for
348 // encryption is to set a custom passphrase.
349 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics())) {
351 // The user is setting a new implicit passphrase. At this point we don't
352 // care, so drop it on the floor. This is safe because if we have a
353 // migrated nigori node, then we don't need to create an initial
355 LOG(WARNING
) << "Ignoring new implicit passphrase. Keystore migration "
356 << "already performed.";
359 // Will fail if we already have an explicit passphrase or we have pending
361 SetCustomPassphrase(passphrase
, &trans
, &node
);
363 // When keystore migration occurs, the "CustomEncryption" UMA stat must be
365 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", true);
369 std::string bootstrap_token
;
370 sync_pb::EncryptedData pending_keys
;
371 if (cryptographer
->has_pending_keys())
372 pending_keys
= cryptographer
->GetPendingKeys();
373 bool success
= false;
375 // There are six cases to handle here:
376 // 1. The user has no pending keys and is setting their current GAIA password
377 // as the encryption passphrase. This happens either during first time sync
378 // with a clean profile, or after re-authenticating on a profile that was
379 // already signed in with the cryptographer ready.
380 // 2. The user has no pending keys, and is overwriting an (already provided)
381 // implicit passphrase with an explicit (custom) passphrase.
382 // 3. The user has pending keys for an explicit passphrase that is somehow set
383 // to their current GAIA passphrase.
384 // 4. The user has pending keys encrypted with their current GAIA passphrase
385 // and the caller passes in the current GAIA passphrase.
386 // 5. The user has pending keys encrypted with an older GAIA passphrase
387 // and the caller passes in the current GAIA passphrase.
388 // 6. The user has previously done encryption with an explicit passphrase.
389 // Furthermore, we enforce the fact that the bootstrap encryption token will
390 // always be derived from the newest GAIA password if the account is using
391 // an implicit passphrase (even if the data is encrypted with an old GAIA
392 // password). If the account is using an explicit (custom) passphrase, the
393 // bootstrap token will be derived from the most recently provided explicit
394 // passphrase (that was able to decrypt the data).
395 if (!IsExplicitPassphrase(passphrase_type_
)) {
396 if (!cryptographer
->has_pending_keys()) {
397 if (cryptographer
->AddKey(key_params
)) {
398 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
399 // keys (1), or overwriting an implicit passphrase with a new explicit
400 // one (2) when there are no pending keys.
402 DVLOG(1) << "Setting explicit passphrase for encryption.";
403 passphrase_type_
= CUSTOM_PASSPHRASE
;
404 custom_passphrase_time_
= base::Time::Now();
405 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
406 OnPassphraseTypeChanged(
408 GetExplicitPassphraseTime()));
410 DVLOG(1) << "Setting implicit passphrase for encryption.";
412 cryptographer
->GetBootstrapToken(&bootstrap_token
);
414 // With M26, sync accounts can be in only one of two encryption states:
415 // 1) Encrypt only passwords with an implicit passphrase.
416 // 2) Encrypt all sync datatypes with an explicit passphrase.
417 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms,
418 // and keep track of an account's encryption state via the
419 // "CustomEncryption" histogram. See http://crbug.com/131478.
420 UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", is_explicit
);
424 NOTREACHED() << "Failed to add key to cryptographer.";
427 } else { // cryptographer->has_pending_keys() == true
429 // This can only happen if the nigori node is updated with a new
430 // implicit passphrase while a client is attempting to set a new custom
431 // passphrase (race condition).
432 DVLOG(1) << "Failing because an implicit passphrase is already set.";
434 } else { // is_explicit == false
435 if (cryptographer
->DecryptPendingKeys(key_params
)) {
436 // Case 4. We successfully decrypted with the implicit GAIA passphrase
438 DVLOG(1) << "Implicit internal passphrase accepted for decryption.";
439 cryptographer
->GetBootstrapToken(&bootstrap_token
);
442 // Case 5. Encryption was done with an old GAIA password, but we were
443 // provided with the current GAIA password. We need to generate a new
444 // bootstrap token to preserve it. We build a temporary cryptographer
445 // to allow us to extract these params without polluting our current
447 DVLOG(1) << "Implicit internal passphrase failed to decrypt, adding "
448 << "anyways as default passphrase and persisting via "
449 << "bootstrap token.";
450 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
451 temp_cryptographer
.AddKey(key_params
);
452 temp_cryptographer
.GetBootstrapToken(&bootstrap_token
);
453 // We then set the new passphrase as the default passphrase of the
454 // real cryptographer, even though we have pending keys. This is safe,
455 // as although Cryptographer::is_initialized() will now be true,
456 // is_ready() will remain false due to having pending keys.
457 cryptographer
->AddKey(key_params
);
461 } // cryptographer->has_pending_keys()
462 } else { // IsExplicitPassphrase(passphrase_type_) == true.
463 // Case 6. We do not want to override a previously set explicit passphrase,
464 // so we return a failure.
465 DVLOG(1) << "Failing because an explicit passphrase is already set.";
469 DVLOG_IF(1, !success
)
470 << "Failure in SetEncryptionPassphrase; notifying and returning.";
472 << "Successfully set encryption passphrase; updating nigori and "
475 FinishSetPassphrase(success
, bootstrap_token
, &trans
, &node
);
478 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
479 const std::string
& passphrase
) {
480 DCHECK(thread_checker_
.CalledOnValidThread());
481 // We do not accept empty passphrases.
482 if (passphrase
.empty()) {
483 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
487 // All accesses to the cryptographer are protected by a transaction.
488 WriteTransaction
trans(FROM_HERE
, user_share_
);
489 KeyParams key_params
= {"localhost", "dummy", passphrase
};
490 WriteNode
node(&trans
);
491 if (node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
) {
496 // Once we've migrated to keystore, we're only ever decrypting keys derived
497 // from an explicit passphrase. But, for clients without a keystore key yet
498 // (either not on by default or failed to download one), we still support
499 // decrypting with a gaia passphrase, and therefore bypass the
500 // DecryptPendingKeysWithExplicitPassphrase logic.
501 if (IsNigoriMigratedToKeystore(node
.GetNigoriSpecifics()) &&
502 IsExplicitPassphrase(passphrase_type_
)) {
503 DecryptPendingKeysWithExplicitPassphrase(passphrase
, &trans
, &node
);
507 Cryptographer
* cryptographer
=
508 &UnlockVaultMutable(trans
.GetWrappedTrans())->cryptographer
;
509 if (!cryptographer
->has_pending_keys()) {
510 // Note that this *can* happen in a rare situation where data is
511 // re-encrypted on another client while a SetDecryptionPassphrase() call is
512 // in-flight on this client. It is rare enough that we choose to do nothing.
513 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
514 << "were no pending keys.";
518 std::string bootstrap_token
;
519 sync_pb::EncryptedData pending_keys
;
520 pending_keys
= cryptographer
->GetPendingKeys();
521 bool success
= false;
523 // There are three cases to handle here:
524 // 7. We're using the current GAIA password to decrypt the pending keys. This
525 // happens when signing in to an account with a previously set implicit
526 // passphrase, where the data is already encrypted with the newest GAIA
528 // 8. The user is providing an old GAIA password to decrypt the pending keys.
529 // In this case, the user is using an implicit passphrase, but has changed
530 // their password since they last encrypted their data, and therefore
531 // their current GAIA password was unable to decrypt the data. This will
532 // happen when the user is setting up a new profile with a previously
533 // encrypted account (after changing passwords).
534 // 9. The user is providing a previously set explicit passphrase to decrypt
536 if (!IsExplicitPassphrase(passphrase_type_
)) {
537 if (cryptographer
->is_initialized()) {
538 // We only want to change the default encryption key to the pending
539 // one if the pending keybag already contains the current default.
540 // This covers the case where a different client re-encrypted
541 // everything with a newer gaia passphrase (and hence the keybag
542 // contains keys from all previously used gaia passphrases).
543 // Otherwise, we're in a situation where the pending keys are
544 // encrypted with an old gaia passphrase, while the default is the
545 // current gaia passphrase. In that case, we preserve the default.
546 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
547 temp_cryptographer
.SetPendingKeys(cryptographer
->GetPendingKeys());
548 if (temp_cryptographer
.DecryptPendingKeys(key_params
)) {
549 // Check to see if the pending bag of keys contains the current
551 sync_pb::EncryptedData encrypted
;
552 cryptographer
->GetKeys(&encrypted
);
553 if (temp_cryptographer
.CanDecrypt(encrypted
)) {
554 DVLOG(1) << "Implicit user provided passphrase accepted for "
555 << "decryption, overwriting default.";
556 // Case 7. The pending keybag contains the current default. Go ahead
557 // and update the cryptographer, letting the default change.
558 cryptographer
->DecryptPendingKeys(key_params
);
559 cryptographer
->GetBootstrapToken(&bootstrap_token
);
562 // Case 8. The pending keybag does not contain the current default
563 // encryption key. We decrypt the pending keys here, and in
564 // FinishSetPassphrase, re-encrypt everything with the current GAIA
565 // passphrase instead of the passphrase just provided by the user.
566 DVLOG(1) << "Implicit user provided passphrase accepted for "
567 << "decryption, restoring implicit internal passphrase "
569 std::string bootstrap_token_from_current_key
;
570 cryptographer
->GetBootstrapToken(
571 &bootstrap_token_from_current_key
);
572 cryptographer
->DecryptPendingKeys(key_params
);
573 // Overwrite the default from the pending keys.
574 cryptographer
->AddKeyFromBootstrapToken(
575 bootstrap_token_from_current_key
);
578 } else { // !temp_cryptographer.DecryptPendingKeys(..)
579 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
581 } // temp_cryptographer.DecryptPendingKeys(...)
582 } else { // cryptographer->is_initialized() == false
583 if (cryptographer
->DecryptPendingKeys(key_params
)) {
584 // This can happpen in two cases:
585 // - First time sync on android, where we'll never have a
586 // !user_provided passphrase.
587 // - This is a restart for a client that lost their bootstrap token.
588 // In both cases, we should go ahead and initialize the cryptographer
589 // and persist the new bootstrap token.
591 // Note: at this point, we cannot distinguish between cases 7 and 8
592 // above. This user provided passphrase could be the current or the
593 // old. But, as long as we persist the token, there's nothing more
595 cryptographer
->GetBootstrapToken(&bootstrap_token
);
596 DVLOG(1) << "Implicit user provided passphrase accepted, initializing"
597 << " cryptographer.";
600 DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
603 } // cryptographer->is_initialized()
604 } else { // nigori_has_explicit_passphrase == true
605 // Case 9. Encryption was done with an explicit passphrase, and we decrypt
606 // with the passphrase provided by the user.
607 if (cryptographer
->DecryptPendingKeys(key_params
)) {
608 DVLOG(1) << "Explicit passphrase accepted for decryption.";
609 cryptographer
->GetBootstrapToken(&bootstrap_token
);
612 DVLOG(1) << "Explicit passphrase failed to decrypt.";
615 } // nigori_has_explicit_passphrase
617 DVLOG_IF(1, !success
)
618 << "Failure in SetDecryptionPassphrase; notifying and returning.";
620 << "Successfully set decryption passphrase; updating nigori and "
623 FinishSetPassphrase(success
, bootstrap_token
, &trans
, &node
);
626 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
627 DCHECK(thread_checker_
.CalledOnValidThread());
628 WriteTransaction
trans(FROM_HERE
, user_share_
);
629 DVLOG(1) << "Enabling encrypt everything.";
630 if (encrypt_everything_
)
632 EnableEncryptEverythingImpl(trans
.GetWrappedTrans());
633 WriteEncryptionStateToNigori(&trans
);
634 if (UnlockVault(trans
.GetWrappedTrans()).cryptographer
.is_ready())
635 ReEncryptEverything(&trans
);
638 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
639 DCHECK(thread_checker_
.CalledOnValidThread());
640 return encrypt_everything_
;
643 PassphraseType
SyncEncryptionHandlerImpl::GetPassphraseType() const {
644 DCHECK(thread_checker_
.CalledOnValidThread());
645 return passphrase_type_
;
648 // Note: this is called from within a syncable transaction, so we need to post
649 // tasks if we want to do any work that creates a new sync_api transaction.
650 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
651 const sync_pb::NigoriSpecifics
& nigori
,
652 syncable::BaseTransaction
* const trans
) {
653 DCHECK(thread_checker_
.CalledOnValidThread());
655 if (!ApplyNigoriUpdateImpl(nigori
, trans
)) {
656 base::MessageLoop::current()->PostTask(
658 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori
,
659 weak_ptr_factory_
.GetWeakPtr()));
663 SyncEncryptionHandler::Observer
,
665 OnCryptographerStateChanged(
666 &UnlockVaultMutable(trans
)->cryptographer
));
669 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
670 sync_pb::NigoriSpecifics
* nigori
,
671 syncable::BaseTransaction
* const trans
) const {
672 DCHECK(thread_checker_
.CalledOnValidThread());
673 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans
).encrypted_types
,
678 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
679 syncable::BaseTransaction
* const trans
) const {
680 DCHECK(thread_checker_
.CalledOnValidThread());
681 return keystore_key_
.empty();
684 bool SyncEncryptionHandlerImpl::SetKeystoreKeys(
685 const google::protobuf::RepeatedPtrField
<google::protobuf::string
>& keys
,
686 syncable::BaseTransaction
* const trans
) {
687 DCHECK(thread_checker_
.CalledOnValidThread());
688 if (keys
.size() == 0)
690 // The last key in the vector is the current keystore key. The others are kept
691 // around for decryption only.
692 const std::string
& raw_keystore_key
= keys
.Get(keys
.size() - 1);
693 if (raw_keystore_key
.empty())
696 // Note: in order to Pack the keys, they must all be base64 encoded (else
697 // JSON serialization fails).
698 base::Base64Encode(raw_keystore_key
, &keystore_key_
);
700 // Go through and save the old keystore keys. We always persist all keystore
701 // keys the server sends us.
702 old_keystore_keys_
.resize(keys
.size() - 1);
703 for (int i
= 0; i
< keys
.size() - 1; ++i
)
704 base::Base64Encode(keys
.Get(i
), &old_keystore_keys_
[i
]);
706 Cryptographer
* cryptographer
= &UnlockVaultMutable(trans
)->cryptographer
;
708 // Update the bootstrap token. If this fails, we persist an empty string,
709 // which will force us to download the keystore keys again on the next
711 std::string keystore_bootstrap
= PackKeystoreBootstrapToken(
714 cryptographer
->encryptor());
715 DCHECK_EQ(keystore_bootstrap
.empty(), keystore_key_
.empty());
716 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
717 OnBootstrapTokenUpdated(keystore_bootstrap
,
718 KEYSTORE_BOOTSTRAP_TOKEN
));
719 DVLOG(1) << "Keystore bootstrap token updated.";
721 // If this is a first time sync, we get the encryption keys before we process
722 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
723 // once we have the nigori node.
724 syncable::Entry
entry(trans
, syncable::GET_TYPE_ROOT
, NIGORI
);
728 const sync_pb::NigoriSpecifics
& nigori
=
729 entry
.GetSpecifics().nigori();
730 if (cryptographer
->has_pending_keys() &&
731 IsNigoriMigratedToKeystore(nigori
) &&
732 !nigori
.keystore_decryptor_token().blob().empty()) {
733 // If the nigori is already migrated and we have pending keys, we might
734 // be able to decrypt them using either the keystore decryptor token
735 // or the existing keystore keys.
736 DecryptPendingKeysWithKeystoreKey(keystore_key_
,
737 nigori
.keystore_decryptor_token(),
741 // Note that triggering migration will have no effect if we're already
742 // properly migrated with the newest keystore keys.
743 if (ShouldTriggerMigration(nigori
, *cryptographer
)) {
744 base::MessageLoop::current()->PostTask(
746 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori
,
747 weak_ptr_factory_
.GetWeakPtr()));
753 ModelTypeSet
SyncEncryptionHandlerImpl::GetEncryptedTypes(
754 syncable::BaseTransaction
* const trans
) const {
755 return UnlockVault(trans
).encrypted_types
;
758 Cryptographer
* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
759 DCHECK(thread_checker_
.CalledOnValidThread());
760 return &vault_unsafe_
.cryptographer
;
763 ModelTypeSet
SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
764 DCHECK(thread_checker_
.CalledOnValidThread());
765 return vault_unsafe_
.encrypted_types
;
768 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
769 DCHECK(thread_checker_
.CalledOnValidThread());
770 ReadTransaction
trans(FROM_HERE
, user_share_
);
771 ReadNode
nigori_node(&trans
);
772 if (nigori_node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
774 return IsNigoriMigratedToKeystore(nigori_node
.GetNigoriSpecifics());
777 base::Time
SyncEncryptionHandlerImpl::migration_time() const {
778 return migration_time_
;
781 base::Time
SyncEncryptionHandlerImpl::custom_passphrase_time() const {
782 return custom_passphrase_time_
;
785 // This function iterates over all encrypted types. There are many scenarios in
786 // which data for some or all types is not currently available. In that case,
787 // the lookup of the root node will fail and we will skip encryption for that
789 void SyncEncryptionHandlerImpl::ReEncryptEverything(
790 WriteTransaction
* trans
) {
791 DCHECK(thread_checker_
.CalledOnValidThread());
792 DCHECK(UnlockVault(trans
->GetWrappedTrans()).cryptographer
.is_ready());
793 for (ModelTypeSet::Iterator iter
=
794 UnlockVault(trans
->GetWrappedTrans()).encrypted_types
.First();
795 iter
.Good(); iter
.Inc()) {
796 if (iter
.Get() == PASSWORDS
|| IsControlType(iter
.Get()))
797 continue; // These types handle encryption differently.
799 ReadNode
type_root(trans
);
800 if (type_root
.InitTypeRoot(iter
.Get()) != BaseNode::INIT_OK
)
801 continue; // Don't try to reencrypt if the type's data is unavailable.
803 // Iterate through all children of this datatype.
804 std::queue
<int64
> to_visit
;
805 int64 child_id
= type_root
.GetFirstChildId();
806 to_visit
.push(child_id
);
807 while (!to_visit
.empty()) {
808 child_id
= to_visit
.front();
810 if (child_id
== kInvalidId
)
813 WriteNode
child(trans
);
814 if (child
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
)
815 continue; // Possible for locally deleted items.
816 if (child
.GetIsFolder()) {
817 to_visit
.push(child
.GetFirstChildId());
819 if (child
.GetEntry()->GetUniqueServerTag().empty()) {
820 // Rewrite the specifics of the node with encrypted data if necessary
821 // (only rewrite the non-unique folders).
822 child
.ResetFromSpecifics();
824 to_visit
.push(child
.GetSuccessorId());
828 // Passwords are encrypted with their own legacy scheme. Passwords are always
829 // encrypted so we don't need to check GetEncryptedTypes() here.
830 ReadNode
passwords_root(trans
);
831 if (passwords_root
.InitTypeRoot(PASSWORDS
) == BaseNode::INIT_OK
) {
832 int64 child_id
= passwords_root
.GetFirstChildId();
833 while (child_id
!= kInvalidId
) {
834 WriteNode
child(trans
);
835 if (child
.InitByIdLookup(child_id
) != BaseNode::INIT_OK
) {
839 child
.SetPasswordSpecifics(child
.GetPasswordSpecifics());
840 child_id
= child
.GetSuccessorId();
844 DVLOG(1) << "Re-encrypt everything complete.";
846 // NOTE: We notify from within a transaction.
847 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
848 OnEncryptionComplete());
851 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
852 const sync_pb::NigoriSpecifics
& nigori
,
853 syncable::BaseTransaction
* const trans
) {
854 DCHECK(thread_checker_
.CalledOnValidThread());
855 DVLOG(1) << "Applying nigori node update.";
856 bool nigori_types_need_update
= !UpdateEncryptedTypesFromNigori(nigori
,
859 if (nigori
.custom_passphrase_time() != 0) {
860 custom_passphrase_time_
=
861 ProtoTimeToTime(nigori
.custom_passphrase_time());
863 bool is_nigori_migrated
= IsNigoriMigratedToKeystore(nigori
);
864 if (is_nigori_migrated
) {
865 DCHECK(nigori
.has_keystore_migration_time());
866 migration_time_
= ProtoTimeToTime(nigori
.keystore_migration_time());
867 PassphraseType nigori_passphrase_type
=
868 ProtoPassphraseTypeToEnum(nigori
.passphrase_type());
870 // Only update the local passphrase state if it's a valid transition:
871 // - implicit -> keystore
872 // - implicit -> frozen implicit
873 // - implicit -> custom
874 // - keystore -> custom
875 // Note: frozen implicit -> custom is not technically a valid transition,
876 // but we let it through here as well in case future versions do add support
877 // for this transition.
878 if (passphrase_type_
!= nigori_passphrase_type
&&
879 nigori_passphrase_type
!= IMPLICIT_PASSPHRASE
&&
880 (passphrase_type_
== IMPLICIT_PASSPHRASE
||
881 nigori_passphrase_type
== CUSTOM_PASSPHRASE
)) {
882 DVLOG(1) << "Changing passphrase state from "
883 << PassphraseTypeToString(passphrase_type_
)
885 << PassphraseTypeToString(nigori_passphrase_type
);
886 passphrase_type_
= nigori_passphrase_type
;
887 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
888 OnPassphraseTypeChanged(
890 GetExplicitPassphraseTime()));
892 if (passphrase_type_
== KEYSTORE_PASSPHRASE
&& encrypt_everything_
) {
893 // This is the case where another client that didn't support keystore
894 // encryption attempted to enable full encryption. We detect it
895 // and switch the passphrase type to frozen implicit passphrase instead
896 // due to full encryption not being compatible with keystore passphrase.
897 // Because the local passphrase type will not match the nigori passphrase
898 // type, we will trigger a rewrite and subsequently a re-migration.
899 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
900 << "due to full encryption.";
901 passphrase_type_
= FROZEN_IMPLICIT_PASSPHRASE
;
902 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
903 OnPassphraseTypeChanged(
905 GetExplicitPassphraseTime()));
908 // It's possible that while we're waiting for migration a client that does
909 // not have keystore encryption enabled switches to a custom passphrase.
910 if (nigori
.keybag_is_frozen() &&
911 passphrase_type_
!= CUSTOM_PASSPHRASE
) {
912 passphrase_type_
= CUSTOM_PASSPHRASE
;
913 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
914 OnPassphraseTypeChanged(
916 GetExplicitPassphraseTime()));
920 Cryptographer
* cryptographer
= &UnlockVaultMutable(trans
)->cryptographer
;
921 bool nigori_needs_new_keys
= false;
922 if (!nigori
.encryption_keybag().blob().empty()) {
923 // We only update the default key if this was a new explicit passphrase.
924 // Else, since it was decryptable, it must not have been a new key.
925 bool need_new_default_key
= false;
926 if (is_nigori_migrated
) {
927 need_new_default_key
= IsExplicitPassphrase(
928 ProtoPassphraseTypeToEnum(nigori
.passphrase_type()));
930 need_new_default_key
= nigori
.keybag_is_frozen();
932 if (!AttemptToInstallKeybag(nigori
.encryption_keybag(),
933 need_new_default_key
,
935 // Check to see if we can decrypt the keybag using the keystore decryptor
937 cryptographer
->SetPendingKeys(nigori
.encryption_keybag());
938 if (!nigori
.keystore_decryptor_token().blob().empty() &&
939 !keystore_key_
.empty()) {
940 if (DecryptPendingKeysWithKeystoreKey(keystore_key_
,
941 nigori
.keystore_decryptor_token(),
943 nigori_needs_new_keys
=
944 cryptographer
->KeybagIsStale(nigori
.encryption_keybag());
946 LOG(ERROR
) << "Failed to decrypt pending keys using keystore "
951 // Keybag was installed. We write back our local keybag into the nigori
952 // node if the nigori node's keybag either contains less keys or
953 // has a different default key.
954 nigori_needs_new_keys
=
955 cryptographer
->KeybagIsStale(nigori
.encryption_keybag());
958 // The nigori node has an empty encryption keybag. Attempt to write our
959 // local encryption keys into it.
960 LOG(WARNING
) << "Nigori had empty encryption keybag.";
961 nigori_needs_new_keys
= true;
964 // If we've completed a sync cycle and the cryptographer isn't ready
965 // yet or has pending keys, prompt the user for a passphrase.
966 if (cryptographer
->has_pending_keys()) {
967 DVLOG(1) << "OnPassphraseRequired Sent";
968 sync_pb::EncryptedData pending_keys
= cryptographer
->GetPendingKeys();
969 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
970 OnPassphraseRequired(REASON_DECRYPTION
,
972 } else if (!cryptographer
->is_ready()) {
973 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
975 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
976 OnPassphraseRequired(REASON_ENCRYPTION
,
977 sync_pb::EncryptedData()));
980 // Check if the current local encryption state is stricter/newer than the
981 // nigori state. If so, we need to overwrite the nigori node with the local
983 bool passphrase_type_matches
= true;
984 if (!is_nigori_migrated
) {
985 DCHECK(passphrase_type_
== CUSTOM_PASSPHRASE
||
986 passphrase_type_
== IMPLICIT_PASSPHRASE
);
987 passphrase_type_matches
=
988 nigori
.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_
);
990 passphrase_type_matches
=
991 (ProtoPassphraseTypeToEnum(nigori
.passphrase_type()) ==
994 if (!passphrase_type_matches
||
995 nigori
.encrypt_everything() != encrypt_everything_
||
996 nigori_types_need_update
||
997 nigori_needs_new_keys
) {
998 DVLOG(1) << "Triggering nigori rewrite.";
1004 void SyncEncryptionHandlerImpl::RewriteNigori() {
1005 DVLOG(1) << "Writing local encryption state into nigori.";
1006 DCHECK(thread_checker_
.CalledOnValidThread());
1007 WriteTransaction
trans(FROM_HERE
, user_share_
);
1008 WriteEncryptionStateToNigori(&trans
);
1011 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
1012 WriteTransaction
* trans
) {
1013 DCHECK(thread_checker_
.CalledOnValidThread());
1014 WriteNode
nigori_node(trans
);
1015 // This can happen in tests that don't have nigori nodes.
1016 if (nigori_node
.InitTypeRoot(NIGORI
) != BaseNode::INIT_OK
)
1019 sync_pb::NigoriSpecifics nigori
= nigori_node
.GetNigoriSpecifics();
1020 const Cryptographer
& cryptographer
=
1021 UnlockVault(trans
->GetWrappedTrans()).cryptographer
;
1023 // Will not do anything if we shouldn't or can't migrate. Otherwise
1024 // migrates, writing the full encryption state as it does.
1025 if (!AttemptToMigrateNigoriToKeystore(trans
, &nigori_node
)) {
1026 if (cryptographer
.is_ready() &&
1027 nigori_overwrite_count_
< kNigoriOverwriteLimit
) {
1028 // Does not modify the encrypted blob if the unencrypted data already
1029 // matches what is about to be written.
1030 sync_pb::EncryptedData original_keys
= nigori
.encryption_keybag();
1031 if (!cryptographer
.GetKeys(nigori
.mutable_encryption_keybag()))
1034 if (nigori
.encryption_keybag().SerializeAsString() !=
1035 original_keys
.SerializeAsString()) {
1036 // We've updated the nigori node's encryption keys. In order to prevent
1037 // a possible looping of two clients constantly overwriting each other,
1038 // we limit the absolute number of overwrites per client instantiation.
1039 nigori_overwrite_count_
++;
1040 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
1041 nigori_overwrite_count_
);
1044 // Note: we don't try to set keybag_is_frozen here since if that
1045 // is lost the user can always set it again (and we don't want to clobber
1046 // any migration state). The main goal at this point is to preserve
1047 // the encryption keys so all data remains decryptable.
1049 syncable::UpdateNigoriFromEncryptedTypes(
1050 UnlockVault(trans
->GetWrappedTrans()).encrypted_types
,
1051 encrypt_everything_
,
1053 if (!custom_passphrase_time_
.is_null()) {
1054 nigori
.set_custom_passphrase_time(
1055 TimeToProtoTime(custom_passphrase_time_
));
1058 // If nothing has changed, this is a no-op.
1059 nigori_node
.SetNigoriSpecifics(nigori
);
1063 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
1064 const sync_pb::NigoriSpecifics
& nigori
,
1065 syncable::BaseTransaction
* const trans
) {
1066 DCHECK(thread_checker_
.CalledOnValidThread());
1067 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1068 if (nigori
.encrypt_everything()) {
1069 EnableEncryptEverythingImpl(trans
);
1070 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1072 } else if (encrypt_everything_
) {
1073 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1077 ModelTypeSet nigori_encrypted_types
;
1078 nigori_encrypted_types
= syncable::GetEncryptedTypesFromNigori(nigori
);
1079 nigori_encrypted_types
.PutAll(SensitiveTypes());
1081 // If anything more than the sensitive types were encrypted, and
1082 // encrypt_everything is not explicitly set to false, we assume it means
1083 // a client intended to enable encrypt everything.
1084 if (!nigori
.has_encrypt_everything() &&
1085 !Difference(nigori_encrypted_types
, SensitiveTypes()).Empty()) {
1086 if (!encrypt_everything_
) {
1087 encrypt_everything_
= true;
1088 *encrypted_types
= EncryptableUserTypes();
1090 Observer
, observers_
,
1091 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1093 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1097 MergeEncryptedTypes(nigori_encrypted_types
, trans
);
1098 return encrypted_types
->Equals(nigori_encrypted_types
);
1101 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
1102 const std::string
& passphrase
,
1103 WriteTransaction
* trans
,
1104 WriteNode
* nigori_node
) {
1105 DCHECK(thread_checker_
.CalledOnValidThread());
1106 DCHECK(IsNigoriMigratedToKeystore(nigori_node
->GetNigoriSpecifics()));
1107 KeyParams key_params
= {"localhost", "dummy", passphrase
};
1109 if (passphrase_type_
!= KEYSTORE_PASSPHRASE
) {
1110 DVLOG(1) << "Failing to set a custom passphrase because one has already "
1112 FinishSetPassphrase(false, std::string(), trans
, nigori_node
);
1116 Cryptographer
* cryptographer
=
1117 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1118 if (cryptographer
->has_pending_keys()) {
1119 // This theoretically shouldn't happen, because the only way to have pending
1120 // keys after migrating to keystore support is if a custom passphrase was
1121 // set, which should update passpshrase_state_ and should be caught by the
1122 // if statement above. For the sake of safety though, we check for it in
1123 // case a client is misbehaving.
1124 LOG(ERROR
) << "Failing to set custom passphrase because of pending keys.";
1125 FinishSetPassphrase(false, std::string(), trans
, nigori_node
);
1129 std::string bootstrap_token
;
1130 if (cryptographer
->AddKey(key_params
)) {
1131 DVLOG(1) << "Setting custom passphrase.";
1132 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1133 passphrase_type_
= CUSTOM_PASSPHRASE
;
1134 custom_passphrase_time_
= base::Time::Now();
1135 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1136 OnPassphraseTypeChanged(
1138 GetExplicitPassphraseTime()));
1140 NOTREACHED() << "Failed to add key to cryptographer.";
1143 FinishSetPassphrase(true, bootstrap_token
, trans
, nigori_node
);
1146 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
1147 const std::string
& passphrase
,
1148 WriteTransaction
* trans
,
1149 WriteNode
* nigori_node
) {
1150 DCHECK(thread_checker_
.CalledOnValidThread());
1151 DCHECK(IsExplicitPassphrase(passphrase_type_
));
1152 KeyParams key_params
= {"localhost", "dummy", passphrase
};
1154 Cryptographer
* cryptographer
=
1155 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1156 if (!cryptographer
->has_pending_keys()) {
1157 // Note that this *can* happen in a rare situation where data is
1158 // re-encrypted on another client while a SetDecryptionPassphrase() call is
1159 // in-flight on this client. It is rare enough that we choose to do nothing.
1160 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
1161 << "were no pending keys.";
1165 DCHECK(IsExplicitPassphrase(passphrase_type_
));
1166 bool success
= false;
1167 std::string bootstrap_token
;
1168 if (cryptographer
->DecryptPendingKeys(key_params
)) {
1169 DVLOG(1) << "Explicit passphrase accepted for decryption.";
1170 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1173 DVLOG(1) << "Explicit passphrase failed to decrypt.";
1176 if (success
&& !keystore_key_
.empty()) {
1177 // Should already be part of the encryption keybag, but we add it just
1179 KeyParams key_params
= {"localhost", "dummy", keystore_key_
};
1180 cryptographer
->AddNonDefaultKey(key_params
);
1182 FinishSetPassphrase(success
, bootstrap_token
, trans
, nigori_node
);
1185 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
1187 const std::string
& bootstrap_token
,
1188 WriteTransaction
* trans
,
1189 WriteNode
* nigori_node
) {
1190 DCHECK(thread_checker_
.CalledOnValidThread());
1192 SyncEncryptionHandler::Observer
,
1194 OnCryptographerStateChanged(
1195 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
));
1197 // It's possible we need to change the bootstrap token even if we failed to
1198 // set the passphrase (for example if we need to preserve the new GAIA
1200 if (!bootstrap_token
.empty()) {
1201 DVLOG(1) << "Passphrase bootstrap token updated.";
1202 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1203 OnBootstrapTokenUpdated(bootstrap_token
,
1204 PASSPHRASE_BOOTSTRAP_TOKEN
));
1207 const Cryptographer
& cryptographer
=
1208 UnlockVault(trans
->GetWrappedTrans()).cryptographer
;
1210 if (cryptographer
.is_ready()) {
1211 LOG(ERROR
) << "Attempt to change passphrase failed while cryptographer "
1213 } else if (cryptographer
.has_pending_keys()) {
1214 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1215 OnPassphraseRequired(REASON_DECRYPTION
,
1216 cryptographer
.GetPendingKeys()));
1218 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1219 OnPassphraseRequired(REASON_ENCRYPTION
,
1220 sync_pb::EncryptedData()));
1225 DCHECK(cryptographer
.is_ready());
1227 // Will do nothing if we're already properly migrated or unable to migrate
1228 // (in otherwords, if ShouldTriggerMigration is false).
1229 // Otherwise will update the nigori node with the current migrated state,
1230 // writing all encryption state as it does.
1231 if (!AttemptToMigrateNigoriToKeystore(trans
, nigori_node
)) {
1232 sync_pb::NigoriSpecifics
nigori(nigori_node
->GetNigoriSpecifics());
1233 // Does not modify nigori.encryption_keybag() if the original decrypted
1234 // data was the same.
1235 if (!cryptographer
.GetKeys(nigori
.mutable_encryption_keybag()))
1237 if (IsNigoriMigratedToKeystore(nigori
)) {
1238 DCHECK(keystore_key_
.empty() || IsExplicitPassphrase(passphrase_type_
));
1239 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1242 nigori
.set_keybag_is_frozen(
1243 IsExplicitPassphrase(passphrase_type_
));
1245 // If we set a new custom passphrase, store the timestamp.
1246 if (!custom_passphrase_time_
.is_null()) {
1247 nigori
.set_custom_passphrase_time(
1248 TimeToProtoTime(custom_passphrase_time_
));
1250 nigori_node
->SetNigoriSpecifics(nigori
);
1253 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
1254 // checks the passphrase state after it has been set.
1255 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1256 OnPassphraseAccepted());
1258 // Does nothing if everything is already encrypted.
1259 // TODO(zea): If we just migrated and enabled encryption, this will be
1260 // redundant. Figure out a way to not do this unnecessarily.
1261 ReEncryptEverything(trans
);
1264 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
1265 ModelTypeSet new_encrypted_types
,
1266 syncable::BaseTransaction
* const trans
) {
1267 DCHECK(thread_checker_
.CalledOnValidThread());
1269 // Only UserTypes may be encrypted.
1270 DCHECK(EncryptableUserTypes().HasAll(new_encrypted_types
));
1272 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1273 if (!encrypted_types
->HasAll(new_encrypted_types
)) {
1274 *encrypted_types
= new_encrypted_types
;
1276 Observer
, observers_
,
1277 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1281 SyncEncryptionHandlerImpl::Vault
* SyncEncryptionHandlerImpl::UnlockVaultMutable(
1282 syncable::BaseTransaction
* const trans
) {
1283 DCHECK_EQ(user_share_
->directory
.get(), trans
->directory());
1284 return &vault_unsafe_
;
1287 const SyncEncryptionHandlerImpl::Vault
& SyncEncryptionHandlerImpl::UnlockVault(
1288 syncable::BaseTransaction
* const trans
) const {
1289 DCHECK_EQ(user_share_
->directory
.get(), trans
->directory());
1290 return vault_unsafe_
;
1293 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1294 const sync_pb::NigoriSpecifics
& nigori
,
1295 const Cryptographer
& cryptographer
) const {
1296 DCHECK(thread_checker_
.CalledOnValidThread());
1297 // Don't migrate if there are pending encryption keys (because data
1298 // encrypted with the pending keys will not be decryptable).
1299 if (cryptographer
.has_pending_keys())
1301 if (IsNigoriMigratedToKeystore(nigori
)) {
1302 // If the nigori is already migrated but does not reflect the explicit
1303 // passphrase state, remigrate. Similarly, if the nigori has an explicit
1304 // passphrase but does not have full encryption, or the nigori has an
1305 // implicit passphrase but does have full encryption, re-migrate.
1306 // Note that this is to defend against other clients without keystore
1307 // encryption enabled transitioning to states that are no longer valid.
1308 if (passphrase_type_
!= KEYSTORE_PASSPHRASE
&&
1309 nigori
.passphrase_type() ==
1310 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE
) {
1312 } else if (IsExplicitPassphrase(passphrase_type_
) &&
1313 !encrypt_everything_
) {
1315 } else if (passphrase_type_
== KEYSTORE_PASSPHRASE
&&
1316 encrypt_everything_
) {
1319 cryptographer
.is_ready() &&
1320 !cryptographer
.CanDecryptUsingDefaultKey(nigori
.encryption_keybag())) {
1321 // We need to overwrite the keybag. This might involve overwriting the
1322 // keystore decryptor too.
1324 } else if (old_keystore_keys_
.size() > 0 && !keystore_key_
.empty()) {
1325 // Check to see if a server key rotation has happened, but the nigori
1326 // node's keys haven't been rotated yet, and hence we should re-migrate.
1327 // Note that once a key rotation has been performed, we no longer
1328 // preserve backwards compatibility, and the keybag will therefore be
1329 // encrypted with the current keystore key.
1330 Cryptographer
temp_cryptographer(cryptographer
.encryptor());
1331 KeyParams keystore_params
= {"localhost", "dummy", keystore_key_
};
1332 temp_cryptographer
.AddKey(keystore_params
);
1333 if (!temp_cryptographer
.CanDecryptUsingDefaultKey(
1334 nigori
.encryption_keybag())) {
1339 } else if (keystore_key_
.empty()) {
1340 // If we haven't already migrated, we don't want to do anything unless
1341 // a keystore key is available (so that those clients without keystore
1342 // encryption enabled aren't forced into new states, e.g. frozen implicit
1349 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1350 WriteTransaction
* trans
,
1351 WriteNode
* nigori_node
) {
1352 DCHECK(thread_checker_
.CalledOnValidThread());
1353 const sync_pb::NigoriSpecifics
& old_nigori
=
1354 nigori_node
->GetNigoriSpecifics();
1355 Cryptographer
* cryptographer
=
1356 &UnlockVaultMutable(trans
->GetWrappedTrans())->cryptographer
;
1358 if (!ShouldTriggerMigration(old_nigori
, *cryptographer
))
1361 DVLOG(1) << "Starting nigori migration to keystore support.";
1362 sync_pb::NigoriSpecifics
migrated_nigori(old_nigori
);
1364 PassphraseType new_passphrase_type
= passphrase_type_
;
1365 bool new_encrypt_everything
= encrypt_everything_
;
1366 if (encrypt_everything_
&& !IsExplicitPassphrase(passphrase_type_
)) {
1367 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1368 << "full encryption.";
1369 new_passphrase_type
= FROZEN_IMPLICIT_PASSPHRASE
;
1370 migrated_nigori
.clear_keystore_decryptor_token();
1371 } else if (IsExplicitPassphrase(passphrase_type_
)) {
1372 DVLOG_IF(1, !encrypt_everything_
) << "Enabling encrypt everything due to "
1373 << "explicit passphrase";
1374 new_encrypt_everything
= true;
1375 migrated_nigori
.clear_keystore_decryptor_token();
1377 DCHECK(!encrypt_everything_
);
1378 new_passphrase_type
= KEYSTORE_PASSPHRASE
;
1379 DVLOG(1) << "Switching to keystore passphrase state.";
1381 migrated_nigori
.set_encrypt_everything(new_encrypt_everything
);
1382 migrated_nigori
.set_passphrase_type(
1383 EnumPassphraseTypeToProto(new_passphrase_type
));
1384 migrated_nigori
.set_keybag_is_frozen(true);
1386 if (!keystore_key_
.empty()) {
1387 KeyParams key_params
= {"localhost", "dummy", keystore_key_
};
1388 if ((old_keystore_keys_
.size() > 0 &&
1389 new_passphrase_type
== KEYSTORE_PASSPHRASE
) ||
1390 !cryptographer
->is_initialized()) {
1391 // Either at least one key rotation has been performed, so we no longer
1392 // care about backwards compatibility, or we're generating keystore-based
1393 // encryption keys without knowing the GAIA password (and therefore the
1394 // cryptographer is not initialized), so we can't support backwards
1395 // compatibility. Ensure the keystore key is the default key.
1396 DVLOG(1) << "Migrating keybag to keystore key.";
1397 bool cryptographer_was_ready
= cryptographer
->is_ready();
1398 if (!cryptographer
->AddKey(key_params
)) {
1399 LOG(ERROR
) << "Failed to add keystore key as default key";
1400 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1401 FAILED_TO_SET_DEFAULT_KEYSTORE
,
1402 MIGRATION_RESULT_SIZE
);
1405 if (!cryptographer_was_ready
&& cryptographer
->is_ready()) {
1407 SyncEncryptionHandler::Observer
,
1409 OnPassphraseAccepted());
1412 // We're in backwards compatible mode -- either the account has an
1413 // explicit passphrase, or we want to preserve the current GAIA-based key
1414 // as the default because we can (there have been no key rotations since
1416 DVLOG(1) << "Migrating keybag while preserving old key";
1417 if (!cryptographer
->AddNonDefaultKey(key_params
)) {
1418 LOG(ERROR
) << "Failed to add keystore key as non-default key.";
1419 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1420 FAILED_TO_SET_NONDEFAULT_KEYSTORE
,
1421 MIGRATION_RESULT_SIZE
);
1426 if (!old_keystore_keys_
.empty()) {
1427 // Go through and add all the old keystore keys as non default keys, so
1428 // they'll be preserved in the encryption_keybag when we next write the
1430 for (std::vector
<std::string
>::const_iterator iter
=
1431 old_keystore_keys_
.begin(); iter
!= old_keystore_keys_
.end();
1433 KeyParams key_params
= {"localhost", "dummy", *iter
};
1434 cryptographer
->AddNonDefaultKey(key_params
);
1437 if (new_passphrase_type
== KEYSTORE_PASSPHRASE
&&
1438 !GetKeystoreDecryptor(
1441 migrated_nigori
.mutable_keystore_decryptor_token())) {
1442 LOG(ERROR
) << "Failed to extract keystore decryptor token.";
1443 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1444 FAILED_TO_EXTRACT_DECRYPTOR
,
1445 MIGRATION_RESULT_SIZE
);
1448 if (!cryptographer
->GetKeys(migrated_nigori
.mutable_encryption_keybag())) {
1449 LOG(ERROR
) << "Failed to extract encryption keybag.";
1450 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1451 FAILED_TO_EXTRACT_KEYBAG
,
1452 MIGRATION_RESULT_SIZE
);
1456 if (migration_time_
.is_null())
1457 migration_time_
= base::Time::Now();
1458 migrated_nigori
.set_keystore_migration_time(TimeToProtoTime(migration_time_
));
1460 if (!custom_passphrase_time_
.is_null()) {
1461 migrated_nigori
.set_custom_passphrase_time(
1462 TimeToProtoTime(custom_passphrase_time_
));
1466 SyncEncryptionHandler::Observer
,
1468 OnCryptographerStateChanged(cryptographer
));
1469 if (passphrase_type_
!= new_passphrase_type
) {
1470 passphrase_type_
= new_passphrase_type
;
1471 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer
, observers_
,
1472 OnPassphraseTypeChanged(
1474 GetExplicitPassphraseTime()));
1477 if (new_encrypt_everything
&& !encrypt_everything_
) {
1478 EnableEncryptEverythingImpl(trans
->GetWrappedTrans());
1479 ReEncryptEverything(trans
);
1480 } else if (!cryptographer
->CanDecryptUsingDefaultKey(
1481 old_nigori
.encryption_keybag())) {
1482 DVLOG(1) << "Rencrypting everything due to key rotation.";
1483 ReEncryptEverything(trans
);
1486 DVLOG(1) << "Completing nigori migration to keystore support.";
1487 nigori_node
->SetNigoriSpecifics(migrated_nigori
);
1489 switch (new_passphrase_type
) {
1490 case KEYSTORE_PASSPHRASE
:
1491 if (old_keystore_keys_
.size() > 0) {
1492 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1493 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT
,
1494 MIGRATION_RESULT_SIZE
);
1496 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1497 MIGRATION_SUCCESS_KEYSTORE_DEFAULT
,
1498 MIGRATION_RESULT_SIZE
);
1501 case FROZEN_IMPLICIT_PASSPHRASE
:
1502 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1503 MIGRATION_SUCCESS_FROZEN_IMPLICIT
,
1504 MIGRATION_RESULT_SIZE
);
1506 case CUSTOM_PASSPHRASE
:
1507 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1508 MIGRATION_SUCCESS_CUSTOM
,
1509 MIGRATION_RESULT_SIZE
);
1518 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1519 const Cryptographer
& cryptographer
,
1520 const std::string
& keystore_key
,
1521 sync_pb::EncryptedData
* encrypted_blob
) {
1522 DCHECK(thread_checker_
.CalledOnValidThread());
1523 DCHECK(!keystore_key
.empty());
1524 DCHECK(cryptographer
.is_ready());
1525 std::string serialized_nigori
;
1526 serialized_nigori
= cryptographer
.GetDefaultNigoriKeyData();
1527 if (serialized_nigori
.empty()) {
1528 LOG(ERROR
) << "Failed to get cryptographer bootstrap token.";
1531 Cryptographer
temp_cryptographer(cryptographer
.encryptor());
1532 KeyParams key_params
= {"localhost", "dummy", keystore_key
};
1533 if (!temp_cryptographer
.AddKey(key_params
))
1535 if (!temp_cryptographer
.EncryptString(serialized_nigori
, encrypted_blob
))
1540 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1541 const sync_pb::EncryptedData
& keybag
,
1542 bool update_default
,
1543 Cryptographer
* cryptographer
) {
1544 if (!cryptographer
->CanDecrypt(keybag
))
1546 cryptographer
->InstallKeys(keybag
);
1548 cryptographer
->SetDefaultKey(keybag
.key_name());
1552 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1553 syncable::BaseTransaction
* const trans
) {
1554 ModelTypeSet
* encrypted_types
= &UnlockVaultMutable(trans
)->encrypted_types
;
1555 if (encrypt_everything_
) {
1556 DCHECK(encrypted_types
->Equals(EncryptableUserTypes()));
1559 encrypt_everything_
= true;
1560 *encrypted_types
= EncryptableUserTypes();
1562 Observer
, observers_
,
1563 OnEncryptedTypesChanged(*encrypted_types
, encrypt_everything_
));
1566 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1567 const std::string
& keystore_key
,
1568 const sync_pb::EncryptedData
& keystore_decryptor_token
,
1569 Cryptographer
* cryptographer
) {
1570 DCHECK(cryptographer
->has_pending_keys());
1571 if (keystore_decryptor_token
.blob().empty())
1573 Cryptographer
temp_cryptographer(cryptographer
->encryptor());
1575 // First, go through and all all the old keystore keys to the temporary
1577 for (size_t i
= 0; i
< old_keystore_keys_
.size(); ++i
) {
1578 KeyParams old_key_params
= {"localhost", "dummy", old_keystore_keys_
[i
]};
1579 temp_cryptographer
.AddKey(old_key_params
);
1582 // Then add the current keystore key as the default key and see if we can
1584 KeyParams keystore_params
= {"localhost", "dummy", keystore_key_
};
1585 if (temp_cryptographer
.AddKey(keystore_params
) &&
1586 temp_cryptographer
.CanDecrypt(keystore_decryptor_token
)) {
1587 // Someone else migrated the nigori for us! How generous! Go ahead and
1588 // install both the keystore key and the new default encryption key
1589 // (i.e. the one provided by the keystore decryptor token) into the
1591 // The keystore decryptor token is a keystore key encrypted blob containing
1592 // the current serialized default encryption key (and as such should be
1593 // able to decrypt the nigori node's encryption keybag).
1594 // Note: it's possible a key rotation has happened since the migration, and
1595 // we're decrypting using an old keystore key. In that case we need to
1596 // ensure we re-encrypt using the newest key.
1597 DVLOG(1) << "Attempting to decrypt pending keys using "
1598 << "keystore decryptor token.";
1599 std::string serialized_nigori
=
1600 temp_cryptographer
.DecryptToString(keystore_decryptor_token
);
1602 // This will decrypt the pending keys and add them if possible. The key
1603 // within |serialized_nigori| will be the default after.
1604 cryptographer
->ImportNigoriKey(serialized_nigori
);
1606 if (!temp_cryptographer
.CanDecryptUsingDefaultKey(
1607 keystore_decryptor_token
)) {
1608 // The keystore decryptor token was derived from an old keystore key.
1609 // A key rotation is necessary, so set the current keystore key as the
1610 // default key (which will trigger a re-migration).
1611 DVLOG(1) << "Pending keys based on old keystore key. Setting newest "
1612 << "keystore key as default.";
1613 cryptographer
->AddKey(keystore_params
);
1615 // Theoretically the encryption keybag should already contain the keystore
1616 // key. We explicitly add it as a safety measure.
1617 DVLOG(1) << "Pending keys based on newest keystore key.";
1618 cryptographer
->AddNonDefaultKey(keystore_params
);
1620 if (cryptographer
->is_ready()) {
1621 std::string bootstrap_token
;
1622 cryptographer
->GetBootstrapToken(&bootstrap_token
);
1623 DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1625 SyncEncryptionHandler::Observer
,
1627 OnPassphraseAccepted());
1629 SyncEncryptionHandler::Observer
,
1631 OnBootstrapTokenUpdated(bootstrap_token
,
1632 PASSPHRASE_BOOTSTRAP_TOKEN
));
1634 SyncEncryptionHandler::Observer
,
1636 OnCryptographerStateChanged(cryptographer
));
1643 base::Time
SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const {
1644 if (passphrase_type_
== FROZEN_IMPLICIT_PASSPHRASE
)
1645 return migration_time();
1646 else if (passphrase_type_
== CUSTOM_PASSPHRASE
)
1647 return custom_passphrase_time();
1648 return base::Time();
1651 } // namespace browser_sync