diff options
author | UltraNix <80540499+UltraNix@users.noreply.github.com> | 2021-03-21 15:17:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-21 15:17:57 +0100 |
commit | 485f7e76391a5bbf1af6b3219d27db721af38440 (patch) | |
tree | 2c8e9f8dfd3f8747d845252a4df2904ca6c80d57 /src/common/Cryptography/CryptoHash.h | |
parent | e9ed6380a6adff3ac96c932038990d0b1e8f2b11 (diff) |
feat(Core/DB/Authserver): remove `sha_pass_hash` (#4827)
Diffstat (limited to 'src/common/Cryptography/CryptoHash.h')
-rw-r--r-- | src/common/Cryptography/CryptoHash.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h new file mode 100644 index 0000000000..cdc3258834 --- /dev/null +++ b/src/common/Cryptography/CryptoHash.h @@ -0,0 +1,107 @@ +/* + * 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) 2008-2021 TrinityCore <http://www.trinitycore.org/> + */ + +#ifndef AZEROTHCORE_CRYPTOHASH_H +#define AZEROTHCORE_CRYPTOHASH_H + +#include "CryptoConstants.h" +#include "Define.h" +#include "Errors.h" +#include <array> +#include <string> +#include <string_view> +#include <openssl/evp.h> + +class BigNumber; + +namespace acore::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(); + } + + 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) + return; + 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)); } + + 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 acore::Crypto +{ + using SHA1 = acore::Impl::GenericHash<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>; + using SHA256 = acore::Impl::GenericHash<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>; +} + +#endif |