mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-06-20 17:17:13 +02:00
Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface. Deprecated the external module API. It was creating more problems than solving. Removed most built-in libraries in favor of system libraries for easier maintenance. Cleaned and secured code with help from static analyzers.
This commit is contained in:
38
vendor/POCO/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp
vendored
Normal file
38
vendor/POCO/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// AcceptCertificateHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: AcceptCertificateHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/AcceptCertificateHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
AcceptCertificateHandler::AcceptCertificateHandler(bool server): InvalidCertificateHandler(server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AcceptCertificateHandler::~AcceptCertificateHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void AcceptCertificateHandler::onInvalidCertificate(const void*, VerificationErrorArgs& errorCert)
|
||||
{
|
||||
errorCert.setIgnoreError(true);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
44
vendor/POCO/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp
vendored
Normal file
44
vendor/POCO/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// CertificateHandlerFactory.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: CertificateHandlerFactory
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/CertificateHandlerFactory.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
CertificateHandlerFactory::CertificateHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CertificateHandlerFactory::~CertificateHandlerFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CertificateHandlerFactoryRegistrar::CertificateHandlerFactoryRegistrar(const std::string& name, CertificateHandlerFactory* pFactory)
|
||||
{
|
||||
SSLManager::instance().certificateHandlerFactoryMgr().setFactory(name, pFactory);
|
||||
}
|
||||
|
||||
|
||||
CertificateHandlerFactoryRegistrar::~CertificateHandlerFactoryRegistrar()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
69
vendor/POCO/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp
vendored
Normal file
69
vendor/POCO/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// CertificateHandlerFactoryMgr.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: CertificateHandlerFactoryMgr
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/CertificateHandlerFactoryMgr.h"
|
||||
#include "Poco/Net/ConsoleCertificateHandler.h"
|
||||
#include "Poco/Net/AcceptCertificateHandler.h"
|
||||
#include "Poco/Net/RejectCertificateHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
CertificateHandlerFactoryMgr::CertificateHandlerFactoryMgr()
|
||||
{
|
||||
setFactory("ConsoleCertificateHandler", new CertificateHandlerFactoryImpl<ConsoleCertificateHandler>());
|
||||
setFactory("AcceptCertificateHandler", new CertificateHandlerFactoryImpl<AcceptCertificateHandler>());
|
||||
setFactory("RejectCertificateHandler", new CertificateHandlerFactoryImpl<RejectCertificateHandler>());
|
||||
}
|
||||
|
||||
|
||||
CertificateHandlerFactoryMgr::~CertificateHandlerFactoryMgr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CertificateHandlerFactoryMgr::setFactory(const std::string& name, CertificateHandlerFactory* pFactory)
|
||||
{
|
||||
bool success = _factories.insert(make_pair(name, Poco::SharedPtr<CertificateHandlerFactory>(pFactory))).second;
|
||||
if (!success)
|
||||
delete pFactory;
|
||||
poco_assert(success);
|
||||
}
|
||||
|
||||
|
||||
bool CertificateHandlerFactoryMgr::hasFactory(const std::string& name) const
|
||||
{
|
||||
return _factories.find(name) != _factories.end();
|
||||
}
|
||||
|
||||
|
||||
const CertificateHandlerFactory* CertificateHandlerFactoryMgr::getFactory(const std::string& name) const
|
||||
{
|
||||
FactoriesMap::const_iterator it = _factories.find(name);
|
||||
if (it != _factories.end())
|
||||
return it->second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CertificateHandlerFactoryMgr::removeFactory(const std::string& name)
|
||||
{
|
||||
_factories.erase(name);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
53
vendor/POCO/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp
vendored
Normal file
53
vendor/POCO/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// ConsoleCertificateHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: ConsoleCertificateHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/ConsoleCertificateHandler.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
ConsoleCertificateHandler::ConsoleCertificateHandler(bool server): InvalidCertificateHandler(server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ConsoleCertificateHandler::~ConsoleCertificateHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ConsoleCertificateHandler::onInvalidCertificate(const void*, VerificationErrorArgs& errorCert)
|
||||
{
|
||||
const X509Certificate& aCert = errorCert.certificate();
|
||||
std::cout << "\n";
|
||||
std::cout << "WARNING: Certificate verification failed\n";
|
||||
std::cout << "----------------------------------------\n";
|
||||
std::cout << "Issuer Name: " << aCert.issuerName() << "\n";
|
||||
std::cout << "Subject Name: " << aCert.subjectName() << "\n\n";
|
||||
std::cout << "The certificate yielded the error: " << errorCert.errorMessage() << "\n\n";
|
||||
std::cout << "The error occurred in the certificate chain at position " << errorCert.errorDepth() << "\n";
|
||||
std::cout << "Accept the certificate (y,n)? ";
|
||||
char c = 0;
|
||||
std::cin >> c;
|
||||
if (c == 'y' || c == 'Y')
|
||||
errorCert.setIgnoreError(true);
|
||||
else
|
||||
errorCert.setIgnoreError(false);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
819
vendor/POCO/NetSSL_OpenSSL/src/Context.cpp
vendored
Normal file
819
vendor/POCO/NetSSL_OpenSSL/src/Context.cpp
vendored
Normal file
@ -0,0 +1,819 @@
|
||||
//
|
||||
// Context.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: Context
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/Utility.h"
|
||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
Context::Params::Params():
|
||||
verificationMode(VERIFY_RELAXED),
|
||||
verificationDepth(9),
|
||||
loadDefaultCAs(false),
|
||||
cipherList("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"),
|
||||
dhUse2048Bits(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Context::Context(Usage usage, const Params& params):
|
||||
_usage(usage),
|
||||
_mode(params.verificationMode),
|
||||
_pSSLContext(0),
|
||||
_extendedCertificateVerification(true)
|
||||
{
|
||||
init(params);
|
||||
}
|
||||
|
||||
|
||||
Context::Context(
|
||||
Usage usage,
|
||||
const std::string& privateKeyFile,
|
||||
const std::string& certificateFile,
|
||||
const std::string& caLocation,
|
||||
VerificationMode verificationMode,
|
||||
int verificationDepth,
|
||||
bool loadDefaultCAs,
|
||||
const std::string& cipherList):
|
||||
_usage(usage),
|
||||
_mode(verificationMode),
|
||||
_pSSLContext(0),
|
||||
_extendedCertificateVerification(true)
|
||||
{
|
||||
Params params;
|
||||
params.privateKeyFile = privateKeyFile;
|
||||
params.certificateFile = certificateFile;
|
||||
params.caLocation = caLocation;
|
||||
params.verificationMode = verificationMode;
|
||||
params.verificationDepth = verificationDepth;
|
||||
params.loadDefaultCAs = loadDefaultCAs;
|
||||
params.cipherList = cipherList;
|
||||
init(params);
|
||||
}
|
||||
|
||||
|
||||
Context::Context(
|
||||
Usage usage,
|
||||
const std::string& caLocation,
|
||||
VerificationMode verificationMode,
|
||||
int verificationDepth,
|
||||
bool loadDefaultCAs,
|
||||
const std::string& cipherList):
|
||||
_usage(usage),
|
||||
_mode(verificationMode),
|
||||
_pSSLContext(0),
|
||||
_extendedCertificateVerification(true)
|
||||
{
|
||||
Params params;
|
||||
params.caLocation = caLocation;
|
||||
params.verificationMode = verificationMode;
|
||||
params.verificationDepth = verificationDepth;
|
||||
params.loadDefaultCAs = loadDefaultCAs;
|
||||
params.cipherList = cipherList;
|
||||
init(params);
|
||||
}
|
||||
|
||||
|
||||
Context::~Context()
|
||||
{
|
||||
try
|
||||
{
|
||||
SSL_CTX_free(_pSSLContext);
|
||||
Poco::Crypto::OpenSSLInitializer::uninitialize();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::init(const Params& params)
|
||||
{
|
||||
Poco::Crypto::OpenSSLInitializer::initialize();
|
||||
|
||||
createSSLContext();
|
||||
|
||||
try
|
||||
{
|
||||
int errCode = 0;
|
||||
if (!params.caLocation.empty())
|
||||
{
|
||||
Poco::File aFile(params.caLocation);
|
||||
if (aFile.isDirectory())
|
||||
errCode = SSL_CTX_load_verify_locations(_pSSLContext, 0, Poco::Path::transcode(params.caLocation).c_str());
|
||||
else
|
||||
errCode = SSL_CTX_load_verify_locations(_pSSLContext, Poco::Path::transcode(params.caLocation).c_str(), 0);
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException(std::string("Cannot load CA file/directory at ") + params.caLocation, msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.loadDefaultCAs)
|
||||
{
|
||||
errCode = SSL_CTX_set_default_verify_paths(_pSSLContext);
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot load default CA certificates", msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.privateKeyFile.empty())
|
||||
{
|
||||
errCode = SSL_CTX_use_PrivateKey_file(_pSSLContext, Poco::Path::transcode(params.privateKeyFile).c_str(), SSL_FILETYPE_PEM);
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException(std::string("Error loading private key from file ") + params.privateKeyFile, msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.certificateFile.empty())
|
||||
{
|
||||
errCode = SSL_CTX_use_certificate_chain_file(_pSSLContext, Poco::Path::transcode(params.certificateFile).c_str());
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string errMsg = Utility::getLastError();
|
||||
throw SSLContextException(std::string("Error loading certificate from file ") + params.certificateFile, errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (isForServerUse())
|
||||
SSL_CTX_set_verify(_pSSLContext, params.verificationMode, &SSLManager::verifyServerCallback);
|
||||
else
|
||||
SSL_CTX_set_verify(_pSSLContext, params.verificationMode, &SSLManager::verifyClientCallback);
|
||||
|
||||
SSL_CTX_set_cipher_list(_pSSLContext, params.cipherList.c_str());
|
||||
SSL_CTX_set_verify_depth(_pSSLContext, params.verificationDepth);
|
||||
SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY);
|
||||
SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF);
|
||||
|
||||
initDH(params.dhUse2048Bits, params.dhParamsFile);
|
||||
initECDH(params.ecdhCurve);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
SSL_CTX_free(_pSSLContext);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::useCertificate(const Poco::Crypto::X509Certificate& certificate)
|
||||
{
|
||||
int errCode = SSL_CTX_use_certificate(_pSSLContext, const_cast<X509*>(certificate.certificate()));
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot set certificate for Context", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::addChainCertificate(const Poco::Crypto::X509Certificate& certificate)
|
||||
{
|
||||
X509* pCert = certificate.dup();
|
||||
int errCode = SSL_CTX_add_extra_chain_cert(_pSSLContext, pCert);
|
||||
if (errCode != 1)
|
||||
{
|
||||
X509_free(pCert);
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot add chain certificate to Context", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::addCertificateAuthority(const Crypto::X509Certificate &certificate)
|
||||
{
|
||||
if (X509_STORE* store = SSL_CTX_get_cert_store(_pSSLContext))
|
||||
{
|
||||
int errCode = X509_STORE_add_cert(store, const_cast<X509*>(certificate.certificate()));
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot add certificate authority to Context", msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot add certificate authority to Context", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::usePrivateKey(const Poco::Crypto::RSAKey& key)
|
||||
{
|
||||
int errCode = SSL_CTX_use_RSAPrivateKey(_pSSLContext, key.impl()->getRSA());
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot set private key for Context", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::usePrivateKey(const Poco::Crypto::EVPPKey& pkey)
|
||||
{
|
||||
int errCode = SSL_CTX_use_PrivateKey(_pSSLContext, const_cast<EVP_PKEY*>(static_cast<const EVP_PKEY*>(pkey)));
|
||||
if (errCode != 1)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException("Cannot set private key for Context", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::enableSessionCache(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
SSL_CTX_set_session_cache_mode(_pSSLContext, isForServerUse() ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_CLIENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::enableSessionCache(bool flag, const std::string& sessionIdContext)
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
if (flag)
|
||||
{
|
||||
SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_SERVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF);
|
||||
}
|
||||
|
||||
unsigned length = static_cast<unsigned>(sessionIdContext.length());
|
||||
if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) length = SSL_MAX_SSL_SESSION_ID_LENGTH;
|
||||
int rc = SSL_CTX_set_session_id_context(_pSSLContext, reinterpret_cast<const unsigned char*>(sessionIdContext.data()), length);
|
||||
if (rc != 1) throw SSLContextException("cannot set session ID context");
|
||||
}
|
||||
|
||||
|
||||
bool Context::sessionCacheEnabled() const
|
||||
{
|
||||
return SSL_CTX_get_session_cache_mode(_pSSLContext) != SSL_SESS_CACHE_OFF;
|
||||
}
|
||||
|
||||
|
||||
void Context::setSessionCacheSize(std::size_t size)
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
SSL_CTX_sess_set_cache_size(_pSSLContext, static_cast<long>(size));
|
||||
}
|
||||
|
||||
|
||||
std::size_t Context::getSessionCacheSize() const
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
return static_cast<std::size_t>(SSL_CTX_sess_get_cache_size(_pSSLContext));
|
||||
}
|
||||
|
||||
|
||||
void Context::setSessionTimeout(long seconds)
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
SSL_CTX_set_timeout(_pSSLContext, seconds);
|
||||
}
|
||||
|
||||
|
||||
long Context::getSessionTimeout() const
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
return SSL_CTX_get_timeout(_pSSLContext);
|
||||
}
|
||||
|
||||
|
||||
void Context::flushSessionCache()
|
||||
{
|
||||
poco_assert (isForServerUse());
|
||||
|
||||
Poco::Timestamp now;
|
||||
SSL_CTX_flush_sessions(_pSSLContext, static_cast<long>(now.epochTime()));
|
||||
}
|
||||
|
||||
|
||||
void Context::enableExtendedCertificateVerification(bool flag)
|
||||
{
|
||||
_extendedCertificateVerification = flag;
|
||||
}
|
||||
|
||||
|
||||
void Context::disableStatelessSessionResumption()
|
||||
{
|
||||
#if defined(SSL_OP_NO_TICKET)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_TICKET);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Context::disableProtocols(int protocols)
|
||||
{
|
||||
if (protocols & PROTO_SSLV2)
|
||||
{
|
||||
#if defined(SSL_OP_NO_SSLv2)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_SSLv2);
|
||||
#endif
|
||||
}
|
||||
if (protocols & PROTO_SSLV3)
|
||||
{
|
||||
#if defined(SSL_OP_NO_SSLv3)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_SSLv3);
|
||||
#endif
|
||||
}
|
||||
if (protocols & PROTO_TLSV1)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_TLSv1);
|
||||
#endif
|
||||
}
|
||||
if (protocols & PROTO_TLSV1_1)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_1)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_TLSv1_1);
|
||||
#endif
|
||||
}
|
||||
if (protocols & PROTO_TLSV1_2)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_2)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_TLSv1_2);
|
||||
#endif
|
||||
}
|
||||
if (protocols & PROTO_TLSV1_3)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_3)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_NO_TLSv1_3);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::requireMinimumProtocol(Protocols protocol)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
int version = 0;
|
||||
switch (protocol)
|
||||
{
|
||||
case PROTO_SSLV2:
|
||||
throw Poco::InvalidArgumentException("SSLv2 is no longer supported");
|
||||
case PROTO_SSLV3:
|
||||
version = SSL3_VERSION;
|
||||
break;
|
||||
case PROTO_TLSV1:
|
||||
version = TLS1_VERSION;
|
||||
break;
|
||||
case PROTO_TLSV1_1:
|
||||
version = TLS1_1_VERSION;
|
||||
break;
|
||||
case PROTO_TLSV1_2:
|
||||
version = TLS1_2_VERSION;
|
||||
break;
|
||||
case PROTO_TLSV1_3:
|
||||
version = TLS1_3_VERSION;
|
||||
break;
|
||||
}
|
||||
if (!SSL_CTX_set_min_proto_version(_pSSLContext, version))
|
||||
{
|
||||
unsigned long err = ERR_get_error();
|
||||
throw SSLException("Cannot set minimum supported version on SSL_CTX object", ERR_error_string(err, 0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
switch (protocol)
|
||||
{
|
||||
case PROTO_SSLV2:
|
||||
throw Poco::InvalidArgumentException("SSLv2 is no longer supported");
|
||||
|
||||
case PROTO_SSLV3:
|
||||
disableProtocols(PROTO_SSLV2);
|
||||
break;
|
||||
|
||||
case PROTO_TLSV1:
|
||||
disableProtocols(PROTO_SSLV2 | PROTO_SSLV3);
|
||||
break;
|
||||
|
||||
case PROTO_TLSV1_1:
|
||||
#if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1)
|
||||
disableProtocols(PROTO_SSLV2 | PROTO_SSLV3 | PROTO_TLSV1);
|
||||
#else
|
||||
throw Poco::InvalidArgumentException("TLSv1.1 is not supported by the available OpenSSL library");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PROTO_TLSV1_2:
|
||||
#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
|
||||
disableProtocols(PROTO_SSLV2 | PROTO_SSLV3 | PROTO_TLSV1 | PROTO_TLSV1_1);
|
||||
#else
|
||||
throw Poco::InvalidArgumentException("TLSv1.2 is not supported by the available OpenSSL library");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PROTO_TLSV1_3:
|
||||
throw Poco::InvalidArgumentException("TLSv1.3 is not supported by the available OpenSSL library");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Context::preferServerCiphers()
|
||||
{
|
||||
#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Context::createSSLContext()
|
||||
{
|
||||
int minTLSVersion = 0;
|
||||
|
||||
if (SSLManager::isFIPSEnabled())
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_method());
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_method());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (_usage)
|
||||
{
|
||||
case CLIENT_USE:
|
||||
case TLS_CLIENT_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_client_method());
|
||||
minTLSVersion = TLS1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(SSLv23_client_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SERVER_USE:
|
||||
case TLS_SERVER_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_server_method());
|
||||
minTLSVersion = TLS1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(SSLv23_server_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TLSV1_CLIENT_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_client_method());
|
||||
minTLSVersion = TLS1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_client_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TLSV1_SERVER_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_server_method());
|
||||
minTLSVersion = TLS1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_server_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1)
|
||||
/* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1.
|
||||
* OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line
|
||||
* if TLS1.x was removed at OpenSSL library build time via Configure options.
|
||||
*/
|
||||
case TLSV1_1_CLIENT_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_client_method());
|
||||
minTLSVersion = TLS1_1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_1_client_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TLSV1_1_SERVER_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_server_method());
|
||||
minTLSVersion = TLS1_1_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_1_server_method());
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
|
||||
case TLSV1_2_CLIENT_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_client_method());
|
||||
minTLSVersion = TLS1_2_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_2_client_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TLSV1_2_SERVER_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_server_method());
|
||||
minTLSVersion = TLS1_2_VERSION;
|
||||
#else
|
||||
_pSSLContext = SSL_CTX_new(TLSv1_2_server_method());
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_3) && !defined(OPENSSL_NO_TLS1)
|
||||
case TLSV1_3_CLIENT_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_client_method());
|
||||
minTLSVersion = TLS1_3_VERSION;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case TLSV1_3_SERVER_USE:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
_pSSLContext = SSL_CTX_new(TLS_server_method());
|
||||
minTLSVersion = TLS1_3_VERSION;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
throw Poco::InvalidArgumentException("Invalid or unsupported usage");
|
||||
}
|
||||
}
|
||||
if (!_pSSLContext)
|
||||
{
|
||||
unsigned long err = ERR_get_error();
|
||||
throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0));
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
if (minTLSVersion)
|
||||
{
|
||||
if (!SSL_CTX_set_min_proto_version(_pSSLContext, minTLSVersion))
|
||||
{
|
||||
SSL_CTX_free(_pSSLContext);
|
||||
_pSSLContext = 0;
|
||||
unsigned long err = ERR_get_error();
|
||||
throw SSLException("Cannot set minimum supported version on SSL_CTX object", ERR_error_string(err, 0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
|
||||
Utility::clearErrorStack();
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
|
||||
}
|
||||
|
||||
|
||||
void Context::initDH(bool use2048Bits, const std::string& dhParamsFile)
|
||||
{
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static const unsigned char dh1024_p[] =
|
||||
{
|
||||
0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E,
|
||||
0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6,
|
||||
0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86,
|
||||
0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0,
|
||||
0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C,
|
||||
0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70,
|
||||
0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA,
|
||||
0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0,
|
||||
0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF,
|
||||
0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08,
|
||||
0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71,
|
||||
};
|
||||
|
||||
static const unsigned char dh1024_g[] =
|
||||
{
|
||||
0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42,
|
||||
0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F,
|
||||
0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E,
|
||||
0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13,
|
||||
0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F,
|
||||
0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1,
|
||||
0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08,
|
||||
0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A,
|
||||
0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59,
|
||||
0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24,
|
||||
0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5,
|
||||
};
|
||||
|
||||
static const unsigned char dh2048_p[] =
|
||||
{
|
||||
0x87,0xA8,0xE6,0x1D,0xB4,0xB6,0x66,0x3C,0xFF,0xBB,0xD1,0x9C,
|
||||
0x65,0x19,0x59,0x99,0x8C,0xEE,0xF6,0x08,0x66,0x0D,0xD0,0xF2,
|
||||
0x5D,0x2C,0xEE,0xD4,0x43,0x5E,0x3B,0x00,0xE0,0x0D,0xF8,0xF1,
|
||||
0xD6,0x19,0x57,0xD4,0xFA,0xF7,0xDF,0x45,0x61,0xB2,0xAA,0x30,
|
||||
0x16,0xC3,0xD9,0x11,0x34,0x09,0x6F,0xAA,0x3B,0xF4,0x29,0x6D,
|
||||
0x83,0x0E,0x9A,0x7C,0x20,0x9E,0x0C,0x64,0x97,0x51,0x7A,0xBD,
|
||||
0x5A,0x8A,0x9D,0x30,0x6B,0xCF,0x67,0xED,0x91,0xF9,0xE6,0x72,
|
||||
0x5B,0x47,0x58,0xC0,0x22,0xE0,0xB1,0xEF,0x42,0x75,0xBF,0x7B,
|
||||
0x6C,0x5B,0xFC,0x11,0xD4,0x5F,0x90,0x88,0xB9,0x41,0xF5,0x4E,
|
||||
0xB1,0xE5,0x9B,0xB8,0xBC,0x39,0xA0,0xBF,0x12,0x30,0x7F,0x5C,
|
||||
0x4F,0xDB,0x70,0xC5,0x81,0xB2,0x3F,0x76,0xB6,0x3A,0xCA,0xE1,
|
||||
0xCA,0xA6,0xB7,0x90,0x2D,0x52,0x52,0x67,0x35,0x48,0x8A,0x0E,
|
||||
0xF1,0x3C,0x6D,0x9A,0x51,0xBF,0xA4,0xAB,0x3A,0xD8,0x34,0x77,
|
||||
0x96,0x52,0x4D,0x8E,0xF6,0xA1,0x67,0xB5,0xA4,0x18,0x25,0xD9,
|
||||
0x67,0xE1,0x44,0xE5,0x14,0x05,0x64,0x25,0x1C,0xCA,0xCB,0x83,
|
||||
0xE6,0xB4,0x86,0xF6,0xB3,0xCA,0x3F,0x79,0x71,0x50,0x60,0x26,
|
||||
0xC0,0xB8,0x57,0xF6,0x89,0x96,0x28,0x56,0xDE,0xD4,0x01,0x0A,
|
||||
0xBD,0x0B,0xE6,0x21,0xC3,0xA3,0x96,0x0A,0x54,0xE7,0x10,0xC3,
|
||||
0x75,0xF2,0x63,0x75,0xD7,0x01,0x41,0x03,0xA4,0xB5,0x43,0x30,
|
||||
0xC1,0x98,0xAF,0x12,0x61,0x16,0xD2,0x27,0x6E,0x11,0x71,0x5F,
|
||||
0x69,0x38,0x77,0xFA,0xD7,0xEF,0x09,0xCA,0xDB,0x09,0x4A,0xE9,
|
||||
0x1E,0x1A,0x15,0x97,
|
||||
};
|
||||
|
||||
static const unsigned char dh2048_g[] =
|
||||
{
|
||||
0x3F,0xB3,0x2C,0x9B,0x73,0x13,0x4D,0x0B,0x2E,0x77,0x50,0x66,
|
||||
0x60,0xED,0xBD,0x48,0x4C,0xA7,0xB1,0x8F,0x21,0xEF,0x20,0x54,
|
||||
0x07,0xF4,0x79,0x3A,0x1A,0x0B,0xA1,0x25,0x10,0xDB,0xC1,0x50,
|
||||
0x77,0xBE,0x46,0x3F,0xFF,0x4F,0xED,0x4A,0xAC,0x0B,0xB5,0x55,
|
||||
0xBE,0x3A,0x6C,0x1B,0x0C,0x6B,0x47,0xB1,0xBC,0x37,0x73,0xBF,
|
||||
0x7E,0x8C,0x6F,0x62,0x90,0x12,0x28,0xF8,0xC2,0x8C,0xBB,0x18,
|
||||
0xA5,0x5A,0xE3,0x13,0x41,0x00,0x0A,0x65,0x01,0x96,0xF9,0x31,
|
||||
0xC7,0x7A,0x57,0xF2,0xDD,0xF4,0x63,0xE5,0xE9,0xEC,0x14,0x4B,
|
||||
0x77,0x7D,0xE6,0x2A,0xAA,0xB8,0xA8,0x62,0x8A,0xC3,0x76,0xD2,
|
||||
0x82,0xD6,0xED,0x38,0x64,0xE6,0x79,0x82,0x42,0x8E,0xBC,0x83,
|
||||
0x1D,0x14,0x34,0x8F,0x6F,0x2F,0x91,0x93,0xB5,0x04,0x5A,0xF2,
|
||||
0x76,0x71,0x64,0xE1,0xDF,0xC9,0x67,0xC1,0xFB,0x3F,0x2E,0x55,
|
||||
0xA4,0xBD,0x1B,0xFF,0xE8,0x3B,0x9C,0x80,0xD0,0x52,0xB9,0x85,
|
||||
0xD1,0x82,0xEA,0x0A,0xDB,0x2A,0x3B,0x73,0x13,0xD3,0xFE,0x14,
|
||||
0xC8,0x48,0x4B,0x1E,0x05,0x25,0x88,0xB9,0xB7,0xD2,0xBB,0xD2,
|
||||
0xDF,0x01,0x61,0x99,0xEC,0xD0,0x6E,0x15,0x57,0xCD,0x09,0x15,
|
||||
0xB3,0x35,0x3B,0xBB,0x64,0xE0,0xEC,0x37,0x7F,0xD0,0x28,0x37,
|
||||
0x0D,0xF9,0x2B,0x52,0xC7,0x89,0x14,0x28,0xCD,0xC6,0x7E,0xB6,
|
||||
0x18,0x4B,0x52,0x3D,0x1D,0xB2,0x46,0xC3,0x2F,0x63,0x07,0x84,
|
||||
0x90,0xF0,0x0E,0xF8,0xD6,0x47,0xD1,0x48,0xD4,0x79,0x54,0x51,
|
||||
0x5E,0x23,0x27,0xCF,0xEF,0x98,0xC5,0x82,0x66,0x4B,0x4C,0x0F,
|
||||
0x6C,0xC4,0x16,0x59,
|
||||
};
|
||||
|
||||
DH* dh = 0;
|
||||
if (!dhParamsFile.empty())
|
||||
{
|
||||
BIO* bio = BIO_new_file(dhParamsFile.c_str(), "r");
|
||||
if (!bio)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException(std::string("Error opening Diffie-Hellman parameters file ") + dhParamsFile, msg);
|
||||
}
|
||||
dh = PEM_read_bio_DHparams(bio, 0, 0, 0);
|
||||
BIO_free(bio);
|
||||
if (!dh)
|
||||
{
|
||||
std::string msg = Utility::getLastError();
|
||||
throw SSLContextException(std::string("Error reading Diffie-Hellman parameters from file ") + dhParamsFile, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dh = DH_new();
|
||||
if (!dh)
|
||||
{
|
||||
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)
|
||||
{
|
||||
p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), 0);
|
||||
g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), 0);
|
||||
DH_set0_pqg(dh, p, 0, g);
|
||||
DH_set_length(dh, 256);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0);
|
||||
g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0);
|
||||
DH_set0_pqg(dh, p, 0, g);
|
||||
DH_set_length(dh, 160);
|
||||
}
|
||||
if (!p || !g)
|
||||
{
|
||||
DH_free(dh);
|
||||
throw SSLContextException("Error creating Diffie-Hellman parameters");
|
||||
}
|
||||
#else
|
||||
if (use2048Bits)
|
||||
{
|
||||
dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), 0);
|
||||
dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), 0);
|
||||
dh->length = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0);
|
||||
dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0);
|
||||
dh->length = 160;
|
||||
}
|
||||
if ((!dh->p) || (!dh->g))
|
||||
{
|
||||
DH_free(dh);
|
||||
throw SSLContextException("Error creating Diffie-Hellman parameters");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
SSL_CTX_set_tmp_dh(_pSSLContext, dh);
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_DH_USE);
|
||||
DH_free(dh);
|
||||
#else
|
||||
if (!dhParamsFile.empty())
|
||||
throw SSLContextException("OpenSSL does not support DH");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Context::initECDH(const std::string& curve)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
|
||||
const std::string groups(curve.empty() ?
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
|
||||
"X448:X25519:P-521:P-384:P-256"
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x1010000fL
|
||||
// while OpenSSL 1.1.0 didn't support Ed25519 (EdDSA using Curve25519),
|
||||
// it did support X25519 (ECDH using Curve25516).
|
||||
"X25519:P-521:P-384:P-256"
|
||||
#else
|
||||
"P-521:P-384:P-256"
|
||||
#endif
|
||||
: curve);
|
||||
if (SSL_CTX_set1_curves_list(_pSSLContext, groups.c_str()) == 0)
|
||||
{
|
||||
throw SSLContextException("Cannot set ECDH groups", groups);
|
||||
}
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_ECDH_USE);
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x0090800fL
|
||||
int nid = 0;
|
||||
if (!curve.empty())
|
||||
{
|
||||
nid = OBJ_sn2nid(curve.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
nid = OBJ_sn2nid("prime256v1");
|
||||
}
|
||||
if (nid == 0)
|
||||
{
|
||||
throw SSLContextException("Unknown ECDH curve name", curve);
|
||||
}
|
||||
|
||||
EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
|
||||
if (!ecdh)
|
||||
{
|
||||
throw SSLContextException("Cannot create ECDH curve");
|
||||
}
|
||||
SSL_CTX_set_tmp_ecdh(_pSSLContext, ecdh);
|
||||
SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_ECDH_USE);
|
||||
EC_KEY_free(ecdh);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
143
vendor/POCO/NetSSL_OpenSSL/src/FTPSClientSession.cpp
vendored
Normal file
143
vendor/POCO/NetSSL_OpenSSL/src/FTPSClientSession.cpp
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
//
|
||||
// FTPSClientSession.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: FTPS
|
||||
// Module: FTPSClientSession
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/FTPSClientSession.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
FTPSClientSession::FTPSClientSession():
|
||||
FTPClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSession::FTPSClientSession(Context::Ptr pContext):
|
||||
FTPClientSession(),
|
||||
_pContext(pContext)
|
||||
{
|
||||
}
|
||||
|
||||
FTPSClientSession::FTPSClientSession(const StreamSocket& socket, bool readWelcomeMessage, bool enableFTPS, Context::Ptr pContext):
|
||||
FTPClientSession(socket, readWelcomeMessage),
|
||||
_enableFTPS(enableFTPS),
|
||||
_pContext(pContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSession::FTPSClientSession(const std::string& host, Poco::UInt16 port, const std::string& username, const std::string& password, Context::Ptr pContext):
|
||||
FTPClientSession(host, port, username, password),
|
||||
_pContext(pContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSClientSession::~FTPSClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSession::enableFTPS(bool enable)
|
||||
{
|
||||
_enableFTPS = enable;
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSession::beforeCreateDataSocket()
|
||||
{
|
||||
if (_secureDataConnection) return;
|
||||
_secureDataConnection = false;
|
||||
if (!_pControlSocket->secure()) return;
|
||||
std::string sResponse;
|
||||
int status = sendCommand("PBSZ 0", sResponse);
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
status = sendCommand("PROT P", sResponse);
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
_secureDataConnection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSession::afterCreateControlSocket()
|
||||
{
|
||||
if (!_enableFTPS) return;
|
||||
_pControlSocket->setNoDelay(true);
|
||||
if (_pControlSocket->secure()) return;
|
||||
|
||||
std::string sResponse;
|
||||
int status = sendCommand("AUTH TLS", sResponse);
|
||||
if (!isPositiveCompletion(status))
|
||||
status = sendCommand("AUTH SSL", sResponse);
|
||||
|
||||
if (isPositiveCompletion(status))
|
||||
{
|
||||
// Server support FTPS
|
||||
try
|
||||
{
|
||||
if (!_pContext) _pContext = Poco::Net::SSLManager::instance().defaultClientContext();
|
||||
Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(*_pControlSocket, _pContext));
|
||||
*_pControlSocket = sss;
|
||||
}
|
||||
catch (Poco::Exception&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_enableFTPS = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StreamSocket FTPSClientSession::establishDataConnection(const std::string& command, const std::string& arg)
|
||||
{
|
||||
beforeCreateDataSocket();
|
||||
|
||||
StreamSocket ss = FTPClientSession::establishDataConnection(command, arg);
|
||||
ss.setNoDelay(true);
|
||||
|
||||
// SSL nogotiating of data socket
|
||||
if (_secureDataConnection && _pControlSocket->secure())
|
||||
{
|
||||
// We need to reuse the control socket SSL session so the server can ensure that client that opened control socket is the same using data socket
|
||||
Poco::Net::SecureStreamSocketImpl* pSecure = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(_pControlSocket->impl());
|
||||
if (pSecure != nullptr)
|
||||
{
|
||||
Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(ss, pSecure->context(), pSecure->currentSession()));
|
||||
ss = sss;
|
||||
}
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
void FTPSClientSession::receiveServerReadyReply()
|
||||
{
|
||||
FTPClientSession::receiveServerReadyReply();
|
||||
afterCreateControlSocket();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
161
vendor/POCO/NetSSL_OpenSSL/src/FTPSStreamFactory.cpp
vendored
Normal file
161
vendor/POCO/NetSSL_OpenSSL/src/FTPSStreamFactory.cpp
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// FTPSStreamFactory.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: FTPS
|
||||
// Module: FTPSStreamFactory
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/FTPSStreamFactory.h"
|
||||
#include "Poco/Net/FTPSClientSession.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/URIStreamOpener.h"
|
||||
#include "Poco/UnbufferedStreamBuf.h"
|
||||
#include "Poco/Path.h"
|
||||
|
||||
|
||||
using Poco::URIStreamFactory;
|
||||
using Poco::URI;
|
||||
using Poco::URIStreamOpener;
|
||||
using Poco::UnbufferedStreamBuf;
|
||||
using Poco::Path;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
class FTPSStreamBuf: public UnbufferedStreamBuf
|
||||
{
|
||||
public:
|
||||
FTPSStreamBuf(std::istream& istr):
|
||||
_istr(istr)
|
||||
{
|
||||
// make sure exceptions from underlying string propagate
|
||||
_istr.exceptions(std::ios::badbit);
|
||||
}
|
||||
|
||||
~FTPSStreamBuf()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int readFromDevice()
|
||||
{
|
||||
return _istr.get();
|
||||
}
|
||||
|
||||
std::istream& _istr;
|
||||
};
|
||||
|
||||
|
||||
class FTPSIOS: public virtual std::ios
|
||||
{
|
||||
public:
|
||||
FTPSIOS(std::istream& istr):
|
||||
_buf(istr)
|
||||
{
|
||||
poco_ios_init(&_buf);
|
||||
}
|
||||
|
||||
~FTPSIOS()
|
||||
{
|
||||
}
|
||||
|
||||
FTPSStreamBuf* rdbuf()
|
||||
{
|
||||
return &_buf;
|
||||
}
|
||||
|
||||
protected:
|
||||
FTPSStreamBuf _buf;
|
||||
};
|
||||
|
||||
|
||||
class FTPSStream: public FTPSIOS, public std::istream
|
||||
{
|
||||
public:
|
||||
FTPSStream(std::istream& istr, FTPSClientSession* pSession):
|
||||
FTPSIOS(istr),
|
||||
std::istream(&_buf),
|
||||
_pSession(pSession)
|
||||
{
|
||||
}
|
||||
|
||||
~FTPSStream()
|
||||
{
|
||||
delete _pSession;
|
||||
}
|
||||
|
||||
private:
|
||||
FTPSClientSession* _pSession;
|
||||
};
|
||||
|
||||
|
||||
FTPSStreamFactory::FTPSStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FTPSStreamFactory::~FTPSStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* FTPSStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "ftps");
|
||||
|
||||
Poco::UInt16 port = uri.getPort();
|
||||
if (port == 0) port = FTPClientSession::FTP_PORT;
|
||||
FTPSClientSession* pSession = new FTPSClientSession(uri.getHost(), port);
|
||||
try
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
getUserInfo(uri, username, password);
|
||||
|
||||
std::string path;
|
||||
char type;
|
||||
getPathAndType(uri, path, type);
|
||||
|
||||
pSession->login(username, password);
|
||||
if (type == 'a')
|
||||
pSession->setFileType(FTPClientSession::TYPE_TEXT);
|
||||
|
||||
Path p(path, Path::PATH_UNIX);
|
||||
p.makeFile();
|
||||
for (int i = 0; i < p.depth(); ++i)
|
||||
pSession->setWorkingDirectory(p[i]);
|
||||
std::string file(p.getFileName());
|
||||
std::istream& istr = (type == 'd' ? pSession->beginList(file) : pSession->beginDownload(file));
|
||||
return new FTPSStream(istr, pSession);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete pSession;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FTPSStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("ftps", new FTPSStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
void FTPSStreamFactory::unregisterFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().unregisterStreamFactory("ftps");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
189
vendor/POCO/NetSSL_OpenSSL/src/HTTPSClientSession.cpp
vendored
Normal file
189
vendor/POCO/NetSSL_OpenSSL/src/HTTPSClientSession.cpp
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
//
|
||||
// HTTPSClientSession.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: HTTPSClient
|
||||
// Module: HTTPSClientSession
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/HTTPRequest.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
|
||||
|
||||
using Poco::NumberFormatter;
|
||||
using Poco::IllegalStateException;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession():
|
||||
HTTPClientSession(SecureStreamSocket()),
|
||||
_pContext(SSLManager::instance().defaultClientContext())
|
||||
{
|
||||
setPort(HTTPS_PORT);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket):
|
||||
HTTPClientSession(socket),
|
||||
_pContext(socket.context())
|
||||
{
|
||||
setPort(HTTPS_PORT);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(const SecureStreamSocket& socket, Session::Ptr pSession):
|
||||
HTTPClientSession(socket),
|
||||
_pContext(socket.context()),
|
||||
_pSession(pSession)
|
||||
{
|
||||
setPort(HTTPS_PORT);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 port):
|
||||
HTTPClientSession(SecureStreamSocket()),
|
||||
_pContext(SSLManager::instance().defaultClientContext())
|
||||
{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext):
|
||||
HTTPClientSession(SecureStreamSocket(pContext)),
|
||||
_pContext(pContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(Context::Ptr pContext, Session::Ptr pSession):
|
||||
HTTPClientSession(SecureStreamSocket(pContext, pSession)),
|
||||
_pContext(pContext),
|
||||
_pSession(pSession)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 port, Context::Ptr pContext):
|
||||
HTTPClientSession(SecureStreamSocket(pContext)),
|
||||
_pContext(pContext)
|
||||
{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::HTTPSClientSession(const std::string& host, Poco::UInt16 port, Context::Ptr pContext, Session::Ptr pSession):
|
||||
HTTPClientSession(SecureStreamSocket(pContext, pSession)),
|
||||
_pContext(pContext),
|
||||
_pSession(pSession)
|
||||
{
|
||||
setHost(host);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
|
||||
HTTPSClientSession::~HTTPSClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool HTTPSClientSession::secure() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSClientSession::abort()
|
||||
{
|
||||
SecureStreamSocket sss(socket());
|
||||
sss.abort();
|
||||
}
|
||||
|
||||
|
||||
X509Certificate HTTPSClientSession::serverCertificate()
|
||||
{
|
||||
SecureStreamSocket sss(socket());
|
||||
return sss.peerCertificate();
|
||||
}
|
||||
|
||||
|
||||
std::string HTTPSClientSession::proxyRequestPrefix() const
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
void HTTPSClientSession::proxyAuthenticate(HTTPRequest& request)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPSClientSession::connect(const SocketAddress& address)
|
||||
{
|
||||
if (getProxyHost().empty() || bypassProxy())
|
||||
{
|
||||
SecureStreamSocket sss(socket());
|
||||
if (sss.getPeerHostName().empty())
|
||||
{
|
||||
sss.setPeerHostName(getHost());
|
||||
}
|
||||
if (_pContext->sessionCacheEnabled())
|
||||
{
|
||||
sss.useSession(_pSession);
|
||||
}
|
||||
HTTPSession::connect(address);
|
||||
if (_pContext->sessionCacheEnabled())
|
||||
{
|
||||
_pSession = sss.currentSession();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamSocket proxySocket(proxyConnect());
|
||||
SecureStreamSocket secureSocket = SecureStreamSocket::attach(proxySocket, getHost(), _pContext, _pSession);
|
||||
attachSocket(secureSocket);
|
||||
if (_pContext->sessionCacheEnabled())
|
||||
{
|
||||
_pSession = secureSocket.currentSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HTTPSClientSession::read(char* buffer, std::streamsize length)
|
||||
{
|
||||
try
|
||||
{
|
||||
return HTTPSession::read(buffer, length);
|
||||
}
|
||||
catch(SSLConnectionUnexpectedlyClosedException&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Session::Ptr HTTPSClientSession::sslSession()
|
||||
{
|
||||
return _pSession;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
71
vendor/POCO/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp
vendored
Normal file
71
vendor/POCO/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// HTTPSSessionInstantiator.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: HTTPSClient
|
||||
// Module: HTTPSSessionInstantiator
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPSSessionInstantiator.h"
|
||||
#include "Poco/Net/HTTPSessionFactory.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
HTTPSSessionInstantiator::HTTPSSessionInstantiator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSSessionInstantiator::HTTPSSessionInstantiator(Context::Ptr pContext) :
|
||||
_pContext(pContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSSessionInstantiator::~HTTPSSessionInstantiator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPClientSession* HTTPSSessionInstantiator::createClientSession(const Poco::URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "https");
|
||||
HTTPSClientSession* pSession = _pContext.isNull() ? new HTTPSClientSession(uri.getHost(), uri.getPort()) : new HTTPSClientSession(uri.getHost(), uri.getPort(), _pContext);
|
||||
if (!proxyHost().empty())
|
||||
{
|
||||
pSession->setProxy(proxyHost(), proxyPort());
|
||||
pSession->setProxyCredentials(proxyUsername(), proxyPassword());
|
||||
}
|
||||
return pSession;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSSessionInstantiator::registerInstantiator()
|
||||
{
|
||||
HTTPSessionFactory::defaultFactory().registerProtocol("https", new HTTPSSessionInstantiator);
|
||||
}
|
||||
|
||||
|
||||
void HTTPSSessionInstantiator::registerInstantiator(Context::Ptr context)
|
||||
{
|
||||
HTTPSessionFactory::defaultFactory().registerProtocol("https", new HTTPSSessionInstantiator(context));
|
||||
}
|
||||
|
||||
|
||||
void HTTPSSessionInstantiator::unregisterInstantiator()
|
||||
{
|
||||
HTTPSessionFactory::defaultFactory().unregisterProtocol("https");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
194
vendor/POCO/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
vendored
Normal file
194
vendor/POCO/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
//
|
||||
// HTTPSStreamFactory.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: HTTPSClient
|
||||
// Module: HTTPSStreamFactory
|
||||
//
|
||||
// Copyright (c) 2006-2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/HTTPSStreamFactory.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/HTTPIOStream.h"
|
||||
#include "Poco/Net/HTTPRequest.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/Net/HTTPCredentials.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/URIStreamOpener.h"
|
||||
#include "Poco/UnbufferedStreamBuf.h"
|
||||
#include "Poco/NullStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/Version.h"
|
||||
|
||||
|
||||
using Poco::URIStreamFactory;
|
||||
using Poco::URI;
|
||||
using Poco::URIStreamOpener;
|
||||
using Poco::UnbufferedStreamBuf;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
HTTPSStreamFactory::HTTPSStreamFactory():
|
||||
_proxyPort(HTTPSession::HTTP_PORT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSStreamFactory::HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort):
|
||||
_proxyHost(proxyHost),
|
||||
_proxyPort(proxyPort)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSStreamFactory::HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort, const std::string& proxyUsername, const std::string& proxyPassword):
|
||||
_proxyHost(proxyHost),
|
||||
_proxyPort(proxyPort),
|
||||
_proxyUsername(proxyUsername),
|
||||
_proxyPassword(proxyPassword)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HTTPSStreamFactory::~HTTPSStreamFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::istream* HTTPSStreamFactory::open(const URI& uri)
|
||||
{
|
||||
poco_assert (uri.getScheme() == "https" || uri.getScheme() == "http");
|
||||
|
||||
URI resolvedURI(uri);
|
||||
URI proxyUri;
|
||||
HTTPClientSession* pSession = 0;
|
||||
HTTPResponse res;
|
||||
try
|
||||
{
|
||||
bool retry = false;
|
||||
bool authorize = false;
|
||||
int redirects = 0;
|
||||
std::string username;
|
||||
std::string password;
|
||||
|
||||
do
|
||||
{
|
||||
if (!pSession)
|
||||
{
|
||||
if (resolvedURI.getScheme() != "http")
|
||||
pSession = new HTTPSClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||
else
|
||||
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||
|
||||
if (proxyUri.empty())
|
||||
{
|
||||
if (!_proxyHost.empty())
|
||||
{
|
||||
pSession->setProxy(_proxyHost, _proxyPort);
|
||||
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
|
||||
if (!_proxyUsername.empty())
|
||||
{
|
||||
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string path = resolvedURI.getPathAndQuery();
|
||||
if (path.empty()) path = "/";
|
||||
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
|
||||
|
||||
if (authorize)
|
||||
{
|
||||
HTTPCredentials::extractCredentials(uri, username, password);
|
||||
HTTPCredentials cred(username, password);
|
||||
cred.authenticate(req, res);
|
||||
}
|
||||
|
||||
req.set("User-Agent", Poco::format("poco/%d.%d.%d",
|
||||
(POCO_VERSION >> 24) & 0xFF,
|
||||
(POCO_VERSION >> 16) & 0xFF,
|
||||
(POCO_VERSION >> 8) & 0xFF));
|
||||
req.set("Accept", "*/*");
|
||||
|
||||
pSession->sendRequest(req);
|
||||
std::istream& rs = pSession->receiveResponse(res);
|
||||
bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY ||
|
||||
res.getStatus() == HTTPResponse::HTTP_FOUND ||
|
||||
res.getStatus() == HTTPResponse::HTTP_SEE_OTHER ||
|
||||
res.getStatus() == HTTPResponse::HTTP_TEMPORARY_REDIRECT);
|
||||
if (moved)
|
||||
{
|
||||
resolvedURI.resolve(res.get("Location"));
|
||||
if (!username.empty())
|
||||
{
|
||||
resolvedURI.setUserInfo(username + ":" + password);
|
||||
authorize = false;
|
||||
}
|
||||
delete pSession;
|
||||
pSession = 0;
|
||||
++redirects;
|
||||
retry = true;
|
||||
}
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_OK)
|
||||
{
|
||||
return new HTTPResponseStream(rs, pSession);
|
||||
}
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry)
|
||||
{
|
||||
// The requested resource MUST be accessed through the proxy
|
||||
// given by the Location field. The Location field gives the
|
||||
// URI of the proxy. The recipient is expected to repeat this
|
||||
// single request via the proxy. 305 responses MUST only be generated by origin servers.
|
||||
// only use for one single request!
|
||||
proxyUri.resolve(res.get("Location"));
|
||||
delete pSession;
|
||||
pSession = 0;
|
||||
retry = true; // only allow useproxy once
|
||||
}
|
||||
else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
|
||||
{
|
||||
authorize = true;
|
||||
retry = true;
|
||||
Poco::NullOutputStream null;
|
||||
Poco::StreamCopier::copyStream(rs, null);
|
||||
}
|
||||
else throw HTTPException(res.getReason(), uri.toString());
|
||||
}
|
||||
while (retry && redirects < MAX_REDIRECTS);
|
||||
throw HTTPException("Too many redirects", uri.toString());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete pSession;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPSStreamFactory::registerFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().registerStreamFactory("https", new HTTPSStreamFactory);
|
||||
}
|
||||
|
||||
|
||||
void HTTPSStreamFactory::unregisterFactory()
|
||||
{
|
||||
URIStreamOpener::defaultOpener().unregisterStreamFactory("https");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
52
vendor/POCO/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp
vendored
Normal file
52
vendor/POCO/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// InvalidCertificateHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: InvalidCertificateHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/InvalidCertificateHandler.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Delegate.h"
|
||||
|
||||
|
||||
using Poco::Delegate;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
InvalidCertificateHandler::InvalidCertificateHandler(bool handleErrorsOnServerSide): _handleErrorsOnServerSide(handleErrorsOnServerSide)
|
||||
{
|
||||
if (_handleErrorsOnServerSide)
|
||||
SSLManager::instance().ServerVerificationError += Delegate<InvalidCertificateHandler, VerificationErrorArgs>(this, &InvalidCertificateHandler::onInvalidCertificate);
|
||||
else
|
||||
SSLManager::instance().ClientVerificationError += Delegate<InvalidCertificateHandler, VerificationErrorArgs>(this, &InvalidCertificateHandler::onInvalidCertificate);
|
||||
}
|
||||
|
||||
|
||||
InvalidCertificateHandler::~InvalidCertificateHandler()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_handleErrorsOnServerSide)
|
||||
SSLManager::instance().ServerVerificationError -= Delegate<InvalidCertificateHandler, VerificationErrorArgs>(this, &InvalidCertificateHandler::onInvalidCertificate);
|
||||
else
|
||||
SSLManager::instance().ClientVerificationError -= Delegate<InvalidCertificateHandler, VerificationErrorArgs>(this, &InvalidCertificateHandler::onInvalidCertificate);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
40
vendor/POCO/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp
vendored
Normal file
40
vendor/POCO/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// KeyConsoleHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: KeyConsoleHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/KeyConsoleHandler.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
KeyConsoleHandler::KeyConsoleHandler(bool server):PrivateKeyPassphraseHandler(server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KeyConsoleHandler::~KeyConsoleHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void KeyConsoleHandler::onPrivateKeyRequested(const void* pSender, std::string& privateKey)
|
||||
{
|
||||
std::cout << "Please enter the passphrase for the private key: ";
|
||||
std::cin >> privateKey;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
61
vendor/POCO/NetSSL_OpenSSL/src/KeyFileHandler.cpp
vendored
Normal file
61
vendor/POCO/NetSSL_OpenSSL/src/KeyFileHandler.cpp
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// KeyFileHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: KeyFileHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/KeyFileHandler.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/OptionException.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
const std::string KeyFileHandler::CFG_PRIV_KEY_FILE("privateKeyPassphraseHandler.options.password");
|
||||
|
||||
|
||||
KeyFileHandler::KeyFileHandler(bool server):PrivateKeyPassphraseHandler(server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KeyFileHandler::~KeyFileHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void KeyFileHandler::onPrivateKeyRequested(const void* pSender, std::string& privateKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
Poco::Util::AbstractConfiguration& config = Poco::Util::Application::instance().config();
|
||||
std::string prefix = serverSide() ? SSLManager::CFG_SERVER_PREFIX : SSLManager::CFG_CLIENT_PREFIX;
|
||||
if (!config.hasProperty(prefix + CFG_PRIV_KEY_FILE))
|
||||
throw Poco::Util::EmptyOptionException(std::string("Missing Configuration Entry: ") + prefix + CFG_PRIV_KEY_FILE);
|
||||
|
||||
privateKey = config.getString(prefix + CFG_PRIV_KEY_FILE);
|
||||
}
|
||||
catch (Poco::NullPointerException&)
|
||||
{
|
||||
throw Poco::IllegalStateException(
|
||||
"An application configuration is required to obtain the private key passphrase, "
|
||||
"but no Poco::Util::Application instance is available."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
44
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp
vendored
Normal file
44
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// PrivateKeyFactory.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: PrivateKeyFactory
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/PrivateKeyFactory.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
PrivateKeyFactory::PrivateKeyFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PrivateKeyFactory::~PrivateKeyFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PrivateKeyFactoryRegistrar::PrivateKeyFactoryRegistrar(const std::string& name, PrivateKeyFactory* pFactory)
|
||||
{
|
||||
SSLManager::instance().privateKeyFactoryMgr().setFactory(name, pFactory);
|
||||
}
|
||||
|
||||
|
||||
PrivateKeyFactoryRegistrar::~PrivateKeyFactoryRegistrar()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
67
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp
vendored
Normal file
67
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// PrivateKeyFactoryMgr.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: PrivateKeyFactoryMgr
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/PrivateKeyFactoryMgr.h"
|
||||
#include "Poco/Net/KeyFileHandler.h"
|
||||
#include "Poco/Net/KeyConsoleHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
PrivateKeyFactoryMgr::PrivateKeyFactoryMgr()
|
||||
{
|
||||
setFactory("KeyFileHandler", new PrivateKeyFactoryImpl<KeyFileHandler>());
|
||||
setFactory("KeyConsoleHandler", new PrivateKeyFactoryImpl<KeyConsoleHandler>());
|
||||
}
|
||||
|
||||
|
||||
PrivateKeyFactoryMgr::~PrivateKeyFactoryMgr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PrivateKeyFactoryMgr::setFactory(const std::string& name, PrivateKeyFactory* pFactory)
|
||||
{
|
||||
bool success = _factories.insert(make_pair(name, Poco::SharedPtr<PrivateKeyFactory>(pFactory))).second;
|
||||
if (!success)
|
||||
delete pFactory;
|
||||
poco_assert(success);
|
||||
}
|
||||
|
||||
|
||||
bool PrivateKeyFactoryMgr::hasFactory(const std::string& name) const
|
||||
{
|
||||
return _factories.find(name) != _factories.end();
|
||||
}
|
||||
|
||||
|
||||
const PrivateKeyFactory* PrivateKeyFactoryMgr::getFactory(const std::string& name) const
|
||||
{
|
||||
FactoriesMap::const_iterator it = _factories.find(name);
|
||||
if (it != _factories.end())
|
||||
return it->second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PrivateKeyFactoryMgr::removeFactory(const std::string& name)
|
||||
{
|
||||
_factories.erase(name);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
46
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp
vendored
Normal file
46
vendor/POCO/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// PrivateKeyPassphraseHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: PrivateKeyPassphraseHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Delegate.h"
|
||||
|
||||
|
||||
using Poco::Delegate;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
PrivateKeyPassphraseHandler::PrivateKeyPassphraseHandler(bool onServerSide): _serverSide(onServerSide)
|
||||
{
|
||||
SSLManager::instance().PrivateKeyPassphraseRequired += Delegate<PrivateKeyPassphraseHandler, std::string>(this, &PrivateKeyPassphraseHandler::onPrivateKeyRequested);
|
||||
}
|
||||
|
||||
|
||||
PrivateKeyPassphraseHandler::~PrivateKeyPassphraseHandler()
|
||||
{
|
||||
try
|
||||
{
|
||||
SSLManager::instance().PrivateKeyPassphraseRequired -= Delegate<PrivateKeyPassphraseHandler, std::string>(this, &PrivateKeyPassphraseHandler::onPrivateKeyRequested);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
38
vendor/POCO/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp
vendored
Normal file
38
vendor/POCO/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// RejectCertificateHandler.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: RejectCertificateHandler
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/RejectCertificateHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
RejectCertificateHandler::RejectCertificateHandler(bool server): InvalidCertificateHandler(server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RejectCertificateHandler::~RejectCertificateHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void RejectCertificateHandler::onInvalidCertificate(const void*, VerificationErrorArgs& errorCert)
|
||||
{
|
||||
errorCert.setIgnoreError(false);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
30
vendor/POCO/NetSSL_OpenSSL/src/SSLException.cpp
vendored
Normal file
30
vendor/POCO/NetSSL_OpenSSL/src/SSLException.cpp
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// SSLException.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: SSLException
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
POCO_IMPLEMENT_EXCEPTION(SSLException, NetException, "SSL Exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(SSLContextException, SSLException, "SSL context exception")
|
||||
POCO_IMPLEMENT_EXCEPTION(InvalidCertificateException, SSLException, "Invalid certficate")
|
||||
POCO_IMPLEMENT_EXCEPTION(CertificateValidationException, SSLException, "Certificate validation error")
|
||||
POCO_IMPLEMENT_EXCEPTION(SSLConnectionUnexpectedlyClosedException, SSLException, "SSL connection unexpectedly closed")
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
468
vendor/POCO/NetSSL_OpenSSL/src/SSLManager.cpp
vendored
Normal file
468
vendor/POCO/NetSSL_OpenSSL/src/SSLManager.cpp
vendored
Normal file
@ -0,0 +1,468 @@
|
||||
//
|
||||
// SSLManager.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: SSLManager
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/Utility.h"
|
||||
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
|
||||
#include "Poco/Net/RejectCertificateHandler.h"
|
||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/SingletonHolder.h"
|
||||
#include "Poco/Delegate.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/OptionException.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
const std::string SSLManager::CFG_PRIV_KEY_FILE("privateKeyFile");
|
||||
const std::string SSLManager::CFG_CERTIFICATE_FILE("certificateFile");
|
||||
const std::string SSLManager::CFG_CA_LOCATION("caConfig");
|
||||
const std::string SSLManager::CFG_VER_MODE("verificationMode");
|
||||
const Context::VerificationMode SSLManager::VAL_VER_MODE(Context::VERIFY_RELAXED);
|
||||
const std::string SSLManager::CFG_VER_DEPTH("verificationDepth");
|
||||
const int SSLManager::VAL_VER_DEPTH(9);
|
||||
const std::string SSLManager::CFG_ENABLE_DEFAULT_CA("loadDefaultCAFile");
|
||||
const bool SSLManager::VAL_ENABLE_DEFAULT_CA(true);
|
||||
const std::string SSLManager::CFG_CIPHER_LIST("cipherList");
|
||||
const std::string SSLManager::CFG_CYPHER_LIST("cypherList");
|
||||
const std::string SSLManager::VAL_CIPHER_LIST("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
|
||||
const std::string SSLManager::CFG_PREFER_SERVER_CIPHERS("preferServerCiphers");
|
||||
const std::string SSLManager::CFG_DELEGATE_HANDLER("privateKeyPassphraseHandler.name");
|
||||
const std::string SSLManager::VAL_DELEGATE_HANDLER("KeyConsoleHandler");
|
||||
const std::string SSLManager::CFG_CERTIFICATE_HANDLER("invalidCertificateHandler.name");
|
||||
const std::string SSLManager::VAL_CERTIFICATE_HANDLER("ConsoleCertificateHandler");
|
||||
const std::string SSLManager::CFG_SERVER_PREFIX("openSSL.server.");
|
||||
const std::string SSLManager::CFG_CLIENT_PREFIX("openSSL.client.");
|
||||
const std::string SSLManager::CFG_CACHE_SESSIONS("cacheSessions");
|
||||
const std::string SSLManager::CFG_SESSION_ID_CONTEXT("sessionIdContext");
|
||||
const std::string SSLManager::CFG_SESSION_CACHE_SIZE("sessionCacheSize");
|
||||
const std::string SSLManager::CFG_SESSION_TIMEOUT("sessionTimeout");
|
||||
const std::string SSLManager::CFG_EXTENDED_VERIFICATION("extendedVerification");
|
||||
const std::string SSLManager::CFG_REQUIRE_TLSV1("requireTLSv1");
|
||||
const std::string SSLManager::CFG_REQUIRE_TLSV1_1("requireTLSv1_1");
|
||||
const std::string SSLManager::CFG_REQUIRE_TLSV1_2("requireTLSv1_2");
|
||||
const std::string SSLManager::CFG_REQUIRE_TLSV1_3("requireTLSv1_3");
|
||||
const std::string SSLManager::CFG_DISABLE_PROTOCOLS("disableProtocols");
|
||||
const std::string SSLManager::CFG_DH_PARAMS_FILE("dhParamsFile");
|
||||
const std::string SSLManager::CFG_ECDH_CURVE("ecdhCurve");
|
||||
#ifdef OPENSSL_FIPS
|
||||
const std::string SSLManager::CFG_FIPS_MODE("openSSL.fips");
|
||||
const bool SSLManager::VAL_FIPS_MODE(false);
|
||||
#endif
|
||||
|
||||
|
||||
SSLManager::SSLManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SSLManager::~SSLManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::shutdown()
|
||||
{
|
||||
PrivateKeyPassphraseRequired.clear();
|
||||
ClientVerificationError.clear();
|
||||
ServerVerificationError.clear();
|
||||
_ptrDefaultServerContext = 0;
|
||||
_ptrDefaultClientContext = 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
static Poco::SingletonHolder<SSLManager> singleton;
|
||||
}
|
||||
|
||||
|
||||
SSLManager& SSLManager::instance()
|
||||
{
|
||||
return *singleton.get();
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initializeServer(PrivateKeyPassphraseHandlerPtr ptrPassphraseHandler, InvalidCertificateHandlerPtr ptrHandler, Context::Ptr ptrContext)
|
||||
{
|
||||
_ptrServerPassphraseHandler = ptrPassphraseHandler;
|
||||
_ptrServerCertificateHandler = ptrHandler;
|
||||
_ptrDefaultServerContext = ptrContext;
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initializeClient(PrivateKeyPassphraseHandlerPtr ptrPassphraseHandler, InvalidCertificateHandlerPtr ptrHandler, Context::Ptr ptrContext)
|
||||
{
|
||||
_ptrClientPassphraseHandler = ptrPassphraseHandler;
|
||||
_ptrClientCertificateHandler = ptrHandler;
|
||||
_ptrDefaultClientContext = ptrContext;
|
||||
}
|
||||
|
||||
|
||||
Context::Ptr SSLManager::defaultServerContext()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrDefaultServerContext)
|
||||
initDefaultContext(true);
|
||||
|
||||
return _ptrDefaultServerContext;
|
||||
}
|
||||
|
||||
|
||||
Context::Ptr SSLManager::defaultClientContext()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrDefaultClientContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
initDefaultContext(false);
|
||||
}
|
||||
catch (Poco::IllegalStateException&)
|
||||
{
|
||||
_ptrClientCertificateHandler = new RejectCertificateHandler(false);
|
||||
_ptrDefaultClientContext = new Context(Context::CLIENT_USE, "", Context::VERIFY_RELAXED, 9, true);
|
||||
_ptrDefaultClientContext->disableProtocols(Context::PROTO_SSLV2 | Context::PROTO_SSLV3);
|
||||
}
|
||||
}
|
||||
|
||||
return _ptrDefaultClientContext;
|
||||
}
|
||||
|
||||
|
||||
SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::serverPassphraseHandler()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrServerPassphraseHandler)
|
||||
initPassphraseHandler(true);
|
||||
|
||||
return _ptrServerPassphraseHandler;
|
||||
}
|
||||
|
||||
|
||||
SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::clientPassphraseHandler()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrClientPassphraseHandler)
|
||||
initPassphraseHandler(false);
|
||||
|
||||
return _ptrClientPassphraseHandler;
|
||||
}
|
||||
|
||||
|
||||
SSLManager::InvalidCertificateHandlerPtr SSLManager::serverCertificateHandler()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrServerCertificateHandler)
|
||||
initCertificateHandler(true);
|
||||
|
||||
return _ptrServerCertificateHandler;
|
||||
}
|
||||
|
||||
|
||||
SSLManager::InvalidCertificateHandlerPtr SSLManager::clientCertificateHandler()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (!_ptrClientCertificateHandler)
|
||||
initCertificateHandler(false);
|
||||
|
||||
return _ptrClientCertificateHandler;
|
||||
}
|
||||
|
||||
|
||||
int SSLManager::verifyCallback(bool server, int ok, X509_STORE_CTX* pStore)
|
||||
{
|
||||
if (!ok)
|
||||
{
|
||||
X509* pCert = X509_STORE_CTX_get_current_cert(pStore);
|
||||
X509Certificate x509(pCert, true);
|
||||
int depth = X509_STORE_CTX_get_error_depth(pStore);
|
||||
int err = X509_STORE_CTX_get_error(pStore);
|
||||
std::string error(X509_verify_cert_error_string(err));
|
||||
VerificationErrorArgs args(x509, depth, err, error);
|
||||
if (server)
|
||||
SSLManager::instance().ServerVerificationError.notify(&SSLManager::instance(), args);
|
||||
else
|
||||
SSLManager::instance().ClientVerificationError.notify(&SSLManager::instance(), args);
|
||||
ok = args.getIgnoreError() ? 1 : 0;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
int SSLManager::privateKeyPassphraseCallback(char* pBuf, int size, int flag, void* userData)
|
||||
{
|
||||
std::string pwd;
|
||||
SSLManager::instance().PrivateKeyPassphraseRequired.notify(&SSLManager::instance(), pwd);
|
||||
|
||||
strncpy(pBuf, (char *)(pwd.c_str()), size);
|
||||
pBuf[size - 1] = '\0';
|
||||
if (size > pwd.length())
|
||||
size = (int) pwd.length();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initDefaultContext(bool server)
|
||||
{
|
||||
if (server && _ptrDefaultServerContext) return;
|
||||
if (!server && _ptrDefaultClientContext) return;
|
||||
|
||||
Poco::Crypto::OpenSSLInitializer openSSLInitializer;
|
||||
initEvents(server);
|
||||
Poco::Util::AbstractConfiguration& config = appConfig();
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
bool fipsEnabled = config.getBool(CFG_FIPS_MODE, VAL_FIPS_MODE);
|
||||
if (fipsEnabled && !Poco::Crypto::OpenSSLInitializer::isFIPSEnabled())
|
||||
{
|
||||
Poco::Crypto::OpenSSLInitializer::enableFIPSMode(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string prefix = server ? CFG_SERVER_PREFIX : CFG_CLIENT_PREFIX;
|
||||
|
||||
Context::Params params;
|
||||
// mandatory options
|
||||
params.privateKeyFile = config.getString(prefix + CFG_PRIV_KEY_FILE, "");
|
||||
params.certificateFile = config.getString(prefix + CFG_CERTIFICATE_FILE, params.privateKeyFile);
|
||||
params.caLocation = config.getString(prefix + CFG_CA_LOCATION, "");
|
||||
|
||||
if (server && params.certificateFile.empty() && params.privateKeyFile.empty())
|
||||
throw SSLException("Configuration error: no certificate file has been specified");
|
||||
|
||||
// optional options for which we have defaults defined
|
||||
params.verificationMode = VAL_VER_MODE;
|
||||
if (config.hasProperty(prefix + CFG_VER_MODE))
|
||||
{
|
||||
// either: none, relaxed, strict, once
|
||||
std::string mode = config.getString(prefix + CFG_VER_MODE);
|
||||
params.verificationMode = Utility::convertVerificationMode(mode);
|
||||
}
|
||||
|
||||
params.verificationDepth = config.getInt(prefix + CFG_VER_DEPTH, VAL_VER_DEPTH);
|
||||
params.loadDefaultCAs = config.getBool(prefix + CFG_ENABLE_DEFAULT_CA, VAL_ENABLE_DEFAULT_CA);
|
||||
params.cipherList = config.getString(prefix + CFG_CIPHER_LIST, VAL_CIPHER_LIST);
|
||||
params.cipherList = config.getString(prefix + CFG_CYPHER_LIST, params.cipherList); // for backwards compatibility
|
||||
bool requireTLSv1 = config.getBool(prefix + CFG_REQUIRE_TLSV1, false);
|
||||
bool requireTLSv1_1 = config.getBool(prefix + CFG_REQUIRE_TLSV1_1, false);
|
||||
bool requireTLSv1_2 = config.getBool(prefix + CFG_REQUIRE_TLSV1_2, false);
|
||||
bool requireTLSv1_3 = config.getBool(prefix + CFG_REQUIRE_TLSV1_3, false);
|
||||
|
||||
params.dhParamsFile = config.getString(prefix + CFG_DH_PARAMS_FILE, "");
|
||||
params.ecdhCurve = config.getString(prefix + CFG_ECDH_CURVE, "");
|
||||
|
||||
Context::Usage usage;
|
||||
|
||||
if (server)
|
||||
{
|
||||
if (requireTLSv1_3)
|
||||
usage = Context::TLSV1_3_SERVER_USE;
|
||||
else if (requireTLSv1_2)
|
||||
usage = Context::TLSV1_2_SERVER_USE;
|
||||
else if (requireTLSv1_1)
|
||||
usage = Context::TLSV1_1_SERVER_USE;
|
||||
else if (requireTLSv1)
|
||||
usage = Context::TLSV1_SERVER_USE;
|
||||
else
|
||||
usage = Context::SERVER_USE;
|
||||
_ptrDefaultServerContext = new Context(usage, params);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (requireTLSv1_3)
|
||||
usage = Context::TLSV1_3_CLIENT_USE;
|
||||
else if (requireTLSv1_2)
|
||||
usage = Context::TLSV1_2_CLIENT_USE;
|
||||
else if (requireTLSv1_1)
|
||||
usage = Context::TLSV1_1_CLIENT_USE;
|
||||
else if (requireTLSv1)
|
||||
usage = Context::TLSV1_CLIENT_USE;
|
||||
else
|
||||
usage = Context::CLIENT_USE;
|
||||
_ptrDefaultClientContext = new Context(usage, params);
|
||||
}
|
||||
|
||||
std::string disabledProtocolsList = config.getString(prefix + CFG_DISABLE_PROTOCOLS, "");
|
||||
Poco::StringTokenizer dpTok(disabledProtocolsList, ";,", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||
int disabledProtocols = 0;
|
||||
for (Poco::StringTokenizer::Iterator it = dpTok.begin(); it != dpTok.end(); ++it)
|
||||
{
|
||||
if (*it == "sslv2")
|
||||
disabledProtocols |= Context::PROTO_SSLV2;
|
||||
else if (*it == "sslv3")
|
||||
disabledProtocols |= Context::PROTO_SSLV3;
|
||||
else if (*it == "tlsv1")
|
||||
disabledProtocols |= Context::PROTO_TLSV1;
|
||||
else if (*it == "tlsv1_1")
|
||||
disabledProtocols |= Context::PROTO_TLSV1_1;
|
||||
else if (*it == "tlsv1_2")
|
||||
disabledProtocols |= Context::PROTO_TLSV1_2;
|
||||
else if (*it == "tlsv1_3")
|
||||
disabledProtocols |= Context::PROTO_TLSV1_3;
|
||||
}
|
||||
if (server)
|
||||
_ptrDefaultServerContext->disableProtocols(disabledProtocols);
|
||||
else
|
||||
_ptrDefaultClientContext->disableProtocols(disabledProtocols);
|
||||
|
||||
bool cacheSessions = config.getBool(prefix + CFG_CACHE_SESSIONS, false);
|
||||
if (server)
|
||||
{
|
||||
std::string sessionIdContext = config.getString(prefix + CFG_SESSION_ID_CONTEXT, config.getString("application.name", ""));
|
||||
_ptrDefaultServerContext->enableSessionCache(cacheSessions, sessionIdContext);
|
||||
if (config.hasProperty(prefix + CFG_SESSION_CACHE_SIZE))
|
||||
{
|
||||
int cacheSize = config.getInt(prefix + CFG_SESSION_CACHE_SIZE);
|
||||
_ptrDefaultServerContext->setSessionCacheSize(cacheSize);
|
||||
}
|
||||
if (config.hasProperty(prefix + CFG_SESSION_TIMEOUT))
|
||||
{
|
||||
int timeout = config.getInt(prefix + CFG_SESSION_TIMEOUT);
|
||||
_ptrDefaultServerContext->setSessionTimeout(timeout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ptrDefaultClientContext->enableSessionCache(cacheSessions);
|
||||
}
|
||||
bool extendedVerification = config.getBool(prefix + CFG_EXTENDED_VERIFICATION, false);
|
||||
if (server)
|
||||
_ptrDefaultServerContext->enableExtendedCertificateVerification(extendedVerification);
|
||||
else
|
||||
_ptrDefaultClientContext->enableExtendedCertificateVerification(extendedVerification);
|
||||
|
||||
bool preferServerCiphers = config.getBool(prefix + CFG_PREFER_SERVER_CIPHERS, false);
|
||||
if (preferServerCiphers)
|
||||
{
|
||||
if (server)
|
||||
_ptrDefaultServerContext->preferServerCiphers();
|
||||
else
|
||||
_ptrDefaultClientContext->preferServerCiphers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initEvents(bool server)
|
||||
{
|
||||
initPassphraseHandler(server);
|
||||
initCertificateHandler(server);
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initPassphraseHandler(bool server)
|
||||
{
|
||||
if (server && _ptrServerPassphraseHandler) return;
|
||||
if (!server && _ptrClientPassphraseHandler) return;
|
||||
|
||||
std::string prefix = server ? CFG_SERVER_PREFIX : CFG_CLIENT_PREFIX;
|
||||
Poco::Util::AbstractConfiguration& config = appConfig();
|
||||
|
||||
std::string className(config.getString(prefix + CFG_DELEGATE_HANDLER, VAL_DELEGATE_HANDLER));
|
||||
|
||||
const PrivateKeyFactory* pFactory = 0;
|
||||
if (privateKeyFactoryMgr().hasFactory(className))
|
||||
{
|
||||
pFactory = privateKeyFactoryMgr().getFactory(className);
|
||||
}
|
||||
|
||||
if (pFactory)
|
||||
{
|
||||
if (server)
|
||||
_ptrServerPassphraseHandler = pFactory->create(server);
|
||||
else
|
||||
_ptrClientPassphraseHandler = pFactory->create(server);
|
||||
}
|
||||
else throw Poco::Util::UnknownOptionException(std::string("No passphrase handler known with the name ") + className);
|
||||
}
|
||||
|
||||
|
||||
void SSLManager::initCertificateHandler(bool server)
|
||||
{
|
||||
if (server && _ptrServerCertificateHandler) return;
|
||||
if (!server && _ptrClientCertificateHandler) return;
|
||||
|
||||
std::string prefix = server ? CFG_SERVER_PREFIX : CFG_CLIENT_PREFIX;
|
||||
Poco::Util::AbstractConfiguration& config = appConfig();
|
||||
|
||||
std::string className(config.getString(prefix+CFG_CERTIFICATE_HANDLER, VAL_CERTIFICATE_HANDLER));
|
||||
|
||||
const CertificateHandlerFactory* pFactory = 0;
|
||||
if (certificateHandlerFactoryMgr().hasFactory(className))
|
||||
{
|
||||
pFactory = certificateHandlerFactoryMgr().getFactory(className);
|
||||
}
|
||||
|
||||
if (pFactory)
|
||||
{
|
||||
if (server)
|
||||
_ptrServerCertificateHandler = pFactory->create(true);
|
||||
else
|
||||
_ptrClientCertificateHandler = pFactory->create(false);
|
||||
}
|
||||
else throw Poco::Util::UnknownOptionException(std::string("No InvalidCertificate handler known with the name ") + className);
|
||||
}
|
||||
|
||||
|
||||
Poco::Util::AbstractConfiguration& SSLManager::appConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Poco::Util::Application::instance().config();
|
||||
}
|
||||
catch (Poco::NullPointerException&)
|
||||
{
|
||||
throw Poco::IllegalStateException(
|
||||
"An application configuration is required to initialize the Poco::Net::SSLManager, "
|
||||
"but no Poco::Util::Application instance is available."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initializeSSL()
|
||||
{
|
||||
Poco::Crypto::initializeCrypto();
|
||||
}
|
||||
|
||||
|
||||
void uninitializeSSL()
|
||||
{
|
||||
SSLManager::instance().shutdown();
|
||||
Poco::Crypto::uninitializeCrypto();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
63
vendor/POCO/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp
vendored
Normal file
63
vendor/POCO/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// SecureSMTPClientSession.h
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: Mail
|
||||
// Module: SecureSMTPClientSession
|
||||
//
|
||||
// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureSMTPClientSession.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/DialogSocket.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureSMTPClientSession::SecureSMTPClientSession(const StreamSocket& socket):
|
||||
SMTPClientSession(socket)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureSMTPClientSession::SecureSMTPClientSession(const std::string& host, Poco::UInt16 port):
|
||||
SMTPClientSession(host, port)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureSMTPClientSession::~SecureSMTPClientSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool SecureSMTPClientSession::startTLS()
|
||||
{
|
||||
return startTLS(SSLManager::instance().defaultClientContext());
|
||||
}
|
||||
|
||||
|
||||
bool SecureSMTPClientSession::startTLS(Context::Ptr pContext)
|
||||
{
|
||||
int status = 0;
|
||||
std::string response;
|
||||
|
||||
status = sendCommand("STARTTLS", response);
|
||||
if (!isPositiveCompletion(status)) return false;
|
||||
|
||||
SecureStreamSocket sss(SecureStreamSocket::attach(socket(), host(), pContext));
|
||||
socket() = sss;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
121
vendor/POCO/NetSSL_OpenSSL/src/SecureServerSocket.cpp
vendored
Normal file
121
vendor/POCO/NetSSL_OpenSSL/src/SecureServerSocket.cpp
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
//
|
||||
// SecureServerSocket.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLSockets
|
||||
// Module: SecureServerSocket
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureServerSocket.h"
|
||||
#include "Poco/Net/SecureServerSocketImpl.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
using Poco::InvalidArgumentException;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket():
|
||||
ServerSocket(new SecureServerSocketImpl(SSLManager::instance().defaultServerContext()), true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket(Context::Ptr pContext):
|
||||
ServerSocket(new SecureServerSocketImpl(pContext), true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket(const Socket& socket):
|
||||
ServerSocket(socket)
|
||||
{
|
||||
if (!dynamic_cast<SecureServerSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket(const SocketAddress& address, int backlog):
|
||||
ServerSocket(new SecureServerSocketImpl(SSLManager::instance().defaultServerContext()), true)
|
||||
{
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket(const SocketAddress& address, int backlog, Context::Ptr pContext):
|
||||
ServerSocket(new SecureServerSocketImpl(pContext), true)
|
||||
{
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::SecureServerSocket(Poco::UInt16 port, int backlog):
|
||||
ServerSocket(new SecureServerSocketImpl(SSLManager::instance().defaultServerContext()), true)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
SecureServerSocket::SecureServerSocket(Poco::UInt16 port, int backlog, Context::Ptr pContext):
|
||||
ServerSocket(new SecureServerSocketImpl(pContext), true)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, true);
|
||||
impl()->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket::~SecureServerSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocket& SecureServerSocket::operator = (const Socket& socket)
|
||||
{
|
||||
if (&socket != this)
|
||||
{
|
||||
if (dynamic_cast<SecureServerSocketImpl*>(socket.impl()))
|
||||
ServerSocket::operator = (socket);
|
||||
else
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
StreamSocket SecureServerSocket::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
return SecureStreamSocket(impl()->acceptConnection(clientAddr));
|
||||
}
|
||||
|
||||
|
||||
StreamSocket SecureServerSocket::acceptConnection()
|
||||
{
|
||||
SocketAddress clientAddr;
|
||||
return SecureStreamSocket(impl()->acceptConnection(clientAddr));
|
||||
}
|
||||
|
||||
|
||||
Context::Ptr SecureServerSocket::context() const
|
||||
{
|
||||
return static_cast<SecureServerSocketImpl*>(impl())->context();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
122
vendor/POCO/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp
vendored
Normal file
122
vendor/POCO/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// SecureServerSocketImpl.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLSockets
|
||||
// Module: SecureServerSocketImpl
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureServerSocketImpl.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureServerSocketImpl::SecureServerSocketImpl(Context::Ptr pContext):
|
||||
_impl(new ServerSocketImpl, pContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureServerSocketImpl::~SecureServerSocketImpl()
|
||||
{
|
||||
try
|
||||
{
|
||||
reset();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SocketImpl* SecureServerSocketImpl::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
return _impl.acceptConnection(clientAddr);
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::connect(const SocketAddress& address)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot connect() a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot connect() a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::connectNB(const SocketAddress& address)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot connect() a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
_impl.bind(address, reuseAddress, reusePort);
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::listen(int backlog)
|
||||
{
|
||||
_impl.listen(backlog);
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::close()
|
||||
{
|
||||
reset();
|
||||
_impl.close();
|
||||
}
|
||||
|
||||
|
||||
int SecureServerSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot sendBytes() on a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
int SecureServerSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot receiveBytes() on a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
int SecureServerSocketImpl::sendTo(const void* buffer, int length, const SocketAddress& address, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot sendTo() on a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
int SecureServerSocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot receiveFrom() on a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
void SecureServerSocketImpl::sendUrgent(unsigned char data)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot sendUrgent() on a SecureServerSocket");
|
||||
}
|
||||
|
||||
|
||||
bool SecureServerSocketImpl::secure() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
554
vendor/POCO/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
vendored
Normal file
554
vendor/POCO/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
vendored
Normal file
@ -0,0 +1,554 @@
|
||||
//
|
||||
// SecureSocketImpl.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLSockets
|
||||
// Module: SecureSocketImpl
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureSocketImpl.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/X509Certificate.h"
|
||||
#include "Poco/Net/Utility.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/StreamSocketImpl.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/DNS.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/Format.h"
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
using Poco::IOException;
|
||||
using Poco::TimeoutException;
|
||||
using Poco::InvalidArgumentException;
|
||||
using Poco::NumberFormatter;
|
||||
using Poco::Timespan;
|
||||
|
||||
|
||||
// workaround for C++-incompatible macro
|
||||
#define POCO_BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(void*)((n)?"a":NULL))
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext):
|
||||
_pSSL(0),
|
||||
_pSocket(pSocketImpl),
|
||||
_pContext(pContext),
|
||||
_needHandshake(false)
|
||||
{
|
||||
poco_check_ptr (_pSocket);
|
||||
poco_check_ptr (_pContext);
|
||||
}
|
||||
|
||||
|
||||
SecureSocketImpl::~SecureSocketImpl()
|
||||
{
|
||||
try
|
||||
{
|
||||
reset();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SocketImpl* SecureSocketImpl::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
poco_assert (!_pSSL);
|
||||
|
||||
StreamSocket ss = _pSocket->acceptConnection(clientAddr);
|
||||
Poco::AutoPtr<SecureStreamSocketImpl> pSecureStreamSocketImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(ss.impl()), _pContext);
|
||||
pSecureStreamSocketImpl->acceptSSL();
|
||||
pSecureStreamSocketImpl->duplicate();
|
||||
return pSecureStreamSocketImpl;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::acceptSSL()
|
||||
{
|
||||
poco_assert (!_pSSL);
|
||||
|
||||
BIO* pBIO = BIO_new(BIO_s_socket());
|
||||
if (!pBIO) throw SSLException("Cannot create BIO object");
|
||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||
|
||||
_pSSL = SSL_new(_pContext->sslContext());
|
||||
if (!_pSSL)
|
||||
{
|
||||
BIO_free(pBIO);
|
||||
throw SSLException("Cannot create SSL object");
|
||||
}
|
||||
SSL_set_bio(_pSSL, pBIO, pBIO);
|
||||
SSL_set_accept_state(_pSSL);
|
||||
_needHandshake = true;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::connect(const SocketAddress& address, bool performHandshake)
|
||||
{
|
||||
if (_pSSL) reset();
|
||||
|
||||
poco_assert (!_pSSL);
|
||||
|
||||
_pSocket->connect(address);
|
||||
connectSSL(performHandshake);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake)
|
||||
{
|
||||
if (_pSSL) reset();
|
||||
|
||||
poco_assert (!_pSSL);
|
||||
|
||||
_pSocket->connect(address, timeout);
|
||||
Poco::Timespan receiveTimeout = _pSocket->getReceiveTimeout();
|
||||
Poco::Timespan sendTimeout = _pSocket->getSendTimeout();
|
||||
_pSocket->setReceiveTimeout(timeout);
|
||||
_pSocket->setSendTimeout(timeout);
|
||||
connectSSL(performHandshake);
|
||||
_pSocket->setReceiveTimeout(receiveTimeout);
|
||||
_pSocket->setSendTimeout(sendTimeout);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::connectNB(const SocketAddress& address)
|
||||
{
|
||||
if (_pSSL) reset();
|
||||
|
||||
poco_assert (!_pSSL);
|
||||
|
||||
_pSocket->connectNB(address);
|
||||
connectSSL(false);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::connectSSL(bool performHandshake)
|
||||
{
|
||||
poco_assert (!_pSSL);
|
||||
poco_assert (_pSocket->initialized());
|
||||
|
||||
BIO* pBIO = BIO_new(BIO_s_socket());
|
||||
if (!pBIO) throw SSLException("Cannot create SSL BIO object");
|
||||
BIO_set_fd(pBIO, static_cast<int>(_pSocket->sockfd()), BIO_NOCLOSE);
|
||||
|
||||
_pSSL = SSL_new(_pContext->sslContext());
|
||||
if (!_pSSL)
|
||||
{
|
||||
BIO_free(pBIO);
|
||||
throw SSLException("Cannot create SSL object");
|
||||
}
|
||||
SSL_set_bio(_pSSL, pBIO, pBIO);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0908060L && !defined(OPENSSL_NO_TLSEXT)
|
||||
if (!_peerHostName.empty())
|
||||
{
|
||||
SSL_set_tlsext_host_name(_pSSL, _peerHostName.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_pSession)
|
||||
{
|
||||
SSL_set_session(_pSSL, _pSession->sslSession());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (performHandshake && _pSocket->getBlocking())
|
||||
{
|
||||
int ret = SSL_connect(_pSSL);
|
||||
handleError(ret);
|
||||
verifyPeerCertificate();
|
||||
}
|
||||
else
|
||||
{
|
||||
SSL_set_connect_state(_pSSL);
|
||||
_needHandshake = true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
SSL_free(_pSSL);
|
||||
_pSSL = 0;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
poco_check_ptr (_pSocket);
|
||||
|
||||
_pSocket->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::listen(int backlog)
|
||||
{
|
||||
poco_check_ptr (_pSocket);
|
||||
|
||||
_pSocket->listen(backlog);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::shutdown()
|
||||
{
|
||||
if (_pSSL)
|
||||
{
|
||||
// Don't shut down the socket more than once.
|
||||
int shutdownState = SSL_get_shutdown(_pSSL);
|
||||
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
|
||||
if (!shutdownSent)
|
||||
{
|
||||
// A proper clean shutdown would require us to
|
||||
// retry the shutdown if we get a zero return
|
||||
// value, until SSL_shutdown() returns 1.
|
||||
// However, this will lead to problems with
|
||||
// most web browsers, so we just set the shutdown
|
||||
// flag by calling SSL_shutdown() once and be
|
||||
// done with it.
|
||||
int rc = SSL_shutdown(_pSSL);
|
||||
if (rc < 0) handleError(rc);
|
||||
if (_pSocket->getBlocking())
|
||||
{
|
||||
_pSocket->shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::close()
|
||||
{
|
||||
try
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
_pSocket->close();
|
||||
}
|
||||
|
||||
|
||||
int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
poco_assert (_pSocket->initialized());
|
||||
poco_check_ptr (_pSSL);
|
||||
|
||||
int rc;
|
||||
if (_needHandshake)
|
||||
{
|
||||
rc = completeHandshake();
|
||||
if (rc == 1)
|
||||
verifyPeerCertificate();
|
||||
else if (rc == 0)
|
||||
throw SSLConnectionUnexpectedlyClosedException();
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
do
|
||||
{
|
||||
rc = SSL_write(_pSSL, buffer, length);
|
||||
}
|
||||
while (mustRetry(rc));
|
||||
if (rc <= 0)
|
||||
{
|
||||
rc = handleError(rc);
|
||||
if (rc == 0) throw SSLConnectionUnexpectedlyClosedException();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
poco_assert (_pSocket->initialized());
|
||||
poco_check_ptr (_pSSL);
|
||||
|
||||
int rc;
|
||||
if (_needHandshake)
|
||||
{
|
||||
rc = completeHandshake();
|
||||
if (rc == 1)
|
||||
verifyPeerCertificate();
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
do
|
||||
{
|
||||
rc = SSL_read(_pSSL, buffer, length);
|
||||
}
|
||||
while (mustRetry(rc));
|
||||
if (rc <= 0)
|
||||
{
|
||||
return handleError(rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int SecureSocketImpl::available() const
|
||||
{
|
||||
poco_check_ptr (_pSSL);
|
||||
|
||||
return SSL_pending(_pSSL);
|
||||
}
|
||||
|
||||
|
||||
int SecureSocketImpl::completeHandshake()
|
||||
{
|
||||
poco_assert (_pSocket->initialized());
|
||||
poco_check_ptr (_pSSL);
|
||||
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
rc = SSL_do_handshake(_pSSL);
|
||||
}
|
||||
while (mustRetry(rc));
|
||||
if (rc <= 0)
|
||||
{
|
||||
return handleError(rc);
|
||||
}
|
||||
_needHandshake = false;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::verifyPeerCertificate()
|
||||
{
|
||||
if (_peerHostName.empty())
|
||||
verifyPeerCertificate(_pSocket->peerAddress().host().toString());
|
||||
else
|
||||
verifyPeerCertificate(_peerHostName);
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::verifyPeerCertificate(const std::string& hostName)
|
||||
{
|
||||
long certErr = verifyPeerCertificateImpl(hostName);
|
||||
if (certErr != X509_V_OK)
|
||||
{
|
||||
std::string msg = Utility::convertCertificateError(certErr);
|
||||
throw CertificateValidationException("Unacceptable certificate from " + hostName, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long SecureSocketImpl::verifyPeerCertificateImpl(const std::string& hostName)
|
||||
{
|
||||
Context::VerificationMode mode = _pContext->verificationMode();
|
||||
if (mode == Context::VERIFY_NONE || !_pContext->extendedCertificateVerificationEnabled() ||
|
||||
(mode != Context::VERIFY_STRICT && isLocalHost(hostName)))
|
||||
{
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
X509* pCert = SSL_get_peer_certificate(_pSSL);
|
||||
if (pCert)
|
||||
{
|
||||
X509Certificate cert(pCert);
|
||||
return cert.verify(hostName) ? X509_V_OK : X509_V_ERR_APPLICATION_VERIFICATION;
|
||||
}
|
||||
else return X509_V_OK;
|
||||
}
|
||||
|
||||
|
||||
bool SecureSocketImpl::isLocalHost(const std::string& hostName)
|
||||
{
|
||||
try
|
||||
{
|
||||
SocketAddress addr(hostName, 0);
|
||||
return addr.host().isLoopback();
|
||||
}
|
||||
catch (Poco::Exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
X509* SecureSocketImpl::peerCertificate() const
|
||||
{
|
||||
if (_pSSL)
|
||||
return SSL_get_peer_certificate(_pSSL);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool SecureSocketImpl::mustRetry(int rc)
|
||||
{
|
||||
if (rc <= 0)
|
||||
{
|
||||
int sslError = SSL_get_error(_pSSL, rc);
|
||||
int socketError = _pSocket->lastError();
|
||||
switch (sslError)
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (_pSocket->getBlocking())
|
||||
{
|
||||
if (_pSocket->poll(_pSocket->getReceiveTimeout(), Poco::Net::Socket::SELECT_READ))
|
||||
return true;
|
||||
else
|
||||
throw Poco::TimeoutException();
|
||||
}
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (_pSocket->getBlocking())
|
||||
{
|
||||
if (_pSocket->poll(_pSocket->getSendTimeout(), Poco::Net::Socket::SELECT_WRITE))
|
||||
return true;
|
||||
else
|
||||
throw Poco::TimeoutException();
|
||||
}
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
return socketError == POCO_EAGAIN || socketError == POCO_EINTR;
|
||||
default:
|
||||
return socketError == POCO_EINTR;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int SecureSocketImpl::handleError(int rc)
|
||||
{
|
||||
if (rc > 0) return rc;
|
||||
|
||||
int sslError = SSL_get_error(_pSSL, rc);
|
||||
int error = SocketImpl::lastError();
|
||||
|
||||
switch (sslError)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return 0;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return SecureStreamSocket::ERR_SSL_WANT_READ;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return SecureStreamSocket::ERR_SSL_WANT_WRITE;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
// these should not occur
|
||||
poco_bugcheck();
|
||||
return rc;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (error != 0)
|
||||
{
|
||||
SocketImpl::error(error);
|
||||
}
|
||||
// fallthrough
|
||||
default:
|
||||
{
|
||||
long lastError = ERR_get_error();
|
||||
if (lastError == 0)
|
||||
{
|
||||
if (rc == 0)
|
||||
{
|
||||
// Most web browsers do this, don't report an error
|
||||
if (_pContext->isForServerUse())
|
||||
return 0;
|
||||
else
|
||||
throw SSLConnectionUnexpectedlyClosedException();
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
throw SSLConnectionUnexpectedlyClosedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
SecureStreamSocketImpl::error(Poco::format("The BIO reported an error: %d", rc));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[256];
|
||||
ERR_error_string_n(lastError, buffer, sizeof(buffer));
|
||||
std::string msg(buffer);
|
||||
throw SSLException(msg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::setPeerHostName(const std::string& peerHostName)
|
||||
{
|
||||
_peerHostName = peerHostName;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::reset()
|
||||
{
|
||||
close();
|
||||
if (_pSSL)
|
||||
{
|
||||
SSL_free(_pSSL);
|
||||
_pSSL = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::abort()
|
||||
{
|
||||
_pSocket->shutdown();
|
||||
}
|
||||
|
||||
|
||||
Session::Ptr SecureSocketImpl::currentSession()
|
||||
{
|
||||
if (_pSSL)
|
||||
{
|
||||
SSL_SESSION* pSession = SSL_get1_session(_pSSL);
|
||||
if (pSession)
|
||||
{
|
||||
if (_pSession && pSession == _pSession->sslSession())
|
||||
{
|
||||
SSL_SESSION_free(pSession);
|
||||
return _pSession;
|
||||
}
|
||||
else return new Session(pSession);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SecureSocketImpl::useSession(Session::Ptr pSession)
|
||||
{
|
||||
_pSession = pSession;
|
||||
}
|
||||
|
||||
|
||||
bool SecureSocketImpl::sessionWasReused()
|
||||
{
|
||||
if (_pSSL)
|
||||
return SSL_session_reused(_pSSL) != 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
287
vendor/POCO/NetSSL_OpenSSL/src/SecureStreamSocket.cpp
vendored
Normal file
287
vendor/POCO/NetSSL_OpenSSL/src/SecureStreamSocket.cpp
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
//
|
||||
// SecureStreamSocket.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLSockets
|
||||
// Module: SecureStreamSocket
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SocketImpl.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
using Poco::InvalidArgumentException;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket():
|
||||
StreamSocket(new SecureStreamSocketImpl(SSLManager::instance().defaultClientContext()))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(Context::Ptr pContext):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(Context::Ptr pContext, Session::Ptr pSession):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
useSession(pSession);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address):
|
||||
StreamSocket(new SecureStreamSocketImpl(SSLManager::instance().defaultClientContext()))
|
||||
{
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::string& hostName):
|
||||
StreamSocket(new SecureStreamSocketImpl(SSLManager::instance().defaultClientContext()))
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext, Session::Ptr pSession):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
useSession(pSession);
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession):
|
||||
StreamSocket(new SecureStreamSocketImpl(pContext))
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
|
||||
useSession(pSession);
|
||||
connect(address);
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(const Socket& socket):
|
||||
StreamSocket(socket)
|
||||
{
|
||||
if (!dynamic_cast<SecureStreamSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::SecureStreamSocket(SocketImpl* pImpl):
|
||||
StreamSocket(pImpl)
|
||||
{
|
||||
if (!dynamic_cast<SecureStreamSocketImpl*>(impl()))
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket::~SecureStreamSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket& SecureStreamSocket::operator = (const Socket& socket)
|
||||
{
|
||||
if (dynamic_cast<SecureStreamSocketImpl*>(socket.impl()))
|
||||
StreamSocket::operator = (socket);
|
||||
else
|
||||
throw InvalidArgumentException("Cannot assign incompatible socket");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocket::havePeerCertificate() const
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->havePeerCertificate();
|
||||
}
|
||||
|
||||
|
||||
X509Certificate SecureStreamSocket::peerCertificate() const
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->peerCertificate();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::setPeerHostName(const std::string& hostName)
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->setPeerHostName(hostName);
|
||||
}
|
||||
|
||||
|
||||
const std::string& SecureStreamSocket::getPeerHostName() const
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->getPeerHostName();
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), SSLManager::instance().defaultClientContext());
|
||||
SecureStreamSocket result(pImpl);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket, Context::Ptr pContext)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), pContext);
|
||||
SecureStreamSocket result(pImpl);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket, Context::Ptr pContext, Session::Ptr pSession)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), pContext);
|
||||
SecureStreamSocket result(pImpl);
|
||||
result.useSession(pSession);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket, const std::string& peerHostName)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), SSLManager::instance().defaultClientContext());
|
||||
SecureStreamSocket result(pImpl);
|
||||
result.setPeerHostName(peerHostName);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), pContext);
|
||||
SecureStreamSocket result(pImpl);
|
||||
result.setPeerHostName(peerHostName);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocket SecureStreamSocket::attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext, Session::Ptr pSession)
|
||||
{
|
||||
SecureStreamSocketImpl* pImpl = new SecureStreamSocketImpl(static_cast<StreamSocketImpl*>(streamSocket.impl()), pContext);
|
||||
SecureStreamSocket result(pImpl);
|
||||
result.setPeerHostName(peerHostName);
|
||||
result.useSession(pSession);
|
||||
if (pImpl->context()->isForServerUse())
|
||||
pImpl->acceptSSL();
|
||||
else
|
||||
pImpl->connectSSL();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Context::Ptr SecureStreamSocket::context() const
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->context();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::setLazyHandshake(bool flag)
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->setLazyHandshake(flag);
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocket::getLazyHandshake() const
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->getLazyHandshake();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::verifyPeerCertificate()
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->verifyPeerCertificate();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::verifyPeerCertificate(const std::string& hostName)
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->verifyPeerCertificate(hostName);
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocket::completeHandshake()
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->completeHandshake();
|
||||
}
|
||||
|
||||
|
||||
Session::Ptr SecureStreamSocket::currentSession()
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->currentSession();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::useSession(Session::Ptr pSession)
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->useSession(pSession);
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocket::sessionWasReused()
|
||||
{
|
||||
return static_cast<SecureStreamSocketImpl*>(impl())->sessionWasReused();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocket::abort()
|
||||
{
|
||||
static_cast<SecureStreamSocketImpl*>(impl())->abort();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
228
vendor/POCO/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp
vendored
Normal file
228
vendor/POCO/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
//
|
||||
// SecureStreamSocketImpl.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLSockets
|
||||
// Module: SecureStreamSocketImpl
|
||||
//
|
||||
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Thread.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
SecureStreamSocketImpl::SecureStreamSocketImpl(Context::Ptr pContext):
|
||||
_impl(new StreamSocketImpl, pContext),
|
||||
_lazyHandshake(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocketImpl::SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext):
|
||||
_impl(pStreamSocket, pContext),
|
||||
_lazyHandshake(false)
|
||||
{
|
||||
pStreamSocket->duplicate();
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
SecureStreamSocketImpl::~SecureStreamSocketImpl()
|
||||
{
|
||||
try
|
||||
{
|
||||
reset();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
poco_unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SocketImpl* SecureStreamSocketImpl::acceptConnection(SocketAddress& clientAddr)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot acceptConnection() on a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::acceptSSL()
|
||||
{
|
||||
_impl.acceptSSL();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::connect(const SocketAddress& address)
|
||||
{
|
||||
_impl.connect(address, !_lazyHandshake);
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout)
|
||||
{
|
||||
_impl.connect(address, timeout, !_lazyHandshake);
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::connectNB(const SocketAddress& address)
|
||||
{
|
||||
_impl.connectNB(address);
|
||||
reset(_impl.sockfd());
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::connectSSL()
|
||||
{
|
||||
_impl.connectSSL(!_lazyHandshake);
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind() a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::listen(int backlog)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot listen() on a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::close()
|
||||
{
|
||||
reset();
|
||||
_impl.close();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::abort()
|
||||
{
|
||||
reset();
|
||||
_impl.abort();
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return _impl.sendBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||
{
|
||||
return _impl.receiveBytes(buffer, length, flags);
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::sendTo(const void* buffer, int length, const SocketAddress& address, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot sendTo() on a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, int flags)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot receiveFrom() on a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::sendUrgent(unsigned char data)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot sendUrgent() on a SecureStreamSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::available()
|
||||
{
|
||||
return _impl.available();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::shutdownReceive()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::shutdownSend()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::shutdown()
|
||||
{
|
||||
_impl.shutdown();
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocketImpl::secure() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocketImpl::havePeerCertificate() const
|
||||
{
|
||||
X509* pCert = _impl.peerCertificate();
|
||||
if (pCert)
|
||||
{
|
||||
X509_free(pCert);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
X509Certificate SecureStreamSocketImpl::peerCertificate() const
|
||||
{
|
||||
X509* pCert = _impl.peerCertificate();
|
||||
if (pCert)
|
||||
return X509Certificate(pCert);
|
||||
else
|
||||
throw SSLException("No certificate available");
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::setLazyHandshake(bool flag)
|
||||
{
|
||||
_lazyHandshake = flag;
|
||||
}
|
||||
|
||||
|
||||
bool SecureStreamSocketImpl::getLazyHandshake() const
|
||||
{
|
||||
return _lazyHandshake;
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::verifyPeerCertificate()
|
||||
{
|
||||
_impl.verifyPeerCertificate();
|
||||
}
|
||||
|
||||
|
||||
void SecureStreamSocketImpl::verifyPeerCertificate(const std::string& hostName)
|
||||
{
|
||||
_impl.verifyPeerCertificate(hostName);
|
||||
}
|
||||
|
||||
|
||||
int SecureStreamSocketImpl::completeHandshake()
|
||||
{
|
||||
return _impl.completeHandshake();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
40
vendor/POCO/NetSSL_OpenSSL/src/Session.cpp
vendored
Normal file
40
vendor/POCO/NetSSL_OpenSSL/src/Session.cpp
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Session.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: Session
|
||||
//
|
||||
// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// Some OpenSSL functions are deprecated in OS X 10.7
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
|
||||
#include "Poco/Net/Session.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
Session::Session(SSL_SESSION* pSession):
|
||||
_pSession(pSession)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
SSL_SESSION_free(_pSession);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
71
vendor/POCO/NetSSL_OpenSSL/src/Utility.cpp
vendored
Normal file
71
vendor/POCO/NetSSL_OpenSSL/src/Utility.cpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// Utility.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: Utility
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/Utility.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Util/OptionException.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
Context::VerificationMode Utility::convertVerificationMode(const std::string& vMode)
|
||||
{
|
||||
std::string mode = Poco::toLower(vMode);
|
||||
Context::VerificationMode verMode = Context::VERIFY_STRICT;
|
||||
|
||||
if (mode == "none")
|
||||
verMode = Context::VERIFY_NONE;
|
||||
else if (mode == "relaxed")
|
||||
verMode = Context::VERIFY_RELAXED;
|
||||
else if (mode == "strict")
|
||||
verMode = Context::VERIFY_STRICT;
|
||||
else if (mode == "once")
|
||||
verMode = Context::VERIFY_ONCE;
|
||||
else
|
||||
throw Poco::InvalidArgumentException("Invalid verification mode. Should be relaxed, strict or once but got", vMode);
|
||||
|
||||
return verMode;
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::convertCertificateError(long errCode)
|
||||
{
|
||||
std::string errMsg(X509_verify_cert_error_string(errCode));
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
void Utility::clearErrorStack()
|
||||
{
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
37
vendor/POCO/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp
vendored
Normal file
37
vendor/POCO/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// VerificationErrorArgs.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: VerificationErrorArgs
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/VerificationErrorArgs.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
VerificationErrorArgs::VerificationErrorArgs(const X509Certificate& cert, int errDepth, int errNum, const std::string& errMsg):
|
||||
_cert(cert),
|
||||
_errorDepth(errDepth),
|
||||
_errorNumber(errNum),
|
||||
_errorMessage(errMsg),
|
||||
_ignoreError(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VerificationErrorArgs::~VerificationErrorArgs()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
202
vendor/POCO/NetSSL_OpenSSL/src/X509Certificate.cpp
vendored
Normal file
202
vendor/POCO/NetSSL_OpenSSL/src/X509Certificate.cpp
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
//
|
||||
// X509Certificate.cpp
|
||||
//
|
||||
// Library: NetSSL_OpenSSL
|
||||
// Package: SSLCore
|
||||
// Module: X509Certificate
|
||||
//
|
||||
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Net/X509Certificate.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/DNS.h"
|
||||
#include "Poco/TemporaryFile.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/RegularExpression.h"
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(std::istream& istr):
|
||||
Poco::Crypto::X509Certificate(istr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(const std::string& path):
|
||||
Poco::Crypto::X509Certificate(path)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(X509* pCert):
|
||||
Poco::Crypto::X509Certificate(pCert)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(X509* pCert, bool shared):
|
||||
Poco::Crypto::X509Certificate(pCert, shared)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(const Poco::Crypto::X509Certificate& cert):
|
||||
Poco::Crypto::X509Certificate(cert)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(const X509Certificate& cert):
|
||||
Poco::Crypto::X509Certificate(cert)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(X509Certificate&& cert) noexcept:
|
||||
Poco::Crypto::X509Certificate(std::move(cert))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate& X509Certificate::operator = (const Poco::Crypto::X509Certificate& cert)
|
||||
{
|
||||
X509Certificate tmp(cert);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
X509Certificate& X509Certificate::operator = (const X509Certificate& cert)
|
||||
{
|
||||
X509Certificate tmp(cert);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
X509Certificate& X509Certificate::operator = (X509Certificate&& cert) noexcept
|
||||
{
|
||||
Poco::Crypto::X509Certificate::operator = (std::move(cert));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::~X509Certificate()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool X509Certificate::verify(const std::string& hostName) const
|
||||
{
|
||||
return verify(*this, hostName);
|
||||
}
|
||||
|
||||
|
||||
bool X509Certificate::verify(const Poco::Crypto::X509Certificate& certificate, const std::string& hostName)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
||||
std::string commonName;
|
||||
std::set<std::string> dnsNames;
|
||||
certificate.extractNames(commonName, dnsNames);
|
||||
if (!commonName.empty()) dnsNames.insert(commonName);
|
||||
bool ok = (dnsNames.find(hostName) != dnsNames.end());
|
||||
if (!ok)
|
||||
{
|
||||
for (std::set<std::string>::const_iterator it = dnsNames.begin(); !ok && it != dnsNames.end(); ++it)
|
||||
{
|
||||
try
|
||||
{
|
||||
// two cases: name contains wildcards or not
|
||||
if (containsWildcards(*it))
|
||||
{
|
||||
// a compare by IPAddress is not possible with wildcards
|
||||
// only allow compare by name
|
||||
ok = matchWildcard(*it, hostName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it depends on hostName whether we compare by IP or by alias
|
||||
IPAddress ip;
|
||||
if (IPAddress::tryParse(hostName, ip))
|
||||
{
|
||||
// compare by IP
|
||||
const HostEntry& heData = DNS::resolve(*it);
|
||||
const HostEntry::AddressList& addr = heData.addresses();
|
||||
HostEntry::AddressList::const_iterator it = addr.begin();
|
||||
HostEntry::AddressList::const_iterator itEnd = addr.end();
|
||||
for (; it != itEnd && !ok; ++it)
|
||||
{
|
||||
ok = (*it == ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = Poco::icompare(*it, hostName) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoAddressFoundException&)
|
||||
{
|
||||
}
|
||||
catch (HostNotFoundException&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
#else
|
||||
if (X509_check_host(const_cast<X509*>(certificate.certificate()), hostName.c_str(), hostName.length(), 0, NULL) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPAddress ip;
|
||||
if (IPAddress::tryParse(hostName, ip))
|
||||
{
|
||||
return (X509_check_ip_asc(const_cast<X509*>(certificate.certificate()), hostName.c_str(), 0) == 1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool X509Certificate::containsWildcards(const std::string& commonName)
|
||||
{
|
||||
return (commonName.find('*') != std::string::npos || commonName.find('?') != std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
bool X509Certificate::matchWildcard(const std::string& wildcard, const std::string& hostName)
|
||||
{
|
||||
// fix wildcards
|
||||
std::string wildcardExpr("^");
|
||||
wildcardExpr += Poco::replace(wildcard, ".", "\\.");
|
||||
Poco::replaceInPlace(wildcardExpr, "*", ".*");
|
||||
Poco::replaceInPlace(wildcardExpr, "..*", ".*");
|
||||
Poco::replaceInPlace(wildcardExpr, "?", ".?");
|
||||
Poco::replaceInPlace(wildcardExpr, "..?", ".?");
|
||||
wildcardExpr += "$";
|
||||
|
||||
Poco::RegularExpression expr(wildcardExpr, Poco::RegularExpression::RE_CASELESS);
|
||||
return expr.match(hostName);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
Reference in New Issue
Block a user