Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
7.1 KiB

  1. // HashCtx.cpp -- definition of CHashContext
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1998. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #include "stdafx.h" // because handles.h uses the ASSERT macro
  8. #include <memory> // for auto_ptr
  9. #include <malloc.h> // for _alloca
  10. #include <scuOsVersion.h>
  11. #include "HashCtx.h"
  12. #include "HashMD2.h"
  13. #include "HashMD4.h"
  14. #include "HashMD5.h"
  15. #include "HashSHA1.h"
  16. #include "HashSHAMD5.h"
  17. using namespace std;
  18. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  19. /////////////////////////// PUBLIC /////////////////////////////////
  20. // Types
  21. // C'tors/D'tors
  22. CHashContext::~CHashContext() throw()
  23. {
  24. try
  25. {
  26. Close();
  27. }
  28. catch (...)
  29. {
  30. }
  31. }
  32. // Operators
  33. // Operations
  34. void
  35. CHashContext::Close()
  36. {
  37. if (m_HashHandle)
  38. {
  39. if (!CryptDestroyHash(m_HashHandle))
  40. throw scu::OsException(GetLastError());
  41. m_HashHandle = NULL;
  42. }
  43. }
  44. void
  45. CHashContext::ExportFromAuxCSP()
  46. {
  47. if (!m_HashHandle)
  48. throw scu::OsException(ERROR_INVALID_PARAMETER);
  49. if (m_fJustCreated)
  50. {
  51. DWORD dwNeedLen;
  52. DWORD dwDataLen = sizeof DWORD;
  53. if (!CryptGetHashParam(m_HashHandle, HP_HASHSIZE,
  54. reinterpret_cast<BYTE *>(&dwNeedLen),
  55. &dwDataLen, 0))
  56. throw scu::OsException(GetLastError());
  57. BYTE *pbHashValue = reinterpret_cast<BYTE *>(_alloca(dwNeedLen));
  58. if (!CryptGetHashParam(m_HashHandle, HP_HASHVAL,
  59. pbHashValue, &dwNeedLen, 0))
  60. throw scu::OsException(GetLastError());
  61. Value(Blob(pbHashValue, dwNeedLen));
  62. }
  63. }
  64. void CHashContext::Hash(BYTE const *pbData,
  65. DWORD dwLength)
  66. {
  67. HCRYPTHASH hch = HashHandleInAuxCSP();
  68. if (!CryptHashData(hch, pbData, dwLength, 0))
  69. throw scu::OsException(GetLastError());
  70. m_fJustCreated = false;
  71. }
  72. void
  73. CHashContext::ImportToAuxCSP()
  74. {
  75. if (!m_HashHandle)
  76. {
  77. if (!CryptCreateHash(m_rcryptctx.AuxContext(),
  78. m_algid, 0, 0, &m_HashHandle))
  79. throw scu::OsException(GetLastError());
  80. }
  81. if (!m_fJustCreated && !m_fDone)
  82. {
  83. if (!CryptSetHashParam(m_HashHandle, HP_HASHVAL,
  84. const_cast<Blob::value_type *>(Value().data()),
  85. 0))
  86. throw scu::OsException(GetLastError());
  87. }
  88. }
  89. void
  90. CHashContext::Initialize()
  91. {
  92. m_fDone = false;
  93. }
  94. auto_ptr<CHashContext>
  95. CHashContext::Make(ALG_ID algid,
  96. CryptContext const &rcryptctx)
  97. {
  98. auto_ptr<CHashContext> apHash;
  99. switch (algid)
  100. {
  101. case CALG_MD2:
  102. apHash = auto_ptr<CHashContext>(new CHashMD2(rcryptctx));
  103. break;
  104. case CALG_MD4:
  105. apHash = auto_ptr<CHashContext>(new CHashMD4(rcryptctx));
  106. break;
  107. case CALG_MD5:
  108. apHash = auto_ptr<CHashContext>(new CHashMD5(rcryptctx));
  109. break;
  110. case CALG_SHA:
  111. apHash = auto_ptr<CHashContext>(new CHashSHA1(rcryptctx));
  112. break;
  113. case CALG_SSL3_SHAMD5:
  114. apHash = auto_ptr<CHashContext>(new CHashSHAMD5(rcryptctx));
  115. break;
  116. default:
  117. throw scu::OsException(NTE_BAD_ALGID);
  118. break;
  119. }
  120. return apHash;
  121. }
  122. void
  123. CHashContext::Value(Blob const &rhs)
  124. {
  125. if (!m_fJustCreated)
  126. throw scu::OsException(NTE_PERM);
  127. m_blbValue = rhs;
  128. m_fJustCreated = false;
  129. m_fDone = true;
  130. }
  131. // Access
  132. ALG_ID
  133. CHashContext::AlgId()
  134. {
  135. return m_algid;
  136. }
  137. Blob
  138. CHashContext::EncodedValue()
  139. {
  140. return EncodedAlgorithmOid() + Value();
  141. }
  142. HCRYPTHASH
  143. CHashContext::HashHandleInAuxCSP()
  144. {
  145. ImportToAuxCSP();
  146. return m_HashHandle;
  147. }
  148. CHashContext::SizeType
  149. CHashContext::Length() const
  150. {
  151. SizeType cHashLength;
  152. if (!m_fDone)
  153. {
  154. DWORD dwData;
  155. DWORD dwDataLength = sizeof dwData;
  156. if (!CryptGetHashParam(m_HashHandle, HP_HASHSIZE,
  157. reinterpret_cast<BYTE *>(&dwData),
  158. &dwDataLength, 0))
  159. throw scu::OsException(GetLastError());
  160. cHashLength = dwData;
  161. }
  162. else
  163. cHashLength = m_blbValue.length();
  164. return cHashLength;
  165. }
  166. Blob
  167. CHashContext::Value()
  168. {
  169. if (!m_fDone)
  170. ExportFromAuxCSP();
  171. return m_blbValue;
  172. }
  173. // Predicates
  174. bool
  175. CHashContext::IsSupported(ALG_ID algid)
  176. {
  177. bool IsSupported = true;
  178. switch (algid)
  179. {
  180. case CALG_MD2:
  181. case CALG_MD4:
  182. case CALG_MD5:
  183. case CALG_SHA:
  184. case CALG_SSL3_SHAMD5:
  185. break;
  186. default:
  187. IsSupported = false;
  188. break;
  189. }
  190. return IsSupported;
  191. }
  192. // Static Variables
  193. /////////////////////////// PROTECTED /////////////////////////////////
  194. // C'tors/D'tors
  195. CHashContext::CHashContext(CryptContext const &rcryptctx,
  196. ALG_ID algid)
  197. : CHandle(),
  198. m_rcryptctx(rcryptctx),
  199. m_algid(algid),
  200. m_blbValue(),
  201. m_fDone(false),
  202. m_fJustCreated(true),
  203. m_HashHandle(NULL)
  204. {}
  205. // Duplicate the hash and its state
  206. CHashContext::CHashContext(CHashContext const &rhs,
  207. DWORD const *pdwReserved,
  208. DWORD dwFlags)
  209. : CHandle(),
  210. m_rcryptctx(rhs.m_rcryptctx),
  211. m_algid(rhs.m_algid),
  212. m_blbValue(rhs.m_blbValue),
  213. m_fDone(rhs.m_fDone),
  214. m_fJustCreated(rhs.m_fJustCreated)
  215. {
  216. #if defined(SLB_WIN2K_BUILD)
  217. if (!CryptDuplicateHash(HashHandleInAuxCSP(),
  218. const_cast<DWORD *>(pdwReserved),
  219. dwFlags,
  220. &m_HashHandle))
  221. throw scu::OsException(GetLastError());
  222. #else
  223. throw scu::OsException(ERROR_NOT_SUPPORTED);
  224. #endif
  225. }
  226. // Operators
  227. // Operations
  228. // Access
  229. // Predicates
  230. // Static Variables
  231. /////////////////////////// PRIVATE /////////////////////////////////
  232. // C'tors/D'tors
  233. // Operators
  234. // Operations
  235. // Access
  236. // Predicates
  237. // Static Variables