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.

435 lines
9.4 KiB

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