| 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 "components/sync/core_impl/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> |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE && | 90 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE && |
| 91 nigori.keystore_decryptor_token().blob().empty()) | 91 nigori.keystore_decryptor_token().blob().empty()) |
| 92 return false; | 92 return false; |
| 93 return true; | 93 return true; |
| 94 } | 94 } |
| 95 | 95 |
| 96 PassphraseType ProtoPassphraseTypeToEnum( | 96 PassphraseType ProtoPassphraseTypeToEnum( |
| 97 sync_pb::NigoriSpecifics::PassphraseType type) { | 97 sync_pb::NigoriSpecifics::PassphraseType type) { |
| 98 switch (type) { | 98 switch (type) { |
| 99 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE: | 99 case sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE: |
| 100 return IMPLICIT_PASSPHRASE; | 100 return PassphraseType::IMPLICIT_PASSPHRASE; |
| 101 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE: | 101 case sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE: |
| 102 return KEYSTORE_PASSPHRASE; | 102 return PassphraseType::KEYSTORE_PASSPHRASE; |
| 103 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE: | 103 case sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE: |
| 104 return CUSTOM_PASSPHRASE; | 104 return PassphraseType::CUSTOM_PASSPHRASE; |
| 105 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE: | 105 case sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE: |
| 106 return FROZEN_IMPLICIT_PASSPHRASE; | 106 return PassphraseType::FROZEN_IMPLICIT_PASSPHRASE; |
| 107 default: | 107 default: |
| 108 NOTREACHED(); | 108 NOTREACHED(); |
| 109 return IMPLICIT_PASSPHRASE; | 109 return PassphraseType::IMPLICIT_PASSPHRASE; |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 sync_pb::NigoriSpecifics::PassphraseType EnumPassphraseTypeToProto( | 113 sync_pb::NigoriSpecifics::PassphraseType EnumPassphraseTypeToProto( |
| 114 PassphraseType type) { | 114 PassphraseType type) { |
| 115 switch (type) { | 115 switch (type) { |
| 116 case IMPLICIT_PASSPHRASE: | 116 case PassphraseType::IMPLICIT_PASSPHRASE: |
| 117 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; | 117 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; |
| 118 case KEYSTORE_PASSPHRASE: | 118 case PassphraseType::KEYSTORE_PASSPHRASE: |
| 119 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE; | 119 return sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE; |
| 120 case CUSTOM_PASSPHRASE: | 120 case PassphraseType::CUSTOM_PASSPHRASE: |
| 121 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE; | 121 return sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE; |
| 122 case FROZEN_IMPLICIT_PASSPHRASE: | 122 case PassphraseType::FROZEN_IMPLICIT_PASSPHRASE: |
| 123 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE; | 123 return sync_pb::NigoriSpecifics::FROZEN_IMPLICIT_PASSPHRASE; |
| 124 default: | 124 default: |
| 125 NOTREACHED(); | 125 NOTREACHED(); |
| 126 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; | 126 return sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE; |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 bool IsExplicitPassphrase(PassphraseType type) { | 130 bool IsExplicitPassphrase(PassphraseType type) { |
| 131 return type == CUSTOM_PASSPHRASE || type == FROZEN_IMPLICIT_PASSPHRASE; | 131 return type == PassphraseType::CUSTOM_PASSPHRASE || |
| 132 type == PassphraseType::FROZEN_IMPLICIT_PASSPHRASE; |
| 132 } | 133 } |
| 133 | 134 |
| 134 // Keystore Bootstrap Token helper methods. | 135 // Keystore Bootstrap Token helper methods. |
| 135 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key | 136 // The bootstrap is a base64 encoded, encrypted, ListValue of keystore key |
| 136 // strings, with the current keystore key as the last value in the list. | 137 // strings, with the current keystore key as the last value in the list. |
| 137 std::string PackKeystoreBootstrapToken( | 138 std::string PackKeystoreBootstrapToken( |
| 138 const std::vector<std::string>& old_keystore_keys, | 139 const std::vector<std::string>& old_keystore_keys, |
| 139 const std::string& current_keystore_key, | 140 const std::string& current_keystore_key, |
| 140 Encryptor* encryptor) { | 141 Encryptor* encryptor) { |
| 141 if (current_keystore_key.empty()) | 142 if (current_keystore_key.empty()) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 SyncEncryptionHandlerImpl::Vault::~Vault() {} | 205 SyncEncryptionHandlerImpl::Vault::~Vault() {} |
| 205 | 206 |
| 206 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( | 207 SyncEncryptionHandlerImpl::SyncEncryptionHandlerImpl( |
| 207 UserShare* user_share, | 208 UserShare* user_share, |
| 208 Encryptor* encryptor, | 209 Encryptor* encryptor, |
| 209 const std::string& restored_key_for_bootstrapping, | 210 const std::string& restored_key_for_bootstrapping, |
| 210 const std::string& restored_keystore_key_for_bootstrapping) | 211 const std::string& restored_keystore_key_for_bootstrapping) |
| 211 : user_share_(user_share), | 212 : user_share_(user_share), |
| 212 vault_unsafe_(encryptor, SensitiveTypes()), | 213 vault_unsafe_(encryptor, SensitiveTypes()), |
| 213 encrypt_everything_(false), | 214 encrypt_everything_(false), |
| 214 passphrase_type_(IMPLICIT_PASSPHRASE), | 215 passphrase_type_(PassphraseType::IMPLICIT_PASSPHRASE), |
| 215 nigori_overwrite_count_(0), | 216 nigori_overwrite_count_(0), |
| 216 weak_ptr_factory_(this) { | 217 weak_ptr_factory_(this) { |
| 217 // Restore the cryptographer's previous keys. Note that we don't add the | 218 // Restore the cryptographer's previous keys. Note that we don't add the |
| 218 // keystore keys into the cryptographer here, in case a migration was pending. | 219 // keystore keys into the cryptographer here, in case a migration was pending. |
| 219 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); | 220 vault_unsafe_.cryptographer.Bootstrap(restored_key_for_bootstrapping); |
| 220 | 221 |
| 221 // If this fails, we won't have a valid keystore key, and will simply request | 222 // If this fails, we won't have a valid keystore key, and will simply request |
| 222 // new ones from the server on the next DownloadUpdates. | 223 // new ones from the server on the next DownloadUpdates. |
| 223 UnpackKeystoreBootstrapToken(restored_keystore_key_for_bootstrapping, | 224 UnpackKeystoreBootstrapToken(restored_keystore_key_for_bootstrapping, |
| 224 encryptor, &old_keystore_keys_, &keystore_key_); | 225 encryptor, &old_keystore_keys_, &keystore_key_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 243 WriteTransaction trans(FROM_HERE, user_share_); | 244 WriteTransaction trans(FROM_HERE, user_share_); |
| 244 WriteNode node(&trans); | 245 WriteNode node(&trans); |
| 245 | 246 |
| 246 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) | 247 if (node.InitTypeRoot(NIGORI) != BaseNode::INIT_OK) |
| 247 return; | 248 return; |
| 248 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(), | 249 if (!ApplyNigoriUpdateImpl(node.GetNigoriSpecifics(), |
| 249 trans.GetWrappedTrans())) { | 250 trans.GetWrappedTrans())) { |
| 250 WriteEncryptionStateToNigori(&trans); | 251 WriteEncryptionStateToNigori(&trans); |
| 251 } | 252 } |
| 252 | 253 |
| 253 UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType", GetPassphraseType(), | 254 UMA_HISTOGRAM_ENUMERATION( |
| 254 PASSPHRASE_TYPE_SIZE); | 255 "Sync.PassphraseType", static_cast<unsigned>(GetPassphraseType()), |
| 256 static_cast<unsigned>(PassphraseType::PASSPHRASE_TYPE_SIZE)); |
| 255 | 257 |
| 256 bool has_pending_keys = | 258 bool has_pending_keys = |
| 257 UnlockVault(trans.GetWrappedTrans()).cryptographer.has_pending_keys(); | 259 UnlockVault(trans.GetWrappedTrans()).cryptographer.has_pending_keys(); |
| 258 bool is_ready = UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready(); | 260 bool is_ready = UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready(); |
| 259 // Log the state of the cryptographer regardless of migration state. | 261 // Log the state of the cryptographer regardless of migration state. |
| 260 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready); | 262 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready); |
| 261 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys); | 263 UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys); |
| 262 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) { | 264 if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) { |
| 263 // This account has a nigori node that has been migrated to support | 265 // This account has a nigori node that has been migrated to support |
| 264 // keystore. | 266 // keystore. |
| 265 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", MIGRATED, | 267 UMA_HISTOGRAM_ENUMERATION("Sync.NigoriMigrationState", MIGRATED, |
| 266 MIGRATION_STATE_SIZE); | 268 MIGRATION_STATE_SIZE); |
| 267 if (has_pending_keys && passphrase_type_ == KEYSTORE_PASSPHRASE) { | 269 if (has_pending_keys && |
| 270 passphrase_type_ == PassphraseType::KEYSTORE_PASSPHRASE) { |
| 268 // If this is happening, it means the keystore decryptor is either | 271 // If this is happening, it means the keystore decryptor is either |
| 269 // undecryptable with the available keystore keys or does not match the | 272 // undecryptable with the available keystore keys or does not match the |
| 270 // nigori keybag's encryption key. Otherwise we're simply missing the | 273 // nigori keybag's encryption key. Otherwise we're simply missing the |
| 271 // keystore key. | 274 // keystore key. |
| 272 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed", | 275 UMA_HISTOGRAM_BOOLEAN("Sync.KeystoreDecryptionFailed", |
| 273 !keystore_key_.empty()); | 276 !keystore_key_.empty()); |
| 274 } | 277 } |
| 275 } else if (!is_ready) { | 278 } else if (!is_ready) { |
| 276 // Migration cannot occur until the cryptographer is ready (initialized | 279 // Migration cannot occur until the cryptographer is ready (initialized |
| 277 // with GAIA password and any pending keys resolved). | 280 // with GAIA password and any pending keys resolved). |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 // bootstrap token will be derived from the most recently provided explicit | 385 // bootstrap token will be derived from the most recently provided explicit |
| 383 // passphrase (that was able to decrypt the data). | 386 // passphrase (that was able to decrypt the data). |
| 384 if (!IsExplicitPassphrase(passphrase_type_)) { | 387 if (!IsExplicitPassphrase(passphrase_type_)) { |
| 385 if (!cryptographer->has_pending_keys()) { | 388 if (!cryptographer->has_pending_keys()) { |
| 386 if (cryptographer->AddKey(key_params)) { | 389 if (cryptographer->AddKey(key_params)) { |
| 387 // Case 1 and 2. We set a new GAIA passphrase when there are no pending | 390 // Case 1 and 2. We set a new GAIA passphrase when there are no pending |
| 388 // keys (1), or overwriting an implicit passphrase with a new explicit | 391 // keys (1), or overwriting an implicit passphrase with a new explicit |
| 389 // one (2) when there are no pending keys. | 392 // one (2) when there are no pending keys. |
| 390 if (is_explicit) { | 393 if (is_explicit) { |
| 391 DVLOG(1) << "Setting explicit passphrase for encryption."; | 394 DVLOG(1) << "Setting explicit passphrase for encryption."; |
| 392 passphrase_type_ = CUSTOM_PASSPHRASE; | 395 passphrase_type_ = PassphraseType::CUSTOM_PASSPHRASE; |
| 393 custom_passphrase_time_ = base::Time::Now(); | 396 custom_passphrase_time_ = base::Time::Now(); |
| 394 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 397 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 395 OnPassphraseTypeChanged( | 398 OnPassphraseTypeChanged( |
| 396 passphrase_type_, GetExplicitPassphraseTime())); | 399 passphrase_type_, GetExplicitPassphraseTime())); |
| 397 } else { | 400 } else { |
| 398 DVLOG(1) << "Setting implicit passphrase for encryption."; | 401 DVLOG(1) << "Setting implicit passphrase for encryption."; |
| 399 } | 402 } |
| 400 cryptographer->GetBootstrapToken(&bootstrap_token); | 403 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 401 | 404 |
| 402 // With M26, sync accounts can be in only one of two encryption states: | 405 // With M26, sync accounts can be in only one of two encryption states: |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 | 875 |
| 873 // Only update the local passphrase state if it's a valid transition: | 876 // Only update the local passphrase state if it's a valid transition: |
| 874 // - implicit -> keystore | 877 // - implicit -> keystore |
| 875 // - implicit -> frozen implicit | 878 // - implicit -> frozen implicit |
| 876 // - implicit -> custom | 879 // - implicit -> custom |
| 877 // - keystore -> custom | 880 // - keystore -> custom |
| 878 // Note: frozen implicit -> custom is not technically a valid transition, | 881 // Note: frozen implicit -> custom is not technically a valid transition, |
| 879 // but we let it through here as well in case future versions do add support | 882 // but we let it through here as well in case future versions do add support |
| 880 // for this transition. | 883 // for this transition. |
| 881 if (passphrase_type_ != nigori_passphrase_type && | 884 if (passphrase_type_ != nigori_passphrase_type && |
| 882 nigori_passphrase_type != IMPLICIT_PASSPHRASE && | 885 nigori_passphrase_type != PassphraseType::IMPLICIT_PASSPHRASE && |
| 883 (passphrase_type_ == IMPLICIT_PASSPHRASE || | 886 (passphrase_type_ == PassphraseType::IMPLICIT_PASSPHRASE || |
| 884 nigori_passphrase_type == CUSTOM_PASSPHRASE)) { | 887 nigori_passphrase_type == PassphraseType::CUSTOM_PASSPHRASE)) { |
| 885 DVLOG(1) << "Changing passphrase state from " | 888 DVLOG(1) << "Changing passphrase state from " |
| 886 << PassphraseTypeToString(passphrase_type_) << " to " | 889 << PassphraseTypeToString(passphrase_type_) << " to " |
| 887 << PassphraseTypeToString(nigori_passphrase_type); | 890 << PassphraseTypeToString(nigori_passphrase_type); |
| 888 passphrase_type_ = nigori_passphrase_type; | 891 passphrase_type_ = nigori_passphrase_type; |
| 889 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 892 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 890 OnPassphraseTypeChanged(passphrase_type_, | 893 OnPassphraseTypeChanged(passphrase_type_, |
| 891 GetExplicitPassphraseTime())); | 894 GetExplicitPassphraseTime())); |
| 892 } | 895 } |
| 893 if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) { | 896 if (passphrase_type_ == PassphraseType::KEYSTORE_PASSPHRASE && |
| 897 encrypt_everything_) { |
| 894 // This is the case where another client that didn't support keystore | 898 // This is the case where another client that didn't support keystore |
| 895 // encryption attempted to enable full encryption. We detect it | 899 // encryption attempted to enable full encryption. We detect it |
| 896 // and switch the passphrase type to frozen implicit passphrase instead | 900 // and switch the passphrase type to frozen implicit passphrase instead |
| 897 // due to full encryption not being compatible with keystore passphrase. | 901 // due to full encryption not being compatible with keystore passphrase. |
| 898 // Because the local passphrase type will not match the nigori passphrase | 902 // Because the local passphrase type will not match the nigori passphrase |
| 899 // type, we will trigger a rewrite and subsequently a re-migration. | 903 // type, we will trigger a rewrite and subsequently a re-migration. |
| 900 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE " | 904 DVLOG(1) << "Changing passphrase state to FROZEN_IMPLICIT_PASSPHRASE " |
| 901 << "due to full encryption."; | 905 << "due to full encryption."; |
| 902 passphrase_type_ = FROZEN_IMPLICIT_PASSPHRASE; | 906 passphrase_type_ = PassphraseType::FROZEN_IMPLICIT_PASSPHRASE; |
| 903 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 907 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 904 OnPassphraseTypeChanged(passphrase_type_, | 908 OnPassphraseTypeChanged(passphrase_type_, |
| 905 GetExplicitPassphraseTime())); | 909 GetExplicitPassphraseTime())); |
| 906 } | 910 } |
| 907 } else { | 911 } else { |
| 908 // It's possible that while we're waiting for migration a client that does | 912 // It's possible that while we're waiting for migration a client that does |
| 909 // not have keystore encryption enabled switches to a custom passphrase. | 913 // not have keystore encryption enabled switches to a custom passphrase. |
| 910 if (nigori.keybag_is_frozen() && passphrase_type_ != CUSTOM_PASSPHRASE) { | 914 if (nigori.keybag_is_frozen() && |
| 911 passphrase_type_ = CUSTOM_PASSPHRASE; | 915 passphrase_type_ != PassphraseType::CUSTOM_PASSPHRASE) { |
| 916 passphrase_type_ = PassphraseType::CUSTOM_PASSPHRASE; |
| 912 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 917 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 913 OnPassphraseTypeChanged(passphrase_type_, | 918 OnPassphraseTypeChanged(passphrase_type_, |
| 914 GetExplicitPassphraseTime())); | 919 GetExplicitPassphraseTime())); |
| 915 } | 920 } |
| 916 } | 921 } |
| 917 | 922 |
| 918 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; | 923 Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; |
| 919 bool nigori_needs_new_keys = false; | 924 bool nigori_needs_new_keys = false; |
| 920 if (!nigori.encryption_keybag().blob().empty()) { | 925 if (!nigori.encryption_keybag().blob().empty()) { |
| 921 // We only update the default key if this was a new explicit passphrase. | 926 // We only update the default key if this was a new explicit passphrase. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 FOR_EACH_OBSERVER( | 976 FOR_EACH_OBSERVER( |
| 972 SyncEncryptionHandler::Observer, observers_, | 977 SyncEncryptionHandler::Observer, observers_, |
| 973 OnPassphraseRequired(REASON_ENCRYPTION, sync_pb::EncryptedData())); | 978 OnPassphraseRequired(REASON_ENCRYPTION, sync_pb::EncryptedData())); |
| 974 } | 979 } |
| 975 | 980 |
| 976 // Check if the current local encryption state is stricter/newer than the | 981 // Check if the current local encryption state is stricter/newer than the |
| 977 // nigori state. If so, we need to overwrite the nigori node with the local | 982 // nigori state. If so, we need to overwrite the nigori node with the local |
| 978 // state. | 983 // state. |
| 979 bool passphrase_type_matches = true; | 984 bool passphrase_type_matches = true; |
| 980 if (!is_nigori_migrated) { | 985 if (!is_nigori_migrated) { |
| 981 DCHECK(passphrase_type_ == CUSTOM_PASSPHRASE || | 986 DCHECK(passphrase_type_ == PassphraseType::CUSTOM_PASSPHRASE || |
| 982 passphrase_type_ == IMPLICIT_PASSPHRASE); | 987 passphrase_type_ == PassphraseType::IMPLICIT_PASSPHRASE); |
| 983 passphrase_type_matches = | 988 passphrase_type_matches = |
| 984 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_); | 989 nigori.keybag_is_frozen() == IsExplicitPassphrase(passphrase_type_); |
| 985 } else { | 990 } else { |
| 986 passphrase_type_matches = | 991 passphrase_type_matches = |
| 987 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) == | 992 (ProtoPassphraseTypeToEnum(nigori.passphrase_type()) == |
| 988 passphrase_type_); | 993 passphrase_type_); |
| 989 } | 994 } |
| 990 if (!passphrase_type_matches || | 995 if (!passphrase_type_matches || |
| 991 nigori.encrypt_everything() != encrypt_everything_ || | 996 nigori.encrypt_everything() != encrypt_everything_ || |
| 992 nigori_types_need_update || nigori_needs_new_keys) { | 997 nigori_types_need_update || nigori_needs_new_keys) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 } | 1098 } |
| 1094 | 1099 |
| 1095 void SyncEncryptionHandlerImpl::SetCustomPassphrase( | 1100 void SyncEncryptionHandlerImpl::SetCustomPassphrase( |
| 1096 const std::string& passphrase, | 1101 const std::string& passphrase, |
| 1097 WriteTransaction* trans, | 1102 WriteTransaction* trans, |
| 1098 WriteNode* nigori_node) { | 1103 WriteNode* nigori_node) { |
| 1099 DCHECK(thread_checker_.CalledOnValidThread()); | 1104 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1100 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics())); | 1105 DCHECK(IsNigoriMigratedToKeystore(nigori_node->GetNigoriSpecifics())); |
| 1101 KeyParams key_params = {"localhost", "dummy", passphrase}; | 1106 KeyParams key_params = {"localhost", "dummy", passphrase}; |
| 1102 | 1107 |
| 1103 if (passphrase_type_ != KEYSTORE_PASSPHRASE) { | 1108 if (passphrase_type_ != PassphraseType::KEYSTORE_PASSPHRASE) { |
| 1104 DVLOG(1) << "Failing to set a custom passphrase because one has already " | 1109 DVLOG(1) << "Failing to set a custom passphrase because one has already " |
| 1105 << "been set."; | 1110 << "been set."; |
| 1106 FinishSetPassphrase(false, std::string(), trans, nigori_node); | 1111 FinishSetPassphrase(false, std::string(), trans, nigori_node); |
| 1107 return; | 1112 return; |
| 1108 } | 1113 } |
| 1109 | 1114 |
| 1110 Cryptographer* cryptographer = | 1115 Cryptographer* cryptographer = |
| 1111 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; | 1116 &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; |
| 1112 if (cryptographer->has_pending_keys()) { | 1117 if (cryptographer->has_pending_keys()) { |
| 1113 // This theoretically shouldn't happen, because the only way to have pending | 1118 // This theoretically shouldn't happen, because the only way to have pending |
| 1114 // keys after migrating to keystore support is if a custom passphrase was | 1119 // keys after migrating to keystore support is if a custom passphrase was |
| 1115 // set, which should update passpshrase_state_ and should be caught by the | 1120 // set, which should update passpshrase_state_ and should be caught by the |
| 1116 // if statement above. For the sake of safety though, we check for it in | 1121 // if statement above. For the sake of safety though, we check for it in |
| 1117 // case a client is misbehaving. | 1122 // case a client is misbehaving. |
| 1118 LOG(ERROR) << "Failing to set custom passphrase because of pending keys."; | 1123 LOG(ERROR) << "Failing to set custom passphrase because of pending keys."; |
| 1119 FinishSetPassphrase(false, std::string(), trans, nigori_node); | 1124 FinishSetPassphrase(false, std::string(), trans, nigori_node); |
| 1120 return; | 1125 return; |
| 1121 } | 1126 } |
| 1122 | 1127 |
| 1123 std::string bootstrap_token; | 1128 std::string bootstrap_token; |
| 1124 if (!cryptographer->AddKey(key_params)) { | 1129 if (!cryptographer->AddKey(key_params)) { |
| 1125 NOTREACHED() << "Failed to add key to cryptographer."; | 1130 NOTREACHED() << "Failed to add key to cryptographer."; |
| 1126 return; | 1131 return; |
| 1127 } | 1132 } |
| 1128 | 1133 |
| 1129 DVLOG(1) << "Setting custom passphrase."; | 1134 DVLOG(1) << "Setting custom passphrase."; |
| 1130 cryptographer->GetBootstrapToken(&bootstrap_token); | 1135 cryptographer->GetBootstrapToken(&bootstrap_token); |
| 1131 passphrase_type_ = CUSTOM_PASSPHRASE; | 1136 passphrase_type_ = PassphraseType::CUSTOM_PASSPHRASE; |
| 1132 custom_passphrase_time_ = base::Time::Now(); | 1137 custom_passphrase_time_ = base::Time::Now(); |
| 1133 FOR_EACH_OBSERVER( | 1138 FOR_EACH_OBSERVER( |
| 1134 SyncEncryptionHandler::Observer, observers_, | 1139 SyncEncryptionHandler::Observer, observers_, |
| 1135 OnPassphraseTypeChanged(passphrase_type_, GetExplicitPassphraseTime())); | 1140 OnPassphraseTypeChanged(passphrase_type_, GetExplicitPassphraseTime())); |
| 1136 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node); | 1141 FinishSetPassphrase(true, bootstrap_token, trans, nigori_node); |
| 1137 } | 1142 } |
| 1138 | 1143 |
| 1139 void SyncEncryptionHandlerImpl::NotifyObserversOfLocalCustomPassphrase( | 1144 void SyncEncryptionHandlerImpl::NotifyObserversOfLocalCustomPassphrase( |
| 1140 WriteTransaction* trans) { | 1145 WriteTransaction* trans) { |
| 1141 WriteNode nigori_node(trans); | 1146 WriteNode nigori_node(trans); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 // encrypted with the pending keys will not be decryptable). | 1309 // encrypted with the pending keys will not be decryptable). |
| 1305 if (cryptographer.has_pending_keys()) | 1310 if (cryptographer.has_pending_keys()) |
| 1306 return false; | 1311 return false; |
| 1307 if (IsNigoriMigratedToKeystore(nigori)) { | 1312 if (IsNigoriMigratedToKeystore(nigori)) { |
| 1308 // If the nigori is already migrated but does not reflect the explicit | 1313 // If the nigori is already migrated but does not reflect the explicit |
| 1309 // passphrase state, remigrate. Similarly, if the nigori has an explicit | 1314 // passphrase state, remigrate. Similarly, if the nigori has an explicit |
| 1310 // passphrase but does not have full encryption, or the nigori has an | 1315 // passphrase but does not have full encryption, or the nigori has an |
| 1311 // implicit passphrase but does have full encryption, re-migrate. | 1316 // implicit passphrase but does have full encryption, re-migrate. |
| 1312 // Note that this is to defend against other clients without keystore | 1317 // Note that this is to defend against other clients without keystore |
| 1313 // encryption enabled transitioning to states that are no longer valid. | 1318 // encryption enabled transitioning to states that are no longer valid. |
| 1314 if (passphrase_type_ != KEYSTORE_PASSPHRASE && | 1319 if (passphrase_type_ != PassphraseType::KEYSTORE_PASSPHRASE && |
| 1315 nigori.passphrase_type() == | 1320 nigori.passphrase_type() == |
| 1316 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) { | 1321 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE) { |
| 1317 return true; | 1322 return true; |
| 1318 } else if (IsExplicitPassphrase(passphrase_type_) && !encrypt_everything_) { | 1323 } else if (IsExplicitPassphrase(passphrase_type_) && !encrypt_everything_) { |
| 1319 return true; | 1324 return true; |
| 1320 } else if (passphrase_type_ == KEYSTORE_PASSPHRASE && encrypt_everything_) { | 1325 } else if (passphrase_type_ == PassphraseType::KEYSTORE_PASSPHRASE && |
| 1326 encrypt_everything_) { |
| 1321 return true; | 1327 return true; |
| 1322 } else if (cryptographer.is_ready() && | 1328 } else if (cryptographer.is_ready() && |
| 1323 !cryptographer.CanDecryptUsingDefaultKey( | 1329 !cryptographer.CanDecryptUsingDefaultKey( |
| 1324 nigori.encryption_keybag())) { | 1330 nigori.encryption_keybag())) { |
| 1325 // We need to overwrite the keybag. This might involve overwriting the | 1331 // We need to overwrite the keybag. This might involve overwriting the |
| 1326 // keystore decryptor too. | 1332 // keystore decryptor too. |
| 1327 return true; | 1333 return true; |
| 1328 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) { | 1334 } else if (old_keystore_keys_.size() > 0 && !keystore_key_.empty()) { |
| 1329 // Check to see if a server key rotation has happened, but the nigori | 1335 // Check to see if a server key rotation has happened, but the nigori |
| 1330 // node's keys haven't been rotated yet, and hence we should re-migrate. | 1336 // node's keys haven't been rotated yet, and hence we should re-migrate. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 return false; | 1369 return false; |
| 1364 | 1370 |
| 1365 DVLOG(1) << "Starting nigori migration to keystore support."; | 1371 DVLOG(1) << "Starting nigori migration to keystore support."; |
| 1366 sync_pb::NigoriSpecifics migrated_nigori(old_nigori); | 1372 sync_pb::NigoriSpecifics migrated_nigori(old_nigori); |
| 1367 | 1373 |
| 1368 PassphraseType new_passphrase_type = passphrase_type_; | 1374 PassphraseType new_passphrase_type = passphrase_type_; |
| 1369 bool new_encrypt_everything = encrypt_everything_; | 1375 bool new_encrypt_everything = encrypt_everything_; |
| 1370 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) { | 1376 if (encrypt_everything_ && !IsExplicitPassphrase(passphrase_type_)) { |
| 1371 DVLOG(1) << "Switching to frozen implicit passphrase due to already having " | 1377 DVLOG(1) << "Switching to frozen implicit passphrase due to already having " |
| 1372 << "full encryption."; | 1378 << "full encryption."; |
| 1373 new_passphrase_type = FROZEN_IMPLICIT_PASSPHRASE; | 1379 new_passphrase_type = PassphraseType::FROZEN_IMPLICIT_PASSPHRASE; |
| 1374 migrated_nigori.clear_keystore_decryptor_token(); | 1380 migrated_nigori.clear_keystore_decryptor_token(); |
| 1375 } else if (IsExplicitPassphrase(passphrase_type_)) { | 1381 } else if (IsExplicitPassphrase(passphrase_type_)) { |
| 1376 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to " | 1382 DVLOG_IF(1, !encrypt_everything_) << "Enabling encrypt everything due to " |
| 1377 << "explicit passphrase"; | 1383 << "explicit passphrase"; |
| 1378 new_encrypt_everything = true; | 1384 new_encrypt_everything = true; |
| 1379 migrated_nigori.clear_keystore_decryptor_token(); | 1385 migrated_nigori.clear_keystore_decryptor_token(); |
| 1380 } else { | 1386 } else { |
| 1381 DCHECK(!encrypt_everything_); | 1387 DCHECK(!encrypt_everything_); |
| 1382 new_passphrase_type = KEYSTORE_PASSPHRASE; | 1388 new_passphrase_type = PassphraseType::KEYSTORE_PASSPHRASE; |
| 1383 DVLOG(1) << "Switching to keystore passphrase state."; | 1389 DVLOG(1) << "Switching to keystore passphrase state."; |
| 1384 } | 1390 } |
| 1385 migrated_nigori.set_encrypt_everything(new_encrypt_everything); | 1391 migrated_nigori.set_encrypt_everything(new_encrypt_everything); |
| 1386 migrated_nigori.set_passphrase_type( | 1392 migrated_nigori.set_passphrase_type( |
| 1387 EnumPassphraseTypeToProto(new_passphrase_type)); | 1393 EnumPassphraseTypeToProto(new_passphrase_type)); |
| 1388 migrated_nigori.set_keybag_is_frozen(true); | 1394 migrated_nigori.set_keybag_is_frozen(true); |
| 1389 | 1395 |
| 1390 if (!keystore_key_.empty()) { | 1396 if (!keystore_key_.empty()) { |
| 1391 KeyParams key_params = {"localhost", "dummy", keystore_key_}; | 1397 KeyParams key_params = {"localhost", "dummy", keystore_key_}; |
| 1392 if ((old_keystore_keys_.size() > 0 && | 1398 if ((old_keystore_keys_.size() > 0 && |
| 1393 new_passphrase_type == KEYSTORE_PASSPHRASE) || | 1399 new_passphrase_type == PassphraseType::KEYSTORE_PASSPHRASE) || |
| 1394 !cryptographer->is_initialized()) { | 1400 !cryptographer->is_initialized()) { |
| 1395 // Either at least one key rotation has been performed, so we no longer | 1401 // Either at least one key rotation has been performed, so we no longer |
| 1396 // care about backwards compatibility, or we're generating keystore-based | 1402 // care about backwards compatibility, or we're generating keystore-based |
| 1397 // encryption keys without knowing the GAIA password (and therefore the | 1403 // encryption keys without knowing the GAIA password (and therefore the |
| 1398 // cryptographer is not initialized), so we can't support backwards | 1404 // cryptographer is not initialized), so we can't support backwards |
| 1399 // compatibility. Ensure the keystore key is the default key. | 1405 // compatibility. Ensure the keystore key is the default key. |
| 1400 DVLOG(1) << "Migrating keybag to keystore key."; | 1406 DVLOG(1) << "Migrating keybag to keystore key."; |
| 1401 bool cryptographer_was_ready = cryptographer->is_ready(); | 1407 bool cryptographer_was_ready = cryptographer->is_ready(); |
| 1402 if (!cryptographer->AddKey(key_params)) { | 1408 if (!cryptographer->AddKey(key_params)) { |
| 1403 LOG(ERROR) << "Failed to add keystore key as default key"; | 1409 LOG(ERROR) << "Failed to add keystore key as default key"; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1429 // Go through and add all the old keystore keys as non default keys, so | 1435 // Go through and add all the old keystore keys as non default keys, so |
| 1430 // they'll be preserved in the encryption_keybag when we next write the | 1436 // they'll be preserved in the encryption_keybag when we next write the |
| 1431 // nigori node. | 1437 // nigori node. |
| 1432 for (std::vector<std::string>::const_iterator iter = | 1438 for (std::vector<std::string>::const_iterator iter = |
| 1433 old_keystore_keys_.begin(); | 1439 old_keystore_keys_.begin(); |
| 1434 iter != old_keystore_keys_.end(); ++iter) { | 1440 iter != old_keystore_keys_.end(); ++iter) { |
| 1435 KeyParams key_params = {"localhost", "dummy", *iter}; | 1441 KeyParams key_params = {"localhost", "dummy", *iter}; |
| 1436 cryptographer->AddNonDefaultKey(key_params); | 1442 cryptographer->AddNonDefaultKey(key_params); |
| 1437 } | 1443 } |
| 1438 } | 1444 } |
| 1439 if (new_passphrase_type == KEYSTORE_PASSPHRASE && | 1445 if (new_passphrase_type == PassphraseType::KEYSTORE_PASSPHRASE && |
| 1440 !GetKeystoreDecryptor( | 1446 !GetKeystoreDecryptor( |
| 1441 *cryptographer, keystore_key_, | 1447 *cryptographer, keystore_key_, |
| 1442 migrated_nigori.mutable_keystore_decryptor_token())) { | 1448 migrated_nigori.mutable_keystore_decryptor_token())) { |
| 1443 LOG(ERROR) << "Failed to extract keystore decryptor token."; | 1449 LOG(ERROR) << "Failed to extract keystore decryptor token."; |
| 1444 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1450 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1445 FAILED_TO_EXTRACT_DECRYPTOR, | 1451 FAILED_TO_EXTRACT_DECRYPTOR, |
| 1446 MIGRATION_RESULT_SIZE); | 1452 MIGRATION_RESULT_SIZE); |
| 1447 return false; | 1453 return false; |
| 1448 } | 1454 } |
| 1449 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) { | 1455 if (!cryptographer->GetKeys(migrated_nigori.mutable_encryption_keybag())) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1477 } else if (!cryptographer->CanDecryptUsingDefaultKey( | 1483 } else if (!cryptographer->CanDecryptUsingDefaultKey( |
| 1478 old_nigori.encryption_keybag())) { | 1484 old_nigori.encryption_keybag())) { |
| 1479 DVLOG(1) << "Rencrypting everything due to key rotation."; | 1485 DVLOG(1) << "Rencrypting everything due to key rotation."; |
| 1480 ReEncryptEverything(trans); | 1486 ReEncryptEverything(trans); |
| 1481 } | 1487 } |
| 1482 | 1488 |
| 1483 DVLOG(1) << "Completing nigori migration to keystore support."; | 1489 DVLOG(1) << "Completing nigori migration to keystore support."; |
| 1484 nigori_node->SetNigoriSpecifics(migrated_nigori); | 1490 nigori_node->SetNigoriSpecifics(migrated_nigori); |
| 1485 | 1491 |
| 1486 if (new_encrypt_everything && | 1492 if (new_encrypt_everything && |
| 1487 (new_passphrase_type == FROZEN_IMPLICIT_PASSPHRASE || | 1493 (new_passphrase_type == PassphraseType::FROZEN_IMPLICIT_PASSPHRASE || |
| 1488 new_passphrase_type == CUSTOM_PASSPHRASE)) { | 1494 new_passphrase_type == PassphraseType::CUSTOM_PASSPHRASE)) { |
| 1489 NotifyObserversOfLocalCustomPassphrase(trans); | 1495 NotifyObserversOfLocalCustomPassphrase(trans); |
| 1490 } | 1496 } |
| 1491 | 1497 |
| 1492 switch (new_passphrase_type) { | 1498 switch (new_passphrase_type) { |
| 1493 case KEYSTORE_PASSPHRASE: | 1499 case PassphraseType::KEYSTORE_PASSPHRASE: |
| 1494 if (old_keystore_keys_.size() > 0) { | 1500 if (old_keystore_keys_.size() > 0) { |
| 1495 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1501 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1496 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT, | 1502 MIGRATION_SUCCESS_KEYSTORE_NONDEFAULT, |
| 1497 MIGRATION_RESULT_SIZE); | 1503 MIGRATION_RESULT_SIZE); |
| 1498 } else { | 1504 } else { |
| 1499 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1505 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1500 MIGRATION_SUCCESS_KEYSTORE_DEFAULT, | 1506 MIGRATION_SUCCESS_KEYSTORE_DEFAULT, |
| 1501 MIGRATION_RESULT_SIZE); | 1507 MIGRATION_RESULT_SIZE); |
| 1502 } | 1508 } |
| 1503 break; | 1509 break; |
| 1504 case FROZEN_IMPLICIT_PASSPHRASE: | 1510 case PassphraseType::FROZEN_IMPLICIT_PASSPHRASE: |
| 1505 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1511 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1506 MIGRATION_SUCCESS_FROZEN_IMPLICIT, | 1512 MIGRATION_SUCCESS_FROZEN_IMPLICIT, |
| 1507 MIGRATION_RESULT_SIZE); | 1513 MIGRATION_RESULT_SIZE); |
| 1508 break; | 1514 break; |
| 1509 case CUSTOM_PASSPHRASE: | 1515 case PassphraseType::CUSTOM_PASSPHRASE: |
| 1510 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", | 1516 UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", |
| 1511 MIGRATION_SUCCESS_CUSTOM, | 1517 MIGRATION_SUCCESS_CUSTOM, |
| 1512 MIGRATION_RESULT_SIZE); | 1518 MIGRATION_RESULT_SIZE); |
| 1513 break; | 1519 break; |
| 1514 default: | 1520 default: |
| 1515 NOTREACHED(); | 1521 NOTREACHED(); |
| 1516 break; | 1522 break; |
| 1517 } | 1523 } |
| 1518 return true; | 1524 return true; |
| 1519 } | 1525 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 OnBootstrapTokenUpdated(bootstrap_token, PASSPHRASE_BOOTSTRAP_TOKEN)); | 1637 OnBootstrapTokenUpdated(bootstrap_token, PASSPHRASE_BOOTSTRAP_TOKEN)); |
| 1632 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, | 1638 FOR_EACH_OBSERVER(SyncEncryptionHandler::Observer, observers_, |
| 1633 OnCryptographerStateChanged(cryptographer)); | 1639 OnCryptographerStateChanged(cryptographer)); |
| 1634 return true; | 1640 return true; |
| 1635 } | 1641 } |
| 1636 } | 1642 } |
| 1637 return false; | 1643 return false; |
| 1638 } | 1644 } |
| 1639 | 1645 |
| 1640 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const { | 1646 base::Time SyncEncryptionHandlerImpl::GetExplicitPassphraseTime() const { |
| 1641 if (passphrase_type_ == FROZEN_IMPLICIT_PASSPHRASE) | 1647 if (passphrase_type_ == PassphraseType::FROZEN_IMPLICIT_PASSPHRASE) |
| 1642 return migration_time(); | 1648 return migration_time(); |
| 1643 else if (passphrase_type_ == CUSTOM_PASSPHRASE) | 1649 else if (passphrase_type_ == PassphraseType::CUSTOM_PASSPHRASE) |
| 1644 return custom_passphrase_time(); | 1650 return custom_passphrase_time(); |
| 1645 return base::Time(); | 1651 return base::Time(); |
| 1646 } | 1652 } |
| 1647 | 1653 |
| 1648 } // namespace syncer | 1654 } // namespace syncer |
| OLD | NEW |