summaryrefslogtreecommitdiff
path: root/src/common/Cryptography/CryptoHash.h
diff options
context:
space:
mode:
authorUltraNix <80540499+UltraNix@users.noreply.github.com>2021-03-21 15:17:57 +0100
committerGitHub <noreply@github.com>2021-03-21 15:17:57 +0100
commit485f7e76391a5bbf1af6b3219d27db721af38440 (patch)
tree2c8e9f8dfd3f8747d845252a4df2904ca6c80d57 /src/common/Cryptography/CryptoHash.h
parente9ed6380a6adff3ac96c932038990d0b1e8f2b11 (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.h107
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