| diff --git a/crypto/rsa_private_key.h b/crypto/rsa_private_key.h |
| index ff368d8..b8ce169 100644 |
| --- a/crypto/rsa_private_key.h |
| +++ b/crypto/rsa_private_key.h |
| @@ -12,8 +12,8 @@ |
| typedef struct evp_pkey_st EVP_PKEY; |
| #elif defined(USE_NSS) |
| // Forward declaration. |
| -struct SECKEYPrivateKeyStr; |
| -struct SECKEYPublicKeyStr; |
| +typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; |
| +typedef struct SECKEYPublicKeyStr SECKEYPublicKey; |
| #elif defined(OS_IOS) |
| #include <Security/Security.h> |
| #elif defined(OS_MACOSX) |
| @@ -200,6 +200,12 @@ class CRYPTO_EXPORT RSAPrivateKey { |
| 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 |
| // an X509 SubjectPublicKeyInfo block. This can return NULL if |
| @@ -214,8 +220,8 @@ class CRYPTO_EXPORT RSAPrivateKey { |
| #if defined(USE_OPENSSL) |
| EVP_PKEY* key() { return key_; } |
| #elif defined(USE_NSS) |
| - SECKEYPrivateKeyStr* key() { return key_; } |
| - SECKEYPublicKeyStr* public_key() { return public_key_; } |
| + SECKEYPrivateKey* key() { return key_; } |
| + SECKEYPublicKey* public_key() { return public_key_; } |
| #elif defined(OS_WIN) |
| HCRYPTPROV provider() { return provider_; } |
| HCRYPTKEY key() { return key_; } |
| @@ -261,8 +267,8 @@ class CRYPTO_EXPORT RSAPrivateKey { |
| #if defined(USE_OPENSSL) |
| EVP_PKEY* key_; |
| #elif defined(USE_NSS) |
| - SECKEYPrivateKeyStr* key_; |
| - SECKEYPublicKeyStr* public_key_; |
| + SECKEYPrivateKey* key_; |
| + SECKEYPublicKey* public_key_; |
| #elif defined(OS_WIN) |
| bool InitProvider(); |
| |
| diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc |
| index 3b8bd44..ea2b432 100644 |
| --- a/crypto/rsa_private_key_nss.cc |
| +++ b/crypto/rsa_private_key_nss.cc |
| @@ -81,6 +81,22 @@ RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( |
| } |
| |
| // static |
| +RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) { |
| + DCHECK(key); |
| + if (SECKEY_GetPrivateKeyType(key) != rsaKey) |
| + return NULL; |
| + RSAPrivateKey* copy = new RSAPrivateKey(); |
| + copy->key_ = SECKEY_CopyPrivateKey(key); |
| + copy->public_key_ = SECKEY_ConvertToPublicKey(key); |
| + if (!copy->key_ || !copy->public_key_) { |
| + NOTREACHED(); |
| + delete copy; |
| + return NULL; |
| + } |
| + return copy; |
| +} |
| + |
| +// static |
| RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( |
| const std::vector<uint8>& input) { |
| EnsureNSSInit(); |
| diff --git a/crypto/rsa_private_key_nss_unittest.cc b/crypto/rsa_private_key_nss_unittest.cc |
| index 0ec801d..66d352a 100644 |
| --- a/crypto/rsa_private_key_nss_unittest.cc |
| +++ b/crypto/rsa_private_key_nss_unittest.cc |
| @@ -25,9 +25,32 @@ class RSAPrivateKeyNSSTest : public testing::Test { |
| } |
| |
| private: |
| + ScopedTestNSSDB test_nssdb_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest); |
| }; |
| |
| +TEST_F(RSAPrivateKeyNSSTest, CreateFromKeyTest) { |
| + scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256)); |
| + |
| + scoped_ptr<crypto::RSAPrivateKey> key_copy( |
| + RSAPrivateKey::CreateFromKey(key_pair->key())); |
| + ASSERT_TRUE(key_copy.get()); |
| + |
| + std::vector<uint8> privkey; |
| + std::vector<uint8> pubkey; |
| + ASSERT_TRUE(key_pair->ExportPrivateKey(&privkey)); |
| + ASSERT_TRUE(key_pair->ExportPublicKey(&pubkey)); |
| + |
| + std::vector<uint8> privkey_copy; |
| + std::vector<uint8> pubkey_copy; |
| + ASSERT_TRUE(key_copy->ExportPrivateKey(&privkey_copy)); |
| + ASSERT_TRUE(key_copy->ExportPublicKey(&pubkey_copy)); |
| + |
| + ASSERT_EQ(privkey, privkey_copy); |
| + ASSERT_EQ(pubkey, pubkey_copy); |
| +} |
| + |
| 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)); |