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 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 const base::Callback<void(crypto::ScopedPK11Slot)>& callback) { | 47 const base::Callback<void(crypto::ScopedPK11Slot)>& callback) { |
48 base::Callback<void(crypto::ScopedPK11Slot)> callback_on_origin_thread = | 48 base::Callback<void(crypto::ScopedPK11Slot)> callback_on_origin_thread = |
49 base::Bind(&RunCallbackOnThreadRunner, response_task_runner, callback); | 49 base::Bind(&RunCallbackOnThreadRunner, response_task_runner, callback); |
50 | 50 |
51 crypto::ScopedPK11Slot system_slot = | 51 crypto::ScopedPK11Slot system_slot = |
52 crypto::GetSystemNSSKeySlot(callback_on_origin_thread); | 52 crypto::GetSystemNSSKeySlot(callback_on_origin_thread); |
53 if (system_slot) | 53 if (system_slot) |
54 callback_on_origin_thread.Run(system_slot.Pass()); | 54 callback_on_origin_thread.Run(system_slot.Pass()); |
55 } | 55 } |
56 | 56 |
57 // Relays |EnsureUserTpmInitializedOnIOThread| callback to | |
58 // |response_task_runner|, ignoring |slot|. | |
59 void RunCallbackWithoutSlotOnThreadRunner( | |
pneubeck (no reviews)
2015/05/12 12:21:43
s/ThreadRunner/TaskRunner/
tbarzic
2015/05/12 17:10:46
Done.
| |
60 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, | |
61 const base::Closure& callback, | |
62 crypto::ScopedPK11Slot slot) { | |
63 response_task_runner->PostTask(FROM_HERE, callback); | |
64 } | |
65 | |
66 void EnsureUserTPMInitializedOnIOThread( | |
67 const std::string& username_hash, | |
68 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, | |
69 const base::Closure& callback) { | |
70 base::Callback<void(crypto::ScopedPK11Slot)> callback_on_origin_thread = | |
71 base::Bind(&RunCallbackWithoutSlotOnThreadRunner, response_task_runner, | |
72 callback); | |
73 | |
74 crypto::ScopedPK11Slot private_slot = crypto::GetPrivateSlotForChromeOSUser( | |
75 username_hash, callback_on_origin_thread); | |
76 if (private_slot) | |
77 callback_on_origin_thread.Run(private_slot.Pass()); | |
78 } | |
79 | |
57 // Checks if a private RSA key associated with |public_key| can be found in | 80 // Checks if a private RSA key associated with |public_key| can be found in |
58 // |slot|. | 81 // |slot|. |
59 // Must be called on a worker thread. | 82 // Must be called on a worker thread. |
60 scoped_ptr<crypto::RSAPrivateKey> GetPrivateKeyOnWorkerThread( | 83 scoped_ptr<crypto::RSAPrivateKey> GetPrivateKeyOnWorkerThread( |
61 PK11SlotInfo* slot, | 84 PK11SlotInfo* slot, |
62 const std::string& public_key) { | 85 const std::string& public_key) { |
63 const uint8* public_key_uint8 = | 86 const uint8* public_key_uint8 = |
64 reinterpret_cast<const uint8*>(public_key.data()); | 87 reinterpret_cast<const uint8*>(public_key.data()); |
65 std::vector<uint8> public_key_vector( | 88 std::vector<uint8> public_key_vector( |
66 public_key_uint8, public_key_uint8 + public_key.size()); | 89 public_key_uint8, public_key_uint8 + public_key.size()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 if (!g_browser_process) | 184 if (!g_browser_process) |
162 return; | 185 return; |
163 PrefService* local_state = g_browser_process->local_state(); | 186 PrefService* local_state = g_browser_process->local_state(); |
164 if (!local_state) | 187 if (!local_state) |
165 return; | 188 return; |
166 | 189 |
167 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockLocalStateTpmKeys); | 190 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockLocalStateTpmKeys); |
168 update->RemoveWithoutPathExpansion(user_id, NULL); | 191 update->RemoveWithoutPathExpansion(user_id, NULL); |
169 } | 192 } |
170 | 193 |
171 EasyUnlockTpmKeyManager::EasyUnlockTpmKeyManager(const std::string& user_id, | 194 EasyUnlockTpmKeyManager::EasyUnlockTpmKeyManager( |
172 PrefService* local_state) | 195 const std::string& user_id, |
196 const std::string& username_hash, | |
197 PrefService* local_state) | |
173 : user_id_(user_id), | 198 : user_id_(user_id), |
199 username_hash_(username_hash), | |
174 local_state_(local_state), | 200 local_state_(local_state), |
175 create_tpm_key_state_(CREATE_TPM_KEY_NOT_STARTED), | 201 create_tpm_key_state_(CREATE_TPM_KEY_NOT_STARTED), |
176 get_tpm_slot_weak_ptr_factory_(this), | 202 get_tpm_slot_weak_ptr_factory_(this), |
177 weak_ptr_factory_(this) { | 203 weak_ptr_factory_(this) { |
178 } | 204 } |
179 | 205 |
180 EasyUnlockTpmKeyManager::~EasyUnlockTpmKeyManager() { | 206 EasyUnlockTpmKeyManager::~EasyUnlockTpmKeyManager() { |
181 } | 207 } |
182 | 208 |
183 bool EasyUnlockTpmKeyManager::PrepareTpmKey( | 209 bool EasyUnlockTpmKeyManager::PrepareTpmKey( |
184 bool check_private_key, | 210 bool check_private_key, |
185 const base::Closure& callback) { | 211 const base::Closure& callback) { |
186 CHECK(!user_id_.empty()); | 212 CHECK(!user_id_.empty()); |
213 CHECK(!username_hash_.empty()); | |
187 | 214 |
188 if (create_tpm_key_state_ == CREATE_TPM_KEY_DONE) | 215 if (create_tpm_key_state_ == CREATE_TPM_KEY_DONE) |
189 return true; | 216 return true; |
190 | 217 |
191 std::string key = GetPublicTpmKey(user_id_); | 218 std::string key = GetPublicTpmKey(user_id_); |
192 if (!check_private_key && !key.empty() && | 219 if (!check_private_key && !key.empty() && |
193 create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { | 220 create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { |
194 return true; | 221 return true; |
195 } | 222 } |
196 | 223 |
197 prepare_tpm_key_callbacks_.push_back(callback); | 224 prepare_tpm_key_callbacks_.push_back(callback); |
198 | 225 |
199 if (create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { | 226 if (create_tpm_key_state_ == CREATE_TPM_KEY_NOT_STARTED) { |
200 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_SYSTEM_SLOT; | 227 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_USER_SLOT; |
201 | 228 |
202 base::Callback<void(crypto::ScopedPK11Slot)> create_key_with_system_slot = | 229 base::Closure on_user_tpm_ready = |
203 base::Bind(&EasyUnlockTpmKeyManager::CreateKeyInSystemSlot, | 230 base::Bind(&EasyUnlockTpmKeyManager::OnUserTPMInitialized, |
204 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), | 231 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), key); |
205 key); | |
206 | 232 |
207 content::BrowserThread::PostTask( | 233 content::BrowserThread::PostTask( |
208 content::BrowserThread::IO, | 234 content::BrowserThread::IO, FROM_HERE, |
209 FROM_HERE, | 235 base::Bind(&EnsureUserTPMInitializedOnIOThread, username_hash_, |
210 base::Bind(&GetSystemSlotOnIOThread, | 236 base::ThreadTaskRunnerHandle::Get(), on_user_tpm_ready)); |
211 base::ThreadTaskRunnerHandle::Get(), | |
212 create_key_with_system_slot)); | |
213 } | 237 } |
214 | 238 |
215 return false; | 239 return false; |
216 } | 240 } |
217 | 241 |
218 bool EasyUnlockTpmKeyManager::StartGetSystemSlotTimeoutMs(size_t timeout_ms) { | 242 bool EasyUnlockTpmKeyManager::StartGetSystemSlotTimeoutMs(size_t timeout_ms) { |
219 if (create_tpm_key_state_ == CREATE_TPM_KEY_DONE || | 243 if (StartedCreatingTpmKeys()) |
220 create_tpm_key_state_ == CREATE_TPM_KEY_GOT_SYSTEM_SLOT) { | |
221 return false; | 244 return false; |
222 } | |
223 | 245 |
224 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 246 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
225 FROM_HERE, | 247 FROM_HERE, |
226 base::Bind(&EasyUnlockTpmKeyManager::OnTpmKeyCreated, | 248 base::Bind(&EasyUnlockTpmKeyManager::OnTpmKeyCreated, |
227 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), | 249 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), |
228 std::string()), | 250 std::string()), |
229 base::TimeDelta::FromMilliseconds(timeout_ms)); | 251 base::TimeDelta::FromMilliseconds(timeout_ms)); |
230 return true; | 252 return true; |
231 } | 253 } |
232 | 254 |
(...skipping 27 matching lines...) Expand all Loading... | |
260 key, data, callback); | 282 key, data, callback); |
261 | 283 |
262 content::BrowserThread::PostTask( | 284 content::BrowserThread::PostTask( |
263 content::BrowserThread::IO, | 285 content::BrowserThread::IO, |
264 FROM_HERE, | 286 FROM_HERE, |
265 base::Bind(&GetSystemSlotOnIOThread, | 287 base::Bind(&GetSystemSlotOnIOThread, |
266 base::ThreadTaskRunnerHandle::Get(), | 288 base::ThreadTaskRunnerHandle::Get(), |
267 sign_with_system_slot)); | 289 sign_with_system_slot)); |
268 } | 290 } |
269 | 291 |
292 bool EasyUnlockTpmKeyManager::StartedCreatingTpmKeys() const { | |
293 return create_tpm_key_state_ == CREATE_TPM_KEY_GOT_SYSTEM_SLOT || | |
294 create_tpm_key_state_ == CREATE_TPM_KEY_DONE; | |
295 } | |
296 | |
270 void EasyUnlockTpmKeyManager::SetKeyInLocalState(const std::string& user_id, | 297 void EasyUnlockTpmKeyManager::SetKeyInLocalState(const std::string& user_id, |
271 const std::string& value) { | 298 const std::string& value) { |
272 if (!local_state_) | 299 if (!local_state_) |
273 return; | 300 return; |
274 | 301 |
275 std::string encoded; | 302 std::string encoded; |
276 base::Base64Encode(value, &encoded); | 303 base::Base64Encode(value, &encoded); |
277 DictionaryPrefUpdate update(local_state_, | 304 DictionaryPrefUpdate update(local_state_, |
278 prefs::kEasyUnlockLocalStateTpmKeys); | 305 prefs::kEasyUnlockLocalStateTpmKeys); |
279 update->SetStringWithoutPathExpansion(user_id, encoded); | 306 update->SetStringWithoutPathExpansion(user_id, encoded); |
280 } | 307 } |
281 | 308 |
309 void EasyUnlockTpmKeyManager::OnUserTPMInitialized( | |
310 const std::string& public_key) { | |
311 create_tpm_key_state_ = CREATE_TPM_KEY_WAITING_FOR_SYSTEM_SLOT; | |
312 | |
313 base::Callback<void(crypto::ScopedPK11Slot)> create_key_with_system_slot = | |
314 base::Bind(&EasyUnlockTpmKeyManager::CreateKeyInSystemSlot, | |
315 get_tpm_slot_weak_ptr_factory_.GetWeakPtr(), public_key); | |
316 | |
317 content::BrowserThread::PostTask( | |
318 content::BrowserThread::IO, FROM_HERE, | |
319 base::Bind(&GetSystemSlotOnIOThread, base::ThreadTaskRunnerHandle::Get(), | |
320 create_key_with_system_slot)); | |
321 } | |
322 | |
282 void EasyUnlockTpmKeyManager::CreateKeyInSystemSlot( | 323 void EasyUnlockTpmKeyManager::CreateKeyInSystemSlot( |
283 const std::string& public_key, | 324 const std::string& public_key, |
284 crypto::ScopedPK11Slot system_slot) { | 325 crypto::ScopedPK11Slot system_slot) { |
285 CHECK(system_slot); | 326 CHECK(system_slot); |
286 | |
287 create_tpm_key_state_ = CREATE_TPM_KEY_GOT_SYSTEM_SLOT; | 327 create_tpm_key_state_ = CREATE_TPM_KEY_GOT_SYSTEM_SLOT; |
288 | 328 |
289 // If there are any delayed tasks posted using |StartGetSystemSlotTimeoutMs|, | 329 // If there are any delayed tasks posted using |StartGetSystemSlotTimeoutMs|, |
290 // this will cancel them. | 330 // this will cancel them. |
291 // Note that this would cancel other pending |CreateKeyInSystemSlot| tasks, | 331 // Note that this would cancel other pending |CreateKeyInSystemSlot| tasks, |
292 // but there should be at most one such task at a time. | 332 // but there should be at most one such task at a time. |
293 get_tpm_slot_weak_ptr_factory_.InvalidateWeakPtrs(); | 333 get_tpm_slot_weak_ptr_factory_.InvalidateWeakPtrs(); |
294 | 334 |
295 base::WorkerPool::PostTask( | 335 base::WorkerPool::PostTask( |
296 FROM_HERE, | 336 FROM_HERE, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 // If key creation failed, reset the state machine. | 386 // If key creation failed, reset the state machine. |
347 create_tpm_key_state_ = | 387 create_tpm_key_state_ = |
348 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; | 388 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; |
349 } | 389 } |
350 | 390 |
351 void EasyUnlockTpmKeyManager::OnDataSigned( | 391 void EasyUnlockTpmKeyManager::OnDataSigned( |
352 const base::Callback<void(const std::string&)>& callback, | 392 const base::Callback<void(const std::string&)>& callback, |
353 const std::string& signature) { | 393 const std::string& signature) { |
354 callback.Run(signature); | 394 callback.Run(signature); |
355 } | 395 } |
OLD | NEW |