mirror of
https://github.com/znc/znc.git
synced 2026-07-28 20:43:34 +02:00
User,Utils: move ConstantTimeEquals to CUtils and add tests (#2011)
This commit is contained in:
+3
-22
@@ -1054,25 +1054,6 @@ CConfig CUser::ToConfig() const {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Constant-time byte-wise compare of two strings. Returns true only if the
|
||||
// strings have the same length and the same contents. Runs in time
|
||||
// proportional to the shorter of the two lengths and does not short-circuit
|
||||
// on the first differing byte, so a remote attacker can't learn the stored
|
||||
// hash byte-by-byte via timing. Local helper to avoid a new OpenSSL
|
||||
// dependency for builds without libssl.
|
||||
static bool ConstantTimeEquals(const CString& a, const CString& b) {
|
||||
if (a.length() != b.length()) {
|
||||
return false;
|
||||
}
|
||||
unsigned char acc = 0;
|
||||
const unsigned char* pa = reinterpret_cast<const unsigned char*>(a.data());
|
||||
const unsigned char* pb = reinterpret_cast<const unsigned char*>(b.data());
|
||||
for (size_t i = 0; i < a.length(); ++i) {
|
||||
acc |= pa[i] ^ pb[i];
|
||||
}
|
||||
return acc == 0;
|
||||
}
|
||||
|
||||
bool CUser::CheckPass(const CString& sPass) {
|
||||
if(AuthOnlyViaModule() || CZNC::Get().GetAuthOnlyViaModule()) {
|
||||
return false;
|
||||
@@ -1082,12 +1063,12 @@ bool CUser::CheckPass(const CString& sPass) {
|
||||
bool bUpgrade = false;
|
||||
switch (m_eHashType) {
|
||||
case HASH_MD5:
|
||||
bResult = ConstantTimeEquals(
|
||||
bResult = CUtils::ConstantTimeEquals(
|
||||
m_sPass, CUtils::SaltedMD5Hash(sPass, m_sPassSalt));
|
||||
bUpgrade = true;
|
||||
break;
|
||||
case HASH_SHA256:
|
||||
bResult = ConstantTimeEquals(
|
||||
bResult = CUtils::ConstantTimeEquals(
|
||||
m_sPass, CUtils::SaltedSHA256Hash(sPass, m_sPassSalt));
|
||||
#if ZNC_HAVE_ARGON
|
||||
bUpgrade = true;
|
||||
@@ -1103,7 +1084,7 @@ bool CUser::CheckPass(const CString& sPass) {
|
||||
case HASH_NONE:
|
||||
// Don't upgrade hash, since the only valid use case for plain are
|
||||
// manual tests, where it's simpler this way
|
||||
return ConstantTimeEquals(sPass, m_sPass);
|
||||
return CUtils::ConstantTimeEquals(sPass, m_sPass);
|
||||
}
|
||||
|
||||
if (bResult && bUpgrade) {
|
||||
|
||||
Reference in New Issue
Block a user