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/platform_keys/platform_keys.h" | 5 #include "chrome/browser/chromeos/platform_keys/platform_keys.h" |
6 | 6 |
7 #include <cert.h> | |
8 #include <cryptohi.h> | 7 #include <cryptohi.h> |
9 #include <keyhi.h> | |
10 #include <secder.h> | |
11 | 8 |
12 #include "base/bind.h" | 9 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
14 #include "base/callback.h" | 11 #include "base/callback.h" |
15 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
16 #include "base/location.h" | 13 #include "base/location.h" |
17 #include "base/logging.h" | 14 #include "base/logging.h" |
18 #include "base/macros.h" | 15 #include "base/macros.h" |
19 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
20 #include "base/stl_util.h" | |
21 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
22 #include "base/threading/worker_pool.h" | 18 #include "base/threading/worker_pool.h" |
23 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
24 #include "chrome/browser/browser_process_platform_part_chromeos.h" | 20 #include "chrome/browser/browser_process_platform_part_chromeos.h" |
25 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" | 21 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" |
26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
27 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 23 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
28 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat
form_keys_api.h" | 24 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat
form_keys_api.h" |
29 #include "chrome/browser/net/nss_context.h" | 25 #include "chrome/browser/net/nss_context.h" |
30 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
31 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 27 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
32 #include "content/public/browser/browser_context.h" | 28 #include "content/public/browser/browser_context.h" |
33 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
34 #include "crypto/rsa_private_key.h" | 30 #include "crypto/rsa_private_key.h" |
35 #include "net/base/crypto_module.h" | 31 #include "net/base/crypto_module.h" |
36 #include "net/base/net_errors.h" | 32 #include "net/base/net_errors.h" |
37 #include "net/cert/cert_database.h" | 33 #include "net/cert/cert_database.h" |
38 #include "net/cert/nss_cert_database.h" | 34 #include "net/cert/nss_cert_database.h" |
39 #include "net/cert/x509_certificate.h" | 35 #include "net/cert/x509_certificate.h" |
40 #include "net/cert/x509_util_nss.h" | |
41 #include "net/ssl/client_cert_store_chromeos.h" | 36 #include "net/ssl/client_cert_store_chromeos.h" |
42 #include "net/ssl/ssl_cert_request_info.h" | 37 #include "net/ssl/ssl_cert_request_info.h" |
43 | 38 |
44 using content::BrowserContext; | 39 using content::BrowserContext; |
45 using content::BrowserThread; | 40 using content::BrowserThread; |
46 | 41 |
47 namespace { | 42 namespace { |
48 const char kErrorInternal[] = "Internal Error."; | 43 const char kErrorInternal[] = "Internal Error."; |
49 const char kErrorKeyNotFound[] = "Key not found."; | 44 const char kErrorKeyNotFound[] = "Key not found."; |
50 const char kErrorCertificateNotFound[] = "Certificate could not be found."; | 45 const char kErrorCertificateNotFound[] = "Certificate could not be found."; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 from, base::Bind(callback_, public_key_spki_der, error_message)); | 161 from, base::Bind(callback_, public_key_spki_der, error_message)); |
167 } | 162 } |
168 | 163 |
169 const unsigned int modulus_length_bits_; | 164 const unsigned int modulus_length_bits_; |
170 | 165 |
171 private: | 166 private: |
172 // Must be called on origin thread, therefore use CallBack(). | 167 // Must be called on origin thread, therefore use CallBack(). |
173 subtle::GenerateKeyCallback callback_; | 168 subtle::GenerateKeyCallback callback_; |
174 }; | 169 }; |
175 | 170 |
176 class SignRSAState : public NSSOperationState { | 171 class SignState : public NSSOperationState { |
177 public: | 172 public: |
178 SignRSAState(const std::string& data, | 173 SignState(const std::string& public_key, |
179 const std::string& public_key, | 174 HashAlgorithm hash_algorithm, |
180 bool sign_direct_pkcs_padded, | 175 const std::string& data, |
181 HashAlgorithm hash_algorithm, | 176 const subtle::SignCallback& callback); |
182 const subtle::SignCallback& callback); | 177 ~SignState() override {} |
183 ~SignRSAState() override {} | |
184 | 178 |
185 void OnError(const tracked_objects::Location& from, | 179 void OnError(const tracked_objects::Location& from, |
186 const std::string& error_message) override { | 180 const std::string& error_message) override { |
187 CallBack(from, std::string() /* no signature */, error_message); | 181 CallBack(from, std::string() /* no signature */, error_message); |
188 } | 182 } |
189 | 183 |
190 void CallBack(const tracked_objects::Location& from, | 184 void CallBack(const tracked_objects::Location& from, |
191 const std::string& signature, | 185 const std::string& signature, |
192 const std::string& error_message) { | 186 const std::string& error_message) { |
193 origin_task_runner_->PostTask( | 187 origin_task_runner_->PostTask( |
194 from, base::Bind(callback_, signature, error_message)); | 188 from, base::Bind(callback_, signature, error_message)); |
195 } | 189 } |
196 | 190 |
197 // The data that will be signed. | 191 const std::string public_key_; |
| 192 HashAlgorithm hash_algorithm_; |
198 const std::string data_; | 193 const std::string data_; |
199 | 194 |
200 // Must be the DER encoding of a SubjectPublicKeyInfo. | |
201 const std::string public_key_; | |
202 | |
203 // If true, |data_| will not be hashed before signing. Only PKCS#1 v1.5 | |
204 // padding will be applied before signing. | |
205 // If false, |hash_algorithm_| must be set to a value != NONE. | |
206 const bool sign_direct_pkcs_padded_; | |
207 | |
208 // Determines the hash algorithm that is used to digest |data| before signing. | |
209 // Ignored if |sign_direct_pkcs_padded_| is true. | |
210 const HashAlgorithm hash_algorithm_; | |
211 | |
212 private: | 195 private: |
213 // Must be called on origin thread, therefore use CallBack(). | 196 // Must be called on origin thread, therefore use CallBack(). |
214 subtle::SignCallback callback_; | 197 subtle::SignCallback callback_; |
215 }; | 198 }; |
216 | 199 |
217 class SelectCertificatesState : public NSSOperationState { | 200 class SelectCertificatesState : public NSSOperationState { |
218 public: | 201 public: |
219 explicit SelectCertificatesState( | 202 explicit SelectCertificatesState( |
220 const std::string& username_hash, | 203 const std::string& username_hash, |
221 const bool use_system_key_slot, | 204 const bool use_system_key_slot, |
222 const scoped_refptr<net::SSLCertRequestInfo>& request, | 205 scoped_refptr<net::SSLCertRequestInfo> request, |
223 const subtle::SelectCertificatesCallback& callback); | 206 const subtle::SelectCertificatesCallback& callback); |
224 ~SelectCertificatesState() override {} | 207 ~SelectCertificatesState() override {} |
225 | 208 |
226 void OnError(const tracked_objects::Location& from, | 209 void OnError(const tracked_objects::Location& from, |
227 const std::string& error_message) override { | 210 const std::string& error_message) override { |
228 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, | 211 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, |
229 error_message); | 212 error_message); |
230 } | 213 } |
231 | 214 |
232 void CallBack(const tracked_objects::Location& from, | 215 void CallBack(const tracked_objects::Location& from, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 | 251 |
269 scoped_ptr<net::CertificateList> certs_; | 252 scoped_ptr<net::CertificateList> certs_; |
270 | 253 |
271 private: | 254 private: |
272 // Must be called on origin thread, therefore use CallBack(). | 255 // Must be called on origin thread, therefore use CallBack(). |
273 GetCertificatesCallback callback_; | 256 GetCertificatesCallback callback_; |
274 }; | 257 }; |
275 | 258 |
276 class ImportCertificateState : public NSSOperationState { | 259 class ImportCertificateState : public NSSOperationState { |
277 public: | 260 public: |
278 ImportCertificateState(const scoped_refptr<net::X509Certificate>& certificate, | 261 ImportCertificateState(scoped_refptr<net::X509Certificate> certificate, |
279 const ImportCertificateCallback& callback); | 262 const ImportCertificateCallback& callback); |
280 ~ImportCertificateState() override {} | 263 ~ImportCertificateState() override {} |
281 | 264 |
282 void OnError(const tracked_objects::Location& from, | 265 void OnError(const tracked_objects::Location& from, |
283 const std::string& error_message) override { | 266 const std::string& error_message) override { |
284 CallBack(from, error_message); | 267 CallBack(from, error_message); |
285 } | 268 } |
286 | 269 |
287 void CallBack(const tracked_objects::Location& from, | 270 void CallBack(const tracked_objects::Location& from, |
288 const std::string& error_message) { | 271 const std::string& error_message) { |
289 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); | 272 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); |
290 } | 273 } |
291 | 274 |
292 scoped_refptr<net::X509Certificate> certificate_; | 275 scoped_refptr<net::X509Certificate> certificate_; |
293 | 276 |
294 private: | 277 private: |
295 // Must be called on origin thread, therefore use CallBack(). | 278 // Must be called on origin thread, therefore use CallBack(). |
296 ImportCertificateCallback callback_; | 279 ImportCertificateCallback callback_; |
297 }; | 280 }; |
298 | 281 |
299 class RemoveCertificateState : public NSSOperationState { | 282 class RemoveCertificateState : public NSSOperationState { |
300 public: | 283 public: |
301 RemoveCertificateState(const scoped_refptr<net::X509Certificate>& certificate, | 284 RemoveCertificateState(scoped_refptr<net::X509Certificate> certificate, |
302 const RemoveCertificateCallback& callback); | 285 const RemoveCertificateCallback& callback); |
303 ~RemoveCertificateState() override {} | 286 ~RemoveCertificateState() override {} |
304 | 287 |
305 void OnError(const tracked_objects::Location& from, | 288 void OnError(const tracked_objects::Location& from, |
306 const std::string& error_message) override { | 289 const std::string& error_message) override { |
307 CallBack(from, error_message); | 290 CallBack(from, error_message); |
308 } | 291 } |
309 | 292 |
310 void CallBack(const tracked_objects::Location& from, | 293 void CallBack(const tracked_objects::Location& from, |
311 const std::string& error_message) { | 294 const std::string& error_message) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 NSSOperationState::NSSOperationState() | 329 NSSOperationState::NSSOperationState() |
347 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 330 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
348 } | 331 } |
349 | 332 |
350 GenerateRSAKeyState::GenerateRSAKeyState( | 333 GenerateRSAKeyState::GenerateRSAKeyState( |
351 unsigned int modulus_length_bits, | 334 unsigned int modulus_length_bits, |
352 const subtle::GenerateKeyCallback& callback) | 335 const subtle::GenerateKeyCallback& callback) |
353 : modulus_length_bits_(modulus_length_bits), callback_(callback) { | 336 : modulus_length_bits_(modulus_length_bits), callback_(callback) { |
354 } | 337 } |
355 | 338 |
356 SignRSAState::SignRSAState(const std::string& data, | 339 SignState::SignState(const std::string& public_key, |
357 const std::string& public_key, | 340 HashAlgorithm hash_algorithm, |
358 bool sign_direct_pkcs_padded, | 341 const std::string& data, |
359 HashAlgorithm hash_algorithm, | 342 const subtle::SignCallback& callback) |
360 const subtle::SignCallback& callback) | 343 : public_key_(public_key), |
361 : data_(data), | |
362 public_key_(public_key), | |
363 sign_direct_pkcs_padded_(sign_direct_pkcs_padded), | |
364 hash_algorithm_(hash_algorithm), | 344 hash_algorithm_(hash_algorithm), |
| 345 data_(data), |
365 callback_(callback) { | 346 callback_(callback) { |
366 } | 347 } |
367 | 348 |
368 SelectCertificatesState::SelectCertificatesState( | 349 SelectCertificatesState::SelectCertificatesState( |
369 const std::string& username_hash, | 350 const std::string& username_hash, |
370 const bool use_system_key_slot, | 351 const bool use_system_key_slot, |
371 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, | 352 scoped_refptr<net::SSLCertRequestInfo> cert_request_info, |
372 const subtle::SelectCertificatesCallback& callback) | 353 const subtle::SelectCertificatesCallback& callback) |
373 : username_hash_(username_hash), | 354 : username_hash_(username_hash), |
374 use_system_key_slot_(use_system_key_slot), | 355 use_system_key_slot_(use_system_key_slot), |
375 cert_request_info_(cert_request_info), | 356 cert_request_info_(cert_request_info), |
376 callback_(callback) { | 357 callback_(callback) { |
377 } | 358 } |
378 | 359 |
379 GetCertificatesState::GetCertificatesState( | 360 GetCertificatesState::GetCertificatesState( |
380 const GetCertificatesCallback& callback) | 361 const GetCertificatesCallback& callback) |
381 : callback_(callback) { | 362 : callback_(callback) { |
382 } | 363 } |
383 | 364 |
384 ImportCertificateState::ImportCertificateState( | 365 ImportCertificateState::ImportCertificateState( |
385 const scoped_refptr<net::X509Certificate>& certificate, | 366 scoped_refptr<net::X509Certificate> certificate, |
386 const ImportCertificateCallback& callback) | 367 const ImportCertificateCallback& callback) |
387 : certificate_(certificate), callback_(callback) { | 368 : certificate_(certificate), callback_(callback) { |
388 } | 369 } |
389 | 370 |
390 RemoveCertificateState::RemoveCertificateState( | 371 RemoveCertificateState::RemoveCertificateState( |
391 const scoped_refptr<net::X509Certificate>& certificate, | 372 scoped_refptr<net::X509Certificate> certificate, |
392 const RemoveCertificateCallback& callback) | 373 const RemoveCertificateCallback& callback) |
393 : certificate_(certificate), callback_(callback) { | 374 : certificate_(certificate), callback_(callback) { |
394 } | 375 } |
395 | 376 |
396 GetTokensState::GetTokensState(const GetTokensCallback& callback) | 377 GetTokensState::GetTokensState(const GetTokensCallback& callback) |
397 : callback_(callback) { | 378 : callback_(callback) { |
398 } | 379 } |
399 | 380 |
400 // Does the actual key generation on a worker thread. Used by | 381 // Does the actual key generation on a worker thread. Used by |
401 // GenerateRSAKeyWithDB(). | 382 // GenerateRSAKeyWithDB(). |
(...skipping 25 matching lines...) Expand all Loading... |
427 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, | 408 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, |
428 net::NSSCertDatabase* cert_db) { | 409 net::NSSCertDatabase* cert_db) { |
429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
430 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. | 411 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. |
431 base::WorkerPool::PostTask( | 412 base::WorkerPool::PostTask( |
432 FROM_HERE, | 413 FROM_HERE, |
433 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), | 414 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), |
434 true /*task is slow*/); | 415 true /*task is slow*/); |
435 } | 416 } |
436 | 417 |
437 // Does the actual signing on a worker thread. Used by SignRSAWithDB(). | 418 // Does the actual signing on a worker thread. Used by RSASignWithDB(). |
438 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) { | 419 void RSASignOnWorkerThread(scoped_ptr<SignState> state) { |
439 const uint8* public_key_uint8 = | 420 const uint8* public_key_uint8 = |
440 reinterpret_cast<const uint8*>(state->public_key_.data()); | 421 reinterpret_cast<const uint8*>(state->public_key_.data()); |
441 std::vector<uint8> public_key_vector( | 422 std::vector<uint8> public_key_vector( |
442 public_key_uint8, public_key_uint8 + state->public_key_.size()); | 423 public_key_uint8, public_key_uint8 + state->public_key_.size()); |
443 | 424 |
444 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. | 425 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. |
445 scoped_ptr<crypto::RSAPrivateKey> rsa_key( | 426 scoped_ptr<crypto::RSAPrivateKey> rsa_key( |
446 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); | 427 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); |
447 | 428 if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) { |
448 // Fail if the key was not found. If a specific slot was requested, also fail | |
449 // if the key was found in the wrong slot. | |
450 if (!rsa_key || | |
451 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) { | |
452 state->OnError(FROM_HERE, kErrorKeyNotFound); | 429 state->OnError(FROM_HERE, kErrorKeyNotFound); |
453 return; | 430 return; |
454 } | 431 } |
455 | 432 |
456 std::string signature_str; | 433 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; |
457 if (state->sign_direct_pkcs_padded_) { | 434 switch (state->hash_algorithm_) { |
458 static_assert( | 435 case HASH_ALGORITHM_SHA1: |
459 sizeof(*state->data_.data()) == sizeof(char), | 436 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
460 "Can't reinterpret data if it's characters are not 8 bit large."); | 437 break; |
461 SECItem input = {siBuffer, | 438 case HASH_ALGORITHM_SHA256: |
462 reinterpret_cast<unsigned char*>( | 439 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; |
463 const_cast<char*>(state->data_.data())), | 440 break; |
464 state->data_.size()}; | 441 case HASH_ALGORITHM_SHA384: |
465 | 442 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; |
466 // Compute signature of hash. | 443 break; |
467 int signature_len = PK11_SignatureLen(rsa_key->key()); | 444 case HASH_ALGORITHM_SHA512: |
468 if (signature_len <= 0) { | 445 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; |
469 state->OnError(FROM_HERE, kErrorInternal); | 446 break; |
470 return; | |
471 } | |
472 | |
473 std::vector<unsigned char> signature(signature_len); | |
474 SECItem signature_output = { | |
475 siBuffer, vector_as_array(&signature), signature.size()}; | |
476 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess) | |
477 signature_str.assign(signature.begin(), signature.end()); | |
478 } else { | |
479 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; | |
480 switch (state->hash_algorithm_) { | |
481 case HASH_ALGORITHM_SHA1: | |
482 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | |
483 break; | |
484 case HASH_ALGORITHM_SHA256: | |
485 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; | |
486 break; | |
487 case HASH_ALGORITHM_SHA384: | |
488 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; | |
489 break; | |
490 case HASH_ALGORITHM_SHA512: | |
491 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; | |
492 break; | |
493 case HASH_ALGORITHM_NONE: | |
494 NOTREACHED(); | |
495 break; | |
496 } | |
497 | |
498 SECItem sign_result = {siBuffer, nullptr, 0}; | |
499 if (SEC_SignData( | |
500 &sign_result, | |
501 reinterpret_cast<const unsigned char*>(state->data_.data()), | |
502 state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) { | |
503 signature_str.assign(sign_result.data, | |
504 sign_result.data + sign_result.len); | |
505 } | |
506 } | 447 } |
507 | 448 |
508 if (signature_str.empty()) { | 449 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); |
| 450 if (SEC_SignData(sign_result.get(), |
| 451 reinterpret_cast<const unsigned char*>(state->data_.data()), |
| 452 state->data_.size(), |
| 453 rsa_key->key(), |
| 454 sign_alg_tag) != SECSuccess) { |
509 LOG(ERROR) << "Couldn't sign."; | 455 LOG(ERROR) << "Couldn't sign."; |
510 state->OnError(FROM_HERE, kErrorInternal); | 456 state->OnError(FROM_HERE, kErrorInternal); |
511 return; | 457 return; |
512 } | 458 } |
513 | 459 |
514 state->CallBack(FROM_HERE, signature_str, std::string() /* no error */); | 460 std::string signature(reinterpret_cast<const char*>(sign_result->data), |
| 461 sign_result->len); |
| 462 state->CallBack(FROM_HERE, signature, std::string() /* no error */); |
515 } | 463 } |
516 | 464 |
517 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). | 465 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). |
518 void SignRSAWithDB(scoped_ptr<SignRSAState> state, | 466 void RSASignWithDB(scoped_ptr<SignState> state, net::NSSCertDatabase* cert_db) { |
519 net::NSSCertDatabase* cert_db) { | |
520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
521 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. | 468 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. |
522 base::WorkerPool::PostTask( | 469 base::WorkerPool::PostTask( |
523 FROM_HERE, base::Bind(&SignRSAOnWorkerThread, base::Passed(&state)), | 470 FROM_HERE, |
| 471 base::Bind(&RSASignOnWorkerThread, base::Passed(&state)), |
524 true /*task is slow*/); | 472 true /*task is slow*/); |
525 } | 473 } |
526 | 474 |
527 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list | 475 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list |
528 // of net::CertificateList and calls back. Used by | 476 // of net::CertificateList and calls back. Used by |
529 // SelectCertificatesOnIOThread(). | 477 // SelectCertificatesOnIOThread(). |
530 void DidSelectCertificatesOnIOThread( | 478 void DidSelectCertificatesOnIOThread( |
531 scoped_ptr<SelectCertificatesState> state) { | 479 scoped_ptr<SelectCertificatesState> state) { |
532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
533 state->CallBack(FROM_HERE, state->certs_.Pass(), | 481 state->CallBack(FROM_HERE, state->certs_.Pass(), |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 } | 648 } |
701 | 649 |
702 // Get the pointer to |state| before base::Passed releases |state|. | 650 // Get the pointer to |state| before base::Passed releases |state|. |
703 NSSOperationState* state_ptr = state.get(); | 651 NSSOperationState* state_ptr = state.get(); |
704 GetCertDatabase(token_id, | 652 GetCertDatabase(token_id, |
705 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), | 653 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), |
706 browser_context, | 654 browser_context, |
707 state_ptr); | 655 state_ptr); |
708 } | 656 } |
709 | 657 |
710 void SignRSAPKCS1Digest(const std::string& token_id, | 658 void Sign(const std::string& token_id, |
711 const std::string& data, | 659 const std::string& public_key, |
712 const std::string& public_key, | 660 HashAlgorithm hash_algorithm, |
713 HashAlgorithm hash_algorithm, | 661 const std::string& data, |
714 const SignCallback& callback, | 662 const SignCallback& callback, |
715 content::BrowserContext* browser_context) { | 663 BrowserContext* browser_context) { |
716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
717 scoped_ptr<SignRSAState> state( | 665 scoped_ptr<SignState> state( |
718 new SignRSAState(data, public_key, false /* digest before signing */, | 666 new SignState(public_key, hash_algorithm, data, callback)); |
719 hash_algorithm, callback)); | |
720 // Get the pointer to |state| before base::Passed releases |state|. | 667 // Get the pointer to |state| before base::Passed releases |state|. |
721 NSSOperationState* state_ptr = state.get(); | 668 NSSOperationState* state_ptr = state.get(); |
722 | 669 |
723 // The NSSCertDatabase object is not required. But in case it's not available | 670 // The NSSCertDatabase object is not required. But in case it's not available |
724 // we would get more informative error messages and we can double check that | 671 // we would get more informative error messages and we can double check that |
725 // we use a key of the correct token. | 672 // we use a key of the correct token. |
726 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)), | 673 GetCertDatabase(token_id, |
727 browser_context, state_ptr); | 674 base::Bind(&RSASignWithDB, base::Passed(&state)), |
728 } | 675 browser_context, |
729 | 676 state_ptr); |
730 void SignRSAPKCS1Raw(const std::string& token_id, | |
731 const std::string& data, | |
732 const std::string& public_key, | |
733 const SignCallback& callback, | |
734 content::BrowserContext* browser_context) { | |
735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
736 scoped_ptr<SignRSAState> state(new SignRSAState( | |
737 data, public_key, true /* sign directly without hashing */, | |
738 HASH_ALGORITHM_NONE, callback)); | |
739 // Get the pointer to |state| before base::Passed releases |state|. | |
740 NSSOperationState* state_ptr = state.get(); | |
741 | |
742 // The NSSCertDatabase object is not required. But in case it's not available | |
743 // we would get more informative error messages and we can double check that | |
744 // we use a key of the correct token. | |
745 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)), | |
746 browser_context, state_ptr); | |
747 } | 677 } |
748 | 678 |
749 void SelectClientCertificates(const ClientCertificateRequest& request, | 679 void SelectClientCertificates(const ClientCertificateRequest& request, |
750 const SelectCertificatesCallback& callback, | 680 const SelectCertificatesCallback& callback, |
751 content::BrowserContext* browser_context) { | 681 content::BrowserContext* browser_context) { |
752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
753 | 683 |
754 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 684 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |
755 new net::SSLCertRequestInfo); | 685 new net::SSLCertRequestInfo); |
756 cert_request_info->cert_key_types = request.certificate_key_types; | 686 cert_request_info->cert_key_types = request.certificate_key_types; |
(...skipping 12 matching lines...) Expand all Loading... |
769 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( | 699 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( |
770 user->username_hash(), use_system_key_slot, cert_request_info, callback)); | 700 user->username_hash(), use_system_key_slot, cert_request_info, callback)); |
771 | 701 |
772 BrowserThread::PostTask( | 702 BrowserThread::PostTask( |
773 BrowserThread::IO, FROM_HERE, | 703 BrowserThread::IO, FROM_HERE, |
774 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); | 704 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); |
775 } | 705 } |
776 | 706 |
777 } // namespace subtle | 707 } // namespace subtle |
778 | 708 |
779 bool GetPublicKey(const scoped_refptr<net::X509Certificate>& certificate, | |
780 std::string* public_key_spki_der, | |
781 net::X509Certificate::PublicKeyType* key_type, | |
782 size_t* key_size_bits) { | |
783 const SECItem& spki_der = certificate->os_cert_handle()->derPublicKey; | |
784 | |
785 net::X509Certificate::PublicKeyType key_type_tmp = | |
786 net::X509Certificate::kPublicKeyTypeUnknown; | |
787 size_t key_size_bits_tmp = 0; | |
788 net::X509Certificate::GetPublicKeyInfo(certificate->os_cert_handle(), | |
789 &key_size_bits_tmp, &key_type_tmp); | |
790 | |
791 if (key_type_tmp == net::X509Certificate::kPublicKeyTypeUnknown) { | |
792 LOG(WARNING) << "Could not extract public key of certificate."; | |
793 return false; | |
794 } | |
795 if (key_type_tmp != net::X509Certificate::kPublicKeyTypeRSA) { | |
796 LOG(WARNING) << "Keys of other type than RSA are not supported."; | |
797 return false; | |
798 } | |
799 | |
800 crypto::ScopedSECKEYPublicKey public_key( | |
801 CERT_ExtractPublicKey(certificate->os_cert_handle())); | |
802 if (!public_key) { | |
803 LOG(WARNING) << "Could not extract public key of certificate."; | |
804 return false; | |
805 } | |
806 long public_exponent = DER_GetInteger(&public_key->u.rsa.publicExponent); | |
807 if (public_exponent != 65537L) { | |
808 LOG(ERROR) << "Rejecting RSA public exponent that is unequal 65537."; | |
809 return false; | |
810 } | |
811 | |
812 public_key_spki_der->assign(spki_der.data, spki_der.data + spki_der.len); | |
813 *key_type = key_type_tmp; | |
814 *key_size_bits = key_size_bits_tmp; | |
815 | |
816 return true; | |
817 } | |
818 | |
819 void GetCertificates(const std::string& token_id, | 709 void GetCertificates(const std::string& token_id, |
820 const GetCertificatesCallback& callback, | 710 const GetCertificatesCallback& callback, |
821 BrowserContext* browser_context) { | 711 BrowserContext* browser_context) { |
822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
823 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); | 713 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); |
824 // Get the pointer to |state| before base::Passed releases |state|. | 714 // Get the pointer to |state| before base::Passed releases |state|. |
825 NSSOperationState* state_ptr = state.get(); | 715 NSSOperationState* state_ptr = state.get(); |
826 GetCertDatabase(token_id, | 716 GetCertDatabase(token_id, |
827 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), | 717 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), |
828 browser_context, | 718 browser_context, |
829 state_ptr); | 719 state_ptr); |
830 } | 720 } |
831 | 721 |
832 void ImportCertificate(const std::string& token_id, | 722 void ImportCertificate(const std::string& token_id, |
833 const scoped_refptr<net::X509Certificate>& certificate, | 723 scoped_refptr<net::X509Certificate> certificate, |
834 const ImportCertificateCallback& callback, | 724 const ImportCertificateCallback& callback, |
835 BrowserContext* browser_context) { | 725 BrowserContext* browser_context) { |
836 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
837 scoped_ptr<ImportCertificateState> state( | 727 scoped_ptr<ImportCertificateState> state( |
838 new ImportCertificateState(certificate, callback)); | 728 new ImportCertificateState(certificate, callback)); |
839 // Get the pointer to |state| before base::Passed releases |state|. | 729 // Get the pointer to |state| before base::Passed releases |state|. |
840 NSSOperationState* state_ptr = state.get(); | 730 NSSOperationState* state_ptr = state.get(); |
841 | 731 |
842 // The NSSCertDatabase object is not required. But in case it's not available | 732 // The NSSCertDatabase object is not required. But in case it's not available |
843 // we would get more informative error messages and we can double check that | 733 // we would get more informative error messages and we can double check that |
844 // we use a key of the correct token. | 734 // we use a key of the correct token. |
845 GetCertDatabase(token_id, | 735 GetCertDatabase(token_id, |
846 base::Bind(&ImportCertificateWithDB, base::Passed(&state)), | 736 base::Bind(&ImportCertificateWithDB, base::Passed(&state)), |
847 browser_context, | 737 browser_context, |
848 state_ptr); | 738 state_ptr); |
849 } | 739 } |
850 | 740 |
851 void RemoveCertificate(const std::string& token_id, | 741 void RemoveCertificate(const std::string& token_id, |
852 const scoped_refptr<net::X509Certificate>& certificate, | 742 scoped_refptr<net::X509Certificate> certificate, |
853 const RemoveCertificateCallback& callback, | 743 const RemoveCertificateCallback& callback, |
854 BrowserContext* browser_context) { | 744 BrowserContext* browser_context) { |
855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
856 scoped_ptr<RemoveCertificateState> state( | 746 scoped_ptr<RemoveCertificateState> state( |
857 new RemoveCertificateState(certificate, callback)); | 747 new RemoveCertificateState(certificate, callback)); |
858 // Get the pointer to |state| before base::Passed releases |state|. | 748 // Get the pointer to |state| before base::Passed releases |state|. |
859 NSSOperationState* state_ptr = state.get(); | 749 NSSOperationState* state_ptr = state.get(); |
860 | 750 |
861 // The NSSCertDatabase object is not required. But in case it's not available | 751 // The NSSCertDatabase object is not required. But in case it's not available |
862 // we would get more informative error messages. | 752 // we would get more informative error messages. |
(...skipping 11 matching lines...) Expand all Loading... |
874 NSSOperationState* state_ptr = state.get(); | 764 NSSOperationState* state_ptr = state.get(); |
875 GetCertDatabase(std::string() /* don't get any specific slot */, | 765 GetCertDatabase(std::string() /* don't get any specific slot */, |
876 base::Bind(&GetTokensWithDB, base::Passed(&state)), | 766 base::Bind(&GetTokensWithDB, base::Passed(&state)), |
877 browser_context, | 767 browser_context, |
878 state_ptr); | 768 state_ptr); |
879 } | 769 } |
880 | 770 |
881 } // namespace platform_keys | 771 } // namespace platform_keys |
882 | 772 |
883 } // namespace chromeos | 773 } // namespace chromeos |
OLD | NEW |