4435 secure sock thread (#4512)

* fix(SecureSocket): Refactor detection of timeout when reading, writing or handshaking. (#3725)

* enh(SecureSocket): some trivial C++17 modernisation changes.

* chore: indentation and compiler warning

* fix(SecureSocketImpl): not thread-safe (1st attempt) #4435

* fix(SecureSocketImpl): silence CodeQL cpp/certificate-not-checked

---------

Co-authored-by: Matej Kenda <matejken@gmail.com>
This commit is contained in:
Aleksandar Fabijanic 2024-04-02 11:53:42 -05:00 committed by GitHub
parent 8d3de8a5ed
commit ece360393f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 7 deletions

View File

@ -284,16 +284,21 @@ protected:
/// Callback to handle new session data sent by server.
private:
using MutexT = Poco::FastMutex;
using LockT = MutexT::ScopedLock;
using UnLockT = Poco::ScopedLockWithUnlock<MutexT>;
SecureSocketImpl(const SecureSocketImpl&);
SecureSocketImpl& operator = (const SecureSocketImpl&);
SSL* _pSSL;
std::atomic<SSL*> _pSSL;
Poco::AutoPtr<SocketImpl> _pSocket;
Context::Ptr _pContext;
bool _needHandshake;
std::string _peerHostName;
Session::Ptr _pSession;
bool _bidirectShutdown = true;
mutable MutexT _mutex;
friend class SecureStreamSocketImpl;
friend class Context;

View File

@ -80,6 +80,8 @@ void SecureSocketImpl::acceptSSL()
{
poco_assert (!_pSSL);
LockT l(_mutex);
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);
@ -156,6 +158,8 @@ void SecureSocketImpl::connectSSL(bool performHandshake)
poco_assert (!_pSSL);
poco_assert (_pSocket->initialized());
LockT l(_mutex);
::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);
@ -253,6 +257,8 @@ void SecureSocketImpl::shutdown()
{
if (_pSSL)
{
UnLockT l(_mutex);
// Don't shut down the socket more than once.
int shutdownState = ::SSL_get_shutdown(_pSSL);
bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
@ -301,6 +307,9 @@ void SecureSocketImpl::shutdown()
int rc = ::SSL_shutdown(_pSSL);
#endif
if (rc < 0) handleError(rc);
l.unlock();
if (_pSocket->getBlocking())
{
_pSocket->shutdown();
@ -345,6 +354,9 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
poco_check_ptr (_pSSL);
int rc;
LockT l(_mutex);
if (_needHandshake)
{
rc = completeHandshake();
@ -381,6 +393,9 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
poco_check_ptr (_pSSL);
int rc;
LockT l(_mutex);
if (_needHandshake)
{
rc = completeHandshake();
@ -414,6 +429,8 @@ int SecureSocketImpl::available() const
{
poco_check_ptr (_pSSL);
LockT l(_mutex);
return ::SSL_pending(_pSSL);
}
@ -499,10 +516,19 @@ bool SecureSocketImpl::isLocalHost(const std::string& hostName)
X509* SecureSocketImpl::peerCertificate() const
{
LockT l(_mutex);
X509* pCert = nullptr;
if (_pSSL)
return ::SSL_get_peer_certificate(_pSSL);
else
return nullptr;
{
pCert = ::SSL_get_peer_certificate(_pSSL);
if (X509_V_OK != SSL_get_verify_result(_pSSL))
throw CertificateValidationException("SecureSocketImpl::peerCertificate(): "
"Certificate verification error " + Utility::getLastError());
}
return pCert;
}
@ -637,6 +663,8 @@ void SecureSocketImpl::reset()
{
if (_pSSL)
{
LockT l(_mutex);
::SSL_set_ex_data(_pSSL, SSLManager::instance().socketIndex(), nullptr);
::SSL_free(_pSSL);
_pSSL = nullptr;
@ -665,8 +693,11 @@ void SecureSocketImpl::useSession(Session::Ptr pSession)
bool SecureSocketImpl::sessionWasReused()
{
if (_pSSL)
{
LockT l(_mutex);
return ::SSL_session_reused(_pSSL) != 0;
else
}
return false;
}