From b90ee449a2a2bb17b619eb2e2388dc9a8a0f3820 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Mon, 18 Sep 2017 12:18:56 -0500 Subject: [PATCH] port RSAKey* changes --- Crypto/include/Poco/Crypto/RSAKey.h | 32 ++++------ Crypto/include/Poco/Crypto/RSAKeyImpl.h | 20 ++++-- Crypto/src/EVPPKey.cpp | 2 +- Crypto/src/RSAKey.cpp | 64 +++++++------------- Crypto/src/RSAKeyImpl.cpp | 58 +++++++++++++----- Crypto/testsuite/src/PKCS12ContainerTest.cpp | 6 +- openssl | 2 +- 7 files changed, 97 insertions(+), 87 deletions(-) diff --git a/Crypto/include/Poco/Crypto/RSAKey.h b/Crypto/include/Poco/Crypto/RSAKey.h index cd858d52b..e40e0e167 100644 --- a/Crypto/include/Poco/Crypto/RSAKey.h +++ b/Crypto/include/Poco/Crypto/RSAKey.h @@ -19,6 +19,7 @@ #include "Poco/Crypto/Crypto.h" +#include "Poco/Crypto/KeyPair.h" #include "Poco/Crypto/RSAKeyImpl.h" @@ -27,9 +28,10 @@ namespace Crypto { class X509Certificate; +class PKCS12Container; -class Crypto_API RSAKey +class Crypto_API RSAKey : public KeyPair /// This class stores an RSA key pair, consisting /// of private and public key. Storage of the private /// key is optional. @@ -53,9 +55,15 @@ public: EXP_LARGE }; - explicit RSAKey(const X509Certificate& cert); + RSAKey(const EVPPKey& key); + /// Constructs ECKeyImpl by extracting the EC key. + + RSAKey(const X509Certificate& cert); /// Extracts the RSA public key from the given certificate. + RSAKey(const PKCS12Container& cert); + /// Extracts the RSA private key from the given certificate. + RSAKey(KeyLength keyLength, Exponent exp); /// Creates the RSAKey. Creates a new public/private keypair using the given parameters. /// Can be used to sign data and verify signatures. @@ -81,9 +89,6 @@ public: ~RSAKey(); /// Destroys the RSAKey. - int size() const; - /// Returns the RSA modulus size. - RSAKeyImpl::ByteVec modulus() const; /// Returns the RSA modulus. @@ -93,23 +98,8 @@ public: RSAKeyImpl::ByteVec decryptionExponent() const; /// Returns the RSA decryption exponent. - void save(const std::string& publicKeyFile, const std::string& privateKeyFile = "", const std::string& privateKeyPassphrase = ""); - /// Exports the public and private keys to the given files. - /// - /// If an empty filename is specified, the corresponding key - /// is not exported. - - void save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream = 0, const std::string& privateKeyPassphrase = ""); - /// Exports the public and private key to the given streams. - /// - /// If a null pointer is passed for a stream, the corresponding - /// key is not exported. - RSAKeyImpl::Ptr impl() const; /// Returns the impl object. - - const std::string& name() const; - /// Returns "rsa" private: RSAKeyImpl::Ptr _pImpl; @@ -128,4 +118,4 @@ inline RSAKeyImpl::Ptr RSAKey::impl() const } } // namespace Poco::Crypto -#endif // Crypto_RSAKey_INCLUDED +#endif // Crypto_RSAKey_INCLUDED \ No newline at end of file diff --git a/Crypto/include/Poco/Crypto/RSAKeyImpl.h b/Crypto/include/Poco/Crypto/RSAKeyImpl.h index 18f7106a9..ae2ca1f72 100644 --- a/Crypto/include/Poco/Crypto/RSAKeyImpl.h +++ b/Crypto/include/Poco/Crypto/RSAKeyImpl.h @@ -19,6 +19,8 @@ #include "Poco/Crypto/Crypto.h" +#include "Poco/Crypto/EVPPKey.h" +#include "Poco/Crypto/KeyPairImpl.h" #include "Poco/Crypto/OpenSSLInitializer.h" #include "Poco/RefCountedObject.h" #include "Poco/AutoPtr.h" @@ -38,18 +40,27 @@ namespace Crypto { class X509Certificate; +class PKCS12Container; -class RSAKeyImpl: public Poco::RefCountedObject +class RSAKeyImpl: public KeyPairImpl /// class RSAKeyImpl { public: typedef Poco::AutoPtr Ptr; typedef std::vector ByteVec; - explicit RSAKeyImpl(const X509Certificate& cert); + RSAKeyImpl() = delete; + + RSAKeyImpl(const EVPPKey& key); + /// Constructs ECKeyImpl by extracting the EC key. + + RSAKeyImpl(const X509Certificate& cert); /// Extracts the RSA public key from the given certificate. + RSAKeyImpl(const PKCS12Container& cert); + /// Extracts the EC private key from the given certificate. + RSAKeyImpl(int keyLength, unsigned long exponent); /// Creates the RSAKey. Creates a new public/private keypair using the given parameters. /// Can be used to sign data and verify signatures. @@ -99,12 +110,9 @@ public: private: void freeRSA(); - static ByteVec convertToByteVec(const BIGNUM* bn); -private: RSA* _pRSA; - OpenSSLInitializer _openSSLInitializer; }; @@ -126,4 +134,4 @@ inline const RSA* RSAKeyImpl::getRSA() const } } // namespace Poco::Crypto -#endif // Crypto_RSAKeyImplImpl_INCLUDED +#endif // Crypto_RSAKeyImplImpl_INCLUDED \ No newline at end of file diff --git a/Crypto/src/EVPPKey.cpp b/Crypto/src/EVPPKey.cpp index 58aae6ed8..7490a07a5 100644 --- a/Crypto/src/EVPPKey.cpp +++ b/Crypto/src/EVPPKey.cpp @@ -21,7 +21,7 @@ namespace Poco { namespace Crypto { - EVPPKey::EVPPKey(const std::string& ecCurveName): _pEVPPKey(0) +EVPPKey::EVPPKey(const std::string& ecCurveName): _pEVPPKey(0) { newECKey(ecCurveName.c_str()); } diff --git a/Crypto/src/RSAKey.cpp b/Crypto/src/RSAKey.cpp index f3c9026df..b81a0281b 100644 --- a/Crypto/src/RSAKey.cpp +++ b/Crypto/src/RSAKey.cpp @@ -20,31 +20,44 @@ namespace Poco { namespace Crypto { +RSAKey::RSAKey(const EVPPKey& key): + KeyPair(new RSAKeyImpl(key)), + _pImpl(KeyPair::impl().cast()) +{ +} + + RSAKey::RSAKey(const X509Certificate& cert): - _pImpl(new RSAKeyImpl(cert)) + KeyPair(new RSAKeyImpl(cert)), + _pImpl(KeyPair::impl().cast()) +{ +} + + +RSAKey::RSAKey(const PKCS12Container& cont): + KeyPair(new RSAKeyImpl(cont)), + _pImpl(KeyPair::impl().cast()) { } RSAKey::RSAKey(KeyLength keyLength, Exponent exp): - _pImpl(0) + KeyPair(new RSAKeyImpl(keyLength, (exp == EXP_LARGE) ? RSA_F4 : RSA_3)), + _pImpl(KeyPair::impl().cast()) { - int keyLen = keyLength; - unsigned long expVal = RSA_3; - if (exp == EXP_LARGE) - expVal = RSA_F4; - _pImpl = new RSAKeyImpl(keyLen, expVal); } RSAKey::RSAKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase): - _pImpl(new RSAKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)) + KeyPair(new RSAKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)), + _pImpl(KeyPair::impl().cast()) { } RSAKey::RSAKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase): - _pImpl(new RSAKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)) + KeyPair(new RSAKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)), + _pImpl(KeyPair::impl().cast()) { } @@ -53,13 +66,6 @@ RSAKey::~RSAKey() { } - -int RSAKey::size() const -{ - return _pImpl->size(); -} - - RSAKeyImpl::ByteVec RSAKey::modulus() const { return _pImpl->modulus(); @@ -78,28 +84,4 @@ RSAKeyImpl::ByteVec RSAKey::decryptionExponent() const } -void RSAKey::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase) -{ - _pImpl->save(publicKeyFile, privateKeyFile, privateKeyPassphrase); -} - - -void RSAKey::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream, const std::string& privateKeyPassphrase) -{ - _pImpl->save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase); -} - - -namespace -{ - static const std::string RSA("rsa"); -} - - -const std::string& RSAKey::name() const -{ - return RSA; -} - - -} } // namespace Poco::Crypto +} } // namespace Poco::Crypto \ No newline at end of file diff --git a/Crypto/src/RSAKeyImpl.cpp b/Crypto/src/RSAKeyImpl.cpp index cc86b3038..bb1513b33 100644 --- a/Crypto/src/RSAKeyImpl.cpp +++ b/Crypto/src/RSAKeyImpl.cpp @@ -14,6 +14,7 @@ #include "Poco/Crypto/RSAKeyImpl.h" #include "Poco/Crypto/X509Certificate.h" +#include "Poco/Crypto/PKCS12Container.h" #include "Poco/FileStream.h" #include "Poco/StreamCopier.h" #include @@ -29,17 +30,40 @@ namespace Poco { namespace Crypto { +RSAKeyImpl::RSAKeyImpl(const EVPPKey& key): + KeyPairImpl("rsa", KT_EC_IMPL), + _pRSA(EVP_PKEY_get1_RSA(const_cast((const EVP_PKEY*)key))) +{ + if (!_pRSA) throw OpenSSLException(); +} + + RSAKeyImpl::RSAKeyImpl(const X509Certificate& cert): + KeyPairImpl("rsa", KT_RSA_IMPL), _pRSA(0) { const X509* pCert = cert.certificate(); EVP_PKEY* pKey = X509_get_pubkey(const_cast(pCert)); - _pRSA = EVP_PKEY_get1_RSA(pKey); - EVP_PKEY_free(pKey); + if (pKey) + { + _pRSA = EVP_PKEY_get1_RSA(pKey); + EVP_PKEY_free(pKey); + } + else + throw OpenSSLException("RSAKeyImpl(const X509Certificate&)"); } -RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent): +RSAKeyImpl::RSAKeyImpl(const PKCS12Container& cont): + KeyPairImpl("ec", KT_EC_IMPL), + _pRSA(0) +{ + EVPPKey key = cont.getKey(); + _pRSA = EVP_PKEY_get1_RSA(key); +} + + +RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent): KeyPairImpl("rsa", KT_RSA_IMPL), _pRSA(0) { #if OPENSSL_VERSION_NUMBER >= 0x00908000L @@ -66,11 +90,10 @@ RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent): } -RSAKeyImpl::RSAKeyImpl( - const std::string& publicKeyFile, - const std::string& privateKeyFile, - const std::string& privateKeyPassphrase): - _pRSA(0) +RSAKeyImpl::RSAKeyImpl(const std::string& publicKeyFile, + const std::string& privateKeyFile, + const std::string& privateKeyPassphrase): KeyPairImpl("rsa", KT_RSA_IMPL), + _pRSA(0) { poco_assert_dbg(_pRSA == 0); @@ -133,8 +156,10 @@ RSAKeyImpl::RSAKeyImpl( } -RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase): - _pRSA(0) +RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, + std::istream* pPrivateKeyStream, + const std::string& privateKeyPassphrase): KeyPairImpl("rsa", KT_RSA_IMPL), + _pRSA(0) { poco_assert_dbg(_pRSA == 0); @@ -191,8 +216,7 @@ RSAKeyImpl::~RSAKeyImpl() void RSAKeyImpl::freeRSA() { - if (_pRSA) - RSA_free(_pRSA); + if (_pRSA) RSA_free(_pRSA); _pRSA = 0; } @@ -245,7 +269,9 @@ RSAKeyImpl::ByteVec RSAKeyImpl::decryptionExponent() const } -void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase) +void RSAKeyImpl::save(const std::string& publicKeyFile, + const std::string& privateKeyFile, + const std::string& privateKeyPassphrase) { if (!publicKeyFile.empty()) { @@ -297,7 +323,9 @@ void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& priva } -void RSAKeyImpl::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream, const std::string& privateKeyPassphrase) +void RSAKeyImpl::save(std::ostream* pPublicKeyStream, + std::ostream* pPrivateKeyStream, + const std::string& privateKeyPassphrase) { if (pPublicKeyStream) { @@ -355,4 +383,4 @@ RSAKeyImpl::ByteVec RSAKeyImpl::convertToByteVec(const BIGNUM* bn) } -} } // namespace Poco::Crypto +} } // namespace Poco::Crypto \ No newline at end of file diff --git a/Crypto/testsuite/src/PKCS12ContainerTest.cpp b/Crypto/testsuite/src/PKCS12ContainerTest.cpp index c7f20324f..cdf12e446 100644 --- a/Crypto/testsuite/src/PKCS12ContainerTest.cpp +++ b/Crypto/testsuite/src/PKCS12ContainerTest.cpp @@ -21,8 +21,7 @@ #include -using Poco::Crypto::PKCS12Container; -using Poco::Crypto::X509Certificate; +using namespace Poco::Crypto; using Poco::Environment; using Poco::Path; using Poco::File; @@ -61,6 +60,9 @@ void PKCS12ContainerTest::full(const PKCS12Container& pkcs12) assert ("vally" == pkcs12.getFriendlyName()); assert (pkcs12.hasKey()); + EVPPKey pKey = pkcs12.getKey(); + assert (EVP_PKEY_RSA == pKey.type()); + assert (pkcs12.hasX509Certificate()); X509Certificate x509 = pkcs12.getX509Certificate(); diff --git a/openssl b/openssl index 630760b13..6dc14894c 160000 --- a/openssl +++ b/openssl @@ -1 +1 @@ -Subproject commit 630760b132854c0227ffe1084f4802ace2c81a22 +Subproject commit 6dc14894cb5cb32d8079acca9cd7d2853ba425da