Chromium Code Reviews| 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> | 7 #include <cert.h> |
| 8 #include <cryptohi.h> | 8 #include <cryptohi.h> |
| 9 #include <keyhi.h> | 9 #include <keyhi.h> |
| 10 #include <secder.h> | 10 #include <secder.h> |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "chrome/browser/browser_process_platform_part_chromeos.h" | 24 #include "chrome/browser/browser_process_platform_part_chromeos.h" |
| 25 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" | 25 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" |
| 26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 27 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 27 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 28 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h" | 28 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h" |
| 29 #include "chrome/browser/net/nss_context.h" | 29 #include "chrome/browser/net/nss_context.h" |
| 30 #include "chrome/browser/profiles/profile.h" | 30 #include "chrome/browser/profiles/profile.h" |
| 31 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 31 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
| 32 #include "content/public/browser/browser_context.h" | 32 #include "content/public/browser/browser_context.h" |
| 33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 34 #include "crypto/rsa_private_key.h" | 34 #include "crypto/nss_key_util.h" |
| 35 #include "crypto/scoped_nss_types.h" | |
| 35 #include "net/base/crypto_module.h" | 36 #include "net/base/crypto_module.h" |
| 36 #include "net/base/net_errors.h" | 37 #include "net/base/net_errors.h" |
| 37 #include "net/cert/cert_database.h" | 38 #include "net/cert/cert_database.h" |
| 38 #include "net/cert/nss_cert_database.h" | 39 #include "net/cert/nss_cert_database.h" |
| 39 #include "net/cert/x509_certificate.h" | 40 #include "net/cert/x509_certificate.h" |
| 40 #include "net/cert/x509_util_nss.h" | 41 #include "net/cert/x509_util_nss.h" |
| 41 #include "net/ssl/client_cert_store_chromeos.h" | 42 #include "net/ssl/client_cert_store_chromeos.h" |
| 42 #include "net/ssl/ssl_cert_request_info.h" | 43 #include "net/ssl/ssl_cert_request_info.h" |
| 43 | 44 |
| 44 using content::BrowserContext; | 45 using content::BrowserContext; |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 : certificate_(certificate), callback_(callback) { | 394 : certificate_(certificate), callback_(callback) { |
| 394 } | 395 } |
| 395 | 396 |
| 396 GetTokensState::GetTokensState(const GetTokensCallback& callback) | 397 GetTokensState::GetTokensState(const GetTokensCallback& callback) |
| 397 : callback_(callback) { | 398 : callback_(callback) { |
| 398 } | 399 } |
| 399 | 400 |
| 400 // Does the actual key generation on a worker thread. Used by | 401 // Does the actual key generation on a worker thread. Used by |
| 401 // GenerateRSAKeyWithDB(). | 402 // GenerateRSAKeyWithDB(). |
| 402 void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) { | 403 void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) { |
| 403 scoped_ptr<crypto::RSAPrivateKey> rsa_key( | 404 crypto::ScopedSECKEYPublicKey public_key; |
| 404 crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(), | 405 crypto::ScopedSECKEYPrivateKey private_key; |
| 405 state->modulus_length_bits_)); | 406 if (!crypto::GenerateRSAKeyPairNSS( |
| 406 if (!rsa_key) { | 407 state->slot_.get(), state->modulus_length_bits_, true /* permanent */, |
| 408 &public_key, &private_key)) { | |
| 407 LOG(ERROR) << "Couldn't create key."; | 409 LOG(ERROR) << "Couldn't create key."; |
| 408 state->OnError(FROM_HERE, kErrorInternal); | 410 state->OnError(FROM_HERE, kErrorInternal); |
| 409 return; | 411 return; |
| 410 } | 412 } |
| 411 | 413 |
| 412 std::vector<uint8> public_key_spki_der; | 414 crypto::ScopedSECItem spki_item( |
|
Ryan Sleevi
2015/04/27 19:11:26
public_key_der?
davidben
2015/04/27 19:53:44
Done.
| |
| 413 if (!rsa_key->ExportPublicKey(&public_key_spki_der)) { | 415 SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get())); |
| 414 // TODO(pneubeck): Remove rsa_key from storage. | 416 if (!spki_item) { |
| 417 // TODO(pneubeck): Remove private_key and public_key from storage. | |
| 415 LOG(ERROR) << "Couldn't export public key."; | 418 LOG(ERROR) << "Couldn't export public key."; |
| 416 state->OnError(FROM_HERE, kErrorInternal); | 419 state->OnError(FROM_HERE, kErrorInternal); |
| 417 return; | 420 return; |
| 418 } | 421 } |
| 419 state->CallBack( | 422 state->CallBack(FROM_HERE, |
| 420 FROM_HERE, | 423 std::string(reinterpret_cast<const char*>(spki_item->data), |
| 421 std::string(public_key_spki_der.begin(), public_key_spki_der.end()), | 424 spki_item->len), |
| 422 std::string() /* no error */); | 425 std::string() /* no error */); |
| 423 } | 426 } |
| 424 | 427 |
| 425 // Continues generating a RSA key with the obtained NSSCertDatabase. Used by | 428 // Continues generating a RSA key with the obtained NSSCertDatabase. Used by |
| 426 // GenerateRSAKey(). | 429 // GenerateRSAKey(). |
| 427 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, | 430 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, |
| 428 net::NSSCertDatabase* cert_db) { | 431 net::NSSCertDatabase* cert_db) { |
| 429 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 432 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 430 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. | 433 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. |
| 431 base::WorkerPool::PostTask( | 434 base::WorkerPool::PostTask( |
| 432 FROM_HERE, | 435 FROM_HERE, |
| 433 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), | 436 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), |
| 434 true /*task is slow*/); | 437 true /*task is slow*/); |
| 435 } | 438 } |
| 436 | 439 |
| 437 // Does the actual signing on a worker thread. Used by SignRSAWithDB(). | 440 // Does the actual signing on a worker thread. Used by SignRSAWithDB(). |
| 438 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) { | 441 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) { |
| 439 const uint8* public_key_uint8 = | 442 const uint8* public_key_uint8 = |
| 440 reinterpret_cast<const uint8*>(state->public_key_.data()); | 443 reinterpret_cast<const uint8*>(state->public_key_.data()); |
| 441 std::vector<uint8> public_key_vector( | 444 std::vector<uint8> public_key_vector( |
| 442 public_key_uint8, public_key_uint8 + state->public_key_.size()); | 445 public_key_uint8, public_key_uint8 + state->public_key_.size()); |
| 443 | 446 |
| 444 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. | 447 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. |
| 445 scoped_ptr<crypto::RSAPrivateKey> rsa_key( | 448 crypto::ScopedSECKEYPrivateKey rsa_key( |
| 446 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); | 449 crypto::FindNSSKeyFromPublicKeyInfo(public_key_vector)); |
| 447 | 450 |
| 448 // Fail if the key was not found. If a specific slot was requested, also fail | 451 // 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. | 452 // if the key was found in the wrong slot. |
| 450 if (!rsa_key || | 453 if (!rsa_key || SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey || |
| 451 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) { | 454 (state->slot_ && rsa_key->pkcs11Slot != state->slot_)) { |
| 452 state->OnError(FROM_HERE, kErrorKeyNotFound); | 455 state->OnError(FROM_HERE, kErrorKeyNotFound); |
| 453 return; | 456 return; |
| 454 } | 457 } |
| 455 | 458 |
| 456 std::string signature_str; | 459 std::string signature_str; |
| 457 if (state->sign_direct_pkcs_padded_) { | 460 if (state->sign_direct_pkcs_padded_) { |
| 458 static_assert( | 461 static_assert( |
| 459 sizeof(*state->data_.data()) == sizeof(char), | 462 sizeof(*state->data_.data()) == sizeof(char), |
| 460 "Can't reinterpret data if it's characters are not 8 bit large."); | 463 "Can't reinterpret data if it's characters are not 8 bit large."); |
| 461 SECItem input = {siBuffer, | 464 SECItem input = {siBuffer, |
| 462 reinterpret_cast<unsigned char*>( | 465 reinterpret_cast<unsigned char*>( |
| 463 const_cast<char*>(state->data_.data())), | 466 const_cast<char*>(state->data_.data())), |
| 464 state->data_.size()}; | 467 state->data_.size()}; |
| 465 | 468 |
| 466 // Compute signature of hash. | 469 // Compute signature of hash. |
| 467 int signature_len = PK11_SignatureLen(rsa_key->key()); | 470 int signature_len = PK11_SignatureLen(rsa_key.get()); |
| 468 if (signature_len <= 0) { | 471 if (signature_len <= 0) { |
| 469 state->OnError(FROM_HERE, kErrorInternal); | 472 state->OnError(FROM_HERE, kErrorInternal); |
| 470 return; | 473 return; |
| 471 } | 474 } |
| 472 | 475 |
| 473 std::vector<unsigned char> signature(signature_len); | 476 std::vector<unsigned char> signature(signature_len); |
| 474 SECItem signature_output = { | 477 SECItem signature_output = { |
| 475 siBuffer, vector_as_array(&signature), signature.size()}; | 478 siBuffer, vector_as_array(&signature), signature.size()}; |
| 476 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess) | 479 if (PK11_Sign(rsa_key.get(), &signature_output, &input) == SECSuccess) |
| 477 signature_str.assign(signature.begin(), signature.end()); | 480 signature_str.assign(signature.begin(), signature.end()); |
| 478 } else { | 481 } else { |
| 479 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; | 482 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; |
| 480 switch (state->hash_algorithm_) { | 483 switch (state->hash_algorithm_) { |
| 481 case HASH_ALGORITHM_SHA1: | 484 case HASH_ALGORITHM_SHA1: |
| 482 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | 485 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
| 483 break; | 486 break; |
| 484 case HASH_ALGORITHM_SHA256: | 487 case HASH_ALGORITHM_SHA256: |
| 485 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; | 488 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; |
| 486 break; | 489 break; |
| 487 case HASH_ALGORITHM_SHA384: | 490 case HASH_ALGORITHM_SHA384: |
| 488 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; | 491 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; |
| 489 break; | 492 break; |
| 490 case HASH_ALGORITHM_SHA512: | 493 case HASH_ALGORITHM_SHA512: |
| 491 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; | 494 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; |
| 492 break; | 495 break; |
| 493 case HASH_ALGORITHM_NONE: | 496 case HASH_ALGORITHM_NONE: |
| 494 NOTREACHED(); | 497 NOTREACHED(); |
| 495 break; | 498 break; |
| 496 } | 499 } |
| 497 | 500 |
| 498 SECItem sign_result = {siBuffer, nullptr, 0}; | 501 SECItem sign_result = {siBuffer, nullptr, 0}; |
| 499 if (SEC_SignData( | 502 if (SEC_SignData( |
| 500 &sign_result, | 503 &sign_result, |
| 501 reinterpret_cast<const unsigned char*>(state->data_.data()), | 504 reinterpret_cast<const unsigned char*>(state->data_.data()), |
| 502 state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) { | 505 state->data_.size(), rsa_key.get(), sign_alg_tag) == SECSuccess) { |
| 503 signature_str.assign(sign_result.data, | 506 signature_str.assign(sign_result.data, |
| 504 sign_result.data + sign_result.len); | 507 sign_result.data + sign_result.len); |
| 505 } | 508 } |
| 506 } | 509 } |
| 507 | 510 |
| 508 if (signature_str.empty()) { | 511 if (signature_str.empty()) { |
| 509 LOG(ERROR) << "Couldn't sign."; | 512 LOG(ERROR) << "Couldn't sign."; |
| 510 state->OnError(FROM_HERE, kErrorInternal); | 513 state->OnError(FROM_HERE, kErrorInternal); |
| 511 return; | 514 return; |
| 512 } | 515 } |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 876 NSSOperationState* state_ptr = state.get(); | 879 NSSOperationState* state_ptr = state.get(); |
| 877 GetCertDatabase(std::string() /* don't get any specific slot */, | 880 GetCertDatabase(std::string() /* don't get any specific slot */, |
| 878 base::Bind(&GetTokensWithDB, base::Passed(&state)), | 881 base::Bind(&GetTokensWithDB, base::Passed(&state)), |
| 879 browser_context, | 882 browser_context, |
| 880 state_ptr); | 883 state_ptr); |
| 881 } | 884 } |
| 882 | 885 |
| 883 } // namespace platform_keys | 886 } // namespace platform_keys |
| 884 | 887 |
| 885 } // namespace chromeos | 888 } // namespace chromeos |
| OLD | NEW |