cmCryptoHash.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCryptoHash.h"
  11. #include <cmsys/MD5.h>
  12. #include "cm_sha2.h"
  13. //----------------------------------------------------------------------------
  14. std::string cmCryptoHash::HashString(const char* input)
  15. {
  16. this->Initialize();
  17. this->Append(reinterpret_cast<unsigned char const*>(input),
  18. static_cast<int>(strlen(input)));
  19. return this->Finalize();
  20. }
  21. //----------------------------------------------------------------------------
  22. std::string cmCryptoHash::HashFile(const char* file)
  23. {
  24. std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
  25. if(!fin)
  26. {
  27. return "";
  28. }
  29. this->Initialize();
  30. // Should be efficient enough on most system:
  31. const int bufferSize = 4096;
  32. char buffer[bufferSize];
  33. unsigned char const* buffer_uc =
  34. reinterpret_cast<unsigned char const*>(buffer);
  35. // This copy loop is very sensitive on certain platforms with
  36. // slightly broken stream libraries (like HPUX). Normally, it is
  37. // incorrect to not check the error condition on the fin.read()
  38. // before using the data, but the fin.gcount() will be zero if an
  39. // error occurred. Therefore, the loop should be safe everywhere.
  40. while(fin)
  41. {
  42. fin.read(buffer, bufferSize);
  43. if(int gcount = static_cast<int>(fin.gcount()))
  44. {
  45. this->Append(buffer_uc, gcount);
  46. }
  47. }
  48. if(fin.eof())
  49. {
  50. return this->Finalize();
  51. }
  52. return "";
  53. }
  54. //----------------------------------------------------------------------------
  55. cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
  56. {
  57. }
  58. //----------------------------------------------------------------------------
  59. cmCryptoHashMD5::~cmCryptoHashMD5()
  60. {
  61. cmsysMD5_Delete(this->MD5);
  62. }
  63. //----------------------------------------------------------------------------
  64. void cmCryptoHashMD5::Initialize()
  65. {
  66. cmsysMD5_Initialize(this->MD5);
  67. }
  68. //----------------------------------------------------------------------------
  69. void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
  70. {
  71. cmsysMD5_Append(this->MD5, buf, sz);
  72. }
  73. //----------------------------------------------------------------------------
  74. std::string cmCryptoHashMD5::Finalize()
  75. {
  76. char md5out[32];
  77. cmsysMD5_FinalizeHex(this->MD5, md5out);
  78. return std::string(md5out, 32);
  79. }
  80. #define cmCryptoHash_SHA_CLASS_IMPL(SHA) \
  81. cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \
  82. cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \
  83. void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \
  84. void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \
  85. { SHA##_Update(this->SHA, buf, sz); } \
  86. std::string cmCryptoHash##SHA::Finalize() \
  87. { \
  88. char out[SHA##_DIGEST_STRING_LENGTH]; \
  89. SHA##_End(this->SHA, out); \
  90. return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \
  91. }
  92. cmCryptoHash_SHA_CLASS_IMPL(SHA1)
  93. cmCryptoHash_SHA_CLASS_IMPL(SHA224)
  94. cmCryptoHash_SHA_CLASS_IMPL(SHA256)
  95. cmCryptoHash_SHA_CLASS_IMPL(SHA384)
  96. cmCryptoHash_SHA_CLASS_IMPL(SHA512)