summaryrefslogtreecommitdiffstats
path: root/contrib/libs/poco/NetSSL_OpenSSL/src
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/NetSSL_OpenSSL/src
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/NetSSL_OpenSSL/src')
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp38
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp44
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp69
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp53
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/Context.cpp578
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSClientSession.cpp189
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp71
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp194
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp52
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp40
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/KeyFileHandler.cpp61
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp44
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp67
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp46
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp38
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SSLException.cpp30
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SSLManager.cpp460
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp64
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocket.cpp121
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp122
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp601
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocket.cpp287
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp241
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/Session.cpp40
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/Utility.cpp71
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp37
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/X509Certificate.cpp175
27 files changed, 3833 insertions, 0 deletions
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp
new file mode 100644
index 00000000000..84017f7c343
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/AcceptCertificateHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp
new file mode 100644
index 00000000000..8c517748be7
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactory.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp
new file mode 100644
index 00000000000..a89bbea11f2
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/CertificateHandlerFactoryMgr.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp
new file mode 100644
index 00000000000..db64752e70c
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/Context.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/Context.cpp
new file mode 100644
index 00000000000..2b16790ca44
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/Context.cpp
@@ -0,0 +1,578 @@
+//
+// 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")
+{
+}
+
+
+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.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::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
+ }
+}
+
+
+void Context::preferServerCiphers()
+{
+#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
+ SSL_CTX_set_options(_pSSLContext, SSL_OP_CIPHER_SERVER_PREFERENCE);
+#endif
+}
+
+
+void Context::createSSLContext()
+{
+ if (SSLManager::isFIPSEnabled())
+ {
+ _pSSLContext = SSL_CTX_new(TLSv1_method());
+ }
+ else
+ {
+ switch (_usage)
+ {
+ case CLIENT_USE:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ _pSSLContext = SSL_CTX_new(TLS_client_method());
+#else
+ _pSSLContext = SSL_CTX_new(SSLv23_client_method());
+#endif
+ break;
+ case SERVER_USE:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ _pSSLContext = SSL_CTX_new(TLS_server_method());
+#else
+ _pSSLContext = SSL_CTX_new(SSLv23_server_method());
+#endif
+ break;
+#if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1)
+ case TLSV1_CLIENT_USE:
+ _pSSLContext = SSL_CTX_new(TLSv1_client_method());
+ break;
+ case TLSV1_SERVER_USE:
+ _pSSLContext = SSL_CTX_new(TLSv1_server_method());
+ break;
+#endif
+#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:
+ _pSSLContext = SSL_CTX_new(TLSv1_1_client_method());
+ break;
+ case TLSV1_1_SERVER_USE:
+ _pSSLContext = SSL_CTX_new(TLSv1_1_server_method());
+ break;
+#endif
+#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
+ case TLSV1_2_CLIENT_USE:
+ _pSSLContext = SSL_CTX_new(TLSv1_2_client_method());
+ break;
+ case TLSV1_2_SERVER_USE:
+ _pSSLContext = SSL_CTX_new(TLSv1_2_server_method());
+ 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));
+ }
+
+ SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
+ Utility::clearErrorStack();
+ SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
+}
+
+
+void Context::initDH(const std::string& dhParamsFile)
+{
+#ifndef OPENSSL_NO_DH
+ // 1024-bit MODP Group with 160-bit prime order subgroup (RFC5114)
+ // -----BEGIN DH PARAMETERS-----
+ // MIIBDAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y
+ // mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4
+ // +qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV
+ // w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0
+ // sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR
+ // jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA=
+ // -----END DH PARAMETERS-----
+ //
+
+ 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,
+ };
+
+ 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 = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0);
+ BIGNUM* 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
+ 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)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#ifndef OPENSSL_NO_ECDH
+ 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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSClientSession.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSClientSession.cpp
new file mode 100644
index 00000000000..325f36a60a6
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSClientSession.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp
new file mode 100644
index 00000000000..fb8774d6549
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSSessionInstantiator.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
new file mode 100644
index 00000000000..6ef20e63ffd
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp
new file mode 100644
index 00000000000..7cf68613c47
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/InvalidCertificateHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp
new file mode 100644
index 00000000000..a0a144216e0
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/KeyConsoleHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/KeyFileHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/KeyFileHandler.cpp
new file mode 100644
index 00000000000..d188b4575cf
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/KeyFileHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp
new file mode 100644
index 00000000000..90297c351e5
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactory.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp
new file mode 100644
index 00000000000..94b4ad34ba9
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp
new file mode 100644
index 00000000000..9c1386c74c0
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/PrivateKeyPassphraseHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp
new file mode 100644
index 00000000000..1502a13e86d
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/RejectCertificateHandler.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SSLException.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SSLException.cpp
new file mode 100644
index 00000000000..2b64d2a4d63
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SSLException.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SSLManager.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SSLManager.cpp
new file mode 100644
index 00000000000..abb4389f26f
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SSLManager.cpp
@@ -0,0 +1,460 @@
+//
+// 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_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);
+
+ params.dhParamsFile = config.getString(prefix + CFG_DH_PARAMS_FILE, "");
+ params.ecdhCurve = config.getString(prefix + CFG_ECDH_CURVE, "");
+
+ Context::Usage usage;
+
+ if (server)
+ {
+ 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_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;
+ }
+ 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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp
new file mode 100644
index 00000000000..c1a9569bc76
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSMTPClientSession.cpp
@@ -0,0 +1,64 @@
+//
+// 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),
+ _host(host)
+{
+}
+
+
+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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocket.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocket.cpp
new file mode 100644
index 00000000000..a394304ace4
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocket.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp
new file mode 100644
index 00000000000..0175622a73d
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureServerSocketImpl.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
new file mode 100644
index 00000000000..ef924d66ac2
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
@@ -0,0 +1,601 @@
+//
+// 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 {
+
+struct RemainingTimeCounter
+{
+ RemainingTimeCounter(Poco::Timespan& remainingTime_) : remainingTime(remainingTime_) {};
+ ~RemainingTimeCounter()
+ {
+ Poco::Timestamp end;
+ Poco::Timespan waited = end - start;
+ if (waited < remainingTime)
+ remainingTime -= waited;
+ else
+ remainingTime = 0;
+ }
+private:
+ Poco::Timespan& remainingTime;
+ Poco::Timestamp start;
+};
+
+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);
+ //FIXME it updates timeouts of SecureStreamSocketImpl::underlying_socket it does not update timeouts of SecureStreamSocketImpl
+ //However, timeouts of SecureStreamSocketImpl are not used in connectSSL() and previous settings are restored after
+ 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;
+ Poco::Timespan remaining_time = getMaxTimeout();
+ do
+ {
+ RemainingTimeCounter counter(remaining_time);
+ ret = SSL_connect(_pSSL);
+ }
+ while (mustRetry(ret, remaining_time));
+ 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;
+ }
+
+ Poco::Timespan remaining_time = getMaxTimeout();
+ do
+ {
+ RemainingTimeCounter counter(remaining_time);
+ rc = SSL_write(_pSSL, buffer, length);
+ }
+ while (mustRetry(rc, remaining_time));
+ 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;
+ }
+
+ Poco::Timespan remaining_time = getMaxTimeout();
+ do
+ {
+ /// SSL record may consist of several TCP packets,
+ /// so thread can be blocked on recv/send and epoll_wait several times
+ /// until SSL_read will return rc > 0. Let's use our own time counter.
+ RemainingTimeCounter counter(remaining_time);
+ rc = SSL_read(_pSSL, buffer, length);
+ }
+ while (mustRetry(rc, remaining_time));
+ 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;
+ Poco::Timespan remaining_time = getMaxTimeout();
+ do
+ {
+ RemainingTimeCounter counter(remaining_time);
+ rc = SSL_do_handshake(_pSSL);
+ }
+ while (mustRetry(rc, remaining_time));
+ 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;
+}
+
+Poco::Timespan SecureSocketImpl::getMaxTimeout()
+{
+ Poco::Timespan remaining_time = _pSocket->getReceiveTimeout();
+ Poco::Timespan send_timeout = _pSocket->getSendTimeout();
+ if (remaining_time < send_timeout)
+ remaining_time = send_timeout;
+ return remaining_time;
+}
+
+bool SecureSocketImpl::mustRetry(int rc, Poco::Timespan& remaining_time)
+{
+ if (rc <= 0)
+ {
+ int sslError = SSL_get_error(_pSSL, rc);
+ int socketError = _pSocket->lastError();
+ switch (sslError)
+ {
+ case SSL_ERROR_WANT_READ:
+ if (_pSocket->getBlocking())
+ {
+ /// Level-triggered mode of epoll_wait is used, so if SSL_read don't read all available data from socket,
+ /// epoll_wait returns true without waiting for new data even if remaining_time == 0
+ if (_pSocket->pollImpl(remaining_time, Poco::Net::Socket::SELECT_READ) && remaining_time != 0)
+ return true;
+ else
+ throw Poco::TimeoutException();
+ }
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ if (_pSocket->getBlocking())
+ {
+ /// The same as for SSL_ERROR_WANT_READ
+ if (_pSocket->pollImpl(remaining_time, Poco::Net::Socket::SELECT_WRITE) && remaining_time != 0)
+ 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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocket.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocket.cpp
new file mode 100644
index 00000000000..f4766ca6f97
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocket.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp
new file mode 100644
index 00000000000..bef198ae691
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp
@@ -0,0 +1,241 @@
+//
+// 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):
+ underlying_socket(new StreamSocketImpl),
+ _impl(underlying_socket, pContext),
+ _lazyHandshake(false)
+{
+}
+
+
+SecureStreamSocketImpl::SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext):
+ underlying_socket(pStreamSocket),
+ _impl(underlying_socket, pContext),
+ _lazyHandshake(false)
+{
+ pStreamSocket->duplicate();
+ reset(_impl.sockfd());
+}
+
+
+SecureStreamSocketImpl::~SecureStreamSocketImpl()
+{
+ try
+ {
+ reset();
+ }
+ catch (...)
+ {
+ poco_unexpected();
+ }
+}
+
+void SecureStreamSocketImpl::setSendTimeout(const Poco::Timespan& timeout)
+{
+ underlying_socket->setSendTimeout(timeout);
+ _sndTimeout = underlying_socket->getSendTimeout();
+}
+
+void SecureStreamSocketImpl::setReceiveTimeout(const Poco::Timespan& timeout)
+{
+ underlying_socket->setReceiveTimeout(timeout);
+ _recvTimeout = underlying_socket->getReceiveTimeout();
+}
+
+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, bool reusePort)
+{
+ 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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/Session.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/Session.cpp
new file mode 100644
index 00000000000..96a507d9469
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/Session.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/Utility.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/Utility.cpp
new file mode 100644
index 00000000000..5428b769968
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/Utility.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp
new file mode 100644
index 00000000000..f7f6451b1cb
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/VerificationErrorArgs.cpp
@@ -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
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/X509Certificate.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/X509Certificate.cpp
new file mode 100644
index 00000000000..54651c3ac87
--- /dev/null
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/X509Certificate.cpp
@@ -0,0 +1,175 @@
+//
+// 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::operator = (const Poco::Crypto::X509Certificate& cert)
+{
+ X509Certificate tmp(cert);
+ swap(tmp);
+ 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