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.

427 lines
9.3 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: along.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 "along.h"
  16. #include "celib.h"
  17. //+--------------------------------------------------------------------------
  18. // CCertEncodeLongArray::~CCertEncodeLongArray -- destructor
  19. //
  20. // free memory associated with this instance
  21. //+--------------------------------------------------------------------------
  22. CCertEncodeLongArray::~CCertEncodeLongArray()
  23. {
  24. _Cleanup();
  25. }
  26. //+--------------------------------------------------------------------------
  27. // CCertEncodeLongArray::_Cleanup -- release all resources
  28. //
  29. // free memory associated with this instance
  30. //+--------------------------------------------------------------------------
  31. VOID
  32. CCertEncodeLongArray::_Cleanup()
  33. {
  34. if (NULL != m_aValue)
  35. {
  36. LocalFree(m_aValue);
  37. m_aValue = NULL;
  38. }
  39. m_cValue = 0;
  40. m_cValuesSet = 0;
  41. m_fConstructing = FALSE;
  42. }
  43. //+--------------------------------------------------------------------------
  44. // CCertEncodeLongArray::Decode -- Decode LongArray
  45. //
  46. // Returns S_OK on success.
  47. //+--------------------------------------------------------------------------
  48. STDMETHODIMP
  49. CCertEncodeLongArray::Decode(
  50. /* [in] */ BSTR const strBinary)
  51. {
  52. HRESULT hr = S_OK;
  53. CRYPT_SEQUENCE_OF_ANY *pSequence = NULL;
  54. DWORD cbSequence;
  55. LONG i;
  56. _Cleanup();
  57. if (NULL == strBinary)
  58. {
  59. hr = E_POINTER;
  60. ceERRORPRINTLINE("NULL parm", hr);
  61. goto error;
  62. }
  63. // Decode to an array of ASN blobs:
  64. if (!ceDecodeObject(
  65. X509_ASN_ENCODING,
  66. X509_SEQUENCE_OF_ANY,
  67. (BYTE *) strBinary,
  68. SysStringByteLen(strBinary),
  69. FALSE,
  70. (VOID **) &pSequence,
  71. &cbSequence))
  72. {
  73. hr = ceHLastError();
  74. ceERRORPRINTLINE("ceDecodeObject", hr);
  75. goto error;
  76. }
  77. m_cValue = pSequence->cValue;
  78. m_aValue = (LONG *) LocalAlloc(LMEM_FIXED, m_cValue * sizeof(m_aValue[0]));
  79. if (NULL == m_aValue)
  80. {
  81. hr = E_OUTOFMEMORY;
  82. ceERRORPRINTLINE("LocalAlloc", hr);
  83. goto error;
  84. }
  85. for (i = 0; i < m_cValue; i++)
  86. {
  87. DWORD cb;
  88. // Decode each ASN blob to an integer:
  89. cb = sizeof(m_aValue[i]);
  90. if (!CryptDecodeObject(
  91. X509_ASN_ENCODING,
  92. X509_INTEGER,
  93. pSequence->rgValue[i].pbData,
  94. pSequence->rgValue[i].cbData,
  95. 0, // dwFlags
  96. (VOID *) &m_aValue[i],
  97. &cb))
  98. {
  99. hr = ceHLastError();
  100. ceERRORPRINTLINE("CryptDecodeObject", hr);
  101. goto error;
  102. }
  103. assert(sizeof(m_aValue[i]) == cb);
  104. }
  105. error:
  106. if (NULL != pSequence)
  107. {
  108. LocalFree(pSequence);
  109. }
  110. if (S_OK != hr)
  111. {
  112. _Cleanup();
  113. }
  114. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Decode"));
  115. }
  116. //+--------------------------------------------------------------------------
  117. // CCertEncodeLongArray::GetCount -- Get Array count
  118. //
  119. // Returns S_OK on success.
  120. //+--------------------------------------------------------------------------
  121. STDMETHODIMP
  122. CCertEncodeLongArray::GetCount(
  123. /* [out, retval] */ LONG __RPC_FAR *pCount)
  124. {
  125. HRESULT hr = S_OK;
  126. if (NULL == pCount)
  127. {
  128. hr = E_POINTER;
  129. ceERRORPRINTLINE("NULL parm", hr);
  130. goto error;
  131. }
  132. if (NULL == m_aValue)
  133. {
  134. hr = E_INVALIDARG;
  135. ceERRORPRINTLINE("bad parameter", hr);
  136. goto error;
  137. }
  138. *pCount = m_cValue;
  139. error:
  140. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::GetCount"));
  141. }
  142. //+--------------------------------------------------------------------------
  143. // CCertEncodeLongArray::GetValue -- Fetch the indexed long
  144. //
  145. // Returns S_OK on success.
  146. //+--------------------------------------------------------------------------
  147. STDMETHODIMP
  148. CCertEncodeLongArray::GetValue(
  149. /* [in] */ LONG Index,
  150. /* [out, retval] */ LONG __RPC_FAR *pValue)
  151. {
  152. HRESULT hr = S_OK;
  153. BYTE *pb;
  154. if (NULL == pValue)
  155. {
  156. hr = E_POINTER;
  157. ceERRORPRINTLINE("NULL parm", hr);
  158. goto error;
  159. }
  160. if (NULL == m_aValue || Index >= m_cValue)
  161. {
  162. hr = E_INVALIDARG;
  163. ceERRORPRINTLINE("bad parameter", hr);
  164. goto error;
  165. }
  166. // Bitmap only exists when constrcuting!
  167. if (m_fConstructing)
  168. {
  169. pb = (BYTE *) &m_aValue[m_cValue];
  170. if (!GETBIT(pb, Index))
  171. {
  172. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  173. ceERRORPRINTLINE("uninitialized", hr);
  174. goto error;
  175. }
  176. }
  177. *pValue = m_aValue[Index];
  178. error:
  179. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::GetValue"));
  180. }
  181. //+--------------------------------------------------------------------------
  182. // CCertEncodeLongArray::Reset -- clear out data, and set up to encode new data
  183. //
  184. // Returns S_OK on success.
  185. //+--------------------------------------------------------------------------
  186. STDMETHODIMP
  187. CCertEncodeLongArray::Reset(
  188. /* [in] */ LONG Count)
  189. {
  190. HRESULT hr = S_OK;
  191. DWORD cbAlloc;
  192. _Cleanup();
  193. m_fConstructing = TRUE;
  194. if (CENCODEMAX < Count || 0 > Count)
  195. {
  196. hr = E_INVALIDARG;
  197. ceERRORPRINTLINE("bad count parameter", hr);
  198. goto error;
  199. }
  200. cbAlloc = Count * sizeof(m_aValue[0]) + BITSTOBYTES(Count);
  201. m_aValue = (LONG *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbAlloc);
  202. if (NULL == m_aValue)
  203. {
  204. hr = E_OUTOFMEMORY;
  205. ceERRORPRINTLINE("LocalAlloc", hr);
  206. goto error;
  207. }
  208. m_cValue = Count;
  209. error:
  210. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Reset"));
  211. }
  212. //+--------------------------------------------------------------------------
  213. // CCertEncodeLongArray::SetValue -- Set an array long
  214. //
  215. // Returns S_OK on success.
  216. //+--------------------------------------------------------------------------
  217. STDMETHODIMP
  218. CCertEncodeLongArray::SetValue(
  219. /* [in] */ LONG Index,
  220. /* [in] */ LONG Value)
  221. {
  222. HRESULT hr = S_OK;
  223. BYTE *pb;
  224. if (!m_fConstructing ||
  225. NULL == m_aValue ||
  226. Index >= m_cValue ||
  227. m_cValuesSet >= m_cValue)
  228. {
  229. hr = E_INVALIDARG;
  230. ceERRORPRINTLINE("bad parameter", hr);
  231. goto error;
  232. }
  233. pb = (BYTE *) &m_aValue[m_cValue];
  234. if (GETBIT(pb, Index))
  235. {
  236. hr = E_INVALIDARG;
  237. ceERRORPRINTLINE("already set", hr);
  238. goto error;
  239. }
  240. SETBIT(pb, Index);
  241. m_aValue[Index] = Value;
  242. m_cValuesSet++;
  243. error:
  244. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::SetValue"));
  245. }
  246. //+--------------------------------------------------------------------------
  247. // CCertEncodeLongArray::Encode -- Encode LongArray
  248. //
  249. // Returns S_OK on success.
  250. //+--------------------------------------------------------------------------
  251. STDMETHODIMP
  252. CCertEncodeLongArray::Encode(
  253. /* [out, retval] */ BSTR __RPC_FAR *pstrBinary)
  254. {
  255. HRESULT hr = S_OK;
  256. LONG i;
  257. CRYPT_SEQUENCE_OF_ANY Sequence;
  258. BYTE *pbEncoded = NULL;
  259. DWORD cbEncoded;
  260. Sequence.cValue = 0;
  261. Sequence.rgValue = NULL;
  262. if (NULL == pstrBinary)
  263. {
  264. hr = E_POINTER;
  265. ceERRORPRINTLINE("NULL parm", hr);
  266. goto error;
  267. }
  268. ceFreeBstr(pstrBinary);
  269. if (!m_fConstructing || NULL == m_aValue)
  270. {
  271. hr = E_INVALIDARG;
  272. ceERRORPRINTLINE("bad parameter", hr);
  273. goto error;
  274. }
  275. if (m_cValuesSet != m_cValue)
  276. {
  277. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  278. ceERRORPRINTLINE("m_cValuesSet", hr);
  279. goto error;
  280. }
  281. Sequence.rgValue = (CRYPT_DER_BLOB *) LocalAlloc(
  282. LMEM_FIXED,
  283. m_cValue * sizeof(Sequence.rgValue[0]));
  284. if (NULL == Sequence.rgValue)
  285. {
  286. hr = E_OUTOFMEMORY;
  287. ceERRORPRINTLINE("LocalAlloc", hr);
  288. goto error;
  289. }
  290. for (i = 0; i < m_cValue; i++)
  291. {
  292. // Encode each integer into an ASN blob:
  293. if (!ceEncodeObject(
  294. X509_ASN_ENCODING,
  295. X509_INTEGER,
  296. &m_aValue[i],
  297. 0,
  298. FALSE,
  299. &Sequence.rgValue[i].pbData,
  300. &Sequence.rgValue[i].cbData))
  301. {
  302. hr = ceHLastError();
  303. ceERRORPRINTLINE("ceEncodeObject", hr);
  304. goto error;
  305. }
  306. Sequence.cValue++;
  307. }
  308. assert((LONG) Sequence.cValue == m_cValue);
  309. // Encode each integer into an ASN blob:
  310. if (!ceEncodeObject(
  311. X509_ASN_ENCODING,
  312. X509_SEQUENCE_OF_ANY,
  313. &Sequence,
  314. 0,
  315. FALSE,
  316. &pbEncoded,
  317. &cbEncoded))
  318. {
  319. hr = ceHLastError();
  320. ceERRORPRINTLINE("ceEncodeObject", hr);
  321. goto error;
  322. }
  323. if (!ceConvertWszToBstr(
  324. pstrBinary,
  325. (WCHAR const *) pbEncoded,
  326. cbEncoded))
  327. {
  328. hr = E_OUTOFMEMORY;
  329. ceERRORPRINTLINE("ceConvertWszToBstr", hr);
  330. goto error;
  331. }
  332. error:
  333. if (NULL != pbEncoded)
  334. {
  335. LocalFree(pbEncoded);
  336. }
  337. if (NULL != Sequence.rgValue)
  338. {
  339. assert((LONG) Sequence.cValue <= m_cValue);
  340. for (i = 0; i < (LONG) Sequence.cValue; i++)
  341. {
  342. assert(NULL != Sequence.rgValue[i].pbData);
  343. LocalFree(Sequence.rgValue[i].pbData);
  344. }
  345. LocalFree(Sequence.rgValue);
  346. }
  347. return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Encode"));
  348. }
  349. //+--------------------------------------------------------------------------
  350. // CCertEncodeLongArray::_SetErrorInfo -- set error object information
  351. //
  352. // Returns passed HRESULT
  353. //+--------------------------------------------------------------------------
  354. HRESULT
  355. CCertEncodeLongArray::_SetErrorInfo(
  356. IN HRESULT hrError,
  357. IN WCHAR const *pwszDescription)
  358. {
  359. assert(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
  360. if (FAILED(hrError))
  361. {
  362. HRESULT hr;
  363. hr = ceDispatchSetErrorInfo(
  364. hrError,
  365. pwszDescription,
  366. wszCLASS_CERTENCODELONGARRAY,
  367. &IID_ICertEncodeLongArray);
  368. assert(hr == hrError);
  369. }
  370. return(hrError);
  371. }