Clear SSL key data as soon as possible when move-assigning

Move-assign uses qSwap to exchange the private pointer and thus can
extend the lifetime of sensitive data. The move assignment operator
is changed so it releases the private data as soon as possible.

[ChangeLog][QtNetwork][QSslKey] Key data is cleared as soon as
possible when move-assigning.

Change-Id: Iebd029bf657acfe000417ce648e3b3829948c0e5
Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
This commit is contained in:
Konstantin Shegunov 2019-04-03 13:00:01 +03:00
parent 65314b6ce8
commit 642ef0c731
3 changed files with 24 additions and 4 deletions

View File

@ -71,9 +71,8 @@ public:
const QByteArray &passPhrase = QByteArray());
explicit QSslKey(Qt::HANDLE handle, QSsl::KeyType type = QSsl::PrivateKey);
QSslKey(const QSslKey &other);
#ifdef Q_COMPILER_RVALUE_REFS
QSslKey &operator=(QSslKey &&other) noexcept { swap(other); return *this; }
#endif
QSslKey(QSslKey &&other) noexcept;
QSslKey &operator=(QSslKey &&other) noexcept;
QSslKey &operator=(const QSslKey &other);
~QSslKey();

View File

@ -385,6 +385,24 @@ QSslKey::QSslKey(const QSslKey &other) : d(other.d)
{
}
QSslKey::QSslKey(QSslKey &&other) noexcept
: d(nullptr)
{
qSwap(d, other.d);
}
QSslKey &QSslKey::operator=(QSslKey &&other) noexcept
{
if (this == &other)
return *this;
// If no one else is referencing the key data we want to make sure
// before we swap the d-ptr that it is not left in memory.
d.reset();
qSwap(d, other.d);
return *this;
}
/*!
Destroys the QSslKey object.
*/

View File

@ -48,6 +48,8 @@
#include <QtNetwork/qpassworddigestor.h>
#include <cstring>
QT_USE_NAMESPACE
static const quint8 bits_table[256] = {
@ -186,8 +188,9 @@ static QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &pas
void QSslKeyPrivate::clear(bool deep)
{
Q_UNUSED(deep);
isNull = true;
if (deep)
std::memset(derData.data(), 0, derData.size());
derData.clear();
keyLength = -1;
}