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 |