From 6ab9e2958d85e9d994726b8c34cdd2adc79168b7 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sat, 10 Feb 2024 10:42:45 -0600 Subject: [PATCH] Use FixedTimeEquals for IPC Password testing (#3142) --- ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs | 15 +++++++++++++++ .../Integration/ApiAuthenticationMiddleware.cs | 4 +--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs index ffdcf9cd1..8aef5d0ab 100644 --- a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs +++ b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs @@ -110,6 +110,21 @@ public static class ArchiCryptoHelper { return Convert.ToBase64String(hashBytes); } + internal static bool VerifyHash(EHashingMethod hashingMethod, string inputString, string verifyHash) { + if (!Enum.IsDefined(hashingMethod)) { + throw new InvalidEnumArgumentException(nameof(hashingMethod), (int) hashingMethod, typeof(EHashingMethod)); + } + + ArgumentException.ThrowIfNullOrEmpty(inputString); + ArgumentException.ThrowIfNullOrEmpty(verifyHash); + + byte[] verifyBytes = hashingMethod == EHashingMethod.PlainText ? Encoding.UTF8.GetBytes(inputString) : Convert.FromBase64String(verifyHash); + byte[] passwordBytes = Encoding.UTF8.GetBytes(inputString); + byte[] hashBytes = Hash(passwordBytes, EncryptionKey, DefaultHashLength, hashingMethod); + + return CryptographicOperations.FixedTimeEquals(hashBytes, verifyBytes); + } + internal static byte[] Hash(byte[] password, byte[] salt, byte hashLength, EHashingMethod hashingMethod) { if ((password == null) || (password.Length == 0)) { throw new ArgumentNullException(nameof(password)); diff --git a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs index 4a22ae797..ba36ab6ef 100644 --- a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs +++ b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs @@ -148,9 +148,7 @@ internal sealed class ApiAuthenticationMiddleware { ArchiCryptoHelper.EHashingMethod ipcPasswordFormat = ASF.GlobalConfig != null ? ASF.GlobalConfig.IPCPasswordFormat : GlobalConfig.DefaultIPCPasswordFormat; - string inputHash = ArchiCryptoHelper.Hash(ipcPasswordFormat, inputPassword); - - bool authorized = ipcPassword == inputHash; + bool authorized = ArchiCryptoHelper.VerifyHash(ipcPasswordFormat, inputPassword, ipcPassword); while (true) { if (AuthorizationTasks.TryGetValue(clientIP, out Task? task)) {