aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-04-30 20:16:08 +0200
committerShauren <shauren.trinity@gmail.com>2014-04-30 20:50:15 +0200
commita142eb9f7a9683f98fe1e9153f6958f80d374c9d (patch)
tree5522fe49d1628ed6969b1bd6393b9e36b6b2f10b
parentcdae208b9a47cf056330b4ded6b0f8201a7ad9e6 (diff)
Core/Auth: Battle.net stuff
-rw-r--r--src/server/authserver/Authentication/AuthCodes.h51
-rw-r--r--src/server/authserver/Main.cpp26
-rw-r--r--src/server/authserver/Server/BattlenetBitStream.h189
-rw-r--r--src/server/authserver/Server/BattlenetPacketCrypt.cpp39
-rw-r--r--src/server/authserver/Server/BattlenetPacketCrypt.h36
-rw-r--r--src/server/authserver/Server/BattlenetPackets.cpp170
-rw-r--r--src/server/authserver/Server/BattlenetPackets.h202
-rw-r--r--src/server/authserver/Server/BattlenetSocket.cpp124
-rw-r--r--src/server/authserver/Server/BattlenetSocket.h54
-rw-r--r--src/server/authserver/Server/RealmAcceptor.h4
-rw-r--r--src/server/game/Server/WorldSocket.h4
-rw-r--r--src/server/game/Warden/WardenWin.cpp4
-rw-r--r--src/server/shared/Cryptography/Authentication/PacketCrypt.cpp39
-rw-r--r--src/server/shared/Cryptography/Authentication/PacketCrypt.h (renamed from src/server/shared/Cryptography/Authentication/AuthCrypt.h)21
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp (renamed from src/server/shared/Cryptography/Authentication/AuthCrypt.cpp)38
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h34
-rw-r--r--src/server/shared/Cryptography/HmacHash.cpp (renamed from src/server/shared/Cryptography/HMACSHA1.cpp)28
-rw-r--r--src/server/shared/Cryptography/HmacHash.h (renamed from src/server/shared/Cryptography/HMACSHA1.h)13
18 files changed, 1003 insertions, 73 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h
index 5e6522f8981..e844863e4b1 100644
--- a/src/server/authserver/Authentication/AuthCodes.h
+++ b/src/server/authserver/Authentication/AuthCodes.h
@@ -70,6 +70,57 @@ enum LoginResult
LOGIN_LOCKED_ENFORCED = 0x10
};
+namespace Battlenet
+{
+ enum AuthResult
+ {
+ AUTH_OK = 0,
+ AUTH_BAD_SERVER_PROOF = 103,
+ AUTH_UNKNOWN_ACCOUNT = 104,
+ AUTH_CLOSED = 105,
+ AUTH_LOGIN_TIMEOUT = 106,
+ AUTH_NO_GAME_ACCOUNTS = 107,
+ AUTH_INVALID_TOKEN = 108,
+ AUTH_INVALID_PROGRAM = 109,
+ AUTH_INVALID_OS = 110,
+ AUTH_UNSUPPORTED_LANGUAGE = 111,
+ AUTH_REGION_BAD_VERSION = 112,
+ AUTH_TEMP_OUTAGE = 113,
+ AUTH_CANT_DOWNLOAD_MODULE = 114,
+ AUTH_DUPLICATE_LOGON = 115,
+ AUTH_BAD_CREDENTIALS_2 = 116,
+ AUTH_VERSION_CHECK_SUCCEEDED = 117,
+ AUTH_BAD_VERSION_HASH = 118,
+ AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
+ AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
+ AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
+ AUTH_BATTLENET_MAINTENANCE = 122,
+ AUTH_LOGON_TOO_FAST = 123,
+ AUTH_USE_GRUNT_LOGON = 124,
+
+ LOGIN_NO_GAME_ACCOUNT = 201,
+ LOGIN_BANNED = 202,
+ LOGIN_SUSPENDED = 203,
+ LOGIN_GAME_ACCOUNT_LOCKED = 204,
+ LOGIN_ALREADY_ONLINE = 205,
+ LOGIN_NOTIME = 206,
+ LOGIN_EXPIRED = 207,
+ LOGIN_EXPIRED_2 = 208,
+ LOGIN_PARENTALCONTROL = 209,
+ LOGIN_TRIAL_EXPIRED = 210,
+ LOGIN_ANTI_INDULGENCE = 211,
+ LOGIN_INCORRECT_REGION = 212,
+ LOGIN_CHARGEBACK = 213,
+ LOGIN_IGR_WITHOUT_BNET = 214,
+ LOGIN_LOCKED_ENFORCED = 215,
+ LOGIN_UNLOCKABLE_LOCK = 216,
+ LOGIN_IGR_REQUIRED = 217,
+ LOGIN_PAYMENT_CHANGED = 218,
+ LOGIN_INVALID_PAYMENT = 219,
+ LOGIN_INVALID_ACCOUNT_STATE = 220
+ };
+}
+
enum ExpansionFlags
{
POST_BC_EXP_FLAG = 0x2,
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index d1b2b614037..0e23dd99ba8 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -151,7 +151,8 @@ extern int main(int argc, char** argv)
}
// Launch the listening network socket
- RealmAcceptor acceptor;
+ RealmAcceptor<AuthSocket> acceptor;
+ RealmAcceptor<Battlenet::Socket> bnetacceptor;
int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
if (rmport < 0 || rmport > 0xFFFF)
@@ -170,6 +171,13 @@ extern int main(int argc, char** argv)
return 1;
}
+ bind_addr.set_port_number(1119);
+ if (bnetacceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
+ {
+ TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), 1119);
+ return 1;
+ }
+
// Initialize the signal handlers
AuthServerSignalHandler SignalINT, SignalTERM;
@@ -179,24 +187,24 @@ extern int main(int argc, char** argv)
Handler.register_handler(SIGTERM, &SignalTERM);
#if defined(_WIN32) || defined(__linux__)
-
+
///- Handle affinity for multiple processors and process priority
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
#ifdef _WIN32 // Windows
-
+
HANDLE hProcess = GetCurrentProcess();
if (affinity > 0)
{
ULONG_PTR appAff;
ULONG_PTR sysAff;
-
+
if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
{
// remove non accessible processors
ULONG_PTR currentAffinity = affinity & appAff;
-
+
if (!currentAffinity)
TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff);
else if (SetProcessAffinityMask(hProcess, currentAffinity))
@@ -205,7 +213,7 @@ extern int main(int argc, char** argv)
TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity);
}
}
-
+
if (highPriority)
{
if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
@@ -213,9 +221,9 @@ extern int main(int argc, char** argv)
else
TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class.");
}
-
+
#else // Linux
-
+
if (affinity > 0)
{
cpu_set_t mask;
@@ -242,7 +250,7 @@ extern int main(int argc, char** argv)
else
TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
}
-
+
#endif
#endif
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h
new file mode 100644
index 00000000000..fa09b24b204
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetBitStream.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BATTLENETBITSTREAM_H__
+#define __BATTLENETBITSTREAM_H__
+
+#include "ByteConverter.h"
+#include <exception>
+#include <string>
+#include <vector>
+
+namespace Battlenet
+{
+ class BitStreamPositionException : public std::exception
+ {
+ public:
+ char const* what() const
+ {
+ return "";
+ }
+ };
+
+ class BitStream
+ {
+ public:
+ static uint32 const MaxSize = 0x1000;
+
+ // length : The maximum number of bytes to read
+ BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0)
+ {
+ _buffer.resize(length, 0);
+ }
+
+ BitStream() : _numBits(0), _readPos(0), _writePos(0)
+ {
+ _buffer.reserve(0x1000);
+ }
+
+ void AlignToNextByte()
+ {
+ _readPos = (_readPos + 7) & ~7;
+ _writePos = (_writePos + 7) & ~7;
+ }
+
+ std::string ReadString(uint32 bitCount, uint32 baseLength = 0)
+ {
+ uint32 len = Read<uint32>(bitCount) + baseLength;
+ AlignToNextByte();
+ std::string str(reinterpret_cast<char*>(&_buffer[_readPos >> 3]), len);
+ _readPos += len * 8;
+ return str;
+ }
+
+ uint8* ReadBytes(uint32 count)
+ {
+ AlignToNextByte();
+ if (_readPos + count * 8 > _numBits)
+ throw BitStreamPositionException();
+
+ uint8* buf = new uint8[count];
+ memcpy(buf, &_buffer[_readPos >> 3], count);
+ _readPos += count * 8;
+ return buf;
+ }
+
+ float ReadFloat()
+ {
+ uint32 val = Read<uint32>(32);
+ return *reinterpret_cast<float*>(&val);
+ }
+
+ std::string ReadFourCC()
+ {
+ uint32 fcc = Read<uint32>(32);
+ EndianConvertReverse(fcc);
+ size_t len = 4;
+ while (!(fcc & 0xFF))
+ {
+ fcc >>= 8;
+ --len;
+ }
+
+ return std::string(reinterpret_cast<char*>(&fcc), len);
+ }
+
+ template<typename T>
+ T Read(uint32 bitCount)
+ {
+ T ret = 0;
+ while (bitCount != 0)
+ {
+ uint32 bitPos = (_readPos & 7);
+ uint32 bitsLeftInByte = 8 - bitPos;
+ if (bitsLeftInByte >= bitCount)
+ bitsLeftInByte = bitCount;
+
+ bitCount -= bitsLeftInByte;
+ ret |= static_cast<T>((uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount);
+ _readPos += bitsLeftInByte;
+ }
+ return ret;
+ }
+
+ //WriteString
+
+ template<typename T>
+ void WriteBytes(T* data, uint32 count)
+ {
+ AlignToNextByte();
+ if (_writePos + 8 * count > MaxSize)
+ throw BitStreamPositionException();
+
+ _buffer.resize(_buffer.size() + count);
+ memcpy(&_buffer[_writePos >> 3], data, count);
+ _writePos += count * 8;
+ }
+
+ //WriteFloat
+ void WriteFourCC(char const* fcc)
+ {
+ uint32 intVal = *(uint32*)fcc;
+ EndianConvertReverse(intVal);
+ Write(intVal, 32);
+ }
+
+ template<typename T>
+ void Write(T value, uint32 bitCount)
+ {
+ if (_writePos + bitCount >= 8 * MaxSize)
+ throw BitStreamPositionException();
+
+ while (bitCount != 0)
+ {
+ uint32 bitPos = (_writePos & 7);
+ uint32 bitsLeftInByte = 8 - bitPos;
+ if (bitsLeftInByte >= bitCount)
+ bitsLeftInByte = bitCount;
+
+ bitCount -= bitsLeftInByte;
+
+ uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos));
+ uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos);
+
+ if (_buffer.size() > (_writePos >> 3))
+ _buffer[_writePos >> 3] = (uint8)(_buffer[_writePos >> 3] & firstHalf | secondHalf);
+ else
+ _buffer.push_back(secondHalf);
+
+ _writePos += bitsLeftInByte;
+ }
+ }
+
+ void SetReadPos(uint32 bits)
+ {
+ if (bits >= _numBits)
+ throw BitStreamPositionException();
+
+ _readPos = bits;
+ }
+
+ bool IsRead() const { return _readPos >= _numBits; }
+
+ uint8* GetBuffer() { return _buffer.data(); }
+
+ size_t GetSize() const { return _buffer.size(); }
+
+ private:
+ std::vector<uint8> _buffer;
+ uint32 _numBits;
+ uint32 _readPos;
+ uint32 _writePos;
+ };
+}
+
+#endif // __BATTLENETBITSTREAM_H__
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.cpp b/src/server/authserver/Server/BattlenetPacketCrypt.cpp
new file mode 100644
index 00000000000..10aa684e10a
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetPacketCrypt.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlenetPacketCrypt.h"
+#include "Cryptography/HmacHash.h"
+#include "Cryptography/BigNumber.h"
+
+Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH)
+{
+}
+
+void Battlenet::PacketCrypt::Init(BigNumber* K)
+{
+ uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E };
+ HmacHash serverEncryptHmac(SEED_KEY_SIZE, ServerEncryptionKey, EVP_sha256(), SHA256_DIGEST_LENGTH);
+ uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
+
+ uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 };
+ HmacHash clientDecryptHmac(SEED_KEY_SIZE, ClientDecryptionKey, EVP_sha256(), SHA256_DIGEST_LENGTH);
+ uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
+
+ _clientDecrypt.Init(decryptHash);
+ _serverEncrypt.Init(encryptHash);
+ _initialized = true;
+}
diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.h b/src/server/authserver/Server/BattlenetPacketCrypt.h
new file mode 100644
index 00000000000..dde687651d3
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetPacketCrypt.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BATTLENETPACKETCRYPT_H__
+#define __BATTLENETPACKETCRYPT_H__
+
+#include "PacketCrypt.h"
+
+class BigNumber;
+
+namespace Battlenet
+{
+ class PacketCrypt : public ::PacketCrypt
+ {
+ public:
+ PacketCrypt();
+
+ void Init(BigNumber* K) override;
+ };
+}
+
+#endif // __BATTLENETPACKETCRYPT_H__
diff --git a/src/server/authserver/Server/BattlenetPackets.cpp b/src/server/authserver/Server/BattlenetPackets.cpp
new file mode 100644
index 00000000000..37040fa6d6e
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetPackets.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Common.h"
+#include "BattlenetBitStream.h"
+#include "BattlenetPackets.h"
+#include "Util.h"
+#include <limits>
+#include <sstream>
+
+std::string Battlenet::PacketHeader::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel;
+ return stream.str();
+}
+
+Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream())
+{
+ _stream.Write(header.Opcode, 6);
+ _stream.Write(1, 1);
+ _stream.Write(header.Channel, 4);
+}
+
+Battlenet::ServerPacket::~ServerPacket()
+{
+ delete &_stream;
+}
+
+void Battlenet::AuthChallenge::Read()
+{
+ Program = _stream.ReadFourCC();
+ Platform = _stream.ReadFourCC();
+ Locale = _stream.ReadFourCC();
+
+ Components.resize(_stream.Read<uint32>(6));
+ for (size_t i = 0; i < Components.size(); ++i)
+ {
+ Component& component = Components[i];
+ component.Program = _stream.ReadFourCC();
+ component.Platform = _stream.ReadFourCC();
+ component.Build = _stream.Read<uint32>(32);
+ }
+
+ if (_stream.Read<uint32>(1))
+ Login = _stream.ReadString(9, 3);
+}
+
+std::string Battlenet::AuthChallenge::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::AuthChallenge Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
+ for (uint32 i = 0; i < Components.size(); ++i)
+ stream << std::endl << "Battlenet::AuthChallenge::Component Program: " << Components[i].Program << ", Platform: " << Components[i].Platform << ", Build: " << Components[i].Build;
+
+ if (!Login.empty())
+ stream << std::endl << "Battlenet::AuthChallenge Login: " << Login;
+
+ return stream.str();
+}
+
+void Battlenet::ProofRequest::Write()
+{
+ _stream.Write(Modules.size(), 3);
+ for (size_t i = 0; i < Modules.size(); ++i)
+ {
+ ModuleInfo& info = Modules[i];
+ _stream.WriteBytes(info.AuthString.c_str(), 4);
+ _stream.WriteFourCC(info.Locale.c_str());
+ _stream.WriteBytes(info.ModuleId, 32);
+ _stream.Write(info.BlobSize, 10);
+ _stream.WriteBytes(info.Blob, info.BlobSize);
+ }
+}
+
+Battlenet::ProofResponse::~ProofResponse()
+{
+ for (size_t i = 0; i < Modules.size(); ++i)
+ delete[] Modules[i].Data;
+}
+
+void Battlenet::ProofResponse::Read()
+{
+ Modules.resize(_stream.Read<uint32>(3));
+ for (size_t i = 0; i < Modules.size(); ++i)
+ {
+ ModuleData& data = Modules[i];
+ data.Size = _stream.Read<uint32>(10);
+ data.Data = _stream.ReadBytes(data.Size);
+ }
+}
+
+std::string Battlenet::ProofResponse::ToString() const
+{
+ std::ostringstream stream;
+ stream << "Battlenet::ProofResponse Modules " << Modules.size();
+ for (size_t i = 0; i < Modules.size(); ++i)
+ {
+ std::string hexStr = ByteArrayToHexStr(Modules[i].Data, Modules[i].Size);
+ stream << std::endl << "Battlenet::ProofResponse::ModuleData Size: " << Modules[i].Size << ", Data: " << hexStr;
+ }
+
+ return stream.str();
+}
+
+void Battlenet::AuthComplete::Write()
+{
+ _stream.Write(AuthResult != 0, 1);
+ if (AuthResult == 0)
+ {
+ _stream.Write(Modules.size(), 3);
+ for (size_t i = 0; i < Modules.size(); ++i)
+ {
+ ModuleInfo& info = Modules[i];
+ _stream.WriteBytes(info.AuthString.c_str(), 4);
+ _stream.WriteFourCC(info.Locale.c_str());
+ _stream.WriteBytes(info.ModuleId, 32);
+ _stream.Write(info.BlobSize, 10);
+ _stream.WriteBytes(info.Blob, info.BlobSize);
+ }
+
+ _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32);
+ _stream.Write(1, 1);
+ // if written == 1
+ {
+ _stream.Write(1, 1);
+ // if written == 1
+ {
+ _stream.Write(Threshold, 32);
+ _stream.Write(Rate, 32);
+ }
+ }
+
+ // todo more
+ }
+ else
+ {
+ _stream.Write(!Modules.empty(), 1);
+ if (!Modules.empty())
+ {
+ ModuleInfo& info = Modules[0];
+ _stream.WriteBytes(info.AuthString.c_str(), 4);
+ _stream.WriteFourCC(info.Locale.c_str());
+ _stream.WriteBytes(info.ModuleId, 32);
+ _stream.Write(info.BlobSize, 10);
+ _stream.WriteBytes(info.Blob, info.BlobSize);
+ }
+
+ _stream.Write(ErrorType, 2);
+ if (ErrorType == 1)
+ {
+ _stream.Write(AuthResult, 16);
+ _stream.Write(0, 32);
+ }
+ }
+}
diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h
new file mode 100644
index 00000000000..23625e30d2b
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetPackets.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BATTLENETPACKETS_H__
+#define __BATTLENETPACKETS_H__
+
+#include "Define.h"
+#include "Errors.h"
+#include <string>
+
+namespace Battlenet
+{
+ class BitStream;
+
+ enum Channel
+ {
+ NOT_SPECIFIED = -1,
+
+ AUTHENTICATION = 0,
+ CREEP = 1,
+ WOW = 2
+ };
+
+ enum AuthOpcode
+ {
+ CMSG_AUTH_CHALLENGE = 0x0,
+ CMSG_AUTH_PROOF_RESPONSE = 0x2,
+
+ SMSG_AUTH_COMPLETE = 0x0,
+ SMSG_AUTH_PROOF_REQUEST = 0x2,
+ };
+
+ struct PacketHeader
+ {
+ PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { }
+ PacketHeader() : Opcode(0), Channel(NOT_SPECIFIED) { }
+
+ uint32 Opcode;
+ int32 Channel;
+
+ bool operator<(PacketHeader const& right) const
+ {
+ return Opcode < right.Opcode || Channel < right.Channel;
+ }
+
+ bool operator==(PacketHeader const& right) const
+ {
+ return Opcode == right.Opcode && Channel == right.Channel;
+ }
+
+ std::string ToString() const;
+ };
+
+ class Packet
+ {
+ public:
+ Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { }
+ virtual ~Packet() { }
+
+ PacketHeader const& GetHeader() const { return _header; }
+
+ virtual void Write() = 0;
+ virtual void Read() = 0;
+
+ virtual std::string ToString() const = 0;
+
+ protected:
+ PacketHeader _header;
+ BitStream& _stream;
+
+ private:
+ Packet(Packet const& right);
+ Packet& operator=(Packet const& right);
+ };
+
+ class ClientPacket : public Packet
+ {
+ public:
+ ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { }
+
+ void Write() override { ASSERT(!"Write not implemented for this packet."); }
+
+ virtual std::string ToString() const override { return "Battenet::ClientPacket"; };
+ };
+
+ class ServerPacket : public Packet
+ {
+ public:
+ ServerPacket(PacketHeader const& header);
+ ~ServerPacket();
+
+ void Read() override { ASSERT(!"Read not implemented for server packets."); }
+
+ virtual std::string ToString() const override { return "Battenet::ServerPacket"; };
+
+ uint8 const* GetData() const { return _stream.GetBuffer(); }
+ size_t GetSize() const { return _stream.GetSize(); }
+ };
+
+ class AuthChallenge final : public ClientPacket
+ {
+ public:
+ AuthChallenge(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_AUTH_CHALLENGE, AUTHENTICATION) && "Invalid packet header for AuthChallenge");
+ }
+
+ struct Component
+ {
+ std::string Program;
+ std::string Platform;
+ uint32 Build;
+ };
+
+ void Read() override;
+ std::string ToString() const override;
+
+ std::string Program;
+ std::string Platform;
+ std::string Locale;
+ std::vector<Component> Components;
+ std::string Login;
+ };
+
+ struct ModuleInfo
+ {
+ std::string AuthString;
+ std::string Locale;
+ uint8 ModuleId[32];
+ uint32 BlobSize;
+ uint8* Blob;
+ };
+
+ class ProofRequest final : public ServerPacket
+ {
+ public:
+ ProofRequest() : ServerPacket(PacketHeader(SMSG_AUTH_PROOF_REQUEST, AUTHENTICATION)) { }
+
+ void Write() override;
+
+ std::vector<ModuleInfo> Modules;
+ };
+
+ class ProofResponse final : public ClientPacket
+ {
+ public:
+ ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
+ {
+ ASSERT(header == PacketHeader(CMSG_AUTH_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse");
+ }
+
+ ~ProofResponse();
+
+ struct ModuleData
+ {
+ uint32 Size;
+ uint8* Data;
+ };
+
+ void Read() override;
+ std::string ToString() const override;
+
+ std::vector<ModuleData> Modules;
+ };
+
+ class AuthComplete final : public ServerPacket
+ {
+ public:
+ AuthComplete() : ServerPacket(PacketHeader(SMSG_AUTH_COMPLETE, AUTHENTICATION)),
+ AuthResult(0), ErrorType(0), PingTimeout(120000), Threshold(1000000), Rate(1000)
+ {
+ }
+
+ void Write() override;
+
+ uint32 AuthResult;
+ std::vector<ModuleInfo> Modules;
+ uint32 ErrorType;
+
+ int32 PingTimeout;
+ uint32 Threshold;
+ uint32 Rate;
+ std::string FirstName;
+ std::string LastName;
+ };
+}
+
+#endif // __BATTLENETPACKETS_H__
diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp
new file mode 100644
index 00000000000..fb9ca008e8b
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetSocket.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AuthCodes.h"
+#include "BattlenetBitStream.h"
+#include "BattlenetPackets.h"
+#include "BattlenetSocket.h"
+#include <map>
+
+bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& packet)
+{
+ AuthChallenge info(header, packet);
+ info.Read();
+
+ printf("%s\n", info.ToString().c_str());
+
+ _accountName = info.Login;
+
+ ProofRequest request;
+ request.Write();
+ _socket.send((char const*)request.GetData(), request.GetSize());
+ return true;
+}
+
+bool Battlenet::Socket::HandleAuthProofResponse(PacketHeader& header, BitStream& packet)
+{
+ ProofResponse response(header, packet);
+ response.Read();
+
+ printf("%s\n", response.ToString().c_str());
+
+ AuthComplete complete;
+ complete.ErrorType = 1;
+ complete.AuthResult = AUTH_USE_GRUNT_LOGON;
+ complete.Write();
+ _socket.send((char const*)complete.GetData(), complete.GetSize());
+ return true;
+}
+
+std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> InitHandlers()
+{
+ std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> handlers;
+
+ handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_CHALLENGE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthChallenge;
+ handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthProofResponse;
+
+ return handlers;
+}
+
+std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> Handlers = InitHandlers();
+
+Battlenet::Socket::Socket(RealmSocket& socket) : _socket(socket), _currentChannel(0)
+{
+}
+
+void Battlenet::Socket::OnRead()
+{
+ while (1)
+ {
+ size_t length = _socket.recv_len();
+ if (!length)
+ return;
+
+ BitStream packet(length);
+ if (!_socket.recv((char*)packet.GetBuffer(), length))
+ return;
+
+ while (!packet.IsRead())
+ {
+ try
+ {
+ PacketHeader header;
+ header.Opcode = packet.Read<uint32>(6);
+ if (packet.Read<uint32>(1))
+ _currentChannel = header.Channel = packet.Read<int32>(4);
+
+ printf("Battlenet::Socket::OnRead %s\n", header.ToString().c_str());
+ std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header);
+ if (itr != Handlers.end())
+ {
+ if (!(this->*(itr->second))(header, packet))
+ {
+ _socket.shutdown();
+ return;
+ }
+ }
+ else
+ printf("Battlenet::Socket::OnRead Unhandled opcode %s\n", header.ToString().c_str());
+
+ packet.AlignToNextByte();
+ }
+ catch (BitStreamPositionException const& e)
+ {
+ printf("Battlenet::Socket::OnRead Exception: %s\n", e.what());
+ _socket.shutdown();
+ return;
+ }
+ }
+ }
+}
+
+void Battlenet::Socket::OnAccept()
+{
+ printf("Battlenet::Socket::OnAccept\n");
+}
+
+void Battlenet::Socket::OnClose()
+{
+ printf("Battlenet::Socket::OnClose\n");
+}
diff --git a/src/server/authserver/Server/BattlenetSocket.h b/src/server/authserver/Server/BattlenetSocket.h
new file mode 100644
index 00000000000..f7cc59d7e97
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetSocket.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BATTLENETSOCKET_H
+#define _BATTLENETSOCKET_H
+
+#include "RealmSocket.h"
+#include "BattlenetPacketCrypt.h"
+
+namespace Battlenet
+{
+ struct PacketHeader;
+ class BitStream;
+
+ class Socket : public RealmSocket::Session
+ {
+ public:
+ Socket(RealmSocket& socket);
+
+ typedef bool(Socket::*PacketHandler)(PacketHeader& socket, BitStream& packet);
+
+ bool HandleAuthChallenge(PacketHeader& header, BitStream& packet);
+ bool HandleAuthProofResponse(PacketHeader& header, BitStream& packet);
+
+ void OnRead() override;
+ void OnAccept() override;
+ void OnClose() override;
+
+ private:
+ RealmSocket& _socket;
+ uint32 _currentChannel;
+
+ std::string _accountName;
+
+ PacketCrypt _crypt;
+ };
+
+}
+
+#endif // _BATTLENETSOCKET_H
diff --git a/src/server/authserver/Server/RealmAcceptor.h b/src/server/authserver/Server/RealmAcceptor.h
index e89135c4896..2089b0c7a22 100644
--- a/src/server/authserver/Server/RealmAcceptor.h
+++ b/src/server/authserver/Server/RealmAcceptor.h
@@ -24,7 +24,9 @@
#include "RealmSocket.h"
#include "AuthSocket.h"
+#include "BattlenetSocket.h"
+template<class LoginType>
class RealmAcceptor : public ACE_Acceptor<RealmSocket, ACE_SOCK_Acceptor>
{
public:
@@ -42,7 +44,7 @@ protected:
ACE_NEW_RETURN(sh, RealmSocket, -1);
sh->reactor(reactor());
- sh->set_session(new AuthSocket(*sh));
+ sh->set_session(new LoginType(*sh));
return 0;
}
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index 4ccacd05c7e..306a50c083a 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -39,7 +39,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "Common.h"
-#include "AuthCrypt.h"
+#include "WorldPacketCrypt.h"
class ACE_Message_Block;
class WorldPacket;
@@ -176,7 +176,7 @@ class WorldSocket : public WorldHandler
std::string m_Address;
/// Class used for managing encryption of the headers
- AuthCrypt m_Crypt;
+ WorldPacketCrypt m_Crypt;
/// Mutex lock to protect m_Session
LockType m_SessionLock;
diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp
index 18bf2897358..3014fcfb993 100644
--- a/src/server/game/Warden/WardenWin.cpp
+++ b/src/server/game/Warden/WardenWin.cpp
@@ -16,7 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Cryptography/HMACSHA1.h"
+#include "Cryptography/HmacHash.h"
#include "Cryptography/WardenKeyGeneration.h"
#include "Common.h"
#include "WorldPacket.h"
@@ -283,7 +283,7 @@ void WardenWin::RequestData()
{
uint32 seed = static_cast<uint32>(rand32());
buff << uint32(seed);
- HmacHash hmac(4, (uint8*)&seed);
+ HmacHash hmac(4, (uint8*)&seed, EVP_sha1(), SHA_DIGEST_LENGTH);
hmac.UpdateData(wd->Str);
hmac.Finalize();
buff.append(hmac.GetDigest(), hmac.GetLength());
diff --git a/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp
new file mode 100644
index 00000000000..7fac311b8a2
--- /dev/null
+++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PacketCrypt.h"
+
+PacketCrypt::PacketCrypt(uint32 rc4InitSize)
+ : _clientDecrypt(rc4InitSize), _serverEncrypt(rc4InitSize), _initialized(false)
+{
+}
+
+void PacketCrypt::DecryptRecv(uint8* data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _clientDecrypt.UpdateData(len, data);
+}
+
+void PacketCrypt::EncryptSend(uint8* data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _serverEncrypt.UpdateData(len, data);
+}
diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.h b/src/server/shared/Cryptography/Authentication/PacketCrypt.h
index 8fa150068a2..36f3b81fb53 100644
--- a/src/server/shared/Cryptography/Authentication/AuthCrypt.h
+++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,27 +15,29 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _AUTHCRYPT_H
-#define _AUTHCRYPT_H
+#ifndef _PACKETCRYPT_H
+#define _PACKETCRYPT_H
#include "Cryptography/ARC4.h"
class BigNumber;
-class AuthCrypt
+class PacketCrypt
{
public:
- AuthCrypt();
+ PacketCrypt(uint32 rc4InitSize);
+ virtual ~PacketCrypt() { }
- void Init(BigNumber* K);
- void DecryptRecv(uint8 *, size_t);
- void EncryptSend(uint8 *, size_t);
+ virtual void Init(BigNumber* K) = 0;
+ void DecryptRecv(uint8* data, size_t length);
+ void EncryptSend(uint8* data, size_t length);
bool IsInitialized() const { return _initialized; }
- private:
+ protected:
ARC4 _clientDecrypt;
ARC4 _serverEncrypt;
bool _initialized;
};
-#endif
+
+#endif // _PACKETCRYPT_H
diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
index ff94f307254..c6b283d9961 100644
--- a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
@@ -16,58 +16,36 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "AuthCrypt.h"
-#include "Cryptography/HMACSHA1.h"
+#include "WorldPacketCrypt.h"
+#include "Cryptography/HmacHash.h"
#include "Cryptography/BigNumber.h"
-AuthCrypt::AuthCrypt() :
- _clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH),
- _initialized(false)
-{ }
+WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH)
+{
+}
-void AuthCrypt::Init(BigNumber* K)
+void WorldPacketCrypt::Init(BigNumber* K)
{
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
- HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
+ HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey, EVP_sha1(), SHA_DIGEST_LENGTH);
uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
- HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
+ HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey, EVP_sha1(), SHA_DIGEST_LENGTH);
uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
- //ARC4 _serverDecrypt(encryptHash);
_clientDecrypt.Init(decryptHash);
_serverEncrypt.Init(encryptHash);
- //ARC4 _clientEncrypt(decryptHash);
// Drop first 1024 bytes, as WoW uses ARC4-drop1024.
uint8 syncBuf[1024];
memset(syncBuf, 0, 1024);
_serverEncrypt.UpdateData(1024, syncBuf);
- //_clientEncrypt.UpdateData(1024, syncBuf);
memset(syncBuf, 0, 1024);
- //_serverDecrypt.UpdateData(1024, syncBuf);
_clientDecrypt.UpdateData(1024, syncBuf);
_initialized = true;
}
-
-void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
-{
- if (!_initialized)
- return;
-
- _clientDecrypt.UpdateData(len, data);
-}
-
-void AuthCrypt::EncryptSend(uint8 *data, size_t len)
-{
- if (!_initialized)
- return;
-
- _serverEncrypt.UpdateData(len, data);
-}
-
diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
new file mode 100644
index 00000000000..7ccca11f09d
--- /dev/null
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _WORLDPACKETCRYPT_H
+#define _WORLDPACKETCRYPT_H
+
+#include "PacketCrypt.h"
+
+class BigNumber;
+
+class WorldPacketCrypt : public PacketCrypt
+{
+ public:
+ WorldPacketCrypt();
+
+ void Init(BigNumber* K) override;
+};
+
+#endif // _WORLDPACKETCRYPT_H
diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HmacHash.cpp
index 2148a3b8a7b..7a365ade457 100644
--- a/src/server/shared/Cryptography/HMACSHA1.cpp
+++ b/src/server/shared/Cryptography/HmacHash.cpp
@@ -16,42 +16,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "HMACSHA1.h"
+#include "HmacHash.h"
#include "BigNumber.h"
#include "Common.h"
-HmacHash::HmacHash(uint32 len, uint8 *seed)
+HmacHash::HmacHash(uint32 len, uint8 *seed, EVP_MD const* hasher, uint32 digestLength)
{
- HMAC_CTX_init(&m_ctx);
- HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL);
- memset(m_digest, 0, sizeof(m_digest));
+ HMAC_CTX_init(&_ctx);
+ HMAC_Init_ex(&_ctx, seed, len, hasher, NULL);
+ _digest = new uint8[digestLength];
+ memset(_digest, 0, digestLength);
}
HmacHash::~HmacHash()
{
- HMAC_CTX_cleanup(&m_ctx);
+ HMAC_CTX_cleanup(&_ctx);
+ delete[] _digest;
}
void HmacHash::UpdateData(const std::string &str)
{
- HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length());
+ HMAC_Update(&_ctx, (uint8 const*)str.c_str(), str.length());
}
void HmacHash::UpdateData(const uint8* data, size_t len)
{
- HMAC_Update(&m_ctx, data, len);
+ HMAC_Update(&_ctx, data, len);
}
void HmacHash::Finalize()
{
uint32 length = 0;
- HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
- ASSERT(length == SHA_DIGEST_LENGTH);
+ HMAC_Final(&_ctx, _digest, &length);
+ ASSERT(length == _digestLength);
}
-uint8 *HmacHash::ComputeHash(BigNumber* bn)
+uint8* HmacHash::ComputeHash(BigNumber* bn)
{
- HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
+ HMAC_Update(&_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
Finalize();
- return (uint8*)m_digest;
+ return _digest;
}
diff --git a/src/server/shared/Cryptography/HMACSHA1.h b/src/server/shared/Cryptography/HmacHash.h
index de1556d3c98..cf59e16f08e 100644
--- a/src/server/shared/Cryptography/HMACSHA1.h
+++ b/src/server/shared/Cryptography/HmacHash.h
@@ -31,17 +31,18 @@ class BigNumber;
class HmacHash
{
public:
- HmacHash(uint32 len, uint8 *seed);
+ HmacHash(uint32 len, uint8 *seed, EVP_MD const* hasher, uint32 digestLength);
~HmacHash();
void UpdateData(const std::string &str);
void UpdateData(const uint8* data, size_t len);
void Finalize();
- uint8 *ComputeHash(BigNumber* bn);
- uint8 *GetDigest() { return (uint8*)m_digest; }
+ uint8* ComputeHash(BigNumber* bn);
+ uint8* GetDigest() { return _digest; }
int GetLength() const { return SHA_DIGEST_LENGTH; }
private:
- HMAC_CTX m_ctx;
- uint8 m_digest[SHA_DIGEST_LENGTH];
+ HMAC_CTX _ctx;
+ uint8* _digest;
+ uint32 _digestLength;
};
-#endif
+#endif