Leaked source code of windows server 2003
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.

686 lines
16 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: Qualifier.cpp
  4. Content: Implementation of CQualifier.
  5. History: 06-15-2001 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "Qualifier.h"
  10. #include "Common.h"
  11. #include "Convert.h"
  12. #include "NoticeNumbers.h"
  13. #include "OID.h"
  14. ////////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Exported functions.
  17. //
  18. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  19. Function : CreateQualifierObject
  20. Synopsis : Create and initialize an CQualifier object.
  21. Parameter: PCERT_POLICY_QUALIFIER_INFO pQualifier - Pointer to qualifier.
  22. IQualifier ** ppIQualifier - Pointer to pointer IQualifier object.
  23. Remark :
  24. ------------------------------------------------------------------------------*/
  25. HRESULT CreateQualifierObject (PCERT_POLICY_QUALIFIER_INFO pQualifier,
  26. IQualifier ** ppIQualifier)
  27. {
  28. HRESULT hr = S_OK;
  29. CComObject<CQualifier> * pCQualifier = NULL;
  30. DebugTrace("Entering CreateQualifierObject().\n");
  31. //
  32. // Sanity check.
  33. //
  34. ATLASSERT(pQualifier);
  35. ATLASSERT(ppIQualifier);
  36. try
  37. {
  38. //
  39. // Create the object. Note that the ref count will still be 0
  40. // after the object is created.
  41. //
  42. if (FAILED(hr = CComObject<CQualifier>::CreateInstance(&pCQualifier)))
  43. {
  44. DebugTrace("Error [%#x]: CComObject<CQualifier>::CreateInstance() failed.\n", hr);
  45. goto ErrorExit;
  46. }
  47. //
  48. // Initialize object.
  49. //
  50. if (FAILED(hr = pCQualifier->Init(pQualifier)))
  51. {
  52. DebugTrace("Error [%#x]: pCQualifier->Init() failed.\n", hr);
  53. goto ErrorExit;
  54. }
  55. //
  56. // Return interface pointer to caller.
  57. //
  58. if (FAILED(hr = pCQualifier->QueryInterface(ppIQualifier)))
  59. {
  60. DebugTrace("Error [%#x]: pCQualifier->QueryInterface() failed.\n", hr);
  61. goto ErrorExit;
  62. }
  63. }
  64. catch(...)
  65. {
  66. hr = E_POINTER;
  67. DebugTrace("Exception: invalid parameter.\n");
  68. goto ErrorExit;
  69. }
  70. CommonExit:
  71. DebugTrace("Leaving CreateQualifierObject().\n");
  72. return hr;
  73. ErrorExit:
  74. //
  75. // Sanity check.
  76. //
  77. ATLASSERT(FAILED(hr));
  78. if (pCQualifier)
  79. {
  80. delete pCQualifier;
  81. }
  82. goto CommonExit;
  83. }
  84. ////////////////////////////////////////////////////////////////////////////////
  85. //
  86. // CQualifier
  87. //
  88. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89. Function : CQualifier::get_OID
  90. Synopsis :Return the OID object.
  91. Parameter: IOID ** pVal - Pointer to pointer to IOID to receive the interface
  92. pointer.
  93. Remark :
  94. ------------------------------------------------------------------------------*/
  95. STDMETHODIMP CQualifier:: get_OID (IOID ** pVal)
  96. {
  97. HRESULT hr = S_OK;
  98. DebugTrace("Entering CQualifier::get_OID().\n");
  99. try
  100. {
  101. //
  102. // Lock access to this object.
  103. //
  104. m_Lock.Lock();
  105. //
  106. // Check parameters.
  107. //
  108. if (NULL == pVal)
  109. {
  110. hr = E_INVALIDARG;
  111. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  112. goto ErrorExit;
  113. }
  114. //
  115. // Sanity check.
  116. //
  117. ATLASSERT(m_pIOID);
  118. //
  119. // Return result.
  120. //
  121. if (FAILED(hr = m_pIOID->QueryInterface(pVal)))
  122. {
  123. DebugTrace("Error [%#x]: m_pIOID->QueryInterface() failed.\n", hr);
  124. goto ErrorExit;
  125. }
  126. }
  127. catch(...)
  128. {
  129. hr = E_POINTER;
  130. DebugTrace("Exception: invalid parameter.\n");
  131. goto ErrorExit;
  132. }
  133. UnlockExit:
  134. //
  135. // Unlock access to this object.
  136. //
  137. m_Lock.Unlock();
  138. DebugTrace("Leaving CQualifier::get_OID().\n");
  139. return hr;
  140. ErrorExit:
  141. //
  142. // Sanity check.
  143. //
  144. ATLASSERT(FAILED(hr));
  145. ReportError(hr);
  146. goto UnlockExit;
  147. }
  148. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  149. Function : CQualifier::get_CPSPointer
  150. Synopsis : Return the URI of the CPS.
  151. Parameter: BSTR * pVal - Pointer to BSTR to receive the value.
  152. Remark :
  153. ------------------------------------------------------------------------------*/
  154. STDMETHODIMP CQualifier::get_CPSPointer (BSTR * pVal)
  155. {
  156. HRESULT hr = S_OK;
  157. DebugTrace("Entering CQualifier::get_CPSPointer().\n");
  158. try
  159. {
  160. //
  161. // Lock access to this object.
  162. //
  163. m_Lock.Lock();
  164. //
  165. // Check parameters.
  166. //
  167. if (NULL == pVal)
  168. {
  169. hr = E_INVALIDARG;
  170. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  171. goto ErrorExit;
  172. }
  173. //
  174. // Return result.
  175. //
  176. if (FAILED(hr = m_bstrCPSPointer.CopyTo(pVal)))
  177. {
  178. DebugTrace("Error [%#x]: m_bstrCPSPointer.CopyTo() failed.\n", hr);
  179. goto ErrorExit;
  180. }
  181. }
  182. catch(...)
  183. {
  184. hr = E_POINTER;
  185. DebugTrace("Exception: invalid parameter.\n");
  186. goto ErrorExit;
  187. }
  188. UnlockExit:
  189. //
  190. // Unlock access to this object.
  191. //
  192. m_Lock.Unlock();
  193. DebugTrace("Leaving CQualifier::get_CPSPointer().\n");
  194. return hr;
  195. ErrorExit:
  196. //
  197. // Sanity check.
  198. //
  199. ATLASSERT(FAILED(hr));
  200. ReportError(hr);
  201. goto UnlockExit;
  202. }
  203. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  204. Function : CQualifier::get_OrganizationName
  205. Synopsis : Return the organization name.
  206. Parameter: BSTR * pVal - Pointer to BSTR to receive the value.
  207. Remark :
  208. ------------------------------------------------------------------------------*/
  209. STDMETHODIMP CQualifier::get_OrganizationName (BSTR * pVal)
  210. {
  211. HRESULT hr = S_OK;
  212. DebugTrace("Entering CQualifier::get_OrganizationName().\n");
  213. try
  214. {
  215. //
  216. // Lock access to this object.
  217. //
  218. m_Lock.Lock();
  219. //
  220. // Check parameters.
  221. //
  222. if (NULL == pVal)
  223. {
  224. hr = E_INVALIDARG;
  225. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  226. goto ErrorExit;
  227. }
  228. //
  229. // Return result.
  230. //
  231. if (FAILED(hr = m_bstrOrganizationName.CopyTo(pVal)))
  232. {
  233. DebugTrace("Error [%#x]: m_bstrOrganizationName.CopyTo() failed.\n", hr);
  234. goto ErrorExit;
  235. }
  236. }
  237. catch(...)
  238. {
  239. hr = E_POINTER;
  240. DebugTrace("Exception: invalid parameter.\n");
  241. goto ErrorExit;
  242. }
  243. UnlockExit:
  244. //
  245. // Unlock access to this object.
  246. //
  247. m_Lock.Unlock();
  248. DebugTrace("Leaving CQualifier::get_OrganizationName().\n");
  249. return hr;
  250. ErrorExit:
  251. //
  252. // Sanity check.
  253. //
  254. ATLASSERT(FAILED(hr));
  255. ReportError(hr);
  256. goto UnlockExit;
  257. }
  258. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  259. Function : CQualifier::get_NoticeNumbers
  260. Synopsis : Return the notice number collection object.
  261. Parameter: INoticeNumbers ** pVal - Pointer to pointer to INoticeNumbers to
  262. to receive the interfcae pointer.
  263. Remark :
  264. ------------------------------------------------------------------------------*/
  265. STDMETHODIMP CQualifier::get_NoticeNumbers (INoticeNumbers ** pVal)
  266. {
  267. HRESULT hr = S_OK;
  268. DebugTrace("Entering CQualifier::get_NoticeNumbers().\n");
  269. try
  270. {
  271. //
  272. // Lock access to this object.
  273. //
  274. m_Lock.Lock();
  275. //
  276. // Check parameters.
  277. //
  278. if (NULL == pVal)
  279. {
  280. hr = E_INVALIDARG;
  281. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  282. goto ErrorExit;
  283. }
  284. //
  285. // Return result.
  286. //
  287. if (m_pINoticeNumbers)
  288. {
  289. if (FAILED(hr = m_pINoticeNumbers->QueryInterface(pVal)))
  290. {
  291. DebugTrace("Error [%#x]: m_pINoticeNumbers->QueryInterface() failed.\n", hr);
  292. goto ErrorExit;
  293. }
  294. }
  295. else
  296. {
  297. *pVal = (INoticeNumbers *) NULL;
  298. }
  299. }
  300. catch(...)
  301. {
  302. hr = E_POINTER;
  303. DebugTrace("Exception: invalid parameter.\n");
  304. goto ErrorExit;
  305. }
  306. UnlockExit:
  307. //
  308. // Unlock access to this object.
  309. //
  310. m_Lock.Unlock();
  311. DebugTrace("Leaving CQualifier::get_NoticeNumbers().\n");
  312. return hr;
  313. ErrorExit:
  314. //
  315. // Sanity check.
  316. //
  317. ATLASSERT(FAILED(hr));
  318. ReportError(hr);
  319. goto UnlockExit;
  320. }
  321. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  322. Function : CQualifier::get_ExplicitText
  323. Synopsis : Return the explicit text.
  324. Parameter: BSTR * pVal - Pointer to BSTR to receive the value.
  325. Remark :
  326. ------------------------------------------------------------------------------*/
  327. STDMETHODIMP CQualifier::get_ExplicitText (BSTR * pVal)
  328. {
  329. HRESULT hr = S_OK;
  330. DebugTrace("Entering CQualifier::get_ExplicitText().\n");
  331. try
  332. {
  333. //
  334. // Lock access to this object.
  335. //
  336. m_Lock.Lock();
  337. //
  338. // Check parameters.
  339. //
  340. if (NULL == pVal)
  341. {
  342. hr = E_INVALIDARG;
  343. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  344. goto ErrorExit;
  345. }
  346. //
  347. // Return result.
  348. //
  349. if (FAILED(hr = m_bstrExplicitText.CopyTo(pVal)))
  350. {
  351. DebugTrace("Error [%#x]: m_bstrExplicitText.CopyTo() failed.\n", hr);
  352. goto ErrorExit;
  353. }
  354. }
  355. catch(...)
  356. {
  357. hr = E_POINTER;
  358. DebugTrace("Exception: invalid parameter.\n");
  359. goto ErrorExit;
  360. }
  361. UnlockExit:
  362. //
  363. // Unlock access to this object.
  364. //
  365. m_Lock.Unlock();
  366. DebugTrace("Leaving CQualifier::get_ExplicitText().\n");
  367. return hr;
  368. ErrorExit:
  369. //
  370. // Sanity check.
  371. //
  372. ATLASSERT(FAILED(hr));
  373. ReportError(hr);
  374. goto UnlockExit;
  375. }
  376. ////////////////////////////////////////////////////////////////////////////////
  377. //
  378. // Private methods.
  379. //
  380. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  381. Function : CQualifier::Init
  382. Synopsis : Initialize the object.
  383. Parameter: PCERT_POLICY_QUALIFIER_INFO pQualifier - Pointer to qualifier.
  384. Remark : This method is not part of the COM interface (it is a normal C++
  385. member function). We need it to initialize the object created
  386. internally by us.
  387. Since it is only a normal C++ member function, this function can
  388. only be called from a C++ class pointer, not an interface pointer.
  389. ------------------------------------------------------------------------------*/
  390. STDMETHODIMP CQualifier::Init (PCERT_POLICY_QUALIFIER_INFO pQualifier)
  391. {
  392. HRESULT hr = S_OK;
  393. DATA_BLOB DataBlob = {0, NULL};
  394. DebugTrace("Entering CQualifier::Init().\n");
  395. //
  396. // Sanity check.
  397. //
  398. ATLASSERT(pQualifier);
  399. //
  400. // Create the embeded OID object.
  401. //
  402. if (FAILED(hr = ::CreateOIDObject(pQualifier->pszPolicyQualifierId, TRUE, &m_pIOID)))
  403. {
  404. DebugTrace("Error [%#x]: CreateOIDObject() failed.\n", hr);
  405. goto ErrorExit;
  406. }
  407. //
  408. // What type of qualifier?
  409. //
  410. if (0 == ::strcmp(szOID_PKIX_POLICY_QUALIFIER_CPS,
  411. pQualifier->pszPolicyQualifierId))
  412. {
  413. PCERT_NAME_VALUE pCertNameValue;
  414. //
  415. // CPS string.
  416. //
  417. if (FAILED(hr = ::DecodeObject(X509_UNICODE_ANY_STRING,
  418. pQualifier->Qualifier.pbData,
  419. pQualifier->Qualifier.cbData,
  420. &DataBlob)))
  421. {
  422. DebugTrace("Error [%#x]: DecodeObject() failed.\n", hr);
  423. goto ErrorExit;
  424. }
  425. pCertNameValue = (PCERT_NAME_VALUE) DataBlob.pbData;
  426. if (!(m_bstrCPSPointer = (LPWSTR) pCertNameValue->Value.pbData))
  427. {
  428. hr = E_OUTOFMEMORY;
  429. DebugTrace("Error [%#x]: m_bstrCPSPointer = (LPWSTR) pCertNameValue->Value.pbData failed.\n", hr);
  430. goto ErrorExit;
  431. }
  432. }
  433. else if (0 == ::strcmp(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,
  434. pQualifier->pszPolicyQualifierId))
  435. {
  436. PCERT_POLICY_QUALIFIER_USER_NOTICE pUserNotice;
  437. //
  438. // User Notice.
  439. //
  440. if (FAILED(hr = ::DecodeObject(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,
  441. pQualifier->Qualifier.pbData,
  442. pQualifier->Qualifier.cbData,
  443. &DataBlob)))
  444. {
  445. DebugTrace("Error [%#x]: DecodeObject() failed.\n", hr);
  446. goto ErrorExit;
  447. }
  448. pUserNotice = (PCERT_POLICY_QUALIFIER_USER_NOTICE) DataBlob.pbData;
  449. //
  450. // Do we have notice reference?
  451. //
  452. if (pUserNotice->pNoticeReference)
  453. {
  454. //
  455. // Any organization name?
  456. //
  457. if (pUserNotice->pNoticeReference->pszOrganization)
  458. {
  459. if (!(m_bstrOrganizationName = pUserNotice->pNoticeReference->pszOrganization))
  460. {
  461. hr = E_OUTOFMEMORY;
  462. DebugTrace("Error [%#x]: m_bstrOrganizationName = pUserNotice->pNoticeReference->pszOrganization failed.\n", hr);
  463. goto ErrorExit;
  464. }
  465. }
  466. //
  467. // Any notice number?
  468. //
  469. if (pUserNotice->pNoticeReference->cNoticeNumbers)
  470. {
  471. if (FAILED(hr = ::CreateNoticeNumbersObject(pUserNotice->pNoticeReference,
  472. &m_pINoticeNumbers)))
  473. {
  474. DebugTrace("Error [%#x]: CreateNoticeNumbersObject() failed.\n", hr);
  475. goto ErrorExit;
  476. }
  477. }
  478. }
  479. //
  480. // Do we have explicit display text?
  481. //
  482. if (pUserNotice->pszDisplayText)
  483. {
  484. if (!(m_bstrExplicitText = pUserNotice->pszDisplayText))
  485. {
  486. hr = E_OUTOFMEMORY;
  487. DebugTrace("Error [%#x]: m_bstrExplicitText = pUserNotice->pszDisplayText failed.\n", hr);
  488. goto ErrorExit;
  489. }
  490. }
  491. }
  492. else
  493. {
  494. DebugTrace("Info: Policy Qualifier (%s) is not recognized.\n", pQualifier->pszPolicyQualifierId);
  495. }
  496. CommonExit:
  497. //
  498. // Free resources.
  499. //
  500. if (DataBlob.pbData)
  501. {
  502. ::CoTaskMemFree(DataBlob.pbData);
  503. }
  504. DebugTrace("Leaving CQualifier::Init().\n");
  505. return hr;
  506. ErrorExit:
  507. //
  508. // Sanity check.
  509. //
  510. ATLASSERT(FAILED(hr));
  511. //
  512. // Free resources.
  513. //
  514. if (m_pIOID)
  515. {
  516. m_pIOID.Release();
  517. }
  518. if (m_pINoticeNumbers)
  519. {
  520. m_pINoticeNumbers.Release();
  521. }
  522. m_bstrCPSPointer.Empty();
  523. m_bstrOrganizationName.Empty();
  524. m_bstrExplicitText.Empty();
  525. goto CommonExit;
  526. }