diff options
author | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-27 09:18:43 +0000 |
---|---|---|
committer | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-27 09:18:43 +0000 |
commit | 5123d9c4a4f9190436a9c15ee0733a5340aad08e (patch) | |
tree | 409d1f94e61b550ede597dfad3ea3b29238c5647 | |
parent | 277823276af8fb584020b981b30fbde5b4e7171d (diff) | |
download | chromium_src-5123d9c4a4f9190436a9c15ee0733a5340aad08e.zip chromium_src-5123d9c4a4f9190436a9c15ee0733a5340aad08e.tar.gz chromium_src-5123d9c4a4f9190436a9c15ee0733a5340aad08e.tar.bz2 |
Remove platform-specific implementations of RSAPrivateKey and SignatureCreator
Use NSS/OpenSSL on all platforms, rather than deferring to the underlying OS routines.
Because X509Certificate::CreateSelfSigned no longer relies on platform-native types for RSA keys or certificates, it has been moved to x509_util and simply returns a DER-encoded certificate as a string.
BUG=none
R=wtc
Review URL: https://chromiumcodereview.appspot.com/17265013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@208870 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 338 insertions, 1321 deletions
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc index 19ef480..31a274f 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc @@ -19,7 +19,7 @@ #include "content/public/test/test_browser_thread.h" #include "crypto/rsa_private_key.h" #include "net/cert/x509_certificate.h" -#include "net/cert/x509_util_nss.h" +#include "net/cert/x509_util.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -220,19 +220,12 @@ class AttestationPolicyObserverTest : public ::testing::Test { &kTestKeyData[arraysize(kTestKeyData)]))); if (!test_key.get()) return false; - net::X509Certificate::OSCertHandle handle = - net::x509_util::CreateSelfSignedCert(test_key->public_key(), - test_key->key(), - "CN=subject", - 12345, - valid_start, - valid_expiry); - - if (!handle) - return false; - bool result = net::X509Certificate::GetDEREncoded(handle, certificate); - net::X509Certificate::FreeOSCertHandle(handle); - return result; + return net::x509_util::CreateSelfSignedCert(test_key.get(), + "CN=subject", + 12345, + valid_start, + valid_expiry, + certificate); } base::MessageLoop message_loop_; diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp index 4ba571b..f6ac0f8 100644 --- a/crypto/crypto.gyp +++ b/crypto/crypto.gyp @@ -49,15 +49,6 @@ ], ], }, { # os_posix != 1 or OS == "mac" or OS == "ios" or OS == "android" - 'sources/': [ - ['exclude', '_nss\.cc$'], - ['include', 'ec_private_key_nss\.cc$'], - ['include', 'ec_signature_creator_nss\.cc$'], - ['include', 'encryptor_nss\.cc$'], - ['include', 'hmac_nss\.cc$'], - ['include', 'signature_verifier_nss\.cc$'], - ['include', 'symmetric_key_nss\.cc$'], - ], 'sources!': [ 'hmac_win.cc', 'openpgp_symmetric_encryption.cc', @@ -93,12 +84,6 @@ }, }, ], - [ 'OS == "ios"', { - 'sources!': [ - # This class is stubbed out on iOS. - 'rsa_private_key.cc', - ], - }], [ 'OS == "mac"', { 'link_settings': { 'libraries': [ @@ -228,11 +213,8 @@ 'random.cc', 'rsa_private_key.cc', 'rsa_private_key.h', - 'rsa_private_key_ios.cc', - 'rsa_private_key_mac.cc', 'rsa_private_key_nss.cc', 'rsa_private_key_openssl.cc', - 'rsa_private_key_win.cc', 'scoped_capi_types.h', 'scoped_nss_types.h', 'secure_hash.h', @@ -241,10 +223,8 @@ 'sha2.cc', 'sha2.h', 'signature_creator.h', - 'signature_creator_mac.cc', 'signature_creator_nss.cc', 'signature_creator_openssl.cc', - 'signature_creator_win.cc', 'signature_verifier.h', 'signature_verifier_nss.cc', 'signature_verifier_openssl.cc', @@ -316,15 +296,6 @@ '../third_party/nss/nss.gyp:nss', ], }], - ['OS == "ios"', { - 'sources!': [ - # These tests are excluded because they test classes that are not - # implemented on iOS. - 'rsa_private_key_unittest.cc', - 'signature_creator_unittest.cc', - 'signature_verifier_unittest.cc', - ], - }], [ 'OS == "mac"', { 'dependencies': [ '../third_party/nss/nss.gyp:nspr', diff --git a/crypto/rsa_private_key.h b/crypto/rsa_private_key.h index b8ce169..ad82148 100644 --- a/crypto/rsa_private_key.h +++ b/crypto/rsa_private_key.h @@ -7,32 +7,26 @@ #include "build/build_config.h" -#if defined(USE_OPENSSL) -// Forward declaration for openssl/*.h -typedef struct evp_pkey_st EVP_PKEY; -#elif defined(USE_NSS) -// Forward declaration. -typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; -typedef struct SECKEYPublicKeyStr SECKEYPublicKey; -#elif defined(OS_IOS) -#include <Security/Security.h> -#elif defined(OS_MACOSX) -#include <Security/cssm.h> -#endif - #include <list> #include <vector> #include "base/basictypes.h" #include "crypto/crypto_export.h" -#if defined(OS_WIN) -#include "crypto/scoped_capi_types.h" -#endif #if defined(USE_NSS) #include "base/gtest_prod_util.h" #endif +#if defined(USE_OPENSSL) +// Forward declaration for openssl/*.h +typedef struct evp_pkey_st EVP_PKEY; +#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) +// Forward declaration. +typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; +typedef struct SECKEYPublicKeyStr SECKEYPublicKey; +#endif + + namespace crypto { // Used internally by RSAPrivateKey for serializing and deserializing @@ -179,32 +173,27 @@ class CRYPTO_EXPORT RSAPrivateKey { // Create a new random instance. Can return NULL if initialization fails. static RSAPrivateKey* Create(uint16 num_bits); - // Create a new random instance. Can return NULL if initialization fails. - // The created key is permanent and is not exportable in plaintext form. - // - // NOTE: Currently only available if USE_NSS is defined. - static RSAPrivateKey* CreateSensitive(uint16 num_bits); - // Create a new instance 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. static RSAPrivateKey* CreateFromPrivateKeyInfo( const std::vector<uint8>& input); +#if defined(USE_NSS) + // Create a new random instance. Can return NULL if initialization fails. + // The created key is permanent and is not exportable in plaintext form. + static RSAPrivateKey* CreateSensitive(uint16 num_bits); + // Create a new instance 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. - // - // NOTE: Currently only available if USE_NSS is defined. static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo( const std::vector<uint8>& input); -#if defined(USE_NSS) // Create a new instance by referencing an existing private key // structure. Does not import the key. static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key); -#endif // 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 @@ -212,25 +201,15 @@ class CRYPTO_EXPORT RSAPrivateKey { // 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. - // - // NOTE: Currently only available if USE_NSS is defined. static RSAPrivateKey* FindFromPublicKeyInfo( const std::vector<uint8>& input); +#endif #if defined(USE_OPENSSL) EVP_PKEY* key() { return key_; } -#elif defined(USE_NSS) +#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) SECKEYPrivateKey* key() { return key_; } SECKEYPublicKey* public_key() { return public_key_; } -#elif defined(OS_WIN) - HCRYPTPROV provider() { return provider_; } - HCRYPTKEY key() { return key_; } -#elif defined(OS_IOS) - SecKeyRef key() { return key_; } - SecKeyRef public_key() { return public_key_; } -#elif defined(OS_MACOSX) - CSSM_KEY_PTR key() { return &key_; } - CSSM_KEY_PTR public_key() { return &public_key_; } #endif // Creates a copy of the object. @@ -255,31 +234,24 @@ class CRYPTO_EXPORT RSAPrivateKey { // 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 is defined. static RSAPrivateKey* CreateWithParams(uint16 num_bits, bool permanent, bool sensitive); // Shared helper for CreateFromPrivateKeyInfo() and // CreateSensitiveFromPrivateKeyInfo(). + // Note: |permanent| is only supported when USE_NSS is defined. static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams( - const std::vector<uint8>& input, bool permanent, bool sensitive); + const std::vector<uint8>& input, + bool permanent, + bool sensitive); #if defined(USE_OPENSSL) EVP_PKEY* key_; -#elif defined(USE_NSS) +#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) SECKEYPrivateKey* key_; SECKEYPublicKey* public_key_; -#elif defined(OS_WIN) - bool InitProvider(); - - ScopedHCRYPTPROV provider_; - ScopedHCRYPTKEY key_; -#elif defined(OS_IOS) - SecKeyRef key_; - SecKeyRef public_key_; -#elif defined(OS_MACOSX) - CSSM_KEY key_; - CSSM_KEY public_key_; #endif DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey); diff --git a/crypto/rsa_private_key_ios.cc b/crypto/rsa_private_key_ios.cc deleted file mode 100644 index d96b3e9..0000000 --- a/crypto/rsa_private_key_ios.cc +++ /dev/null @@ -1,67 +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 "base/logging.h" - -namespace crypto { - -// |RSAPrivateKey| is not used on iOS. This implementation was written so that -// it would compile. It may be possible to use the NSS implementation as a real -// implementation, but it hasn't yet been necessary. - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) {} - -RSAPrivateKey::~RSAPrivateKey() { - if (public_key_) - CFRelease(public_key_); - if (key_) - CFRelease(key_); -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) const { - NOTIMPLEMENTED(); - return false; -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) const { - NOTIMPLEMENTED(); - return false; -} - -} // namespace base diff --git a/crypto/rsa_private_key_mac.cc b/crypto/rsa_private_key_mac.cc deleted file mode 100644 index fbe1491e..0000000 --- a/crypto/rsa_private_key_mac.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2012 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 <list> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "crypto/cssm_init.h" - -namespace crypto { - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - CSSM_CC_HANDLE cc_handle; - CSSM_RETURN crtn; - crtn = CSSM_CSP_CreateKeyGenContext(GetSharedCSPHandle(), CSSM_ALGID_RSA, - num_bits, NULL, NULL, NULL, NULL, NULL, - &cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; - return NULL; - } - - CSSM_DATA label = { 9, - const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) }; - crtn = CSSM_GenerateKeyPair(cc_handle, - CSSM_KEYUSE_VERIFY, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, - result->public_key(), CSSM_KEYUSE_SIGN, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL, - result->key()); - CSSM_DeleteContext(cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; - return NULL; - } - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - if (input.empty()) - return NULL; - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - CSSM_KEY key; - memset(&key, 0, sizeof(key)); - key.KeyData.Data = const_cast<uint8*>(&input.front()); - key.KeyData.Length = input.size(); - key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; - key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA; - key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; - key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; - - CSSM_KEY_SIZE key_size; - CSSM_RETURN crtn; - crtn = CSSM_QueryKeySizeInBits( - GetSharedCSPHandle(), CSSM_INVALID_HANDLE, &key, &key_size); - if (crtn) { - NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; - return NULL; - } - key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; - - // Perform a NULL unwrap operation on the key so that result's key_ - // instance variable points to a key that can be released via CSSM_FreeKey(). - CSSM_ACCESS_CREDENTIALS creds; - memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); - CSSM_CC_HANDLE cc_handle; - crtn = CSSM_CSP_CreateSymmetricContext(GetSharedCSPHandle(), CSSM_ALGID_NONE, - CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn; - return NULL; - } - CSSM_DATA label_data, desc_data = { 0, NULL }; - label_data.Data = - const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped")); - label_data.Length = 9; - crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data, - NULL, result->key(), &desc_data); - if (crtn) { - NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn; - return NULL; - } - - // Extract a public key from the private key. - // Apple doesn't accept CSSM_KEYBLOB_RAW_FORMAT_X509 as a valid key - // format when attempting to generate certs, so use PKCS1 instead. - PrivateKeyInfoCodec codec(true); - std::vector<uint8> private_key_data; - private_key_data.assign(key.KeyData.Data, - key.KeyData.Data + key.KeyData.Length); - if (!codec.Import(private_key_data)) { - return NULL; - } - std::vector<uint8> public_key_data; - if (!codec.ExportPublicKey(&public_key_data)) { - return NULL; - } - - CSSM_KEY* public_key = result->public_key(); - size_t size = public_key_data.size(); - public_key->KeyData.Data = reinterpret_cast<uint8*>(CSSMMalloc(size)); - if (!public_key->KeyData.Data) { - NOTREACHED() << "CSSMMalloc failed"; - return NULL; - } - memcpy(public_key->KeyData.Data, &public_key_data.front(), size); - public_key->KeyData.Length = size; - public_key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; - public_key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - public_key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - public_key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA; - public_key->KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY; - public_key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - public_key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; - - crtn = CSSM_QueryKeySizeInBits( - GetSharedCSPHandle(), CSSM_INVALID_HANDLE, public_key, &key_size); - if (crtn) { - DLOG(ERROR) << "CSSM_QueryKeySizeInBits failed " << crtn; - return NULL; - } - public_key->KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() { - memset(&key_, 0, sizeof(key_)); - memset(&public_key_, 0, sizeof(public_key_)); - - EnsureCSSMInit(); -} - -RSAPrivateKey::~RSAPrivateKey() { - if (key_.KeyData.Data) { - CSSM_FreeKey(GetSharedCSPHandle(), NULL, &key_, CSSM_FALSE); - } - if (public_key_.KeyData.Data) { - CSSM_FreeKey(GetSharedCSPHandle(), NULL, &public_key_, CSSM_FALSE); - } -} - -RSAPrivateKey* RSAPrivateKey::Copy() const { - std::vector<uint8> key_bytes; - if (!ExportPrivateKey(&key_bytes)) - return NULL; - return CreateFromPrivateKeyInfo(key_bytes); -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) const { - if (!key_.KeyData.Data || !key_.KeyData.Length) { - return false; - } - output->clear(); - output->insert(output->end(), key_.KeyData.Data, - key_.KeyData.Data + key_.KeyData.Length); - return true; -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) const { - PrivateKeyInfoCodec private_key_info(true); - std::vector<uint8> private_key_data; - private_key_data.assign(key_.KeyData.Data, - key_.KeyData.Data + key_.KeyData.Length); - return (private_key_info.Import(private_key_data) && - private_key_info.ExportPublicKeyInfo(output)); -} - -} // namespace crypto diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc index 3574432..35697ab 100644 --- a/crypto/rsa_private_key_nss.cc +++ b/crypto/rsa_private_key_nss.cc @@ -19,8 +19,7 @@ #include "crypto/nss_util_internal.h" #include "crypto/scoped_nss_types.h" -// TODO(rafaelw): Consider refactoring common functions and definitions from -// rsa_private_key_win.cc or using NSS's ASN.1 encoder. +// TODO(rafaelw): Consider using NSS's ASN.1 encoder. namespace { static bool ReadAttribute(SECKEYPrivateKey* key, @@ -53,31 +52,32 @@ RSAPrivateKey::~RSAPrivateKey() { // static RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { return CreateWithParams(num_bits, - PR_FALSE /* not permanent */, - PR_FALSE /* not sensitive */); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - return CreateWithParams(num_bits, - PR_TRUE /* permanent */, - PR_TRUE /* sensitive */); + false /* not permanent */, + false /* not sensitive */); } // static RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( const std::vector<uint8>& input) { return CreateFromPrivateKeyInfoWithParams(input, - PR_FALSE /* not permanent */, - PR_FALSE /* not sensitive */); + false /* not permanent */, + false /* not sensitive */); +} + +#if defined(USE_NSS) +// static +RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { + return CreateWithParams(num_bits, + true /* permanent */, + true /* sensitive */); } // static RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( const std::vector<uint8>& input) { return CreateFromPrivateKeyInfoWithParams(input, - PR_TRUE /* permanent */, - PR_TRUE /* sensitive */); + true /* permanent */, + true /* sensitive */); } // static @@ -153,6 +153,7 @@ RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( // We didn't find the key. return NULL; } +#endif RSAPrivateKey* RSAPrivateKey::Copy() const { RSAPrivateKey* copy = new RSAPrivateKey(); @@ -202,6 +203,13 @@ RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) { RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, bool permanent, bool sensitive) { +#if !defined(USE_NSS) + if (permanent) { + NOTIMPLEMENTED(); + return NULL; + } +#endif + EnsureNSSInit(); scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); @@ -230,6 +238,13 @@ RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, // static RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( const std::vector<uint8>& input, bool permanent, bool sensitive) { +#if !defined(USE_NSS) + if (permanent) { + NOTIMPLEMENTED(); + return NULL; + } +#endif + // This method currently leaks some memory. // See http://crbug.com/34742. ANNOTATE_SCOPED_MEMORY_LEAK; diff --git a/crypto/rsa_private_key_openssl.cc b/crypto/rsa_private_key_openssl.cc index 64a627e..f191e39 100644 --- a/crypto/rsa_private_key_openssl.cc +++ b/crypto/rsa_private_key_openssl.cc @@ -67,12 +67,6 @@ RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { } // static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( const std::vector<uint8>& input) { if (input.empty()) @@ -101,20 +95,6 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( return result.release(); } -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - RSAPrivateKey::RSAPrivateKey() : key_(NULL) { } diff --git a/crypto/rsa_private_key_win.cc b/crypto/rsa_private_key_win.cc deleted file mode 100644 index 29ee663..0000000 --- a/crypto/rsa_private_key_win.cc +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) 2012 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 <list> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/string_util.h" - -#pragma comment(lib, "crypt32.lib") - -namespace crypto { - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - if (!result->InitProvider()) - return NULL; - - DWORD flags = CRYPT_EXPORTABLE; - - // The size is encoded as the upper 16 bits of the flags. :: sigh ::. - flags |= (num_bits << 16); - if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags, - result->key_.receive())) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - if (!result->InitProvider()) - return NULL; - - PrivateKeyInfoCodec pki(false); // Little-Endian - if (!pki.Import(input)) - return NULL; - - size_t blob_size = sizeof(PUBLICKEYSTRUC) + - sizeof(RSAPUBKEY) + - pki.modulus()->size() + - pki.prime1()->size() + - pki.prime2()->size() + - pki.exponent1()->size() + - pki.exponent2()->size() + - pki.coefficient()->size() + - pki.private_exponent()->size(); - scoped_ptr<BYTE[]> blob(new BYTE[blob_size]); - - uint8* dest = blob.get(); - PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest); - public_key_struc->bType = PRIVATEKEYBLOB; - public_key_struc->bVersion = 0x02; - public_key_struc->reserved = 0; - public_key_struc->aiKeyAlg = CALG_RSA_SIGN; - dest += sizeof(PUBLICKEYSTRUC); - - RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest); - rsa_pub_key->magic = 0x32415352; - rsa_pub_key->bitlen = pki.modulus()->size() * 8; - int public_exponent_int = 0; - for (size_t i = pki.public_exponent()->size(); i > 0; --i) { - public_exponent_int <<= 8; - public_exponent_int |= (*pki.public_exponent())[i - 1]; - } - rsa_pub_key->pubexp = public_exponent_int; - dest += sizeof(RSAPUBKEY); - - memcpy(dest, &pki.modulus()->front(), pki.modulus()->size()); - dest += pki.modulus()->size(); - memcpy(dest, &pki.prime1()->front(), pki.prime1()->size()); - dest += pki.prime1()->size(); - memcpy(dest, &pki.prime2()->front(), pki.prime2()->size()); - dest += pki.prime2()->size(); - memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size()); - dest += pki.exponent1()->size(); - memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size()); - dest += pki.exponent2()->size(); - memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size()); - dest += pki.coefficient()->size(); - memcpy(dest, &pki.private_exponent()->front(), - pki.private_exponent()->size()); - dest += pki.private_exponent()->size(); - - if (dest != blob.get() + blob_size) { - NOTREACHED(); - return NULL; - } - if (!CryptImportKey(result->provider_, - reinterpret_cast<uint8*>(public_key_struc), - static_cast<DWORD>(blob_size), 0, CRYPT_EXPORTABLE, - result->key_.receive())) { - return NULL; - } - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() : provider_(NULL), key_(NULL) {} - -RSAPrivateKey::~RSAPrivateKey() {} - -bool RSAPrivateKey::InitProvider() { - return FALSE != CryptAcquireContext(provider_.receive(), NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); -} - -RSAPrivateKey* RSAPrivateKey::Copy() const { - scoped_ptr<RSAPrivateKey> copy(new RSAPrivateKey()); - if (!CryptContextAddRef(provider_, NULL, 0)) { - NOTREACHED(); - return NULL; - } - copy->provider_.reset(provider_.get()); - if (!CryptDuplicateKey(key_.get(), NULL, 0, copy->key_.receive())) - return NULL; - return copy.release(); -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) const { - // Export the key - DWORD blob_length = 0; - if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, NULL, &blob_length)) { - NOTREACHED(); - return false; - } - - scoped_ptr<uint8[]> blob(new uint8[blob_length]); - if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, blob.get(), &blob_length)) { - NOTREACHED(); - return false; - } - - uint8* pos = blob.get(); - PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos); - pos += sizeof(PUBLICKEYSTRUC); - - RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos); - pos += sizeof(RSAPUBKEY); - - int mod_size = rsa_pub_key->bitlen / 8; - int primes_size = rsa_pub_key->bitlen / 16; - - PrivateKeyInfoCodec pki(false); // Little-Endian - - pki.modulus()->assign(pos, pos + mod_size); - pos += mod_size; - - pki.prime1()->assign(pos, pos + primes_size); - pos += primes_size; - pki.prime2()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.exponent1()->assign(pos, pos + primes_size); - pos += primes_size; - pki.exponent2()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.coefficient()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.private_exponent()->assign(pos, pos + mod_size); - pos += mod_size; - - pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp), - reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4); - - CHECK_EQ(pos - blob_length, reinterpret_cast<BYTE*>(publickey_struct)); - - return pki.Export(output); -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) const { - DWORD key_info_len; - if (!CryptExportPublicKeyInfo( - provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - NULL, &key_info_len)) { - NOTREACHED(); - return false; - } - - scoped_ptr<uint8[]> key_info(new uint8[key_info_len]); - if (!CryptExportPublicKeyInfo( - provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), &key_info_len)) { - NOTREACHED(); - return false; - } - - DWORD encoded_length; - if (!CryptEncodeObject( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), NULL, - &encoded_length)) { - NOTREACHED(); - return false; - } - - scoped_ptr<BYTE[]> encoded(new BYTE[encoded_length]); - if (!CryptEncodeObject( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), encoded.get(), - &encoded_length)) { - NOTREACHED(); - return false; - } - - output->assign(encoded.get(), encoded.get() + encoded_length); - return true; -} - -} // namespace crypto diff --git a/crypto/signature_creator.h b/crypto/signature_creator.h index 301ab19..1a1d6e5 100644 --- a/crypto/signature_creator.h +++ b/crypto/signature_creator.h @@ -7,23 +7,17 @@ #include "build/build_config.h" -#if defined(USE_OPENSSL) -// Forward declaration for openssl/*.h -typedef struct env_md_ctx_st EVP_MD_CTX; -#elif defined(USE_NSS) -// Forward declaration. -struct SGNContextStr; -#elif defined(OS_MACOSX) && !defined(OS_IOS) -#include <Security/cssm.h> -#endif - #include <vector> #include "base/basictypes.h" #include "crypto/crypto_export.h" -#if defined(OS_WIN) -#include "crypto/scoped_capi_types.h" +#if defined(USE_OPENSSL) +// Forward declaration for openssl/*.h +typedef struct env_md_ctx_st EVP_MD_CTX; +#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) +// Forward declaration. +struct SGNContextStr; #endif namespace crypto { @@ -54,12 +48,8 @@ class CRYPTO_EXPORT SignatureCreator { #if defined(USE_OPENSSL) EVP_MD_CTX* sign_context_; -#elif defined(USE_NSS) +#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) SGNContextStr* sign_context_; -#elif defined(OS_MACOSX) && !defined(OS_IOS) - CSSM_CC_HANDLE sig_handle_; -#elif defined(OS_WIN) - ScopedHCRYPTHASH hash_object_; #endif DISALLOW_COPY_AND_ASSIGN(SignatureCreator); diff --git a/crypto/signature_creator_mac.cc b/crypto/signature_creator_mac.cc deleted file mode 100644 index cdc34f8..0000000 --- a/crypto/signature_creator_mac.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2012 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/signature_creator.h" - -#include <stdlib.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "crypto/cssm_init.h" -#include "crypto/rsa_private_key.h" - -namespace crypto { - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - - CSSM_RETURN crtn; - crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(), - CSSM_ALGID_SHA1WithRSA, - NULL, - key->key(), - &result->sig_handle_); - if (crtn) { - NOTREACHED(); - return NULL; - } - - crtn = CSSM_SignDataInit(result->sig_handle_); - if (crtn) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -SignatureCreator::SignatureCreator() : key_(NULL), sig_handle_(0) { - EnsureCSSMInit(); -} - -SignatureCreator::~SignatureCreator() { - CSSM_RETURN crtn; - if (sig_handle_) { - crtn = CSSM_DeleteContext(sig_handle_); - DCHECK_EQ(CSSM_OK, crtn); - } -} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - CSSM_DATA data; - data.Data = const_cast<uint8*>(data_part); - data.Length = data_part_len; - CSSM_RETURN crtn = CSSM_SignDataUpdate(sig_handle_, &data, 1); - DCHECK_EQ(CSSM_OK, crtn); - return true; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - ScopedCSSMData sig; - CSSM_RETURN crtn = CSSM_SignDataFinal(sig_handle_, sig); - - if (crtn) { - NOTREACHED(); - return false; - } - - signature->assign(sig->Data, sig->Data + sig->Length); - return true; -} - -} // namespace crypto diff --git a/crypto/signature_creator_win.cc b/crypto/signature_creator_win.cc deleted file mode 100644 index 69e6513..0000000 --- a/crypto/signature_creator_win.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2012 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/signature_creator.h" - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "crypto/rsa_private_key.h" - -namespace crypto { - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - - if (!CryptCreateHash(key->provider(), CALG_SHA1, 0, 0, - result->hash_object_.receive())) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -SignatureCreator::SignatureCreator() : key_(NULL), hash_object_(0) {} - -SignatureCreator::~SignatureCreator() {} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - if (!CryptHashData(hash_object_, data_part, data_part_len, 0)) { - NOTREACHED(); - return false; - } - - return true; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - DWORD signature_length = 0; - if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, NULL, - &signature_length)) { - return false; - } - - std::vector<uint8> temp; - temp.resize(signature_length); - if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, &temp.front(), - &signature_length)) { - return false; - } - - temp.resize(signature_length); - for (size_t i = temp.size(); i > 0; --i) - signature->push_back(temp[i - 1]); - - return true; -} - -} // namespace crypto diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h index b75efa7..d12c0ba 100644 --- a/net/cert/x509_certificate.h +++ b/net/cert/x509_certificate.h @@ -37,10 +37,6 @@ struct CERTCertificateStr; class Pickle; class PickleIterator; -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - namespace net { class CRLSet; @@ -195,29 +191,6 @@ class NET_EXPORT X509Certificate int length, int format); - // Create a self-signed certificate containing the public key in |key|. - // Subject, serial number and validity period are given as parameters. - // The certificate is signed by the private key in |key|. The hashing - // algorithm for the signature is SHA-1. - // - // |subject| is a distinguished name defined in RFC4514. - // - // An example: - // CN=Michael Wong,O=FooBar Corporation,DC=foobar,DC=com - // - // SECURITY WARNING - // - // Using self-signed certificates has the following security risks: - // 1. Encryption without authentication and thus vulnerable to - // man-in-the-middle attacks. - // 2. Self-signed certificates cannot be revoked. - // - // Use this certificate only after the above risks are acknowledged. - static X509Certificate* CreateSelfSigned(crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration); - // Appends a representation of this object to the given pickle. void Persist(Pickle* pickle); diff --git a/net/cert/x509_certificate_ios.cc b/net/cert/x509_certificate_ios.cc index 32a4883..efeb54e 100644 --- a/net/cert/x509_certificate_ios.cc +++ b/net/cert/x509_certificate_ios.cc @@ -85,18 +85,6 @@ bool X509Certificate::IsIssuedByEncoded( nss_chain.cert_chain(), issuers); } -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - DCHECK(!subject.empty()); - NOTIMPLEMENTED(); - return NULL; -} - void X509Certificate::GetSubjectAltName( std::vector<std::string>* dns_names, std::vector<std::string>* ip_addrs) const { diff --git a/net/cert/x509_certificate_mac.cc b/net/cert/x509_certificate_mac.cc index fd9aaca..2f8ce43 100644 --- a/net/cert/x509_certificate_mac.cc +++ b/net/cert/x509_certificate_mac.cc @@ -25,7 +25,6 @@ #include "crypto/cssm_init.h" #include "crypto/mac_security_services_lock.h" #include "crypto/nss_util.h" -#include "crypto/rsa_private_key.h" #include "net/cert/x509_util_mac.h" using base::ScopedCFTypeRef; @@ -326,144 +325,6 @@ bool X509Certificate::IsIssuedByEncoded( return false; } -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - DCHECK(!subject.empty()); - - if (valid_duration.InSeconds() > kuint32max) { - LOG(ERROR) << "valid_duration too big " << valid_duration.InSeconds(); - valid_duration = base::TimeDelta::FromSeconds(kuint32max); - } - - // There is a comment in - // http://www.opensource.apple.com/source/security_certtool/security_certtool-31828/src/CertTool.cpp - // that serial_numbers being passed into CSSM_TP_SubmitCredRequest can't have - // their high bit set. We will continue though and mask it out below. - if (serial_number & 0x80000000) - LOG(ERROR) << "serial_number has high bit set " << serial_number; - - // NSS is used to parse the subject string into a set of - // CSSM_OID/string pairs. There doesn't appear to be a system routine for - // parsing Distinguished Name strings. - crypto::EnsureNSSInit(); - - CSSMOIDStringVector subject_name_oids; - ScopedCertName subject_name( - CERT_AsciiToName(const_cast<char*>(subject.c_str()))); - if (!CERTNameToCSSMOIDVector(subject_name, &subject_name_oids)) { - DLOG(ERROR) << "Unable to generate CSSMOIDMap from " << subject; - return NULL; - } - - // Convert the map of oid/string pairs into an array of - // CSSM_APPLE_TP_NAME_OIDs. - std::vector<CSSM_APPLE_TP_NAME_OID> cssm_subject_names; - for (CSSMOIDStringVector::iterator iter = subject_name_oids.begin(); - iter != subject_name_oids.end(); ++iter) { - CSSM_APPLE_TP_NAME_OID cssm_subject_name; - cssm_subject_name.oid = iter->oid_; - cssm_subject_name.string = iter->string_.c_str(); - cssm_subject_names.push_back(cssm_subject_name); - } - - if (cssm_subject_names.empty()) { - DLOG(ERROR) << "cssm_subject_names.size() == 0. Input: " << subject; - return NULL; - } - - // Set up a certificate request. - CSSM_APPLE_TP_CERT_REQUEST certReq; - memset(&certReq, 0, sizeof(certReq)); - certReq.cspHand = crypto::GetSharedCSPHandle(); - certReq.clHand = crypto::GetSharedCLHandle(); - // See comment about serial numbers above. - certReq.serialNumber = serial_number & 0x7fffffff; - certReq.numSubjectNames = cssm_subject_names.size(); - certReq.subjectNames = &cssm_subject_names[0]; - certReq.numIssuerNames = 0; // Root. - certReq.issuerNames = NULL; - certReq.issuerNameX509 = NULL; - certReq.certPublicKey = key->public_key(); - certReq.issuerPrivateKey = key->key(); - // These are the Apple defaults. - certReq.signatureAlg = CSSM_ALGID_SHA1WithRSA; - certReq.signatureOid = CSSMOID_SHA1WithRSA; - certReq.notBefore = 0; - certReq.notAfter = static_cast<uint32>(valid_duration.InSeconds()); - certReq.numExtensions = 0; - certReq.extensions = NULL; - certReq.challengeString = NULL; - - CSSM_TP_REQUEST_SET reqSet; - reqSet.NumberOfRequests = 1; - reqSet.Requests = &certReq; - - CSSM_FIELD policyId; - memset(&policyId, 0, sizeof(policyId)); - policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN; - - CSSM_TP_CALLERAUTH_CONTEXT callerAuthContext; - memset(&callerAuthContext, 0, sizeof(callerAuthContext)); - callerAuthContext.Policy.NumberOfPolicyIds = 1; - callerAuthContext.Policy.PolicyIds = &policyId; - - CSSM_TP_HANDLE tp_handle = crypto::GetSharedTPHandle(); - CSSM_DATA refId; - memset(&refId, 0, sizeof(refId)); - sint32 estTime; - CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tp_handle, NULL, - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, &reqSet, &callerAuthContext, - &estTime, &refId); - if (crtn) { - DLOG(ERROR) << "CSSM_TP_SubmitCredRequest failed " << crtn; - return NULL; - } - - CSSM_BOOL confirmRequired; - CSSM_TP_RESULT_SET* resultSet = NULL; - crtn = CSSM_TP_RetrieveCredResult(tp_handle, &refId, NULL, &estTime, - &confirmRequired, &resultSet); - ScopedEncodedCertResults scopedResults(resultSet); - crypto::CSSMFree(refId.Data); - if (crtn) { - DLOG(ERROR) << "CSSM_TP_RetrieveCredResult failed " << crtn; - return NULL; - } - - if (confirmRequired) { - // Potential leak here of resultSet. |confirmRequired| should never be - // true. - DLOG(ERROR) << "CSSM_TP_RetrieveCredResult required confirmation"; - return NULL; - } - - if (resultSet->NumberOfResults != 1) { - DLOG(ERROR) << "Unexpected number of results: " - << resultSet->NumberOfResults; - return NULL; - } - - CSSM_ENCODED_CERT* encCert = - reinterpret_cast<CSSM_ENCODED_CERT*>(resultSet->Results); - ScopedCFTypeRef<SecCertificateRef> scoped_cert; - SecCertificateRef certificate_ref = NULL; - OSStatus os_status = - SecCertificateCreateFromData(&encCert->CertBlob, encCert->CertType, - encCert->CertEncoding, &certificate_ref); - if (os_status != 0) { - OSSTATUS_DLOG(ERROR, os_status) << "SecCertificateCreateFromData failed"; - return NULL; - } - scoped_cert.reset(certificate_ref); - - return CreateFromHandle(scoped_cert, X509Certificate::OSCertHandles()); -} - void X509Certificate::GetSubjectAltName( std::vector<std::string>* dns_names, std::vector<std::string>* ip_addrs) const { diff --git a/net/cert/x509_certificate_nss.cc b/net/cert/x509_certificate_nss.cc index bbc448f..8448a49 100644 --- a/net/cert/x509_certificate_nss.cc +++ b/net/cert/x509_certificate_nss.cc @@ -20,7 +20,6 @@ #include "base/strings/stringprintf.h" #include "base/time.h" #include "crypto/nss_util.h" -#include "crypto/rsa_private_key.h" #include "crypto/scoped_nss_types.h" #include "net/cert/x509_util_nss.h" @@ -114,30 +113,6 @@ std::string X509Certificate::GetDefaultNickname(CertType type) const { return result; } -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - base::Time not_valid_before = base::Time::Now(); - base::Time not_valid_after = not_valid_before + valid_duration; - CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(), - key->key(), - subject, - serial_number, - not_valid_before, - not_valid_after); - if (!cert) - return NULL; - - X509Certificate* x509_cert = X509Certificate::CreateFromHandle( - cert, X509Certificate::OSCertHandles()); - CERT_DestroyCertificate(cert); - return x509_cert; -} - void X509Certificate::GetSubjectAltName( std::vector<std::string>* dns_names, std::vector<std::string>* ip_addrs) const { diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc index 82475ff..bdf2bf2 100644 --- a/net/cert/x509_certificate_openssl.cc +++ b/net/cert/x509_certificate_openssl.cc @@ -362,17 +362,6 @@ X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( return results; } -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - // TODO(port): Implement. See http://crbug.com/91512. - NOTIMPLEMENTED(); - return NULL; -} - void X509Certificate::GetSubjectAltName( std::vector<std::string>* dns_names, std::vector<std::string>* ip_addrs) const { diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc index 427431d..a457538 100644 --- a/net/cert/x509_certificate_unittest.cc +++ b/net/cert/x509_certificate_unittest.cc @@ -795,132 +795,6 @@ TEST(X509CertificateTest, GetDefaultNickname) { } #endif -#if !defined(OS_IOS) // TODO(ios): Unable to create certificates. -#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) -// This test creates a self-signed cert from a private key and then verify the -// content of the certificate. -TEST(X509CertificateTest, CreateSelfSigned) { - scoped_ptr<crypto::RSAPrivateKey> private_key( - crypto::RSAPrivateKey::Create(1024)); - scoped_refptr<X509Certificate> cert = - X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); - - EXPECT_EQ("subject", cert->subject().GetDisplayName()); - EXPECT_FALSE(cert->HasExpired()); - - const uint8 private_key_info[] = { - 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, - 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, - 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, - 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, - 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, - 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, - 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, - 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, - 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, - 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, - 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, - 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, - 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, - 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, - 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, - 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, - 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, - 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, - 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb, - 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, - 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, - 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95, - 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, - 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, - 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e, - 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, - 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, - 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa, - 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, - 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, - 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e, - 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, - 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, - 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00, - 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, - 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, - 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82, - 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, - 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, - 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8, - 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, - 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, - 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1, - 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, - 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, - 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62, - 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, - 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, - 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6, - 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, - 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, - 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9, - 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, - 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, - 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93, - 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, - 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, - 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17, - 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, - 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, - 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1, - 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, - 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, - 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd, - 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, - 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, - 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7, - 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, - 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, - 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99, - 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, - 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, - 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb, - 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, - 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, - 0xb1, 0xc5, 0x15, 0xf3 - }; - - std::vector<uint8> input; - input.resize(sizeof(private_key_info)); - memcpy(&input.front(), private_key_info, sizeof(private_key_info)); - - private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); - ASSERT_TRUE(private_key.get()); - - cert = X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); - - EXPECT_EQ("subject", cert->subject().GetDisplayName()); - EXPECT_FALSE(cert->HasExpired()); -} - -TEST(X509CertificateTest, GetDEREncoded) { - scoped_ptr<crypto::RSAPrivateKey> private_key( - crypto::RSAPrivateKey::Create(1024)); - scoped_refptr<X509Certificate> cert = - X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 0, base::TimeDelta::FromDays(1)); - - std::string der_cert; - EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), - &der_cert)); - EXPECT_FALSE(der_cert.empty()); -} -#endif -#endif // !defined(OS_IOS) - class X509CertificateParseTest : public testing::TestWithParam<CertificateFormatTestData> { public: diff --git a/net/cert/x509_certificate_win.cc b/net/cert/x509_certificate_win.cc index 02e4df6..9c8901d 100644 --- a/net/cert/x509_certificate_win.cc +++ b/net/cert/x509_certificate_win.cc @@ -13,7 +13,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "crypto/capi_util.h" -#include "crypto/rsa_private_key.h" #include "crypto/scoped_capi_types.h" #include "net/base/net_errors.h" @@ -165,67 +164,6 @@ void X509Certificate::Initialize() { reinterpret_cast<char*>(serial_bytes.get()), serial->cbData); } -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - // Get the ASN.1 encoding of the certificate subject. - std::wstring w_subject = ASCIIToWide(subject); - DWORD encoded_subject_length = 0; - if (!CertStrToName( - X509_ASN_ENCODING, - w_subject.c_str(), - CERT_X500_NAME_STR, NULL, NULL, &encoded_subject_length, NULL)) { - return NULL; - } - - scoped_ptr<BYTE[]> encoded_subject(new BYTE[encoded_subject_length]); - if (!CertStrToName( - X509_ASN_ENCODING, - w_subject.c_str(), - CERT_X500_NAME_STR, NULL, - encoded_subject.get(), - &encoded_subject_length, NULL)) { - return NULL; - } - - CERT_NAME_BLOB subject_name; - memset(&subject_name, 0, sizeof(subject_name)); - subject_name.cbData = encoded_subject_length; - subject_name.pbData = encoded_subject.get(); - - CRYPT_ALGORITHM_IDENTIFIER sign_algo; - memset(&sign_algo, 0, sizeof(sign_algo)); - sign_algo.pszObjId = szOID_RSA_SHA1RSA; - - base::Time not_before = base::Time::Now(); - base::Time not_after = not_before + valid_duration; - base::Time::Exploded exploded; - - // Create the system time structs representing our exploded times. - not_before.UTCExplode(&exploded); - SYSTEMTIME start_time; - ExplodedTimeToSystemTime(exploded, &start_time); - not_after.UTCExplode(&exploded); - SYSTEMTIME end_time; - ExplodedTimeToSystemTime(exploded, &end_time); - - PCCERT_CONTEXT cert_handle = - CertCreateSelfSignCertificate(key->provider(), &subject_name, - CERT_CREATE_SELFSIGN_NO_KEY_INFO, NULL, - &sign_algo, &start_time, &end_time, NULL); - DCHECK(cert_handle) << "Failed to create self-signed certificate: " - << GetLastError(); - if (!cert_handle) - return NULL; - - X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); - FreeOSCertHandle(cert_handle); - return cert; -} - void X509Certificate::GetSubjectAltName( std::vector<std::string>* dns_names, std::vector<std::string>* ip_addrs) const { diff --git a/net/cert/x509_util.h b/net/cert/x509_util.h index 50ffc7f..c618fe9 100644 --- a/net/cert/x509_util.h +++ b/net/cert/x509_util.h @@ -13,6 +13,7 @@ namespace crypto { class ECPrivateKey; +class RSAPrivateKey; } namespace net { @@ -44,6 +45,31 @@ NET_EXPORT_PRIVATE bool CreateDomainBoundCertEC( base::Time not_valid_after, std::string* der_cert); +// Create a self-signed certificate containing the public key in |key|. +// Subject, serial number and validity period are given as parameters. +// The certificate is signed by the private key in |key|. The hashing +// algorithm for the signature is SHA-1. +// +// |subject| is a distinguished name defined in RFC4514. +// +// An example: +// CN=Michael Wong,O=FooBar Corporation,DC=foobar,DC=com +// +// SECURITY WARNING +// +// Using self-signed certificates has the following security risks: +// 1. Encryption without authentication and thus vulnerable to +// man-in-the-middle attacks. +// 2. Self-signed certificates cannot be revoked. +// +// Use this certificate only after the above risks are acknowledged. +NET_EXPORT bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, + const std::string& subject, + uint32 serial_number, + base::Time not_valid_before, + base::Time not_valid_after, + std::string* der_cert); + // Comparator for use in STL algorithms that will sort client certificates by // order of preference. // Returns true if |a| is more preferable than |b|, allowing it to be used diff --git a/net/cert/x509_util_nss.cc b/net/cert/x509_util_nss.cc index 5666935..f8fbd6f 100644 --- a/net/cert/x509_util_nss.cc +++ b/net/cert/x509_util_nss.cc @@ -24,6 +24,7 @@ #include "crypto/ec_private_key.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/third_party/nss/chromium-nss.h" #include "net/cert/x509_certificate.h" @@ -182,80 +183,6 @@ bool SignCertificate( return true; } -bool CreateDomainBoundCertInternal( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert) { - CERTCertificate* cert = CreateCertificate(public_key, - "CN=anonymous.invalid", - serial_number, - not_valid_before, - not_valid_after); - - if (!cert) - return false; - - // Create opaque handle used to add extensions later. - void* cert_handle; - if ((cert_handle = CERT_StartCertExtensions(cert)) == NULL) { - LOG(ERROR) << "Unable to get opaque handle for adding extensions"; - CERT_DestroyCertificate(cert); - return false; - } - - // Create SECItem for IA5String encoding. - SECItem domain_string_item = { - siAsciiString, - (unsigned char*)domain.data(), - static_cast<unsigned>(domain.size()) - }; - - // IA5Encode and arena allocate SECItem - SECItem* asn1_domain_string = SEC_ASN1EncodeItem( - cert->arena, NULL, &domain_string_item, - SEC_ASN1_GET(SEC_IA5StringTemplate)); - if (asn1_domain_string == NULL) { - LOG(ERROR) << "Unable to get ASN1 encoding for domain in domain_bound_cert" - " extension"; - CERT_DestroyCertificate(cert); - return false; - } - - // Add the extension to the opaque handle - if (CERT_AddExtension( - cert_handle, - DomainBoundCertOIDWrapper::GetInstance()->domain_bound_cert_oid_tag(), - asn1_domain_string, PR_TRUE, PR_TRUE) != SECSuccess){ - LOG(ERROR) << "Unable to add domain bound cert extension to opaque handle"; - CERT_DestroyCertificate(cert); - return false; - } - - // Copy extension into x509 cert - if (CERT_FinishExtensions(cert_handle) != SECSuccess){ - LOG(ERROR) << "Unable to copy extension to X509 cert"; - CERT_DestroyCertificate(cert); - return false; - } - - if (!SignCertificate(cert, private_key)) { - CERT_DestroyCertificate(cert); - return false; - } - - DCHECK(cert->derCert.len); - // XXX copied from X509Certificate::GetDEREncoded - der_cert->clear(); - der_cert->append(reinterpret_cast<char*>(cert->derCert.data), - cert->derCert.len); - CERT_DestroyCertificate(cert); - return true; -} - #if defined(USE_NSS) || defined(OS_IOS) // Callback for CERT_DecodeCertPackage(), used in // CreateOSCertHandlesFromBytes(). @@ -312,27 +239,30 @@ CERTName* CreateCertNameFromEncoded(PLArenaPool* arena, namespace x509_util { -CERTCertificate* CreateSelfSignedCert( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& subject, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after) { - CERTCertificate* cert = CreateCertificate(public_key, +bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, + const std::string& subject, + uint32 serial_number, + base::Time not_valid_before, + base::Time not_valid_after, + std::string* der_cert) { + DCHECK(key); + CERTCertificate* cert = CreateCertificate(key->public_key(), subject, serial_number, not_valid_before, not_valid_after); if (!cert) - return NULL; + return false; - if (!SignCertificate(cert, private_key)) { + if (!SignCertificate(cert, key->key())) { CERT_DestroyCertificate(cert); - return NULL; + return false; } - return cert; + der_cert->assign(reinterpret_cast<char*>(cert->derCert.data), + cert->derCert.len); + CERT_DestroyCertificate(cert); + return true; } bool IsSupportedValidityRange(base::Time not_valid_before, @@ -348,21 +278,80 @@ bool IsSupportedValidityRange(base::Time not_valid_before, return true; } -bool CreateDomainBoundCertEC( - crypto::ECPrivateKey* key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert) { +bool CreateDomainBoundCertEC(crypto::ECPrivateKey* key, + const std::string& domain, + uint32 serial_number, + base::Time not_valid_before, + base::Time not_valid_after, + std::string* der_cert) { DCHECK(key); - return CreateDomainBoundCertInternal(key->public_key(), - key->key(), - domain, - serial_number, - not_valid_before, - not_valid_after, - der_cert); + + CERTCertificate* cert = CreateCertificate(key->public_key(), + "CN=anonymous.invalid", + serial_number, + not_valid_before, + not_valid_after); + + if (!cert) + return false; + + // Create opaque handle used to add extensions later. + void* cert_handle; + if ((cert_handle = CERT_StartCertExtensions(cert)) == NULL) { + LOG(ERROR) << "Unable to get opaque handle for adding extensions"; + CERT_DestroyCertificate(cert); + return false; + } + + // Create SECItem for IA5String encoding. + SECItem domain_string_item = { + siAsciiString, + (unsigned char*)domain.data(), + static_cast<unsigned>(domain.size()) + }; + + // IA5Encode and arena allocate SECItem + SECItem* asn1_domain_string = SEC_ASN1EncodeItem( + cert->arena, NULL, &domain_string_item, + SEC_ASN1_GET(SEC_IA5StringTemplate)); + if (asn1_domain_string == NULL) { + LOG(ERROR) << "Unable to get ASN1 encoding for domain in domain_bound_cert" + " extension"; + CERT_DestroyCertificate(cert); + return false; + } + + // Add the extension to the opaque handle + if (CERT_AddExtension( + cert_handle, + DomainBoundCertOIDWrapper::GetInstance()->domain_bound_cert_oid_tag(), + asn1_domain_string, + PR_TRUE, + PR_TRUE) != SECSuccess){ + LOG(ERROR) << "Unable to add domain bound cert extension to opaque handle"; + CERT_DestroyCertificate(cert); + return false; + } + + // Copy extension into x509 cert + if (CERT_FinishExtensions(cert_handle) != SECSuccess){ + LOG(ERROR) << "Unable to copy extension to X509 cert"; + CERT_DestroyCertificate(cert); + return false; + } + + if (!SignCertificate(cert, key->key())) { + CERT_DestroyCertificate(cert); + return false; + } + + DCHECK(cert->derCert.len); + // XXX copied from X509Certificate::GetDEREncoded + der_cert->clear(); + der_cert->append(reinterpret_cast<char*>(cert->derCert.data), + cert->derCert.len); + CERT_DestroyCertificate(cert); + return true; } #if defined(USE_NSS) || defined(OS_IOS) diff --git a/net/cert/x509_util_nss.h b/net/cert/x509_util_nss.h index 5ad752e..493e661 100644 --- a/net/cert/x509_util_nss.h +++ b/net/cert/x509_util_nss.h @@ -19,25 +19,11 @@ typedef struct CERTNameStr CERTName; typedef struct PK11SlotInfoStr PK11SlotInfo; typedef struct PLArenaPool PLArenaPool; typedef struct SECItemStr SECItem; -typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; -typedef struct SECKEYPublicKeyStr SECKEYPublicKey; namespace net { namespace x509_util { -// Creates a self-signed certificate containing |public_key|. Subject, serial -// number and validity period are given as parameters. The certificate is -// signed by |private_key|. The hashing algorithm for the signature is SHA-1. -// |subject| is a distinguished name defined in RFC4514. -NET_EXPORT_PRIVATE CERTCertificate* CreateSelfSignedCert( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& subject, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after); - #if defined(USE_NSS) || defined(OS_IOS) // Parses the Principal attribute from |name| and outputs the result in // |principal|. diff --git a/net/cert/x509_util_openssl.cc b/net/cert/x509_util_openssl.cc index e98c2a0..e4dec99 100644 --- a/net/cert/x509_util_openssl.cc +++ b/net/cert/x509_util_openssl.cc @@ -59,6 +59,16 @@ bool CreateDomainBoundCertEC( return false; } +bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, + const std::string& common_name, + uint32 serial_number, + base::Time not_valid_before, + base::Time not_valid_after, + std::string* der_encoded) { + NOTIMPLEMENTED(); + return false; +} + bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, int index, std::string* key, diff --git a/net/cert/x509_util_unittest.cc b/net/cert/x509_util_unittest.cc index ee42f1c..e0c1ec6 100644 --- a/net/cert/x509_util_unittest.cc +++ b/net/cert/x509_util_unittest.cc @@ -6,7 +6,10 @@ #include <algorithm> +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/time.h" +#include "crypto/rsa_private_key.h" #include "net/cert/x509_certificate.h" #include "testing/gtest/include/gtest/gtest.h" @@ -49,6 +52,139 @@ TEST(X509UtilTest, SortClientCertificates) { ASSERT_FALSE(certs[5].get()); } +#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) +// This test creates a self-signed cert from a private key and then verify the +// content of the certificate. +TEST(X509UtilTest, CreateSelfSigned) { + scoped_ptr<crypto::RSAPrivateKey> private_key( + crypto::RSAPrivateKey::Create(1024)); + + ASSERT_TRUE(private_key.get()); + + std::string der_cert; + ASSERT_TRUE(x509_util::CreateSelfSignedCert( + private_key.get(), + "CN=subject", + 1, + base::Time::Now(), + base::Time::Now() + base::TimeDelta::FromDays(1), + &der_cert)); + + scoped_refptr<X509Certificate> cert(X509Certificate::CreateFromBytes( + der_cert.data(), der_cert.size())); + ASSERT_TRUE(cert.get()); + + EXPECT_EQ("subject", cert->subject().GetDisplayName()); + EXPECT_FALSE(cert->HasExpired()); + + cert = NULL; + + const uint8 private_key_info[] = { + 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, + 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, + 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, + 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, + 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, + 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, + 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, + 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, + 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, + 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, + 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, + 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, + 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, + 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, + 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, + 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, + 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, + 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, + 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb, + 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, + 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, + 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95, + 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, + 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, + 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e, + 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, + 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, + 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa, + 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, + 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, + 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e, + 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, + 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, + 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00, + 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, + 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, + 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82, + 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, + 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, + 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8, + 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, + 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, + 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1, + 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, + 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, + 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62, + 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, + 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, + 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6, + 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, + 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, + 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9, + 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, + 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, + 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93, + 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, + 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, + 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17, + 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, + 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, + 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1, + 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, + 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, + 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd, + 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, + 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, + 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7, + 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, + 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, + 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99, + 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, + 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, + 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb, + 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, + 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, + 0xb1, 0xc5, 0x15, 0xf3 + }; + + std::vector<uint8> input; + input.resize(sizeof(private_key_info)); + memcpy(&input.front(), private_key_info, sizeof(private_key_info)); + + private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); + ASSERT_TRUE(private_key.get()); + + ASSERT_TRUE(x509_util::CreateSelfSignedCert( + private_key.get(), + "CN=subject", + 1, + base::Time::Now(), + base::Time::Now() + base::TimeDelta::FromDays(1), + &der_cert)); + + cert = X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()); + ASSERT_TRUE(cert.get()); + + EXPECT_EQ("subject", cert->subject().GetDisplayName()); + EXPECT_FALSE(cert->HasExpired()); +} +#endif + } // namespace x509_util } // namespace net diff --git a/remoting/base/rsa_key_pair.cc b/remoting/base/rsa_key_pair.cc index 9f8b11f..81e8a92 100644 --- a/remoting/base/rsa_key_pair.cc +++ b/remoting/base/rsa_key_pair.cc @@ -14,7 +14,7 @@ #include "base/time.h" #include "crypto/rsa_private_key.h" #include "crypto/signature_creator.h" -#include "net/cert/x509_certificate.h" +#include "net/cert/x509_util.h" namespace remoting { @@ -92,19 +92,15 @@ std::string RsaKeyPair::SignMessage(const std::string& message) const { } std::string RsaKeyPair::GenerateCertificate() const { - scoped_refptr<net::X509Certificate> cert = - net::X509Certificate::CreateSelfSigned( - key_.get(), "CN=chromoting", - base::RandInt(1, std::numeric_limits<int>::max()), - base::TimeDelta::FromDays(1)); - if (!cert.get()) - return std::string(); - - std::string encoded; - bool result = net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), - &encoded); - CHECK(result); - return encoded; + std::string der_cert; + net::x509_util::CreateSelfSignedCert( + key_.get(), + "CN=chromoting", + base::RandInt(1, std::numeric_limits<int>::max()), + base::Time::Now(), + base::Time::Now() + base::TimeDelta::FromDays(1), + &der_cert); + return der_cert; } } // namespace remoting |