hashes.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: hashes.cc,v 1.1 2001/03/06 07:15:29 jgg Exp $
  4. /* ######################################################################
  5. Hashes - Simple wrapper around the hash functions
  6. This is just used to make building the methods simpler, this is the
  7. only interface required..
  8. ##################################################################### */
  9. /*}}}*/
  10. // Include Files /*{{{*/
  11. #include <config.h>
  12. #include <apt-pkg/hashes.h>
  13. #include <apt-pkg/fileutl.h>
  14. #include <apt-pkg/configuration.h>
  15. #include <apt-pkg/md5.h>
  16. #include <apt-pkg/sha1.h>
  17. #include <apt-pkg/sha2.h>
  18. #include <stddef.h>
  19. #include <algorithm>
  20. #include <unistd.h>
  21. #include <string>
  22. #include <iostream>
  23. /*}}}*/
  24. const char* HashString::_SupportedHashes[] =
  25. {
  26. "SHA512", "SHA256", "SHA1", "MD5Sum", NULL
  27. };
  28. HashString::HashString()
  29. {
  30. }
  31. HashString::HashString(std::string Type, std::string Hash) : Type(Type), Hash(Hash)
  32. {
  33. }
  34. HashString::HashString(std::string StringedHash) /*{{{*/
  35. {
  36. // legacy: md5sum without "MD5Sum:" prefix
  37. if (StringedHash.find(":") == std::string::npos && StringedHash.size() == 32)
  38. {
  39. Type = "MD5Sum";
  40. Hash = StringedHash;
  41. return;
  42. }
  43. std::string::size_type pos = StringedHash.find(":");
  44. Type = StringedHash.substr(0,pos);
  45. Hash = StringedHash.substr(pos+1, StringedHash.size() - pos);
  46. if(_config->FindB("Debug::Hashes",false) == true)
  47. std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
  48. }
  49. /*}}}*/
  50. bool HashString::VerifyFile(std::string filename) const /*{{{*/
  51. {
  52. std::string fileHash = GetHashForFile(filename);
  53. if(_config->FindB("Debug::Hashes",false) == true)
  54. std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl;
  55. return (fileHash == Hash);
  56. }
  57. /*}}}*/
  58. bool HashString::FromFile(std::string filename) /*{{{*/
  59. {
  60. // pick the strongest hash
  61. if (Type == "")
  62. Type = _SupportedHashes[0];
  63. Hash = GetHashForFile(filename);
  64. return true;
  65. }
  66. /*}}}*/
  67. std::string HashString::GetHashForFile(std::string filename) const /*{{{*/
  68. {
  69. std::string fileHash;
  70. FileFd Fd(filename, FileFd::ReadOnly);
  71. if(Type == "MD5Sum")
  72. {
  73. MD5Summation MD5;
  74. MD5.AddFD(Fd);
  75. fileHash = (std::string)MD5.Result();
  76. }
  77. else if (Type == "SHA1")
  78. {
  79. SHA1Summation SHA1;
  80. SHA1.AddFD(Fd);
  81. fileHash = (std::string)SHA1.Result();
  82. }
  83. else if (Type == "SHA256")
  84. {
  85. SHA256Summation SHA256;
  86. SHA256.AddFD(Fd);
  87. fileHash = (std::string)SHA256.Result();
  88. }
  89. else if (Type == "SHA512")
  90. {
  91. SHA512Summation SHA512;
  92. SHA512.AddFD(Fd);
  93. fileHash = (std::string)SHA512.Result();
  94. }
  95. Fd.Close();
  96. return fileHash;
  97. }
  98. /*}}}*/
  99. const char** HashString::SupportedHashes()
  100. {
  101. return _SupportedHashes;
  102. }
  103. APT_PURE bool HashString::empty() const
  104. {
  105. return (Type.empty() || Hash.empty());
  106. }
  107. std::string HashString::toStr() const
  108. {
  109. return Type + std::string(":") + Hash;
  110. }
  111. // Hashes::AddFD - Add the contents of the FD /*{{{*/
  112. // ---------------------------------------------------------------------
  113. /* */
  114. bool Hashes::AddFD(int const Fd,unsigned long long Size, bool const addMD5,
  115. bool const addSHA1, bool const addSHA256, bool const addSHA512)
  116. {
  117. unsigned char Buf[64*64];
  118. bool const ToEOF = (Size == 0);
  119. while (Size != 0 || ToEOF)
  120. {
  121. unsigned long long n = sizeof(Buf);
  122. if (!ToEOF) n = std::min(Size, n);
  123. ssize_t const Res = read(Fd,Buf,n);
  124. if (Res < 0 || (!ToEOF && Res != (ssize_t) n)) // error, or short read
  125. return false;
  126. if (ToEOF && Res == 0) // EOF
  127. break;
  128. Size -= Res;
  129. if (addMD5 == true)
  130. MD5.Add(Buf,Res);
  131. if (addSHA1 == true)
  132. SHA1.Add(Buf,Res);
  133. if (addSHA256 == true)
  134. SHA256.Add(Buf,Res);
  135. if (addSHA512 == true)
  136. SHA512.Add(Buf,Res);
  137. }
  138. return true;
  139. }
  140. bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, bool const addMD5,
  141. bool const addSHA1, bool const addSHA256, bool const addSHA512)
  142. {
  143. unsigned char Buf[64*64];
  144. bool const ToEOF = (Size == 0);
  145. while (Size != 0 || ToEOF)
  146. {
  147. unsigned long long n = sizeof(Buf);
  148. if (!ToEOF) n = std::min(Size, n);
  149. unsigned long long a = 0;
  150. if (Fd.Read(Buf, n, &a) == false) // error
  151. return false;
  152. if (ToEOF == false)
  153. {
  154. if (a != n) // short read
  155. return false;
  156. }
  157. else if (a == 0) // EOF
  158. break;
  159. Size -= a;
  160. if (addMD5 == true)
  161. MD5.Add(Buf, a);
  162. if (addSHA1 == true)
  163. SHA1.Add(Buf, a);
  164. if (addSHA256 == true)
  165. SHA256.Add(Buf, a);
  166. if (addSHA512 == true)
  167. SHA512.Add(Buf, a);
  168. }
  169. return true;
  170. }
  171. /*}}}*/