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.

558 lines
12 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: astring.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 "astring.h"
  16. #include "celib.h"
  17. //+--------------------------------------------------------------------------
  18. // CCertEncodeStringArray::~CCertEncodeStringArray -- destructor
  19. //
  20. // free memory associated with this instance
  21. //+--------------------------------------------------------------------------
  22. CCertEncodeStringArray::~CCertEncodeStringArray()
  23. {
  24. _Cleanup();
  25. }
  26. //+--------------------------------------------------------------------------
  27. // CCertEncodeStringArray::_Cleanup -- release all resources
  28. //
  29. // free memory associated with this instance
  30. //+--------------------------------------------------------------------------
  31. VOID
  32. CCertEncodeStringArray::_Cleanup()
  33. {
  34. LONG i;
  35. if (NULL != m_aValue)
  36. {
  37. for (i = 0; i < m_cValue; i++)
  38. {
  39. CERT_NAME_VALUE *pNameValue;
  40. pNameValue = m_aValue[i];
  41. assert(NULL != pNameValue);
  42. if (m_fConstructing)
  43. {
  44. if (NULL != pNameValue->Value.pbData)
  45. {
  46. LocalFree(pNameValue->Value.pbData);
  47. }
  48. }
  49. else
  50. {
  51. LocalFree(pNameValue);
  52. }
  53. }
  54. if (m_fConstructing && NULL != m_aValue[0])
  55. {
  56. LocalFree(m_aValue[0]);
  57. }
  58. LocalFree(m_aValue);
  59. m_aValue = NULL;
  60. }
  61. m_cValue = 0;
  62. m_cValuesSet = 0;
  63. m_fConstructing = FALSE;
  64. m_StringType = CERT_RDN_IA5_STRING;
  65. }
  66. //+--------------------------------------------------------------------------
  67. // CCertEncodeStringArray::Decode -- Decode StringArray
  68. //
  69. // Returns S_OK on success.
  70. //+--------------------------------------------------------------------------
  71. STDMETHODIMP
  72. CCertEncodeStringArray::Decode(
  73. /* [in] */ BSTR const strBinary)
  74. {
  75. HRESULT hr = S_OK;
  76. CRYPT_SEQUENCE_OF_ANY *pSequence = NULL;
  77. DWORD cbSequence;
  78. LONG i;
  79. _Cleanup();
  80. if (NULL == strBinary)
  81. {
  82. hr = E_POINTER;
  83. ceERRORPRINTLINE("NULL parm", hr);
  84. goto error;
  85. }
  86. // Decode to an array of ASN blobs:
  87. if (!ceDecodeObject(
  88. X509_ASN_ENCODING,
  89. X509_SEQUENCE_OF_ANY,
  90. (BYTE *) strBinary,
  91. SysStringByteLen(strBinary),
  92. FALSE,
  93. (VOID **) &pSequence,
  94. &cbSequence))
  95. {
  96. hr = ceHLastError();
  97. ceERRORPRINTLINE("ceDecodeObject", hr);
  98. goto error;
  99. }
  100. m_aValue = (CERT_NAME_VALUE **) LocalAlloc(
  101. LMEM_FIXED,
  102. pSequence->cValue * sizeof(m_aValue[0]));
  103. if (NULL == m_aValue)
  104. {
  105. hr = E_OUTOFMEMORY;
  106. ceERRORPRINTLINE("LocalAlloc", hr);
  107. goto error;
  108. }
  109. for (i = 0; i < (LONG) pSequence->cValue; i++)
  110. {
  111. DWORD cb;
  112. // Decode each ASN blob to a name value (string blob + encoding type):
  113. if (!ceDecodeObject(
  114. X509_ASN_ENCODING,
  115. X509_UNICODE_ANY_STRING,
  116. pSequence->rgValue[i].pbData,
  117. pSequence->rgValue[i].cbData,
  118. FALSE,
  119. (VOID **) &m_aValue[i],
  120. &cb))
  121. {
  122. hr = ceHLastError();
  123. ceERRORPRINTLINE("ceDecodeObject", hr);
  124. goto error;
  125. }
  126. if (0 == i)
  127. {
  128. m_StringType = m_aValue[i]->dwValueType;
  129. }
  130. else
  131. {
  132. if (m_StringType != (LONG) m_aValue[i]->dwValueType)
  133. {
  134. ceERRORPRINTLINE("dwValueType mismatch", hr);
  135. }
  136. }
  137. m_cValue++;
  138. }
  139. assert((LONG) pSequence->cValue == m_cValue);
  140. error:
  141. if (NULL != pSequence)
  142. {
  143. LocalFree(pSequence);
  144. }
  145. if (S_OK != hr)
  146. {
  147. _Cleanup();
  148. }
  149. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::Decode"));
  150. }
  151. //+--------------------------------------------------------------------------
  152. // CCertEncodeStringArray::GetStringType -- Get string type
  153. //
  154. // Returns S_OK on success.
  155. //+--------------------------------------------------------------------------
  156. STDMETHODIMP
  157. CCertEncodeStringArray::GetStringType(
  158. /* [out, retval] */ LONG __RPC_FAR *pStringType)
  159. {
  160. HRESULT hr = S_OK;
  161. if (NULL == pStringType)
  162. {
  163. hr = E_POINTER;
  164. ceERRORPRINTLINE("NULL parm", hr);
  165. goto error;
  166. }
  167. if (NULL == m_aValue)
  168. {
  169. hr = E_INVALIDARG;
  170. ceERRORPRINTLINE("bad parameter", hr);
  171. goto error;
  172. }
  173. *pStringType = m_StringType;
  174. error:
  175. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::GetStringType"));
  176. }
  177. //+--------------------------------------------------------------------------
  178. // CCertEncodeStringArray::GetCount -- Get Array count
  179. //
  180. // Returns S_OK on success.
  181. //+--------------------------------------------------------------------------
  182. STDMETHODIMP
  183. CCertEncodeStringArray::GetCount(
  184. /* [out, retval] */ LONG __RPC_FAR *pCount)
  185. {
  186. HRESULT hr = S_OK;
  187. if (NULL == pCount)
  188. {
  189. hr = E_POINTER;
  190. ceERRORPRINTLINE("NULL parm", hr);
  191. goto error;
  192. }
  193. if (NULL == m_aValue)
  194. {
  195. hr = E_INVALIDARG;
  196. ceERRORPRINTLINE("bad parameter", hr);
  197. goto error;
  198. }
  199. *pCount = m_cValue;
  200. error:
  201. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::GetCount"));
  202. }
  203. //+--------------------------------------------------------------------------
  204. // CCertEncodeStringArray::GetValue -- Fetch the indexed string
  205. //
  206. // Returns S_OK on success.
  207. //+--------------------------------------------------------------------------
  208. STDMETHODIMP
  209. CCertEncodeStringArray::GetValue(
  210. /* [in] */ LONG Index,
  211. /* [out, retval] */ BSTR __RPC_FAR *pstr)
  212. {
  213. HRESULT hr = S_OK;
  214. if (NULL == pstr)
  215. {
  216. hr = E_POINTER;
  217. ceERRORPRINTLINE("NULL parm", hr);
  218. goto error;
  219. }
  220. ceFreeBstr(pstr);
  221. if (NULL == m_aValue || Index >= m_cValue)
  222. {
  223. hr = E_INVALIDARG;
  224. ceERRORPRINTLINE("bad parameter", hr);
  225. goto error;
  226. }
  227. if (NULL == m_aValue[Index]->Value.pbData)
  228. {
  229. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  230. ceERRORPRINTLINE("uninitialized", hr);
  231. goto error;
  232. }
  233. if (!ceConvertWszToBstr(
  234. pstr,
  235. (WCHAR const *) m_aValue[Index]->Value.pbData,
  236. -1))
  237. {
  238. hr = E_OUTOFMEMORY;
  239. ceERRORPRINTLINE("ceConvertWszToBstr", hr);
  240. goto error;
  241. }
  242. error:
  243. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::GetValue"));
  244. }
  245. //+--------------------------------------------------------------------------
  246. // CCertEncodeStringArray::Reset -- clear out data
  247. //
  248. // Returns S_OK on success.
  249. //+--------------------------------------------------------------------------
  250. STDMETHODIMP
  251. CCertEncodeStringArray::Reset(
  252. /* [in] */ LONG Count,
  253. /* [in] */ LONG StringType)
  254. {
  255. HRESULT hr = S_OK;
  256. CERT_NAME_VALUE *aNameValue = NULL;
  257. LONG i;
  258. _Cleanup();
  259. m_fConstructing = TRUE;
  260. if (CENCODEMAX < Count || 0 > Count)
  261. {
  262. hr = E_INVALIDARG;
  263. ceERRORPRINTLINE("bad count parameter", hr);
  264. goto error;
  265. }
  266. switch (StringType)
  267. {
  268. case CERT_RDN_ANY_TYPE:
  269. //case CERT_RDN_ENCODED_BLOB:
  270. //case CERT_RDN_OCTET_STRING:
  271. case CERT_RDN_NUMERIC_STRING:
  272. case CERT_RDN_PRINTABLE_STRING:
  273. //case CERT_RDN_TELETEX_STRING: same as CERT_RDN_T61_STRING:
  274. case CERT_RDN_T61_STRING:
  275. case CERT_RDN_VIDEOTEX_STRING:
  276. case CERT_RDN_IA5_STRING:
  277. case CERT_RDN_GRAPHIC_STRING:
  278. //case CERT_RDN_VISIBLE_STRING: same as CERT_RDN_ISO646_STRING:
  279. case CERT_RDN_ISO646_STRING:
  280. case CERT_RDN_GENERAL_STRING:
  281. //case CERT_RDN_UNIVERSAL_STRING: same as CERT_RDN_INT4_STRING:
  282. case CERT_RDN_INT4_STRING:
  283. //case CERT_RDN_BMP_STRING: same as case CERT_RDN_UNICODE_STRING:
  284. case CERT_RDN_UNICODE_STRING:
  285. break;
  286. default:
  287. hr = E_INVALIDARG;
  288. ceERRORPRINTLINE("bad parameter", hr);
  289. goto error;
  290. }
  291. m_StringType = StringType;
  292. aNameValue = (CERT_NAME_VALUE *) LocalAlloc(
  293. LMEM_FIXED | LMEM_ZEROINIT,
  294. Count * sizeof(*m_aValue[0]));
  295. if (NULL == aNameValue)
  296. {
  297. hr = E_OUTOFMEMORY;
  298. ceERRORPRINTLINE("LocalAlloc", hr);
  299. goto error;
  300. }
  301. m_aValue = (CERT_NAME_VALUE **) LocalAlloc(
  302. LMEM_FIXED,
  303. Count * sizeof(m_aValue[0]));
  304. if (NULL == m_aValue)
  305. {
  306. hr = E_OUTOFMEMORY;
  307. ceERRORPRINTLINE("LocalAlloc", hr);
  308. goto error;
  309. }
  310. m_cValue = Count;
  311. for (i = 0; i < Count; i++)
  312. {
  313. m_aValue[i] = &aNameValue[i];
  314. }
  315. aNameValue = NULL;
  316. error:
  317. if (NULL != aNameValue)
  318. {
  319. LocalFree(aNameValue);
  320. }
  321. if (S_OK != hr)
  322. {
  323. _Cleanup();
  324. }
  325. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::Reset"));
  326. }
  327. //+--------------------------------------------------------------------------
  328. // CCertEncodeStringArray::SetValue -- Set an array string
  329. //
  330. // Returns S_OK on success.
  331. //+--------------------------------------------------------------------------
  332. STDMETHODIMP
  333. CCertEncodeStringArray::SetValue(
  334. /* [in] */ LONG Index,
  335. /* [in] */ BSTR const str)
  336. {
  337. HRESULT hr = S_OK;
  338. WCHAR *pwsz;
  339. if (NULL == str)
  340. {
  341. hr = E_POINTER;
  342. ceERRORPRINTLINE("NULL parm", hr);
  343. goto error;
  344. }
  345. if (!m_fConstructing ||
  346. NULL == m_aValue ||
  347. Index >= m_cValue ||
  348. m_cValuesSet >= m_cValue ||
  349. NULL != m_aValue[Index]->Value.pbData)
  350. {
  351. hr = E_INVALIDARG;
  352. ceERRORPRINTLINE("bad parameter", hr);
  353. goto error;
  354. }
  355. pwsz = ceDuplicateString(str);
  356. if (NULL == pwsz)
  357. {
  358. hr = E_OUTOFMEMORY;
  359. ceERRORPRINTLINE("ceDuplicateString", hr);
  360. goto error;
  361. }
  362. m_aValue[Index]->dwValueType = m_StringType;
  363. m_aValue[Index]->Value.pbData = (BYTE *) pwsz;
  364. m_aValue[Index]->Value.cbData = 0;
  365. m_cValuesSet++;
  366. error:
  367. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::SetValue"));
  368. }
  369. //+--------------------------------------------------------------------------
  370. // CCertEncodeStringArray::Encode -- Encode StringArray
  371. //
  372. // Returns S_OK on success.
  373. //+--------------------------------------------------------------------------
  374. STDMETHODIMP
  375. CCertEncodeStringArray::Encode(
  376. /* [out, retval] */ BSTR __RPC_FAR *pstrBinary)
  377. {
  378. HRESULT hr = S_OK;
  379. LONG i;
  380. CRYPT_SEQUENCE_OF_ANY Sequence;
  381. BYTE *pbEncoded = NULL;
  382. DWORD cbEncoded;
  383. Sequence.cValue = 0;
  384. Sequence.rgValue = NULL;
  385. if (NULL == pstrBinary)
  386. {
  387. hr = E_POINTER;
  388. ceERRORPRINTLINE("NULL parm", hr);
  389. goto error;
  390. }
  391. ceFreeBstr(pstrBinary);
  392. if (!m_fConstructing || NULL == m_aValue)
  393. {
  394. hr = E_INVALIDARG;
  395. ceERRORPRINTLINE("bad parameter", hr);
  396. goto error;
  397. }
  398. if (m_cValuesSet != m_cValue)
  399. {
  400. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  401. ceERRORPRINTLINE("uninitialized values", hr);
  402. goto error;
  403. }
  404. Sequence.rgValue = (CRYPT_DER_BLOB *) LocalAlloc(
  405. LMEM_FIXED,
  406. m_cValue * sizeof(Sequence.rgValue[0]));
  407. if (NULL == Sequence.rgValue)
  408. {
  409. hr = E_OUTOFMEMORY;
  410. ceERRORPRINTLINE("LocalAlloc", hr);
  411. goto error;
  412. }
  413. for (i = 0; i < m_cValue; i++)
  414. {
  415. // Encode each name blob into an ASN blob:
  416. if (!ceEncodeObject(
  417. X509_ASN_ENCODING,
  418. X509_UNICODE_ANY_STRING,
  419. m_aValue[i],
  420. 0,
  421. FALSE,
  422. &Sequence.rgValue[i].pbData,
  423. &Sequence.rgValue[i].cbData))
  424. {
  425. hr = ceHLastError();
  426. ceERRORPRINTLINE("ceEncodeObject", hr);
  427. goto error;
  428. }
  429. Sequence.cValue++;
  430. }
  431. assert((LONG) Sequence.cValue == m_cValue);
  432. // Encode the array of ASN blob:
  433. if (!ceEncodeObject(
  434. X509_ASN_ENCODING,
  435. X509_SEQUENCE_OF_ANY,
  436. &Sequence,
  437. 0,
  438. FALSE,
  439. &pbEncoded,
  440. &cbEncoded))
  441. {
  442. hr = ceHLastError();
  443. ceERRORPRINTLINE("ceEncodeObject", hr);
  444. goto error;
  445. }
  446. if (!ceConvertWszToBstr(
  447. pstrBinary,
  448. (WCHAR const *) pbEncoded,
  449. cbEncoded))
  450. {
  451. hr = E_OUTOFMEMORY;
  452. ceERRORPRINTLINE("ceConvertWszToBstr", hr);
  453. goto error;
  454. }
  455. error:
  456. if (NULL != pbEncoded)
  457. {
  458. LocalFree(pbEncoded);
  459. }
  460. if (NULL != Sequence.rgValue)
  461. {
  462. assert((LONG) Sequence.cValue <= m_cValue);
  463. for (i = 0; i < (LONG) Sequence.cValue; i++)
  464. {
  465. assert(NULL != Sequence.rgValue[i].pbData);
  466. LocalFree(Sequence.rgValue[i].pbData);
  467. }
  468. LocalFree(Sequence.rgValue);
  469. }
  470. return(_SetErrorInfo(hr, L"CCertEncodeStringArray::Encode"));
  471. }
  472. //+--------------------------------------------------------------------------
  473. // CCertEncodeStringArray::_SetErrorInfo -- set error object information
  474. //
  475. // Returns passed HRESULT
  476. //+--------------------------------------------------------------------------
  477. HRESULT
  478. CCertEncodeStringArray::_SetErrorInfo(
  479. IN HRESULT hrError,
  480. IN WCHAR const *pwszDescription)
  481. {
  482. assert(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
  483. if (FAILED(hrError))
  484. {
  485. HRESULT hr;
  486. hr = ceDispatchSetErrorInfo(
  487. hrError,
  488. pwszDescription,
  489. wszCLASS_CERTENCODESTRINGARRAY,
  490. &IID_ICertEncodeStringArray);
  491. assert(hr == hrError);
  492. }
  493. return(hrError);
  494. }