| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 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 "components/sync/core_impl/sync_encryption_handler_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <queue> | 11 #include <queue> |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "base/base64.h" | 14 #include "base/base64.h" |
| 15 #include "base/bind.h" | 15 #include "base/bind.h" |
| 16 #include "base/json/json_string_value_serializer.h" | 16 #include "base/json/json_string_value_serializer.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 21 #include "base/time/time.h" | 21 #include "base/time/time.h" |
| 22 #include "base/tracked_objects.h" | 22 #include "base/tracked_objects.h" |
| 23 #include "sync/internal_api/public/read_node.h" | 23 #include "components/sync/base/cryptographer.h" |
| 24 #include "sync/internal_api/public/read_transaction.h" | 24 #include "components/sync/base/encryptor.h" |
| 25 #include "sync/internal_api/public/user_share.h" | 25 #include "components/sync/base/experiments.h" |
| 26 #include "sync/internal_api/public/util/experiments.h" | 26 #include "components/sync/base/sync_string_conversions.h" |
| 27 #include "sync/internal_api/public/util/sync_string_conversions.h" | 27 #include "components/sync/base/time.h" |
| 28 #include "sync/internal_api/public/write_node.h" | 28 #include "components/sync/core/read_node.h" |
| 29 #include "sync/internal_api/public/write_transaction.h" | 29 #include "components/sync/core/read_transaction.h" |
| 30 #include "sync/protocol/encryption.pb.h" | 30 #include "components/sync/core/user_share.h" |
| 31 #include "sync/protocol/nigori_specifics.pb.h" | 31 #include "components/sync/core/write_node.h" |
| 32 #include "sync/protocol/sync.pb.h" | 32 #include "components/sync/core/write_transaction.h" |
| 33 #include "sync/syncable/directory.h" | 33 #include "components/sync/protocol/encryption.pb.h" |
| 34 #include "sync/syncable/entry.h" | 34 #include "components/sync/protocol/nigori_specifics.pb.h" |
| 35 #include "sync/syncable/mutable_entry.h" | 35 #include "components/sync/protocol/sync.pb.h" |
| 36 #include "sync/syncable/nigori_util.h" | 36 #include "components/sync/syncable/directory.h" |
| 37 #include "sync/syncable/syncable_base_transaction.h" | 37 #include "components/sync/syncable/entry.h" |
| 38 #include "sync/syncable/syncable_model_neutral_write_transaction.h" | 38 #include "components/sync/syncable/mutable_entry.h" |
| 39 #include "sync/syncable/syncable_write_transaction.h" | 39 #include "components/sync/syncable/nigori_util.h" |
| 40 #include "sync/util/cryptographer.h" | 40 #include "components/sync/syncable/syncable_base_transaction.h" |
| 41 #include "sync/util/encryptor.h" | 41 #include "components/sync/syncable/syncable_model_neutral_write_transaction.h" |
| 42 #include "sync/util/time.h" | 42 #include "components/sync/syncable/syncable_write_transaction.h" |
| 43 | 43 |
| 44 namespace syncer { | 44 namespace syncer { |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 // The maximum number of times we will automatically overwrite the nigori node | 48 // The maximum number of times we will automatically overwrite the nigori node |
| 49 // because the encryption keys don't match (per chrome instantiation). | 49 // because the encryption keys don't match (per chrome instantiation). |
| 50 // We protect ourselves against nigori rollbacks, but it's possible two | 50 // We protect ourselves against nigori rollbacks, but it's possible two |
| 51 // different clients might have contrasting view of what the nigori node state | 51 // different clients might have contrasting view of what the nigori node state |
| 52 // should be, in which case they might ping pong (see crbug.com/119207). | 52 // should be, in which case they might ping pong (see crbug.com/119207). |
| (...skipping 24 matching lines...) Expand all Loading... |
| 77 // is migrated to support keystore encryption. In addition though, we also | 77 // is migrated to support keystore encryption. In addition though, we also |
| 78 // want to verify the conditions for proper keystore encryption functionality. | 78 // want to verify the conditions for proper keystore encryption functionality. |
| 79 // 1. Passphrase type is set. | 79 // 1. Passphrase type is set. |
| 80 // 2. Frozen keybag is true | 80 // 2. Frozen keybag is true |
| 81 // 3. If passphrase state is keystore, keystore_decryptor_token is set. | 81 // 3. If passphrase state is keystore, keystore_decryptor_token is set. |
| 82 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) { | 82 bool IsNigoriMigratedToKeystore(const sync_pb::NigoriSpecifics& nigori) { |
| 83 if (!nigori.has_passphrase_type()) | 83 if (!nigori.has_passphrase_type()) |
| 84 return false; | 84 return false; |
| 85 if (!nigori.keybag_is_frozen()) | 85 if (!nigori.keybag_is_frozen()) |
| 86 return false; | 86 return false; |
| 87 if (nigori.passphrase_type() == | 87 if (nigori.passphrase_type() == sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE) |
| 88 sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE) | |
| 89 return false; | 88 return false; |
| 90 if (nigori.passphrase_type() == | 89 if (nigori.passphrase_type() == |
| 91 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE && | 90 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE && |
| 92 nigori.keystore_decryptor_token().blob().empty()) | 91 nigori.keystore_decryptor_token().blob().empty()) |
| 93 return false; | 92 return false; |
| 94 return true; | 93 return true; |
| 95 } | 94 } |
| 96 | 95 |
| 97 PassphraseType ProtoPassphraseTypeToEnum( | 96 PassphraseType ProtoPassphraseTypeToEnum( |
| 98 sync_pb::NigoriSpecifics::PassphraseType type) { | 97 sync_pb::NigoriSpecifics::PassphraseType type) { |
| 99 switch (type) { | 98 switch (type) { |
| 100 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE: | 99 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE: |
| 101 return IMPLICIT_PASSPHRASE; | 100 return IMPLICIT_PASSPHRASE; |
| 102 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE: | 101 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE: |
| 103 return KEYSTORE_PASSPHRASE; | 102 return KEYSTORE_PASSPHRASE; |
| 104 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE: | 103 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE: |
| 105 return CUSTOM_PASSPHRASE; | 104 return CUSTOM_PASSPHRASE; |
| 106 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE: | 105 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE: |
| 107 return FROZEN_IMPLICIT_PASSPHRASE; | 106 return FROZEN_IMPLICIT_PASSPHRASE; |
| 108 default: | 107 default: |
| 109 NOTREACHED(); | 108 NOTREACHED(); |
| 110 return IMPLICIT_PASSPHRASE; | 109 return IMPLICIT_PASSPHRASE; |
| 111 } | 110 } |
| 112 } | 111 } |
| 113 | 112 |
| 114 sync_pb::NigoriSpecifics::PassphraseType | 113 sync_pb::NigoriSpecifics::PassphraseType EnumPassphraseTypeToProto( |
| 115 EnumPassphraseTypeToProto(PassphraseType type) { | 114 PassphraseType type) { |
| 116 switch (type) { | 115 switch (type) { |
| 117 case IMPLICIT_PASSPHRASE: | 116 case IMPLICIT_PASSPHRASE: |
| 118 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; | 117 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; |
| 119 case KEYSTORE_PASSPHRASE: | 118 case KEYSTORE_PASSPHRASE: |
| 120 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE; | 119 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE; |
| 121 case CUSTOM_PASSPHRASE: | 120 case CUSTOM_PASSPHRASE: |
| 122 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE; | 121 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE; |
| 123 case FROZEN_IMPLICIT_PASSPHRASE: | 122 case FROZEN_IMPLICIT_PASSPHRASE: |
| 124 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE; | 123 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE; |
| 125 default: | 124 default: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 147 keystore_key_values.AppendString(old_keystore_keys[i]); | 146 keystore_key_values.AppendString(old_keystore_keys[i]); |
| 148 keystore_key_values.AppendString(current_keystore_key); | 147 keystore_key_values.AppendString(current_keystore_key); |
| 149 | 148 |
| 150 // Update the bootstrap token. | 149 // Update the bootstrap token. |
| 151 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key | 150 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key |
| 152 // strings, with the current keystore key as the last value in the list. | 151 // strings, with the current keystore key as the last value in the list. |
| 153 std::string serialized_keystores; | 152 std::string serialized_keystores; |
| 154 JSONStringValueSerializer json(&serialized_keystores); | 153 JSONStringValueSerializer json(&serialized_keystores); |
| 155 json.Serialize(keystore_key_values); | 154 json.Serialize(keystore_key_values); |
| 156 std::string encrypted_keystores; | 155 std::string encrypted_keystores; |
| 157 encryptor->EncryptString(serialized_keystores, | 156 encryptor->EncryptString(serialized_keystores, &encrypted_keystores); |
| 158 &encrypted_keystores); | |
| 159 std::string keystore_bootstrap; | 157 std::string keystore_bootstrap; |
| 160 base::Base64Encode(encrypted_keystores, &keystore_bootstrap); | 158 base::Base64Encode(encrypted_keystores, &keystore_bootstrap); |
| 161 return keystore_bootstrap; | 159 return keystore_bootstrap; |
| 162 } | 160 } |
| 163 | 161 |
| 164 bool UnpackKeystoreBootstrapToken( | 162 bool UnpackKeystoreBootstrapToken(const std::string& keystore_bootstrap_token, |
| 165 const std::string& keystore_bootstrap_token, | 163 Encryptor* encryptor, |
| 166 Encryptor* encryptor, | 164 std::vector<std::string>* old_keystore_keys, |
| 167 std::vector<std::string>* old_keystore_keys, | 165 std::string* current_keystore_key) { |
| 168 std::string* current_keystore_key) { | |
| 169 if (keystore_bootstrap_token.empty()) | 166 if (keystore_bootstrap_token.empty()) |
| 170 return false; | 167 return false; |
| 171 std::string base64_decoded_keystore_bootstrap; | 168 std::string base64_decoded_keystore_bootstrap; |
| 172 if (!base::Base64Decode(keystore_bootstrap_token, | 169 if (!base::Base64Decode(keystore_bootstrap_token, |
| 173 &base64_decoded_keystore_bootstrap)) { | 170 &base64_decoded_keystore_bootstrap)) { |
| 174 return false; | 171 return false; |
| 175 } | 172 } |
| 176 std::string decrypted_keystore_bootstrap; | 173 std::string decrypted_keystore_bootstrap; |
| 177 if (!encryptor->DecryptString(base64_decoded_keystore_bootstrap, | 174 if (!encryptor->DecryptString(base64_decoded_keystore_bootstrap, |
| 178 &decrypted_keystore_bootstrap)) { | 175 &decrypted_keystore_bootstrap)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 193 return false; | 190 return false; |
| 194 } | 191 } |
| 195 old_keystore_keys->resize(number_of_keystore_keys - 1); | 192 old_keystore_keys->resize(number_of_keystore_keys - 1); |
| 196 for (int i = 0; i < number_of_keystore_keys - 1; ++i) | 193 for (int i = 0; i < number_of_keystore_keys - 1; ++i) |
| 197 internal_list_value->GetString(i, &(*old_keystore_keys)[i]); | 194 internal_list_value->GetString(i, &(*old_keystore_keys)[i]); |
| 198 return true; | 195 return true; |
| 199 } | 196 } |
| 200 | 197 |
| 201 } // namespace | 198 } // namespace |
| 202 | 199 |
| 203 SyncEncryptionHandlerImpl::Vault::Vault( | 200 SyncEncryptionHandlerImpl::Vault::Vault(Encryptor* encryptor, |
| 204 Encryptor* encryptor, | 201 ModelTypeSet encrypted_types) |
| 205 ModelTypeSet encrypted_types) | 202 : cryptographer(encryptor), encrypted_types(encrypted_types) {} |
| 206 : cryptographer(encryptor), | |
| 207 encrypted_types(encrypted_types) { | |
| 208 } | |
| 209 | 203 |
| 210 SyncEncryptionHandlerImpl::Vault::~Vault() { | 204 SyncEncryptionHandlerImpl::Vault::~Vault() {} |
| 211 } | |
| 212 | 205 |
| 213 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( | 206 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( |
| 214 UserShare* user_share, | 207 UserShare* user_share, |
| 215 Encryptor* encryptor, | 208 Encryptor* encryptor, |
| 216 const std::string& restored_key_for_bootstrapping, | 209 const std::string& restored_key_for_bootstrapping, |
| 217 const std::string& restored_keystore_key_for_bootstrapping) | 210 const std::string& restored_keystore_key_for_bootstrapping) |
| 218 : user_share_(user_share), | 211 : user_share_(user_share), |
| 219 vault_unsafe_(encryptor, SensitiveTypes()), | 212 vault_unsafe_(encryptor, SensitiveTypes()), |
| 220 encrypt_everything_(false), | 213 encrypt_everything_(false), |
| 221 passphrase_type_(IMPLICIT_PASSPHRASE), | 214 passphrase_type_(IMPLICIT_PASSPHRASE), |
| 222 nigori_overwrite_count_(0), | 215 nigori_overwrite_count_(0), |
| 223 weak_ptr_factory_(this) { | 216 weak_ptr_factory_(this) { |
| 224 // Restore the cryptographer's previous keys. Note that we don't add the | 217 // Restore the cryptographer's previous keys. Note that we don't add the |
| 225 // keystore keys into the cryptographer here, in case a migration was pending. | 218 // keystore keys into the cryptographer here, in case a migration was pending. |
| 226 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); | 219 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); |
| 227 | 220 |
| 228 // If this fails, we won't have a valid keystore key, and will simply request | 221 // If this fails, we won't have a valid keystore key, and will simply request |
| 229 // new ones from the server on the next DownloadUpdates. | 222 // new ones from the server on the next DownloadUpdates. |
| 230 UnpackKeystoreBootstrapToken( | 223 UnpackKeystoreBootstrapToken(restored_keystore_key_for_bootstrapping, |
| 231 restored_keystore_key_for_bootstrapping, | 224 encryptor, &old_keystore_keys_, &keystore_key_); |
| 232 encryptor, | |
| 233 &old_keystore_keys_, | |
| 234 &keystore_key_); | |
| 235 } | 225 } |
| 236 | 226 |
| 237 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} | 227 SyncEncryptionHandlerImpl::~SyncEncryptionHandlerImpl() {} |
| 238 | 228 |
| 239 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { | 229 void SyncEncryptionHandlerImpl::AddObserver(Observer* observer) { |
| 240 DCHECK(thread_checker_.CalledOnValidThread()); | 230 DCHECK(thread_checker_.CalledOnValidThread()); |
| 241 DCHECK(!observers_.HasObserver(observer)); | 231 DCHECK(!observers_.HasObserver(observer)); |
| 242 observers_.AddObserver(observer); | 232 observers_.AddObserver(observer); |
| 243 } | 233 } |
| 244 | 234 |
| 245 void SyncEncryptionHandlerImpl::RemoveObserver(Observer* observer) { | 235 void SyncEncryptionHandlerImpl::RemoveObserver(Observer* observer) { |
| 246 DCHECK(thread_checker_.CalledOnValidThread()); | 236 DCHECK(thread_checker_.CalledOnValidThread()); |
| 247 DCHECK(observers_.HasObserver(observer)); | 237 DCHECK(observers_.HasObserver(observer)); |
| 248 observers_.RemoveObserver(observer); | 238 observers_.RemoveObserver(observer); |
| 249 } | 239 } |
| 250 | 240 |
| 251 void SyncEncryptionHandlerImpl::Init() { | 241 void SyncEncryptionHandlerImpl::Init() { |
| 252 DCHECK(thread_checker_.CalledOnValidThread()); | 242 DCHECK(thread_checker_.CalledOnValidThread()); |
| 253 WriteTransaction trans(FROM_HERE, user_share_); | 243 WriteTransaction trans(FROM_HERE, user_share_); |
| 254 WriteNode node(&trans); | 244 WriteNode node(&trans); |
| 255 | 245 |
| 256 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) | 246 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) |
| 257 return; | 247 return; |
| 258 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(), | 248 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(), |
| 259 trans.GetWrappedTrans())) { | 249 trans.GetWrappedTrans())) { |
| 260 WriteEncryptionStateToNigori(&trans); | 250 WriteEncryptionStateToNigori(&trans); |
| 261 } | 251 } |
| 262 | 252 |
| 263 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType", | 253 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType", GetPassphraseType(), |
| 264 GetPassphraseType(), | |
| 265 PASSPHRASE_TYPE_SIZE); | 254 PASSPHRASE_TYPE_SIZE); |
| 266 | 255 |
| 267 bool has_pending_keys = UnlockVault( | 256 bool has_pending_keys = |
| 268 trans.GetWrappedTrans()).cryptographer.has_pending_keys(); | 257 UnlockVault(trans.GetWrappedTrans()).cryptographer.has_pending_keys(); |
| 269 bool is_ready = UnlockVault( | 258 bool is_ready = UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready(); |
| 270 trans.GetWrappedTrans()).cryptographer.is_ready(); | |
| 271 // Log the state of the cryptographer regardless of migration state. | 259 // Log the state of the cryptographer regardless of migration state. |
| 272 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready); | 260 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready); |
| 273 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys); | 261 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys); |
| 274 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) { | 262 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) { |
| 275 // This account has a nigori node that has been migrated to support | 263 // This account has a nigori node that has been migrated to support |
| 276 // keystore. | 264 // keystore. |
| 277 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", | 265 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", MIGRATED, |
| 278 MIGRATED, | |
| 279 MIGRATION_STATE_SIZE); | 266 MIGRATION_STATE_SIZE); |
| 280 if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) { | 267 if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) { |
| 281 // If this is happening, it means the keystore decryptor is either | 268 // If this is happening, it means the keystore decryptor is either |
| 282 // undecryptable with the available keystore keys or does not match the | 269 // undecryptable with the available keystore keys or does not match the |
| 283 // nigori keybag's encryption key. Otherwise we're simply missing the | 270 // nigori keybag's encryption key. Otherwise we're simply missing the |
| 284 // keystore key. | 271 // keystore key. |
| 285 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed", | 272 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed", |
| 286 !keystore_key_.empty()); | 273 !keystore_key_.empty()); |
| 287 } | 274 } |
| 288 } else if (!is_ready) { | 275 } else if (!is_ready) { |
| 289 // Migration cannot occur until the cryptographer is ready (initialized | 276 // Migration cannot occur until the cryptographer is ready (initialized |
| 290 // with GAIA password and any pending keys resolved). | 277 // with GAIA password and any pending keys resolved). |
| 291 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", | 278 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", |
| 292 NOT_MIGRATED_CRYPTO_NOT_READY, | 279 NOT_MIGRATED_CRYPTO_NOT_READY, |
| 293 MIGRATION_STATE_SIZE); | 280 MIGRATION_STATE_SIZE); |
| 294 } else if (keystore_key_.empty()) { | 281 } else if (keystore_key_.empty()) { |
| 295 // The client has no keystore key, either because it is not yet enabled or | 282 // The client has no keystore key, either because it is not yet enabled or |
| 296 // the server is not sending a valid keystore key. | 283 // the server is not sending a valid keystore key. |
| 297 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", | 284 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", |
| 298 NOT_MIGRATED_NO_KEYSTORE_KEY, | 285 NOT_MIGRATED_NO_KEYSTORE_KEY, |
| 299 MIGRATION_STATE_SIZE); | 286 MIGRATION_STATE_SIZE); |
| 300 } else { | 287 } else { |
| 301 // If the above conditions have been met and the nigori node is still not | 288 // If the above conditions have been met and the nigori node is still not |
| 302 // migrated, something failed in the migration process. | 289 // migrated, something failed in the migration process. |
| 303 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", | 290 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", |
| 304 NOT_MIGRATED_UNKNOWN_REASON, | 291 NOT_MIGRATED_UNKNOWN_REASON, |
| 305 MIGRATION_STATE_SIZE); | 292 MIGRATION_STATE_SIZE); |
| 306 } | 293 } |
| 307 | 294 |
| 308 | |
| 309 // Always trigger an encrypted types and cryptographer state change event at | 295 // Always trigger an encrypted types and cryptographer state change event at |
| 310 // init time so observers get the initial values. | 296 // init time so observers get the initial values. |
| 297 FOR_EACH_OBSERVER(Observer, observers_, |
| 298 OnEncryptedTypesChanged( |
| 299 UnlockVault(trans.GetWrappedTrans()).encrypted_types, |
| 300 encrypt_everything_)); |
| 311 FOR_EACH_OBSERVER( | 301 FOR_EACH_OBSERVER( |
| 312 Observer, observers_, | 302 SyncEncryptionHandler::Observer, observers_, |
| 313 OnEncryptedTypesChanged( | |
| 314 UnlockVault(trans.GetWrappedTrans()).encrypted_types, | |
| 315 encrypt_everything_)); | |
| 316 FOR_EACH_OBSERVER( | |
| 317 SyncEncryptionHandler::Observer, | |
| 318 observers_, | |
| 319 OnCryptographerStateChanged( | 303 OnCryptographerStateChanged( |
| 320 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer)); | 304 &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer)); |
| 321 | 305 |
| 322 // If the cryptographer is not ready (either it has pending keys or we | 306 // If the cryptographer is not ready (either it has pending keys or we |
| 323 // failed to initialize it), we don't want to try and re-encrypt the data. | 307 // failed to initialize it), we don't want to try and re-encrypt the data. |
| 324 // If we had encrypted types, the DataTypeManager will block, preventing | 308 // If we had encrypted types, the DataTypeManager will block, preventing |
| 325 // sync from happening until the the passphrase is provided. | 309 // sync from happening until the the passphrase is provided. |
| 326 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) | 310 if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) |
| 327 ReEncryptEverything(&trans); | 311 ReEncryptEverything(&trans); |
| 328 } | 312 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 if (cryptographer->AddKey(key_params)) { | 386 if (cryptographer->AddKey(key_params)) { |
| 403 // Case 1 and 2. We set a new GAIA passphrase when there are no pending | 387 // Case 1 and 2. We set a new GAIA passphrase when there are no pending |
| 404 // keys (1), or overwriting an implicit passphrase with a new explicit | 388 // keys (1), or overwriting an implicit passphrase with a new explicit |
| 405 // one (2) when there are no pending keys. | 389 // one (2) when there are no pending keys. |
| 406 if (is_explicit) { | 390 if (is_explicit) { |
| 407 DVLOG(1) << "Setting explicit passphrase for encryption."; | 391 DVLOG(1) << "Setting explicit passphrase for encryption."; |
| 408 passphrase_type_ = CUSTOM_PASSPHRASE; | 392 passphrase_type_ = CUSTOM_PASSPHRASE; |
| 409 custom_passphrase_time_ = base::Time::Now(); | 393 custom_passphrase_time_ = base::Time::Now(); |
| 410 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 394 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 411 OnPassphraseTypeChanged( | 395 OnPassphraseTypeChanged( |
| 412 passphrase_type_, | 396 passphrase_type_, GetExplicitPassphraseTime())); |
| 413 GetExplicitPassphraseTime())); | |
| 414 } else { | 397 } else { |
| 415 DVLOG(1) << "Setting implicit passphrase for encryption."; | 398 DVLOG(1) << "Setting implicit passphrase for encryption."; |
| 416 } | 399 } |
| 417 cryptographer->GetBootstrapToken(&bootstrap_token); | 400 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 418 | 401 |
| 419 // With M26, sync accounts can be in only one of two encryption states: | 402 // With M26, sync accounts can be in only one of two encryption states: |
| 420 // 1) Encrypt only passwords with an implicit passphrase. | 403 // 1) Encrypt only passwords with an implicit passphrase. |
| 421 // 2) Encrypt all sync datatypes with an explicit passphrase. | 404 // 2) Encrypt all sync datatypes with an explicit passphrase. |
| 422 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms, | 405 // We deprecate the "EncryptAllData" and "CustomPassphrase" histograms, |
| 423 // and keep track of an account's encryption state via the | 406 // and keep track of an account's encryption state via the |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 Cryptographer temp_cryptographer(cryptographer->encryptor()); | 438 Cryptographer temp_cryptographer(cryptographer->encryptor()); |
| 456 temp_cryptographer.AddKey(key_params); | 439 temp_cryptographer.AddKey(key_params); |
| 457 temp_cryptographer.GetBootstrapToken(&bootstrap_token); | 440 temp_cryptographer.GetBootstrapToken(&bootstrap_token); |
| 458 // We then set the new passphrase as the default passphrase of the | 441 // We then set the new passphrase as the default passphrase of the |
| 459 // real cryptographer, even though we have pending keys. This is safe, | 442 // real cryptographer, even though we have pending keys. This is safe, |
| 460 // as although Cryptographer::is_initialized() will now be true, | 443 // as although Cryptographer::is_initialized() will now be true, |
| 461 // is_ready() will remain false due to having pending keys. | 444 // is_ready() will remain false due to having pending keys. |
| 462 cryptographer->AddKey(key_params); | 445 cryptographer->AddKey(key_params); |
| 463 success = false; | 446 success = false; |
| 464 } | 447 } |
| 465 } // is_explicit | 448 } // is_explicit |
| 466 } // cryptographer->has_pending_keys() | 449 } // cryptographer->has_pending_keys() |
| 467 } else { // IsExplicitPassphrase(passphrase_type_) == true. | 450 } else { // IsExplicitPassphrase(passphrase_type_) == true. |
| 468 // Case 6. We do not want to override a previously set explicit passphrase, | 451 // Case 6. We do not want to override a previously set explicit passphrase, |
| 469 // so we return a failure. | 452 // so we return a failure. |
| 470 DVLOG(1) << "Failing because an explicit passphrase is already set."; | 453 DVLOG(1) << "Failing because an explicit passphrase is already set."; |
| 471 success = false; | 454 success = false; |
| 472 } | 455 } |
| 473 | 456 |
| 474 DVLOG_IF(1, !success) | 457 DVLOG_IF(1, !success) |
| 475 << "Failure in SetEncryptionPassphrase; notifying and returning."; | 458 << "Failure in SetEncryptionPassphrase; notifying and returning."; |
| 476 DVLOG_IF(1, success) | 459 DVLOG_IF(1, success) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 success = true; | 548 success = true; |
| 566 } else { | 549 } else { |
| 567 // Case 8. The pending keybag does not contain the current default | 550 // Case 8. The pending keybag does not contain the current default |
| 568 // encryption key. We decrypt the pending keys here, and in | 551 // encryption key. We decrypt the pending keys here, and in |
| 569 // FinishSetPassphrase, re-encrypt everything with the current GAIA | 552 // FinishSetPassphrase, re-encrypt everything with the current GAIA |
| 570 // passphrase instead of the passphrase just provided by the user. | 553 // passphrase instead of the passphrase just provided by the user. |
| 571 DVLOG(1) << "Implicit user provided passphrase accepted for " | 554 DVLOG(1) << "Implicit user provided passphrase accepted for " |
| 572 << "decryption, restoring implicit internal passphrase " | 555 << "decryption, restoring implicit internal passphrase " |
| 573 << "as default."; | 556 << "as default."; |
| 574 std::string bootstrap_token_from_current_key; | 557 std::string bootstrap_token_from_current_key; |
| 575 cryptographer->GetBootstrapToken( | 558 cryptographer->GetBootstrapToken(&bootstrap_token_from_current_key); |
| 576 &bootstrap_token_from_current_key); | |
| 577 cryptographer->DecryptPendingKeys(key_params); | 559 cryptographer->DecryptPendingKeys(key_params); |
| 578 // Overwrite the default from the pending keys. | 560 // Overwrite the default from the pending keys. |
| 579 cryptographer->AddKeyFromBootstrapToken( | 561 cryptographer->AddKeyFromBootstrapToken( |
| 580 bootstrap_token_from_current_key); | 562 bootstrap_token_from_current_key); |
| 581 success = true; | 563 success = true; |
| 582 } | 564 } |
| 583 } else { // !temp_cryptographer.DecryptPendingKeys(..) | 565 } else { // !temp_cryptographer.DecryptPendingKeys(..) |
| 584 DVLOG(1) << "Implicit user provided passphrase failed to decrypt."; | 566 DVLOG(1) << "Implicit user provided passphrase failed to decrypt."; |
| 585 success = false; | 567 success = false; |
| 586 } // temp_cryptographer.DecryptPendingKeys(...) | 568 } // temp_cryptographer.DecryptPendingKeys(...) |
| 587 } else { // cryptographer->is_initialized() == false | 569 } else { // cryptographer->is_initialized() == false |
| 588 if (cryptographer->DecryptPendingKeys(key_params)) { | 570 if (cryptographer->DecryptPendingKeys(key_params)) { |
| 589 // This can happpen in two cases: | 571 // This can happpen in two cases: |
| 590 // - First time sync on android, where we'll never have a | 572 // - First time sync on android, where we'll never have a |
| 591 // !user_provided passphrase. | 573 // !user_provided passphrase. |
| 592 // - This is a restart for a client that lost their bootstrap token. | 574 // - This is a restart for a client that lost their bootstrap token. |
| 593 // In both cases, we should go ahead and initialize the cryptographer | 575 // In both cases, we should go ahead and initialize the cryptographer |
| 594 // and persist the new bootstrap token. | 576 // and persist the new bootstrap token. |
| 595 // | 577 // |
| 596 // Note: at this point, we cannot distinguish between cases 7 and 8 | 578 // Note: at this point, we cannot distinguish between cases 7 and 8 |
| 597 // above. This user provided passphrase could be the current or the | 579 // above. This user provided passphrase could be the current or the |
| 598 // old. But, as long as we persist the token, there's nothing more | 580 // old. But, as long as we persist the token, there's nothing more |
| 599 // we can do. | 581 // we can do. |
| 600 cryptographer->GetBootstrapToken(&bootstrap_token); | 582 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 601 DVLOG(1) << "Implicit user provided passphrase accepted, initializing" | 583 DVLOG(1) << "Implicit user provided passphrase accepted, initializing" |
| 602 << " cryptographer."; | 584 << " cryptographer."; |
| 603 success = true; | 585 success = true; |
| 604 } else { | 586 } else { |
| 605 DVLOG(1) << "Implicit user provided passphrase failed to decrypt."; | 587 DVLOG(1) << "Implicit user provided passphrase failed to decrypt."; |
| 606 success = false; | 588 success = false; |
| 607 } | 589 } |
| 608 } // cryptographer->is_initialized() | 590 } // cryptographer->is_initialized() |
| 609 } else { // nigori_has_explicit_passphrase == true | 591 } else { // nigori_has_explicit_passphrase == true |
| 610 // Case 9. Encryption was done with an explicit passphrase, and we decrypt | 592 // Case 9. Encryption was done with an explicit passphrase, and we decrypt |
| 611 // with the passphrase provided by the user. | 593 // with the passphrase provided by the user. |
| 612 if (cryptographer->DecryptPendingKeys(key_params)) { | 594 if (cryptographer->DecryptPendingKeys(key_params)) { |
| 613 DVLOG(1) << "Explicit passphrase accepted for decryption."; | 595 DVLOG(1) << "Explicit passphrase accepted for decryption."; |
| 614 cryptographer->GetBootstrapToken(&bootstrap_token); | 596 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 615 success = true; | 597 success = true; |
| 616 } else { | 598 } else { |
| 617 DVLOG(1) << "Explicit passphrase failed to decrypt."; | 599 DVLOG(1) << "Explicit passphrase failed to decrypt."; |
| 618 success = false; | 600 success = false; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 syncable::BaseTransaction* const trans) { | 639 syncable::BaseTransaction* const trans) { |
| 658 DCHECK(thread_checker_.CalledOnValidThread()); | 640 DCHECK(thread_checker_.CalledOnValidThread()); |
| 659 DCHECK(trans); | 641 DCHECK(trans); |
| 660 if (!ApplyNigoriUpdateImpl(nigori, trans)) { | 642 if (!ApplyNigoriUpdateImpl(nigori, trans)) { |
| 661 base::ThreadTaskRunnerHandle::Get()->PostTask( | 643 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 662 FROM_HERE, base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, | 644 FROM_HERE, base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, |
| 663 weak_ptr_factory_.GetWeakPtr())); | 645 weak_ptr_factory_.GetWeakPtr())); |
| 664 } | 646 } |
| 665 | 647 |
| 666 FOR_EACH_OBSERVER( | 648 FOR_EACH_OBSERVER( |
| 667 SyncEncryptionHandler::Observer, | 649 SyncEncryptionHandler::Observer, observers_, |
| 668 observers_, | 650 OnCryptographerStateChanged(&UnlockVaultMutable(trans)->cryptographer)); |
| 669 OnCryptographerStateChanged( | |
| 670 &UnlockVaultMutable(trans)->cryptographer)); | |
| 671 } | 651 } |
| 672 | 652 |
| 673 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes( | 653 void SyncEncryptionHandlerImpl::UpdateNigoriFromEncryptedTypes( |
| 674 sync_pb::NigoriSpecifics* nigori, | 654 sync_pb::NigoriSpecifics* nigori, |
| 675 syncable::BaseTransaction* const trans) const { | 655 syncable::BaseTransaction* const trans) const { |
| 676 DCHECK(thread_checker_.CalledOnValidThread()); | 656 DCHECK(thread_checker_.CalledOnValidThread()); |
| 677 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types, | 657 syncable::UpdateNigoriFromEncryptedTypes(UnlockVault(trans).encrypted_types, |
| 678 encrypt_everything_, | 658 encrypt_everything_, nigori); |
| 679 nigori); | |
| 680 } | 659 } |
| 681 | 660 |
| 682 bool SyncEncryptionHandlerImpl::NeedKeystoreKey( | 661 bool SyncEncryptionHandlerImpl::NeedKeystoreKey( |
| 683 syncable::BaseTransaction* const trans) const { | 662 syncable::BaseTransaction* const trans) const { |
| 684 DCHECK(thread_checker_.CalledOnValidThread()); | 663 DCHECK(thread_checker_.CalledOnValidThread()); |
| 685 return keystore_key_.empty(); | 664 return keystore_key_.empty(); |
| 686 } | 665 } |
| 687 | 666 |
| 688 bool SyncEncryptionHandlerImpl::SetKeystoreKeys( | 667 bool SyncEncryptionHandlerImpl::SetKeystoreKeys( |
| 689 const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys, | 668 const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 706 old_keystore_keys_.resize(keys.size() - 1); | 685 old_keystore_keys_.resize(keys.size() - 1); |
| 707 for (int i = 0; i < keys.size() - 1; ++i) | 686 for (int i = 0; i < keys.size() - 1; ++i) |
| 708 base::Base64Encode(keys.Get(i), &old_keystore_keys_[i]); | 687 base::Base64Encode(keys.Get(i), &old_keystore_keys_[i]); |
| 709 | 688 |
| 710 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; | 689 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; |
| 711 | 690 |
| 712 // Update the bootstrap token. If this fails, we persist an empty string, | 691 // Update the bootstrap token. If this fails, we persist an empty string, |
| 713 // which will force us to download the keystore keys again on the next | 692 // which will force us to download the keystore keys again on the next |
| 714 // restart. | 693 // restart. |
| 715 std::string keystore_bootstrap = PackKeystoreBootstrapToken( | 694 std::string keystore_bootstrap = PackKeystoreBootstrapToken( |
| 716 old_keystore_keys_, | 695 old_keystore_keys_, keystore_key_, cryptographer->encryptor()); |
| 717 keystore_key_, | |
| 718 cryptographer->encryptor()); | |
| 719 | 696 |
| 720 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 697 FOR_EACH_OBSERVER( |
| 721 OnBootstrapTokenUpdated(keystore_bootstrap, | 698 SyncEncryptionHandler::Observer, observers_, |
| 722 KEYSTORE_BOOTSTRAP_TOKEN)); | 699 OnBootstrapTokenUpdated(keystore_bootstrap, KEYSTORE_BOOTSTRAP_TOKEN)); |
| 723 DVLOG(1) << "Keystore bootstrap token updated."; | 700 DVLOG(1) << "Keystore bootstrap token updated."; |
| 724 | 701 |
| 725 // If this is a first time sync, we get the encryption keys before we process | 702 // If this is a first time sync, we get the encryption keys before we process |
| 726 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked | 703 // the nigori node. Just return for now, ApplyNigoriUpdate will be invoked |
| 727 // once we have the nigori node. | 704 // once we have the nigori node. |
| 728 syncable::Entry entry(trans, syncable::GET_TYPE_ROOT, NIGORI); | 705 syncable::Entry entry(trans, syncable::GET_TYPE_ROOT, NIGORI); |
| 729 if (!entry.good()) | 706 if (!entry.good()) |
| 730 return true; | 707 return true; |
| 731 | 708 |
| 732 const sync_pb::NigoriSpecifics& nigori = | 709 const sync_pb::NigoriSpecifics& nigori = entry.GetSpecifics().nigori(); |
| 733 entry.GetSpecifics().nigori(); | 710 if (cryptographer->has_pending_keys() && IsNigoriMigratedToKeystore(nigori) && |
| 734 if (cryptographer->has_pending_keys() && | |
| 735 IsNigoriMigratedToKeystore(nigori) && | |
| 736 !nigori.keystore_decryptor_token().blob().empty()) { | 711 !nigori.keystore_decryptor_token().blob().empty()) { |
| 737 // If the nigori is already migrated and we have pending keys, we might | 712 // If the nigori is already migrated and we have pending keys, we might |
| 738 // be able to decrypt them using either the keystore decryptor token | 713 // be able to decrypt them using either the keystore decryptor token |
| 739 // or the existing keystore keys. | 714 // or the existing keystore keys. |
| 740 DecryptPendingKeysWithKeystoreKey(keystore_key_, | 715 DecryptPendingKeysWithKeystoreKey( |
| 741 nigori.keystore_decryptor_token(), | 716 keystore_key_, nigori.keystore_decryptor_token(), cryptographer); |
| 742 cryptographer); | |
| 743 } | 717 } |
| 744 | 718 |
| 745 // Note that triggering migration will have no effect if we're already | 719 // Note that triggering migration will have no effect if we're already |
| 746 // properly migrated with the newest keystore keys. | 720 // properly migrated with the newest keystore keys. |
| 747 if (ShouldTriggerMigration(nigori, *cryptographer)) { | 721 if (ShouldTriggerMigration(nigori, *cryptographer)) { |
| 748 base::ThreadTaskRunnerHandle::Get()->PostTask( | 722 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 749 FROM_HERE, base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, | 723 FROM_HERE, base::Bind(&SyncEncryptionHandlerImpl::RewriteNigori, |
| 750 weak_ptr_factory_.GetWeakPtr())); | 724 weak_ptr_factory_.GetWeakPtr())); |
| 751 } | 725 } |
| 752 | 726 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 mutable_entry.PutSpecifics(specifics); | 787 mutable_entry.PutSpecifics(specifics); |
| 814 | 788 |
| 815 // Update our state based on the saved nigori node. | 789 // Update our state based on the saved nigori node. |
| 816 ApplyNigoriUpdate(nigori_state.nigori_specifics, trans.GetWrappedTrans()); | 790 ApplyNigoriUpdate(nigori_state.nigori_specifics, trans.GetWrappedTrans()); |
| 817 } | 791 } |
| 818 | 792 |
| 819 // This function iterates over all encrypted types. There are many scenarios in | 793 // This function iterates over all encrypted types. There are many scenarios in |
| 820 // which data for some or all types is not currently available. In that case, | 794 // which data for some or all types is not currently available. In that case, |
| 821 // the lookup of the root node will fail and we will skip encryption for that | 795 // the lookup of the root node will fail and we will skip encryption for that |
| 822 // type. | 796 // type. |
| 823 void SyncEncryptionHandlerImpl::ReEncryptEverything( | 797 void SyncEncryptionHandlerImpl::ReEncryptEverything(WriteTransaction* trans) { |
| 824 WriteTransaction* trans) { | |
| 825 DCHECK(thread_checker_.CalledOnValidThread()); | 798 DCHECK(thread_checker_.CalledOnValidThread()); |
| 826 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); | 799 DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); |
| 827 for (ModelTypeSet::Iterator iter = | 800 for (ModelTypeSet::Iterator iter = |
| 828 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); | 801 UnlockVault(trans->GetWrappedTrans()).encrypted_types.First(); |
| 829 iter.Good(); iter.Inc()) { | 802 iter.Good(); iter.Inc()) { |
| 830 if (iter.Get() == PASSWORDS || IsControlType(iter.Get())) | 803 if (iter.Get() == PASSWORDS || IsControlType(iter.Get())) |
| 831 continue; // These types handle encryption differently. | 804 continue; // These types handle encryption differently. |
| 832 | 805 |
| 833 ReadNode type_root(trans); | 806 ReadNode type_root(trans); |
| 834 if (type_root.InitTypeRoot(iter.Get()) != BaseNode::INIT_OK) | 807 if (type_root.InitTypeRoot(iter.Get()) != BaseNode::INIT_OK) |
| 835 continue; // Don't try to reencrypt if the type's data is unavailable. | 808 continue; // Don't try to reencrypt if the type's data is unavailable. |
| 836 | 809 |
| 837 // Iterate through all children of this datatype. | 810 // Iterate through all children of this datatype. |
| 838 std::queue<int64_t> to_visit; | 811 std::queue<int64_t> to_visit; |
| 839 int64_t child_id = type_root.GetFirstChildId(); | 812 int64_t child_id = type_root.GetFirstChildId(); |
| 840 to_visit.push(child_id); | 813 to_visit.push(child_id); |
| 841 while (!to_visit.empty()) { | 814 while (!to_visit.empty()) { |
| 842 child_id = to_visit.front(); | 815 child_id = to_visit.front(); |
| 843 to_visit.pop(); | 816 to_visit.pop(); |
| 844 if (child_id == kInvalidId) | 817 if (child_id == kInvalidId) |
| 845 continue; | 818 continue; |
| 846 | 819 |
| 847 WriteNode child(trans); | 820 WriteNode child(trans); |
| 848 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK) | 821 if (child.InitByIdLookup(child_id) != BaseNode::INIT_OK) |
| 849 continue; // Possible for locally deleted items. | 822 continue; // Possible for locally deleted items. |
| 850 if (child.GetIsFolder()) { | 823 if (child.GetIsFolder()) { |
| 851 to_visit.push(child.GetFirstChildId()); | 824 to_visit.push(child.GetFirstChildId()); |
| 852 } | 825 } |
| 853 if (!child.GetIsPermanentFolder()) { | 826 if (!child.GetIsPermanentFolder()) { |
| 854 // Rewrite the specifics of the node with encrypted data if necessary | 827 // Rewrite the specifics of the node with encrypted data if necessary |
| 855 // (only rewrite the non-unique folders). | 828 // (only rewrite the non-unique folders). |
| 856 child.ResetFromSpecifics(); | 829 child.ResetFromSpecifics(); |
| 857 } | 830 } |
| 858 to_visit.push(child.GetSuccessorId()); | 831 to_visit.push(child.GetSuccessorId()); |
| 859 } | 832 } |
| 860 } | 833 } |
| 861 | 834 |
| 862 // Passwords are encrypted with their own legacy scheme. Passwords are always | 835 // Passwords are encrypted with their own legacy scheme. Passwords are always |
| 863 // encrypted so we don't need to check GetEncryptedTypes() here. | 836 // encrypted so we don't need to check GetEncryptedTypes() here. |
| 864 ReadNode passwords_root(trans); | 837 ReadNode passwords_root(trans); |
| 865 if (passwords_root.InitTypeRoot(PASSWORDS) == BaseNode::INIT_OK) { | 838 if (passwords_root.InitTypeRoot(PASSWORDS) == BaseNode::INIT_OK) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 878 // NOTE: We notify from within a transaction. | 851 // NOTE: We notify from within a transaction. |
| 879 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 852 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 880 OnEncryptionComplete()); | 853 OnEncryptionComplete()); |
| 881 } | 854 } |
| 882 | 855 |
| 883 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( | 856 bool SyncEncryptionHandlerImpl::ApplyNigoriUpdateImpl( |
| 884 const sync_pb::NigoriSpecifics& nigori, | 857 const sync_pb::NigoriSpecifics& nigori, |
| 885 syncable::BaseTransaction* const trans) { | 858 syncable::BaseTransaction* const trans) { |
| 886 DCHECK(thread_checker_.CalledOnValidThread()); | 859 DCHECK(thread_checker_.CalledOnValidThread()); |
| 887 DVLOG(1) << "Applying nigori node update."; | 860 DVLOG(1) << "Applying nigori node update."; |
| 888 bool nigori_types_need_update = !UpdateEncryptedTypesFromNigori(nigori, | 861 bool nigori_types_need_update = |
| 889 trans); | 862 !UpdateEncryptedTypesFromNigori(nigori, trans); |
| 890 | 863 |
| 891 if (nigori.custom_passphrase_time() != 0) { | 864 if (nigori.custom_passphrase_time() != 0) { |
| 892 custom_passphrase_time_ = | 865 custom_passphrase_time_ = ProtoTimeToTime(nigori.custom_passphrase_time()); |
| 893 ProtoTimeToTime(nigori.custom_passphrase_time()); | |
| 894 } | 866 } |
| 895 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori); | 867 bool is_nigori_migrated = IsNigoriMigratedToKeystore(nigori); |
| 896 if (is_nigori_migrated) { | 868 if (is_nigori_migrated) { |
| 897 migration_time_ = ProtoTimeToTime(nigori.keystore_migration_time()); | 869 migration_time_ = ProtoTimeToTime(nigori.keystore_migration_time()); |
| 898 PassphraseType nigori_passphrase_type = | 870 PassphraseType nigori_passphrase_type = |
| 899 ProtoPassphraseTypeToEnum(nigori.passphrase_type()); | 871 ProtoPassphraseTypeToEnum(nigori.passphrase_type()); |
| 900 | 872 |
| 901 // Only update the local passphrase state if it's a valid transition: | 873 // Only update the local passphrase state if it's a valid transition: |
| 902 // - implicit -> keystore | 874 // - implicit -> keystore |
| 903 // - implicit -> frozen implicit | 875 // - implicit -> frozen implicit |
| 904 // - implicit -> custom | 876 // - implicit -> custom |
| 905 // - keystore -> custom | 877 // - keystore -> custom |
| 906 // Note: frozen implicit -> custom is not technically a valid transition, | 878 // Note: frozen implicit -> custom is not technically a valid transition, |
| 907 // but we let it through here as well in case future versions do add support | 879 // but we let it through here as well in case future versions do add support |
| 908 // for this transition. | 880 // for this transition. |
| 909 if (passphrase_type_ != nigori_passphrase_type && | 881 if (passphrase_type_ != nigori_passphrase_type && |
| 910 nigori_passphrase_type != IMPLICIT_PASSPHRASE && | 882 nigori_passphrase_type != IMPLICIT_PASSPHRASE && |
| 911 (passphrase_type_ == IMPLICIT_PASSPHRASE || | 883 (passphrase_type_ == IMPLICIT_PASSPHRASE || |
| 912 nigori_passphrase_type == CUSTOM_PASSPHRASE)) { | 884 nigori_passphrase_type == CUSTOM_PASSPHRASE)) { |
| 913 DVLOG(1) << "Changing passphrase state from " | 885 DVLOG(1) << "Changing passphrase state from " |
| 914 << PassphraseTypeToString(passphrase_type_) | 886 << PassphraseTypeToString(passphrase_type_) << " to " |
| 915 << " to " | |
| 916 << PassphraseTypeToString(nigori_passphrase_type); | 887 << PassphraseTypeToString(nigori_passphrase_type); |
| 917 passphrase_type_ = nigori_passphrase_type; | 888 passphrase_type_ = nigori_passphrase_type; |
| 918 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 889 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 919 OnPassphraseTypeChanged( | 890 OnPassphraseTypeChanged(passphrase_type_, |
| 920 passphrase_type_, | 891 GetExplicitPassphraseTime())); |
| 921 GetExplicitPassphraseTime())); | |
| 922 } | 892 } |
| 923 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) { | 893 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) { |
| 924 // This is the case where another client that didn't support keystore | 894 // This is the case where another client that didn't support keystore |
| 925 // encryption attempted to enable full encryption. We detect it | 895 // encryption attempted to enable full encryption. We detect it |
| 926 // and switch the passphrase type to frozen implicit passphrase instead | 896 // and switch the passphrase type to frozen implicit passphrase instead |
| 927 // due to full encryption not being compatible with keystore passphrase. | 897 // due to full encryption not being compatible with keystore passphrase. |
| 928 // Because the local passphrase type will not match the nigori passphrase | 898 // Because the local passphrase type will not match the nigori passphrase |
| 929 // type, we will trigger a rewrite and subsequently a re-migration. | 899 // type, we will trigger a rewrite and subsequently a re-migration. |
| 930 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE " | 900 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE " |
| 931 << "due to full encryption."; | 901 << "due to full encryption."; |
| 932 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE; | 902 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE; |
| 933 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 903 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 934 OnPassphraseTypeChanged( | 904 OnPassphraseTypeChanged(passphrase_type_, |
| 935 passphrase_type_, | 905 GetExplicitPassphraseTime())); |
| 936 GetExplicitPassphraseTime())); | |
| 937 } | 906 } |
| 938 } else { | 907 } else { |
| 939 // It's possible that while we're waiting for migration a client that does | 908 // It's possible that while we're waiting for migration a client that does |
| 940 // not have keystore encryption enabled switches to a custom passphrase. | 909 // not have keystore encryption enabled switches to a custom passphrase. |
| 941 if (nigori.keybag_is_frozen() && | 910 if (nigori.keybag_is_frozen() && passphrase_type_ != CUSTOM_PASSPHRASE) { |
| 942 passphrase_type_ != CUSTOM_PASSPHRASE) { | |
| 943 passphrase_type_ = CUSTOM_PASSPHRASE; | 911 passphrase_type_ = CUSTOM_PASSPHRASE; |
| 944 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 912 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 945 OnPassphraseTypeChanged( | 913 OnPassphraseTypeChanged(passphrase_type_, |
| 946 passphrase_type_, | 914 GetExplicitPassphraseTime())); |
| 947 GetExplicitPassphraseTime())); | |
| 948 } | 915 } |
| 949 } | 916 } |
| 950 | 917 |
| 951 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; | 918 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; |
| 952 bool nigori_needs_new_keys = false; | 919 bool nigori_needs_new_keys = false; |
| 953 if (!nigori.encryption_keybag().blob().empty()) { | 920 if (!nigori.encryption_keybag().blob().empty()) { |
| 954 // We only update the default key if this was a new explicit passphrase. | 921 // We only update the default key if this was a new explicit passphrase. |
| 955 // Else, since it was decryptable, it must not have been a new key. | 922 // Else, since it was decryptable, it must not have been a new key. |
| 956 bool need_new_default_key = false; | 923 bool need_new_default_key = false; |
| 957 if (is_nigori_migrated) { | 924 if (is_nigori_migrated) { |
| 958 need_new_default_key = IsExplicitPassphrase( | 925 need_new_default_key = IsExplicitPassphrase( |
| 959 ProtoPassphraseTypeToEnum(nigori.passphrase_type())); | 926 ProtoPassphraseTypeToEnum(nigori.passphrase_type())); |
| 960 } else { | 927 } else { |
| 961 need_new_default_key = nigori.keybag_is_frozen(); | 928 need_new_default_key = nigori.keybag_is_frozen(); |
| 962 } | 929 } |
| 963 if (!AttemptToInstallKeybag(nigori.encryption_keybag(), | 930 if (!AttemptToInstallKeybag(nigori.encryption_keybag(), |
| 964 need_new_default_key, | 931 need_new_default_key, cryptographer)) { |
| 965 cryptographer)) { | |
| 966 // Check to see if we can decrypt the keybag using the keystore decryptor | 932 // Check to see if we can decrypt the keybag using the keystore decryptor |
| 967 // token. | 933 // token. |
| 968 cryptographer->SetPendingKeys(nigori.encryption_keybag()); | 934 cryptographer->SetPendingKeys(nigori.encryption_keybag()); |
| 969 if (!nigori.keystore_decryptor_token().blob().empty() && | 935 if (!nigori.keystore_decryptor_token().blob().empty() && |
| 970 !keystore_key_.empty()) { | 936 !keystore_key_.empty()) { |
| 971 if (DecryptPendingKeysWithKeystoreKey(keystore_key_, | 937 if (DecryptPendingKeysWithKeystoreKey(keystore_key_, |
| 972 nigori.keystore_decryptor_token(), | 938 nigori.keystore_decryptor_token(), |
| 973 cryptographer)) { | 939 cryptographer)) { |
| 974 nigori_needs_new_keys = | 940 nigori_needs_new_keys = |
| 975 cryptographer->KeybagIsStale(nigori.encryption_keybag()); | 941 cryptographer->KeybagIsStale(nigori.encryption_keybag()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 991 LOG(WARNING) << "Nigori had empty encryption keybag."; | 957 LOG(WARNING) << "Nigori had empty encryption keybag."; |
| 992 nigori_needs_new_keys = true; | 958 nigori_needs_new_keys = true; |
| 993 } | 959 } |
| 994 | 960 |
| 995 // If we've completed a sync cycle and the cryptographer isn't ready | 961 // If we've completed a sync cycle and the cryptographer isn't ready |
| 996 // yet or has pending keys, prompt the user for a passphrase. | 962 // yet or has pending keys, prompt the user for a passphrase. |
| 997 if (cryptographer->has_pending_keys()) { | 963 if (cryptographer->has_pending_keys()) { |
| 998 DVLOG(1) << "OnPassphraseRequired Sent"; | 964 DVLOG(1) << "OnPassphraseRequired Sent"; |
| 999 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys(); | 965 sync_pb::EncryptedData pending_keys = cryptographer->GetPendingKeys(); |
| 1000 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 966 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1001 OnPassphraseRequired(REASON_DECRYPTION, | 967 OnPassphraseRequired(REASON_DECRYPTION, pending_keys)); |
| 1002 pending_keys)); | |
| 1003 } else if (!cryptographer->is_ready()) { | 968 } else if (!cryptographer->is_ready()) { |
| 1004 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " | 969 DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " |
| 1005 << "ready"; | 970 << "ready"; |
| 1006 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 971 FOR_EACH_OBSERVER( |
| 1007 OnPassphraseRequired(REASON_ENCRYPTION, | 972 SyncEncryptionHandler::Observer, observers_, |
| 1008 sync_pb::EncryptedData())); | 973 OnPassphraseRequired(REASON_ENCRYPTION, sync_pb::EncryptedData())); |
| 1009 } | 974 } |
| 1010 | 975 |
| 1011 // Check if the current local encryption state is stricter/newer than the | 976 // Check if the current local encryption state is stricter/newer than the |
| 1012 // nigori state. If so, we need to overwrite the nigori node with the local | 977 // nigori state. If so, we need to overwrite the nigori node with the local |
| 1013 // state. | 978 // state. |
| 1014 bool passphrase_type_matches = true; | 979 bool passphrase_type_matches = true; |
| 1015 if (!is_nigori_migrated) { | 980 if (!is_nigori_migrated) { |
| 1016 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE || | 981 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE || |
| 1017 passphrase_type_ == IMPLICIT_PASSPHRASE); | 982 passphrase_type_ == IMPLICIT_PASSPHRASE); |
| 1018 passphrase_type_matches = | 983 passphrase_type_matches = |
| 1019 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_); | 984 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_); |
| 1020 } else { | 985 } else { |
| 1021 passphrase_type_matches = | 986 passphrase_type_matches = |
| 1022 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) == | 987 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) == |
| 1023 passphrase_type_); | 988 passphrase_type_); |
| 1024 } | 989 } |
| 1025 if (!passphrase_type_matches || | 990 if (!passphrase_type_matches || |
| 1026 nigori.encrypt_everything() != encrypt_everything_ || | 991 nigori.encrypt_everything() != encrypt_everything_ || |
| 1027 nigori_types_need_update || | 992 nigori_types_need_update || nigori_needs_new_keys) { |
| 1028 nigori_needs_new_keys) { | |
| 1029 DVLOG(1) << "Triggering nigori rewrite."; | 993 DVLOG(1) << "Triggering nigori rewrite."; |
| 1030 return false; | 994 return false; |
| 1031 } | 995 } |
| 1032 return true; | 996 return true; |
| 1033 } | 997 } |
| 1034 | 998 |
| 1035 void SyncEncryptionHandlerImpl::RewriteNigori() { | 999 void SyncEncryptionHandlerImpl::RewriteNigori() { |
| 1036 DVLOG(1) << "Writing local encryption state into nigori."; | 1000 DVLOG(1) << "Writing local encryption state into nigori."; |
| 1037 DCHECK(thread_checker_.CalledOnValidThread()); | 1001 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1038 WriteTransaction trans(FROM_HERE, user_share_); | 1002 WriteTransaction trans(FROM_HERE, user_share_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 nigori_overwrite_count_); | 1036 nigori_overwrite_count_); |
| 1073 } | 1037 } |
| 1074 | 1038 |
| 1075 // Note: we don't try to set keybag_is_frozen here since if that | 1039 // Note: we don't try to set keybag_is_frozen here since if that |
| 1076 // is lost the user can always set it again (and we don't want to clobber | 1040 // is lost the user can always set it again (and we don't want to clobber |
| 1077 // any migration state). The main goal at this point is to preserve | 1041 // any migration state). The main goal at this point is to preserve |
| 1078 // the encryption keys so all data remains decryptable. | 1042 // the encryption keys so all data remains decryptable. |
| 1079 } | 1043 } |
| 1080 syncable::UpdateNigoriFromEncryptedTypes( | 1044 syncable::UpdateNigoriFromEncryptedTypes( |
| 1081 UnlockVault(trans->GetWrappedTrans()).encrypted_types, | 1045 UnlockVault(trans->GetWrappedTrans()).encrypted_types, |
| 1082 encrypt_everything_, | 1046 encrypt_everything_, &nigori); |
| 1083 &nigori); | |
| 1084 if (!custom_passphrase_time_.is_null()) { | 1047 if (!custom_passphrase_time_.is_null()) { |
| 1085 nigori.set_custom_passphrase_time( | 1048 nigori.set_custom_passphrase_time( |
| 1086 TimeToProtoTime(custom_passphrase_time_)); | 1049 TimeToProtoTime(custom_passphrase_time_)); |
| 1087 } | 1050 } |
| 1088 | 1051 |
| 1089 // If nothing has changed, this is a no-op. | 1052 // If nothing has changed, this is a no-op. |
| 1090 nigori_node.SetNigoriSpecifics(nigori); | 1053 nigori_node.SetNigoriSpecifics(nigori); |
| 1091 } | 1054 } |
| 1092 } | 1055 } |
| 1093 | 1056 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node); | 1190 FinishSetPassphrase(success, bootstrap_token, trans, nigori_node); |
| 1228 } | 1191 } |
| 1229 | 1192 |
| 1230 void SyncEncryptionHandlerImpl::FinishSetPassphrase( | 1193 void SyncEncryptionHandlerImpl::FinishSetPassphrase( |
| 1231 bool success, | 1194 bool success, |
| 1232 const std::string& bootstrap_token, | 1195 const std::string& bootstrap_token, |
| 1233 WriteTransaction* trans, | 1196 WriteTransaction* trans, |
| 1234 WriteNode* nigori_node) { | 1197 WriteNode* nigori_node) { |
| 1235 DCHECK(thread_checker_.CalledOnValidThread()); | 1198 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1236 FOR_EACH_OBSERVER( | 1199 FOR_EACH_OBSERVER( |
| 1237 SyncEncryptionHandler::Observer, | 1200 SyncEncryptionHandler::Observer, observers_, |
| 1238 observers_, | |
| 1239 OnCryptographerStateChanged( | 1201 OnCryptographerStateChanged( |
| 1240 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer)); | 1202 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer)); |
| 1241 | 1203 |
| 1242 // It's possible we need to change the bootstrap token even if we failed to | 1204 // It's possible we need to change the bootstrap token even if we failed to |
| 1243 // set the passphrase (for example if we need to preserve the new GAIA | 1205 // set the passphrase (for example if we need to preserve the new GAIA |
| 1244 // passphrase). | 1206 // passphrase). |
| 1245 if (!bootstrap_token.empty()) { | 1207 if (!bootstrap_token.empty()) { |
| 1246 DVLOG(1) << "Passphrase bootstrap token updated."; | 1208 DVLOG(1) << "Passphrase bootstrap token updated."; |
| 1247 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 1209 FOR_EACH_OBSERVER( |
| 1248 OnBootstrapTokenUpdated(bootstrap_token, | 1210 SyncEncryptionHandler::Observer, observers_, |
| 1249 PASSPHRASE_BOOTSTRAP_TOKEN)); | 1211 OnBootstrapTokenUpdated(bootstrap_token, PASSPHRASE_BOOTSTRAP_TOKEN)); |
| 1250 } | 1212 } |
| 1251 | 1213 |
| 1252 const Cryptographer& cryptographer = | 1214 const Cryptographer& cryptographer = |
| 1253 UnlockVault(trans->GetWrappedTrans()).cryptographer; | 1215 UnlockVault(trans->GetWrappedTrans()).cryptographer; |
| 1254 if (!success) { | 1216 if (!success) { |
| 1255 if (cryptographer.is_ready()) { | 1217 if (cryptographer.is_ready()) { |
| 1256 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer " | 1218 LOG(ERROR) << "Attempt to change passphrase failed while cryptographer " |
| 1257 << "was ready."; | 1219 << "was ready."; |
| 1258 } else if (cryptographer.has_pending_keys()) { | 1220 } else if (cryptographer.has_pending_keys()) { |
| 1259 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 1221 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1260 OnPassphraseRequired(REASON_DECRYPTION, | 1222 OnPassphraseRequired(REASON_DECRYPTION, |
| 1261 cryptographer.GetPendingKeys())); | 1223 cryptographer.GetPendingKeys())); |
| 1262 } else { | 1224 } else { |
| 1263 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 1225 FOR_EACH_OBSERVER( |
| 1264 OnPassphraseRequired(REASON_ENCRYPTION, | 1226 SyncEncryptionHandler::Observer, observers_, |
| 1265 sync_pb::EncryptedData())); | 1227 OnPassphraseRequired(REASON_ENCRYPTION, sync_pb::EncryptedData())); |
| 1266 } | 1228 } |
| 1267 return; | 1229 return; |
| 1268 } | 1230 } |
| 1269 DCHECK(success); | 1231 DCHECK(success); |
| 1270 DCHECK(cryptographer.is_ready()); | 1232 DCHECK(cryptographer.is_ready()); |
| 1271 | 1233 |
| 1272 // Will do nothing if we're already properly migrated or unable to migrate | 1234 // Will do nothing if we're already properly migrated or unable to migrate |
| 1273 // (in otherwords, if ShouldTriggerMigration is false). | 1235 // (in otherwords, if ShouldTriggerMigration is false). |
| 1274 // Otherwise will update the nigori node with the current migrated state, | 1236 // Otherwise will update the nigori node with the current migrated state, |
| 1275 // writing all encryption state as it does. | 1237 // writing all encryption state as it does. |
| 1276 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) { | 1238 if (!AttemptToMigrateNigoriToKeystore(trans, nigori_node)) { |
| 1277 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics()); | 1239 sync_pb::NigoriSpecifics nigori(nigori_node->GetNigoriSpecifics()); |
| 1278 // Does not modify nigori.encryption_keybag() if the original decrypted | 1240 // Does not modify nigori.encryption_keybag() if the original decrypted |
| 1279 // data was the same. | 1241 // data was the same. |
| 1280 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag())) | 1242 if (!cryptographer.GetKeys(nigori.mutable_encryption_keybag())) |
| 1281 NOTREACHED(); | 1243 NOTREACHED(); |
| 1282 if (IsNigoriMigratedToKeystore(nigori)) { | 1244 if (IsNigoriMigratedToKeystore(nigori)) { |
| 1283 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_)); | 1245 DCHECK(keystore_key_.empty() || IsExplicitPassphrase(passphrase_type_)); |
| 1284 DVLOG(1) << "Leaving nigori migration state untouched after setting" | 1246 DVLOG(1) << "Leaving nigori migration state untouched after setting" |
| 1285 << " passphrase."; | 1247 << " passphrase."; |
| 1286 } else { | 1248 } else { |
| 1287 nigori.set_keybag_is_frozen( | 1249 nigori.set_keybag_is_frozen(IsExplicitPassphrase(passphrase_type_)); |
| 1288 IsExplicitPassphrase(passphrase_type_)); | |
| 1289 } | 1250 } |
| 1290 // If we set a new custom passphrase, store the timestamp. | 1251 // If we set a new custom passphrase, store the timestamp. |
| 1291 if (!custom_passphrase_time_.is_null()) { | 1252 if (!custom_passphrase_time_.is_null()) { |
| 1292 nigori.set_custom_passphrase_time( | 1253 nigori.set_custom_passphrase_time( |
| 1293 TimeToProtoTime(custom_passphrase_time_)); | 1254 TimeToProtoTime(custom_passphrase_time_)); |
| 1294 } | 1255 } |
| 1295 nigori_node->SetNigoriSpecifics(nigori); | 1256 nigori_node->SetNigoriSpecifics(nigori); |
| 1296 } | 1257 } |
| 1297 | 1258 |
| 1298 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS | 1259 // Must do this after OnPassphraseTypeChanged, in order to ensure the PSS |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 // If the nigori is already migrated but does not reflect the explicit | 1308 // If the nigori is already migrated but does not reflect the explicit |
| 1348 // passphrase state, remigrate. Similarly, if the nigori has an explicit | 1309 // passphrase state, remigrate. Similarly, if the nigori has an explicit |
| 1349 // passphrase but does not have full encryption, or the nigori has an | 1310 // passphrase but does not have full encryption, or the nigori has an |
| 1350 // implicit passphrase but does have full encryption, re-migrate. | 1311 // implicit passphrase but does have full encryption, re-migrate. |
| 1351 // Note that this is to defend against other clients without keystore | 1312 // Note that this is to defend against other clients without keystore |
| 1352 // encryption enabled transitioning to states that are no longer valid. | 1313 // encryption enabled transitioning to states that are no longer valid. |
| 1353 if (passphrase_type_ != KEYSTORE_PASSPHRASE && | 1314 if (passphrase_type_ != KEYSTORE_PASSPHRASE && |
| 1354 nigori.passphrase_type() == | 1315 nigori.passphrase_type() == |
| 1355 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) { | 1316 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) { |
| 1356 return true; | 1317 return true; |
| 1357 } else if (IsExplicitPassphrase(passphrase_type_) && | 1318 } else if (IsExplicitPassphrase(passphrase_type_) && !encrypt_everything_) { |
| 1358 !encrypt_everything_) { | |
| 1359 return true; | 1319 return true; |
| 1360 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE && | 1320 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) { |
| 1361 encrypt_everything_) { | |
| 1362 return true; | 1321 return true; |
| 1363 } else if ( | 1322 } else if (cryptographer.is_ready() && |
| 1364 cryptographer.is_ready() && | 1323 !cryptographer.CanDecryptUsingDefaultKey( |
| 1365 !cryptographer.CanDecryptUsingDefaultKey(nigori.encryption_keybag())) { | 1324 nigori.encryption_keybag())) { |
| 1366 // We need to overwrite the keybag. This might involve overwriting the | 1325 // We need to overwrite the keybag. This might involve overwriting the |
| 1367 // keystore decryptor too. | 1326 // keystore decryptor too. |
| 1368 return true; | 1327 return true; |
| 1369 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) { | 1328 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) { |
| 1370 // Check to see if a server key rotation has happened, but the nigori | 1329 // Check to see if a server key rotation has happened, but the nigori |
| 1371 // node's keys haven't been rotated yet, and hence we should re-migrate. | 1330 // node's keys haven't been rotated yet, and hence we should re-migrate. |
| 1372 // Note that once a key rotation has been performed, we no longer | 1331 // Note that once a key rotation has been performed, we no longer |
| 1373 // preserve backwards compatibility, and the keybag will therefore be | 1332 // preserve backwards compatibility, and the keybag will therefore be |
| 1374 // encrypted with the current keystore key. | 1333 // encrypted with the current keystore key. |
| 1375 Cryptographer temp_cryptographer(cryptographer.encryptor()); | 1334 Cryptographer temp_cryptographer(cryptographer.encryptor()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 DVLOG(1) << "Migrating keybag to keystore key."; | 1400 DVLOG(1) << "Migrating keybag to keystore key."; |
| 1442 bool cryptographer_was_ready = cryptographer->is_ready(); | 1401 bool cryptographer_was_ready = cryptographer->is_ready(); |
| 1443 if (!cryptographer->AddKey(key_params)) { | 1402 if (!cryptographer->AddKey(key_params)) { |
| 1444 LOG(ERROR) << "Failed to add keystore key as default key"; | 1403 LOG(ERROR) << "Failed to add keystore key as default key"; |
| 1445 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1404 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1446 FAILED_TO_SET_DEFAULT_KEYSTORE, | 1405 FAILED_TO_SET_DEFAULT_KEYSTORE, |
| 1447 MIGRATION_RESULT_SIZE); | 1406 MIGRATION_RESULT_SIZE); |
| 1448 return false; | 1407 return false; |
| 1449 } | 1408 } |
| 1450 if (!cryptographer_was_ready && cryptographer->is_ready()) { | 1409 if (!cryptographer_was_ready && cryptographer->is_ready()) { |
| 1451 FOR_EACH_OBSERVER( | 1410 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1452 SyncEncryptionHandler::Observer, | 1411 OnPassphraseAccepted()); |
| 1453 observers_, | |
| 1454 OnPassphraseAccepted()); | |
| 1455 } | 1412 } |
| 1456 } else { | 1413 } else { |
| 1457 // We're in backwards compatible mode -- either the account has an | 1414 // We're in backwards compatible mode -- either the account has an |
| 1458 // explicit passphrase, or we want to preserve the current GAIA-based key | 1415 // explicit passphrase, or we want to preserve the current GAIA-based key |
| 1459 // as the default because we can (there have been no key rotations since | 1416 // as the default because we can (there have been no key rotations since |
| 1460 // the migration). | 1417 // the migration). |
| 1461 DVLOG(1) << "Migrating keybag while preserving old key"; | 1418 DVLOG(1) << "Migrating keybag while preserving old key"; |
| 1462 if (!cryptographer->AddNonDefaultKey(key_params)) { | 1419 if (!cryptographer->AddNonDefaultKey(key_params)) { |
| 1463 LOG(ERROR) << "Failed to add keystore key as non-default key."; | 1420 LOG(ERROR) << "Failed to add keystore key as non-default key."; |
| 1464 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1421 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1465 FAILED_TO_SET_NONDEFAULT_KEYSTORE, | 1422 FAILED_TO_SET_NONDEFAULT_KEYSTORE, |
| 1466 MIGRATION_RESULT_SIZE); | 1423 MIGRATION_RESULT_SIZE); |
| 1467 return false; | 1424 return false; |
| 1468 } | 1425 } |
| 1469 } | 1426 } |
| 1470 } | 1427 } |
| 1471 if (!old_keystore_keys_.empty()) { | 1428 if (!old_keystore_keys_.empty()) { |
| 1472 // Go through and add all the old keystore keys as non default keys, so | 1429 // Go through and add all the old keystore keys as non default keys, so |
| 1473 // they'll be preserved in the encryption_keybag when we next write the | 1430 // they'll be preserved in the encryption_keybag when we next write the |
| 1474 // nigori node. | 1431 // nigori node. |
| 1475 for (std::vector<std::string>::const_iterator iter = | 1432 for (std::vector<std::string>::const_iterator iter = |
| 1476 old_keystore_keys_.begin(); iter != old_keystore_keys_.end(); | 1433 old_keystore_keys_.begin(); |
| 1477 ++iter) { | 1434 iter != old_keystore_keys_.end(); ++iter) { |
| 1478 KeyParams key_params = {"localhost", "dummy", *iter}; | 1435 KeyParams key_params = {"localhost", "dummy", *iter}; |
| 1479 cryptographer->AddNonDefaultKey(key_params); | 1436 cryptographer->AddNonDefaultKey(key_params); |
| 1480 } | 1437 } |
| 1481 } | 1438 } |
| 1482 if (new_passphrase_type == KEYSTORE_PASSPHRASE && | 1439 if (new_passphrase_type == KEYSTORE_PASSPHRASE && |
| 1483 !GetKeystoreDecryptor( | 1440 !GetKeystoreDecryptor( |
| 1484 *cryptographer, | 1441 *cryptographer, keystore_key_, |
| 1485 keystore_key_, | |
| 1486 migrated_nigori.mutable_keystore_decryptor_token())) { | 1442 migrated_nigori.mutable_keystore_decryptor_token())) { |
| 1487 LOG(ERROR) << "Failed to extract keystore decryptor token."; | 1443 LOG(ERROR) << "Failed to extract keystore decryptor token."; |
| 1488 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1444 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1489 FAILED_TO_EXTRACT_DECRYPTOR, | 1445 FAILED_TO_EXTRACT_DECRYPTOR, |
| 1490 MIGRATION_RESULT_SIZE); | 1446 MIGRATION_RESULT_SIZE); |
| 1491 return false; | 1447 return false; |
| 1492 } | 1448 } |
| 1493 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) { | 1449 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) { |
| 1494 LOG(ERROR) << "Failed to extract encryption keybag."; | 1450 LOG(ERROR) << "Failed to extract encryption keybag."; |
| 1495 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1451 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1496 FAILED_TO_EXTRACT_KEYBAG, | 1452 FAILED_TO_EXTRACT_KEYBAG, MIGRATION_RESULT_SIZE); |
| 1497 MIGRATION_RESULT_SIZE); | |
| 1498 return false; | 1453 return false; |
| 1499 } | 1454 } |
| 1500 | 1455 |
| 1501 if (migration_time_.is_null()) | 1456 if (migration_time_.is_null()) |
| 1502 migration_time_ = base::Time::Now(); | 1457 migration_time_ = base::Time::Now(); |
| 1503 migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_)); | 1458 migrated_nigori.set_keystore_migration_time(TimeToProtoTime(migration_time_)); |
| 1504 | 1459 |
| 1505 if (!custom_passphrase_time_.is_null()) { | 1460 if (!custom_passphrase_time_.is_null()) { |
| 1506 migrated_nigori.set_custom_passphrase_time( | 1461 migrated_nigori.set_custom_passphrase_time( |
| 1507 TimeToProtoTime(custom_passphrase_time_)); | 1462 TimeToProtoTime(custom_passphrase_time_)); |
| 1508 } | 1463 } |
| 1509 | 1464 |
| 1510 FOR_EACH_OBSERVER( | 1465 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1511 SyncEncryptionHandler::Observer, | 1466 OnCryptographerStateChanged(cryptographer)); |
| 1512 observers_, | |
| 1513 OnCryptographerStateChanged(cryptographer)); | |
| 1514 if (passphrase_type_ != new_passphrase_type) { | 1467 if (passphrase_type_ != new_passphrase_type) { |
| 1515 passphrase_type_ = new_passphrase_type; | 1468 passphrase_type_ = new_passphrase_type; |
| 1516 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 1469 FOR_EACH_OBSERVER( |
| 1517 OnPassphraseTypeChanged( | 1470 SyncEncryptionHandler::Observer, observers_, |
| 1518 passphrase_type_, | 1471 OnPassphraseTypeChanged(passphrase_type_, GetExplicitPassphraseTime())); |
| 1519 GetExplicitPassphraseTime())); | |
| 1520 } | 1472 } |
| 1521 | 1473 |
| 1522 if (new_encrypt_everything && !encrypt_everything_) { | 1474 if (new_encrypt_everything && !encrypt_everything_) { |
| 1523 EnableEncryptEverythingImpl(trans->GetWrappedTrans()); | 1475 EnableEncryptEverythingImpl(trans->GetWrappedTrans()); |
| 1524 ReEncryptEverything(trans); | 1476 ReEncryptEverything(trans); |
| 1525 } else if (!cryptographer->CanDecryptUsingDefaultKey( | 1477 } else if (!cryptographer->CanDecryptUsingDefaultKey( |
| 1526 old_nigori.encryption_keybag())) { | 1478 old_nigori.encryption_keybag())) { |
| 1527 DVLOG(1) << "Rencrypting everything due to key rotation."; | 1479 DVLOG(1) << "Rencrypting everything due to key rotation."; |
| 1528 ReEncryptEverything(trans); | 1480 ReEncryptEverything(trans); |
| 1529 } | 1481 } |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 } else { | 1617 } else { |
| 1666 // Theoretically the encryption keybag should already contain the keystore | 1618 // Theoretically the encryption keybag should already contain the keystore |
| 1667 // key. We explicitly add it as a safety measure. | 1619 // key. We explicitly add it as a safety measure. |
| 1668 DVLOG(1) << "Pending keys based on newest keystore key."; | 1620 DVLOG(1) << "Pending keys based on newest keystore key."; |
| 1669 cryptographer->AddNonDefaultKey(keystore_params); | 1621 cryptographer->AddNonDefaultKey(keystore_params); |
| 1670 } | 1622 } |
| 1671 if (cryptographer->is_ready()) { | 1623 if (cryptographer->is_ready()) { |
| 1672 std::string bootstrap_token; | 1624 std::string bootstrap_token; |
| 1673 cryptographer->GetBootstrapToken(&bootstrap_token); | 1625 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 1674 DVLOG(1) << "Keystore decryptor token decrypted pending keys."; | 1626 DVLOG(1) << "Keystore decryptor token decrypted pending keys."; |
| 1627 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1628 OnPassphraseAccepted()); |
| 1675 FOR_EACH_OBSERVER( | 1629 FOR_EACH_OBSERVER( |
| 1676 SyncEncryptionHandler::Observer, | 1630 SyncEncryptionHandler::Observer, observers_, |
| 1677 observers_, | 1631 OnBootstrapTokenUpdated(bootstrap_token, PASSPHRASE_BOOTSTRAP_TOKEN)); |
| 1678 OnPassphraseAccepted()); | 1632 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1679 FOR_EACH_OBSERVER( | 1633 OnCryptographerStateChanged(cryptographer)); |
| 1680 SyncEncryptionHandler::Observer, | |
| 1681 observers_, | |
| 1682 OnBootstrapTokenUpdated(bootstrap_token, | |
| 1683 PASSPHRASE_BOOTSTRAP_TOKEN)); | |
| 1684 FOR_EACH_OBSERVER( | |
| 1685 SyncEncryptionHandler::Observer, | |
| 1686 observers_, | |
| 1687 OnCryptographerStateChanged(cryptographer)); | |
| 1688 return true; | 1634 return true; |
| 1689 } | 1635 } |
| 1690 } | 1636 } |
| 1691 return false; | 1637 return false; |
| 1692 } | 1638 } |
| 1693 | 1639 |
| 1694 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const { | 1640 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const { |
| 1695 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE) | 1641 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE) |
| 1696 return migration_time(); | 1642 return migration_time(); |
| 1697 else if (passphrase_type_ == CUSTOM_PASSPHRASE) | 1643 else if (passphrase_type_ == CUSTOM_PASSPHRASE) |
| 1698 return custom_passphrase_time(); | 1644 return custom_passphrase_time(); |
| 1699 return base::Time(); | 1645 return base::Time(); |
| 1700 } | 1646 } |
| 1701 | 1647 |
| 1702 } // namespace syncer | 1648 } // namespace syncer |
| OLD | NEW |