From 9a596b33bbfdb274ccf7f678c78cb8826c7c363b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 3 Nov 2016 11:33:43 -0400 Subject: cmCryptoHash: Re-implement in terms of librhash Offer direct construction with an enumeration of supported algorithms. Also expose the Initialize/Append/Finalize steps publicly and add a FinalizeHex method. --- Source/cmCryptoHash.cxx | 97 +++++++++++++++++++++++++++---------------------- Source/cmCryptoHash.h | 61 ++++++++++--------------------- 2 files changed, 73 insertions(+), 85 deletions(-) diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index 9b3f84a..f440999 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -2,31 +2,62 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCryptoHash.h" -#include "cm_sha2.h" - +#include +#include #include -#include #include +static unsigned int const cmCryptoHashAlgoToId[] = { + /* clang-format needs this comment to break after the opening brace */ + RHASH_MD5, // + RHASH_SHA1, // + RHASH_SHA224, // + RHASH_SHA256, // + RHASH_SHA384, // + RHASH_SHA512 +}; + +static int cmCryptoHash_rhash_library_initialized; + +static rhash cmCryptoHash_rhash_init(unsigned int id) +{ + if (!cmCryptoHash_rhash_library_initialized) { + cmCryptoHash_rhash_library_initialized = 1; + rhash_library_init(); + } + return rhash_init(id); +} + +cmCryptoHash::cmCryptoHash(Algo algo) + : Id(cmCryptoHashAlgoToId[algo]) + , CTX(cmCryptoHash_rhash_init(Id)) +{ +} + +cmCryptoHash::~cmCryptoHash() +{ + rhash_free(this->CTX); +} + CM_AUTO_PTR cmCryptoHash::New(const char* algo) { if (strcmp(algo, "MD5") == 0) { - return CM_AUTO_PTR(new cmCryptoHashMD5); + return CM_AUTO_PTR(new cmCryptoHash(AlgoMD5)); } if (strcmp(algo, "SHA1") == 0) { - return CM_AUTO_PTR(new cmCryptoHashSHA1); + return CM_AUTO_PTR(new cmCryptoHash(AlgoSHA1)); } if (strcmp(algo, "SHA224") == 0) { - return CM_AUTO_PTR(new cmCryptoHashSHA224); + return CM_AUTO_PTR(new cmCryptoHash(AlgoSHA224)); } if (strcmp(algo, "SHA256") == 0) { - return CM_AUTO_PTR(new cmCryptoHashSHA256); + return CM_AUTO_PTR(new cmCryptoHash(AlgoSHA256)); } if (strcmp(algo, "SHA384") == 0) { - return CM_AUTO_PTR(new cmCryptoHashSHA384); + return CM_AUTO_PTR(new cmCryptoHash(AlgoSHA384)); } if (strcmp(algo, "SHA512") == 0) { - return CM_AUTO_PTR(new cmCryptoHashSHA512); + return CM_AUTO_PTR(new cmCryptoHash(AlgoSHA512)); } return CM_AUTO_PTR(CM_NULLPTR); } @@ -80,7 +111,7 @@ std::vector cmCryptoHash::ByteHashFile(const std::string& file) this->Initialize(); { // Should be efficient enough on most system: - cm_sha2_uint64_t buffer[512]; + KWIML_INT_uint64_t buffer[512]; char* buffer_c = reinterpret_cast(buffer); unsigned char const* buffer_uc = reinterpret_cast(buffer); @@ -117,51 +148,29 @@ std::string cmCryptoHash::HashFile(const std::string& file) return ByteHashToString(this->ByteHashFile(file)); } -cmCryptoHashMD5::cmCryptoHashMD5() - : MD5(cmsysMD5_New()) +void cmCryptoHash::Initialize() { + rhash_reset(this->CTX); } -cmCryptoHashMD5::~cmCryptoHashMD5() +void cmCryptoHash::Append(void const* buf, size_t sz) { - cmsysMD5_Delete(this->MD5); + rhash_update(this->CTX, buf, sz); } -void cmCryptoHashMD5::Initialize() +void cmCryptoHash::Append(std::string const& str) { - cmsysMD5_Initialize(this->MD5); + this->Append(str.c_str(), str.size()); } -void cmCryptoHashMD5::Append(unsigned char const* buf, int sz) +std::vector cmCryptoHash::Finalize() { - cmsysMD5_Append(this->MD5, buf, sz); + std::vector hash(rhash_get_digest_size(this->Id), 0); + rhash_final(this->CTX, &hash[0]); + return hash; } -std::vector cmCryptoHashMD5::Finalize() +std::string cmCryptoHash::FinalizeHex() { - std::vector hash(16, 0); - cmsysMD5_Finalize(this->MD5, &hash[0]); - return hash; + return cmCryptoHash::ByteHashToString(this->Finalize()); } - -#define cmCryptoHash_SHA_CLASS_IMPL(SHA) \ - cmCryptoHash##SHA::cmCryptoHash##SHA() \ - : SHA(new SHA_CTX) \ - { \ - } \ - cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \ - void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \ - void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \ - { \ - SHA##_Update(this->SHA, buf, sz); \ - } \ - std::vector cmCryptoHash##SHA::Finalize() \ - { \ - std::vector hash(SHA##_DIGEST_LENGTH, 0); \ - SHA##_Final(&hash[0], this->SHA); \ - return hash; \ - } - -cmCryptoHash_SHA_CLASS_IMPL(SHA1) cmCryptoHash_SHA_CLASS_IMPL(SHA224) - cmCryptoHash_SHA_CLASS_IMPL(SHA256) cmCryptoHash_SHA_CLASS_IMPL(SHA384) - cmCryptoHash_SHA_CLASS_IMPL(SHA512) diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index 5c2d3ca..95080ac 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -15,7 +15,18 @@ class cmCryptoHash { public: - virtual ~cmCryptoHash() {} + enum Algo + { + AlgoMD5, + AlgoSHA1, + AlgoSHA224, + AlgoSHA256, + AlgoSHA384, + AlgoSHA512 + }; + + cmCryptoHash(Algo algo); + ~cmCryptoHash(); /// @brief Returns a new hash generator of the requested type /// @arg algo Hash type name. Supported hash types are @@ -53,47 +64,15 @@ public: /// An empty string otherwise. std::string HashFile(const std::string& file); -protected: - virtual void Initialize() = 0; - virtual void Append(unsigned char const*, int) = 0; - virtual std::vector Finalize() = 0; -}; - -class cmCryptoHashMD5 : public cmCryptoHash -{ - struct cmsysMD5_s* MD5; - -public: - cmCryptoHashMD5(); - ~cmCryptoHashMD5() CM_OVERRIDE; + void Initialize(); + void Append(void const*, size_t); + void Append(std::string const& str); + std::vector Finalize(); + std::string FinalizeHex(); -protected: - void Initialize() CM_OVERRIDE; - void Append(unsigned char const* buf, int sz) CM_OVERRIDE; - std::vector Finalize() CM_OVERRIDE; +private: + unsigned int Id; + struct rhash_context* CTX; }; -#define cmCryptoHash_SHA_CLASS_DECL(SHA) \ - class cmCryptoHash##SHA : public cmCryptoHash \ - { \ - union _SHA_CTX* SHA; \ - \ - public: \ - cmCryptoHash##SHA(); \ - ~cmCryptoHash##SHA(); \ - \ - protected: \ - virtual void Initialize(); \ - virtual void Append(unsigned char const* buf, int sz); \ - virtual std::vector Finalize(); \ - } - -cmCryptoHash_SHA_CLASS_DECL(SHA1); -cmCryptoHash_SHA_CLASS_DECL(SHA224); -cmCryptoHash_SHA_CLASS_DECL(SHA256); -cmCryptoHash_SHA_CLASS_DECL(SHA384); -cmCryptoHash_SHA_CLASS_DECL(SHA512); - -#undef cmCryptoHash_SHA_CLASS_DECL - #endif -- cgit v0.12