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.

275 lines
6.3 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: crldist.cpp
  7. //
  8. // Contents: Cert Server Extension Encoding/Decoding implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. #include <assert.h>
  14. #include "resource.h"
  15. #include "bitstr.h"
  16. #include "celib.h"
  17. //+--------------------------------------------------------------------------
  18. // CCertEncodeBitString::~CCertEncodeBitString -- destructor
  19. //
  20. // free memory associated with this instance
  21. //+--------------------------------------------------------------------------
  22. CCertEncodeBitString::~CCertEncodeBitString()
  23. {
  24. _Cleanup();
  25. }
  26. //+--------------------------------------------------------------------------
  27. // CCertEncodeBitString::_Cleanup -- release all resources
  28. //
  29. // free memory associated with this instance
  30. //+--------------------------------------------------------------------------
  31. VOID
  32. CCertEncodeBitString::_Cleanup()
  33. {
  34. if (NULL != m_DecodeInfo)
  35. {
  36. LocalFree(m_DecodeInfo);
  37. m_DecodeInfo = NULL;
  38. }
  39. }
  40. //+--------------------------------------------------------------------------
  41. // CCertEncodeBitString::Decode -- Decode BitString
  42. //
  43. // Returns S_OK on success.
  44. //+--------------------------------------------------------------------------
  45. STDMETHODIMP
  46. CCertEncodeBitString::Decode(
  47. /* [in] */ BSTR const strBinary)
  48. {
  49. HRESULT hr = S_OK;
  50. DWORD cbBitString;
  51. _Cleanup();
  52. if (NULL == strBinary)
  53. {
  54. hr = E_POINTER;
  55. ceERRORPRINTLINE("NULL parm", hr);
  56. goto error;
  57. }
  58. // Decode CRYPT_BIT_BLOB:
  59. if (!ceDecodeObject(
  60. X509_ASN_ENCODING,
  61. X509_BITS,
  62. (BYTE *) strBinary,
  63. SysStringByteLen(strBinary),
  64. FALSE,
  65. (VOID **) &m_DecodeInfo,
  66. &cbBitString))
  67. {
  68. hr = ceHLastError();
  69. ceERRORPRINTLINE("ceDecodeObject", hr);
  70. goto error;
  71. }
  72. error:
  73. if (S_OK != hr)
  74. {
  75. _Cleanup();
  76. }
  77. return(_SetErrorInfo(hr, L"CCertEncodeBitString::Decode"));
  78. }
  79. //+--------------------------------------------------------------------------
  80. // CCertEncodeBitString::GetBitCount -- Get the Distribution Name Count
  81. //
  82. // Returns S_OK on success.
  83. //+--------------------------------------------------------------------------
  84. STDMETHODIMP
  85. CCertEncodeBitString::GetBitCount(
  86. /* [out, retval] */ LONG __RPC_FAR *pBitCount)
  87. {
  88. HRESULT hr = E_INVALIDARG;
  89. if (NULL == pBitCount)
  90. {
  91. hr = E_POINTER;
  92. ceERRORPRINTLINE("NULL parm", hr);
  93. goto error;
  94. }
  95. if (NULL == m_DecodeInfo)
  96. {
  97. ceERRORPRINTLINE("bad parameter", hr);
  98. goto error;
  99. }
  100. *pBitCount = m_DecodeInfo->cbData * 8 - m_DecodeInfo->cUnusedBits;
  101. hr = S_OK;
  102. error:
  103. return(_SetErrorInfo(hr, L"CCertEncodeBitString::GetBitCount"));
  104. }
  105. //+--------------------------------------------------------------------------
  106. // CCertEncodeBitString::GetBitString -- Get the bits
  107. //
  108. // Returns S_OK on success.
  109. //+--------------------------------------------------------------------------
  110. STDMETHODIMP
  111. CCertEncodeBitString::GetBitString(
  112. /* [out, retval] */ BSTR __RPC_FAR *pstrBitString)
  113. {
  114. HRESULT hr = E_INVALIDARG;
  115. if (NULL == pstrBitString)
  116. {
  117. hr = E_POINTER;
  118. ceERRORPRINTLINE("NULL parm", hr);
  119. goto error;
  120. }
  121. ceFreeBstr(pstrBitString);
  122. if (NULL == m_DecodeInfo)
  123. {
  124. ceERRORPRINTLINE("bad parameter", hr);
  125. goto error;
  126. }
  127. hr = E_OUTOFMEMORY;
  128. if (!ceConvertWszToBstr(
  129. pstrBitString,
  130. (WCHAR const *) m_DecodeInfo->pbData,
  131. m_DecodeInfo->cbData))
  132. {
  133. ceERRORPRINTLINE("no memory", hr);
  134. goto error;
  135. }
  136. hr = S_OK;
  137. error:
  138. return(_SetErrorInfo(hr, L"CCertEncodeBitString::GetBitString"));
  139. }
  140. //+--------------------------------------------------------------------------
  141. // CCertEncodeBitString::Encode -- Encode BitString
  142. //
  143. // Returns S_OK on success.
  144. //+--------------------------------------------------------------------------
  145. STDMETHODIMP
  146. CCertEncodeBitString::Encode(
  147. /* [in] */ LONG BitCount,
  148. /* [in] */ BSTR strBitString,
  149. /* [out, retval] */ BSTR __RPC_FAR *pstrBinary)
  150. {
  151. HRESULT hr = S_OK;
  152. CRYPT_BIT_BLOB BitString;
  153. LONG cbData;
  154. BYTE *pbEncoded = NULL;
  155. DWORD cbEncoded;
  156. if (NULL != pstrBinary)
  157. {
  158. ceFreeBstr(pstrBinary);
  159. }
  160. if (NULL == strBitString || NULL == pstrBinary)
  161. {
  162. hr = E_POINTER;
  163. ceERRORPRINTLINE("NULL parm", hr);
  164. goto error;
  165. }
  166. if (CENCODEMAX < BitCount || 0 > BitCount)
  167. {
  168. hr = E_INVALIDARG;
  169. ceERRORPRINTLINE("bad count parameter", hr);
  170. goto error;
  171. }
  172. cbData = SysStringByteLen(strBitString);
  173. if (BitCount > cbData * 8 || BitCount <= (cbData - 1) * 8)
  174. {
  175. hr = E_INVALIDARG;
  176. ceERRORPRINTLINE("bad BitCount parameter", hr);
  177. goto error;
  178. }
  179. BitString.cbData = cbData;
  180. BitString.pbData = (BYTE *) strBitString;
  181. BitString.cUnusedBits = cbData * 8 - BitCount;
  182. // Encode CRYPT_BIT_BLOB:
  183. // If cUnusedBits is 0, encode as X509_KEY_USAGE to ensure that trailing
  184. // zero bytes are stripped, and trailing zero bits in the last byte are
  185. // counted and that count is encoded into the CRYPT_BIT_BLOB.
  186. if (!ceEncodeObject(
  187. X509_ASN_ENCODING,
  188. 0 == BitString.cUnusedBits? X509_KEY_USAGE : X509_BITS,
  189. &BitString,
  190. 0,
  191. FALSE,
  192. &pbEncoded,
  193. &cbEncoded))
  194. {
  195. hr = ceHLastError();
  196. ceERRORPRINTLINE("ceEncodeObject", hr);
  197. goto error;
  198. }
  199. if (!ceConvertWszToBstr(pstrBinary, (WCHAR const *) pbEncoded, cbEncoded))
  200. {
  201. hr = E_OUTOFMEMORY;
  202. ceERRORPRINTLINE("ceConvertWszToBstr", hr);
  203. goto error;
  204. }
  205. error:
  206. if (NULL != pbEncoded)
  207. {
  208. LocalFree(pbEncoded);
  209. }
  210. return(_SetErrorInfo(hr, L"CCertEncodeBitString::Encode"));
  211. }
  212. //+--------------------------------------------------------------------------
  213. // CCertEncodeStringArray::_SetErrorInfo -- set error object information
  214. //
  215. // Returns passed HRESULT
  216. //+--------------------------------------------------------------------------
  217. HRESULT
  218. CCertEncodeBitString::_SetErrorInfo(
  219. IN HRESULT hrError,
  220. IN WCHAR const *pwszDescription)
  221. {
  222. assert(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
  223. if (FAILED(hrError))
  224. {
  225. HRESULT hr;
  226. hr = ceDispatchSetErrorInfo(
  227. hrError,
  228. pwszDescription,
  229. wszCLASS_CERTENCODEBITSTRING,
  230. &IID_ICertEncodeBitString);
  231. assert(hr == hrError);
  232. }
  233. return(hrError);
  234. }