summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc9
-rw-r--r--chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc42
-rw-r--r--chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc22
-rw-r--r--chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h4
-rw-r--r--chrome/browser/chromeos/platform_keys/platform_keys_nss.cc42
-rw-r--r--components/ownership.gypi5
-rw-r--r--components/ownership/BUILD.gn5
-rw-r--r--components/ownership/owner_key_util_impl.cc21
-rw-r--r--crypto/BUILD.gn23
-rw-r--r--crypto/crypto.gyp16
-rw-r--r--crypto/crypto.gypi2
-rw-r--r--crypto/nss_key_util.cc163
-rw-r--r--crypto/nss_key_util.h58
-rw-r--r--crypto/nss_key_util_unittest.cc87
-rw-r--r--crypto/rsa_private_key.h69
-rw-r--r--crypto/rsa_private_key_nss.cc233
-rw-r--r--crypto/rsa_private_key_nss_unittest.cc66
-rw-r--r--net/net.gyp1
-rw-r--r--net/test/cert_test_util.h15
-rw-r--r--net/test/cert_test_util_nss.cc29
20 files changed, 478 insertions, 434 deletions
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
index 2607ace..c96e922 100644
--- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -45,6 +45,7 @@
#include "components/ownership/mock_owner_key_util.h"
#include "components/user_manager/fake_user_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_test_nss_chromeos_user.h"
#include "google_apis/gaia/mock_url_fetcher_factory.h"
@@ -118,11 +119,11 @@ std::vector<uint8> GetOwnerPublicKey() {
kOwnerPublicKey + arraysize(kOwnerPublicKey));
}
-scoped_ptr<crypto::RSAPrivateKey> CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
+bool CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
const std::vector<uint8> key(kOwnerPrivateKey,
kOwnerPrivateKey + arraysize(kOwnerPrivateKey));
- return make_scoped_ptr(
- crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, key));
+ return crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key,
+ true /* permanent */);
}
} // namespace
@@ -472,7 +473,7 @@ TEST_F(CryptohomeAuthenticatorTest, ResolveOwnerNeededSuccess) {
crypto::ScopedPK11Slot user_slot(
crypto::GetPublicSlotForChromeOSUser(user_context_.GetUserIDHash()));
- CreateOwnerKeyInSlot(user_slot.get());
+ ASSERT_TRUE(CreateOwnerKeyInSlot(user_slot.get()));
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc
index 3321ed9..46058c1 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h"
#include <cryptohi.h>
+#include <keyhi.h>
#include "base/base64.h"
#include "base/bind.h"
@@ -22,8 +23,8 @@
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util_internal.h"
-#include "crypto/rsa_private_key.h"
#include "crypto/scoped_nss_types.h"
namespace {
@@ -57,7 +58,7 @@ void GetSystemSlotOnIOThread(
// Checks if a private RSA key associated with |public_key| can be found in
// |slot|.
// Must be called on a worker thread.
-scoped_ptr<crypto::RSAPrivateKey> GetPrivateKeyOnWorkerThread(
+crypto::ScopedSECKEYPrivateKey GetPrivateKeyOnWorkerThread(
PK11SlotInfo* slot,
const std::string& public_key) {
const uint8* public_key_uint8 =
@@ -65,10 +66,14 @@ scoped_ptr<crypto::RSAPrivateKey> GetPrivateKeyOnWorkerThread(
std::vector<uint8> public_key_vector(
public_key_uint8, public_key_uint8 + public_key.size());
- scoped_ptr<crypto::RSAPrivateKey> rsa_key(
- crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector));
- if (!rsa_key || rsa_key->key()->pkcs11Slot != slot)
- return scoped_ptr<crypto::RSAPrivateKey>();
+ // TODO(davidben): This should be equivalent to calling
+ // FindNSSKeyFromPublicKeyInfoInSlot.
+ crypto::ScopedSECKEYPrivateKey rsa_key(
+ crypto::FindNSSKeyFromPublicKeyInfo(public_key_vector));
+ if (!rsa_key || rsa_key->pkcs11Slot != slot ||
+ SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey) {
+ return nullptr;
+ }
return rsa_key.Pass();
}
@@ -81,7 +86,7 @@ void SignDataOnWorkerThread(
const std::string& data,
const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
const base::Callback<void(const std::string&)>& callback) {
- scoped_ptr<crypto::RSAPrivateKey> private_key(
+ crypto::ScopedSECKEYPrivateKey private_key(
GetPrivateKeyOnWorkerThread(slot.get(), public_key));
if (!private_key) {
LOG(ERROR) << "Private key for signing data not found";
@@ -93,8 +98,7 @@ void SignDataOnWorkerThread(
crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0));
if (SEC_SignData(sign_result.get(),
reinterpret_cast<const unsigned char*>(data.data()),
- data.size(),
- private_key->key(),
+ data.size(), private_key.get(),
SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION) != SECSuccess) {
LOG(ERROR) << "Failed to sign data";
response_task_runner->PostTask(FROM_HERE,
@@ -123,17 +127,20 @@ void CreateTpmKeyPairOnWorkerThread(
return;
}
- scoped_ptr<crypto::RSAPrivateKey> rsa_key(
- crypto::RSAPrivateKey::CreateSensitive(slot.get(), kKeyModulusLength));
- if (!rsa_key) {
+ crypto::ScopedSECKEYPublicKey public_key_obj;
+ crypto::ScopedSECKEYPrivateKey private_key_obj;
+ if (!crypto::GenerateRSAKeyPairNSS(slot.get(), kKeyModulusLength,
+ true /* permanent */, &public_key_obj,
+ &private_key_obj)) {
LOG(ERROR) << "Failed to create an RSA key.";
response_task_runner->PostTask(FROM_HERE,
base::Bind(callback, std::string()));
return;
}
- std::vector<uint8> created_public_key;
- if (!rsa_key->ExportPublicKey(&created_public_key)) {
+ crypto::ScopedSECItem public_key_der(
+ SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_obj.get()));
+ if (!public_key_der) {
LOG(ERROR) << "Failed to export public key.";
response_task_runner->PostTask(FROM_HERE,
base::Bind(callback, std::string()));
@@ -141,10 +148,9 @@ void CreateTpmKeyPairOnWorkerThread(
}
response_task_runner->PostTask(
- FROM_HERE,
- base::Bind(callback,
- std::string(created_public_key.begin(),
- created_public_key.end())));
+ FROM_HERE, base::Bind(callback, std::string(reinterpret_cast<const char*>(
+ public_key_der->data),
+ public_key_der->len)));
}
} // namespace
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
index a96f0aa..20fdd78 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
+#include <keyhi.h>
+
#include <algorithm>
#include <string>
@@ -29,9 +31,9 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/common/content_switches.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
-#include "crypto/rsa_private_key.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/signature_creator.h"
@@ -72,9 +74,14 @@ void LoadPrivateKeyByPublicKey(
crypto::ScopedPK11Slot private_slot = crypto::GetPrivateSlotForChromeOSUser(
username_hash, base::Callback<void(crypto::ScopedPK11Slot)>());
- // If private slot is already available, this will check it. If not,
- // we'll get called again later when the TPM Token is ready, and the
- // slot will be available then.
+ // If private slot is already available, this will check it. If not, we'll get
+ // called again later when the TPM Token is ready, and the slot will be
+ // available then. FindPrivateKeyInSlot internally checks for a null slot if
+ // needbe.
+ //
+ // TODO(davidben): The null check should be in the caller rather than
+ // internally in the OwnerKeyUtil implementation. The tests currently get a
+ // null private_slot and expect the mock OwnerKeyUtil to still be called.
scoped_refptr<PrivateKey> private_key(
new PrivateKey(owner_key_util->FindPrivateKeyInSlot(public_key->data(),
private_slot.get())));
@@ -124,10 +131,9 @@ bool DoesPrivateKeyExistAsyncHelper(
std::vector<uint8> public_key;
if (!owner_key_util->ImportPublicKey(&public_key))
return false;
- scoped_ptr<crypto::RSAPrivateKey> key(
- crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
- bool is_owner = key.get() != NULL;
- return is_owner;
+ crypto::ScopedSECKEYPrivateKey key =
+ crypto::FindNSSKeyFromPublicKeyInfo(public_key);
+ return key && SECKEY_GetPrivateKeyType(key.get()) == rsaKey;
}
// Checks whether NSS slots with private key are mounted or
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
index 354450b..aea7cc0 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
@@ -135,7 +135,9 @@ class OwnerSettingsServiceChromeOS : public ownership::OwnerSettingsService,
// OwnerSettingsService protected interface overrides:
- // Reloads private key from profile's NSS slots, responds via |callback|.
+ // Reloads private key from profile's NSS slots, responds via |callback|. On
+ // success, |private_key| is non-null, but if the private key doesn't exist,
+ // |private_key->key()| may be null.
void ReloadKeypairImpl(const base::Callback<
void(const scoped_refptr<ownership::PublicKey>& public_key,
const scoped_refptr<ownership::PrivateKey>& private_key)>& callback)
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
index af14d11..5678baf 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -31,7 +31,8 @@
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "crypto/rsa_private_key.h"
+#include "crypto/nss_key_util.h"
+#include "crypto/scoped_nss_types.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_database.h"
@@ -400,25 +401,34 @@ GetTokensState::GetTokensState(const GetTokensCallback& callback)
// Does the actual key generation on a worker thread. Used by
// GenerateRSAKeyWithDB().
void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) {
- scoped_ptr<crypto::RSAPrivateKey> rsa_key(
- crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(),
- state->modulus_length_bits_));
- if (!rsa_key) {
+ if (!state->slot_) {
+ LOG(ERROR) << "No slot.";
+ state->OnError(FROM_HERE, kErrorInternal);
+ return;
+ }
+
+ crypto::ScopedSECKEYPublicKey public_key;
+ crypto::ScopedSECKEYPrivateKey private_key;
+ if (!crypto::GenerateRSAKeyPairNSS(
+ state->slot_.get(), state->modulus_length_bits_, true /* permanent */,
+ &public_key, &private_key)) {
LOG(ERROR) << "Couldn't create key.";
state->OnError(FROM_HERE, kErrorInternal);
return;
}
- std::vector<uint8> public_key_spki_der;
- if (!rsa_key->ExportPublicKey(&public_key_spki_der)) {
- // TODO(pneubeck): Remove rsa_key from storage.
+ crypto::ScopedSECItem public_key_der(
+ SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
+ if (!public_key_der) {
+ // TODO(pneubeck): Remove private_key and public_key from storage.
LOG(ERROR) << "Couldn't export public key.";
state->OnError(FROM_HERE, kErrorInternal);
return;
}
state->CallBack(
FROM_HERE,
- std::string(public_key_spki_der.begin(), public_key_spki_der.end()),
+ std::string(reinterpret_cast<const char*>(public_key_der->data),
+ public_key_der->len),
std::string() /* no error */);
}
@@ -442,13 +452,13 @@ void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
public_key_uint8, public_key_uint8 + state->public_key_.size());
// TODO(pneubeck): This searches all slots. Change to look only at |slot_|.
- scoped_ptr<crypto::RSAPrivateKey> rsa_key(
- crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector));
+ crypto::ScopedSECKEYPrivateKey rsa_key(
+ crypto::FindNSSKeyFromPublicKeyInfo(public_key_vector));
// Fail if the key was not found. If a specific slot was requested, also fail
// if the key was found in the wrong slot.
- if (!rsa_key ||
- (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) {
+ if (!rsa_key || SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey ||
+ (state->slot_ && rsa_key->pkcs11Slot != state->slot_)) {
state->OnError(FROM_HERE, kErrorKeyNotFound);
return;
}
@@ -464,7 +474,7 @@ void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
state->data_.size()};
// Compute signature of hash.
- int signature_len = PK11_SignatureLen(rsa_key->key());
+ int signature_len = PK11_SignatureLen(rsa_key.get());
if (signature_len <= 0) {
state->OnError(FROM_HERE, kErrorInternal);
return;
@@ -473,7 +483,7 @@ void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
std::vector<unsigned char> signature(signature_len);
SECItem signature_output = {
siBuffer, vector_as_array(&signature), signature.size()};
- if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess)
+ if (PK11_Sign(rsa_key.get(), &signature_output, &input) == SECSuccess)
signature_str.assign(signature.begin(), signature.end());
} else {
SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
@@ -499,7 +509,7 @@ void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
if (SEC_SignData(
&sign_result,
reinterpret_cast<const unsigned char*>(state->data_.data()),
- state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) {
+ state->data_.size(), rsa_key.get(), sign_alg_tag) == SECSuccess) {
signature_str.assign(sign_result.data,
sign_result.data + sign_result.len);
}
diff --git a/components/ownership.gypi b/components/ownership.gypi
index 0b95fe2..4784259 100644
--- a/components/ownership.gypi
+++ b/components/ownership.gypi
@@ -35,6 +35,11 @@
'<(DEPTH)/components/components.gyp:policy',
],
}],
+ ['use_nss_certs==1', {
+ 'dependencies': [
+ '../build/linux/system.gyp:ssl',
+ ],
+ }],
],
}],
}
diff --git a/components/ownership/BUILD.gn b/components/ownership/BUILD.gn
index 1bca927..cdaf227 100644
--- a/components/ownership/BUILD.gn
+++ b/components/ownership/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/crypto.gni")
import("//build/config/features.gni")
component("ownership") {
@@ -29,6 +30,10 @@ component("ownership") {
if (enable_configuration_policy) {
deps += [ "//components/policy" ]
}
+
+ if (use_nss_certs) {
+ deps += [ "//crypto:platform" ]
+ }
}
source_set("unit_tests") {
diff --git a/components/ownership/owner_key_util_impl.cc b/components/ownership/owner_key_util_impl.cc
index bc7208e..5a400d5 100644
--- a/components/ownership/owner_key_util_impl.cc
+++ b/components/ownership/owner_key_util_impl.cc
@@ -8,7 +8,12 @@
#include "base/files/file_util.h"
#include "base/logging.h"
+
+#if defined(USE_NSS_CERTS)
+#include <keythi.h>
+#include "crypto/nss_key_util.h"
#include "crypto/rsa_private_key.h"
+#endif
namespace ownership {
@@ -54,7 +59,21 @@ bool OwnerKeyUtilImpl::ImportPublicKey(std::vector<uint8>* output) {
crypto::RSAPrivateKey* OwnerKeyUtilImpl::FindPrivateKeyInSlot(
const std::vector<uint8>& key,
PK11SlotInfo* slot) {
- return crypto::RSAPrivateKey::FindFromPublicKeyInfoInSlot(key, slot);
+ if (!slot)
+ return nullptr;
+
+ crypto::ScopedSECKEYPrivateKey private_key(
+ crypto::FindNSSKeyFromPublicKeyInfoInSlot(key, slot));
+ if (!private_key || SECKEY_GetPrivateKeyType(private_key.get()) != rsaKey)
+ return nullptr;
+#if defined(USE_OPENSSL)
+ // TODO(davidben): This assumes that crypto::RSAPrivateKey also uses NSS.
+ // https://crbug.com/478777
+ NOTIMPLEMENTED();
+ return nullptr;
+#else
+ return crypto::RSAPrivateKey::CreateFromKey(private_key.get());
+#endif
}
#endif // defined(USE_NSS_CERTS)
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn
index c1eabe6..f84c4d4 100644
--- a/crypto/BUILD.gn
+++ b/crypto/BUILD.gn
@@ -50,6 +50,8 @@ component("crypto") {
"mock_apple_keychain.h",
"mock_apple_keychain_ios.cc",
"mock_apple_keychain_mac.cc",
+ "nss_key_util.cc",
+ "nss_key_util.h",
"nss_util.cc",
"nss_util.h",
"nss_util_internal.h",
@@ -171,10 +173,12 @@ component("crypto") {
]
}
- # Remove nss_util when NSS is used for neither the internal crypto library
- # nor the platform certificate library.
+ # Some files are built when NSS is used at all, either for the internal crypto
+ # library or the platform certificate library.
if (use_openssl && !use_nss_certs) {
sources -= [
+ "nss_key_util.cc",
+ "nss_key_util.h",
"nss_util.cc",
"nss_util.h",
"nss_util_internal.h",
@@ -226,12 +230,12 @@ test("crypto_unittests") {
"ghash_unittest.cc",
"hkdf_unittest.cc",
"hmac_unittest.cc",
+ "nss_key_util_unittest.cc",
"nss_util_unittest.cc",
"openssl_bio_string_unittest.cc",
"p224_spake_unittest.cc",
"p224_unittest.cc",
"random_unittest.cc",
- "rsa_private_key_nss_unittest.cc",
"rsa_private_key_unittest.cc",
"secure_hash_unittest.cc",
"sha2_unittest.cc",
@@ -240,15 +244,16 @@ test("crypto_unittests") {
"symmetric_key_unittest.cc",
]
- # Remove nss_util when NSS is used for neither the internal crypto library
- # nor the platform certificate library.
+ # Some files are built when NSS is used at all, either for the internal crypto
+ # library or the platform certificate library.
if (use_openssl && !use_nss_certs) {
- sources -= [ "nss_util_unittest.cc" ]
+ sources -= [
+ "nss_key_util_unittest.cc",
+ "nss_util_unittest.cc",
+ ]
}
- if (use_openssl) {
- sources -= [ "rsa_private_key_nss_unittest.cc" ]
- } else {
+ if (!use_openssl) {
sources -= [ "openssl_bio_string_unittest.cc" ]
}
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index 00b59b5..e6bff0b 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -143,9 +143,11 @@
],
},],
[ 'use_openssl==1 and use_nss_certs==0', {
- # NSS is used for neither the internal crypto library nor the
- # platform certificate library.
+ # Some files are built when NSS is used at all, either for the
+ # internal crypto library or the platform certificate library.
'sources!': [
+ 'nss_key_util.cc',
+ 'nss_key_util.h',
'nss_util.cc',
'nss_util.h',
'nss_util_internal.h',
@@ -168,13 +170,13 @@
'ghash_unittest.cc',
'hkdf_unittest.cc',
'hmac_unittest.cc',
+ 'nss_key_util_unittest.cc',
'nss_util_unittest.cc',
'openssl_bio_string_unittest.cc',
'p224_unittest.cc',
'p224_spake_unittest.cc',
'random_unittest.cc',
'rsa_private_key_unittest.cc',
- 'rsa_private_key_nss_unittest.cc',
'secure_hash_unittest.cc',
'sha2_unittest.cc',
'signature_creator_unittest.cc',
@@ -205,9 +207,10 @@
],
}],
[ 'use_openssl == 1 and use_nss_certs == 0', {
- # nss_util is built if NSS is used for either the internal crypto
- # library or the platform certificate library.
+ # Some files are built when NSS is used at all, either for the
+ # internal crypto library or the platform certificate library.
'sources!': [
+ 'nss_key_util_unittest.cc',
'nss_util_unittest.cc',
],
}],
@@ -224,9 +227,6 @@
'dependencies': [
'../third_party/boringssl/boringssl.gyp:boringssl',
],
- 'sources!': [
- 'rsa_private_key_nss_unittest.cc',
- ],
}, {
'sources!': [
'openssl_bio_string_unittest.cc',
diff --git a/crypto/crypto.gypi b/crypto/crypto.gypi
index 4456b10..73b3332 100644
--- a/crypto/crypto.gypi
+++ b/crypto/crypto.gypi
@@ -67,6 +67,8 @@
'p224_spake.cc',
'p224_spake.h',
'nss_crypto_module_delegate.h',
+ 'nss_key_util.cc',
+ 'nss_key_util.h',
'nss_util.cc',
'nss_util.h',
'nss_util_internal.h',
diff --git a/crypto/nss_key_util.cc b/crypto/nss_key_util.cc
new file mode 100644
index 0000000..77435fb
--- /dev/null
+++ b/crypto/nss_key_util.cc
@@ -0,0 +1,163 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/nss_key_util.h"
+
+#include <cryptohi.h>
+#include <keyhi.h>
+#include <pk11pub.h>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "crypto/nss_util.h"
+
+#if defined(USE_NSS_CERTS)
+#include <secmod.h>
+#include "crypto/nss_util_internal.h"
+#endif
+
+namespace crypto {
+
+namespace {
+
+#if defined(USE_NSS_CERTS)
+
+struct PublicKeyInfoDeleter {
+ inline void operator()(CERTSubjectPublicKeyInfo* spki) {
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ }
+};
+
+typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
+ ScopedPublicKeyInfo;
+
+// Decodes |input| as a SubjectPublicKeyInfo and returns a SECItem containing
+// the CKA_ID of that public key or nullptr on error.
+ScopedSECItem MakeIDFromSPKI(const std::vector<uint8_t>& input) {
+ // First, decode and save the public key.
+ SECItem key_der;
+ key_der.type = siBuffer;
+ key_der.data = const_cast<unsigned char*>(vector_as_array(&input));
+ key_der.len = input.size();
+
+ ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
+ if (!spki)
+ return nullptr;
+
+ ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get()));
+ if (!result)
+ return nullptr;
+
+ // See pk11_MakeIDFromPublicKey from NSS. For now, only RSA keys are
+ // supported.
+ if (SECKEY_GetPublicKeyType(result.get()) != rsaKey)
+ return nullptr;
+
+ return ScopedSECItem(PK11_MakeIDFromPubKey(&result->u.rsa.modulus));
+}
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace
+
+bool GenerateRSAKeyPairNSS(PK11SlotInfo* slot,
+ uint16_t num_bits,
+ bool permanent,
+ ScopedSECKEYPublicKey* public_key,
+ ScopedSECKEYPrivateKey* private_key) {
+ DCHECK(slot);
+
+ PK11RSAGenParams param;
+ param.keySizeInBits = num_bits;
+ param.pe = 65537L;
+ SECKEYPublicKey* public_key_raw = nullptr;
+ private_key->reset(PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
+ &param, &public_key_raw, permanent,
+ permanent /* sensitive */, nullptr));
+ if (!*private_key)
+ return false;
+
+ public_key->reset(public_key_raw);
+ return true;
+}
+
+ScopedSECKEYPrivateKey ImportNSSKeyFromPrivateKeyInfo(
+ PK11SlotInfo* slot,
+ const std::vector<uint8_t>& input,
+ bool permanent) {
+ DCHECK(slot);
+
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ DCHECK(arena);
+
+ // Excess data is illegal, but NSS silently accepts it, so first ensure that
+ // |input| consists of a single ASN.1 element.
+ SECItem input_item;
+ input_item.data = const_cast<unsigned char*>(vector_as_array(&input));
+ input_item.len = input.size();
+ SECItem der_private_key_info;
+ SECStatus rv =
+ SEC_QuickDERDecodeItem(arena.get(), &der_private_key_info,
+ SEC_ASN1_GET(SEC_AnyTemplate), &input_item);
+ if (rv != SECSuccess)
+ return nullptr;
+
+ // Allow the private key to be used for key unwrapping, data decryption,
+ // and signature generation.
+ const unsigned int key_usage =
+ KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
+ SECKEYPrivateKey* key_raw = nullptr;
+ rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+ slot, &der_private_key_info, nullptr, nullptr, permanent,
+ permanent /* sensitive */, key_usage, &key_raw, nullptr);
+ if (rv != SECSuccess)
+ return nullptr;
+ return ScopedSECKEYPrivateKey(key_raw);
+}
+
+#if defined(USE_NSS_CERTS)
+
+ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfo(
+ const std::vector<uint8_t>& input) {
+ EnsureNSSInit();
+
+ ScopedSECItem cka_id(MakeIDFromSPKI(input));
+ if (!cka_id)
+ return nullptr;
+
+ // Search all slots in all modules for the key with the given ID.
+ AutoSECMODListReadLock auto_lock;
+ const SECMODModuleList* head = SECMOD_GetDefaultModuleList();
+ for (const SECMODModuleList* item = head; item != nullptr;
+ item = item->next) {
+ int slot_count = item->module->loaded ? item->module->slotCount : 0;
+ for (int i = 0; i < slot_count; i++) {
+ // Look for the key in slot |i|.
+ ScopedSECKEYPrivateKey key(
+ PK11_FindKeyByKeyID(item->module->slots[i], cka_id.get(), nullptr));
+ if (key)
+ return key.Pass();
+ }
+ }
+
+ // The key wasn't found in any module.
+ return nullptr;
+}
+
+ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfoInSlot(
+ const std::vector<uint8_t>& input,
+ PK11SlotInfo* slot) {
+ DCHECK(slot);
+
+ ScopedSECItem cka_id(MakeIDFromSPKI(input));
+ if (!cka_id)
+ return nullptr;
+
+ return ScopedSECKEYPrivateKey(
+ PK11_FindKeyByKeyID(slot, cka_id.get(), nullptr));
+}
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
diff --git a/crypto/nss_key_util.h b/crypto/nss_key_util.h
new file mode 100644
index 0000000..12b948d
--- /dev/null
+++ b/crypto/nss_key_util.h
@@ -0,0 +1,58 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CRYPTO_NSS_KEY_UTIL_H_
+#define CRYPTO_NSS_KEY_UTIL_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "build/build_config.h"
+#include "crypto/crypto_export.h"
+#include "crypto/scoped_nss_types.h"
+
+typedef struct PK11SlotInfoStr PK11SlotInfo;
+
+namespace crypto {
+
+// Generates a new RSA keypair of size |num_bits| in |slot|. Returns true on
+// success and false on failure. If |permanent| is true, the resulting key is
+// permanent and is not exportable in plaintext form.
+CRYPTO_EXPORT bool GenerateRSAKeyPairNSS(
+ PK11SlotInfo* slot,
+ uint16_t num_bits,
+ bool permanent,
+ ScopedSECKEYPublicKey* out_public_key,
+ ScopedSECKEYPrivateKey* out_private_key);
+
+// Imports a private key from |input| into |slot|. |input| is interpreted as a
+// DER-encoded PrivateKeyInfo block from PKCS #8. Returns nullptr on error. If
+// |permanent| is true, the resulting key is permanent and is not exportable in
+// plaintext form.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+ImportNSSKeyFromPrivateKeyInfo(PK11SlotInfo* slot,
+ const std::vector<uint8_t>& input,
+ bool permanent);
+
+#if defined(USE_NSS_CERTS)
+
+// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and searches for
+// the private key half in the key database. Returns the private key on success
+// or nullptr on error.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+FindNSSKeyFromPublicKeyInfo(const std::vector<uint8_t>& input);
+
+// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and searches for
+// the private key half in the slot specified by |slot|. Returns the private key
+// on success or nullptr on error.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+FindNSSKeyFromPublicKeyInfoInSlot(const std::vector<uint8_t>& input,
+ PK11SlotInfo* slot);
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
+
+#endif // CRYPTO_NSS_KEY_UTIL_H_
diff --git a/crypto/nss_key_util_unittest.cc b/crypto/nss_key_util_unittest.cc
new file mode 100644
index 0000000..f8de8e2
--- /dev/null
+++ b/crypto/nss_key_util_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/nss_key_util.h"
+
+#include <keyhi.h>
+#include <pk11pub.h>
+
+#include <vector>
+
+#include "crypto/nss_util.h"
+#include "crypto/scoped_nss_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace crypto {
+
+class NSSKeyUtilTest : public testing::Test {
+ public:
+ void SetUp() override {
+ EnsureNSSInit();
+
+ internal_slot_.reset(PK11_GetInternalSlot());
+ ASSERT_TRUE(internal_slot_);
+ }
+
+ PK11SlotInfo* internal_slot() { return internal_slot_.get(); }
+
+ private:
+ ScopedPK11Slot internal_slot_;
+};
+
+TEST_F(NSSKeyUtilTest, GenerateRSAKeyPairNSS) {
+ const int kKeySizeBits = 1024;
+
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), kKeySizeBits,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ EXPECT_EQ(rsaKey, SECKEY_GetPublicKeyType(public_key.get()));
+ EXPECT_EQ(rsaKey, SECKEY_GetPrivateKeyType(private_key.get()));
+ EXPECT_EQ((kKeySizeBits + 7) / 8,
+ PK11_GetPrivateModulusLen(private_key.get()));
+}
+
+#if defined(USE_NSS_CERTS)
+TEST_F(NSSKeyUtilTest, FindNSSKeyFromPublicKeyInfo) {
+ // Create an NSS keypair, which will put the keys in the user's NSSDB.
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), 256,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ ScopedSECItem item(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
+ ASSERT_TRUE(item);
+ std::vector<uint8_t> public_key_der(item->data, item->data + item->len);
+
+ ScopedSECKEYPrivateKey private_key2 =
+ FindNSSKeyFromPublicKeyInfo(public_key_der);
+ ASSERT_TRUE(private_key2);
+ EXPECT_EQ(private_key->pkcs11ID, private_key2->pkcs11ID);
+}
+
+TEST_F(NSSKeyUtilTest, FailedFindNSSKeyFromPublicKeyInfo) {
+ // Create an NSS keypair, which will put the keys in the user's NSSDB.
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), 256,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ ScopedSECItem item(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
+ ASSERT_TRUE(item);
+ std::vector<uint8_t> public_key_der(item->data, item->data + item->len);
+
+ // Remove the keys from the DB, and make sure we can't find them again.
+ PK11_DestroyTokenObject(private_key->pkcs11Slot, private_key->pkcs11ID);
+ PK11_DestroyTokenObject(public_key->pkcs11Slot, public_key->pkcs11ID);
+
+ EXPECT_FALSE(FindNSSKeyFromPublicKeyInfo(public_key_der));
+}
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
diff --git a/crypto/rsa_private_key.h b/crypto/rsa_private_key.h
index 9ab9c57..637be38 100644
--- a/crypto/rsa_private_key.h
+++ b/crypto/rsa_private_key.h
@@ -191,44 +191,6 @@ class CRYPTO_EXPORT RSAPrivateKey {
static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
#endif
- // TODO(davidben): These functions are used when NSS is the platform key
- // store, but they also assume that the internal crypto library is NSS. Split
- // out the convenience NSS platform key methods from the logic which expects
- // an RSAPrivateKey. See https://crbug.com/478777.
-#if defined(USE_NSS_CERTS) && !defined(USE_OPENSSL)
- // Create a new random instance in |slot|. Can return NULL if initialization
- // fails. The created key is permanent and is not exportable in plaintext
- // form.
- static RSAPrivateKey* CreateSensitive(PK11SlotInfo* slot, uint16 num_bits);
-
- // Create a new instance in |slot| by importing an existing private key. The
- // format is an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can
- // return NULL if initialization fails.
- // The created key is permanent and is not exportable in plaintext form.
- static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input);
-
- // Import an existing public key, and then search for the private
- // half in the key database. The format of the public key blob is is
- // an X509 SubjectPublicKeyInfo block. This can return NULL if
- // initialization fails or the private key cannot be found. The
- // caller takes ownership of the returned object, but nothing new is
- // created in the key database.
- static RSAPrivateKey* FindFromPublicKeyInfo(
- const std::vector<uint8>& input);
-
- // Import an existing public key, and then search for the private
- // half in the slot specified by |slot|. The format of the public
- // key blob is is an X509 SubjectPublicKeyInfo block. This can return
- // NULL if initialization fails or the private key cannot be found.
- // The caller takes ownership of the returned object, but nothing new
- // is created in the slot.
- static RSAPrivateKey* FindFromPublicKeyInfoInSlot(
- const std::vector<uint8>& input,
- PK11SlotInfo* slot);
-#endif // USE_NSS_CERTS && !USE_OPENSSL
-
#if defined(USE_OPENSSL)
EVP_PKEY* key() { return key_; }
#else
@@ -251,38 +213,9 @@ class CRYPTO_EXPORT RSAPrivateKey {
FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey);
#endif
- // Constructor is private. Use one of the Create*() or Find*()
- // methods above instead.
+ // Constructor is private. Use one of the Create*() methods above instead.
RSAPrivateKey();
-#if !defined(USE_OPENSSL)
- // Shared helper for Create() and CreateSensitive().
- // TODO(cmasone): consider replacing |permanent| and |sensitive| with a
- // flags arg created by ORing together some enumerated values.
- // Note: |permanent| is only supported when USE_NSS_CERTS is defined.
- static RSAPrivateKey* CreateWithParams(PK11SlotInfo* slot,
- uint16 num_bits,
- bool permanent,
- bool sensitive);
-
- // Shared helper for CreateFromPrivateKeyInfo() and
- // CreateSensitiveFromPrivateKeyInfo().
- // Note: |permanent| is only supported when USE_NSS_CERTS is defined.
- static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input,
- bool permanent,
- bool sensitive);
-#endif
-
-#if defined(USE_NSS_CERTS)
- // Import an existing public key. The format of the public key blob
- // is an X509 SubjectPublicKeyInfo block. This can return NULL if
- // initialization fails. The caller takes ownership of the returned
- // object. Note that this method doesn't initialize the |key_| member.
- static RSAPrivateKey* InitPublicPart(const std::vector<uint8>& input);
-#endif
-
#if defined(USE_OPENSSL)
EVP_PKEY* key_;
#else
diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc
index c9e6a87..88e55fa 100644
--- a/crypto/rsa_private_key_nss.cc
+++ b/crypto/rsa_private_key_nss.cc
@@ -7,7 +7,6 @@
#include <cryptohi.h>
#include <keyhi.h>
#include <pk11pub.h>
-#include <secmod.h>
#include <list>
@@ -15,8 +14,8 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
-#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
// TODO(rafaelw): Consider using NSS's ASN.1 encoder.
@@ -38,37 +37,6 @@ static bool ReadAttribute(SECKEYPrivateKey* key,
return true;
}
-#if defined(USE_NSS_CERTS)
-struct PublicKeyInfoDeleter {
- inline void operator()(CERTSubjectPublicKeyInfo* spki) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
-};
-
-typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
- ScopedPublicKeyInfo;
-
-// The function decodes RSA public key from the |input|.
-crypto::ScopedSECKEYPublicKey GetRSAPublicKey(const std::vector<uint8>& input) {
- // First, decode and save the public key.
- SECItem key_der;
- key_der.type = siBuffer;
- key_der.data = const_cast<unsigned char*>(&input[0]);
- key_der.len = input.size();
-
- ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
- if (!spki)
- return crypto::ScopedSECKEYPublicKey();
-
- crypto::ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get()));
-
- // Make sure the key is an RSA key.. If not, that's an error.
- if (!result || result->keyType != rsaKey)
- return crypto::ScopedSECKEYPublicKey();
- return result.Pass();
-}
-#endif // defined(USE_NSS_CERTS)
-
} // namespace
namespace crypto {
@@ -85,10 +53,22 @@ RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
EnsureNSSInit();
ScopedPK11Slot slot(PK11_GetInternalSlot());
- return CreateWithParams(slot.get(),
- num_bits,
- false /* not permanent */,
- false /* not sensitive */);
+ if (!slot) {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ if (!GenerateRSAKeyPairNSS(slot.get(), num_bits, false /* not permanent */,
+ &public_key, &private_key)) {
+ return nullptr;
+ }
+
+ RSAPrivateKey* rsa_key = new RSAPrivateKey;
+ rsa_key->public_key_ = public_key.release();
+ rsa_key->key_ = private_key.release();
+ return rsa_key;
}
// static
@@ -97,11 +77,15 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
EnsureNSSInit();
ScopedPK11Slot slot(PK11_GetInternalSlot());
- return CreateFromPrivateKeyInfoWithParams(
- slot.get(),
- input,
- false /* not permanent */,
- false /* not sensitive */);
+ if (!slot) {
+ NOTREACHED();
+ return nullptr;
+ }
+ ScopedSECKEYPrivateKey key(ImportNSSKeyFromPrivateKeyInfo(
+ slot.get(), input, false /* not permanent */));
+ if (!key || SECKEY_GetPrivateKeyType(key.get()) != rsaKey)
+ return nullptr;
+ return RSAPrivateKey::CreateFromKey(key.get());
}
// static
@@ -120,83 +104,6 @@ RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
return copy;
}
-#if defined(USE_NSS_CERTS)
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(PK11SlotInfo* slot,
- uint16 num_bits) {
- return CreateWithParams(slot,
- num_bits,
- true /* permanent */,
- true /* sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input) {
- return CreateFromPrivateKeyInfoWithParams(slot,
- input,
- true /* permanent */,
- true /* sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
- if (!result)
- return NULL;
-
- ScopedSECItem ck_id(
- PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
- if (!ck_id.get()) {
- NOTREACHED();
- return NULL;
- }
-
- // Search all slots in all modules for the key with the given ID.
- AutoSECMODListReadLock auto_lock;
- SECMODModuleList* head = SECMOD_GetDefaultModuleList();
- for (SECMODModuleList* item = head; item != NULL; item = item->next) {
- int slot_count = item->module->loaded ? item->module->slotCount : 0;
- for (int i = 0; i < slot_count; i++) {
- // Finally...Look for the key!
- result->key_ = PK11_FindKeyByKeyID(item->module->slots[i],
- ck_id.get(), NULL);
- if (result->key_)
- return result.release();
- }
- }
-
- // We didn't find the key.
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfoInSlot(
- const std::vector<uint8>& input,
- PK11SlotInfo* slot) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
- if (!result)
- return NULL;
-
- ScopedSECItem ck_id(
- PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
- if (!ck_id.get()) {
- NOTREACHED();
- return NULL;
- }
-
- result->key_ = PK11_FindKeyByKeyID(slot, ck_id.get(), NULL);
- if (!result->key_)
- return NULL;
- return result.release();
-}
-#endif
-
RSAPrivateKey* RSAPrivateKey::Copy() const {
RSAPrivateKey* copy = new RSAPrivateKey();
copy->key_ = SECKEY_CopyPrivateKey(key_);
@@ -241,92 +148,4 @@ RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) {
EnsureNSSInit();
}
-// static
-RSAPrivateKey* RSAPrivateKey::CreateWithParams(PK11SlotInfo* slot,
- uint16 num_bits,
- bool permanent,
- bool sensitive) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- PK11RSAGenParams param;
- param.keySizeInBits = num_bits;
- param.pe = 65537L;
- result->key_ = PK11_GenerateKeyPair(slot,
- CKM_RSA_PKCS_KEY_PAIR_GEN,
- &param,
- &result->public_key_,
- permanent,
- sensitive,
- NULL);
- if (!result->key_)
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input,
- bool permanent,
- bool sensitive) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena) {
- NOTREACHED();
- return NULL;
- }
-
- // Excess data is illegal, but NSS silently accepts it, so first ensure that
- // |input| consists of a single ASN.1 element.
- SECItem input_item;
- input_item.data = const_cast<unsigned char*>(&input.front());
- input_item.len = input.size();
- SECItem der_private_key_info;
- SECStatus rv = SEC_QuickDERDecodeItem(arena.get(), &der_private_key_info,
- SEC_ASN1_GET(SEC_AnyTemplate),
- &input_item);
- if (rv != SECSuccess)
- return NULL;
-
- // Allow the private key to be used for key unwrapping, data decryption,
- // and signature generation.
- const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
- KU_DIGITAL_SIGNATURE;
- rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
- slot, &der_private_key_info, NULL, NULL, permanent, sensitive,
- key_usage, &result->key_, NULL);
- if (rv != SECSuccess)
- return NULL;
-
- result->public_key_ = SECKEY_ConvertToPublicKey(result->key_);
- if (!result->public_key_)
- return NULL;
-
- return result.release();
-}
-
-#if defined(USE_NSS_CERTS)
-// static
-RSAPrivateKey* RSAPrivateKey::InitPublicPart(const std::vector<uint8>& input) {
- EnsureNSSInit();
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey());
- result->public_key_ = GetRSAPublicKey(input).release();
- if (!result->public_key_) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-#endif // defined(USE_NSS_CERTS)
-
} // namespace crypto
diff --git a/crypto/rsa_private_key_nss_unittest.cc b/crypto/rsa_private_key_nss_unittest.cc
deleted file mode 100644
index dad6688..0000000
--- a/crypto/rsa_private_key_nss_unittest.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "crypto/rsa_private_key.h"
-
-#include <keyhi.h>
-#include <pk11pub.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "crypto/scoped_test_nss_db.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace crypto {
-
-// TODO(davidben): These tests assume NSS is used for both the internal crypto
-// library and the platform key store. See https://crbug.com/478777.
-#if defined(USE_NSS_CERTS)
-
-class RSAPrivateKeyNSSTest : public testing::Test {
- public:
- RSAPrivateKeyNSSTest() {}
- ~RSAPrivateKeyNSSTest() override {}
-
- private:
- ScopedTestNSSDB test_nssdb_;
-
- DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest);
-};
-
-TEST_F(RSAPrivateKeyNSSTest, FindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- scoped_ptr<crypto::RSAPrivateKey> key_pair_2(
- crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-
- EXPECT_EQ(key_pair->key_->pkcs11ID, key_pair_2->key_->pkcs11ID);
-}
-
-TEST_F(RSAPrivateKeyNSSTest, FailedFindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- // Remove the keys from the DB, and make sure we can't find them again.
- if (key_pair->key_) {
- PK11_DestroyTokenObject(key_pair->key_->pkcs11Slot,
- key_pair->key_->pkcs11ID);
- }
- if (key_pair->public_key_) {
- PK11_DestroyTokenObject(key_pair->public_key_->pkcs11Slot,
- key_pair->public_key_->pkcs11ID);
- }
-
- EXPECT_EQ(NULL, crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-}
-
-#endif // USE_NSS_CERTS
-
-} // namespace crypto
diff --git a/net/net.gyp b/net/net.gyp
index 9c35d10..3db83b5 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -506,6 +506,7 @@
# TODO(mmenke): This depends on icu, figure out a way to build tests
# without icu.
'../base/base.gyp:test_support_base',
+ '../crypto/crypto.gyp:crypto',
'../testing/gtest.gyp:gtest',
'../testing/gmock.gyp:gmock',
],
diff --git a/net/test/cert_test_util.h b/net/test/cert_test_util.h
index 8ad5664..219ccd8 100644
--- a/net/test/cert_test_util.h
+++ b/net/test/cert_test_util.h
@@ -12,8 +12,6 @@
#include "net/cert/x509_certificate.h"
#if defined(USE_NSS_CERTS)
-#include "base/memory/scoped_ptr.h"
-
// From <pk11pub.h>
typedef struct PK11SlotInfoStr PK11SlotInfo;
#endif
@@ -31,13 +29,12 @@ namespace net {
class EVRootCAMetadata;
#if defined(USE_NSS_CERTS)
-// Imports a private key from file |key_filename| in |dir|. The file must
-// contain a PKCS#8 PrivateKeyInfo in DER encoding. The key is imported to
-// |slot|.
-scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
- const base::FilePath& dir,
- const std::string& key_filename,
- PK11SlotInfo* slot);
+// Imports a private key from file |key_filename| in |dir| into |slot|. The file
+// must contain a PKCS#8 PrivateKeyInfo in DER encoding. Returns true on success
+// and false on failure.
+bool ImportSensitiveKeyFromFile(const base::FilePath& dir,
+ const std::string& key_filename,
+ PK11SlotInfo* slot);
bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,
PK11SlotInfo* slot);
diff --git a/net/test/cert_test_util_nss.cc b/net/test/cert_test_util_nss.cc
index 74884c7..4427ceb 100644
--- a/net/test/cert_test_util_nss.cc
+++ b/net/test/cert_test_util_nss.cc
@@ -9,30 +9,22 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
-#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_nss_types.h"
#include "net/cert/cert_type.h"
namespace net {
-scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
- const base::FilePath& dir,
- const std::string& key_filename,
- PK11SlotInfo* slot) {
-#if defined(USE_OPENSSL)
- // TODO(davidben): Port RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo away
- // from RSAPrivateKey so it doesn't make assumptions about the internal crypto
- // library. Instead, return a ScopedSECKEYPrivateKey or have this function
- // just return bool. https://crbug.com/478777
- NOTIMPLEMENTED();
- return nullptr;
-#else
+bool ImportSensitiveKeyFromFile(const base::FilePath& dir,
+ const std::string& key_filename,
+ PK11SlotInfo* slot) {
base::FilePath key_path = dir.AppendASCII(key_filename);
std::string key_pkcs8;
bool success = base::ReadFileToString(key_path, &key_pkcs8);
if (!success) {
LOG(ERROR) << "Failed to read file " << key_path.value();
- return scoped_ptr<crypto::RSAPrivateKey>();
+ return false;
}
const uint8* key_pkcs8_begin =
@@ -40,13 +32,12 @@ scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
std::vector<uint8> key_vector(key_pkcs8_begin,
key_pkcs8_begin + key_pkcs8.length());
- scoped_ptr<crypto::RSAPrivateKey> private_key(
- crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot,
- key_vector));
+ crypto::ScopedSECKEYPrivateKey private_key(
+ crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key_vector,
+ true /* permanent */));
LOG_IF(ERROR, !private_key) << "Could not create key from file "
<< key_path.value();
- return private_key.Pass();
-#endif
+ return private_key;
}
bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,