mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-23 08:31:43 +02:00 
			
		
		
		
	Netssl/openssl3 (#3575)
* feat(Context): DH init openssl3 port (1/2 hardcoded params) * create poco-1.11.3 branch, bump version * update copyright date * #3567: check legacy provider existence for legacy exception #3567 * fix(Placeholder): comparison for zero value * feat(Context): DH init openssl3 port (2/2 params from file) * test(HTTPSClientSession): try/catch to understand CI failure * chore(cmake): copy the DH parameters file * fix(OpenSSLInitializer): unload provider on uninitialize * chore(HTTPSClientSessionTest): remove try/catch * fix(OpenSSLInitializer): fix provider unloading * feat(CppUnit): make tests exceptions more descriptive * chore(CppUnit): a more descriptive name for callback Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>
This commit is contained in:
		 Aleksandar Fabijanic
					Aleksandar Fabijanic
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							4dfbcd33db
						
					
				
				
					commit
					7db9831f32
				
			| @@ -20,10 +20,17 @@ | ||||
| #include "Poco/File.h" | ||||
| #include "Poco/Path.h" | ||||
| #include "Poco/Timestamp.h" | ||||
| #include "Poco/Format.h" | ||||
| #include "Poco/Error.h" | ||||
| #include <openssl/bio.h> | ||||
| #include <openssl/err.h> | ||||
| #include <openssl/ssl.h> | ||||
| #include <openssl/x509v3.h> | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
| #include <openssl/core_names.h> | ||||
| #include <openssl/decoder.h> | ||||
| #endif // OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
| #include <iostream> | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
| @@ -727,6 +734,110 @@ void Context::initDH(bool use2048Bits, const std::string& dhParamsFile) | ||||
| 		0x6C,0xC4,0x16,0x59, | ||||
| 	}; | ||||
|  | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
|  | ||||
| 	EVP_PKEY_CTX* pKeyCtx = NULL; | ||||
| 	OSSL_DECODER_CTX* pOSSLDecodeCtx = NULL; | ||||
| 	EVP_PKEY* pKey = NULL; | ||||
| 	bool freeEVPPKey = true; | ||||
| 	if (!dhParamsFile.empty()) | ||||
| 	{ | ||||
| 		freeEVPPKey = false; | ||||
| 		pOSSLDecodeCtx = OSSL_DECODER_CTX_new_for_pkey(&pKey, NULL, NULL, "DH", | ||||
| 				OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, NULL, NULL); | ||||
|  | ||||
| 		if (!pOSSLDecodeCtx) | ||||
| 		{ | ||||
| 			std::string err = Poco::format( | ||||
| 					"Context::initDH(%s):OSSL_DECODER_CTX_new_for_pkey():OSSL_DECODER_CTX*\n", dhParamsFile); | ||||
| 			throw Poco::NullPointerException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
|  | ||||
| 		if (!OSSL_DECODER_CTX_get_num_decoders(pOSSLDecodeCtx)) | ||||
| 		{ | ||||
| 			OSSL_DECODER_CTX_free(pOSSLDecodeCtx); | ||||
| 			throw Poco::Crypto::OpenSSLException( | ||||
| 				Poco::format("Context::initDH(%s):OSSL_DECODER_CTX_get_num_decoders()=0", | ||||
| 					dhParamsFile)); | ||||
| 		} | ||||
|  | ||||
| 		FILE* pFile = fopen(dhParamsFile.c_str(), "r"); | ||||
| 		if (!pFile) | ||||
| 		{ | ||||
| 			OSSL_DECODER_CTX_free(pOSSLDecodeCtx); | ||||
| 			throw Poco::NullPointerException( | ||||
| 				Poco::format("Context::initDH(%s):fopen()\n%s", | ||||
| 					dhParamsFile, Poco::Error::getMessage(Poco::Error::last()))); | ||||
| 		} | ||||
|  | ||||
| 		if (!OSSL_DECODER_from_fp(pOSSLDecodeCtx, pFile)) | ||||
| 		{ | ||||
| 			fclose(pFile); | ||||
| 			OSSL_DECODER_CTX_free(pOSSLDecodeCtx); | ||||
| 			std::string err = Poco::format( | ||||
| 					"Context::initDH(%s):OSSL_DECODER_from_fp()\n%s", dhParamsFile); | ||||
| 			throw Poco::Crypto::OpenSSLException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
| 		fclose(pFile); | ||||
| 		OSSL_DECODER_CTX_free(pOSSLDecodeCtx); | ||||
|  | ||||
| 		if (!pKey) | ||||
| 		{ | ||||
| 			std::string err = Poco::format( | ||||
| 					"Context::initDH(%s):OSSL_DECODER_CTX_new_for_pkey():EVP_PKEY*\n", dhParamsFile); | ||||
| 			throw Poco::NullPointerException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		pKeyCtx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); | ||||
| 		if (!pKeyCtx) | ||||
| 		{ | ||||
| 			std::string err = "Context::initDH():EVP_PKEY_CTX_new_from_name()\n"; | ||||
| 			throw Poco::NullPointerException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
|  | ||||
| 		size_t keyLength = use2048Bits ? 256 : 160; | ||||
| 		unsigned char* pDH_p = const_cast<unsigned char*>(use2048Bits ? dh2048_p : dh1024_p); | ||||
| 		std::size_t sz_p = use2048Bits ? sizeof(dh2048_p) : sizeof(dh1024_p); | ||||
| 		unsigned char* pDH_g = const_cast<unsigned char*>(use2048Bits ? dh2048_g : dh1024_g); | ||||
| 		std::size_t sz_g = use2048Bits ? sizeof(dh2048_g) : sizeof(dh1024_g); | ||||
| 		OSSL_PARAM params[] | ||||
| 		{ | ||||
| 			OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &keyLength), | ||||
| 			OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, pDH_p, sz_p), | ||||
| 			OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, pDH_g, sz_g), | ||||
| 			OSSL_PARAM_END | ||||
| 		}; | ||||
|  | ||||
| 		if (1 != EVP_PKEY_fromdata_init(pKeyCtx)) | ||||
| 		{ | ||||
| 			EVP_PKEY_CTX_free(pKeyCtx); | ||||
| 			std::string err = "Context::initDH():EVP_PKEY_fromdata_init()\n"; | ||||
| 			throw SSLContextException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
|  | ||||
| 		if (1 != EVP_PKEY_fromdata(pKeyCtx, &pKey, EVP_PKEY_KEYPAIR, params)) | ||||
| 		{ | ||||
| 			EVP_PKEY_CTX_free(pKeyCtx); | ||||
| 			std::string err = "Context::initDH():EVP_PKEY_fromdata()\n"; | ||||
| 			throw SSLContextException(Poco::Crypto::getError(err)); | ||||
| 		} | ||||
| 		EVP_PKEY_CTX_free(pKeyCtx); | ||||
| 	} | ||||
|  | ||||
| 	if (!pKey) | ||||
| 	{ | ||||
| 		throw SSLContextException(Poco::format("Context::initDH(%s):EVP_PKEY*", dhParamsFile)); | ||||
| 	} | ||||
|  | ||||
| 	SSL_CTX_set0_tmp_dh_pkey(_pSSLContext, pKey); | ||||
| 	SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_DH_USE); | ||||
|  | ||||
| 	if (freeEVPPKey) EVP_PKEY_free(pKey); | ||||
|  | ||||
| #else // OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
|  | ||||
| 	DH* dh = 0; | ||||
| 	if (!dhParamsFile.empty()) | ||||
| 	{ | ||||
| @@ -752,7 +863,9 @@ void Context::initDH(bool use2048Bits, const std::string& dhParamsFile) | ||||
| 			std::string msg = Utility::getLastError(); | ||||
| 			throw SSLContextException("Error creating Diffie-Hellman parameters", msg); | ||||
| 		} | ||||
|  | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) | ||||
|  | ||||
| 		BIGNUM* p = nullptr; | ||||
| 		BIGNUM* g = nullptr; | ||||
| 		if (use2048Bits) | ||||
| @@ -774,7 +887,9 @@ void Context::initDH(bool use2048Bits, const std::string& dhParamsFile) | ||||
| 			DH_free(dh); | ||||
| 			throw SSLContextException("Error creating Diffie-Hellman parameters"); | ||||
| 		} | ||||
| #else | ||||
|  | ||||
| #else // OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) | ||||
|  | ||||
| 		if (use2048Bits) | ||||
| 		{ | ||||
| 			dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), 0); | ||||
| @@ -792,15 +907,23 @@ void Context::initDH(bool use2048Bits, const std::string& dhParamsFile) | ||||
| 			DH_free(dh); | ||||
| 			throw SSLContextException("Error creating Diffie-Hellman parameters"); | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) | ||||
|  | ||||
| 	} | ||||
| 	SSL_CTX_set_tmp_dh(_pSSLContext, dh); | ||||
| 	SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_DH_USE); | ||||
| 	DH_free(dh); | ||||
| #else | ||||
|  | ||||
| #endif // OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
|  | ||||
| #else // OPENSSL_NO_DH | ||||
|  | ||||
| 	if (!dhParamsFile.empty()) | ||||
| 		throw SSLContextException("OpenSSL does not support DH"); | ||||
| #endif | ||||
| 		throw SSLContextException("Implementation does not support DH"); | ||||
|  | ||||
| #endif // OPENSSL_NO_DH | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include "Poco/Net/Utility.h" | ||||
| #include "Poco/String.h" | ||||
| #include "Poco/Util/OptionException.h" | ||||
| #include "Poco/Crypto/Crypto.h" | ||||
| #include <openssl/err.h> | ||||
|  | ||||
|  | ||||
| @@ -51,14 +52,9 @@ std::string Utility::convertCertificateError(long errCode) | ||||
|  | ||||
| std::string Utility::getLastError() | ||||
| { | ||||
| 	unsigned long errCode = ERR_get_error(); | ||||
| 	if (errCode != 0) | ||||
| 	{ | ||||
| 		char buffer[256]; | ||||
| 		ERR_error_string_n(errCode, buffer, sizeof(buffer)); | ||||
| 		return std::string(buffer); | ||||
| 	} | ||||
| 	else return "No error"; | ||||
| 	std::string msg; | ||||
| 	Poco::Crypto::getError(msg); | ||||
| 	return msg; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user