summaryrefslogtreecommitdiff
path: root/src/common/Cryptography/CryptoHash.h
diff options
context:
space:
mode:
authorWinfidonarleyan <dowlandtop@yandex.com>2022-11-23 21:12:20 +0300
committerGitHub <noreply@github.com>2022-11-24 01:12:20 +0700
commita1a1528cb4a9ed6f0220621fe6ecf9e2c36a5534 (patch)
tree04598163bda650f353cc1e12872c03f94537f700 /src/common/Cryptography/CryptoHash.h
parent4a2964e10a03a2b6ba2077e6b362b8a6ba6675fb (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.h158
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>;
}