Index: crypto/rsa_private_key_nss.cc |
diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc |
index bd54c2e4037131b536a6134305e1027fdf804b73..078544de0c3fa0a81e8bdb952113511c9b475471 100644 |
--- a/crypto/rsa_private_key_nss.cc |
+++ b/crypto/rsa_private_key_nss.cc |
@@ -38,6 +38,37 @@ static bool ReadAttribute(SECKEYPrivateKey* key, |
return true; |
} |
+#if defined(USE_NSS) |
+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) |
+ |
} // namespace |
namespace crypto { |
@@ -112,35 +143,9 @@ RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) { |
// static |
RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( |
const std::vector<uint8>& input) { |
- EnsureNSSInit(); |
- |
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
- |
- // 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(); |
- |
- CERTSubjectPublicKeyInfo* spki = |
- SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der); |
- if (!spki) { |
- NOTREACHED(); |
- return NULL; |
- } |
- |
- result->public_key_ = SECKEY_ExtractPublicKey(spki); |
- SECKEY_DestroySubjectPublicKeyInfo(spki); |
- if (!result->public_key_) { |
- NOTREACHED(); |
- return NULL; |
- } |
- |
- // Make sure the key is an RSA key. If not, that's an error |
- if (result->public_key_->keyType != rsaKey) { |
- NOTREACHED(); |
+ scoped_ptr<RSAPrivateKey> result(InitPublicPart(input)); |
+ if (!result) |
return NULL; |
- } |
ScopedSECItem ck_id( |
PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus))); |
@@ -166,6 +171,30 @@ RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( |
// 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 { |
@@ -273,4 +302,20 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( |
return result.release(); |
} |
+#if defined(USE_NSS) |
+// 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) |
+ |
} // namespace crypto |