mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 16:10:14 +00:00
Add integrity hash support and SRP tuning options
This commit is contained in:
parent
b3001a4b5b
commit
5435796a98
10 changed files with 591 additions and 22 deletions
91
src/auth/integrity.cpp
Normal file
91
src/auth/integrity.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#include "auth/integrity.hpp"
|
||||
#include "auth/crypto.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace wowee {
|
||||
namespace auth {
|
||||
|
||||
static bool readWholeFile(const std::string& path, std::vector<uint8_t>& out, std::string& err) {
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (!f.is_open()) {
|
||||
err = "missing: " + path;
|
||||
return false;
|
||||
}
|
||||
f.seekg(0, std::ios::end);
|
||||
std::streamoff size = f.tellg();
|
||||
if (size < 0) size = 0;
|
||||
f.seekg(0, std::ios::beg);
|
||||
out.resize(static_cast<size_t>(size));
|
||||
if (size > 0) {
|
||||
f.read(reinterpret_cast<char*>(out.data()), size);
|
||||
if (!f) {
|
||||
err = "read failed: " + path;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool computeIntegrityHashWin32WithExe(const std::array<uint8_t, 16>& checksumSalt,
|
||||
const std::vector<uint8_t>& clientPublicKeyA,
|
||||
const std::string& miscDir,
|
||||
const std::string& exeName,
|
||||
std::array<uint8_t, 20>& outHash,
|
||||
std::string& outError) {
|
||||
// Files expected by 1.12.x Windows clients for the integrity check.
|
||||
// If this needs to vary by build, make it data-driven in expansion.json later.
|
||||
const char* kFiles[] = {
|
||||
nullptr, // exeName
|
||||
"fmod.dll",
|
||||
"ijl15.dll",
|
||||
"dbghelp.dll",
|
||||
"unicows.dll",
|
||||
};
|
||||
|
||||
std::vector<uint8_t> allFiles;
|
||||
std::string err;
|
||||
for (size_t idx = 0; idx < (sizeof(kFiles) / sizeof(kFiles[0])); ++idx) {
|
||||
const char* name = kFiles[idx];
|
||||
std::string nameStr = name ? std::string(name) : exeName;
|
||||
std::vector<uint8_t> bytes;
|
||||
std::string path = miscDir;
|
||||
if (!path.empty() && path.back() != '/') path += '/';
|
||||
path += nameStr;
|
||||
if (!readWholeFile(path, bytes, err)) {
|
||||
outError = err;
|
||||
return false;
|
||||
}
|
||||
allFiles.insert(allFiles.end(), bytes.begin(), bytes.end());
|
||||
}
|
||||
|
||||
// HMAC_SHA1(checksumSalt, allFiles)
|
||||
std::vector<uint8_t> key(checksumSalt.begin(), checksumSalt.end());
|
||||
const std::vector<uint8_t> checksum = Crypto::hmacSHA1(key, allFiles); // 20 bytes
|
||||
|
||||
// SHA1(A || checksum)
|
||||
std::vector<uint8_t> shaIn;
|
||||
shaIn.reserve(clientPublicKeyA.size() + checksum.size());
|
||||
shaIn.insert(shaIn.end(), clientPublicKeyA.begin(), clientPublicKeyA.end());
|
||||
shaIn.insert(shaIn.end(), checksum.begin(), checksum.end());
|
||||
const std::vector<uint8_t> finalHash = Crypto::sha1(shaIn);
|
||||
|
||||
if (finalHash.size() != outHash.size()) {
|
||||
outError = "unexpected sha1 size";
|
||||
return false;
|
||||
}
|
||||
std::copy(finalHash.begin(), finalHash.end(), outHash.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool computeIntegrityHashWin32(const std::array<uint8_t, 16>& checksumSalt,
|
||||
const std::vector<uint8_t>& clientPublicKeyA,
|
||||
const std::string& miscDir,
|
||||
std::array<uint8_t, 20>& outHash,
|
||||
std::string& outError) {
|
||||
return computeIntegrityHashWin32WithExe(checksumSalt, clientPublicKeyA, miscDir, "WoW.exe", outHash, outError);
|
||||
}
|
||||
|
||||
} // namespace auth
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue