diff options
author | Winfidonarleyan <dowlandtop@yandex.com> | 2022-11-23 21:12:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-24 01:12:20 +0700 |
commit | a1a1528cb4a9ed6f0220621fe6ecf9e2c36a5534 (patch) | |
tree | 04598163bda650f353cc1e12872c03f94537f700 /src/common/Cryptography/CryptoHash.h | |
parent | 4a2964e10a03a2b6ba2077e6b362b8a6ba6675fb (diff) |
feat(Core/Crypto): add support `OpenSSL 3.0` (#13354)
Diffstat (limited to 'src/common/Cryptography/CryptoHash.h')
-rw-r--r-- | src/common/Cryptography/CryptoHash.h | 158 |
1 files changed, 94 insertions, 64 deletions
diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h index e2f38da8d8..1763351bc7 100644 --- a/src/common/Cryptography/CryptoHash.h +++ b/src/common/Cryptography/CryptoHash.h @@ -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>; - - 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) + 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(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX()) + { + *this = right; + } + + GenericHash(GenericHash&& right) noexcept + { + *this = std::move(right); + } + + ~GenericHash() + { + if (!_ctx) + return; + GenericHashImpl::DestroyCTX(_ctx); + _ctx = nullptr; + } + + GenericHash& operator=(GenericHash const& right) { - return; + if (this == &right) + return *this; + + int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx); + ASSERT(result == 1); + _digest = right._digest; + return *this; } - 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 = { }; + + 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>; } |