mirror of
				https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
				synced 2025-10-31 18:47:47 +00:00 
			
		
		
		
	integrated changes from 1.3.5
This commit is contained in:
		| @@ -1,10 +1,10 @@ | ||||
| // | ||||
| // RSAKeyImpl.cpp | ||||
| // | ||||
| // $Id: //poco/Main/Crypto/src/RSAKeyImpl.cpp#2 $ | ||||
| // $Id: //poco/Main/Crypto/src/RSAKeyImpl.cpp#3 $ | ||||
| // | ||||
| // Library: Crypto | ||||
| // Package: CryptoCore | ||||
| // Package: RSA | ||||
| // Module:  RSAKeyImpl | ||||
| // | ||||
| // Copyright (c) 2008, Applied Informatics Software Engineering GmbH. | ||||
| @@ -35,11 +35,10 @@ | ||||
|  | ||||
|  | ||||
| #include "Poco/Crypto/RSAKeyImpl.h" | ||||
| #include "Poco/Crypto/X509Certificate.h" | ||||
| #include "Poco/FileStream.h" | ||||
| #include "Poco/StreamCopier.h" | ||||
| #include "Poco/TemporaryFile.h" | ||||
| #include "Poco/Net/SSLManager.h" | ||||
| #include "Poco/Net/X509Certificate.h" | ||||
| #include <openssl/pem.h> | ||||
| #include <openssl/rsa.h> | ||||
|  | ||||
| @@ -48,7 +47,7 @@ namespace Poco { | ||||
| namespace Crypto { | ||||
|  | ||||
|  | ||||
| RSAKeyImpl::RSAKeyImpl(const Poco::Net::X509Certificate& cert): | ||||
| RSAKeyImpl::RSAKeyImpl(const X509Certificate& cert): | ||||
| 	_pRSA(0) | ||||
| { | ||||
| 	const X509* pCert = cert.certificate(); | ||||
| @@ -62,11 +61,10 @@ RSAKeyImpl::RSAKeyImpl(const Poco::Net::X509Certificate& cert): | ||||
| RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent): | ||||
| 	_pRSA(0) | ||||
| { | ||||
| 	//dummy access to SSLMananger so that the SSLInitializer of NetSSL gets called! | ||||
| 	Poco::Net::SSLManager::instance(); | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x00908000L | ||||
| 	_pRSA = RSA_new(); | ||||
| 	int ret = 0; | ||||
| 	BIGNUM *bn = 0; | ||||
| 	BIGNUM* bn = 0; | ||||
| 	try | ||||
| 	{ | ||||
| 		bn = BN_new(); | ||||
| @@ -74,109 +72,108 @@ RSAKeyImpl::RSAKeyImpl(int keyLength, unsigned long exponent): | ||||
| 		ret = RSA_generate_key_ex(_pRSA, keyLength, bn, 0); | ||||
| 		BN_free(bn); | ||||
| 	} | ||||
| 	catch(...) | ||||
| 	catch (...) | ||||
| 	{ | ||||
| 		BN_free(bn); | ||||
| 		throw; | ||||
| 	} | ||||
| 	if (!ret) | ||||
| 		throw Poco::InvalidArgumentException("Failed to create RSA context"); | ||||
| 	if (!ret) throw Poco::InvalidArgumentException("Failed to create RSA context"); | ||||
| #else | ||||
| 	_pRSA = RSA_generate_key(keyLength, exponent, 0, 0); | ||||
| 	if (!_pRSA) throw Poco::InvalidArgumentException("Failed to create RSA context"); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| RSAKeyImpl::RSAKeyImpl( | ||||
| 		const std::string& publicKey,  | ||||
| 		const std::string& publicKeyFile,  | ||||
| 		const std::string& privateKeyFile,  | ||||
| 		const std::string& privateKeyPwd): | ||||
| 		const std::string& privateKeyPassphrase): | ||||
| 	_pRSA(0) | ||||
| { | ||||
| 	//dummy access to SSLMananger so that the SSLInitializer of NetSSL gets called! | ||||
| 	Poco::Net::SSLManager::instance(); | ||||
| 	init(publicKey, privateKeyFile, privateKeyPwd); | ||||
| 	init(publicKeyFile, privateKeyFile, privateKeyPassphrase); | ||||
| } | ||||
|  | ||||
|  | ||||
| RSAKeyImpl::RSAKeyImpl(std::istream* pubKey, std::istream* privKey, const std::string& privKeyPwd): | ||||
| RSAKeyImpl::RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase): | ||||
| 	_pRSA(0) | ||||
| { | ||||
| 	//dummy access to SSLMananger so that the SSLInitializer of NetSSL gets called! | ||||
| 	Poco::Net::SSLManager::instance(); | ||||
| 	// due to C lib not supporting streams, we create two temporary files | ||||
| 	std::string pubKeyFile; | ||||
| 	std::string publicKeyFile; | ||||
| 	Poco::TemporaryFile pubFile; | ||||
| 	if (pubKey) | ||||
| 	if (pPublicKeyStream) | ||||
| 	{ | ||||
| 		if (!pubFile.createFile()) | ||||
| 			throw Poco::FileException("No temporary file could be created for public file!"); | ||||
| 		pubKeyFile = pubFile.path(); | ||||
| 		Poco::FileOutputStream fout(pubKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(*pubKey, fout); | ||||
| 			throw Poco::CreateFileException("Cannot create temporary file for writing public key"); | ||||
| 		publicKeyFile = pubFile.path(); | ||||
| 		Poco::FileOutputStream fout(publicKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(*pPublicKeyStream, fout); | ||||
| 	} | ||||
| 	std::string privKeyFile; | ||||
| 	std::string privateKeyFile; | ||||
| 	Poco::TemporaryFile privFile; | ||||
| 	if (privKey) | ||||
| 	if (pPrivateKeyStream) | ||||
| 	{ | ||||
| 		if (!privFile.createFile()) | ||||
| 			throw Poco::FileException("No temporary file could be created for private file!"); | ||||
| 		privKeyFile = privFile.path(); | ||||
| 		Poco::FileOutputStream fout(privKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(*privKey, fout); | ||||
| 			throw Poco::CreateFileException("Cannot create temporary file for writing private key"); | ||||
| 		privateKeyFile = privFile.path(); | ||||
| 		Poco::FileOutputStream fout(privateKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(*pPrivateKeyStream, fout); | ||||
|  | ||||
| 	} | ||||
| 	init(pubKeyFile, privKeyFile, privKeyPwd); | ||||
| 	init(publicKeyFile, privateKeyFile, privateKeyPassphrase); | ||||
| } | ||||
|  | ||||
|  | ||||
| void RSAKeyImpl::init(const std::string& pubKeyFile, const std::string& privKeyFile, const std::string& privKeyPwd) | ||||
| void RSAKeyImpl::init(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase) | ||||
| { | ||||
| 	poco_assert_dbg(_pRSA == 0); | ||||
| 	 | ||||
| 	_pRSA = RSA_new(); | ||||
| 	if (!pubKeyFile.empty()) | ||||
| 	if (!publicKeyFile.empty()) | ||||
| 	{ | ||||
| 		BIO *out=BIO_new(BIO_s_file()); | ||||
| 		const char* pFN = pubKeyFile.c_str(); | ||||
| 		BIO_read_filename(out, (void*)pFN); | ||||
| 		if (out) | ||||
| 		BIO* out = BIO_new(BIO_s_file()); | ||||
| 		if (!out) throw Poco::IOException("Cannot create BIO for reading public key", publicKeyFile); | ||||
| 		int rc = BIO_read_filename(out, publicKeyFile.c_str()); | ||||
| 		if (rc) | ||||
| 		{ | ||||
| 			RSA* pubKey = PEM_read_bio_RSAPublicKey(out, &_pRSA, 0, 0); | ||||
| 			BIO_free(out); | ||||
| 			if (!pubKey) | ||||
| 			{ | ||||
| 				freeRSA(); | ||||
| 				throw Poco::FileException("Failed to load public key: " + pubKeyFile); | ||||
| 				throw Poco::FileException("Failed to load public key", publicKeyFile); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			freeRSA(); | ||||
| 			throw Poco::FileNotFoundException("Public key file not found: " + pubKeyFile); | ||||
| 			throw Poco::FileNotFoundException("Public key file", publicKeyFile); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!privKeyFile.empty()) | ||||
| 	if (!privateKeyFile.empty()) | ||||
| 	{ | ||||
| 		BIO* out=BIO_new(BIO_s_file()); | ||||
| 		const char* pFN = privKeyFile.c_str(); | ||||
| 		BIO_read_filename(out, (void*)pFN); | ||||
| 		 | ||||
| 		if (out) | ||||
| 		BIO* out = BIO_new(BIO_s_file()); | ||||
| 		if (!out) throw Poco::IOException("Cannot create BIO for reading private key", privateKeyFile); | ||||
| 		int rc = BIO_read_filename(out, privateKeyFile.c_str()); | ||||
| 		if (rc) | ||||
| 		{ | ||||
| 			RSA* privKey = 0; | ||||
| 			if (privKeyPwd.empty()) | ||||
| 			if (privateKeyPassphrase.empty()) | ||||
| 				privKey = PEM_read_bio_RSAPrivateKey(out, &_pRSA, 0, 0); | ||||
| 			else | ||||
| 				privKey = PEM_read_bio_RSAPrivateKey(out, &_pRSA, 0, (void*)privKeyPwd.c_str()); | ||||
| 				privKey = PEM_read_bio_RSAPrivateKey(out, &_pRSA, 0, const_cast<char*>(privateKeyPassphrase.c_str())); | ||||
| 			BIO_free(out); | ||||
| 			if (!privKey) | ||||
| 			{ | ||||
| 				freeRSA(); | ||||
| 				throw Poco::FileException("Failed to load private key: " + privKeyFile); | ||||
| 				throw Poco::FileException("Failed to load private key", privateKeyFile); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			freeRSA(); | ||||
| 			throw Poco::FileNotFoundException("Private key file not found: " + privKeyFile); | ||||
| 			throw Poco::FileNotFoundException("Private key file", privateKeyFile); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -184,6 +181,7 @@ void RSAKeyImpl::init(const std::string& pubKeyFile, const std::string& privKeyF | ||||
|  | ||||
| RSAKeyImpl::~RSAKeyImpl() | ||||
| { | ||||
| 	freeRSA(); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -201,70 +199,91 @@ int RSAKeyImpl::size() const | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void RSAKeyImpl::save(const std::string& pubKeyFile, const std::string& privKeyFile, const std::string& privKeyPwd) | ||||
| void RSAKeyImpl::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase) | ||||
| { | ||||
| 	if (!pubKeyFile.empty()) | ||||
| 	if (!publicKeyFile.empty()) | ||||
| 	{ | ||||
| 		BIO *out=BIO_new(BIO_s_file()); | ||||
| 		const char* pFN = pubKeyFile.c_str(); | ||||
| 		BIO_write_filename(out, (void*)pFN); | ||||
| 		if (!PEM_write_bio_RSAPublicKey(out,_pRSA)) | ||||
| 			throw Poco::FileException("Failed to write public key to file:" + pubKeyFile); | ||||
| 		BIO* out = BIO_new(BIO_s_file()); | ||||
| 		if (!out) throw Poco::IOException("Cannot create BIO for writing public key file", publicKeyFile); | ||||
| 		try | ||||
| 		{ | ||||
| 			if (BIO_write_filename(out, const_cast<char*>(publicKeyFile.c_str()))) | ||||
| 			{ | ||||
| 				if (!PEM_write_bio_RSAPublicKey(out, _pRSA)) | ||||
| 					throw Poco::WriteFileException("Failed to write public key to file", publicKeyFile); | ||||
| 			} | ||||
| 			else throw Poco::CreateFileException("Cannot create public key file"); | ||||
| 		} | ||||
| 		catch (...) | ||||
| 		{ | ||||
| 			BIO_free(out); | ||||
| 			throw; | ||||
| 		} | ||||
| 		BIO_free(out); | ||||
| 	} | ||||
| 	if (!privKeyFile.empty()) | ||||
| 	 | ||||
| 	if (!privateKeyFile.empty()) | ||||
| 	{ | ||||
| 		BIO *out=BIO_new(BIO_s_file()); | ||||
| 		const char* pFN = privKeyFile.c_str(); | ||||
| 		BIO_write_filename(out, (void*)pFN); | ||||
|  | ||||
| 		int ret = 0; | ||||
| 		if (privKeyPwd.empty()) | ||||
| 			ret = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0); | ||||
| 		else | ||||
| 			ret = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(), (unsigned char *)privKeyPwd.c_str(), privKeyPwd.length(), 0, 0); | ||||
|  | ||||
| 		if (!ret) | ||||
| 			throw Poco::FileException("Failed to write private key to file:" + privKeyFile); | ||||
| 		BIO* out = BIO_new(BIO_s_file()); | ||||
| 		if (!out) throw Poco::IOException("Cannot create BIO for writing private key file", privateKeyFile); | ||||
| 		try | ||||
| 		{ | ||||
| 			if (BIO_write_filename(out, const_cast<char*>(privateKeyFile.c_str()))) | ||||
| 			{ | ||||
| 				int rc = 0; | ||||
| 				if (privateKeyPassphrase.empty()) | ||||
| 					rc = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(), 0, 0, 0, 0); | ||||
| 				else | ||||
| 					rc = PEM_write_bio_RSAPrivateKey(out, _pRSA, EVP_des_ede3_cbc(),  | ||||
| 						reinterpret_cast<unsigned char*>(const_cast<char*>(privateKeyPassphrase.c_str())),  | ||||
| 						static_cast<int>(privateKeyPassphrase.length()), 0, 0); | ||||
| 				if (!rc) throw Poco::FileException("Failed to write private key to file", privateKeyFile); | ||||
| 			} | ||||
| 			else throw Poco::CreateFileException("Cannot create private key file", privateKeyFile); | ||||
| 		} | ||||
| 		catch (...) | ||||
| 		{ | ||||
| 			BIO_free(out); | ||||
| 			throw; | ||||
| 		} | ||||
| 		BIO_free(out); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| void RSAKeyImpl::save(std::ostream* pPubKey, std::ostream* pPrivKey, const std::string& privateKeyPwd) | ||||
| void RSAKeyImpl::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream, const std::string& privateKeyPassphrase) | ||||
| { | ||||
| 	if (!pPubKey && !pPrivKey) | ||||
| 		return; | ||||
| 	if (!pPublicKeyStream && !pPrivateKeyStream) return; | ||||
| 	 | ||||
| 	// due to C lib not supporting streams, we create two temporary files | ||||
| 	std::string pubKeyFile; | ||||
| 	std::string publicKeyFile; | ||||
| 	Poco::TemporaryFile pubFile; | ||||
| 	if (pPubKey) | ||||
| 	if (pPublicKeyStream) | ||||
| 	{ | ||||
| 		pubKeyFile = pubFile.path(); | ||||
| 		publicKeyFile = pubFile.path(); | ||||
| 		if (!pubFile.createFile()) | ||||
| 			throw Poco::FileException("No temporary file could be created for public file!"); | ||||
| 			throw Poco::CreateFileException("Cannot create temporary public file"); | ||||
| 	} | ||||
| 	std::string privKeyFile; | ||||
| 	std::string privateKeyFile; | ||||
| 	Poco::TemporaryFile privFile; | ||||
| 	if (pPrivKey) | ||||
| 	if (pPrivateKeyStream) | ||||
| 	{ | ||||
| 		privateKeyFile = privFile.path(); | ||||
| 		if (!privFile.createFile()) | ||||
| 			throw Poco::FileException("No temporary file could be created for private file!"); | ||||
| 		privKeyFile = privFile.path(); | ||||
| 			throw Poco::FileException("Cannot crate temporary private key file"); | ||||
| 	} | ||||
| 	save(pubKeyFile, privKeyFile, privateKeyPwd); | ||||
| 	save(publicKeyFile, privateKeyFile, privateKeyPassphrase); | ||||
| 	 | ||||
| 	// now copy everything from the temp files to the original streams | ||||
| 	if (pPubKey) | ||||
| 	if (pPublicKeyStream) | ||||
| 	{ | ||||
| 		Poco::FileInputStream fPub(pubKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(fPub, *pPubKey); | ||||
| 		Poco::FileInputStream istr(publicKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(istr, *pPublicKeyStream); | ||||
| 	} | ||||
| 	if (pPrivKey) | ||||
| 	if (pPrivateKeyStream) | ||||
| 	{ | ||||
| 		Poco::FileInputStream fPriv(privKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(fPriv, *pPrivKey); | ||||
| 		Poco::FileInputStream istr(privateKeyFile); | ||||
| 		Poco::StreamCopier::copyStream(istr, *pPrivateKeyStream); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Guenter Obiltschnig
					Guenter Obiltschnig