summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qmessageauthenticationcode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qmessageauthenticationcode.cpp')
-rw-r--r--src/corelib/tools/qmessageauthenticationcode.cpp37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp
index 40a1193622..40d120eb52 100644
--- a/src/corelib/tools/qmessageauthenticationcode.cpp
+++ b/src/corelib/tools/qmessageauthenticationcode.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2023 The Qt Company Ltd.
** Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru>
** Contact: https://www.qt.io/licensing/
**
@@ -39,6 +40,8 @@
#include "qmessageauthenticationcode.h"
#include "qvarlengtharray.h"
+#include "qmutex.h"
+#include "private/qlocking_p.h"
/*
These #defines replace the typedefs needed by the RFC6234 code. Normally
@@ -125,11 +128,18 @@ public:
QByteArray key;
QByteArray result;
+ QMutex finalizeMutex;
QCryptographicHash messageHash;
QCryptographicHash::Algorithm method;
bool messageHashInited;
void initMessageHash();
+ void finalize();
+
+ // when not called from the static hash() function, this function needs to be
+ // called with finalizeMutex held:
+ void finalizeUnchecked();
+ // END functions that need to be called with finalizeMutex held
};
void QMessageAuthenticationCodePrivate::initMessageHash()
@@ -266,27 +276,36 @@ bool QMessageAuthenticationCode::addData(QIODevice *device)
*/
QByteArray QMessageAuthenticationCode::result() const
{
- if (!d->result.isEmpty())
- return d->result;
+ d->finalize();
+ return d->result;
+}
- d->initMessageHash();
+void QMessageAuthenticationCodePrivate::finalize()
+{
+ const auto lock = qt_scoped_lock(finalizeMutex);
+ if (!result.isEmpty())
+ return;
+ initMessageHash();
+ finalizeUnchecked();
+}
- const int blockSize = qt_hash_block_size(d->method);
+void QMessageAuthenticationCodePrivate::finalizeUnchecked()
+{
+ const int blockSize = qt_hash_block_size(method);
- QByteArray hashedMessage = d->messageHash.result();
+ QByteArray hashedMessage = messageHash.result();
QVarLengthArray<char> oKeyPad(blockSize);
- const char * const keyData = d->key.constData();
+ const char * const keyData = key.constData();
for (int i = 0; i < blockSize; ++i)
oKeyPad[i] = keyData[i] ^ 0x5c;
- QCryptographicHash hash(d->method);
+ QCryptographicHash hash(method);
hash.addData(oKeyPad.data(), oKeyPad.size());
hash.addData(hashedMessage);
- d->result = hash.result();
- return d->result;
+ result = hash.result();
}
/*!