Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc

Issue 1128153003: Reland "Don't use RSAPrivateKey in NSS integration code." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix crash Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 if (!state->slot_) {
davidben 2015/05/06 18:48:39 This shouldn't be possible, but if token_id is emp
pneubeck (no reviews) 2015/05/07 12:19:16 That's right. I'll create a separate CL that adds
404 crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(), 405 LOG(ERROR) << "No slot.";
405 state->modulus_length_bits_)); 406 state->OnError(FROM_HERE, kErrorInternal);
406 if (!rsa_key) { 407 return;
408 }
409
410 crypto::ScopedSECKEYPublicKey public_key;
411 crypto::ScopedSECKEYPrivateKey private_key;
412 if (!crypto::GenerateRSAKeyPairNSS(
413 state->slot_.get(), state->modulus_length_bits_, true /* permanent */,
414 &public_key, &private_key)) {
407 LOG(ERROR) << "Couldn't create key."; 415 LOG(ERROR) << "Couldn't create key.";
408 state->OnError(FROM_HERE, kErrorInternal); 416 state->OnError(FROM_HERE, kErrorInternal);
409 return; 417 return;
410 } 418 }
411 419
412 std::vector<uint8> public_key_spki_der; 420 crypto::ScopedSECItem public_key_der(
413 if (!rsa_key->ExportPublicKey(&public_key_spki_der)) { 421 SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
414 // TODO(pneubeck): Remove rsa_key from storage. 422 if (!public_key_der) {
423 // TODO(pneubeck): Remove private_key and public_key from storage.
415 LOG(ERROR) << "Couldn't export public key."; 424 LOG(ERROR) << "Couldn't export public key.";
416 state->OnError(FROM_HERE, kErrorInternal); 425 state->OnError(FROM_HERE, kErrorInternal);
417 return; 426 return;
418 } 427 }
419 state->CallBack( 428 state->CallBack(
420 FROM_HERE, 429 FROM_HERE,
421 std::string(public_key_spki_der.begin(), public_key_spki_der.end()), 430 std::string(reinterpret_cast<const char*>(public_key_der->data),
431 public_key_der->len),
422 std::string() /* no error */); 432 std::string() /* no error */);
423 } 433 }
424 434
425 // Continues generating a RSA key with the obtained NSSCertDatabase. Used by 435 // Continues generating a RSA key with the obtained NSSCertDatabase. Used by
426 // GenerateRSAKey(). 436 // GenerateRSAKey().
427 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, 437 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state,
428 net::NSSCertDatabase* cert_db) { 438 net::NSSCertDatabase* cert_db) {
429 DCHECK_CURRENTLY_ON(BrowserThread::IO); 439 DCHECK_CURRENTLY_ON(BrowserThread::IO);
430 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 440 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|.
431 base::WorkerPool::PostTask( 441 base::WorkerPool::PostTask(
432 FROM_HERE, 442 FROM_HERE,
433 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), 443 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)),
434 true /*task is slow*/); 444 true /*task is slow*/);
435 } 445 }
436 446
437 // Does the actual signing on a worker thread. Used by SignRSAWithDB(). 447 // Does the actual signing on a worker thread. Used by SignRSAWithDB().
438 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) { 448 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
439 const uint8* public_key_uint8 = 449 const uint8* public_key_uint8 =
440 reinterpret_cast<const uint8*>(state->public_key_.data()); 450 reinterpret_cast<const uint8*>(state->public_key_.data());
441 std::vector<uint8> public_key_vector( 451 std::vector<uint8> public_key_vector(
442 public_key_uint8, public_key_uint8 + state->public_key_.size()); 452 public_key_uint8, public_key_uint8 + state->public_key_.size());
443 453
444 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. 454 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|.
445 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 455 crypto::ScopedSECKEYPrivateKey rsa_key(
446 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); 456 crypto::FindNSSKeyFromPublicKeyInfo(public_key_vector));
447 457
448 // Fail if the key was not found. If a specific slot was requested, also fail 458 // 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. 459 // if the key was found in the wrong slot.
450 if (!rsa_key || 460 if (!rsa_key || SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey ||
451 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) { 461 (state->slot_ && rsa_key->pkcs11Slot != state->slot_)) {
452 state->OnError(FROM_HERE, kErrorKeyNotFound); 462 state->OnError(FROM_HERE, kErrorKeyNotFound);
453 return; 463 return;
454 } 464 }
455 465
456 std::string signature_str; 466 std::string signature_str;
457 if (state->sign_direct_pkcs_padded_) { 467 if (state->sign_direct_pkcs_padded_) {
458 static_assert( 468 static_assert(
459 sizeof(*state->data_.data()) == sizeof(char), 469 sizeof(*state->data_.data()) == sizeof(char),
460 "Can't reinterpret data if it's characters are not 8 bit large."); 470 "Can't reinterpret data if it's characters are not 8 bit large.");
461 SECItem input = {siBuffer, 471 SECItem input = {siBuffer,
462 reinterpret_cast<unsigned char*>( 472 reinterpret_cast<unsigned char*>(
463 const_cast<char*>(state->data_.data())), 473 const_cast<char*>(state->data_.data())),
464 state->data_.size()}; 474 state->data_.size()};
465 475
466 // Compute signature of hash. 476 // Compute signature of hash.
467 int signature_len = PK11_SignatureLen(rsa_key->key()); 477 int signature_len = PK11_SignatureLen(rsa_key.get());
468 if (signature_len <= 0) { 478 if (signature_len <= 0) {
469 state->OnError(FROM_HERE, kErrorInternal); 479 state->OnError(FROM_HERE, kErrorInternal);
470 return; 480 return;
471 } 481 }
472 482
473 std::vector<unsigned char> signature(signature_len); 483 std::vector<unsigned char> signature(signature_len);
474 SECItem signature_output = { 484 SECItem signature_output = {
475 siBuffer, vector_as_array(&signature), signature.size()}; 485 siBuffer, vector_as_array(&signature), signature.size()};
476 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess) 486 if (PK11_Sign(rsa_key.get(), &signature_output, &input) == SECSuccess)
477 signature_str.assign(signature.begin(), signature.end()); 487 signature_str.assign(signature.begin(), signature.end());
478 } else { 488 } else {
479 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; 489 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
480 switch (state->hash_algorithm_) { 490 switch (state->hash_algorithm_) {
481 case HASH_ALGORITHM_SHA1: 491 case HASH_ALGORITHM_SHA1:
482 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 492 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
483 break; 493 break;
484 case HASH_ALGORITHM_SHA256: 494 case HASH_ALGORITHM_SHA256:
485 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 495 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
486 break; 496 break;
487 case HASH_ALGORITHM_SHA384: 497 case HASH_ALGORITHM_SHA384:
488 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 498 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
489 break; 499 break;
490 case HASH_ALGORITHM_SHA512: 500 case HASH_ALGORITHM_SHA512:
491 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 501 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
492 break; 502 break;
493 case HASH_ALGORITHM_NONE: 503 case HASH_ALGORITHM_NONE:
494 NOTREACHED(); 504 NOTREACHED();
495 break; 505 break;
496 } 506 }
497 507
498 SECItem sign_result = {siBuffer, nullptr, 0}; 508 SECItem sign_result = {siBuffer, nullptr, 0};
499 if (SEC_SignData( 509 if (SEC_SignData(
500 &sign_result, 510 &sign_result,
501 reinterpret_cast<const unsigned char*>(state->data_.data()), 511 reinterpret_cast<const unsigned char*>(state->data_.data()),
502 state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) { 512 state->data_.size(), rsa_key.get(), sign_alg_tag) == SECSuccess) {
503 signature_str.assign(sign_result.data, 513 signature_str.assign(sign_result.data,
504 sign_result.data + sign_result.len); 514 sign_result.data + sign_result.len);
505 } 515 }
506 } 516 }
507 517
508 if (signature_str.empty()) { 518 if (signature_str.empty()) {
509 LOG(ERROR) << "Couldn't sign."; 519 LOG(ERROR) << "Couldn't sign.";
510 state->OnError(FROM_HERE, kErrorInternal); 520 state->OnError(FROM_HERE, kErrorInternal);
511 return; 521 return;
512 } 522 }
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 NSSOperationState* state_ptr = state.get(); 886 NSSOperationState* state_ptr = state.get();
877 GetCertDatabase(std::string() /* don't get any specific slot */, 887 GetCertDatabase(std::string() /* don't get any specific slot */,
878 base::Bind(&GetTokensWithDB, base::Passed(&state)), 888 base::Bind(&GetTokensWithDB, base::Passed(&state)),
879 browser_context, 889 browser_context,
880 state_ptr); 890 state_ptr);
881 } 891 }
882 892
883 } // namespace platform_keys 893 } // namespace platform_keys
884 894
885 } // namespace chromeos 895 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698