• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "sync/internal_api/sync_encryption_handler_impl.h"
6 
7 #include <queue>
8 #include <string>
9 
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"
34 
35 namespace syncer {
36 
37 namespace {
38 
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;
45 
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,
57 };
58 
59 enum NigoriMigrationState {
60   MIGRATED,
61   NOT_MIGRATED_CRYPTO_NOT_READY,
62   NOT_MIGRATED_NO_KEYSTORE_KEY,
63   NOT_MIGRATED_UNKNOWN_REASON,
64   MIGRATION_STATE_SIZE,
65 };
66 
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.
IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics & nigori)74 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) {
75   if (!nigori.has_passphrase_type())
76     return false;
77   if (!nigori.has_keystore_migration_time())
78     return false;
79   if (!nigori.keybag_is_frozen())
80     return false;
81   if (nigori.passphrase_type() ==
82           sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)
83     return false;
84   if (nigori.passphrase_type() ==
85           sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
86       nigori.keystore_decryptor_token().blob().empty())
87     return false;
88   if (!nigori.has_keystore_migration_time())
89     return false;
90   return true;
91 }
92 
ProtoPassphraseTypeToEnum(sync_pb::NigoriSpecifics::PassphraseType type)93 PassphraseType ProtoPassphraseTypeToEnum(
94     sync_pb::NigoriSpecifics::PassphraseType type) {
95   switch(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;
104     default:
105       NOTREACHED();
106       return IMPLICIT_PASSPHRASE;
107   };
108 }
109 
110 sync_pb::NigoriSpecifics::PassphraseType
EnumPassphraseTypeToProto(PassphraseType type)111 EnumPassphraseTypeToProto(PassphraseType type) {
112   switch(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;
121     default:
122       NOTREACHED();
123       return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
124   };
125 }
126 
IsExplicitPassphrase(PassphraseType type)127 bool IsExplicitPassphrase(PassphraseType type) {
128   return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE;
129 }
130 
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.
PackKeystoreBootstrapToken(const std::vector<std::string> & old_keystore_keys,const std::string & current_keystore_key,Encryptor * encryptor)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();
140 
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);
145 
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;
158 }
159 
UnpackKeystoreBootstrapToken(const std::string & keystore_bootstrap_token,Encryptor * encryptor,std::vector<std::string> * old_keystore_keys,std::string * current_keystore_key)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())
166     return false;
167   std::string base64_decoded_keystore_bootstrap;
168   if (!base::Base64Decode(keystore_bootstrap_token,
169                           &base64_decoded_keystore_bootstrap)) {
170     return false;
171   }
172   std::string decrypted_keystore_bootstrap;
173   if (!encryptor->DecryptString(base64_decoded_keystore_bootstrap,
174                                 &decrypted_keystore_bootstrap)) {
175     return false;
176   }
177   JSONStringValueSerializer json(&decrypted_keystore_bootstrap);
178   scoped_ptr<base::Value> deserialized_keystore_keys(
179       json.Deserialize(NULL, NULL));
180   if (!deserialized_keystore_keys)
181     return false;
182   base::ListValue* internal_list_value = NULL;
183   if (!deserialized_keystore_keys->GetAsList(&internal_list_value))
184     return false;
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)) {
188     return false;
189   }
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]);
193   return true;
194 }
195 
196 }  // namespace
197 
Vault(Encryptor * encryptor,ModelTypeSet encrypted_types)198 SyncEncryptionHandlerImpl::Vault::Vault(
199     Encryptor* encryptor,
200     ModelTypeSet encrypted_types)
201     : cryptographer(encryptor),
202       encrypted_types(encrypted_types) {
203 }
204 
~Vault()205 SyncEncryptionHandlerImpl::Vault::~Vault() {
206 }
207 
SyncEncryptionHandlerImpl(UserShare * user_share,Encryptor * encryptor,const std::string & restored_key_for_bootstrapping,const std::string & restored_keystore_key_for_bootstrapping)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);
222 
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,
227       encryptor,
228       &old_keystore_keys_,
229       &keystore_key_);
230 }
231 
~SyncEncryptionHandlerImpl()232 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
233 
AddObserver(Observer * observer)234 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
235   DCHECK(thread_checker_.CalledOnValidThread());
236   DCHECK(!observers_.HasObserver(observer));
237   observers_.AddObserver(observer);
238 }
239 
RemoveObserver(Observer * observer)240 void SyncEncryptionHandlerImpl::RemoveObserver(Observer* observer) {
241   DCHECK(thread_checker_.CalledOnValidThread());
242   DCHECK(observers_.HasObserver(observer));
243   observers_.RemoveObserver(observer);
244 }
245 
Init()246 void SyncEncryptionHandlerImpl::Init() {
247   DCHECK(thread_checker_.CalledOnValidThread());
248   WriteTransaction trans(FROM_HERE, user_share_);
249   WriteNode node(&trans);
250 
251   if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
252     return;
253   if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(),
254                              trans.GetWrappedTrans())) {
255     WriteEncryptionStateToNigori(&trans);
256   }
257 
258   bool has_pending_keys = UnlockVault(
259       trans.GetWrappedTrans()).cryptographer.has_pending_keys();
260   bool is_ready = UnlockVault(
261       trans.GetWrappedTrans()).cryptographer.is_ready();
262   // Log the state of the cryptographer regardless of migration state.
263   UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready);
264   UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys);
265   if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
266     // This account has a nigori node that has been migrated to support
267     // keystore.
268     UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
269                               MIGRATED,
270                               MIGRATION_STATE_SIZE);
271     if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) {
272       // If this is happening, it means the keystore decryptor is either
273       // undecryptable with the available keystore keys or does not match the
274       // nigori keybag's encryption key. Otherwise we're simply missing the
275       // keystore key.
276       UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed",
277                             !keystore_key_.empty());
278     }
279   } else if (!is_ready) {
280     // Migration cannot occur until the cryptographer is ready (initialized
281     // with GAIA password and any pending keys resolved).
282     UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
283                               NOT_MIGRATED_CRYPTO_NOT_READY,
284                               MIGRATION_STATE_SIZE);
285   } else if (keystore_key_.empty()) {
286     // The client has no keystore key, either because it is not yet enabled or
287     // the server is not sending a valid keystore key.
288     UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
289                               NOT_MIGRATED_NO_KEYSTORE_KEY,
290                               MIGRATION_STATE_SIZE);
291   } else {
292     // If the above conditions have been met and the nigori node is still not
293     // migrated, something failed in the migration process.
294     UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState",
295                               NOT_MIGRATED_UNKNOWN_REASON,
296                               MIGRATION_STATE_SIZE);
297   }
298 
299 
300   // Always trigger an encrypted types and cryptographer state change event at
301   // init time so observers get the initial values.
302   FOR_EACH_OBSERVER(
303       Observer, observers_,
304       OnEncryptedTypesChanged(
305           UnlockVault(trans.GetWrappedTrans()).encrypted_types,
306           encrypt_everything_));
307   FOR_EACH_OBSERVER(
308       SyncEncryptionHandler::Observer,
309       observers_,
310       OnCryptographerStateChanged(
311           &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer));
312 
313   // If the cryptographer is not ready (either it has pending keys or we
314   // failed to initialize it), we don't want to try and re-encrypt the data.
315   // If we had encrypted types, the DataTypeManager will block, preventing
316   // sync from happening until the the passphrase is provided.
317   if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
318     ReEncryptEverything(&trans);
319 }
320 
SetEncryptionPassphrase(const std::string & passphrase,bool is_explicit)321 void SyncEncryptionHandlerImpl::SetEncryptionPassphrase(
322     const std::string& passphrase,
323     bool is_explicit) {
324   DCHECK(thread_checker_.CalledOnValidThread());
325   // We do not accept empty passphrases.
326   if (passphrase.empty()) {
327     NOTREACHED() << "Cannot encrypt with an empty passphrase.";
328     return;
329   }
330 
331   // All accesses to the cryptographer are protected by a transaction.
332   WriteTransaction trans(FROM_HERE, user_share_);
333   KeyParams key_params = {"localhost", "dummy", passphrase};
334   WriteNode node(&trans);
335   if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
336     NOTREACHED();
337     return;
338   }
339 
340   Cryptographer* cryptographer =
341       &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
342 
343   // Once we've migrated to keystore, the only way to set a passphrase for
344   // encryption is to set a custom passphrase.
345   if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
346     if (!is_explicit) {
347       DCHECK(cryptographer->is_ready());
348       // The user is setting a new implicit passphrase. At this point we don't
349       // care, so drop it on the floor. This is safe because if we have a
350       // migrated nigori node, then we don't need to create an initial
351       // encryption key.
352       LOG(WARNING) << "Ignoring new implicit passphrase. Keystore migration "
353                    << "already performed.";
354       return;
355     }
356     // Will fail if we already have an explicit passphrase or we have pending
357     // keys.
358     SetCustomPassphrase(passphrase, &trans, &node);
359 
360     // When keystore migration occurs, the "CustomEncryption" UMA stat must be
361     // logged as true.
362     UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", true);
363     return;
364   }
365 
366   std::string bootstrap_token;
367   sync_pb::EncryptedData pending_keys;
368   if (cryptographer->has_pending_keys())
369     pending_keys = cryptographer->GetPendingKeys();
370   bool success = false;
371 
372   // There are six cases to handle here:
373   // 1. The user has no pending keys and is setting their current GAIA password
374   //    as the encryption passphrase. This happens either during first time sync
375   //    with a clean profile, or after re-authenticating on a profile that was
376   //    already signed in with the cryptographer ready.
377   // 2. The user has no pending keys, and is overwriting an (already provided)
378   //    implicit passphrase with an explicit (custom) passphrase.
379   // 3. The user has pending keys for an explicit passphrase that is somehow set
380   //    to their current GAIA passphrase.
381   // 4. The user has pending keys encrypted with their current GAIA passphrase
382   //    and the caller passes in the current GAIA passphrase.
383   // 5. The user has pending keys encrypted with an older GAIA passphrase
384   //    and the caller passes in the current GAIA passphrase.
385   // 6. The user has previously done encryption with an explicit passphrase.
386   // Furthermore, we enforce the fact that the bootstrap encryption token will
387   // always be derived from the newest GAIA password if the account is using
388   // an implicit passphrase (even if the data is encrypted with an old GAIA
389   // password). If the account is using an explicit (custom) passphrase, the
390   // bootstrap token will be derived from the most recently provided explicit
391   // passphrase (that was able to decrypt the data).
392   if (!IsExplicitPassphrase(passphrase_type_)) {
393     if (!cryptographer->has_pending_keys()) {
394       if (cryptographer->AddKey(key_params)) {
395         // Case 1 and 2. We set a new GAIA passphrase when there are no pending
396         // keys (1), or overwriting an implicit passphrase with a new explicit
397         // one (2) when there are no pending keys.
398         if (is_explicit) {
399           DVLOG(1) << "Setting explicit passphrase for encryption.";
400           passphrase_type_ = CUSTOM_PASSPHRASE;
401           custom_passphrase_time_ = base::Time::Now();
402           FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
403                             OnPassphraseTypeChanged(
404                                 passphrase_type_,
405                                 GetExplicitPassphraseTime()));
406         } else {
407           DVLOG(1) << "Setting implicit passphrase for encryption.";
408         }
409         cryptographer->GetBootstrapToken(&bootstrap_token);
410 
411         // With M26, sync accounts can be in only one of two encryption states:
412         // 1) Encrypt only passwords with an implicit passphrase.
413         // 2) Encrypt all sync datatypes with an explicit passphrase.
414         // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms,
415         // and keep track of an account's encryption state via the
416         // "CustomEncryption" histogram. See http://crbug.com/131478.
417         UMA_HISTOGRAM_BOOLEAN("Sync.CustomEncryption", is_explicit);
418 
419         success = true;
420       } else {
421         NOTREACHED() << "Failed to add key to cryptographer.";
422         success = false;
423       }
424     } else {  // cryptographer->has_pending_keys() == true
425       if (is_explicit) {
426         // This can only happen if the nigori node is updated with a new
427         // implicit passphrase while a client is attempting to set a new custom
428         // passphrase (race condition).
429         DVLOG(1) << "Failing because an implicit passphrase is already set.";
430         success = false;
431       } else {  // is_explicit == false
432         if (cryptographer->DecryptPendingKeys(key_params)) {
433           // Case 4. We successfully decrypted with the implicit GAIA passphrase
434           // passed in.
435           DVLOG(1) << "Implicit internal passphrase accepted for decryption.";
436           cryptographer->GetBootstrapToken(&bootstrap_token);
437           success = true;
438         } else {
439           // Case 5. Encryption was done with an old GAIA password, but we were
440           // provided with the current GAIA password. We need to generate a new
441           // bootstrap token to preserve it. We build a temporary cryptographer
442           // to allow us to extract these params without polluting our current
443           // cryptographer.
444           DVLOG(1) << "Implicit internal passphrase failed to decrypt, adding "
445                    << "anyways as default passphrase and persisting via "
446                    << "bootstrap token.";
447           Cryptographer temp_cryptographer(cryptographer->encryptor());
448           temp_cryptographer.AddKey(key_params);
449           temp_cryptographer.GetBootstrapToken(&bootstrap_token);
450           // We then set the new passphrase as the default passphrase of the
451           // real cryptographer, even though we have pending keys. This is safe,
452           // as although Cryptographer::is_initialized() will now be true,
453           // is_ready() will remain false due to having pending keys.
454           cryptographer->AddKey(key_params);
455           success = false;
456         }
457       }  // is_explicit
458     }  // cryptographer->has_pending_keys()
459   } else {  // IsExplicitPassphrase(passphrase_type_) == true.
460     // Case 6. We do not want to override a previously set explicit passphrase,
461     // so we return a failure.
462     DVLOG(1) << "Failing because an explicit passphrase is already set.";
463     success = false;
464   }
465 
466   DVLOG_IF(1, !success)
467       << "Failure in SetEncryptionPassphrase; notifying and returning.";
468   DVLOG_IF(1, success)
469       << "Successfully set encryption passphrase; updating nigori and "
470          "reencrypting.";
471 
472   FinishSetPassphrase(success, bootstrap_token, &trans, &node);
473 }
474 
SetDecryptionPassphrase(const std::string & passphrase)475 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
476     const std::string& passphrase) {
477   DCHECK(thread_checker_.CalledOnValidThread());
478   // We do not accept empty passphrases.
479   if (passphrase.empty()) {
480     NOTREACHED() << "Cannot decrypt with an empty passphrase.";
481     return;
482   }
483 
484   // All accesses to the cryptographer are protected by a transaction.
485   WriteTransaction trans(FROM_HERE, user_share_);
486   KeyParams key_params = {"localhost", "dummy", passphrase};
487   WriteNode node(&trans);
488   if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
489     NOTREACHED();
490     return;
491   }
492 
493   // Once we've migrated to keystore, we're only ever decrypting keys derived
494   // from an explicit passphrase. But, for clients without a keystore key yet
495   // (either not on by default or failed to download one), we still support
496   // decrypting with a gaia passphrase, and therefore bypass the
497   // DecryptPendingKeysWithExplicitPassphrase logic.
498   if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
499       IsExplicitPassphrase(passphrase_type_)) {
500     DecryptPendingKeysWithExplicitPassphrase(passphrase, &trans, &node);
501     return;
502   }
503 
504   Cryptographer* cryptographer =
505       &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
506   if (!cryptographer->has_pending_keys()) {
507     // Note that this *can* happen in a rare situation where data is
508     // re-encrypted on another client while a SetDecryptionPassphrase() call is
509     // in-flight on this client. It is rare enough that we choose to do nothing.
510     NOTREACHED() << "Attempt to set decryption passphrase failed because there "
511                  << "were no pending keys.";
512     return;
513   }
514 
515   std::string bootstrap_token;
516   sync_pb::EncryptedData pending_keys;
517   pending_keys = cryptographer->GetPendingKeys();
518   bool success = false;
519 
520   // There are three cases to handle here:
521   // 7. We're using the current GAIA password to decrypt the pending keys. This
522   //    happens when signing in to an account with a previously set implicit
523   //    passphrase, where the data is already encrypted with the newest GAIA
524   //    password.
525   // 8. The user is providing an old GAIA password to decrypt the pending keys.
526   //    In this case, the user is using an implicit passphrase, but has changed
527   //    their password since they last encrypted their data, and therefore
528   //    their current GAIA password was unable to decrypt the data. This will
529   //    happen when the user is setting up a new profile with a previously
530   //    encrypted account (after changing passwords).
531   // 9. The user is providing a previously set explicit passphrase to decrypt
532   //    the pending keys.
533   if (!IsExplicitPassphrase(passphrase_type_)) {
534     if (cryptographer->is_initialized()) {
535       // We only want to change the default encryption key to the pending
536       // one if the pending keybag already contains the current default.
537       // This covers the case where a different client re-encrypted
538       // everything with a newer gaia passphrase (and hence the keybag
539       // contains keys from all previously used gaia passphrases).
540       // Otherwise, we're in a situation where the pending keys are
541       // encrypted with an old gaia passphrase, while the default is the
542       // current gaia passphrase. In that case, we preserve the default.
543       Cryptographer temp_cryptographer(cryptographer->encryptor());
544       temp_cryptographer.SetPendingKeys(cryptographer->GetPendingKeys());
545       if (temp_cryptographer.DecryptPendingKeys(key_params)) {
546         // Check to see if the pending bag of keys contains the current
547         // default key.
548         sync_pb::EncryptedData encrypted;
549         cryptographer->GetKeys(&encrypted);
550         if (temp_cryptographer.CanDecrypt(encrypted)) {
551           DVLOG(1) << "Implicit user provided passphrase accepted for "
552                    << "decryption, overwriting default.";
553           // Case 7. The pending keybag contains the current default. Go ahead
554           // and update the cryptographer, letting the default change.
555           cryptographer->DecryptPendingKeys(key_params);
556           cryptographer->GetBootstrapToken(&bootstrap_token);
557           success = true;
558         } else {
559           // Case 8. The pending keybag does not contain the current default
560           // encryption key. We decrypt the pending keys here, and in
561           // FinishSetPassphrase, re-encrypt everything with the current GAIA
562           // passphrase instead of the passphrase just provided by the user.
563           DVLOG(1) << "Implicit user provided passphrase accepted for "
564                    << "decryption, restoring implicit internal passphrase "
565                    << "as default.";
566           std::string bootstrap_token_from_current_key;
567           cryptographer->GetBootstrapToken(
568               &bootstrap_token_from_current_key);
569           cryptographer->DecryptPendingKeys(key_params);
570           // Overwrite the default from the pending keys.
571           cryptographer->AddKeyFromBootstrapToken(
572               bootstrap_token_from_current_key);
573           success = true;
574         }
575       } else {  // !temp_cryptographer.DecryptPendingKeys(..)
576         DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
577         success = false;
578       }  // temp_cryptographer.DecryptPendingKeys(...)
579     } else {  // cryptographer->is_initialized() == false
580       if (cryptographer->DecryptPendingKeys(key_params)) {
581         // This can happpen in two cases:
582         // - First time sync on android, where we'll never have a
583         //   !user_provided passphrase.
584         // - This is a restart for a client that lost their bootstrap token.
585         // In both cases, we should go ahead and initialize the cryptographer
586         // and persist the new bootstrap token.
587         //
588         // Note: at this point, we cannot distinguish between cases 7 and 8
589         // above. This user provided passphrase could be the current or the
590         // old. But, as long as we persist the token, there's nothing more
591         // we can do.
592         cryptographer->GetBootstrapToken(&bootstrap_token);
593         DVLOG(1) << "Implicit user provided passphrase accepted, initializing"
594                  << " cryptographer.";
595         success = true;
596       } else {
597         DVLOG(1) << "Implicit user provided passphrase failed to decrypt.";
598         success = false;
599       }
600     }  // cryptographer->is_initialized()
601   } else {  // nigori_has_explicit_passphrase == true
602     // Case 9. Encryption was done with an explicit passphrase, and we decrypt
603     // with the passphrase provided by the user.
604     if (cryptographer->DecryptPendingKeys(key_params)) {
605       DVLOG(1) << "Explicit passphrase accepted for decryption.";
606       cryptographer->GetBootstrapToken(&bootstrap_token);
607       success = true;
608     } else {
609       DVLOG(1) << "Explicit passphrase failed to decrypt.";
610       success = false;
611     }
612   }  // nigori_has_explicit_passphrase
613 
614   DVLOG_IF(1, !success)
615       << "Failure in SetDecryptionPassphrase; notifying and returning.";
616   DVLOG_IF(1, success)
617       << "Successfully set decryption passphrase; updating nigori and "
618          "reencrypting.";
619 
620   FinishSetPassphrase(success, bootstrap_token, &trans, &node);
621 }
622 
EnableEncryptEverything()623 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
624   DCHECK(thread_checker_.CalledOnValidThread());
625   WriteTransaction trans(FROM_HERE, user_share_);
626   DVLOG(1) << "Enabling encrypt everything.";
627   if (encrypt_everything_)
628     return;
629   EnableEncryptEverythingImpl(trans.GetWrappedTrans());
630   WriteEncryptionStateToNigori(&trans);
631   if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
632     ReEncryptEverything(&trans);
633 }
634 
EncryptEverythingEnabled() const635 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
636   DCHECK(thread_checker_.CalledOnValidThread());
637   return encrypt_everything_;
638 }
639 
GetPassphraseType() const640 PassphraseType SyncEncryptionHandlerImpl::GetPassphraseType() const {
641   DCHECK(thread_checker_.CalledOnValidThread());
642   return passphrase_type_;
643 }
644 
645 // Note: this is called from within a syncable transaction, so we need to post
646 // tasks if we want to do any work that creates a new sync_api transaction.
ApplyNigoriUpdate(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)647 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
648     const sync_pb::NigoriSpecifics& nigori,
649     syncable::BaseTransaction* const trans) {
650   DCHECK(thread_checker_.CalledOnValidThread());
651   DCHECK(trans);
652   if (!ApplyNigoriUpdateImpl(nigori, trans)) {
653     base::MessageLoop::current()->PostTask(
654         FROM_HERE,
655         base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
656                    weak_ptr_factory_.GetWeakPtr()));
657   }
658 
659   FOR_EACH_OBSERVER(
660       SyncEncryptionHandler::Observer,
661       observers_,
662       OnCryptographerStateChanged(
663           &UnlockVaultMutable(trans)->cryptographer));
664 }
665 
UpdateNigoriFromEncryptedTypes(sync_pb::NigoriSpecifics * nigori,syncable::BaseTransaction * const trans) const666 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
667     sync_pb::NigoriSpecifics* nigori,
668     syncable::BaseTransaction* const trans) const {
669   DCHECK(thread_checker_.CalledOnValidThread());
670   syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types,
671                                            encrypt_everything_,
672                                            nigori);
673 }
674 
NeedKeystoreKey(syncable::BaseTransaction * const trans) const675 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
676     syncable::BaseTransaction* const trans) const {
677   DCHECK(thread_checker_.CalledOnValidThread());
678   return keystore_key_.empty();
679 }
680 
SetKeystoreKeys(const google::protobuf::RepeatedPtrField<google::protobuf::string> & keys,syncable::BaseTransaction * const trans)681 bool SyncEncryptionHandlerImpl::SetKeystoreKeys(
682     const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
683     syncable::BaseTransaction* const trans) {
684   DCHECK(thread_checker_.CalledOnValidThread());
685   if (keys.size() == 0)
686     return false;
687   // The last key in the vector is the current keystore key. The others are kept
688   // around for decryption only.
689   const std::string& raw_keystore_key = keys.Get(keys.size() - 1);
690   if (raw_keystore_key.empty())
691     return false;
692 
693   // Note: in order to Pack the keys, they must all be base64 encoded (else
694   // JSON serialization fails).
695   base::Base64Encode(raw_keystore_key, &keystore_key_);
696 
697   // Go through and save the old keystore keys. We always persist all keystore
698   // keys the server sends us.
699   old_keystore_keys_.resize(keys.size() - 1);
700   for (int i = 0; i < keys.size() - 1; ++i)
701     base::Base64Encode(keys.Get(i), &old_keystore_keys_[i]);
702 
703   Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
704 
705   // Update the bootstrap token. If this fails, we persist an empty string,
706   // which will force us to download the keystore keys again on the next
707   // restart.
708   std::string keystore_bootstrap = PackKeystoreBootstrapToken(
709       old_keystore_keys_,
710       keystore_key_,
711       cryptographer->encryptor());
712   DCHECK_EQ(keystore_bootstrap.empty(), keystore_key_.empty());
713   FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
714                     OnBootstrapTokenUpdated(keystore_bootstrap,
715                                             KEYSTORE_BOOTSTRAP_TOKEN));
716   DVLOG(1) << "Keystore bootstrap token updated.";
717 
718   // If this is a first time sync, we get the encryption keys before we process
719   // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked
720   // once we have the nigori node.
721   syncable::Entry entry(trans, syncable::GET_BY_SERVER_TAG, kNigoriTag);
722   if (!entry.good())
723     return true;
724 
725   const sync_pb::NigoriSpecifics& nigori =
726       entry.GetSpecifics().nigori();
727   if (cryptographer->has_pending_keys() &&
728       IsNigoriMigratedToKeystore(nigori) &&
729       !nigori.keystore_decryptor_token().blob().empty()) {
730     // If the nigori is already migrated and we have pending keys, we might
731     // be able to decrypt them using either the keystore decryptor token
732     // or the existing keystore keys.
733     DecryptPendingKeysWithKeystoreKey(keystore_key_,
734                                       nigori.keystore_decryptor_token(),
735                                       cryptographer);
736   }
737 
738   // Note that triggering migration will have no effect if we're already
739   // properly migrated with the newest keystore keys.
740   if (ShouldTriggerMigration(nigori, *cryptographer)) {
741     base::MessageLoop::current()->PostTask(
742         FROM_HERE,
743         base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
744                    weak_ptr_factory_.GetWeakPtr()));
745   }
746 
747   return true;
748 }
749 
GetEncryptedTypes(syncable::BaseTransaction * const trans) const750 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes(
751     syncable::BaseTransaction* const trans) const {
752   return UnlockVault(trans).encrypted_types;
753 }
754 
GetCryptographerUnsafe()755 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
756   DCHECK(thread_checker_.CalledOnValidThread());
757   return &vault_unsafe_.cryptographer;
758 }
759 
GetEncryptedTypesUnsafe()760 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
761   DCHECK(thread_checker_.CalledOnValidThread());
762   return vault_unsafe_.encrypted_types;
763 }
764 
MigratedToKeystore()765 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
766   DCHECK(thread_checker_.CalledOnValidThread());
767   ReadTransaction trans(FROM_HERE, user_share_);
768   ReadNode nigori_node(&trans);
769   if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
770     return false;
771   return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
772 }
773 
migration_time() const774 base::Time SyncEncryptionHandlerImpl::migration_time() const {
775   return migration_time_;
776 }
777 
custom_passphrase_time() const778 base::Time SyncEncryptionHandlerImpl::custom_passphrase_time() const {
779   return custom_passphrase_time_;
780 }
781 
782 // This function iterates over all encrypted types.  There are many scenarios in
783 // which data for some or all types is not currently available.  In that case,
784 // the lookup of the root node will fail and we will skip encryption for that
785 // type.
ReEncryptEverything(WriteTransaction * trans)786 void SyncEncryptionHandlerImpl::ReEncryptEverything(
787     WriteTransaction* trans) {
788   DCHECK(thread_checker_.CalledOnValidThread());
789   DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
790   for (ModelTypeSet::Iterator iter =
791            UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
792        iter.Good(); iter.Inc()) {
793     if (iter.Get() == PASSWORDS || IsControlType(iter.Get()))
794       continue; // These types handle encryption differently.
795 
796     ReadNode type_root(trans);
797     std::string tag = ModelTypeToRootTag(iter.Get());
798     if (type_root.InitByTagLookup(tag) != BaseNode::INIT_OK)
799       continue; // Don't try to reencrypt if the type's data is unavailable.
800 
801     // Iterate through all children of this datatype.
802     std::queue<int64> to_visit;
803     int64 child_id = type_root.GetFirstChildId();
804     to_visit.push(child_id);
805     while (!to_visit.empty()) {
806       child_id = to_visit.front();
807       to_visit.pop();
808       if (child_id == kInvalidId)
809         continue;
810 
811       WriteNode child(trans);
812       if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK)
813         continue;  // Possible for locally deleted items.
814       if (child.GetIsFolder()) {
815         to_visit.push(child.GetFirstChildId());
816       }
817       if (child.GetEntry()->GetUniqueServerTag().empty()) {
818       // Rewrite the specifics of the node with encrypted data if necessary
819       // (only rewrite the non-unique folders).
820         child.ResetFromSpecifics();
821       }
822       to_visit.push(child.GetSuccessorId());
823     }
824   }
825 
826   // Passwords are encrypted with their own legacy scheme.  Passwords are always
827   // encrypted so we don't need to check GetEncryptedTypes() here.
828   ReadNode passwords_root(trans);
829   std::string passwords_tag = ModelTypeToRootTag(PASSWORDS);
830   if (passwords_root.InitByTagLookup(passwords_tag) ==
831           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) {
836         NOTREACHED();
837         return;
838       }
839       child.SetPasswordSpecifics(child.GetPasswordSpecifics());
840       child_id = child.GetSuccessorId();
841     }
842   }
843 
844   DVLOG(1) << "Re-encrypt everything complete.";
845 
846   // NOTE: We notify from within a transaction.
847   FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
848                     OnEncryptionComplete());
849 }
850 
ApplyNigoriUpdateImpl(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)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,
857                                                                   trans);
858 
859   if (nigori.custom_passphrase_time() != 0) {
860     custom_passphrase_time_ =
861         ProtoTimeToTime(nigori.custom_passphrase_time());
862   }
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());
869 
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_)
884                << " to "
885                << PassphraseTypeToString(nigori_passphrase_type);
886       passphrase_type_ = nigori_passphrase_type;
887       FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
888                             OnPassphraseTypeChanged(
889                                 passphrase_type_,
890                                 GetExplicitPassphraseTime()));
891     }
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(
904                                 passphrase_type_,
905                                 GetExplicitPassphraseTime()));
906     }
907   } else {
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(
915                                 passphrase_type_,
916                                 GetExplicitPassphraseTime()));
917     }
918   }
919 
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()));
929     } else {
930       need_new_default_key = nigori.keybag_is_frozen();
931     }
932     if (!AttemptToInstallKeybag(nigori.encryption_keybag(),
933                                 need_new_default_key,
934                                 cryptographer)) {
935       // Check to see if we can decrypt the keybag using the keystore decryptor
936       // token.
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(),
942                                               cryptographer)) {
943           nigori_needs_new_keys =
944               cryptographer->KeybagIsStale(nigori.encryption_keybag());
945         } else {
946           LOG(ERROR) << "Failed to decrypt pending keys using keystore "
947                      << "bootstrap key.";
948         }
949       }
950     } else {
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());
956     }
957   } else {
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;
962   }
963 
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,
971                                            pending_keys));
972   } else if (!cryptographer->is_ready()) {
973     DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
974              << "ready";
975     FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
976                       OnPassphraseRequired(REASON_ENCRYPTION,
977                                            sync_pb::EncryptedData()));
978   }
979 
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
982   // state.
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_);
989   } else {
990     passphrase_type_matches =
991         (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) ==
992              passphrase_type_);
993   }
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.";
999     return false;
1000   }
1001   return true;
1002 }
1003 
RewriteNigori()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);
1009 }
1010 
WriteEncryptionStateToNigori(WriteTransaction * 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.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
1017     return;
1018 
1019   sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
1020   const Cryptographer& cryptographer =
1021       UnlockVault(trans->GetWrappedTrans()).cryptographer;
1022 
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()))
1032         NOTREACHED();
1033 
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_);
1042       }
1043 
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.
1048     }
1049     syncable::UpdateNigoriFromEncryptedTypes(
1050         UnlockVault(trans->GetWrappedTrans()).encrypted_types,
1051         encrypt_everything_,
1052         &nigori);
1053     if (!custom_passphrase_time_.is_null()) {
1054       nigori.set_custom_passphrase_time(
1055           TimeToProtoTime(custom_passphrase_time_));
1056     }
1057 
1058     // If nothing has changed, this is a no-op.
1059     nigori_node.SetNigoriSpecifics(nigori);
1060   }
1061 }
1062 
UpdateEncryptedTypesFromNigori(const sync_pb::NigoriSpecifics & nigori,syncable::BaseTransaction * const trans)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()));
1071     return true;
1072   } else if (encrypt_everything_) {
1073     DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1074     return false;
1075   }
1076 
1077   ModelTypeSet nigori_encrypted_types;
1078   nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori);
1079   nigori_encrypted_types.PutAll(SensitiveTypes());
1080 
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();
1089       FOR_EACH_OBSERVER(
1090           Observer, observers_,
1091           OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1092     }
1093     DCHECK(encrypted_types->Equals(EncryptableUserTypes()));
1094     return false;
1095   }
1096 
1097   MergeEncryptedTypes(nigori_encrypted_types, trans);
1098   return encrypted_types->Equals(nigori_encrypted_types);
1099 }
1100 
SetCustomPassphrase(const std::string & passphrase,WriteTransaction * trans,WriteNode * nigori_node)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};
1108 
1109   if (passphrase_type_ != KEYSTORE_PASSPHRASE) {
1110     DVLOG(1) << "Failing to set a custom passphrase because one has already "
1111              << "been set.";
1112     FinishSetPassphrase(false, std::string(), trans, nigori_node);
1113     return;
1114   }
1115 
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);
1126     return;
1127   }
1128 
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(
1137                                 passphrase_type_,
1138                                 GetExplicitPassphraseTime()));
1139   } else {
1140     NOTREACHED() << "Failed to add key to cryptographer.";
1141     return;
1142   }
1143   FinishSetPassphrase(true, bootstrap_token, trans, nigori_node);
1144 }
1145 
DecryptPendingKeysWithExplicitPassphrase(const std::string & passphrase,WriteTransaction * trans,WriteNode * 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};
1153 
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.";
1162     return;
1163   }
1164 
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);
1171     success = true;
1172   } else {
1173     DVLOG(1) << "Explicit passphrase failed to decrypt.";
1174     success = false;
1175   }
1176   if (success && !keystore_key_.empty()) {
1177     // Should already be part of the encryption keybag, but we add it just
1178     // in case.
1179     KeyParams key_params = {"localhost", "dummy", keystore_key_};
1180     cryptographer->AddNonDefaultKey(key_params);
1181   }
1182   FinishSetPassphrase(success, bootstrap_token, trans, nigori_node);
1183 }
1184 
FinishSetPassphrase(bool success,const std::string & bootstrap_token,WriteTransaction * trans,WriteNode * nigori_node)1185 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
1186     bool success,
1187     const std::string& bootstrap_token,
1188     WriteTransaction* trans,
1189     WriteNode* nigori_node) {
1190   DCHECK(thread_checker_.CalledOnValidThread());
1191   FOR_EACH_OBSERVER(
1192       SyncEncryptionHandler::Observer,
1193       observers_,
1194       OnCryptographerStateChanged(
1195           &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
1196 
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
1199   // passphrase).
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));
1205   }
1206 
1207   const Cryptographer& cryptographer =
1208       UnlockVault(trans->GetWrappedTrans()).cryptographer;
1209   if (!success) {
1210     if (cryptographer.is_ready()) {
1211       LOG(ERROR) << "Attempt to change passphrase failed while cryptographer "
1212                  << "was ready.";
1213     } else if (cryptographer.has_pending_keys()) {
1214       FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1215                         OnPassphraseRequired(REASON_DECRYPTION,
1216                                              cryptographer.GetPendingKeys()));
1217     } else {
1218       FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1219                         OnPassphraseRequired(REASON_ENCRYPTION,
1220                                              sync_pb::EncryptedData()));
1221     }
1222     return;
1223   }
1224   DCHECK(success);
1225   DCHECK(cryptographer.is_ready());
1226 
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()))
1236       NOTREACHED();
1237     if (IsNigoriMigratedToKeystore(nigori)) {
1238       DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_));
1239       DVLOG(1) << "Leaving nigori migration state untouched after setting"
1240                << " passphrase.";
1241     } else {
1242       nigori.set_keybag_is_frozen(
1243           IsExplicitPassphrase(passphrase_type_));
1244     }
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_));
1249     }
1250     nigori_node->SetNigoriSpecifics(nigori);
1251   }
1252 
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());
1257 
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);
1262 }
1263 
MergeEncryptedTypes(ModelTypeSet new_encrypted_types,syncable::BaseTransaction * const trans)1264 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
1265     ModelTypeSet new_encrypted_types,
1266     syncable::BaseTransaction* const trans) {
1267   DCHECK(thread_checker_.CalledOnValidThread());
1268 
1269   // Only UserTypes may be encrypted.
1270   DCHECK(EncryptableUserTypes().HasAll(new_encrypted_types));
1271 
1272   ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1273   if (!encrypted_types->HasAll(new_encrypted_types)) {
1274     *encrypted_types = new_encrypted_types;
1275     FOR_EACH_OBSERVER(
1276         Observer, observers_,
1277         OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1278   }
1279 }
1280 
UnlockVaultMutable(syncable::BaseTransaction * const trans)1281 SyncEncryptionHandlerImpl::Vault* SyncEncryptionHandlerImpl::UnlockVaultMutable(
1282     syncable::BaseTransaction* const trans) {
1283   DCHECK_EQ(user_share_->directory.get(), trans->directory());
1284   return &vault_unsafe_;
1285 }
1286 
UnlockVault(syncable::BaseTransaction * const trans) const1287 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
1288     syncable::BaseTransaction* const trans) const {
1289   DCHECK_EQ(user_share_->directory.get(), trans->directory());
1290   return vault_unsafe_;
1291 }
1292 
ShouldTriggerMigration(const sync_pb::NigoriSpecifics & nigori,const Cryptographer & cryptographer) const1293 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())
1300     return false;
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) {
1311       return true;
1312     } else if (IsExplicitPassphrase(passphrase_type_) &&
1313                !encrypt_everything_) {
1314       return true;
1315     } else if (passphrase_type_ == KEYSTORE_PASSPHRASE &&
1316                encrypt_everything_) {
1317       return true;
1318     } else if (
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.
1323       return true;
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())) {
1335         return true;
1336       }
1337     }
1338     return false;
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
1343     // passphrase).
1344     return false;
1345   }
1346   return true;
1347 }
1348 
AttemptToMigrateNigoriToKeystore(WriteTransaction * trans,WriteNode * nigori_node)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;
1357 
1358   if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1359     return false;
1360 
1361   DVLOG(1) << "Starting nigori migration to keystore support.";
1362   sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1363 
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();
1376   } else {
1377     DCHECK(!encrypt_everything_);
1378     new_passphrase_type = KEYSTORE_PASSPHRASE;
1379     DVLOG(1) << "Switching to keystore passphrase state.";
1380   }
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);
1385 
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);
1403         return false;
1404       }
1405       if (!cryptographer_was_ready && cryptographer->is_ready()) {
1406         FOR_EACH_OBSERVER(
1407             SyncEncryptionHandler::Observer,
1408             observers_,
1409             OnPassphraseAccepted());
1410       }
1411     } else {
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
1415       // the migration).
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);
1422         return false;
1423       }
1424     }
1425   }
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
1429     // nigori node.
1430     for (std::vector<std::string>::const_iterator iter =
1431              old_keystore_keys_.begin(); iter != old_keystore_keys_.end();
1432          ++iter) {
1433       KeyParams key_params = {"localhost", "dummy", *iter};
1434       cryptographer->AddNonDefaultKey(key_params);
1435     }
1436   }
1437   if (new_passphrase_type == KEYSTORE_PASSPHRASE &&
1438       !GetKeystoreDecryptor(
1439           *cryptographer,
1440           keystore_key_,
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);
1446     return false;
1447   }
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);
1453     return false;
1454   }
1455 
1456   if (migration_time_.is_null())
1457     migration_time_ = base::Time::Now();
1458   migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_));
1459 
1460   if (!custom_passphrase_time_.is_null()) {
1461     migrated_nigori.set_custom_passphrase_time(
1462         TimeToProtoTime(custom_passphrase_time_));
1463   }
1464 
1465   FOR_EACH_OBSERVER(
1466       SyncEncryptionHandler::Observer,
1467       observers_,
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(
1473                                 passphrase_type_,
1474                                 GetExplicitPassphraseTime()));
1475   }
1476 
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);
1484   }
1485 
1486   DVLOG(1) << "Completing nigori migration to keystore support.";
1487   nigori_node->SetNigoriSpecifics(migrated_nigori);
1488 
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);
1495       } else {
1496         UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1497                                   MIGRATION_SUCCESS_KEYSTORE_DEFAULT,
1498                                   MIGRATION_RESULT_SIZE);
1499       }
1500       break;
1501     case FROZEN_IMPLICIT_PASSPHRASE:
1502       UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1503                                 MIGRATION_SUCCESS_FROZEN_IMPLICIT,
1504                                 MIGRATION_RESULT_SIZE);
1505       break;
1506     case CUSTOM_PASSPHRASE:
1507       UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration",
1508                                 MIGRATION_SUCCESS_CUSTOM,
1509                                 MIGRATION_RESULT_SIZE);
1510       break;
1511     default:
1512       NOTREACHED();
1513       break;
1514   }
1515   return true;
1516 }
1517 
GetKeystoreDecryptor(const Cryptographer & cryptographer,const std::string & keystore_key,sync_pb::EncryptedData * encrypted_blob)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.GetDefaultNigoriKey();
1527   if (serialized_nigori.empty()) {
1528     LOG(ERROR) << "Failed to get cryptographer bootstrap token.";
1529     return false;
1530   }
1531   Cryptographer temp_cryptographer(cryptographer.encryptor());
1532   KeyParams key_params = {"localhost", "dummy", keystore_key};
1533   if (!temp_cryptographer.AddKey(key_params))
1534     return false;
1535   if (!temp_cryptographer.EncryptString(serialized_nigori, encrypted_blob))
1536     return false;
1537   return true;
1538 }
1539 
AttemptToInstallKeybag(const sync_pb::EncryptedData & keybag,bool update_default,Cryptographer * cryptographer)1540 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1541     const sync_pb::EncryptedData& keybag,
1542     bool update_default,
1543     Cryptographer* cryptographer) {
1544   if (!cryptographer->CanDecrypt(keybag))
1545     return false;
1546   cryptographer->InstallKeys(keybag);
1547   if (update_default)
1548     cryptographer->SetDefaultKey(keybag.key_name());
1549   return true;
1550 }
1551 
EnableEncryptEverythingImpl(syncable::BaseTransaction * const trans)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()));
1557     return;
1558   }
1559   encrypt_everything_ = true;
1560   *encrypted_types = EncryptableUserTypes();
1561   FOR_EACH_OBSERVER(
1562       Observer, observers_,
1563       OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1564 }
1565 
DecryptPendingKeysWithKeystoreKey(const std::string & keystore_key,const sync_pb::EncryptedData & keystore_decryptor_token,Cryptographer * cryptographer)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())
1572     return false;
1573   Cryptographer temp_cryptographer(cryptographer->encryptor());
1574 
1575   // First, go through and all all the old keystore keys to the temporary
1576   // cryptographer.
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);
1580   }
1581 
1582   // Then add the current keystore key as the default key and see if we can
1583   // decrypt.
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
1590     // cryptographer.
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);
1601 
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);
1605 
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);
1614     } else {
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);
1619     }
1620     if (cryptographer->is_ready()) {
1621       std::string bootstrap_token;
1622       cryptographer->GetBootstrapToken(&bootstrap_token);
1623       DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
1624       FOR_EACH_OBSERVER(
1625           SyncEncryptionHandler::Observer,
1626           observers_,
1627           OnPassphraseAccepted());
1628       FOR_EACH_OBSERVER(
1629           SyncEncryptionHandler::Observer,
1630           observers_,
1631           OnBootstrapTokenUpdated(bootstrap_token,
1632                                   PASSPHRASE_BOOTSTRAP_TOKEN));
1633       FOR_EACH_OBSERVER(
1634           SyncEncryptionHandler::Observer,
1635           observers_,
1636           OnCryptographerStateChanged(cryptographer));
1637       return true;
1638     }
1639   }
1640   return false;
1641 }
1642 
GetExplicitPassphraseTime() const1643 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();
1649 }
1650 
1651 }  // namespace browser_sync
1652