Add & use HMACAuth method that calculates hash atomically

To avoid issues with race conditions involving separate
addData() and result() calls use a method that does
both in the lock.
This commit is contained in:
Simon Walton 2018-04-25 14:41:16 -07:00
parent e25e15d6b3
commit 4fa11f116f
3 changed files with 28 additions and 9 deletions

View file

@ -68,7 +68,7 @@ bool HMACAuth::setKey(const char* keyValue, int keyLen) {
return false;
}
//QMutexLocker lock(&_lock);
QMutexLocker lock(&_lock);
return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr);
}
@ -78,14 +78,14 @@ bool HMACAuth::setKey(const QUuid& uidKey) {
}
bool HMACAuth::addData(const char* data, int dataLen) {
//QMutexLocker lock(&_lock);
QMutexLocker lock(&_lock);
return (bool) HMAC_Update(_hmacContext, reinterpret_cast<const unsigned char*>(data), dataLen);
}
HMACAuth::HMACHash HMACAuth::result() {
HMACHash hashValue(EVP_MAX_MD_SIZE);
unsigned int hashLen;
//QMutexLocker lock(&_lock);
unsigned int hashLen;
QMutexLocker lock(&_lock);
if (HMAC_Final(_hmacContext, &hashValue[0], &hashLen)) {
hashValue.resize((size_t)hashLen);
}
@ -93,3 +93,20 @@ HMACAuth::HMACHash HMACAuth::result() {
HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr);
return hashValue;
}
bool HMACAuth::calculateHash(HMACHash& hashResult, const char* data, int dataLen) {
QMutexLocker lock(&_lock);
if (!HMAC_Update(_hmacContext, reinterpret_cast<const unsigned char*>(data), dataLen)) {
return false;
}
hashResult.resize(EVP_MAX_MD_SIZE);
unsigned int hashLen;
if (HMAC_Final(_hmacContext, &hashResult[0], &hashLen)) {
hashResult.resize((size_t)hashLen);
// Clear state for possible reuse.
HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr);
return true;
}
return false;
}

View file

@ -26,10 +26,11 @@ public:
explicit HMACAuth(AuthMethod authMethod = MD5);
~HMACAuth();
QMutex& getLock() { return _lock; }
bool setKey(const char* keyValue, int keyLen);
bool setKey(const QUuid& uidKey);
// Calculate complete hash in one.
bool calculateHash(HMACHash& hashResult, const char* data, int dataLen);
// Append data to be hashed.
bool addData(const char* data, int dataLen);
HMACHash result();

View file

@ -157,9 +157,10 @@ QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& h
+ NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH;
// add the packet payload and the connection UUID
QMutexLocker hashLock(&hash.getLock());
hash.addData(packet.getData() + offset, packet.getDataSize() - offset);
auto hashResult { hash.result() };
HMACAuth::HMACHash hashResult;
if (!hash.calculateHash(hashResult, packet.getData() + offset, packet.getDataSize() - offset)) {
return QByteArray();
}
return QByteArray((const char*) hashResult.data(), (int) hashResult.size());
}