cmCryptoHash.cxx 4.5 KB

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