aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp')
-rw-r--r--contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp1094
1 files changed, 547 insertions, 547 deletions
diff --git a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
index ef924d66ac..564bc18683 100644
--- a/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
+++ b/contrib/libs/poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
@@ -1,49 +1,49 @@
-//
-// SecureSocketImpl.cpp
-//
-// Library: NetSSL_OpenSSL
-// Package: SSLSockets
-// Module: SecureSocketImpl
-//
-// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
-// and Contributors.
-//
-// SPDX-License-Identifier: BSL-1.0
-//
-
-
-#include "Poco/Net/SecureSocketImpl.h"
-#include "Poco/Net/SSLException.h"
-#include "Poco/Net/Context.h"
-#include "Poco/Net/X509Certificate.h"
-#include "Poco/Net/Utility.h"
-#include "Poco/Net/SecureStreamSocket.h"
-#include "Poco/Net/SecureStreamSocketImpl.h"
-#include "Poco/Net/StreamSocketImpl.h"
-#include "Poco/Net/StreamSocket.h"
-#include "Poco/Net/NetException.h"
-#include "Poco/Net/DNS.h"
-#include "Poco/NumberFormatter.h"
-#include "Poco/NumberParser.h"
-#include "Poco/Format.h"
-#include <openssl/x509v3.h>
-#include <openssl/err.h>
-
-
-using Poco::IOException;
-using Poco::TimeoutException;
-using Poco::InvalidArgumentException;
-using Poco::NumberFormatter;
-using Poco::Timespan;
-
-
-// workaround for C++-incompatible macro
-#define POCO_BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(void*)((n)?"a":NULL))
-
-
-namespace Poco {
-namespace Net {
-
+//
+// SecureSocketImpl.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_) {};
@@ -60,137 +60,137 @@ 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);
+
+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())
- {
+ 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
@@ -199,237 +199,237 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
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;
- }
+ 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
- {
+ do
+ {
RemainingTimeCounter counter(remaining_time);
- rc = SSL_write(_pSSL, buffer, length);
- }
+ 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;
- }
+ 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
- {
+ 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);
- }
+ 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;
+ 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
- {
+ do
+ {
RemainingTimeCounter counter(remaining_time);
- rc = SSL_do_handshake(_pSSL);
- }
+ 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;
-}
-
+ 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();
@@ -438,164 +438,164 @@ Poco::Timespan SecureSocketImpl::getMaxTimeout()
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())
- {
+{
+ 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())
- {
+ 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
+ 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