From 33179842341fcf7d42e74f62a600470aed6b08a1 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 30 Jan 2012 15:52:27 +0000 Subject: Prevent data loss when an ssl socket is closed by remote SSL context was destroyed on disconnect. This makes it impossible to decrypt buffered encrypted data. So if there is encrypted data in the receive buffers, then don't destroy the ssl context until the socket is destroyed. Task-Number: QTBUG-23607 Change-Id: I16a7b4fa006647ec73049c90cdbc72686696850f Reviewed-by: Jonas Gastal Reviewed-by: Richard J. Moore (cherry picked from commit c5aba0ac17ae6ed8f3847bd30325acdbd1ecaa80) --- src/network/ssl/qsslsocket_openssl.cpp | 34 +++++++++++++++++++++------------- src/network/ssl/qsslsocket_openssl_p.h | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 25d1d9e..5b1cd1b 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -183,6 +183,7 @@ QSslSocketBackendPrivate::QSslSocketBackendPrivate() QSslSocketBackendPrivate::~QSslSocketBackendPrivate() { + destroySslContext(); } QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher) @@ -483,6 +484,22 @@ init_context: return true; } +void QSslSocketBackendPrivate::destroySslContext() +{ + if (ssl) { + q_SSL_free(ssl); + ssl = 0; + } + if (ctx) { + q_SSL_CTX_free(ctx); + ctx = 0; + } + if (pkey) { + q_EVP_PKEY_free(pkey); + pkey = 0; + } +} + /*! \internal */ @@ -1403,19 +1420,10 @@ void QSslSocketBackendPrivate::disconnectFromHost() void QSslSocketBackendPrivate::disconnected() { - if (ssl) { - q_SSL_free(ssl); - ssl = 0; - } - if (ctx) { - q_SSL_CTX_free(ctx); - ctx = 0; - } - if (pkey) { - q_EVP_PKEY_free(pkey); - pkey = 0; - } - + if (plainSocket->bytesAvailable() <= 0) + destroySslContext(); + //if there is still buffered data in the plain socket, don't destroy the ssl context yet. + //it will be destroyed when the socket is deleted. } QSslCipher QSslSocketBackendPrivate::sessionCipher() const diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index bad2c9c..2940480 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -99,6 +99,7 @@ public: // SSL context bool initSslContext(); + void destroySslContext(); SSL *ssl; SSL_CTX *ctx; EVP_PKEY *pkey; -- cgit v0.12