OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.
h" | 5 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.
h" |
6 | 6 |
7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
8 #include <keyhi.h> | 8 #include <keyhi.h> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } // namespace | 177 } // namespace |
178 | 178 |
179 // static | 179 // static |
180 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs( | 180 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs( |
181 PrefRegistrySimple* registry) { | 181 PrefRegistrySimple* registry) { |
182 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys); | 182 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys); |
183 } | 183 } |
184 | 184 |
185 // static | 185 // static |
186 void EasyUnlockTpmKeyManager::ResetLocalStateForUser( | 186 void EasyUnlockTpmKeyManager::ResetLocalStateForUser( |
187 const std::string& user_id) { | 187 const AccountId& account_id) { |
188 if (!g_browser_process) | 188 if (!g_browser_process) |
189 return; | 189 return; |
190 PrefService* local_state = g_browser_process->local_state(); | 190 PrefService* local_state = g_browser_process->local_state(); |
191 if (!local_state) | 191 if (!local_state) |
192 return; | 192 return; |
193 | 193 |
194 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockLocalStateTpmKeys); | 194 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockLocalStateTpmKeys); |
195 update->RemoveWithoutPathExpansion(user_id, NULL); | 195 update->RemoveWithoutPathExpansion(account_id.GetUserEmail(), NULL); |
196 } | 196 } |
197 | 197 |
198 EasyUnlockTpmKeyManager::EasyUnlockTpmKeyManager( | 198 EasyUnlockTpmKeyManager::EasyUnlockTpmKeyManager( |
199 const std::string& user_id, | 199 const AccountId& account_id, |
200 const std::string& username_hash, | 200 const std::string& username_hash, |
201 PrefService* local_state) | 201 PrefService* local_state) |
202 : user_id_(user_id), | 202 : account_id_(account_id), |
203 username_hash_(username_hash), | 203 username_hash_(username_hash), |
204 local_state_(local_state), | 204 local_state_(local_state), |
205 create_tpm_key_state_(CREATE_TPM_KEY_NOT_STARTED), | 205 create_tpm_key_state_(CREATE_TPM_KEY_NOT_STARTED), |
206 get_tpm_slot_weak_ptr_factory_(this), | 206 get_tpm_slot_weak_ptr_factory_(this), |
207 weak_ptr_factory_(this) { | 207 weak_ptr_factory_(this) {} |
208 } | |
209 | 208 |
210 EasyUnlockTpmKeyManager::~EasyUnlockTpmKeyManager() { | 209 EasyUnlockTpmKeyManager::~EasyUnlockTpmKeyManager() { |
211 } | 210 } |
212 | 211 |
213 bool EasyUnlockTpmKeyManager::PrepareTpmKey( | 212 bool EasyUnlockTpmKeyManager::PrepareTpmKey( |
214 bool check_private_key, | 213 bool check_private_key, |
215 const base::Closure& callback) { | 214 const base::Closure& callback) { |
216 CHECK(!user_id_.empty()); | 215 CHECK(account_id_.is_valid()); |
217 CHECK(!username_hash_.empty()); | 216 CHECK(!username_hash_.empty()); |
218 | 217 |
219 if (create_tpm_key_state_ == CREATE_TPM_KEY_DONE) | 218 if (create_tpm_key_state_ == CREATE_TPM_KEY_DONE) |
220 return true; | 219 return true; |
221 | 220 |
222 std::string key = GetPublicTpmKey(user_id_); | 221 std::string key = GetPublicTpmKey(account_id_); |
223 if (!check_private_key && !key.empty() && | 222 if (!check_private_key && !key.empty() && |
224 create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { | 223 create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { |
225 return true; | 224 return true; |
226 } | 225 } |
227 | 226 |
228 prepare_tpm_key_callbacks_.push_back(callback); | 227 prepare_tpm_key_callbacks_.push_back(callback); |
229 | 228 |
230 if (create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { | 229 if (create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { |
231 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_USER_SLOT; | 230 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_USER_SLOT; |
232 | 231 |
(...skipping 17 matching lines...) Expand all Loading... |
250 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 249 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
251 FROM_HERE, | 250 FROM_HERE, |
252 base::Bind(&EasyUnlockTpmKeyManager::OnTpmKeyCreated, | 251 base::Bind(&EasyUnlockTpmKeyManager::OnTpmKeyCreated, |
253 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), | 252 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), |
254 std::string()), | 253 std::string()), |
255 base::TimeDelta::FromMilliseconds(timeout_ms)); | 254 base::TimeDelta::FromMilliseconds(timeout_ms)); |
256 return true; | 255 return true; |
257 } | 256 } |
258 | 257 |
259 std::string EasyUnlockTpmKeyManager::GetPublicTpmKey( | 258 std::string EasyUnlockTpmKeyManager::GetPublicTpmKey( |
260 const std::string& user_id) { | 259 const AccountId& account_id) { |
261 if (!local_state_) | 260 if (!local_state_) |
262 return std::string(); | 261 return std::string(); |
263 const base::DictionaryValue* dict = | 262 const base::DictionaryValue* dict = |
264 local_state_->GetDictionary(prefs::kEasyUnlockLocalStateTpmKeys); | 263 local_state_->GetDictionary(prefs::kEasyUnlockLocalStateTpmKeys); |
265 std::string key; | 264 std::string key; |
266 if (dict) | 265 if (dict) |
267 dict->GetStringWithoutPathExpansion(user_id, &key); | 266 dict->GetStringWithoutPathExpansion(account_id.GetUserEmail(), &key); |
268 std::string decoded; | 267 std::string decoded; |
269 base::Base64Decode(key, &decoded); | 268 base::Base64Decode(key, &decoded); |
270 return decoded; | 269 return decoded; |
271 } | 270 } |
272 | 271 |
273 void EasyUnlockTpmKeyManager::SignUsingTpmKey( | 272 void EasyUnlockTpmKeyManager::SignUsingTpmKey( |
274 const std::string& user_id, | 273 const AccountId& account_id, |
275 const std::string& data, | 274 const std::string& data, |
276 const base::Callback<void(const std::string& data)> callback) { | 275 const base::Callback<void(const std::string& data)> callback) { |
277 std::string key = GetPublicTpmKey(user_id); | 276 const std::string key = GetPublicTpmKey(account_id); |
278 if (key.empty()) { | 277 if (key.empty()) { |
279 callback.Run(std::string()); | 278 callback.Run(std::string()); |
280 return; | 279 return; |
281 } | 280 } |
282 | 281 |
283 base::Callback<void(crypto::ScopedPK11Slot)> sign_with_system_slot = | 282 base::Callback<void(crypto::ScopedPK11Slot)> sign_with_system_slot = |
284 base::Bind(&EasyUnlockTpmKeyManager::SignDataWithSystemSlot, | 283 base::Bind(&EasyUnlockTpmKeyManager::SignDataWithSystemSlot, |
285 weak_ptr_factory_.GetWeakPtr(), | 284 weak_ptr_factory_.GetWeakPtr(), |
286 key, data, callback); | 285 key, data, callback); |
287 | 286 |
288 content::BrowserThread::PostTask( | 287 content::BrowserThread::PostTask( |
289 content::BrowserThread::IO, | 288 content::BrowserThread::IO, |
290 FROM_HERE, | 289 FROM_HERE, |
291 base::Bind(&GetSystemSlotOnIOThread, | 290 base::Bind(&GetSystemSlotOnIOThread, |
292 base::ThreadTaskRunnerHandle::Get(), | 291 base::ThreadTaskRunnerHandle::Get(), |
293 sign_with_system_slot)); | 292 sign_with_system_slot)); |
294 } | 293 } |
295 | 294 |
296 bool EasyUnlockTpmKeyManager::StartedCreatingTpmKeys() const { | 295 bool EasyUnlockTpmKeyManager::StartedCreatingTpmKeys() const { |
297 return create_tpm_key_state_ == CREATE_TPM_KEY_GOT_SYSTEM_SLOT || | 296 return create_tpm_key_state_ == CREATE_TPM_KEY_GOT_SYSTEM_SLOT || |
298 create_tpm_key_state_ == CREATE_TPM_KEY_DONE; | 297 create_tpm_key_state_ == CREATE_TPM_KEY_DONE; |
299 } | 298 } |
300 | 299 |
301 void EasyUnlockTpmKeyManager::SetKeyInLocalState(const std::string& user_id, | 300 void EasyUnlockTpmKeyManager::SetKeyInLocalState(const AccountId& account_id, |
302 const std::string& value) { | 301 const std::string& value) { |
303 if (!local_state_) | 302 if (!local_state_) |
304 return; | 303 return; |
305 | 304 |
306 std::string encoded; | 305 std::string encoded; |
307 base::Base64Encode(value, &encoded); | 306 base::Base64Encode(value, &encoded); |
308 DictionaryPrefUpdate update(local_state_, | 307 DictionaryPrefUpdate update(local_state_, |
309 prefs::kEasyUnlockLocalStateTpmKeys); | 308 prefs::kEasyUnlockLocalStateTpmKeys); |
310 update->SetStringWithoutPathExpansion(user_id, encoded); | 309 update->SetStringWithoutPathExpansion(account_id.GetUserEmail(), encoded); |
311 } | 310 } |
312 | 311 |
313 void EasyUnlockTpmKeyManager::OnUserTPMInitialized( | 312 void EasyUnlockTpmKeyManager::OnUserTPMInitialized( |
314 const std::string& public_key) { | 313 const std::string& public_key) { |
315 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_SYSTEM_SLOT; | 314 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_SYSTEM_SLOT; |
316 | 315 |
317 base::Callback<void(crypto::ScopedPK11Slot)> create_key_with_system_slot = | 316 base::Callback<void(crypto::ScopedPK11Slot)> create_key_with_system_slot = |
318 base::Bind(&EasyUnlockTpmKeyManager::CreateKeyInSystemSlot, | 317 base::Bind(&EasyUnlockTpmKeyManager::CreateKeyInSystemSlot, |
319 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), public_key); | 318 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), public_key); |
320 | 319 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 // |OnTpmKeyCreated| is called by a timeout task posted by | 370 // |OnTpmKeyCreated| is called by a timeout task posted by |
372 // |StartGetSystemSlotTimeoutMs|. Invalidating the factory will have | 371 // |StartGetSystemSlotTimeoutMs|. Invalidating the factory will have |
373 // an effect of canceling any pending |GetSystemSlotOnIOThread| callbacks, | 372 // an effect of canceling any pending |GetSystemSlotOnIOThread| callbacks, |
374 // as well as other pending timeouts. | 373 // as well as other pending timeouts. |
375 // Note that in the case |OnTpmKeyCreated| was called as a result of | 374 // Note that in the case |OnTpmKeyCreated| was called as a result of |
376 // |CreateKeyInSystemSlot|, this should have no effect as no weak ptrs from | 375 // |CreateKeyInSystemSlot|, this should have no effect as no weak ptrs from |
377 // this factory should be in use in this case. | 376 // this factory should be in use in this case. |
378 get_tpm_slot_weak_ptr_factory_.InvalidateWeakPtrs(); | 377 get_tpm_slot_weak_ptr_factory_.InvalidateWeakPtrs(); |
379 | 378 |
380 if (!public_key.empty()) | 379 if (!public_key.empty()) |
381 SetKeyInLocalState(user_id_, public_key); | 380 SetKeyInLocalState(account_id_, public_key); |
382 | 381 |
383 for (size_t i = 0; i < prepare_tpm_key_callbacks_.size(); ++i) { | 382 for (size_t i = 0; i < prepare_tpm_key_callbacks_.size(); ++i) { |
384 if (!prepare_tpm_key_callbacks_[i].is_null()) | 383 if (!prepare_tpm_key_callbacks_[i].is_null()) |
385 prepare_tpm_key_callbacks_[i].Run(); | 384 prepare_tpm_key_callbacks_[i].Run(); |
386 } | 385 } |
387 | 386 |
388 prepare_tpm_key_callbacks_.clear(); | 387 prepare_tpm_key_callbacks_.clear(); |
389 | 388 |
390 // If key creation failed, reset the state machine. | 389 // If key creation failed, reset the state machine. |
391 create_tpm_key_state_ = | 390 create_tpm_key_state_ = |
392 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; | 391 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; |
393 } | 392 } |
394 | 393 |
395 void EasyUnlockTpmKeyManager::OnDataSigned( | 394 void EasyUnlockTpmKeyManager::OnDataSigned( |
396 const base::Callback<void(const std::string&)>& callback, | 395 const base::Callback<void(const std::string&)>& callback, |
397 const std::string& signature) { | 396 const std::string& signature) { |
398 callback.Run(signature); | 397 callback.Run(signature); |
399 } | 398 } |
OLD | NEW |