mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-23 21:56:22 +00:00
Merge branch 'master' into Playerbot
# Conflicts: # src/server/game/Server/WorldSession.cpp # src/server/game/Server/WorldSession.h
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 "AES.h"
|
||||
@@ -30,34 +42,24 @@ bool Acore::Crypto::AES::Process(IV const& iv, uint8* data, size_t length, Tag&
|
||||
ASSERT(length <= static_cast<size_t>(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, 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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 Warhead_AES_h__
|
||||
#define Warhead_AES_h__
|
||||
#ifndef Azeroth_AES_h__
|
||||
#define Azeroth_AES_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include <array>
|
||||
@@ -36,4 +48,4 @@ namespace Acore::Crypto
|
||||
};
|
||||
}
|
||||
|
||||
#endif // Warhead_AES_h__
|
||||
#endif // Azeroth_AES_h__
|
||||
|
||||
@@ -18,17 +18,26 @@
|
||||
#include "ARC4.h"
|
||||
#include "Errors.h"
|
||||
|
||||
Acore::Crypto::ARC4::ARC4()
|
||||
: _ctx(EVP_CIPHER_CTX_new())
|
||||
Acore::Crypto::ARC4::ARC4() : _ctx(EVP_CIPHER_CTX_new())
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
_cipher = EVP_CIPHER_fetch(nullptr, "RC4", nullptr);
|
||||
#else
|
||||
EVP_CIPHER const* _cipher = EVP_rc4();
|
||||
#endif
|
||||
|
||||
EVP_CIPHER_CTX_init(_ctx);
|
||||
int result = EVP_EncryptInit_ex(_ctx, EVP_rc4(), nullptr, nullptr, nullptr);
|
||||
int result = EVP_EncryptInit_ex(_ctx, _cipher, nullptr, nullptr, nullptr);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
|
||||
Acore::Crypto::ARC4::~ARC4()
|
||||
{
|
||||
EVP_CIPHER_CTX_free(_ctx);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_CIPHER_free(_cipher);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Acore::Crypto::ARC4::Init(uint8 const* seed, size_t len)
|
||||
|
||||
@@ -24,20 +24,25 @@
|
||||
|
||||
namespace Acore::Crypto
|
||||
{
|
||||
class ARC4
|
||||
class AC_COMMON_API ARC4
|
||||
{
|
||||
public:
|
||||
ARC4();
|
||||
~ARC4();
|
||||
|
||||
void Init(uint8 const* seed, size_t len);
|
||||
|
||||
template <typename Container>
|
||||
void Init(Container const& c) { Init(std::data(c), std::size(c)); }
|
||||
|
||||
void UpdateData(uint8* data, size_t len);
|
||||
|
||||
template <typename Container>
|
||||
void UpdateData(Container& c) { UpdateData(std::data(c), std::size(c)); }
|
||||
private:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_CIPHER* _cipher;
|
||||
#endif
|
||||
EVP_CIPHER_CTX* _ctx;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 "Argon2.h"
|
||||
@@ -20,9 +32,7 @@
|
||||
);
|
||||
|
||||
if (status == ARGON2_OK)
|
||||
{
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 WARHEAD_ARGON2_H
|
||||
#define WARHEAD_ARGON2_H
|
||||
#ifndef AC_ARGON2_H
|
||||
#define AC_ARGON2_H
|
||||
|
||||
#include "BigNumber.h"
|
||||
#include "Define.h"
|
||||
#include "Optional.h"
|
||||
#include <string>
|
||||
|
||||
namespace Acore::Crypto
|
||||
{
|
||||
|
||||
@@ -19,19 +19,16 @@
|
||||
#include "Errors.h"
|
||||
#include "HMAC.h"
|
||||
|
||||
AuthCrypt::AuthCrypt() : _initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
void AuthCrypt::Init(SessionKey const& K)
|
||||
{
|
||||
uint8 ServerEncryptionKey[] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
|
||||
_serverEncrypt.Init(Acore::Crypto::HMAC_SHA1::GetDigestOf(ServerEncryptionKey, K));
|
||||
|
||||
uint8 ServerDecryptionKey[] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
|
||||
_clientDecrypt.Init(Acore::Crypto::HMAC_SHA1::GetDigestOf(ServerDecryptionKey, K));
|
||||
|
||||
// Drop first 1024 bytes, as WoW uses ARC4-drop1024.
|
||||
std::array<uint8, 1024> syncBuf;
|
||||
std::array<uint8, 1024> syncBuf{};
|
||||
_serverEncrypt.UpdateData(syncBuf);
|
||||
_clientDecrypt.UpdateData(syncBuf);
|
||||
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
|
||||
#include "ARC4.h"
|
||||
#include "AuthDefines.h"
|
||||
#include <array>
|
||||
|
||||
class AuthCrypt
|
||||
class AC_COMMON_API AuthCrypt
|
||||
{
|
||||
public:
|
||||
AuthCrypt();
|
||||
AuthCrypt() = default;
|
||||
|
||||
void Init(SessionKey const& K);
|
||||
void DecryptRecv(uint8* data, size_t len);
|
||||
@@ -36,6 +35,6 @@ public:
|
||||
private:
|
||||
Acore::Crypto::ARC4 _clientDecrypt;
|
||||
Acore::Crypto::ARC4 _serverEncrypt;
|
||||
bool _initialized;
|
||||
bool _initialized{ false };
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -50,8 +50,8 @@ using SRP6 = Acore::Crypto::SRP6;
|
||||
/*static*/ SessionKey SRP6::SHA1Interleave(SRP6::EphemeralKey const& S)
|
||||
{
|
||||
// split S into two buffers
|
||||
std::array<uint8, EPHEMERAL_KEY_LENGTH/2> buf0, buf1;
|
||||
for (size_t i = 0; i < EPHEMERAL_KEY_LENGTH/2; ++i)
|
||||
std::array<uint8, EPHEMERAL_KEY_LENGTH / 2> buf0{}, buf1{};
|
||||
for (size_t i = 0; i < EPHEMERAL_KEY_LENGTH / 2; ++i)
|
||||
{
|
||||
buf0[i] = S[2 * i + 0];
|
||||
buf1[i] = S[2 * i + 1];
|
||||
@@ -59,8 +59,12 @@ using SRP6 = Acore::Crypto::SRP6;
|
||||
|
||||
// find position of first nonzero byte
|
||||
size_t p = 0;
|
||||
while (p < EPHEMERAL_KEY_LENGTH && !S[p]) { ++p; }
|
||||
if (p & 1) { ++p; } // skip one extra byte if p is odd
|
||||
while (p < EPHEMERAL_KEY_LENGTH && !S[p])
|
||||
++p;
|
||||
|
||||
if (p & 1)
|
||||
++p; // skip one extra byte if p is odd
|
||||
|
||||
p /= 2; // offset into buffers
|
||||
|
||||
// hash each of the halves, starting at the first nonzero byte
|
||||
@@ -82,14 +86,12 @@ SRP6::SRP6(std::string const& username, Salt const& salt, Verifier const& verifi
|
||||
|
||||
std::optional<SessionKey> SRP6::VerifyChallengeResponse(EphemeralKey const& A, SHA1::Digest const& clientM)
|
||||
{
|
||||
ASSERT(!_used);
|
||||
ASSERT(!_used, "A single SRP6 object must only ever be used to verify ONCE!");
|
||||
_used = true;
|
||||
|
||||
BigNumber const _A(A);
|
||||
if ((_A % _N).IsZero())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
BigNumber const u(SHA1::GetDigestOf(A, B));
|
||||
EphemeralKey const S = (_A * (_v.ModExp(u, _N))).ModExp(_b, N).ToByteArray<32>();
|
||||
@@ -104,11 +106,7 @@ std::optional<SessionKey> SRP6::VerifyChallengeResponse(EphemeralKey const& A, S
|
||||
|
||||
SHA1::Digest const ourM = SHA1::GetDigestOf(NgHash, _I, s, A, B, K);
|
||||
if (ourM == clientM)
|
||||
{
|
||||
return K;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -20,21 +20,20 @@
|
||||
|
||||
#include "AuthDefines.h"
|
||||
#include "BigNumber.h"
|
||||
#include "Common.h"
|
||||
#include "CryptoHash.h"
|
||||
#include "Define.h"
|
||||
#include <array>
|
||||
#include <optional>
|
||||
|
||||
namespace Acore::Crypto
|
||||
{
|
||||
class SRP6
|
||||
class AC_COMMON_API SRP6
|
||||
{
|
||||
public:
|
||||
static constexpr size_t SALT_LENGTH = 32;
|
||||
using Salt = std::array<uint8, SALT_LENGTH>;
|
||||
|
||||
static constexpr size_t VERIFIER_LENGTH = 32;
|
||||
using Verifier = std::array<uint8, VERIFIER_LENGTH>;
|
||||
|
||||
static constexpr size_t EPHEMERAL_KEY_LENGTH = 32;
|
||||
using EphemeralKey = std::array<uint8, EPHEMERAL_KEY_LENGTH>;
|
||||
|
||||
@@ -43,6 +42,7 @@ namespace Acore::Crypto
|
||||
|
||||
// username + password must be passed through Utf8ToUpperOnlyLatin FIRST!
|
||||
static std::pair<Salt, Verifier> MakeRegistrationData(std::string const& username, std::string const& password);
|
||||
|
||||
// username + password must be passed through Utf8ToUpperOnlyLatin FIRST!
|
||||
static bool CheckLogin(std::string const& username, std::string const& password, Salt const& salt, Verifier const& verifier)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 "Cryptography/BigNumber.h"
|
||||
#include "BigNumber.h"
|
||||
#include "Errors.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
BigNumber::BigNumber()
|
||||
@@ -25,9 +39,7 @@ void BigNumber::SetDword(int32 val)
|
||||
{
|
||||
SetDword(uint32(std::abs(val)));
|
||||
if (val < 0)
|
||||
{
|
||||
BN_set_negative(_bn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BigNumber::SetDword(uint32 val)
|
||||
@@ -50,9 +62,7 @@ void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian)
|
||||
uint8* array = new uint8[len];
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
array[i] = bytes[len - 1 - i];
|
||||
}
|
||||
|
||||
BN_bin2bn(array, len, _bn);
|
||||
|
||||
@@ -62,9 +72,7 @@ void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
BN_bin2bn(bytes, len, _bn);
|
||||
}
|
||||
}
|
||||
|
||||
bool BigNumber::SetHexStr(char const* str)
|
||||
@@ -81,9 +89,7 @@ void BigNumber::SetRand(int32 numbits)
|
||||
BigNumber& BigNumber::operator=(BigNumber const& bn)
|
||||
{
|
||||
if (this == &bn)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
BN_copy(_bn, bn._bn);
|
||||
return *this;
|
||||
@@ -103,7 +109,7 @@ BigNumber& BigNumber::operator-=(BigNumber const& bn)
|
||||
|
||||
BigNumber& BigNumber::operator*=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX* bnctx;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mul(_bn, _bn, bn._bn, bnctx);
|
||||
@@ -114,7 +120,7 @@ BigNumber& BigNumber::operator*=(BigNumber const& bn)
|
||||
|
||||
BigNumber& BigNumber::operator/=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX* bnctx;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_div(_bn, nullptr, _bn, bn._bn, bnctx);
|
||||
@@ -125,7 +131,7 @@ BigNumber& BigNumber::operator/=(BigNumber const& bn)
|
||||
|
||||
BigNumber& BigNumber::operator%=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX* bnctx;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod(_bn, _bn, bn._bn, bnctx);
|
||||
@@ -148,7 +154,7 @@ int BigNumber::CompareTo(BigNumber const& bn) const
|
||||
BigNumber BigNumber::Exp(BigNumber const& bn) const
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX* bnctx;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_exp(ret._bn, _bn, bn._bn, bnctx);
|
||||
@@ -160,7 +166,7 @@ BigNumber BigNumber::Exp(BigNumber const& bn) const
|
||||
BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) const
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX* bnctx;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
|
||||
@@ -201,17 +207,13 @@ void BigNumber::GetBytes(uint8* buf, size_t bufsize, bool littleEndian) const
|
||||
|
||||
// If we need more bytes than length of BigNumber set the rest to 0
|
||||
if (numBytes < bufsize)
|
||||
{
|
||||
memset((void*)buf, 0, bufsize);
|
||||
}
|
||||
|
||||
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(buf, buf + bufsize);
|
||||
}
|
||||
#else
|
||||
int res = littleEndian ? BN_bn2lebinpad(_bn, buf, bufsize) : BN_bn2binpad(_bn, buf, bufsize);
|
||||
ASSERT(res > 0, "Buffer of size {} is too small to hold bignum with {} bytes.\n", bufsize, BN_num_bytes(_bn));
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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_BIGNUMBER_H
|
||||
@@ -8,7 +20,6 @@
|
||||
|
||||
#include "Define.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace Acore::Crypto
|
||||
{
|
||||
struct Constants
|
||||
{
|
||||
static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20;
|
||||
static constexpr size_t MD5_DIGEST_LENGTH_BYTES = 16;
|
||||
static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20;
|
||||
static constexpr size_t SHA256_DIGEST_LENGTH_BYTES = 32;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Acore::Crypto
|
||||
{
|
||||
using IV = typename Cipher::IV;
|
||||
using Tag = typename Cipher::Tag;
|
||||
|
||||
// extract trailing IV and tag
|
||||
IV iv;
|
||||
Tag tag;
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
#define AZEROTHCORE_CRYPTOHASH_H
|
||||
|
||||
#include "CryptoConstants.h"
|
||||
#include "Define.h"
|
||||
#include "Errors.h"
|
||||
#include <array>
|
||||
#include <openssl/evp.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace Acore::Impl
|
||||
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 EVP_MD_CTX* MakeCTX() noexcept { 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 EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_new(); }
|
||||
static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); }
|
||||
#endif
|
||||
};
|
||||
@@ -46,74 +46,104 @@ namespace Acore::Impl
|
||||
template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength>
|
||||
class GenericHash
|
||||
{
|
||||
public:
|
||||
static constexpr size_t DIGEST_LENGTH = DigestLength;
|
||||
using Digest = std::array<uint8, DIGEST_LENGTH>;
|
||||
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();
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
static auto GetDigestOf(Ts&& ... pack) -> std::enable_if_t < !(std::is_integral_v<std::decay_t<Ts>> || ...), Digest >
|
||||
{
|
||||
GenericHash hash;
|
||||
(hash.UpdateData(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)
|
||||
static Digest GetDigestOf(uint8 const* data, size_t len)
|
||||
{
|
||||
return;
|
||||
GenericHash hash;
|
||||
hash.UpdateData(data, len);
|
||||
hash.Finalize();
|
||||
return hash.GetDigest();
|
||||
}
|
||||
GenericHashImpl::DestroyCTX(_ctx);
|
||||
_ctx = nullptr;
|
||||
}
|
||||
|
||||
void UpdateData(uint8 const* data, size_t len)
|
||||
{
|
||||
int result = EVP_DigestUpdate(_ctx, data, len);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
|
||||
void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
template <typename Container>
|
||||
void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); }
|
||||
template <typename... Ts>
|
||||
static auto GetDigestOf(Ts&&... pack) -> std::enable_if_t<!(std::is_integral_v<std::decay_t<Ts>> || ...), Digest>
|
||||
{
|
||||
GenericHash hash;
|
||||
(hash.UpdateData(std::forward<Ts>(pack)), ...);
|
||||
hash.Finalize();
|
||||
return hash.GetDigest();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
GenericHash() : _ctx(GenericHashImpl::MakeCTX())
|
||||
{
|
||||
int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
|
||||
Digest const& GetDigest() const { return _digest; }
|
||||
GenericHash(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX())
|
||||
{
|
||||
*this = right;
|
||||
}
|
||||
|
||||
private:
|
||||
EVP_MD_CTX* _ctx;
|
||||
Digest _digest = { };
|
||||
GenericHash(GenericHash&& right) noexcept
|
||||
{
|
||||
*this = std::move(right);
|
||||
}
|
||||
|
||||
~GenericHash()
|
||||
{
|
||||
if (!_ctx)
|
||||
return;
|
||||
GenericHashImpl::DestroyCTX(_ctx);
|
||||
_ctx = nullptr;
|
||||
}
|
||||
|
||||
GenericHash& operator=(GenericHash const& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx);
|
||||
ASSERT(result == 1);
|
||||
_digest = right._digest;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GenericHash& operator=(GenericHash&& right) noexcept
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
_ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX());
|
||||
_digest = std::exchange(right._digest, Digest{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
void UpdateData(uint8 const* data, size_t len)
|
||||
{
|
||||
int result = EVP_DigestUpdate(_ctx, data, len);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
|
||||
void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
|
||||
void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
|
||||
template <typename Container>
|
||||
void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); }
|
||||
|
||||
void Finalize()
|
||||
{
|
||||
uint32 length;
|
||||
int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length);
|
||||
ASSERT(result == 1);
|
||||
ASSERT(length == DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
Digest const& GetDigest() const { return _digest; }
|
||||
|
||||
private:
|
||||
EVP_MD_CTX* _ctx{};
|
||||
Digest _digest{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace Acore::Crypto
|
||||
{
|
||||
using MD5 = Acore::Impl::GenericHash<EVP_md5, Constants::MD5_DIGEST_LENGTH_BYTES>;
|
||||
using SHA1 = Acore::Impl::GenericHash<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>;
|
||||
using SHA256 = Acore::Impl::GenericHash<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>;
|
||||
}
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
void Acore::Crypto::GetRandomBytes(uint8* buf, size_t len)
|
||||
{
|
||||
int result = RAND_bytes(buf, len);
|
||||
ASSERT(result == 1);
|
||||
ASSERT(result == 1, "Not enough randomness in OpenSSL's entropy pool. What in the world are you running on?");
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
namespace Acore::Crypto
|
||||
{
|
||||
void GetRandomBytes(uint8* buf, size_t len);
|
||||
AC_COMMON_API void GetRandomBytes(uint8* buf, size_t len);
|
||||
|
||||
template <typename Container>
|
||||
void GetRandomBytes(Container& c)
|
||||
|
||||
@@ -19,10 +19,9 @@
|
||||
#define AZEROTHCORE_HMAC_H
|
||||
|
||||
#include "CryptoConstants.h"
|
||||
#include "Define.h"
|
||||
#include "CryptoHash.h"
|
||||
#include "Errors.h"
|
||||
#include <array>
|
||||
#include <openssl/hmac.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
@@ -30,96 +29,108 @@ class BigNumber;
|
||||
|
||||
namespace Acore::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>
|
||||
template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength>
|
||||
class GenericHMAC
|
||||
{
|
||||
public:
|
||||
static constexpr size_t DIGEST_LENGTH = DigestLength;
|
||||
using Digest = std::array<uint8, DIGEST_LENGTH>;
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
(hash.UpdateData(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(std::data(container), std::size(container)) {}
|
||||
|
||||
~GenericHMAC()
|
||||
{
|
||||
if (!_ctx)
|
||||
template <typename Container>
|
||||
static Digest GetDigestOf(Container const& seed, uint8 const* data, size_t len)
|
||||
{
|
||||
return;
|
||||
GenericHMAC hash(seed);
|
||||
hash.UpdateData(data, len);
|
||||
hash.Finalize();
|
||||
return hash.GetDigest();
|
||||
}
|
||||
HMACImpl::DestroyCTX(_ctx);
|
||||
_ctx = nullptr;
|
||||
}
|
||||
|
||||
void UpdateData(uint8 const* data, size_t len)
|
||||
{
|
||||
int result = HMAC_Update(_ctx, data, len);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
|
||||
void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
template <typename Container>
|
||||
void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); }
|
||||
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);
|
||||
(hash.UpdateData(std::forward<Ts>(pack)), ...);
|
||||
hash.Finalize();
|
||||
return hash.GetDigest();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
GenericHMAC(uint8 const* seed, size_t len) : _ctx(GenericHashImpl::MakeCTX()), _key(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, seed, len))
|
||||
{
|
||||
int result = EVP_DigestSignInit(_ctx, nullptr, HashCreator(), nullptr, _key);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
|
||||
Digest const& GetDigest() const { return _digest; }
|
||||
private:
|
||||
HMAC_CTX* _ctx;
|
||||
Digest _digest = { };
|
||||
template <typename Container>
|
||||
GenericHMAC(Container const& container) : GenericHMAC(std::data(container), std::size(container)) {}
|
||||
|
||||
GenericHMAC(GenericHMAC const& right) : _ctx(GenericHashImpl::MakeCTX())
|
||||
{
|
||||
*this = right;
|
||||
}
|
||||
|
||||
GenericHMAC(GenericHMAC&& right) noexcept
|
||||
{
|
||||
*this = std::move(right);
|
||||
}
|
||||
|
||||
~GenericHMAC()
|
||||
{
|
||||
GenericHashImpl::DestroyCTX(_ctx);
|
||||
_ctx = nullptr;
|
||||
EVP_PKEY_free(_key);
|
||||
_key = nullptr;
|
||||
}
|
||||
|
||||
GenericHMAC& operator=(GenericHMAC const& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx);
|
||||
ASSERT(result == 1);
|
||||
_key = right._key; // EVP_PKEY uses reference counting internally, just copy the pointer
|
||||
EVP_PKEY_up_ref(_key); // Bump reference count for PKEY, as every instance of this class holds two references to PKEY and destructor decrements it twice
|
||||
_digest = right._digest;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GenericHMAC& operator=(GenericHMAC&& right) noexcept
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
_ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX());
|
||||
_key = std::exchange(right._key, EVP_PKEY_new());
|
||||
_digest = std::exchange(right._digest, Digest{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
void UpdateData(uint8 const* data, size_t len)
|
||||
{
|
||||
int result = EVP_DigestSignUpdate(_ctx, data, len);
|
||||
ASSERT(result == 1);
|
||||
}
|
||||
|
||||
void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
|
||||
void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */
|
||||
|
||||
template <typename Container>
|
||||
void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); }
|
||||
|
||||
void Finalize()
|
||||
{
|
||||
size_t length = DIGEST_LENGTH;
|
||||
int result = EVP_DigestSignFinal(_ctx, _digest.data(), &length);
|
||||
ASSERT(result == 1);
|
||||
ASSERT(length == DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
Digest const& GetDigest() const { return _digest; }
|
||||
private:
|
||||
EVP_MD_CTX* _ctx{};
|
||||
EVP_PKEY* _key{};
|
||||
Digest _digest{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -128,4 +139,5 @@ namespace Acore::Crypto
|
||||
using HMAC_SHA1 = Acore::Impl::GenericHMAC<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>;
|
||||
using HMAC_SHA256 = Acore::Impl::GenericHMAC<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,49 +15,90 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <OpenSSLCrypto.h>
|
||||
#include "OpenSSLCrypto.h"
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
std::vector<std::mutex*> cryptoLocks;
|
||||
|
||||
static void lockingCallback(int mode, int type, char const* /*file*/, int /*line*/)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
{
|
||||
cryptoLocks[type]->lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
cryptoLocks[type]->unlock();
|
||||
}
|
||||
}
|
||||
static void threadIdCallback(CRYPTO_THREADID* id)
|
||||
|
||||
static void threadIdCallback(CRYPTO_THREADID * id)
|
||||
{
|
||||
(void)id;
|
||||
CRYPTO_THREADID_set_numeric(id, std::hash<std::thread::id>()(std::this_thread::get_id()));
|
||||
}
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/provider.h>
|
||||
OSSL_PROVIDER* LegacyProvider;
|
||||
OSSL_PROVIDER* DefaultProvider;
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
void SetupLibrariesForWindows()
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
fs::path programLocation{ boost::dll::program_location().remove_filename().string() };
|
||||
fs::path libLegacy{ boost::dll::program_location().remove_filename().string() + "/legacy.dll" };
|
||||
|
||||
ASSERT(fs::exists(libLegacy), "Not found 'legacy.dll'. Please copy library 'legacy.dll' from OpenSSL default dir to '{}'", programLocation.generic_string());
|
||||
OSSL_PROVIDER_set_default_search_path(nullptr, programLocation.generic_string().c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
void OpenSSLCrypto::threadsSetup()
|
||||
{
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||
cryptoLocks.resize(CRYPTO_num_locks());
|
||||
|
||||
for (int i = 0 ; i < CRYPTO_num_locks(); ++i)
|
||||
{
|
||||
cryptoLocks[i] = new std::mutex();
|
||||
}
|
||||
|
||||
(void)&threadIdCallback;
|
||||
CRYPTO_THREADID_set_callback(threadIdCallback);
|
||||
|
||||
(void)&lockingCallback;
|
||||
CRYPTO_set_locking_callback(lockingCallback);
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||
SetupLibrariesForWindows();
|
||||
#endif
|
||||
LegacyProvider = OSSL_PROVIDER_load(nullptr, "legacy");
|
||||
DefaultProvider = OSSL_PROVIDER_load(nullptr, "default");
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenSSLCrypto::threadsCleanup()
|
||||
{
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||
CRYPTO_set_locking_callback(nullptr);
|
||||
CRYPTO_THREADID_set_callback(nullptr);
|
||||
|
||||
for (int i = 0 ; i < CRYPTO_num_locks(); ++i)
|
||||
{
|
||||
delete cryptoLocks[i];
|
||||
}
|
||||
|
||||
cryptoLocks.resize(0);
|
||||
}
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
OSSL_PROVIDER_unload(LegacyProvider);
|
||||
OSSL_PROVIDER_unload(DefaultProvider);
|
||||
OSSL_PROVIDER_set_default_search_path(nullptr, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_CRYPTO_H
|
||||
#define OPENSSL_CRYPTO_H
|
||||
#ifndef _AC_OPENSSL_CRYPTO_H
|
||||
#define _AC_OPENSSL_CRYPTO_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
/**
|
||||
* A group of functions which setup openssl crypto module to work properly in multithreaded enviroment
|
||||
@@ -27,17 +26,11 @@
|
||||
*/
|
||||
namespace OpenSSLCrypto
|
||||
{
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||
/// Needs to be called before threads using openssl are spawned
|
||||
void threadsSetup();
|
||||
/// Needs to be called after threads using openssl are despawned
|
||||
void threadsCleanup();
|
||||
#else
|
||||
void threadsSetup() { };
|
||||
void threadsCleanup() { };
|
||||
#endif
|
||||
AC_COMMON_API void threadsSetup();
|
||||
|
||||
/// Needs to be called after threads using openssl are despawned
|
||||
AC_COMMON_API void threadsCleanup();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,17 +15,18 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CryptoHash.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifndef AZEROTHCORE_SESSIONKEYGENERATOR_HPP
|
||||
#define AZEROTHCORE_SESSIONKEYGENERATOR_HPP
|
||||
|
||||
#include "CryptoHash.h"
|
||||
#include <cstring>
|
||||
|
||||
template <typename Hash>
|
||||
class SessionKeyGenerator
|
||||
{
|
||||
public:
|
||||
template <typename C> SessionKeyGenerator(C const& buf) :
|
||||
template <typename C>
|
||||
SessionKeyGenerator(C const& buf) :
|
||||
o0it(o0.begin())
|
||||
{
|
||||
uint8 const* data = std::data(buf);
|
||||
@@ -52,9 +53,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typename Hash::Digest o0 = { };
|
||||
typename Hash::Digest o1 = { };
|
||||
typename Hash::Digest o2 = { };
|
||||
typename Hash::Digest o0{};
|
||||
typename Hash::Digest o1{};
|
||||
typename Hash::Digest o2{};
|
||||
typename Hash::Digest::const_iterator o0it;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,11 +28,8 @@ static constexpr uint32 HMAC_RESULT_SIZE = 20;
|
||||
{
|
||||
timestamp /= TOTP_INTERVAL;
|
||||
unsigned char challenge[8];
|
||||
|
||||
for (int i = 8; i--; timestamp >>= 8)
|
||||
{
|
||||
challenge[i] = timestamp;
|
||||
}
|
||||
|
||||
unsigned char digest[HMAC_RESULT_SIZE];
|
||||
uint32 digestSize = HMAC_RESULT_SIZE;
|
||||
@@ -41,7 +38,6 @@ static constexpr uint32 HMAC_RESULT_SIZE = 20;
|
||||
uint32 offset = digest[19] & 0xF;
|
||||
uint32 truncated = (digest[offset] << 24) | (digest[offset + 1] << 16) | (digest[offset + 2] << 8) | (digest[offset + 3]);
|
||||
truncated &= 0x7FFFFFFF;
|
||||
|
||||
return (truncated % 1000000);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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 WARHEAD_TOTP_H
|
||||
|
||||
@@ -34,7 +34,7 @@ private:
|
||||
std::atomic<bool> _shutdown;
|
||||
|
||||
public:
|
||||
ProducerConsumerQueue<T>() : _shutdown(false) { }
|
||||
ProducerConsumerQueue() : _shutdown(false) { }
|
||||
|
||||
void Push(const T& value)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user