diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2020-07-26 01:53:34 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2020-08-03 19:39:00 +0200 |
| commit | e9392ad28767626e519c463e2110184d71ba8426 (patch) | |
| tree | da391d7daf1ede4ef73883b5053520e160dc4ec4 /src/server | |
| parent | caa1e1171a1ea4e2db754cfb52b3be795385d544 (diff) | |
Core/Authserver: Authserver cleanup (PR#25093)
- Fix a handful of 1/256 bugs with most significant byte zero in BigNumber
- Get rid of (most of) the C-style arrays in authserver
- CryptoRandom as a unified source for cryptographic randomness
- Bring our other crypto APIs into 2020
- BigNumber usability improvements
- Authserver is now actually readable as a result of all of the above
(cherry picked from commit 210176fd915cf4ba16f428d3c1a249a71f4aa7a7)
Diffstat (limited to 'src/server')
24 files changed, 143 insertions, 172 deletions
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index bbb48ac6128..c2590271b98 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -25,6 +25,7 @@ #include "AppenderDB.h" #include "Banner.h" +#include "BigNumber.h" #include "Config.h" #include "DatabaseEnv.h" #include "DatabaseLoader.h" diff --git a/src/server/bnetserver/REST/LoginRESTService.cpp b/src/server/bnetserver/REST/LoginRESTService.cpp index c8fb91b163b..16ce194b190 100644 --- a/src/server/bnetserver/REST/LoginRESTService.cpp +++ b/src/server/bnetserver/REST/LoginRESTService.cpp @@ -17,6 +17,8 @@ #include "LoginRESTService.h" #include "Configuration/Config.h" +#include "CryptoHash.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" #include "Errors.h" #include "IpNetwork.h" @@ -24,8 +26,6 @@ #include "Realm.h" #include "Resolver.h" #include "SessionManager.h" -#include "SHA1.h" -#include "SHA256.h" #include "SslContext.h" #include "Util.h" #include "httpget.h" @@ -362,10 +362,9 @@ int32 LoginRESTService::HandlePostLogin(std::shared_ptr<AsyncRequest> request) { if (loginTicket.empty() || loginTicketExpiry < time(nullptr)) { - BigNumber ticket; - ticket.SetRand(20 * 8); + std::array<uint8, 20> ticket = Trinity::Crypto::GetRandomBytes<20>(); - loginTicket = "TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20); + loginTicket = "TC-" + ByteArrayToHexStr(ticket); } LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_AUTHENTICATION); @@ -503,17 +502,17 @@ void LoginRESTService::HandleAsyncRequest(std::shared_ptr<AsyncRequest> request) std::string LoginRESTService::CalculateShaPassHash(std::string const& name, std::string const& password) { - SHA256Hash email; + Trinity::Crypto::SHA256 email; email.UpdateData(name); email.Finalize(); - SHA256Hash sha; - sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength())); + Trinity::Crypto::SHA256 sha; + sha.UpdateData(ByteArrayToHexStr(email.GetDigest())); sha.UpdateData(":"); sha.UpdateData(password); sha.Finalize(); - return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); + return ByteArrayToHexStr(sha.GetDigest(), true); } Namespace namespaces[] = diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 9e3ec49a0ca..249a871aa04 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -18,6 +18,7 @@ #include "Session.h" #include "BattlenetRpcErrorCodes.h" #include "ByteConverter.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" #include "Errors.h" #include "IPLocation.h" @@ -386,9 +387,8 @@ uint32 Battlenet::Session::VerifyWebCredentials(std::string const& webCredential if (!_ipCountry.empty()) logonResult.set_geoip_country(_ipCountry); - BigNumber k; - k.SetRand(8 * 64); - logonResult.set_session_key(k.AsByteArray(64).get(), 64); + std::array<uint8, 64> k = Trinity::Crypto::GetRandomBytes<64>(); + logonResult.set_session_key(k.data(), 64); _authed = true; diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 5738b43e381..520ee263545 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -23,7 +23,6 @@ #include "SslContext.h" #include "SslSocket.h" #include "Socket.h" -#include "BigNumber.h" #include "QueryResult.h" #include <boost/asio/ip/tcp.hpp> #include <boost/asio/ssl.hpp> diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp index b34cb9ff39c..a5220ab7af1 100644 --- a/src/server/database/Updater/UpdateFetcher.cpp +++ b/src/server/database/Updater/UpdateFetcher.cpp @@ -19,10 +19,10 @@ #include "Common.h" #include "DBUpdater.h" #include "Field.h" +#include "CryptoHash.h" #include "Log.h" #include "QueryResult.h" #include "Util.h" -#include "SHA1.h" #include <boost/filesystem/operations.hpp> #include <fstream> #include <sstream> @@ -223,7 +223,7 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, } // Calculate a Sha1 hash based on query content. - std::string const hash = CalculateSHA1Hash(ReadSQLUpdate(availableQuery.first)); + std::string const hash = ByteArrayToHexStr(Trinity::Crypto::SHA1::GetDigestOf(ReadSQLUpdate(availableQuery.first))); UpdateMode mode = MODE_APPLY; diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 30e831a598b..a0720e6f93c 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -18,12 +18,12 @@ #include "AccountMgr.h" #include "Config.h" #include "DatabaseEnv.h" +#include "CryptoHash.h" #include "Log.h" #include "ObjectAccessor.h" #include "Player.h" #include "Realm.h" #include "ScriptMgr.h" -#include "SHA1.h" #include "Util.h" #include "World.h" #include "WorldSession.h" @@ -389,14 +389,7 @@ uint32 AccountMgr::GetCharactersCount(uint32 accountId) std::string AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) { - SHA1Hash sha; - sha.Initialize(); - sha.UpdateData(name); - sha.UpdateData(":"); - sha.UpdateData(password); - sha.Finalize(); - - return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength()); + return ByteArrayToHexStr(Trinity::Crypto::SHA1::GetDigestOf(name, ":", password)); } bool AccountMgr::IsBannedAccount(std::string const& name) diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp index fc78a264156..a726fdf5c7d 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.cpp +++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp @@ -17,9 +17,9 @@ #include "BattlenetAccountMgr.h" #include "AccountMgr.h" +#include "CryptoHash.h" #include "DatabaseEnv.h" #include "Util.h" -#include "SHA256.h" using GameAccountMgr = AccountMgr; @@ -174,15 +174,15 @@ uint8 Battlenet::AccountMgr::GetMaxIndex(uint32 accountId) std::string Battlenet::AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) { - SHA256Hash email; + Trinity::Crypto::SHA256 email; email.UpdateData(name); email.Finalize(); - SHA256Hash sha; - sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength())); + Trinity::Crypto::SHA256 sha; + sha.UpdateData(ByteArrayToHexStr(email.GetDigest())); sha.UpdateData(":"); sha.UpdateData(password); sha.Finalize(); - return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); + return ByteArrayToHexStr(sha.GetDigest(), true); } diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index b8cc437ecb7..1df8b5705db 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -40,13 +40,14 @@ ScriptReloadMgr* ScriptReloadMgr::instance() #include "BuiltInConfig.h" #include "Config.h" #include "GitRevision.h" +#include "CryptoHash.h" #include "Log.h" #include "MPSCQueue.h" #include "Regex.h" #include "ScriptMgr.h" -#include "SHA1.h" #include "StartProcess.h" #include "Timer.h" +#include "Util.h" #include "World.h" #include <boost/algorithm/string/replace.hpp> #include <boost/filesystem.hpp> @@ -758,7 +759,7 @@ private: auto path = fs::temp_directory_path(); path /= Trinity::StringFormat("tc_script_cache_%s_%s", GitRevision::GetBranch(), - CalculateSHA1Hash(sConfigMgr->GetFilename()).c_str()); + ByteArrayToHexStr(Trinity::Crypto::SHA1::GetDigestOf(sConfigMgr->GetFilename())).c_str()); return path; } diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index b69f7b1c3ab..5b2e9aa28f0 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -18,10 +18,10 @@ #include "AuthenticationPackets.h" #include "BigNumber.h" #include "CharacterTemplateDataStore.h" -#include "HmacHash.h" +#include "CryptoHash.h" +#include "HMAC.h" #include "ObjectMgr.h" #include "RSA.h" -#include "SHA256.h" #include "Util.h" ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Auth::VirtualRealmNameInfo const& virtualRealmInfo) @@ -272,13 +272,13 @@ WorldPacket const* WorldPackets::Auth::ConnectTo::Write() } uint32 type = Payload.Where.Type; - SHA256Hash hash; + Trinity::Crypto::SHA256 hash; hash.UpdateData(whereBuffer.contents(), whereBuffer.size()); hash.UpdateData(reinterpret_cast<uint8 const*>(&type), 4); hash.UpdateData(reinterpret_cast<uint8 const*>(&Payload.Port), 2); hash.Finalize(); - ConnectToRSA->Sign(hash.GetDigest(), hash.GetLength(), Payload.Signature.data(), Trinity::Crypto::RSA::SHA256{}); + ConnectToRSA->Sign(hash.GetDigest(), Payload.Signature.data(), Trinity::Crypto::RSA::SHA256{}); _worldPacket.append(Payload.Signature.data(), Payload.Signature.size()); _worldPacket.append(whereBuffer); @@ -308,14 +308,14 @@ uint8 constexpr EnableEncryptionSeed[16] = { 0x90, 0x9C, 0xD0, 0x50, 0x5A, 0x2C, WorldPacket const* WorldPackets::Auth::EnableEncryption::Write() { - HmacSha256 hash(16, EncryptionKey); + Trinity::Crypto::HMAC_SHA256 hash(EncryptionKey, 16); hash.UpdateData(reinterpret_cast<uint8 const*>(&Enabled), 1); hash.UpdateData(EnableEncryptionSeed, 16); hash.Finalize(); _worldPacket.resize(_worldPacket.size() + ConnectToRSA->GetOutputSize()); - ConnectToRSA->Sign(hash.GetDigest(), hash.GetLength(), _worldPacket.contents(), Trinity::Crypto::RSA::SHA256{}); + ConnectToRSA->Sign(hash.GetDigest(), _worldPacket.contents(), Trinity::Crypto::RSA::SHA256{}); _worldPacket.WriteBit(Enabled); _worldPacket.FlushBits(); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 0e3817bb509..9ac9aba7b56 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -906,7 +906,7 @@ TransactionCallback& WorldSession::AddTransactionCallback(TransactionCallback&& return _transactionCallbacks.AddCallback(std::move(callback)); } -void WorldSession::InitWarden(BigNumber* k) +void WorldSession::InitWarden(std::array<uint8, 40> const& k) { if (_os == "Win") { diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index fdbac1a465e..29b6a104bb6 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -35,7 +35,6 @@ #include <unordered_set> class BattlePetMgr; -class BigNumber; class BlackMarketEntry; class CollectionMgr; class Creature; @@ -958,7 +957,7 @@ class TC_GAME_API WorldSession uint8 GetExpansion() const { return m_expansion; } std::string const& GetOS() const { return _os; } - void InitWarden(BigNumber* k); + void InitWarden(std::array<uint8, 40> const& k); /// Session in auth.queue currently void SetInQueue(bool state) { m_inQueue = state; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 0ea17e4143d..b05afa02883 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -19,16 +19,17 @@ #include "AuthenticationPackets.h" #include "BattlenetRpcErrorCodes.h" #include "CharacterPackets.h" +#include "CryptoHash.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" #include "Errors.h" -#include "HmacHash.h" +#include "HMAC.h" #include "IPLocation.h" #include "PacketLog.h" #include "RealmList.h" #include "RBAC.h" #include "ScriptMgr.h" -#include "SessionKeyGeneration.h" -#include "SHA256.h" +#include "SessionKeyGenerator.h" #include "Util.h" #include "World.h" #include "WorldPacket.h" @@ -72,8 +73,8 @@ WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket)), _type(CONNECTION_TYPE_REALM), _key(0), _OverSpeedPings(0), _worldSession(nullptr), _authed(false), _sendBufferSize(4096), _compressionStream(nullptr) { - _serverChallenge.SetRand(8 * 16); - memset(_encryptKey, 0, sizeof(_encryptKey)); + Trinity::Crypto::GetRandomBytes(_serverChallenge); + _encryptKey.fill(0); _headerBuffer.Resize(sizeof(PacketHeader)); } @@ -237,12 +238,9 @@ bool WorldSocket::Update() void WorldSocket::HandleSendAuthSession() { - BigNumber dosChallenge; - dosChallenge.SetRand(32 * 8); - WorldPackets::Auth::AuthChallenge challenge; - memcpy(challenge.Challenge.data(), _serverChallenge.AsByteArray(16).get(), 16); - memcpy(challenge.DosChallenge.data(), dosChallenge.AsByteArray(32).get(), 32); + challenge.Challenge = _serverChallenge; + memcpy(challenge.DosChallenge.data(), Trinity::Crypto::GetRandomBytes<32>().data(), 32); challenge.DosZeroBits = 1; SendPacketAndLogOpcode(*challenge.Write()); @@ -683,7 +681,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: // For hook purposes, we get Remoteaddress at this point. std::string address = GetRemoteIpAddress().to_string(); - SHA256Hash digestKeyHash; + Trinity::Crypto::SHA256 digestKeyHash; digestKeyHash.UpdateData(account.Game.KeyData.data(), account.Game.KeyData.size()); if (account.Game.OS == "Wn64") digestKeyHash.UpdateData(buildInfo->Win64AuthSeed.data(), buildInfo->Win64AuthSeed.size()); @@ -692,44 +690,41 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: digestKeyHash.Finalize(); - HmacSha256 hmac(digestKeyHash.GetLength(), digestKeyHash.GetDigest()); - hmac.UpdateData(authSession->LocalChallenge.data(), authSession->LocalChallenge.size()); - hmac.UpdateData(_serverChallenge.AsByteArray(16).get(), 16); + Trinity::Crypto::HMAC_SHA256 hmac(digestKeyHash.GetDigest()); + hmac.UpdateData(authSession->LocalChallenge); + hmac.UpdateData(_serverChallenge); hmac.UpdateData(AuthCheckSeed, 16); hmac.Finalize(); // Check that Key and account name are the same on client and server - if (memcmp(hmac.GetDigest(), authSession->Digest.data(), authSession->Digest.size()) != 0) + if (memcmp(hmac.GetDigest().data(), authSession->Digest.data(), authSession->Digest.size()) != 0) { TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", account.Game.Id, authSession->RealmJoinTicket.c_str(), address.c_str()); DelayedCloseSocket(); return; } - SHA256Hash keyData; + Trinity::Crypto::SHA256 keyData; keyData.UpdateData(account.Game.KeyData.data(), account.Game.KeyData.size()); keyData.Finalize(); - HmacSha256 sessionKeyHmac(keyData.GetLength(), keyData.GetDigest()); - sessionKeyHmac.UpdateData(_serverChallenge.AsByteArray(16).get(), 16); - sessionKeyHmac.UpdateData(authSession->LocalChallenge.data(), authSession->LocalChallenge.size()); + Trinity::Crypto::HMAC_SHA256 sessionKeyHmac(keyData.GetDigest()); + sessionKeyHmac.UpdateData(_serverChallenge); + sessionKeyHmac.UpdateData(authSession->LocalChallenge); sessionKeyHmac.UpdateData(SessionKeySeed, 16); sessionKeyHmac.Finalize(); - uint8 sessionKey[40]; - SessionKeyGenerator<SHA256Hash> sessionKeyGenerator(sessionKeyHmac.GetDigest(), sessionKeyHmac.GetLength()); - sessionKeyGenerator.Generate(sessionKey, 40); - - _sessionKey.SetBinary(sessionKey, 40); + SessionKeyGenerator<Trinity::Crypto::SHA256> sessionKeyGenerator(sessionKeyHmac.GetDigest()); + sessionKeyGenerator.Generate(_sessionKey.data(), 40); - HmacSha256 encryptKeyGen(40, sessionKey); - encryptKeyGen.UpdateData(authSession->LocalChallenge.data(), authSession->LocalChallenge.size()); - encryptKeyGen.UpdateData(_serverChallenge.AsByteArray(16).get(), 16); + Trinity::Crypto::HMAC_SHA256 encryptKeyGen(_sessionKey); + encryptKeyGen.UpdateData(authSession->LocalChallenge); + encryptKeyGen.UpdateData(_serverChallenge); encryptKeyGen.UpdateData(EncryptionKeySeed, 16); encryptKeyGen.Finalize(); // only first 16 bytes of the hmac are used - memcpy(_encryptKey, encryptKeyGen.GetDigest(), 16); + memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 16); // As we don't know if attempted login process by ip works, we update last_attempt_ip right away LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP); @@ -739,7 +734,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: // This also allows to check for possible "hack" attempts on account stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_INFO_CONTINUED_SESSION); - stmt->setString(0, _sessionKey.AsHexStr()); + stmt->setString(0, ByteArrayToHexStr(_sessionKey)); stmt->setUInt32(1, account.Game.Id); LoginDatabase.Execute(stmt); @@ -852,7 +847,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: // Initialize Warden system only if it is enabled by config if (wardenActive) - _worldSession->InitWarden(&_sessionKey); + _worldSession->InitWarden(_sessionKey); _queryProcessor.AddCallback(_worldSession->LoadPermissionsAsync().WithPreparedCallback(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1))); AsyncRead(); @@ -863,7 +858,7 @@ void WorldSocket::LoadSessionPermissionsCallback(PreparedQueryResult result) // RBAC must be loaded before adding session to check for skip queue permission _worldSession->GetRBACData()->LoadFromDBCallback(result); - SendPacketAndLogOpcode(*WorldPackets::Auth::EnableEncryption(_encryptKey, true).Write()); + SendPacketAndLogOpcode(*WorldPackets::Auth::EnableEncryption(_encryptKey.data(), true).Write()); } void WorldSocket::HandleAuthContinuedSession(std::shared_ptr<WorldPackets::Auth::AuthContinuedSession> authSession) @@ -901,32 +896,32 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPacket uint32 accountId = uint32(key.Fields.AccountId); Field* fields = result->Fetch(); std::string login = fields[0].GetString(); - _sessionKey.SetHexStr(fields[1].GetCString()); + HexStrToByteArray(fields[1].GetString(), _sessionKey.data()); - HmacSha256 hmac(40, _sessionKey.AsByteArray(40).get()); + Trinity::Crypto::HMAC_SHA256 hmac(_sessionKey); hmac.UpdateData(reinterpret_cast<uint8 const*>(&authSession->Key), sizeof(authSession->Key)); - hmac.UpdateData(authSession->LocalChallenge.data(), authSession->LocalChallenge.size()); - hmac.UpdateData(_serverChallenge.AsByteArray(16).get(), 16); + hmac.UpdateData(authSession->LocalChallenge); + hmac.UpdateData(_serverChallenge); hmac.UpdateData(ContinuedSessionSeed, 16); hmac.Finalize(); - if (memcmp(hmac.GetDigest(), authSession->Digest.data(), authSession->Digest.size())) + if (memcmp(hmac.GetDigest().data(), authSession->Digest.data(), authSession->Digest.size())) { TC_LOG_ERROR("network", "WorldSocket::HandleAuthContinuedSession: Authentication failed for account: %u ('%s') address: %s", accountId, login.c_str(), GetRemoteIpAddress().to_string().c_str()); DelayedCloseSocket(); return; } - HmacSha256 encryptKeyGen(40, _sessionKey.AsByteArray(40).get()); - encryptKeyGen.UpdateData(authSession->LocalChallenge.data(), authSession->LocalChallenge.size()); - encryptKeyGen.UpdateData(_serverChallenge.AsByteArray(16).get(), 16); + Trinity::Crypto::HMAC_SHA256 encryptKeyGen(_sessionKey); + encryptKeyGen.UpdateData(authSession->LocalChallenge); + encryptKeyGen.UpdateData(_serverChallenge); encryptKeyGen.UpdateData(EncryptionKeySeed, 16); encryptKeyGen.Finalize(); // only first 16 bytes of the hmac are used - memcpy(_encryptKey, encryptKeyGen.GetDigest(), 16); + memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 16); - SendPacketAndLogOpcode(*WorldPackets::Auth::EnableEncryption(_encryptKey, true).Write()); + SendPacketAndLogOpcode(*WorldPackets::Auth::EnableEncryption(_encryptKey.data(), true).Write()); AsyncRead(); } diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 057c5bd1250..77028643855 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -20,12 +20,12 @@ #include "Common.h" #include "AsyncCallbackProcessor.h" -#include "BigNumber.h" #include "DatabaseEnvFwd.h" #include "MessageBuffer.h" #include "Socket.h" #include "WorldPacketCrypt.h" #include "MPSCQueue.h" +#include <array> #include <chrono> #include <functional> #include <mutex> @@ -130,10 +130,10 @@ private: ConnectionType _type; uint64 _key; - BigNumber _serverChallenge; + std::array<uint8, 16> _serverChallenge; WorldPacketCrypt _authCrypt; - BigNumber _sessionKey; - uint8 _encryptKey[16]; + std::array<uint8, 40> _sessionKey; + std::array<uint8, 16> _encryptKey; std::chrono::steady_clock::time_point _LastPingTime; uint32 _OverSpeedPings; diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index e96a1101ad4..87d2c76b874 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -636,7 +636,7 @@ inline void AppendTableDump(StringTransaction& trans, TableStruct const& tableSt else { std::vector<uint8> b(fields[i].GetBinary()); - ss << "0x" << ByteArrayToHexStr(b.data(), b.size()); + ss << "0x" << ByteArrayToHexStr(b); } } diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index e3ddf6a2e74..fdfc128106b 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -30,7 +30,7 @@ #include <openssl/sha.h> -Warden::Warden() : _session(NULL), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), +Warden::Warden() : _session(NULL), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), _dataSent(false), _previousTimestamp(0), _module(NULL), _initialized(false) { memset(_inputKey, 0, sizeof(_inputKey)); @@ -131,12 +131,12 @@ void Warden::Update() void Warden::DecryptData(uint8* buffer, uint32 length) { - _inputCrypto.UpdateData(length, buffer); + _inputCrypto.UpdateData(buffer, length); } void Warden::EncryptData(uint8* buffer, uint32 length) { - _outputCrypto.UpdateData(length, buffer); + _outputCrypto.UpdateData(buffer, length); } bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length) diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index 12dea8861fa..8ed0c222969 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -18,11 +18,10 @@ #ifndef _WARDEN_BASE_H #define _WARDEN_BASE_H -#include <map> -#include "Cryptography/ARC4.h" -#include "Cryptography/BigNumber.h" +#include "ARC4.h" #include "ByteBuffer.h" #include "WardenCheckMgr.h" +#include <array> enum WardenOpcodes { @@ -100,7 +99,7 @@ class TC_GAME_API Warden Warden(); virtual ~Warden(); - virtual void Init(WorldSession* session, BigNumber* k) = 0; + virtual void Init(WorldSession* session, std::array<uint8, 40> const& K) = 0; virtual ClientWardenModule* GetModuleForClient() = 0; virtual void InitializeModule() = 0; virtual void RequestHash() = 0; @@ -125,8 +124,8 @@ class TC_GAME_API Warden uint8 _inputKey[16]; uint8 _outputKey[16]; uint8 _seed[16]; - ARC4 _inputCrypto; - ARC4 _outputCrypto; + Trinity::Crypto::ARC4 _inputCrypto; + Trinity::Crypto::ARC4 _outputCrypto; uint32 _checkTimer; // Timer for sending check requests uint32 _clientResponseTimer; // Timer for client response delay bool _dataSent; diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index b79b760581b..872779b574d 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -89,19 +89,7 @@ void WardenCheckMgr::LoadWardenChecks() wardenCheck->Action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION)); if (checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == DRIVER_CHECK) - { wardenCheck->Data.SetHexStr(data.c_str()); - int len = data.size() / 2; - - if (wardenCheck->Data.GetNumBytes() < len) - { - uint8 temp[24]; - memset(temp, 0, len); - memcpy(temp, wardenCheck->Data.AsByteArray().get(), wardenCheck->Data.GetNumBytes()); - std::reverse(temp, temp + len); - wardenCheck->Data.SetBinary((uint8*)temp, len); - } - } if (checkType == MEM_CHECK || checkType == MODULE_CHECK) MemChecksIdPool.push_back(id); @@ -124,16 +112,6 @@ void WardenCheckMgr::LoadWardenChecks() { WardenCheckResult* wr = new WardenCheckResult(); wr->Result.SetHexStr(checkResult.c_str()); - int len = checkResult.size() / 2; - if (wr->Result.GetNumBytes() < len) - { - uint8 *temp = new uint8[len]; - memset(temp, 0, len); - memcpy(temp, wr->Result.AsByteArray().get(), wr->Result.GetNumBytes()); - std::reverse(temp, temp + len); - wr->Result.SetBinary((uint8*)temp, len); - delete [] temp; - } CheckResultStore[id] = wr; } diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index cc344298eb6..0129c805a08 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -15,20 +15,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cryptography/SessionKeyGeneration.h" +#include "WardenMac.h" +#include "ByteBuffer.h" #include "Common.h" -#include "WorldPacket.h" -#include "WorldSession.h" +#include "GameTime.h" #include "Log.h" #include "Opcodes.h" -#include "ByteBuffer.h" -#include "GameTime.h" -#include "World.h" #include "Player.h" +#include "SessionKeyGenerator.h" #include "Util.h" -#include "WardenMac.h" #include "WardenModuleMac.h" -#include "SHA1.h" +#include "WorldPacket.h" +#include "WorldSession.h" #include <openssl/md5.h> @@ -36,11 +34,11 @@ WardenMac::WardenMac() : Warden() { } WardenMac::~WardenMac() { } -void WardenMac::Init(WorldSession* pClient, BigNumber* K) +void WardenMac::Init(WorldSession* pClient, std::array<uint8, 40> const& K) { _session = pClient; // Generate Warden Key - SessionKeyGenerator<SHA1Hash> WK(K->AsByteArray().get(), K->GetNumBytes()); + SessionKeyGenerator<Trinity::Crypto::SHA1> WK(K); WK.Generate(_inputKey, 16); WK.Generate(_outputKey, 16); /* @@ -156,14 +154,14 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) buff.rpos(buff.wpos()); - SHA1Hash sha1; + Trinity::Crypto::SHA1 sha1; sha1.UpdateData((uint8*)keyIn, 16); sha1.Finalize(); //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // Verify key - if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) + if (memcmp(buff.contents() + 1, sha1.GetDigest().data(), 20) != 0) { TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; @@ -237,16 +235,16 @@ void WardenMac::HandleData(ByteBuffer &buff) std::string str = "Test string!"; - SHA1Hash sha1; + Trinity::Crypto::SHA1 sha1; sha1.UpdateData(str); uint32 magic = 0xFEEDFACE; // unsure sha1.UpdateData((uint8*)&magic, 4); sha1.Finalize(); - uint8 sha1Hash[20]; - buff.read(sha1Hash, 20); + std::array<uint8, Trinity::Crypto::SHA1::DIGEST_LENGTH> sha1Hash; + buff.read(sha1Hash.data(), sha1Hash.size()); - if (memcmp(sha1Hash, sha1.GetDigest(), 20) != 0) + if (sha1Hash != sha1.GetDigest()) { TC_LOG_DEBUG("warden", "Handle data failed: SHA1 hash is wrong!"); //found = true; diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h index 81ab864cf02..c186e546f9e 100644 --- a/src/server/game/Warden/WardenMac.h +++ b/src/server/game/Warden/WardenMac.h @@ -18,9 +18,7 @@ #ifndef _WARDEN_MAC_H #define _WARDEN_MAC_H -#include "Cryptography/ARC4.h" -#include <map> -#include "Cryptography/BigNumber.h" +#include "ARC4.h" #include "ByteBuffer.h" #include "Warden.h" @@ -33,7 +31,7 @@ class TC_GAME_API WardenMac : public Warden WardenMac(); ~WardenMac(); - void Init(WorldSession* session, BigNumber* k) override; + void Init(WorldSession* session, std::array<uint8, 40> const& k) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; void RequestHash() override; diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 8e427de0acc..3e374c98a11 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -15,24 +15,24 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cryptography/HmacHash.h" -#include "Cryptography/SessionKeyGeneration.h" +#include "WardenWin.h" #include "Common.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Log.h" -#include "Opcodes.h" #include "ByteBuffer.h" -#include "Database/DatabaseEnv.h" +#include "CryptoRandom.h" +#include "DatabaseEnv.h" #include "GameTime.h" -#include "World.h" +#include "HMAC.h" +#include "Log.h" +#include "Opcodes.h" #include "Player.h" +#include "Random.h" +#include "SessionKeyGenerator.h" #include "Util.h" -#include "WardenWin.h" #include "WardenModuleWin.h" #include "WardenCheckMgr.h" -#include "SHA1.h" -#include "Random.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" #include <boost/thread/locks.hpp> #include <boost/thread/shared_mutex.hpp> #include <openssl/md5.h> @@ -41,11 +41,11 @@ WardenWin::WardenWin() : Warden(), _serverTicks(0) {} WardenWin::~WardenWin() { } -void WardenWin::Init(WorldSession* session, BigNumber* k) +void WardenWin::Init(WorldSession* session, std::array<uint8, 40> const& K) { _session = session; // Generate Warden Key - SessionKeyGenerator<SHA1Hash> WK(k->AsByteArray().get(), k->GetNumBytes()); + SessionKeyGenerator<Trinity::Crypto::SHA1> WK(K); WK.Generate(_inputKey, 16); WK.Generate(_outputKey, 16); @@ -265,7 +265,8 @@ void WardenWin::RequestData() case PAGE_CHECK_A: case PAGE_CHECK_B: { - buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes()); + std::vector<uint8> data = wd->Data.ToByteVector(0, false); + buff.append(data.data(), data.size()); buff << uint32(wd->Address); buff << uint8(wd->Length); break; @@ -278,18 +279,16 @@ void WardenWin::RequestData() } case DRIVER_CHECK: { - buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes()); + std::vector<uint8> data = wd->Data.ToByteVector(0, false); + buff.append(data.data(), data.size()); buff << uint8(index++); break; } case MODULE_CHECK: { - uint32 seed = rand32(); - buff << uint32(seed); - HmacSha1 hmac(4, (uint8*)&seed); - hmac.UpdateData(wd->Str); - hmac.Finalize(); - buff.append(hmac.GetDigest(), hmac.GetLength()); + std::array<uint8, 4> seed = Trinity::Crypto::GetRandomBytes<4>(); + buff.append(seed); + buff.append(Trinity::Crypto::HMAC_SHA1::GetDigestOf(seed, wd->Str)); break; } /*case PROC_CHECK: @@ -394,7 +393,8 @@ void WardenWin::HandleData(ByteBuffer &buff) continue; } - if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), rd->Length) != 0) + std::vector<uint8> result = rs->Result.ToByteVector(); + if (memcmp(buff.contents() + buff.rpos(), result.data(), rd->Length) != 0) { TC_LOG_DEBUG("warden", "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; @@ -473,7 +473,7 @@ void WardenWin::HandleData(ByteBuffer &buff) continue; } - if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), 20) != 0) // SHA1 + if (memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<20>(false).data(), 20) != 0) // SHA1 { TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h index c45d73572be..77f66f621a3 100644 --- a/src/server/game/Warden/WardenWin.h +++ b/src/server/game/Warden/WardenWin.h @@ -18,11 +18,11 @@ #ifndef _WARDEN_WIN_H #define _WARDEN_WIN_H -#include <map> #include "Cryptography/ARC4.h" #include "Cryptography/BigNumber.h" #include "ByteBuffer.h" #include "Warden.h" +#include <list> #pragma pack(push, 1) @@ -67,7 +67,7 @@ class TC_GAME_API WardenWin : public Warden WardenWin(); ~WardenWin(); - void Init(WorldSession* session, BigNumber* K) override; + void Init(WorldSession* session, std::array<uint8, 40> const& K) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; void RequestHash() override; diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp index a1166a6c3c9..fc7e8948382 100644 --- a/src/server/scripts/Commands/cs_battlenet_account.cpp +++ b/src/server/scripts/Commands/cs_battlenet_account.cpp @@ -17,8 +17,8 @@ #include "AccountMgr.h" #include "BattlenetAccountMgr.h" -#include "BigNumber.h" #include "Chat.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" #include "IpAddress.h" #include "IPLocation.h" @@ -425,10 +425,9 @@ public: std::string accountName = std::to_string(accountId) + '#' + std::to_string(uint32(index)); // Generate random hex string for password, these accounts must not be logged on with GRUNT - BigNumber randPassword; - randPassword.SetRand(8 * 16); + std::array<uint8, 16> randPassword = Trinity::Crypto::GetRandomBytes<16>(); - switch (sAccountMgr->CreateAccount(accountName, ByteArrayToHexStr(randPassword.AsByteArray().get(), randPassword.GetNumBytes()), bnetAccountName, accountId, index)) + switch (sAccountMgr->CreateAccount(accountName, ByteArrayToHexStr(randPassword), bnetAccountName, accountId, index)) { case AccountOpResult::AOR_OK: handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName.c_str()); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 296da13dafe..13d77b41c14 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -20,6 +20,7 @@ #include "Define.h" #include "ByteConverter.h" +#include <array> #include <string> #include <vector> #include <cstring> @@ -472,6 +473,12 @@ class TC_SHARED_API ByteBuffer _rpos += len; } + template <size_t Size> + void read(std::array<uint8, Size>& arr) + { + read(arr.data(), Size); + } + void ReadPackedUInt64(uint64& guid) { guid = 0; @@ -564,6 +571,12 @@ class TC_SHARED_API ByteBuffer append(buffer.contents(), buffer.size()); } + template <size_t Size> + void append(std::array<uint8, Size> const& arr) + { + append(arr.data(), Size); + } + // can be used in SMSG_MONSTER_MOVE opcode void appendPackXYZ(float x, float y, float z) { diff --git a/src/server/shared/Realm/RealmList.cpp b/src/server/shared/Realm/RealmList.cpp index ca591e423f5..5673636eb28 100644 --- a/src/server/shared/Realm/RealmList.cpp +++ b/src/server/shared/Realm/RealmList.cpp @@ -17,7 +17,7 @@ #include "RealmList.h" #include "BattlenetRpcErrorCodes.h" -#include "BigNumber.h" +#include "CryptoRandom.h" #include "DatabaseEnv.h" #include "DeadlineTimer.h" #include "Errors.h" @@ -404,15 +404,14 @@ uint32 RealmList::JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip:: if (compress(compressed.data() + 4, &compressedLength, reinterpret_cast<uint8 const*>(json.c_str()), uLong(json.length() + 1)) != Z_OK) return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE; - BigNumber serverSecret; - serverSecret.SetRand(8 * 32); + std::array<uint8, 32> serverSecret = Trinity::Crypto::GetRandomBytes<32>(); std::array<uint8, 64> keyData; memcpy(&keyData[0], clientSecret.data(), 32); - memcpy(&keyData[32], serverSecret.AsByteArray(32).get(), 32); + memcpy(&keyData[32], serverSecret.data(), 32); LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO); - stmt->setString(0, ByteArrayToHexStr(keyData.data(), keyData.size())); + stmt->setString(0, ByteArrayToHexStr(keyData)); stmt->setString(1, clientAddress.to_string()); stmt->setUInt8(2, locale); stmt->setString(3, os); @@ -429,7 +428,7 @@ uint32 RealmList::JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip:: attribute = response->add_attribute(); attribute->set_name("Param_JoinSecret"); - attribute->mutable_value()->set_blob_value(serverSecret.AsByteArray(32).get(), 32); + attribute->mutable_value()->set_blob_value(serverSecret.data(), 32); return ERROR_OK; } |
