aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-07-26 01:53:34 +0200
committerShauren <shauren.trinity@gmail.com>2020-08-03 19:39:00 +0200
commite9392ad28767626e519c463e2110184d71ba8426 (patch)
treeda391d7daf1ede4ef73883b5053520e160dc4ec4 /src
parentcaa1e1171a1ea4e2db754cfb52b3be795385d544 (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')
-rw-r--r--src/common/Cryptography/AES.cpp22
-rw-r--r--src/common/Cryptography/AES.h31
-rw-r--r--src/common/Cryptography/ARC4.cpp36
-rw-r--r--src/common/Cryptography/ARC4.h33
-rw-r--r--src/common/Cryptography/Authentication/WorldPacketCrypt.cpp10
-rw-r--r--src/common/Cryptography/Authentication/WorldPacketCrypt.h11
-rw-r--r--src/common/Cryptography/BigNumber.cpp42
-rw-r--r--src/common/Cryptography/BigNumber.h26
-rw-r--r--src/common/Cryptography/CryptoConstants.h35
-rw-r--r--src/common/Cryptography/CryptoGenerics.h117
-rw-r--r--src/common/Cryptography/CryptoHash.h142
-rw-r--r--src/common/Cryptography/CryptoRandom.cpp26
-rw-r--r--src/common/Cryptography/CryptoRandom.h (renamed from src/common/Cryptography/SHA256.h)57
-rw-r--r--src/common/Cryptography/HMAC.h153
-rw-r--r--src/common/Cryptography/HmacHash.cpp80
-rw-r--r--src/common/Cryptography/HmacHash.h52
-rw-r--r--src/common/Cryptography/RSA.h13
-rw-r--r--src/common/Cryptography/SHA1.cpp76
-rw-r--r--src/common/Cryptography/SHA1.h55
-rw-r--r--src/common/Cryptography/SHA256.cpp67
-rw-r--r--src/common/Cryptography/SessionKeyGeneration.h82
-rw-r--r--src/common/Cryptography/SessionKeyGenerator.h63
-rw-r--r--src/common/Utilities/Util.cpp2
-rw-r--r--src/common/Utilities/Util.h5
-rw-r--r--src/common/Utilities/advstd.h52
-rw-r--r--src/server/bnetserver/Main.cpp1
-rw-r--r--src/server/bnetserver/REST/LoginRESTService.cpp17
-rw-r--r--src/server/bnetserver/Server/Session.cpp6
-rw-r--r--src/server/bnetserver/Server/Session.h1
-rw-r--r--src/server/database/Updater/UpdateFetcher.cpp4
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp11
-rw-r--r--src/server/game/Accounts/BattlenetAccountMgr.cpp10
-rw-r--r--src/server/game/Scripting/ScriptReloadMgr.cpp5
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.cpp12
-rw-r--r--src/server/game/Server/WorldSession.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/Server/WorldSocket.cpp77
-rw-r--r--src/server/game/Server/WorldSocket.h8
-rw-r--r--src/server/game/Tools/PlayerDump.cpp2
-rw-r--r--src/server/game/Warden/Warden.cpp6
-rw-r--r--src/server/game/Warden/Warden.h11
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp22
-rw-r--r--src/server/game/Warden/WardenMac.cpp30
-rw-r--r--src/server/game/Warden/WardenMac.h6
-rw-r--r--src/server/game/Warden/WardenWin.cpp46
-rw-r--r--src/server/game/Warden/WardenWin.h4
-rw-r--r--src/server/scripts/Commands/cs_battlenet_account.cpp7
-rw-r--r--src/server/shared/Packets/ByteBuffer.h13
-rw-r--r--src/server/shared/Realm/RealmList.cpp11
49 files changed, 906 insertions, 697 deletions
diff --git a/src/common/Cryptography/AES.cpp b/src/common/Cryptography/AES.cpp
index 08762e224e9..7d4ccc7c46f 100644
--- a/src/common/Cryptography/AES.cpp
+++ b/src/common/Cryptography/AES.cpp
@@ -16,11 +16,14 @@
*/
#include "AES.h"
+#include "Errors.h"
+#include <limits>
Trinity::Crypto::AES::AES(bool encrypting) : _ctx(EVP_CIPHER_CTX_new()), _encrypting(encrypting)
{
EVP_CIPHER_CTX_init(_ctx);
- EVP_CipherInit_ex(_ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr, _encrypting ? 1 : 0);
+ int status = EVP_CipherInit_ex(_ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr, _encrypting ? 1 : 0);
+ ASSERT(status);
}
Trinity::Crypto::AES::~AES()
@@ -28,26 +31,33 @@ Trinity::Crypto::AES::~AES()
EVP_CIPHER_CTX_free(_ctx);
}
-void Trinity::Crypto::AES::Init(uint8 const* key)
+void Trinity::Crypto::AES::Init(Key const& key)
{
- EVP_CipherInit_ex(_ctx, nullptr, nullptr, key, nullptr, -1);
+ int status = EVP_CipherInit_ex(_ctx, nullptr, nullptr, key.data(), nullptr, -1);
+ ASSERT(status);
}
-bool Trinity::Crypto::AES::Process(uint8 const* iv, uint8* data, std::size_t length, uint8(&tag)[12])
+bool Trinity::Crypto::AES::Process(IV const& iv, uint8* data, size_t length, Tag& tag)
{
- if (!EVP_CipherInit_ex(_ctx, nullptr, nullptr, nullptr, iv, -1))
+ ASSERT(length <= std::numeric_limits<int>::max());
+ int len = static_cast<int>(length);
+ if (!EVP_CipherInit_ex(_ctx, nullptr, nullptr, nullptr, iv.data(), -1))
return false;
int outLen;
- if (!EVP_CipherUpdate(_ctx, data, &outLen, data, length))
+ if (!EVP_CipherUpdate(_ctx, data, &outLen, data, len))
return false;
+ len -= outLen;
+
if (!_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag))
return false;
if (!EVP_CipherFinal_ex(_ctx, data + outLen, &outLen))
return false;
+ ASSERT(len == outLen);
+
if (_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag))
return false;
diff --git a/src/common/Cryptography/AES.h b/src/common/Cryptography/AES.h
index 8f83b2e3e57..d3b9f48c552 100644
--- a/src/common/Cryptography/AES.h
+++ b/src/common/Cryptography/AES.h
@@ -19,26 +19,35 @@
#define Trinity_AES_h__
#include "Define.h"
+#include <array>
#include <openssl/evp.h>
namespace Trinity
{
namespace Crypto
{
-class TC_COMMON_API AES
-{
-public:
- AES(bool encrypting);
- ~AES();
+ class TC_COMMON_API AES
+ {
+ public:
+ static constexpr size_t IV_SIZE_BYTES = 12;
+ static constexpr size_t KEY_SIZE_BYTES = 16;
+ static constexpr size_t TAG_SIZE_BYTES = 12;
+
+ using IV = std::array<uint8, IV_SIZE_BYTES>;
+ using Key = std::array<uint8, KEY_SIZE_BYTES>;
+ using Tag = uint8[TAG_SIZE_BYTES];
+
+ AES(bool encrypting);
+ ~AES();
- void Init(uint8 const* key);
+ void Init(Key const& key);
- bool Process(uint8 const* iv, uint8* data, std::size_t length, uint8(&tag)[12]);
+ bool Process(IV const& iv, uint8* data, size_t length, Tag& tag);
-private:
- EVP_CIPHER_CTX* _ctx;
- bool _encrypting;
-};
+ private:
+ EVP_CIPHER_CTX* _ctx;
+ bool _encrypting;
+ };
}
}
diff --git a/src/common/Cryptography/ARC4.cpp b/src/common/Cryptography/ARC4.cpp
index fe32fec8ef4..161303e2c15 100644
--- a/src/common/Cryptography/ARC4.cpp
+++ b/src/common/Cryptography/ARC4.cpp
@@ -16,35 +16,33 @@
*/
#include "ARC4.h"
+#include "Errors.h"
-ARC4::ARC4(uint32 len) : m_ctx(EVP_CIPHER_CTX_new())
+Trinity::Crypto::ARC4::ARC4() : _ctx(EVP_CIPHER_CTX_new())
{
- EVP_CIPHER_CTX_init(m_ctx);
- EVP_EncryptInit_ex(m_ctx, EVP_rc4(), nullptr, nullptr, nullptr);
- EVP_CIPHER_CTX_set_key_length(m_ctx, len);
+ EVP_CIPHER_CTX_init(_ctx);
+ int result = EVP_EncryptInit_ex(_ctx, EVP_rc4(), nullptr, nullptr, nullptr);
+ ASSERT(result == 1);
}
-ARC4::ARC4(uint8* seed, uint32 len) : m_ctx(EVP_CIPHER_CTX_new())
+Trinity::Crypto::ARC4::~ARC4()
{
- EVP_CIPHER_CTX_init(m_ctx);
- EVP_EncryptInit_ex(m_ctx, EVP_rc4(), nullptr, nullptr, nullptr);
- EVP_CIPHER_CTX_set_key_length(m_ctx, len);
- EVP_EncryptInit_ex(m_ctx, nullptr, nullptr, seed, nullptr);
+ EVP_CIPHER_CTX_free(_ctx);
}
-ARC4::~ARC4()
+void Trinity::Crypto::ARC4::Init(uint8 const* seed, size_t len)
{
- EVP_CIPHER_CTX_free(m_ctx);
+ int result1 = EVP_CIPHER_CTX_set_key_length(_ctx, len);
+ ASSERT(result1 == 1);
+ int result2 = EVP_EncryptInit_ex(_ctx, nullptr, nullptr, seed, nullptr);
+ ASSERT(result2 == 1);
}
-void ARC4::Init(uint8* seed)
-{
- EVP_EncryptInit_ex(m_ctx, nullptr, nullptr, seed, nullptr);
-}
-
-void ARC4::UpdateData(int len, uint8* data)
+void Trinity::Crypto::ARC4::UpdateData(uint8* data, size_t len)
{
int outlen = 0;
- EVP_EncryptUpdate(m_ctx, data, &outlen, data, len);
- EVP_EncryptFinal_ex(m_ctx, data, &outlen);
+ int result1 = EVP_EncryptUpdate(_ctx, data, &outlen, data, len);
+ ASSERT(result1 == 1);
+ int result2 = EVP_EncryptFinal_ex(_ctx, data, &outlen);
+ ASSERT(result2 == 1);
}
diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h
index e0b0d2d39b6..2adfba919ec 100644
--- a/src/common/Cryptography/ARC4.h
+++ b/src/common/Cryptography/ARC4.h
@@ -19,18 +19,31 @@
#define _AUTH_SARC4_H
#include "Define.h"
+#include <array>
#include <openssl/evp.h>
+#include "advstd.h" // data/size
-class TC_COMMON_API ARC4
+namespace Trinity
{
- public:
- ARC4(uint32 len);
- ARC4(uint8* seed, uint32 len);
- ~ARC4();
- void Init(uint8* seed);
- void UpdateData(int len, uint8* data);
- private:
- EVP_CIPHER_CTX* m_ctx;
-};
+namespace Crypto
+{
+ class TC_COMMON_API ARC4
+ {
+ public:
+ ARC4();
+ ~ARC4();
+
+ void Init(uint8 const* seed, size_t len);
+ template <typename Container>
+ void Init(Container const& c) { Init(advstd::data(c), advstd::size(c)); }
+
+ void UpdateData(uint8* data, size_t len);
+ template <typename Container>
+ void UpdateData(Container& c) { UpdateData(advstd::data(c), advstd::size(c)); }
+ private:
+ EVP_CIPHER_CTX* _ctx;
+ };
+}
+}
#endif
diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
index 6385c5cfd83..723657048d5 100644
--- a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
+++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
@@ -23,7 +23,7 @@ WorldPacketCrypt::WorldPacketCrypt() : _clientDecrypt(false), _serverEncrypt(tru
{
}
-void WorldPacketCrypt::Init(uint8 const* key)
+void WorldPacketCrypt::Init(Trinity::Crypto::AES::Key const& key)
{
_clientDecrypt.Init(key);
_serverEncrypt.Init(key);
@@ -41,12 +41,12 @@ struct WorldPacketCryptIV
std::array<uint8, 12> Value;
};
-bool WorldPacketCrypt::DecryptRecv(uint8* data, size_t length, uint8 (&tag)[12])
+bool WorldPacketCrypt::DecryptRecv(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag)
{
if (_initialized)
{
WorldPacketCryptIV iv{ _clientCounter, 0x544E4C43 };
- if (!_clientDecrypt.Process(iv.Value.data(), data, length, tag))
+ if (!_clientDecrypt.Process(iv.Value, data, length, tag))
return false;
}
else
@@ -56,12 +56,12 @@ bool WorldPacketCrypt::DecryptRecv(uint8* data, size_t length, uint8 (&tag)[12])
return true;
}
-bool WorldPacketCrypt::EncryptSend(uint8* data, size_t length, uint8 (&tag)[12])
+bool WorldPacketCrypt::EncryptSend(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag)
{
if (_initialized)
{
WorldPacketCryptIV iv{ _serverCounter, 0x52565253 };
- if (!_serverEncrypt.Process(iv.Value.data(), data, length, tag))
+ if (!_serverEncrypt.Process(iv.Value, data, length, tag))
return false;
}
else
diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.h b/src/common/Cryptography/Authentication/WorldPacketCrypt.h
index e2f061183f3..5cd6e1282b8 100644
--- a/src/common/Cryptography/Authentication/WorldPacketCrypt.h
+++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.h
@@ -18,18 +18,17 @@
#ifndef _WORLDPACKETCRYPT_H
#define _WORLDPACKETCRYPT_H
-#include "Cryptography/AES.h"
-
-class BigNumber;
+#include "AES.h"
+#include <array>
class TC_COMMON_API WorldPacketCrypt
{
public:
WorldPacketCrypt();
- void Init(uint8 const* key);
- bool DecryptRecv(uint8* data, size_t length, uint8 (&tag)[12]);
- bool EncryptSend(uint8* data, size_t length, uint8 (&tag)[12]);
+ void Init(Trinity::Crypto::AES::Key const& key);
+ bool DecryptRecv(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag);
+ bool EncryptSend(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag);
bool IsInitialized() const { return _initialized; }
diff --git a/src/common/Cryptography/BigNumber.cpp b/src/common/Cryptography/BigNumber.cpp
index 456893d3637..ef5a413d964 100644
--- a/src/common/Cryptography/BigNumber.cpp
+++ b/src/common/Cryptography/BigNumber.cpp
@@ -16,6 +16,7 @@
*/
#include "Cryptography/BigNumber.h"
+#include "Errors.h"
#include <openssl/bn.h>
#include <cstring>
#include <algorithm>
@@ -29,12 +30,6 @@ BigNumber::BigNumber(BigNumber const& bn)
: _bn(BN_dup(bn._bn))
{ }
-BigNumber::BigNumber(uint32 val)
- : _bn(BN_new())
-{
- BN_set_word(_bn, val);
-}
-
BigNumber::~BigNumber()
{
BN_free(_bn);
@@ -64,9 +59,10 @@ void BigNumber::SetBinary(uint8 const* bytes, int32 len)
delete[] array;
}
-void BigNumber::SetHexStr(char const* str)
+bool BigNumber::SetHexStr(char const* str)
{
- BN_hex2bn(&_bn, str);
+ int n = BN_hex2bn(&_bn, str);
+ return (n > 0);
}
void BigNumber::SetRand(int32 numbits)
@@ -152,7 +148,7 @@ BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2)
return ret;
}
-int32 BigNumber::GetNumBytes(void)
+int32 BigNumber::GetNumBytes(void) const
{
return BN_num_bytes(_bn);
}
@@ -172,25 +168,33 @@ bool BigNumber::IsNegative() const
return BN_is_negative(_bn);
}
-std::unique_ptr<uint8[]> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
+void BigNumber::GetBytes(uint8* buf, std::size_t bufsize, bool littleEndian) const
{
- int numBytes = GetNumBytes();
- int length = (minSize >= numBytes) ? minSize : numBytes;
+ int nBytes = GetNumBytes();
+ ASSERT(nBytes >= 0, "Bignum has negative number of bytes (%d).", nBytes);
+ std::size_t numBytes = static_cast<std::size_t>(nBytes);
- uint8* array = new uint8[length];
+ // too large to store
+ ASSERT(numBytes <= bufsize, "Buffer of size %zu is too small to hold bignum with %zu bytes.\n", bufsize, numBytes);
// If we need more bytes than length of BigNumber set the rest to 0
- if (length > numBytes)
- memset((void*)array, 0, length);
+ if (numBytes < bufsize)
+ memset((void*)buf, 0, bufsize);
- BN_bn2bin(_bn, (unsigned char *)array);
+ BN_bn2bin(_bn, buf + (bufsize - numBytes));
// openssl's BN stores data internally in big endian format, reverse if little endian desired
if (littleEndian)
- std::reverse(array, array + numBytes);
+ std::reverse(buf, buf + bufsize);
+}
- std::unique_ptr<uint8[]> ret(array);
- return ret;
+std::vector<uint8> BigNumber::ToByteVector(int32 minSize, bool littleEndian) const
+{
+ std::size_t length = std::max(GetNumBytes(), minSize);
+ std::vector<uint8> v;
+ v.resize(length);
+ GetBytes(v.data(), length, littleEndian);
+ return v;
}
std::string BigNumber::AsHexStr() const
diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h
index 44052f5959b..1f5050bc4f5 100644
--- a/src/common/Cryptography/BigNumber.h
+++ b/src/common/Cryptography/BigNumber.h
@@ -21,6 +21,8 @@
#include "Define.h"
#include <memory>
#include <string>
+#include <vector>
+#include "advstd.h" // data/size
struct bignum_st;
@@ -29,13 +31,20 @@ class TC_COMMON_API BigNumber
public:
BigNumber();
BigNumber(BigNumber const& bn);
- BigNumber(uint32);
+ BigNumber(uint32 v) : BigNumber() { SetDword(v); }
+ BigNumber(std::string const& v) : BigNumber() { SetHexStr(v); }
+ template <size_t Size>
+ BigNumber(std::array<uint8, Size> const& v) : BigNumber() { SetBinary(v.data(), Size); }
+
~BigNumber();
void SetDword(uint32);
void SetQword(uint64);
void SetBinary(uint8 const* bytes, int32 len);
- void SetHexStr(char const* str);
+ template <typename Container>
+ void SetBinary(Container const& c) { SetBinary(advstd::data(c), advstd::size(c)); }
+ bool SetHexStr(char const* str);
+ bool SetHexStr(std::string const& str) { return SetHexStr(str.c_str()); }
void SetRand(int32 numbits);
@@ -82,13 +91,22 @@ class TC_COMMON_API BigNumber
BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2);
BigNumber Exp(BigNumber const&);
- int32 GetNumBytes(void);
+ int32 GetNumBytes(void) const;
struct bignum_st *BN() { return _bn; }
uint32 AsDword();
- std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
+ void GetBytes(uint8* buf, size_t bufsize, bool littleEndian = true) const;
+ std::vector<uint8> ToByteVector(int32 minSize = 0, bool littleEndian = true) const;
+
+ template <std::size_t Size>
+ std::array<uint8, Size> ToByteArray(bool littleEndian = true) const
+ {
+ std::array<uint8, Size> buf;
+ GetBytes(buf.data(), Size, littleEndian);
+ return buf;
+ }
std::string AsHexStr() const;
std::string AsDecStr() const;
diff --git a/src/common/Cryptography/CryptoConstants.h b/src/common/Cryptography/CryptoConstants.h
new file mode 100644
index 00000000000..2def8f13622
--- /dev/null
+++ b/src/common/Cryptography/CryptoConstants.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_CRYPTO_CONSTANTS_H
+#define TRINITY_CRYPTO_CONSTANTS_H
+
+#include "Define.h"
+
+namespace Trinity
+{
+namespace Crypto
+{
+ struct Constants
+ {
+ static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20;
+ static constexpr size_t SHA256_DIGEST_LENGTH_BYTES = 32;
+ };
+}
+}
+
+#endif
diff --git a/src/common/Cryptography/CryptoGenerics.h b/src/common/Cryptography/CryptoGenerics.h
new file mode 100644
index 00000000000..affa11bf79d
--- /dev/null
+++ b/src/common/Cryptography/CryptoGenerics.h
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_CRYPTO_GENERICS_HPP
+#define TRINITY_CRYPTO_GENERICS_HPP
+
+#include "BigNumber.h"
+#include "CryptoRandom.h"
+#include "Define.h"
+#include "Errors.h"
+#include <iterator>
+#include <vector>
+
+namespace Trinity
+{
+namespace Impl
+{
+ struct CryptoGenericsImpl
+ {
+ template <typename Cipher>
+ static typename Cipher::IV GenerateRandomIV()
+ {
+ typename Cipher::IV iv;
+ Trinity::Crypto::GetRandomBytes(iv);
+ return iv;
+ }
+
+ template <typename Container>
+ static void AppendToBack(std::vector<uint8>& data, Container const& tail)
+ {
+ data.insert(data.end(), std::begin(tail), std::end(tail));
+ }
+
+ template <typename Container>
+ static void SplitFromBack(std::vector<uint8>& data, Container& tail)
+ {
+ ASSERT(data.size() >= std::size(tail));
+ for (size_t i = 1, N = std::size(tail); i <= N; ++i)
+ {
+ tail[N - i] = data.back();
+ data.pop_back();
+ }
+ }
+ };
+}
+}
+
+namespace Trinity
+{
+namespace Crypto
+{
+ template <typename Cipher>
+ void AEEncryptWithRandomIV(std::vector<uint8>& data, typename Cipher::Key const& key)
+ {
+ using IV = typename Cipher::IV;
+ using Tag = typename Cipher::Tag;
+ // select random IV
+ IV iv = Trinity::Impl::CryptoGenericsImpl::GenerateRandomIV<Cipher>();
+ Tag tag;
+
+ // encrypt data
+ Cipher cipher(true);
+ cipher.Init(key);
+ bool success = cipher.Process(iv, data.data(), data.size(), tag);
+ ASSERT(success);
+
+ // append trailing IV and tag
+ Trinity::Impl::CryptoGenericsImpl::AppendToBack(data, iv);
+ Trinity::Impl::CryptoGenericsImpl::AppendToBack(data, tag);
+ }
+
+ template <typename Cipher>
+ void AEEncryptWithRandomIV(std::vector<uint8>& data, BigNumber const& key)
+ {
+ AEEncryptWithRandomIV<Cipher>(data, key.ToByteArray<Cipher::KEY_SIZE_BYTES>());
+ }
+
+ template <typename Cipher>
+ bool AEDecrypt(std::vector<uint8>& data, typename Cipher::Key const& key)
+ {
+ using IV = typename Cipher::IV;
+ using Tag = typename Cipher::Tag;
+ // extract trailing IV and tag
+ IV iv;
+ Tag tag;
+ Trinity::Impl::CryptoGenericsImpl::SplitFromBack(data, tag);
+ Trinity::Impl::CryptoGenericsImpl::SplitFromBack(data, iv);
+
+ // decrypt data
+ Cipher cipher(false);
+ cipher.Init(key);
+ return cipher.Process(iv, data.data(), data.size(), tag);
+ }
+
+ template <typename Cipher>
+ bool AEDecrypt(std::vector<uint8>& data, BigNumber const& key)
+ {
+ return AEDecrypt<Cipher>(data, key.ToByteArray<Cipher::KEY_SIZE_BYTES>());
+ }
+}
+}
+
+#endif
diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h
new file mode 100644
index 00000000000..bb9fbc51c15
--- /dev/null
+++ b/src/common/Cryptography/CryptoHash.h
@@ -0,0 +1,142 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_CRYPTOHASH_H
+#define TRINITY_CRYPTOHASH_H
+
+#include "CryptoConstants.h"
+#include "Define.h"
+#include "Errors.h"
+#include <array>
+#include <string>
+//#include <string_view>
+#include <openssl/evp.h>
+#include <cstring>
+#include "advstd.h" // data/size
+
+class BigNumber;
+
+namespace Trinity
+{
+namespace Impl
+{
+ struct GenericHashImpl
+ {
+ typedef EVP_MD const* (*HashCreator)();
+
+#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_create(); }
+ static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); }
+#else
+ static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_new(); }
+ static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); }
+#endif
+ };
+
+ template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength>
+ class GenericHash
+ {
+ public:
+ static constexpr size_t DIGEST_LENGTH = DigestLength;
+ using Digest = std::array<uint8, DIGEST_LENGTH>;
+
+ static Digest GetDigestOf(uint8 const* data, size_t len)
+ {
+ GenericHash hash;
+ hash.UpdateData(data, len);
+ hash.Finalize();
+ return hash.GetDigest();
+ }
+
+ private: // c++17
+ template <typename T>
+ static void UpdateData_OLDCPP(GenericHash& hash, T const& data)
+ {
+ hash.UpdateData(data);
+ }
+
+ template <typename T, typename... TRest>
+ static void UpdateData_OLDCPP(GenericHash& hash, T const& data, TRest&&... rest)
+ {
+ hash.UpdateData(data);
+ UpdateData_OLDCPP(hash, std::forward<TRest>(rest)...);
+ }
+
+ public:
+ template <typename... Ts>
+ static auto GetDigestOf(Ts&&... pack) -> /*std::enable_if_t<!(std::is_integral_v<std::decay_t<Ts>> || ...),*/ Digest/*>*/
+ {
+ GenericHash hash;
+ UpdateData_OLDCPP(hash, std::forward<Ts>(pack)...);
+ hash.Finalize();
+ return hash.GetDigest();
+ }
+
+ GenericHash() : _ctx(GenericHashImpl::MakeCTX())
+ {
+ int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr);
+ ASSERT(result == 1);
+ }
+
+ ~GenericHash()
+ {
+ if (!_ctx)
+ return;
+ GenericHashImpl::DestroyCTX(_ctx);
+ _ctx = nullptr;
+ }
+
+ void UpdateData(uint8 const* data, size_t len)
+ {
+ int result = EVP_DigestUpdate(_ctx, data, len);
+ ASSERT(result == 1);
+ }
+ // c++17 void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
+ void UpdateData(std::string const& str) { UpdateData(str.c_str()); } /* explicit overload to avoid using the container template */
+ void UpdateData(char const* str) { UpdateData(reinterpret_cast<uint8 const*>(str), strlen(str)); } /* explicit overload to avoid using the container template */
+ template <typename Container>
+ void UpdateData(Container const& c) { UpdateData(advstd::data(c), advstd::size(c)); }
+
+ void Finalize()
+ {
+ uint32 length;
+ int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length);
+ ASSERT(result == 1);
+ ASSERT(length == DIGEST_LENGTH);
+ GenericHashImpl::DestroyCTX(_ctx);
+ _ctx = nullptr;
+ }
+
+ Digest const& GetDigest() const { return _digest; }
+
+ private:
+ EVP_MD_CTX* _ctx;
+ Digest _digest = { };
+ };
+}
+}
+
+namespace Trinity
+{
+namespace Crypto
+{
+ using SHA1 = Trinity::Impl::GenericHash<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>;
+ using SHA256 = Trinity::Impl::GenericHash<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>;
+}
+}
+
+#endif
diff --git a/src/common/Cryptography/CryptoRandom.cpp b/src/common/Cryptography/CryptoRandom.cpp
new file mode 100644
index 00000000000..971c2ce7f7c
--- /dev/null
+++ b/src/common/Cryptography/CryptoRandom.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 "CryptoRandom.h"
+#include "Errors.h"
+#include <openssl/rand.h>
+
+void Trinity::Crypto::GetRandomBytes(uint8* buf, size_t len)
+{
+ int result = RAND_bytes(buf, len);
+ ASSERT(result == 1, "Not enough randomness in OpenSSL's entropy pool. What in the world are you running on?");
+}
diff --git a/src/common/Cryptography/SHA256.h b/src/common/Cryptography/CryptoRandom.h
index 2c97b49dbed..da8498a1fa4 100644
--- a/src/common/Cryptography/SHA256.h
+++ b/src/common/Cryptography/CryptoRandom.h
@@ -15,38 +15,33 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SHA256_h__
-#define SHA256_h__
+#ifndef TRINITY_CRYPTORANDOM_H
+#define TRINITY_CRYPTORANDOM_H
#include "Define.h"
-#include <string>
-#include <type_traits>
-#include <openssl/sha.h>
+#include <array>
+#include "advstd.h"
-class BigNumber;
-
-class TC_COMMON_API SHA256Hash
+namespace Trinity
{
- public:
- typedef std::integral_constant<uint32, SHA256_DIGEST_LENGTH> DigestLength;
-
- SHA256Hash();
- ~SHA256Hash();
-
- void UpdateBigNumbers(BigNumber* bn0, ...);
-
- void UpdateData(uint8 const* data, size_t len);
- void UpdateData(std::string const& str);
-
- void Initialize();
- void Finalize();
-
- uint8 *GetDigest() { return mDigest; }
- uint32 GetLength() const { return SHA256_DIGEST_LENGTH; }
-
- private:
- SHA256_CTX mC;
- uint8 mDigest[SHA256_DIGEST_LENGTH];
-};
-
-#endif // SHA256_h__
+namespace Crypto
+{
+ void TC_COMMON_API GetRandomBytes(uint8* buf, size_t len);
+
+ template <typename Container>
+ void GetRandomBytes(Container& c)
+ {
+ GetRandomBytes(advstd::data(c), advstd::size(c));
+ }
+
+ template <size_t S>
+ std::array<uint8, S> GetRandomBytes()
+ {
+ std::array<uint8, S> arr;
+ GetRandomBytes(arr);
+ return arr;
+ }
+}
+}
+
+#endif
diff --git a/src/common/Cryptography/HMAC.h b/src/common/Cryptography/HMAC.h
new file mode 100644
index 00000000000..8562d3b5e2e
--- /dev/null
+++ b/src/common/Cryptography/HMAC.h
@@ -0,0 +1,153 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_HMAC_H
+#define TRINITY_HMAC_H
+
+#include "CryptoConstants.h"
+#include "Define.h"
+#include "Errors.h"
+#include <array>
+#include <string>
+//#include <string_view>
+#include <openssl/hmac.h>
+#include "advstd.h"
+
+class BigNumber;
+
+namespace Trinity
+{
+namespace Impl
+{
+ struct HMACImpl
+ {
+ typedef EVP_MD const* (*HashCreator)();
+
+#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ static HMAC_CTX* MakeCTX()
+ {
+ HMAC_CTX* ctx = new HMAC_CTX();
+ HMAC_CTX_init(ctx);
+ return ctx;
+ }
+
+ static void DestroyCTX(HMAC_CTX* ctx)
+ {
+ HMAC_CTX_cleanup(ctx);
+ delete ctx;
+ }
+#else
+ static HMAC_CTX* MakeCTX() { return HMAC_CTX_new(); }
+ static void DestroyCTX(HMAC_CTX* ctx) { HMAC_CTX_free(ctx); }
+#endif
+ };
+
+ template <HMACImpl::HashCreator HashCreator, size_t DigestLength>
+ class GenericHMAC
+ {
+ public:
+ static constexpr size_t DIGEST_LENGTH = DigestLength;
+ using Digest = std::array<uint8, DIGEST_LENGTH>;
+
+ template <typename Container>
+ static Digest GetDigestOf(Container const& seed, uint8 const* data, size_t len)
+ {
+ GenericHMAC hash(seed);
+ hash.UpdateData(data, len);
+ hash.Finalize();
+ return hash.GetDigest();
+ }
+
+ private: // c++17
+ template <typename T>
+ static void UpdateData_OLDCPP(GenericHMAC& hash, T const& data)
+ {
+ hash.UpdateData(data);
+ }
+
+ template <typename T, typename... TRest>
+ static void UpdateData_OLDCPP(GenericHMAC& hash, T const& data, TRest&&... rest)
+ {
+ hash.UpdateData(data);
+ UpdateData_OLDCPP(hash, std::forward<TRest>(rest)...);
+ }
+
+ public:
+ template <typename Container, typename... Ts>
+ static auto GetDigestOf(Container const& seed, Ts&&... pack) -> /*std::enable_if_t<!(std::is_integral_v<std::decay_t<Ts>> || ...),*/ Digest/*>*/
+ {
+ GenericHMAC hash(seed);
+ UpdateData_OLDCPP(hash, std::forward<Ts>(pack)...);
+ hash.Finalize();
+ return hash.GetDigest();
+ }
+
+ GenericHMAC(uint8 const* seed, size_t len) : _ctx(HMACImpl::MakeCTX())
+ {
+ int result = HMAC_Init_ex(_ctx, seed, len, HashCreator(), nullptr);
+ ASSERT(result == 1);
+ }
+ template <typename Container>
+ GenericHMAC(Container const& container) : GenericHMAC(container.data(), container.size()) {}
+
+ ~GenericHMAC()
+ {
+ if (!_ctx)
+ return;
+ HMACImpl::DestroyCTX(_ctx);
+ _ctx = nullptr;
+ }
+
+ void UpdateData(uint8 const* data, size_t len)
+ {
+ int result = HMAC_Update(_ctx, data, len);
+ ASSERT(result == 1);
+ }
+ // c++17 void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
+ void UpdateData(std::string const& str) { UpdateData(str.c_str()); } /* explicit overload to avoid using the container template */
+ void UpdateData(char const* str) { UpdateData(reinterpret_cast<uint8 const*>(str), strlen(str)); } /* explicit overload to avoid using the container template */
+ template <typename Container>
+ void UpdateData(Container const& c) { UpdateData(advstd::data(c), advstd::size(c)); }
+
+ void Finalize()
+ {
+ uint32 length = 0;
+ int result = HMAC_Final(_ctx, _digest.data(), &length);
+ ASSERT(result == 1);
+ ASSERT(length == DIGEST_LENGTH);
+ HMACImpl::DestroyCTX(_ctx);
+ _ctx = nullptr;
+ }
+
+ Digest const& GetDigest() const { return _digest; }
+ private:
+ HMAC_CTX* _ctx;
+ Digest _digest = { };
+ };
+}
+}
+
+namespace Trinity
+{
+namespace Crypto
+{
+ using HMAC_SHA1 = Trinity::Impl::GenericHMAC<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>;
+ using HMAC_SHA256 = Trinity::Impl::GenericHMAC<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>;
+}
+}
+
+#endif
diff --git a/src/common/Cryptography/HmacHash.cpp b/src/common/Cryptography/HmacHash.cpp
deleted file mode 100644
index e52113d2e0e..00000000000
--- a/src/common/Cryptography/HmacHash.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 "HmacHash.h"
-#include "BigNumber.h"
-#include "Errors.h"
-#include <cstring>
-
-#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
-HMAC_CTX* HMAC_CTX_new()
-{
- HMAC_CTX *ctx = new HMAC_CTX();
- HMAC_CTX_init(ctx);
- return ctx;
-}
-
-void HMAC_CTX_free(HMAC_CTX* ctx)
-{
- HMAC_CTX_cleanup(ctx);
- delete ctx;
-}
-#endif
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-HmacHash<HashCreator, DigestLength>::HmacHash(uint32 len, uint8 const* seed) : _ctx(HMAC_CTX_new())
-{
- HMAC_Init_ex(_ctx, seed, len, HashCreator(), nullptr);
- memset(_digest, 0, DigestLength);
-}
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-HmacHash<HashCreator, DigestLength>::~HmacHash()
-{
- HMAC_CTX_free(_ctx);
-}
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-void HmacHash<HashCreator, DigestLength>::UpdateData(std::string const& str)
-{
- HMAC_Update(_ctx, reinterpret_cast<uint8 const*>(str.c_str()), str.length());
-}
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-void HmacHash<HashCreator, DigestLength>::UpdateData(uint8 const* data, size_t len)
-{
- HMAC_Update(_ctx, data, len);
-}
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-void HmacHash<HashCreator, DigestLength>::Finalize()
-{
- uint32 length = 0;
- HMAC_Final(_ctx, _digest, &length);
- ASSERT(length == DigestLength);
-}
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-uint8* HmacHash<HashCreator, DigestLength>::ComputeHash(BigNumber* bn)
-{
- HMAC_Update(_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
- Finalize();
- return _digest;
-}
-
-template class TC_COMMON_API HmacHash<EVP_sha1, SHA_DIGEST_LENGTH>;
-template class TC_COMMON_API HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH>;
diff --git a/src/common/Cryptography/HmacHash.h b/src/common/Cryptography/HmacHash.h
deleted file mode 100644
index 6985e4ac59a..00000000000
--- a/src/common/Cryptography/HmacHash.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 _AUTH_HMAC_H
-#define _AUTH_HMAC_H
-
-#include "Define.h"
-#include <string>
-#include <openssl/hmac.h>
-#include <openssl/sha.h>
-
-class BigNumber;
-
-#define SEED_KEY_SIZE 16
-
-typedef EVP_MD const* (*HashCreateFn)();
-
-template<HashCreateFn HashCreator, uint32 DigestLength>
-class TC_COMMON_API HmacHash
-{
- public:
- HmacHash(uint32 len, uint8 const* seed);
- ~HmacHash();
- void UpdateData(std::string const& str);
- void UpdateData(uint8 const* data, size_t len);
- void Finalize();
- uint8* ComputeHash(BigNumber* bn);
- uint8* GetDigest() { return _digest; }
- uint32 GetLength() const { return DigestLength; }
- private:
- HMAC_CTX* _ctx;
- uint8 _digest[DigestLength];
-};
-
-typedef HmacHash<EVP_sha1, SHA_DIGEST_LENGTH> HmacSha1;
-typedef HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH> HmacSha256;
-
-#endif
diff --git a/src/common/Cryptography/RSA.h b/src/common/Cryptography/RSA.h
index 6b51dcb8d10..a99bae8536a 100644
--- a/src/common/Cryptography/RSA.h
+++ b/src/common/Cryptography/RSA.h
@@ -18,6 +18,7 @@
#include "Define.h"
#include <openssl/objects.h>
#include <openssl/rsa.h>
+#include <array>
#include <string>
#include <type_traits>
@@ -57,12 +58,24 @@ public:
return Encrypt<KeyTag>(data, dataLength, output, PaddingTag::value);
}
+ template <std::size_t N, typename KeyTag, typename PaddingTag>
+ bool Encrypt(std::array<uint8, N> const& data, uint8* output, KeyTag, PaddingTag)
+ {
+ return Encrypt<KeyTag>(data.data(), data.size(), output, PaddingTag::value);
+ }
+
template <typename HashTag>
bool Sign(uint8 const* dataHash, std::size_t dataHashLength, uint8* output, HashTag)
{
return Sign(HashTag::value, dataHash, dataHashLength, output);
}
+ template <std::size_t N, typename HashTag>
+ bool Sign(std::array<uint8, N> const& dataHash, uint8* output, HashTag)
+ {
+ return Sign(HashTag::value, dataHash.data(), dataHash.size(), output);
+ }
+
private:
template <typename KeyTag>
bool Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, int32 paddingType);
diff --git a/src/common/Cryptography/SHA1.cpp b/src/common/Cryptography/SHA1.cpp
deleted file mode 100644
index 15140d82a43..00000000000
--- a/src/common/Cryptography/SHA1.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 "SHA1.h"
-#include "BigNumber.h"
-#include "Util.h"
-#include <cstring>
-#include <stdarg.h>
-
-SHA1Hash::SHA1Hash()
-{
- SHA1_Init(&mC);
- memset(mDigest, 0, SHA_DIGEST_LENGTH * sizeof(uint8));
-}
-
-SHA1Hash::~SHA1Hash()
-{
- SHA1_Init(&mC);
-}
-
-void SHA1Hash::UpdateData(const uint8 *dta, int len)
-{
- SHA1_Update(&mC, dta, len);
-}
-
-void SHA1Hash::UpdateData(const std::string &str)
-{
- UpdateData((uint8 const*)str.c_str(), str.length());
-}
-
-void SHA1Hash::UpdateBigNumbers(BigNumber* bn0, ...)
-{
- va_list v;
- BigNumber* bn;
-
- va_start(v, bn0);
- bn = bn0;
- while (bn)
- {
- UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
- bn = va_arg(v, BigNumber*);
- }
- va_end(v);
-}
-
-void SHA1Hash::Initialize()
-{
- SHA1_Init(&mC);
-}
-
-void SHA1Hash::Finalize(void)
-{
- SHA1_Final(mDigest, &mC);
-}
-
-std::string CalculateSHA1Hash(std::string const& content)
-{
- unsigned char digest[SHA_DIGEST_LENGTH];
- SHA1((unsigned char*)content.c_str(), content.length(), (unsigned char*)&digest);
-
- return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH);
-}
diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h
deleted file mode 100644
index 5a537598bf8..00000000000
--- a/src/common/Cryptography/SHA1.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 _AUTH_SHA1_H
-#define _AUTH_SHA1_H
-
-#include "Define.h"
-#include <string>
-#include <type_traits>
-#include <openssl/sha.h>
-
-class BigNumber;
-
-class TC_COMMON_API SHA1Hash
-{
- public:
- typedef std::integral_constant<uint32, SHA_DIGEST_LENGTH> DigestLength;
-
- SHA1Hash();
- ~SHA1Hash();
-
- void UpdateBigNumbers(BigNumber* bn0, ...);
-
- void UpdateData(const uint8 *dta, int len);
- void UpdateData(const std::string &str);
-
- void Initialize();
- void Finalize();
-
- uint8 *GetDigest(void) { return mDigest; }
- int GetLength(void) const { return SHA_DIGEST_LENGTH; }
-
- private:
- SHA_CTX mC;
- uint8 mDigest[SHA_DIGEST_LENGTH];
-};
-
-/// Returns the SHA1 hash of the given content as hex string.
-TC_COMMON_API std::string CalculateSHA1Hash(std::string const& content);
-
-#endif
diff --git a/src/common/Cryptography/SHA256.cpp b/src/common/Cryptography/SHA256.cpp
deleted file mode 100644
index 5baa569ecc4..00000000000
--- a/src/common/Cryptography/SHA256.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 "SHA256.h"
-#include "BigNumber.h"
-#include <cstring>
-#include <stdarg.h>
-
-SHA256Hash::SHA256Hash()
-{
- SHA256_Init(&mC);
- memset(mDigest, 0, SHA256_DIGEST_LENGTH * sizeof(uint8));
-}
-
-SHA256Hash::~SHA256Hash()
-{
- SHA256_Init(&mC);
-}
-
-void SHA256Hash::UpdateData(uint8 const* data, size_t len)
-{
- SHA256_Update(&mC, data, len);
-}
-
-void SHA256Hash::UpdateData(const std::string &str)
-{
- UpdateData((uint8 const*)str.c_str(), str.length());
-}
-
-void SHA256Hash::UpdateBigNumbers(BigNumber* bn0, ...)
-{
- va_list v;
- BigNumber* bn;
-
- va_start(v, bn0);
- bn = bn0;
- while (bn)
- {
- UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
- bn = va_arg(v, BigNumber*);
- }
- va_end(v);
-}
-
-void SHA256Hash::Initialize()
-{
- SHA256_Init(&mC);
-}
-
-void SHA256Hash::Finalize(void)
-{
- SHA256_Final(mDigest, &mC);
-}
diff --git a/src/common/Cryptography/SessionKeyGeneration.h b/src/common/Cryptography/SessionKeyGeneration.h
deleted file mode 100644
index c16178a1dd4..00000000000
--- a/src/common/Cryptography/SessionKeyGeneration.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * 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 SessionKeyGeneration_h__
-#define SessionKeyGeneration_h__
-
-#include "Define.h"
-#include <cstring>
-
-template<class Hash>
-class SessionKeyGenerator
-{
-public:
- SessionKeyGenerator(uint8* buff, uint32 size)
- {
- uint32 halfSize = size / 2;
-
- sh.Initialize();
- sh.UpdateData(buff, halfSize);
- sh.Finalize();
-
- memcpy(o1, sh.GetDigest(), Hash::DigestLength::value);
-
- sh.Initialize();
- sh.UpdateData(buff + halfSize, size - halfSize);
- sh.Finalize();
-
- memcpy(o2, sh.GetDigest(), Hash::DigestLength::value);
-
- memset(o0, 0x00, Hash::DigestLength::value);
-
- FillUp();
- }
-
- void Generate(uint8* buf, uint32 sz)
- {
- for (uint32 i = 0; i < sz; ++i)
- {
- if (taken == Hash::DigestLength::value)
- FillUp();
-
- buf[i] = o0[taken];
- taken++;
- }
- }
-
-private:
- void FillUp()
- {
- sh.Initialize();
- sh.UpdateData(o1, Hash::DigestLength::value);
- sh.UpdateData(o0, Hash::DigestLength::value);
- sh.UpdateData(o2, Hash::DigestLength::value);
- sh.Finalize();
-
- memcpy(o0, sh.GetDigest(), Hash::DigestLength::value);
-
- taken = 0;
- }
-
- Hash sh;
- uint32 taken;
- uint8 o0[Hash::DigestLength::value];
- uint8 o1[Hash::DigestLength::value];
- uint8 o2[Hash::DigestLength::value];
-};
-
-#endif // SessionKeyGeneration_h__
diff --git a/src/common/Cryptography/SessionKeyGenerator.h b/src/common/Cryptography/SessionKeyGenerator.h
new file mode 100644
index 00000000000..5e9471b7746
--- /dev/null
+++ b/src/common/Cryptography/SessionKeyGenerator.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_SESSIONKEYGENERATOR_HPP
+#define TRINITY_SESSIONKEYGENERATOR_HPP
+
+#include "CryptoHash.h"
+#include <cstring>
+#include "advstd.h" // for data/size
+
+template <typename Hash>
+class SessionKeyGenerator
+{
+ public:
+ template <typename C>
+ SessionKeyGenerator(C const& buf) :
+ o0it(o0.begin())
+ {
+ uint8 const* data = advstd::data(buf);
+ size_t const len = advstd::size(buf);
+ size_t const halflen = (len / 2);
+
+ o1 = Hash::GetDigestOf(data, halflen);
+ o2 = Hash::GetDigestOf(data + halflen, len - halflen);
+ o0 = Hash::GetDigestOf(o1, o0, o2);
+ }
+
+ void Generate(uint8* buf, uint32 sz)
+ {
+ for (uint32 i = 0; i < sz; ++i)
+ {
+ if (o0it == o0.end())
+ {
+ o0 = Hash::GetDigestOf(o1, o0, o2);
+ o0it = o0.begin();
+ }
+
+ buf[i] = *(o0it++);
+ }
+ }
+
+ private:
+ typename Hash::Digest o0 = { };
+ typename Hash::Digest o1 = { };
+ typename Hash::Digest o2 = { };
+ typename Hash::Digest::const_iterator o0it;
+ };
+
+#endif
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index f5ca8a6ac4e..7625ae9d2ff 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -699,7 +699,7 @@ bool Utf8ToUpperOnlyLatin(std::string& utf8String)
return WStrToUtf8(wstr, utf8String);
}
-std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
+std::string ByteArrayToHexStr(uint8 const* bytes, size_t arrayLen, bool reverse /* = false */)
{
int32 init = 0;
int32 end = arrayLen;
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 5711397f904..b3270eb6c2c 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -22,6 +22,7 @@
#include "Errors.h"
#include <string>
#include <vector>
+#include "advstd.h"
enum LocaleConstant : uint8;
@@ -301,7 +302,9 @@ TC_COMMON_API bool IsIPAddress(char const* ipaddress);
TC_COMMON_API uint32 CreatePIDFile(std::string const& filename);
TC_COMMON_API uint32 GetPID();
-TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, size_t length, bool reverse = false);
+template <typename Container>
+std::string ByteArrayToHexStr(Container const& c, bool reverse = false) { return ByteArrayToHexStr(advstd::data(c), advstd::size(c), reverse); }
TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
TC_COMMON_API bool StringToBool(std::string const& str);
diff --git a/src/common/Utilities/advstd.h b/src/common/Utilities/advstd.h
new file mode 100644
index 00000000000..7514f156050
--- /dev/null
+++ b/src/common/Utilities/advstd.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 TRINITY_ADVSTD_H
+#define TRINITY_ADVSTD_H
+
+#include <cstddef>
+#include <initializer_list>
+#include <type_traits>
+
+// this namespace holds implementations of upcoming stdlib features that our c++ version doesn't have yet
+namespace advstd
+{
+ // C++17 std::size
+ template <typename C>
+ constexpr auto size(const C& c) { return c.size(); }
+
+ template <typename T, std::size_t N>
+ constexpr std::size_t size(const T(&)[N]) noexcept { return N; }
+
+ // C++17 std::data
+ template <typename C>
+ constexpr auto data(C& c) { return c.data(); }
+
+ template <typename C>
+ constexpr auto data(C const& c) { return c.data(); }
+
+ template <typename T, std::size_t N>
+ constexpr T* data(T(&a)[N]) noexcept { return a; }
+
+ template <typename T, std::size_t N>
+ constexpr T const* data(const T(&a)[N]) noexcept { return a; }
+
+ template <typename T>
+ constexpr T const* data(std::initializer_list<T> l) noexcept { return l.begin(); }
+}
+
+#endif
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;
}