cmCryptoHash.cxx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 <cmsys/FStream.hxx>
  13. #include "cm_sha2.h"
  14. //----------------------------------------------------------------------------
  15. cmsys::auto_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo)
  16. {
  17. if(strcmp(algo,"MD5") == 0)
  18. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashMD5); }
  19. else if(strcmp(algo,"SHA1") == 0)
  20. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA1); }
  21. else if(strcmp(algo,"SHA224") == 0)
  22. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA224); }
  23. else if(strcmp(algo,"SHA256") == 0)
  24. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA256); }
  25. else if(strcmp(algo,"SHA384") == 0)
  26. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA384); }
  27. else if(strcmp(algo,"SHA512") == 0)
  28. { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA512); }
  29. else
  30. { return cmsys::auto_ptr<cmCryptoHash>(0); }
  31. }
  32. //----------------------------------------------------------------------------
  33. std::string cmCryptoHash::HashString(const char* input)
  34. {
  35. this->Initialize();
  36. this->Append(reinterpret_cast<unsigned char const*>(input),
  37. static_cast<int>(strlen(input)));
  38. return this->Finalize();
  39. }
  40. //----------------------------------------------------------------------------
  41. std::string cmCryptoHash::HashFile(const char* file)
  42. {
  43. cmsys::ifstream fin(file, std::ios::in | cmsys_ios_binary);
  44. if(!fin)
  45. {
  46. return "";
  47. }
  48. this->Initialize();
  49. // Should be efficient enough on most system:
  50. cm_sha2_uint64_t buffer[512];
  51. char* buffer_c = reinterpret_cast<char*>(buffer);
  52. unsigned char const* buffer_uc =
  53. reinterpret_cast<unsigned char const*>(buffer);
  54. // This copy loop is very sensitive on certain platforms with
  55. // slightly broken stream libraries (like HPUX). Normally, it is
  56. // incorrect to not check the error condition on the fin.read()
  57. // before using the data, but the fin.gcount() will be zero if an
  58. // error occurred. Therefore, the loop should be safe everywhere.
  59. while(fin)
  60. {
  61. fin.read(buffer_c, sizeof(buffer));
  62. if(int gcount = static_cast<int>(fin.gcount()))
  63. {
  64. this->Append(buffer_uc, gcount);
  65. }
  66. }
  67. if(fin.eof())
  68. {
  69. return this->Finalize();
  70. }
  71. return "";
  72. }
  73. //----------------------------------------------------------------------------
  74. cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
  75. {
  76. }
  77. //----------------------------------------------------------------------------
  78. cmCryptoHashMD5::~cmCryptoHashMD5()
  79. {
  80. cmsysMD5_Delete(this->MD5);
  81. }
  82. //----------------------------------------------------------------------------
  83. void cmCryptoHashMD5::Initialize()
  84. {
  85. cmsysMD5_Initialize(this->MD5);
  86. }
  87. //----------------------------------------------------------------------------
  88. void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
  89. {
  90. cmsysMD5_Append(this->MD5, buf, sz);
  91. }
  92. //----------------------------------------------------------------------------
  93. std::string cmCryptoHashMD5::Finalize()
  94. {
  95. char md5out[32];
  96. cmsysMD5_FinalizeHex(this->MD5, md5out);
  97. return std::string(md5out, 32);
  98. }
  99. #define cmCryptoHash_SHA_CLASS_IMPL(SHA) \
  100. cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \
  101. cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \
  102. void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \
  103. void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \
  104. { SHA##_Update(this->SHA, buf, sz); } \
  105. std::string cmCryptoHash##SHA::Finalize() \
  106. { \
  107. char out[SHA##_DIGEST_STRING_LENGTH]; \
  108. SHA##_End(this->SHA, out); \
  109. return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \
  110. }
  111. cmCryptoHash_SHA_CLASS_IMPL(SHA1)
  112. cmCryptoHash_SHA_CLASS_IMPL(SHA224)
  113. cmCryptoHash_SHA_CLASS_IMPL(SHA256)
  114. cmCryptoHash_SHA_CLASS_IMPL(SHA384)
  115. cmCryptoHash_SHA_CLASS_IMPL(SHA512)