Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(760)

Side by Side Diff: sync/internal_api/sync_encryption_handler_impl.cc

Issue 10916036: [Sync] Implement keystore migration support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/internal_api/sync_encryption_handler_impl.h" 5 #include "sync/internal_api/sync_encryption_handler_impl.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/time.h"
12 #include "base/tracked_objects.h" 13 #include "base/tracked_objects.h"
13 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
14 #include "sync/internal_api/public/read_node.h" 15 #include "sync/internal_api/public/read_node.h"
15 #include "sync/internal_api/public/read_transaction.h" 16 #include "sync/internal_api/public/read_transaction.h"
16 #include "sync/internal_api/public/user_share.h" 17 #include "sync/internal_api/public/user_share.h"
17 #include "sync/internal_api/public/util/experiments.h" 18 #include "sync/internal_api/public/util/experiments.h"
18 #include "sync/internal_api/public/write_node.h" 19 #include "sync/internal_api/public/write_node.h"
19 #include "sync/internal_api/public/write_transaction.h" 20 #include "sync/internal_api/public/write_transaction.h"
21 #include "sync/internal_api/public/util/sync_string_conversions.h"
20 #include "sync/protocol/encryption.pb.h" 22 #include "sync/protocol/encryption.pb.h"
21 #include "sync/protocol/nigori_specifics.pb.h" 23 #include "sync/protocol/nigori_specifics.pb.h"
22 #include "sync/protocol/sync.pb.h" 24 #include "sync/protocol/sync.pb.h"
23 #include "sync/syncable/base_transaction.h" 25 #include "sync/syncable/base_transaction.h"
24 #include "sync/syncable/directory.h" 26 #include "sync/syncable/directory.h"
25 #include "sync/syncable/entry.h" 27 #include "sync/syncable/entry.h"
26 #include "sync/syncable/nigori_util.h" 28 #include "sync/syncable/nigori_util.h"
27 #include "sync/util/cryptographer.h" 29 #include "sync/util/cryptographer.h"
30 #include "sync/util/time.h"
28 31
29 namespace syncer { 32 namespace syncer {
30 33
31 namespace { 34 namespace {
35
32 // The maximum number of times we will automatically overwrite the nigori node 36 // The maximum number of times we will automatically overwrite the nigori node
33 // because the encryption keys don't match (per chrome instantiation). 37 // because the encryption keys don't match (per chrome instantiation).
34 // We protect ourselves against nigori rollbacks, but it's possible two 38 // We protect ourselves against nigori rollbacks, but it's possible two
35 // different clients might have contrasting view of what the nigori node state 39 // different clients might have contrasting view of what the nigori node state
36 // should be, in which case they might ping pong (see crbug.com/119207). 40 // should be, in which case they might ping pong (see crbug.com/119207).
37 static const int kNigoriOverwriteLimit = 10; 41 static const int kNigoriOverwriteLimit = 10;
42
43 // The new passphrase state is sufficient to determine whether a nigori node
44 // is migrated to support keystore encryption. In addition though, we also
45 // want to verify the conditions for proper keystore encryption functionality.
46 // 1. Passphrase state is set.
47 // 2. Migration time is set.
48 // 3. Frozen keybag is true
49 // 4. If passphrase state is keystore, keystore_decryptor_key is set.
50 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) {
51 if (!nigori.has_passphrase_type())
52 return false;
53 if (!nigori.has_keystore_migration_time())
54 return false;
55 if (!nigori.frozen_keybag())
56 return false;
57 if (nigori.passphrase_type() ==
58 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)
59 return false;
60 if (nigori.passphrase_type() ==
61 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE &&
62 nigori.keystore_decryptor().blob().empty())
63 return false;
64 return true;
38 } 65 }
39 66
67 PassphraseType ProtoPassphraseTypeToEnum(
68 sync_pb::NigoriSpecifics::PassphraseType type) {
69 switch(type) {
70 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE:
71 return IMPLICIT_PASSPHRASE;
72 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE:
73 return KEYSTORE_PASSPHRASE;
74 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE:
75 return CUSTOM_PASSPHRASE;
76 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE:
77 return FROZEN_IMPLICIT_PASSPHRASE;
78 default:
79 NOTREACHED();
80 return IMPLICIT_PASSPHRASE;
81 };
82 }
83
84 sync_pb::NigoriSpecifics::PassphraseType
85 EnumPassphraseTypeToProto(PassphraseType type) {
86 switch(type) {
87 case IMPLICIT_PASSPHRASE:
88 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;
89 case KEYSTORE_PASSPHRASE:
90 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE;
91 case CUSTOM_PASSPHRASE:
92 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE;
93 case FROZEN_IMPLICIT_PASSPHRASE:
94 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE;
95 default:
96 NOTREACHED();
97 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE;;
98 };
99 }
100
101 bool IsExplicitPassphrase(PassphraseType type) {
102 return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE;
103 }
104
105 } // namespace
106
40 SyncEncryptionHandlerImpl::Vault::Vault( 107 SyncEncryptionHandlerImpl::Vault::Vault(
41 Encryptor* encryptor, 108 Encryptor* encryptor,
42 ModelTypeSet encrypted_types) 109 ModelTypeSet encrypted_types)
43 : cryptographer(encryptor), 110 : cryptographer(encryptor),
44 encrypted_types(encrypted_types) { 111 encrypted_types(encrypted_types) {
45 } 112 }
46 113
47 SyncEncryptionHandlerImpl::Vault::~Vault() { 114 SyncEncryptionHandlerImpl::Vault::~Vault() {
48 } 115 }
49 116
50 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( 117 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl(
51 UserShare* user_share, 118 UserShare* user_share,
52 Encryptor* encryptor, 119 Encryptor* encryptor,
53 const std::string& restored_key_for_bootstrapping, 120 const std::string& restored_key_for_bootstrapping,
54 const std::string& restored_keystore_key_for_bootstrapping) 121 const std::string& restored_keystore_key_for_bootstrapping)
55 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 122 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
56 user_share_(user_share), 123 user_share_(user_share),
57 vault_unsafe_(encryptor, SensitiveTypes()), 124 vault_unsafe_(encryptor, SensitiveTypes()),
58 encrypt_everything_(false), 125 encrypt_everything_(false),
59 passphrase_state_(IMPLICIT_PASSPHRASE), 126 passphrase_type_(IMPLICIT_PASSPHRASE),
60 keystore_key_(restored_keystore_key_for_bootstrapping), 127 keystore_key_(restored_keystore_key_for_bootstrapping),
61 nigori_overwrite_count_(0) { 128 nigori_overwrite_count_(0),
129 migration_time_ms_(0) {
62 // We only bootstrap the user provided passphrase. The keystore key is handled 130 // We only bootstrap the user provided passphrase. The keystore key is handled
63 // at Init time once we're sure the nigori is downloaded. 131 // at Init time once we're sure the nigori is downloaded.
64 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); 132 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping);
65 } 133 }
66 134
67 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} 135 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {}
68 136
69 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { 137 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) {
70 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
71 DCHECK(!observers_.HasObserver(observer)); 139 DCHECK(!observers_.HasObserver(observer));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 191
124 // All accesses to the cryptographer are protected by a transaction. 192 // All accesses to the cryptographer are protected by a transaction.
125 WriteTransaction trans(FROM_HERE, user_share_); 193 WriteTransaction trans(FROM_HERE, user_share_);
126 KeyParams key_params = {"localhost", "dummy", passphrase}; 194 KeyParams key_params = {"localhost", "dummy", passphrase};
127 WriteNode node(&trans); 195 WriteNode node(&trans);
128 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 196 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
129 NOTREACHED(); 197 NOTREACHED();
130 return; 198 return;
131 } 199 }
132 200
133 bool nigori_has_explicit_passphrase = 201 Cryptographer* cryptographer =
134 node.GetNigoriSpecifics().using_explicit_passphrase(); 202 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
203
204 // Once we've migrated to keystore, the only way to set a passphrase for
205 // encryption is to set a custom passphrase.
206 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
207 if (!is_explicit) {
208 DCHECK(cryptographer->is_ready());
209 // The user is setting a new implicit passphrase. At this point we don't
210 // care, so drop it on the floor. This is safe because if we have a
211 // migrated nigori node, then we don't need to create an initial
212 // encryption key.
213 LOG(WARNING) << "Ignoring new implicit passphrase. Keystore migration "
214 << "already performed.";
215 return;
216 }
217 // Will fail if we already have an explicit passphrase or we have pending
218 // keys.
219 SetCustomPassphrase(passphrase, &trans, &node);
220 return;
221 }
222
135 std::string bootstrap_token; 223 std::string bootstrap_token;
136 sync_pb::EncryptedData pending_keys; 224 sync_pb::EncryptedData pending_keys;
137 Cryptographer* cryptographer =
138 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
139 if (cryptographer->has_pending_keys()) 225 if (cryptographer->has_pending_keys())
140 pending_keys = cryptographer->GetPendingKeys(); 226 pending_keys = cryptographer->GetPendingKeys();
141 bool success = false; 227 bool success = false;
142 228
143 // There are six cases to handle here: 229 // There are six cases to handle here:
144 // 1. The user has no pending keys and is setting their current GAIA password 230 // 1. The user has no pending keys and is setting their current GAIA password
145 // as the encryption passphrase. This happens either during first time sync 231 // as the encryption passphrase. This happens either during first time sync
146 // with a clean profile, or after re-authenticating on a profile that was 232 // with a clean profile, or after re-authenticating on a profile that was
147 // already signed in with the cryptographer ready. 233 // already signed in with the cryptographer ready.
148 // 2. The user has no pending keys, and is overwriting an (already provided) 234 // 2. The user has no pending keys, and is overwriting an (already provided)
149 // implicit passphrase with an explicit (custom) passphrase. 235 // implicit passphrase with an explicit (custom) passphrase.
150 // 3. The user has pending keys for an explicit passphrase that is somehow set 236 // 3. The user has pending keys for an explicit passphrase that is somehow set
151 // to their current GAIA passphrase. 237 // to their current GAIA passphrase.
152 // 4. The user has pending keys encrypted with their current GAIA passphrase 238 // 4. The user has pending keys encrypted with their current GAIA passphrase
153 // and the caller passes in the current GAIA passphrase. 239 // and the caller passes in the current GAIA passphrase.
154 // 5. The user has pending keys encrypted with an older GAIA passphrase 240 // 5. The user has pending keys encrypted with an older GAIA passphrase
155 // and the caller passes in the current GAIA passphrase. 241 // and the caller passes in the current GAIA passphrase.
156 // 6. The user has previously done encryption with an explicit passphrase. 242 // 6. The user has previously done encryption with an explicit passphrase.
157 // Furthermore, we enforce the fact that the bootstrap encryption token will 243 // Furthermore, we enforce the fact that the bootstrap encryption token will
158 // always be derived from the newest GAIA password if the account is using 244 // always be derived from the newest GAIA password if the account is using
159 // an implicit passphrase (even if the data is encrypted with an old GAIA 245 // an implicit passphrase (even if the data is encrypted with an old GAIA
160 // password). If the account is using an explicit (custom) passphrase, the 246 // password). If the account is using an explicit (custom) passphrase, the
161 // bootstrap token will be derived from the most recently provided explicit 247 // bootstrap token will be derived from the most recently provided explicit
162 // passphrase (that was able to decrypt the data). 248 // passphrase (that was able to decrypt the data).
163 if (!nigori_has_explicit_passphrase) { 249 if (!IsExplicitPassphrase(passphrase_type_)) {
164 if (!cryptographer->has_pending_keys()) { 250 if (!cryptographer->has_pending_keys()) {
165 if (cryptographer->AddKey(key_params)) { 251 if (cryptographer->AddKey(key_params)) {
166 // Case 1 and 2. We set a new GAIA passphrase when there are no pending 252 // Case 1 and 2. We set a new GAIA passphrase when there are no pending
167 // keys (1), or overwriting an implicit passphrase with a new explicit 253 // keys (1), or overwriting an implicit passphrase with a new explicit
168 // one (2) when there are no pending keys. 254 // one (2) when there are no pending keys.
169 DVLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit" ) 255 if (is_explicit) {
170 << " passphrase for encryption."; 256 DVLOG(1) << "Setting explicit passphrase for encryption.";
257 passphrase_type_ = CUSTOM_PASSPHRASE;
258 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
259 OnPassphraseTypeChanged(passphrase_type_));
260 } else {
261 DVLOG(1) << "Setting implicit passphrase for encryption.";
262 }
171 cryptographer->GetBootstrapToken(&bootstrap_token); 263 cryptographer->GetBootstrapToken(&bootstrap_token);
172 success = true; 264 success = true;
173 } else { 265 } else {
174 NOTREACHED() << "Failed to add key to cryptographer."; 266 NOTREACHED() << "Failed to add key to cryptographer.";
175 success = false; 267 success = false;
176 } 268 }
177 } else { // cryptographer->has_pending_keys() == true 269 } else { // cryptographer->has_pending_keys() == true
178 if (is_explicit) { 270 if (is_explicit) {
179 // This can only happen if the nigori node is updated with a new 271 // This can only happen if the nigori node is updated with a new
180 // implicit passphrase while a client is attempting to set a new custom 272 // implicit passphrase while a client is attempting to set a new custom
(...skipping 21 matching lines...) Expand all
202 temp_cryptographer.GetBootstrapToken(&bootstrap_token); 294 temp_cryptographer.GetBootstrapToken(&bootstrap_token);
203 // We then set the new passphrase as the default passphrase of the 295 // We then set the new passphrase as the default passphrase of the
204 // real cryptographer, even though we have pending keys. This is safe, 296 // real cryptographer, even though we have pending keys. This is safe,
205 // as although Cryptographer::is_initialized() will now be true, 297 // as although Cryptographer::is_initialized() will now be true,
206 // is_ready() will remain false due to having pending keys. 298 // is_ready() will remain false due to having pending keys.
207 cryptographer->AddKey(key_params); 299 cryptographer->AddKey(key_params);
208 success = false; 300 success = false;
209 } 301 }
210 } // is_explicit 302 } // is_explicit
211 } // cryptographer->has_pending_keys() 303 } // cryptographer->has_pending_keys()
212 } else { // nigori_has_explicit_passphrase == true 304 } else { // IsExplicitPassphrase(passphrase_type_) == true.
213 // Case 6. We do not want to override a previously set explicit passphrase, 305 // Case 6. We do not want to override a previously set explicit passphrase,
214 // so we return a failure. 306 // so we return a failure.
215 DVLOG(1) << "Failing because an explicit passphrase is already set."; 307 DVLOG(1) << "Failing because an explicit passphrase is already set.";
216 success = false; 308 success = false;
217 } 309 }
218 310
219 DVLOG_IF(1, !success) 311 DVLOG_IF(1, !success)
220 << "Failure in SetEncryptionPassphrase; notifying and returning."; 312 << "Failure in SetEncryptionPassphrase; notifying and returning.";
221 DVLOG_IF(1, success) 313 DVLOG_IF(1, success)
222 << "Successfully set encryption passphrase; updating nigori and " 314 << "Successfully set encryption passphrase; updating nigori and "
223 "reencrypting."; 315 "reencrypting.";
224 316
225 FinishSetPassphrase( 317 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
226 success, bootstrap_token, is_explicit, &trans, &node);
227 } 318 }
228 319
229 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase( 320 void SyncEncryptionHandlerImpl::SetDecryptionPassphrase(
230 const std::string& passphrase) { 321 const std::string& passphrase) {
231 DCHECK(thread_checker_.CalledOnValidThread()); 322 DCHECK(thread_checker_.CalledOnValidThread());
232 // We do not accept empty passphrases. 323 // We do not accept empty passphrases.
233 if (passphrase.empty()) { 324 if (passphrase.empty()) {
234 NOTREACHED() << "Cannot decrypt with an empty passphrase."; 325 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
235 return; 326 return;
236 } 327 }
237 328
238 // All accesses to the cryptographer are protected by a transaction. 329 // All accesses to the cryptographer are protected by a transaction.
239 WriteTransaction trans(FROM_HERE, user_share_); 330 WriteTransaction trans(FROM_HERE, user_share_);
240 KeyParams key_params = {"localhost", "dummy", passphrase}; 331 KeyParams key_params = {"localhost", "dummy", passphrase};
241 WriteNode node(&trans); 332 WriteNode node(&trans);
242 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) { 333 if (node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) {
243 NOTREACHED(); 334 NOTREACHED();
244 return; 335 return;
245 } 336 }
246 337
338 // Once we've migrated to keystore, we're only ever decrypting keys derived
339 // from an explicit passphrase. But, for clients without a keystore key yet
340 // (either not on by default or failed to download one), we still support
341 // decrypting with a gaia passphrase, and therefore bypass the
342 // DecryptExplicitPassphrase logic.
343 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics()) &&
344 IsExplicitPassphrase(passphrase_type_)) {
345 DecryptPendingKeysWithExplicitPassphrase(passphrase, &trans, &node);
346 return;
347 }
348
247 Cryptographer* cryptographer = 349 Cryptographer* cryptographer =
248 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer; 350 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer;
249 if (!cryptographer->has_pending_keys()) { 351 if (!cryptographer->has_pending_keys()) {
250 // Note that this *can* happen in a rare situation where data is 352 // Note that this *can* happen in a rare situation where data is
251 // re-encrypted on another client while a SetDecryptionPassphrase() call is 353 // re-encrypted on another client while a SetDecryptionPassphrase() call is
252 // in-flight on this client. It is rare enough that we choose to do nothing. 354 // in-flight on this client. It is rare enough that we choose to do nothing.
253 NOTREACHED() << "Attempt to set decryption passphrase failed because there " 355 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
254 << "were no pending keys."; 356 << "were no pending keys.";
255 return; 357 return;
256 } 358 }
257 359
258 bool nigori_has_explicit_passphrase =
259 node.GetNigoriSpecifics().using_explicit_passphrase();
260 std::string bootstrap_token; 360 std::string bootstrap_token;
261 sync_pb::EncryptedData pending_keys; 361 sync_pb::EncryptedData pending_keys;
262 pending_keys = cryptographer->GetPendingKeys(); 362 pending_keys = cryptographer->GetPendingKeys();
263 bool success = false; 363 bool success = false;
264 364
265 // There are three cases to handle here: 365 // There are three cases to handle here:
266 // 7. We're using the current GAIA password to decrypt the pending keys. This 366 // 7. We're using the current GAIA password to decrypt the pending keys. This
267 // happens when signing in to an account with a previously set implicit 367 // happens when signing in to an account with a previously set implicit
268 // passphrase, where the data is already encrypted with the newest GAIA 368 // passphrase, where the data is already encrypted with the newest GAIA
269 // password. 369 // password.
270 // 8. The user is providing an old GAIA password to decrypt the pending keys. 370 // 8. The user is providing an old GAIA password to decrypt the pending keys.
271 // In this case, the user is using an implicit passphrase, but has changed 371 // In this case, the user is using an implicit passphrase, but has changed
272 // their password since they last encrypted their data, and therefore 372 // their password since they last encrypted their data, and therefore
273 // their current GAIA password was unable to decrypt the data. This will 373 // their current GAIA password was unable to decrypt the data. This will
274 // happen when the user is setting up a new profile with a previously 374 // happen when the user is setting up a new profile with a previously
275 // encrypted account (after changing passwords). 375 // encrypted account (after changing passwords).
276 // 9. The user is providing a previously set explicit passphrase to decrypt 376 // 9. The user is providing a previously set explicit passphrase to decrypt
277 // the pending keys. 377 // the pending keys.
278 if (!nigori_has_explicit_passphrase) { 378 if (!IsExplicitPassphrase(passphrase_type_)) {
279 if (cryptographer->is_initialized()) { 379 if (cryptographer->is_initialized()) {
280 // We only want to change the default encryption key to the pending 380 // We only want to change the default encryption key to the pending
281 // one if the pending keybag already contains the current default. 381 // one if the pending keybag already contains the current default.
282 // This covers the case where a different client re-encrypted 382 // This covers the case where a different client re-encrypted
283 // everything with a newer gaia passphrase (and hence the keybag 383 // everything with a newer gaia passphrase (and hence the keybag
284 // contains keys from all previously used gaia passphrases). 384 // contains keys from all previously used gaia passphrases).
285 // Otherwise, we're in a situation where the pending keys are 385 // Otherwise, we're in a situation where the pending keys are
286 // encrypted with an old gaia passphrase, while the default is the 386 // encrypted with an old gaia passphrase, while the default is the
287 // current gaia passphrase. In that case, we preserve the default. 387 // current gaia passphrase. In that case, we preserve the default.
288 Cryptographer temp_cryptographer(cryptographer->encryptor()); 388 Cryptographer temp_cryptographer(cryptographer->encryptor());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 success = false; 455 success = false;
356 } 456 }
357 } // nigori_has_explicit_passphrase 457 } // nigori_has_explicit_passphrase
358 458
359 DVLOG_IF(1, !success) 459 DVLOG_IF(1, !success)
360 << "Failure in SetDecryptionPassphrase; notifying and returning."; 460 << "Failure in SetDecryptionPassphrase; notifying and returning.";
361 DVLOG_IF(1, success) 461 DVLOG_IF(1, success)
362 << "Successfully set decryption passphrase; updating nigori and " 462 << "Successfully set decryption passphrase; updating nigori and "
363 "reencrypting."; 463 "reencrypting.";
364 464
365 FinishSetPassphrase(success, 465 FinishSetPassphrase(success, bootstrap_token, &trans, &node);
366 bootstrap_token,
367 nigori_has_explicit_passphrase,
368 &trans,
369 &node);
370 } 466 }
371 467
372 void SyncEncryptionHandlerImpl::EnableEncryptEverything() { 468 void SyncEncryptionHandlerImpl::EnableEncryptEverything() {
373 DCHECK(thread_checker_.CalledOnValidThread()); 469 DCHECK(thread_checker_.CalledOnValidThread());
374 WriteTransaction trans(FROM_HERE, user_share_); 470 WriteTransaction trans(FROM_HERE, user_share_);
375 ModelTypeSet* encrypted_types = 471 DVLOG(1) << "Enabling encrypt everything.";
376 &UnlockVaultMutable(trans.GetWrappedTrans())->encrypted_types; 472 if (encrypt_everything_)
377 if (encrypt_everything_) {
378 DCHECK(encrypted_types->Equals(ModelTypeSet::All()));
379 return; 473 return;
380 } 474 EnableEncryptEverythingImpl(trans.GetWrappedTrans());
381 DVLOG(1) << "Enabling encrypt everything.";
382 encrypt_everything_ = true;
383 // Change |encrypted_types_| directly to avoid sending more than one
384 // notification.
385 *encrypted_types = ModelTypeSet::All();
386 FOR_EACH_OBSERVER(
387 Observer, observers_,
388 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
389 WriteEncryptionStateToNigori(&trans); 475 WriteEncryptionStateToNigori(&trans);
390 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) 476 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready())
391 ReEncryptEverything(&trans); 477 ReEncryptEverything(&trans);
392 } 478 }
393 479
394 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const { 480 bool SyncEncryptionHandlerImpl::EncryptEverythingEnabled() const {
395 DCHECK(thread_checker_.CalledOnValidThread()); 481 DCHECK(thread_checker_.CalledOnValidThread());
396 return encrypt_everything_; 482 return encrypt_everything_;
397 } 483 }
398 484
399 PassphraseState SyncEncryptionHandlerImpl::GetPassphraseState() const { 485 PassphraseType SyncEncryptionHandlerImpl::GetPassphraseType() const {
400 DCHECK(thread_checker_.CalledOnValidThread()); 486 DCHECK(thread_checker_.CalledOnValidThread());
401 return passphrase_state_; 487 return passphrase_type_;
402 } 488 }
403 489
404 // Note: this is called from within a syncable transaction, so we need to post 490 // Note: this is called from within a syncable transaction, so we need to post
405 // tasks if we want to do any work that creates a new sync_api transaction. 491 // tasks if we want to do any work that creates a new sync_api transaction.
406 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate( 492 void SyncEncryptionHandlerImpl::ApplyNigoriUpdate(
407 const sync_pb::NigoriSpecifics& nigori, 493 const sync_pb::NigoriSpecifics& nigori,
408 syncable::BaseTransaction* const trans) { 494 syncable::BaseTransaction* const trans) {
409 DCHECK(thread_checker_.CalledOnValidThread()); 495 DCHECK(thread_checker_.CalledOnValidThread());
410 DCHECK(trans); 496 DCHECK(trans);
411 if (!ApplyNigoriUpdateImpl(nigori, trans)) { 497 if (!ApplyNigoriUpdateImpl(nigori, trans)) {
412 MessageLoop::current()->PostTask( 498 MessageLoop::current()->PostTask(
413 FROM_HERE, 499 FROM_HERE,
414 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, 500 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
415 weak_ptr_factory_.GetWeakPtr())); 501 weak_ptr_factory_.GetWeakPtr()));
416 } 502 }
417 503
418 FOR_EACH_OBSERVER( 504 FOR_EACH_OBSERVER(
419 SyncEncryptionHandler::Observer, 505 SyncEncryptionHandler::Observer,
420 observers_, 506 observers_,
421 OnCryptographerStateChanged( 507 OnCryptographerStateChanged(
422 &UnlockVaultMutable(trans)->cryptographer)); 508 &UnlockVaultMutable(trans)->cryptographer));
423 } 509 }
424 510
425 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes( 511 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes(
426 sync_pb::NigoriSpecifics* nigori, 512 sync_pb::NigoriSpecifics* nigori,
427 syncable::BaseTransaction* const trans) const { 513 syncable::BaseTransaction* const trans) const {
514 DCHECK(thread_checker_.CalledOnValidThread());
428 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types, 515 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types,
429 encrypt_everything_, 516 encrypt_everything_,
430 nigori); 517 nigori);
431 } 518 }
432 519
433 bool SyncEncryptionHandlerImpl::NeedKeystoreKey( 520 bool SyncEncryptionHandlerImpl::NeedKeystoreKey(
434 syncable::BaseTransaction* const trans) const { 521 syncable::BaseTransaction* const trans) const {
522 DCHECK(thread_checker_.CalledOnValidThread());
435 return keystore_key_.empty(); 523 return keystore_key_.empty();
436 } 524 }
437 525
438 bool SyncEncryptionHandlerImpl::SetKeystoreKey( 526 bool SyncEncryptionHandlerImpl::SetKeystoreKey(
439 const std::string& key, 527 const std::string& key,
440 syncable::BaseTransaction* const trans) { 528 syncable::BaseTransaction* const trans) {
529 DCHECK(thread_checker_.CalledOnValidThread());
441 if (!keystore_key_.empty() || key.empty()) 530 if (!keystore_key_.empty() || key.empty())
442 return false; 531 return false;
443 keystore_key_ = key; 532 keystore_key_ = key;
444 533
445 // TODO(zea): trigger migration if necessary.
446
447 DVLOG(1) << "Keystore bootstrap token updated."; 534 DVLOG(1) << "Keystore bootstrap token updated.";
448 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 535 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
449 OnBootstrapTokenUpdated(key, 536 OnBootstrapTokenUpdated(key,
450 KEYSTORE_BOOTSTRAP_TOKEN)); 537 KEYSTORE_BOOTSTRAP_TOKEN));
538
539 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
540 syncable::Entry entry(trans, syncable::GET_BY_SERVER_TAG, kNigoriTag);
541 if (entry.good()) {
542 const sync_pb::NigoriSpecifics& nigori =
543 entry.Get(syncable::SPECIFICS).nigori();
544 if (cryptographer->has_pending_keys() &&
545 IsNigoriMigratedToKeystore(nigori) &&
546 !nigori.keystore_decryptor().blob().empty()) {
547 // If the nigori is already migrated and we have pending keys, we might
548 // be able to decrypt them using the keystore decryptor.
549 DecryptPendingKeysWithKeystoreKey(keystore_key_,
550 nigori.keystore_decryptor(),
551 cryptographer);
552 } else if (ShouldTriggerMigration(nigori, *cryptographer)) {
553 // We call rewrite nigori to attempt to trigger migration.
554 // Need to post a task to open a new sync_api transaction.
555 MessageLoop::current()->PostTask(
556 FROM_HERE,
557 base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori,
558 weak_ptr_factory_.GetWeakPtr()));
559 }
560 }
561
451 return true; 562 return true;
452 } 563 }
453 564
454 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes( 565 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes(
455 syncable::BaseTransaction* const trans) const { 566 syncable::BaseTransaction* const trans) const {
456 return UnlockVault(trans).encrypted_types; 567 return UnlockVault(trans).encrypted_types;
457 } 568 }
458 569
459 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() { 570 Cryptographer* SyncEncryptionHandlerImpl::GetCryptographerUnsafe() {
460 DCHECK(thread_checker_.CalledOnValidThread()); 571 DCHECK(thread_checker_.CalledOnValidThread());
461 return &vault_unsafe_.cryptographer; 572 return &vault_unsafe_.cryptographer;
462 } 573 }
463 574
464 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() { 575 ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypesUnsafe() {
465 DCHECK(thread_checker_.CalledOnValidThread()); 576 DCHECK(thread_checker_.CalledOnValidThread());
466 return vault_unsafe_.encrypted_types; 577 return vault_unsafe_.encrypted_types;
467 } 578 }
468 579
580 bool SyncEncryptionHandlerImpl::MigratedToKeystore() {
581 DCHECK(thread_checker_.CalledOnValidThread());
582 ReadTransaction trans(FROM_HERE, user_share_);
583 ReadNode nigori_node(&trans);
584 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
585 return false;
586 return IsNigoriMigratedToKeystore(nigori_node.GetNigoriSpecifics());
587 }
588
469 // This function iterates over all encrypted types. There are many scenarios in 589 // This function iterates over all encrypted types. There are many scenarios in
470 // which data for some or all types is not currently available. In that case, 590 // which data for some or all types is not currently available. In that case,
471 // the lookup of the root node will fail and we will skip encryption for that 591 // the lookup of the root node will fail and we will skip encryption for that
472 // type. 592 // type.
473 void SyncEncryptionHandlerImpl::ReEncryptEverything( 593 void SyncEncryptionHandlerImpl::ReEncryptEverything(
474 WriteTransaction* trans) { 594 WriteTransaction* trans) {
475 DCHECK(thread_checker_.CalledOnValidThread()); 595 DCHECK(thread_checker_.CalledOnValidThread());
476 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); 596 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready());
477 for (ModelTypeSet::Iterator iter = 597 for (ModelTypeSet::Iterator iter =
478 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); 598 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 OnEncryptionComplete()); 657 OnEncryptionComplete());
538 } 658 }
539 659
540 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( 660 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl(
541 const sync_pb::NigoriSpecifics& nigori, 661 const sync_pb::NigoriSpecifics& nigori,
542 syncable::BaseTransaction* const trans) { 662 syncable::BaseTransaction* const trans) {
543 DCHECK(thread_checker_.CalledOnValidThread()); 663 DCHECK(thread_checker_.CalledOnValidThread());
544 DVLOG(1) << "Applying nigori node update."; 664 DVLOG(1) << "Applying nigori node update.";
545 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori, 665 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori,
546 trans); 666 trans);
547 if (nigori.using_explicit_passphrase() && 667 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori);
548 passphrase_state_ != CUSTOM_PASSPHRASE) { 668 if (is_nigori_migrated) {
549 passphrase_state_ = CUSTOM_PASSPHRASE; 669 migration_time_ms_ = nigori.keystore_migration_time();
550 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 670 PassphraseType nigori_passphrase_type =
551 OnPassphraseStateChanged(passphrase_state_)); 671 ProtoPassphraseTypeToEnum(nigori.passphrase_type());
672
673 // Only update the local passphrase state if it's a valid transition:
674 // - implicit -> keystore
675 // - implicit -> frozen implicit
676 // - implicit -> custom
677 // - keystore -> custom
678 if (passphrase_type_ != nigori_passphrase_type &&
679 nigori_passphrase_type != IMPLICIT_PASSPHRASE &&
680 (passphrase_type_ == IMPLICIT_PASSPHRASE ||
681 nigori_passphrase_type == CUSTOM_PASSPHRASE)) {
tim (not reviewing) 2012/09/10 20:41:52 in theory passphrase_type_ = frozen implicit can s
Nicolas Zea 2012/09/11 14:21:31 I actually think that's okay. This leaves some roo
682 DVLOG(1) << "Changing passphrase state from "
683 << PassphraseTypeToString(passphrase_type_)
684 << " to "
685 << PassphraseTypeToString(nigori_passphrase_type);
686 passphrase_type_ = nigori_passphrase_type;
687 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
688 OnPassphraseTypeChanged(passphrase_type_));
689 }
690 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) {
691 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE "
692 << "due to full encryption.";
tim (not reviewing) 2012/09/10 20:41:52 I think a comment here explaining that this is eff
Nicolas Zea 2012/09/11 14:21:31 Done.
693 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE;
694 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
695 OnPassphraseTypeChanged(passphrase_type_));
696 }
697 } else {
698 // It's possible that while we're waiting for migration another old
tim (not reviewing) 2012/09/10 20:41:52 "another old client"... what does 'old' mean here?
Nicolas Zea 2012/09/11 14:21:31 Old client means those that do not have keystore e
699 // client enables a custom passphrase.
700 if (nigori.frozen_keybag() &&
tim (not reviewing) 2012/09/10 20:41:52 can we call this keybag_is_frozen()? Everytime I
Nicolas Zea 2012/09/11 14:21:31 Done.
701 passphrase_type_ != CUSTOM_PASSPHRASE) {
702 passphrase_type_ = CUSTOM_PASSPHRASE;
tim (not reviewing) 2012/09/10 20:41:52 before setting, can we DCHECK that passphrase_type
Nicolas Zea 2012/09/11 14:21:31 That dcheck might fire due to nigori races. We han
703 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
704 OnPassphraseTypeChanged(passphrase_type_));
705 }
552 } 706 }
553 707
554 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; 708 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer;
555 bool nigori_needs_new_keys = false; 709 bool nigori_needs_new_keys = false;
556 if (!nigori.encrypted().blob().empty()) { 710 if (!nigori.encryption_keybag().blob().empty()) {
557 if (cryptographer->CanDecrypt(nigori.encrypted())) { 711 // We only update the default passphrase if this was a new explicit
tim (not reviewing) 2012/09/10 20:41:52 nit - '...update the default key...' / need_new_de
558 cryptographer->InstallKeys(nigori.encrypted()); 712 // passphrase. Else, since it was decryptable, it must not have been a new
559 // We only update the default passphrase if this was a new explicit 713 // key.
560 // passphrase. Else, since it was decryptable, it must not have been a new 714 bool need_new_default = false;
561 // key. 715 if (is_nigori_migrated) {
562 if (nigori.using_explicit_passphrase()) 716 need_new_default = IsExplicitPassphrase(
563 cryptographer->SetDefaultKey(nigori.encrypted().key_name()); 717 ProtoPassphraseTypeToEnum(nigori.passphrase_type()));
564
565 // Check if the cryptographer's keybag is newer than the nigori's
566 // keybag. If so, we need to overwrite the nigori node.
567 sync_pb::EncryptedData new_keys = nigori.encrypted();
568 if (!cryptographer->GetKeys(&new_keys))
569 NOTREACHED();
570 if (nigori.encrypted().SerializeAsString() !=
571 new_keys.SerializeAsString())
572 nigori_needs_new_keys = true;
573 } else { 718 } else {
574 cryptographer->SetPendingKeys(nigori.encrypted()); 719 need_new_default = nigori.frozen_keybag();
720 }
721 if (!AttemptToInstallKeybag(nigori.encryption_keybag(),
722 need_new_default,
723 cryptographer)) {
724 // Check to see if we can decrypt the keybag using the keystore decryptor.
725 cryptographer->SetPendingKeys(nigori.encryption_keybag());
726 if (!nigori.keystore_decryptor().blob().empty() &&
727 !keystore_key_.empty()) {
728 if (DecryptPendingKeysWithKeystoreKey(keystore_key_,
729 nigori.keystore_decryptor(),
730 cryptographer)) {
731 nigori_needs_new_keys =
732 cryptographer->KeybagIsStale(nigori.encryption_keybag());
733 } else {
734 LOG(ERROR) << "Failed to decrypt pending keys using keystore "
735 << "bootstrap key.";
tim (not reviewing) 2012/09/10 20:41:52 Can we surface this somehow? Is it a LOG(ERROR) be
Nicolas Zea 2012/09/11 14:21:31 Right, if we failed to decrypt a keystore decrypto
736 }
737 }
738 } else {
739 // Keybag was installed. We write back our local keybag into the nigori
740 // node if the nigori node's keybag either contains less keys or
741 // has a different default key.
742 nigori_needs_new_keys =
743 cryptographer->KeybagIsStale(nigori.encryption_keybag());
575 } 744 }
576 } else { 745 } else {
746 // The nigori node has an empty encryption keybag. Attempt to write our
747 // local encryption keys into it.
748 LOG(WARNING) << "Nigori had empty encryption keybag.";
577 nigori_needs_new_keys = true; 749 nigori_needs_new_keys = true;
578 } 750 }
579 751
580 // If we've completed a sync cycle and the cryptographer isn't ready 752 // If we've completed a sync cycle and the cryptographer isn't ready
581 // yet or has pending keys, prompt the user for a passphrase. 753 // yet or has pending keys, prompt the user for a passphrase.
582 if (cryptographer->has_pending_keys()) { 754 if (cryptographer->has_pending_keys()) {
583 DVLOG(1) << "OnPassphraseRequired Sent"; 755 DVLOG(1) << "OnPassphraseRequired Sent";
584 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys(); 756 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys();
585 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 757 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
586 OnPassphraseRequired(REASON_DECRYPTION, 758 OnPassphraseRequired(REASON_DECRYPTION,
587 pending_keys)); 759 pending_keys));
588 } else if (!cryptographer->is_ready()) { 760 } else if (!cryptographer->is_ready()) {
589 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " 761 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not "
590 << "ready"; 762 << "ready";
591 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 763 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
592 OnPassphraseRequired(REASON_ENCRYPTION, 764 OnPassphraseRequired(REASON_ENCRYPTION,
593 sync_pb::EncryptedData())); 765 sync_pb::EncryptedData()));
594 } 766 }
595 767
596 // Check if the current local encryption state is stricter/newer than the 768 // Check if the current local encryption state is stricter/newer than the
597 // nigori state. If so, we need to overwrite the nigori node with the local 769 // nigori state. If so, we need to overwrite the nigori node with the local
598 // state. 770 // state.
599 bool explicit_passphrase = passphrase_state_ == CUSTOM_PASSPHRASE; 771 bool passphrase_type_matches = true;
600 if (nigori.using_explicit_passphrase() != explicit_passphrase || 772 if (!is_nigori_migrated) {
773 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE ||
774 passphrase_type_ == IMPLICIT_PASSPHRASE);
775 passphrase_type_matches =
776 nigori.frozen_keybag() == IsExplicitPassphrase(passphrase_type_);
777 } else {
778 passphrase_type_matches =
779 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) ==
780 passphrase_type_);
781 }
782 if (!passphrase_type_matches ||
601 nigori.encrypt_everything() != encrypt_everything_ || 783 nigori.encrypt_everything() != encrypt_everything_ ||
602 nigori_types_need_update || 784 nigori_types_need_update ||
603 nigori_needs_new_keys) { 785 nigori_needs_new_keys) {
786 DVLOG(1) << "Triggering nigori rewrite.";
604 return false; 787 return false;
605 } 788 }
606 return true; 789 return true;
607 } 790 }
608 791
609 void SyncEncryptionHandlerImpl::RewriteNigori() { 792 void SyncEncryptionHandlerImpl::RewriteNigori() {
610 DVLOG(1) << "Overwriting stale nigori node."; 793 DVLOG(1) << "Writing local encryption state into nigori.";
611 DCHECK(thread_checker_.CalledOnValidThread()); 794 DCHECK(thread_checker_.CalledOnValidThread());
612 WriteTransaction trans(FROM_HERE, user_share_); 795 WriteTransaction trans(FROM_HERE, user_share_);
613 WriteEncryptionStateToNigori(&trans); 796 WriteEncryptionStateToNigori(&trans);
614 } 797 }
615 798
616 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori( 799 void SyncEncryptionHandlerImpl::WriteEncryptionStateToNigori(
617 WriteTransaction* trans) { 800 WriteTransaction* trans) {
618 DCHECK(thread_checker_.CalledOnValidThread()); 801 DCHECK(thread_checker_.CalledOnValidThread());
619 WriteNode nigori_node(trans); 802 WriteNode nigori_node(trans);
620 // This can happen in tests that don't have nigori nodes. 803 // This can happen in tests that don't have nigori nodes.
621 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK) 804 if (nigori_node.InitByTagLookup(kNigoriTag) != BaseNode::INIT_OK)
622 return; 805 return;
806
623 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics(); 807 sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics();
624 const Cryptographer& cryptographer = 808 const Cryptographer& cryptographer =
625 UnlockVault(trans->GetWrappedTrans()).cryptographer; 809 UnlockVault(trans->GetWrappedTrans()).cryptographer;
626 if (cryptographer.is_ready() &&
627 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
628 // Does not modify the encrypted blob if the unencrypted data already
629 // matches what is about to be written.
630 sync_pb::EncryptedData original_keys = nigori.encrypted();
631 if (!cryptographer.GetKeys(nigori.mutable_encrypted()))
632 NOTREACHED();
633 810
634 if (nigori.encrypted().SerializeAsString() != 811 // Will not do anything if we shouldn't or can't migrate. Otherwise
635 original_keys.SerializeAsString()) { 812 // migrates, writing the full encryption state as it does.
636 // We've updated the nigori node's encryption keys. In order to prevent 813 if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node)) {
637 // a possible looping of two clients constantly overwriting each other, 814 if (cryptographer.is_ready() &&
638 // we limit the absolute number of overwrites per client instantiation. 815 nigori_overwrite_count_ < kNigoriOverwriteLimit) {
639 nigori_overwrite_count_++; 816 // Does not modify the encrypted blob if the unencrypted data already
640 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites", 817 // matches what is about to be written.
641 nigori_overwrite_count_); 818 sync_pb::EncryptedData original_keys = nigori.encryption_keybag();
819 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
820 NOTREACHED();
821
822 if (nigori.encryption_keybag().SerializeAsString() !=
823 original_keys.SerializeAsString()) {
824 // We've updated the nigori node's encryption keys. In order to prevent
825 // a possible looping of two clients constantly overwriting each other,
826 // we limit the absolute number of overwrites per client instantiation.
827 nigori_overwrite_count_++;
828 UMA_HISTOGRAM_COUNTS("Sync.AutoNigoriOverwrites",
829 nigori_overwrite_count_);
830 }
831
832 // Note: we don't try to set frozen_keybag here since if that
833 // is lost the user can always set it again (and we don't want to clobber
834 // any migration state). The main goal at this point is to preserve
835 // the encryption keys so all data remains decryptable.
642 } 836 }
837 syncable::UpdateNigoriFromEncryptedTypes(
838 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
839 encrypt_everything_,
840 &nigori);
643 841
644 // Note: we don't try to set using_explicit_passphrase here since if that 842 // If nothing has changed, this is a no-op.
645 // is lost the user can always set it again. The main point is to preserve 843 nigori_node.SetNigoriSpecifics(nigori);
646 // the encryption keys so all data remains decryptable.
647 } 844 }
648 syncable::UpdateNigoriFromEncryptedTypes(
649 UnlockVault(trans->GetWrappedTrans()).encrypted_types,
650 encrypt_everything_,
651 &nigori);
652
653 // If nothing has changed, this is a no-op.
654 nigori_node.SetNigoriSpecifics(nigori);
655 } 845 }
656 846
657 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori( 847 bool SyncEncryptionHandlerImpl::UpdateEncryptedTypesFromNigori(
658 const sync_pb::NigoriSpecifics& nigori, 848 const sync_pb::NigoriSpecifics& nigori,
659 syncable::BaseTransaction* const trans) { 849 syncable::BaseTransaction* const trans) {
660 DCHECK(thread_checker_.CalledOnValidThread()); 850 DCHECK(thread_checker_.CalledOnValidThread());
661 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types; 851 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
662 if (nigori.encrypt_everything()) { 852 if (nigori.encrypt_everything()) {
663 if (!encrypt_everything_) { 853 EnableEncryptEverythingImpl(trans);
664 encrypt_everything_ = true;
665 *encrypted_types = ModelTypeSet::All();
666 DVLOG(1) << "Enabling encrypt everything via nigori node update";
667 FOR_EACH_OBSERVER(
668 Observer, observers_,
669 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
670 }
671 DCHECK(encrypted_types->Equals(ModelTypeSet::All())); 854 DCHECK(encrypted_types->Equals(ModelTypeSet::All()));
672 return true; 855 return true;
856 } else if (encrypt_everything_) {
857 DCHECK(encrypted_types->Equals(ModelTypeSet::All()));
858 return false;
673 } 859 }
674 860
675 ModelTypeSet nigori_encrypted_types; 861 ModelTypeSet nigori_encrypted_types;
676 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori); 862 nigori_encrypted_types = syncable::GetEncryptedTypesFromNigori(nigori);
677 nigori_encrypted_types.PutAll(SensitiveTypes()); 863 nigori_encrypted_types.PutAll(SensitiveTypes());
678 864
679 // If anything more than the sensitive types were encrypted, and 865 // If anything more than the sensitive types were encrypted, and
680 // encrypt_everything is not explicitly set to false, we assume it means 866 // encrypt_everything is not explicitly set to false, we assume it means
681 // a client intended to enable encrypt everything. 867 // a client intended to enable encrypt everything.
682 if (!nigori.has_encrypt_everything() && 868 if (!nigori.has_encrypt_everything() &&
683 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) { 869 !Difference(nigori_encrypted_types, SensitiveTypes()).Empty()) {
684 if (!encrypt_everything_) { 870 if (!encrypt_everything_) {
685 encrypt_everything_ = true; 871 encrypt_everything_ = true;
686 *encrypted_types = ModelTypeSet::All(); 872 *encrypted_types = ModelTypeSet::All();
687 FOR_EACH_OBSERVER( 873 FOR_EACH_OBSERVER(
688 Observer, observers_, 874 Observer, observers_,
689 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_)); 875 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
690 } 876 }
691 DCHECK(encrypted_types->Equals(ModelTypeSet::All())); 877 DCHECK(encrypted_types->Equals(ModelTypeSet::All()));
692 return false; 878 return false;
693 } 879 }
694 880
695 MergeEncryptedTypes(nigori_encrypted_types, trans); 881 MergeEncryptedTypes(nigori_encrypted_types, trans);
696 return encrypted_types->Equals(nigori_encrypted_types); 882 return encrypted_types->Equals(nigori_encrypted_types);
697 } 883 }
698 884
885 void SyncEncryptionHandlerImpl::SetCustomPassphrase(
886 const std::string& passphrase,
887 WriteTransaction* trans,
888 WriteNode* nigori_node) {
889 DCHECK(thread_checker_.CalledOnValidThread());
890 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics()));
891 KeyParams key_params = {"localhost", "dummy", passphrase};
892
893 if (passphrase_type_ != KEYSTORE_PASSPHRASE) {
894 DVLOG(1) << "Failing to set a custom passphrase because one has already "
895 << "been set.";
896 FinishSetPassphrase(false, "", trans, nigori_node);
897 return;
898 }
899
900 Cryptographer* cryptographer =
901 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
902 if (cryptographer->has_pending_keys()) {
903 // This theoretically shouldn't happen, because the only way to have pending
904 // keys after migrating to keystore support is if a custom passphrase was
905 // set, which should update passpshrase_state_ and should be caught by the
906 // if statement above. For the sake of safety though, we check for it in
907 // case a client is misbehaving.
908 LOG(ERROR) << "Failing to set custom passphrase because of pending keys.";
909 FinishSetPassphrase(false, "", trans, nigori_node);
910 return;
911 }
912
913 std::string bootstrap_token;
914 if (cryptographer->AddKey(key_params)) {
915 DVLOG(1) << "Setting custom passphrase.";
916 cryptographer->GetBootstrapToken(&bootstrap_token);
917 passphrase_type_ = CUSTOM_PASSPHRASE;
918 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
919 OnPassphraseTypeChanged(passphrase_type_));
920 } else {
921 NOTREACHED() << "Failed to add key to cryptographer.";
922 return;
923 }
924 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node);
925 }
926
927 void SyncEncryptionHandlerImpl::DecryptPendingKeysWithExplicitPassphrase(
928 const std::string& passphrase,
929 WriteTransaction* trans,
930 WriteNode* nigori_node) {
931 DCHECK(thread_checker_.CalledOnValidThread());
932 DCHECK(IsExplicitPassphrase(passphrase_type_));
933 KeyParams key_params = {"localhost", "dummy", passphrase};
934
935 Cryptographer* cryptographer =
936 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
937 if (!cryptographer->has_pending_keys()) {
938 // Note that this *can* happen in a rare situation where data is
939 // re-encrypted on another client while a SetDecryptionPassphrase() call is
940 // in-flight on this client. It is rare enough that we choose to do nothing.
941 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
942 << "were no pending keys.";
943 return;
944 }
945
946 DCHECK(IsExplicitPassphrase(passphrase_type_));
947 bool success = false;
948 std::string bootstrap_token;
949 if (cryptographer->DecryptPendingKeys(key_params)) {
950 DVLOG(1) << "Explicit passphrase accepted for decryption.";
951 cryptographer->GetBootstrapToken(&bootstrap_token);
952 success = true;
953 } else {
954 DVLOG(1) << "Explicit passphrase failed to decrypt.";
955 success = false;
956 }
957 if (success && !keystore_key_.empty()) {
958 // Should already be part of the encryption keybag, but we add it just
959 // in case.
960 KeyParams key_params = {"localhost", "dummy", keystore_key_};
961 cryptographer->AddNonDefaultKey(key_params);
962 }
963 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node);
964 }
965
699 void SyncEncryptionHandlerImpl::FinishSetPassphrase( 966 void SyncEncryptionHandlerImpl::FinishSetPassphrase(
700 bool success, 967 bool success,
701 const std::string& bootstrap_token, 968 const std::string& bootstrap_token,
702 bool is_explicit,
703 WriteTransaction* trans, 969 WriteTransaction* trans,
704 WriteNode* nigori_node) { 970 WriteNode* nigori_node) {
705 DCHECK(thread_checker_.CalledOnValidThread()); 971 DCHECK(thread_checker_.CalledOnValidThread());
706 FOR_EACH_OBSERVER( 972 FOR_EACH_OBSERVER(
707 SyncEncryptionHandler::Observer, 973 SyncEncryptionHandler::Observer,
708 observers_, 974 observers_,
709 OnCryptographerStateChanged( 975 OnCryptographerStateChanged(
710 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer)); 976 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer));
711 977
712 // It's possible we need to change the bootstrap token even if we failed to 978 // It's possible we need to change the bootstrap token even if we failed to
(...skipping 16 matching lines...) Expand all
729 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 995 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
730 OnPassphraseRequired(REASON_DECRYPTION, 996 OnPassphraseRequired(REASON_DECRYPTION,
731 cryptographer.GetPendingKeys())); 997 cryptographer.GetPendingKeys()));
732 } else { 998 } else {
733 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 999 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
734 OnPassphraseRequired(REASON_ENCRYPTION, 1000 OnPassphraseRequired(REASON_ENCRYPTION,
735 sync_pb::EncryptedData())); 1001 sync_pb::EncryptedData()));
736 } 1002 }
737 return; 1003 return;
738 } 1004 }
739 1005 DCHECK(success);
740 DCHECK(cryptographer.is_ready()); 1006 DCHECK(cryptographer.is_ready());
741 1007
742 // TODO(zea): trigger migration if necessary. 1008 // Will do nothing if we're already properly migrated or unable to migrate.
tim (not reviewing) 2012/09/10 20:41:52 "Will do nothing if we're already properly migrate
Nicolas Zea 2012/09/11 14:21:31 Done.
1009 // Otherwise will update the nigori node with the current migrated state,
1010 // writing all encryption state as it does.
1011 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) {
1012 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics());
1013 // Does not modify nigori.encryption_keybag() if the original decrypted
1014 // data was the same.
1015 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag()))
1016 NOTREACHED();
1017 if (IsNigoriMigratedToKeystore(nigori)) {
1018 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_));
1019 DVLOG(1) << "Leaving nigori migration state untouched after setting"
1020 << " passphrase.";
1021 } else {
1022 nigori.set_frozen_keybag(
1023 IsExplicitPassphrase(passphrase_type_));
1024 }
1025 nigori_node->SetNigoriSpecifics(nigori);
1026 }
743 1027
744 sync_pb::NigoriSpecifics specifics(nigori_node->GetNigoriSpecifics()); 1028 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS
745 // Does not modify specifics.encrypted() if the original decrypted data was
746 // the same.
747 if (!cryptographer.GetKeys(specifics.mutable_encrypted()))
748 NOTREACHED();
749 if (is_explicit && passphrase_state_ != CUSTOM_PASSPHRASE) {
750 passphrase_state_ = CUSTOM_PASSPHRASE;
751 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
752 OnPassphraseStateChanged(passphrase_state_));
753 }
754 specifics.set_using_explicit_passphrase(is_explicit);
755 nigori_node->SetNigoriSpecifics(specifics);
756
757 // Must do this after OnPassphraseStateChanged, in order to ensure the PSS
758 // checks the passphrase state after it has been set. 1029 // checks the passphrase state after it has been set.
759 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, 1030 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
760 OnPassphraseAccepted()); 1031 OnPassphraseAccepted());
761 1032
762 // Does nothing if everything is already encrypted. 1033 // Does nothing if everything is already encrypted.
1034 // TODO(zea): If we just migrated and enabled encryption, this will be
1035 // redundant. Figure out a way to not do this unnecessarily.
763 ReEncryptEverything(trans); 1036 ReEncryptEverything(trans);
764 } 1037 }
765 1038
766 void SyncEncryptionHandlerImpl::MergeEncryptedTypes( 1039 void SyncEncryptionHandlerImpl::MergeEncryptedTypes(
767 ModelTypeSet new_encrypted_types, 1040 ModelTypeSet new_encrypted_types,
768 syncable::BaseTransaction* const trans) { 1041 syncable::BaseTransaction* const trans) {
769 DCHECK(thread_checker_.CalledOnValidThread()); 1042 DCHECK(thread_checker_.CalledOnValidThread());
770 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types; 1043 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
771 if (!encrypted_types->HasAll(new_encrypted_types)) { 1044 if (!encrypted_types->HasAll(new_encrypted_types)) {
772 *encrypted_types = new_encrypted_types; 1045 *encrypted_types = new_encrypted_types;
773 FOR_EACH_OBSERVER( 1046 FOR_EACH_OBSERVER(
774 Observer, observers_, 1047 Observer, observers_,
775 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_)); 1048 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
776 } 1049 }
777 } 1050 }
778 1051
779 SyncEncryptionHandlerImpl::Vault* SyncEncryptionHandlerImpl::UnlockVaultMutable( 1052 SyncEncryptionHandlerImpl::Vault* SyncEncryptionHandlerImpl::UnlockVaultMutable(
780 syncable::BaseTransaction* const trans) { 1053 syncable::BaseTransaction* const trans) {
781 DCHECK_EQ(user_share_->directory.get(), trans->directory()); 1054 DCHECK_EQ(user_share_->directory.get(), trans->directory());
782 return &vault_unsafe_; 1055 return &vault_unsafe_;
783 } 1056 }
784 1057
785 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault( 1058 const SyncEncryptionHandlerImpl::Vault& SyncEncryptionHandlerImpl::UnlockVault(
786 syncable::BaseTransaction* const trans) const { 1059 syncable::BaseTransaction* const trans) const {
787 DCHECK_EQ(user_share_->directory.get(), trans->directory()); 1060 DCHECK_EQ(user_share_->directory.get(), trans->directory());
788 return vault_unsafe_; 1061 return vault_unsafe_;
789 } 1062 }
790 1063
1064 bool SyncEncryptionHandlerImpl::ShouldTriggerMigration(
1065 const sync_pb::NigoriSpecifics& nigori,
1066 const Cryptographer& cryptographer) const {
1067 DCHECK(thread_checker_.CalledOnValidThread());
1068 // TODO(zea): once we're willing to have the keystore key be the only
1069 // encryption key, change this to !has_pending_keys(). For now, we need the
1070 // cryptographer to be initialized with the current GAIA pass so that older
1071 // clients (that don't have keystore support) can decrypt the keybag.
1072 if (!cryptographer.is_ready())
1073 return false;
1074 if (IsNigoriMigratedToKeystore(nigori)) {
1075 // If the nigori is already migrated but has an old passphrase state,
tim (not reviewing) 2012/09/10 20:41:52 What is an "old passphrase state"?
Nicolas Zea 2012/09/11 14:21:31 Rewritten to reflect that this is detecting a migr
1076 // re-migrate. Similarly, if the nigori has an explicit passphrase but
1077 // does not have full encryption, or the nigori has an implicit passphrase
tim (not reviewing) 2012/09/10 20:41:52 "if the nigori has an explicit passphrase but does
Nicolas Zea 2012/09/11 14:21:31 Right. Noted that these cases are also detecting t
1078 // but does have full encryption, re-migrate.
1079 if (passphrase_type_ != KEYSTORE_PASSPHRASE &&
1080 nigori.passphrase_type() ==
1081 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) {
1082 return true;
1083 } else if (IsExplicitPassphrase(passphrase_type_) &&
1084 !encrypt_everything_) {
1085 return true;
1086 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE &&
1087 encrypt_everything_) {
1088 return true;
1089 } else {
1090 return false;
1091 }
1092 } else if (keystore_key_.empty()) {
1093 // If we haven't already migrated, we don't want to do anything unless
1094 // a keystore key is available (so that those clients without keystore
1095 // encryption enabled aren't forced into new states, e.g. frozen implicit
1096 // passphrase).
1097 return false;
1098 }
1099 return true;
1100 }
1101
1102 bool SyncEncryptionHandlerImpl::AttemptToMigrateNigoriToKeystore(
1103 WriteTransaction* trans,
1104 WriteNode* nigori_node) {
1105 DCHECK(thread_checker_.CalledOnValidThread());
1106 const sync_pb::NigoriSpecifics& old_nigori =
1107 nigori_node->GetNigoriSpecifics();
1108 Cryptographer* cryptographer =
1109 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer;
1110
1111 if (!ShouldTriggerMigration(old_nigori, *cryptographer))
1112 return false;
1113
1114 DVLOG(1) << "Starting nigori migration to keystore support.";
1115 if (migration_time_ms_ == 0)
1116 migration_time_ms_ = TimeToProtoTime(base::Time::Now());
1117 sync_pb::NigoriSpecifics migrated_nigori(old_nigori);
1118 migrated_nigori.set_keystore_migration_time(migration_time_ms_);
tim (not reviewing) 2012/09/10 20:41:52 Should we be doing this before actually completing
Nicolas Zea 2012/09/11 14:21:31 Moved this down so that we don't set migration_tim
1119
1120 PassphraseType new_passphrase_type = passphrase_type_;
1121 bool new_encrypt_everything = encrypt_everything_;
1122 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) {
1123 DVLOG(1) << "Switching to frozen implicit passphrase due to already having "
1124 << "full encryption.";
1125 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE;
1126 migrated_nigori.clear_keystore_decryptor();
1127 } else if (IsExplicitPassphrase(passphrase_type_)) {
1128 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to "
1129 << "explicit passphrase";
1130 new_encrypt_everything = true;
1131 migrated_nigori.clear_keystore_decryptor();
1132 } else {
1133 DCHECK_EQ(passphrase_type_, IMPLICIT_PASSPHRASE);
1134 DCHECK(!encrypt_everything_);
1135 new_passphrase_type = KEYSTORE_PASSPHRASE;
1136 DVLOG(1) << "Switching to keystore passphrase state.";
1137 }
1138 migrated_nigori.set_encrypt_everything(new_encrypt_everything);
1139 migrated_nigori.set_passphrase_type(
1140 EnumPassphraseTypeToProto(new_passphrase_type));
1141 migrated_nigori.set_frozen_keybag(true);
1142
1143 if (!keystore_key_.empty()) {
1144 KeyParams key_params = {"localhost", "dummy", keystore_key_};
1145 if (!cryptographer->AddNonDefaultKey(key_params)) {
1146 LOG(ERROR) << "Failed to add keystore key as non-default key.";
1147 return false;
1148 }
1149 }
1150 if (new_passphrase_type == KEYSTORE_PASSPHRASE &&
1151 !GetKeystoreDecryptor(
1152 *cryptographer,
1153 keystore_key_,
1154 migrated_nigori.mutable_keystore_decryptor())) {
1155 LOG(ERROR) << "Failed to extract keystore decryptor.";
1156 return false;
1157 }
1158 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) {
1159 LOG(ERROR) << "Failed to extract encryption keybag.";
1160 return false;
1161 }
1162
1163 DVLOG(1) << "Completing nigori migration to keystore support.";
1164 nigori_node->SetNigoriSpecifics(migrated_nigori);
1165 if (passphrase_type_ != new_passphrase_type) {
1166 passphrase_type_ = new_passphrase_type;
1167 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_,
1168 OnPassphraseTypeChanged(passphrase_type_));
1169 }
1170 if (new_encrypt_everything && !encrypt_everything_) {
1171 EnableEncryptEverythingImpl(trans->GetWrappedTrans());
1172 ReEncryptEverything(trans);
1173 }
1174 return true;
1175 }
1176
1177 bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor(
1178 const Cryptographer& cryptographer,
1179 const std::string& keystore_key,
1180 sync_pb::EncryptedData* encrypted_blob) {
1181 DCHECK(thread_checker_.CalledOnValidThread());
1182 DCHECK(!keystore_key.empty());
1183 DCHECK(cryptographer.is_ready());
1184 std::string serialized_nigori;
1185 serialized_nigori = cryptographer.GetDefaultNigoriKey();
1186 if (serialized_nigori.empty()) {
1187 LOG(ERROR) << "Failed to get cryptographer bootstrap token.";
1188 return false;
1189 }
1190 Cryptographer temp_cryptographer(cryptographer.encryptor());
1191 KeyParams key_params = {"localhost", "dummy", keystore_key};
1192 if (!temp_cryptographer.AddKey(key_params))
1193 return false;
1194 if (!temp_cryptographer.EncryptString(serialized_nigori, encrypted_blob))
1195 return false;
1196 return true;
1197 }
1198
1199 bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag(
1200 const sync_pb::EncryptedData& keybag,
1201 bool update_default,
1202 Cryptographer* cryptographer) {
1203 if (!cryptographer->CanDecrypt(keybag))
1204 return false;
1205 cryptographer->InstallKeys(keybag);
1206 if (update_default)
1207 cryptographer->SetDefaultKey(keybag.key_name());
1208 return true;
1209 }
1210
1211 void SyncEncryptionHandlerImpl::EnableEncryptEverythingImpl(
1212 syncable::BaseTransaction* const trans) {
1213 ModelTypeSet* encrypted_types = &UnlockVaultMutable(trans)->encrypted_types;
1214 if (encrypt_everything_) {
1215 DCHECK(encrypted_types->Equals(ModelTypeSet::All()));
1216 return;
1217 }
1218 encrypt_everything_ = true;
1219 *encrypted_types = ModelTypeSet::All();
1220 FOR_EACH_OBSERVER(
1221 Observer, observers_,
1222 OnEncryptedTypesChanged(*encrypted_types, encrypt_everything_));
1223 }
1224
1225 bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey(
1226 const std::string& keystore_key,
1227 const sync_pb::EncryptedData& keystore_decryptor,
1228 Cryptographer* cryptographer) {
1229 DCHECK(cryptographer->has_pending_keys());
1230 if (keystore_decryptor.blob().empty())
1231 return false;
1232 Cryptographer temp_cryptographer(cryptographer->encryptor());
1233 KeyParams keystore_params = {"localhost", "dummy", keystore_key_};
1234 if (temp_cryptographer.AddKey(keystore_params) &&
1235 temp_cryptographer.CanDecrypt(keystore_decryptor)) {
1236 // Someone else migrated the nigori for us! How generous! Go ahead and
1237 // install both the keystore key and the new default encryption key
1238 // (i.e. the one provided by the keystore decryptor) into the
1239 // cryptographer.
1240 // The keystore decryptor is a keystore key encrypted blob containing
1241 // the current serialized default encryption key (and as such should be
1242 // able to decrypt the nigori node's encryption keybag).
1243 DVLOG(1) << "Attempting to decrypt pending keys using "
1244 << "keystore decryptor.";
1245 std::string serialized_nigori =
1246 temp_cryptographer.DecryptToString(keystore_decryptor);
1247 // This will decrypt the pending keys and add them if possible. The key
1248 // within |serialized_nigori| will be the default after.
1249 cryptographer->ImportNigoriKey(serialized_nigori);
1250 // Theoretically the encryption keybag should already contain the keystore
1251 // key. We explicitly add it as a safety measure.
1252 cryptographer->AddNonDefaultKey(keystore_params);
1253 if (cryptographer->is_ready()) {
1254 std::string bootstrap_token;
1255 cryptographer->GetBootstrapToken(&bootstrap_token);
1256 DVLOG(1) << "Keystore decryptor decrypted pending keys.";
1257 FOR_EACH_OBSERVER(
1258 SyncEncryptionHandler::Observer,
1259 observers_,
1260 OnBootstrapTokenUpdated(bootstrap_token,
1261 PASSPHRASE_BOOTSTRAP_TOKEN));
1262 FOR_EACH_OBSERVER(
1263 SyncEncryptionHandler::Observer,
1264 observers_,
1265 OnCryptographerStateChanged(cryptographer));
1266 return true;
1267 }
1268 }
1269 return false;
1270 }
1271
791 } // namespace browser_sync 1272 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698