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.

581 lines
13 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: BasicConstraints.cpp
  4. Content: Implementation of CBasicConstraints.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "BasicConstraints.h"
  10. #include "Common.h"
  11. ////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Exported functions.
  14. //
  15. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  16. Function : CreateBasicConstraintsObject
  17. Synopsis : Create a IBasicConstraints object and populate the porperties with
  18. data from the key usage extension of the specified certificate.
  19. Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
  20. IBasicConstraints ** ppIBasicConstraints - Pointer to pointer
  21. IBasicConstraints
  22. object.
  23. Remark :
  24. ------------------------------------------------------------------------------*/
  25. HRESULT CreateBasicConstraintsObject (PCCERT_CONTEXT pCertContext,
  26. IBasicConstraints ** ppIBasicConstraints)
  27. {
  28. HRESULT hr = S_OK;
  29. CComObject<CBasicConstraints> * pCBasicConstraints = NULL;
  30. DebugTrace("Entering CreateBasicConstraintsObject().\n");
  31. //
  32. // Sanity check.
  33. //
  34. ATLASSERT(pCertContext);
  35. ATLASSERT(ppIBasicConstraints);
  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<CBasicConstraints>::CreateInstance(&pCBasicConstraints)))
  43. {
  44. DebugTrace("Error [%#x]: CComObject<CBasicConstraints>::CreateInstance() failed.\n", hr);
  45. goto ErrorExit;
  46. }
  47. //
  48. // Initialize object.
  49. //
  50. if (FAILED(hr = pCBasicConstraints->Init(pCertContext)))
  51. {
  52. DebugTrace("Error [%#x]: pCBasicConstraints::Init() failed.\n", hr);
  53. goto ErrorExit;
  54. }
  55. //
  56. // Return interface pointer to caller.
  57. //
  58. if (FAILED(hr = pCBasicConstraints->QueryInterface(ppIBasicConstraints)))
  59. {
  60. DebugTrace("Error [%#x]: pCBasicConstraints->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("Entering CreateBasicConstraintsObject().\n");
  72. return hr;
  73. ErrorExit:
  74. //
  75. // Sanity check.
  76. //
  77. ATLASSERT(FAILED(hr));
  78. //
  79. // Free resource.
  80. //
  81. if (pCBasicConstraints)
  82. {
  83. delete pCBasicConstraints;
  84. }
  85. goto CommonExit;
  86. }
  87. ////////////////////////////////////////////////////////////////////////////////
  88. //
  89. // CBasicConstraints
  90. //
  91. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  92. Function : CBasicConstraints::get_IsPresent
  93. Synopsis : Check to see if the basic constraints extension is present.
  94. Parameter: VARIANT_BOOL * pVal - Pointer to VARIANT_BOOL to receive result.
  95. Remark :
  96. ------------------------------------------------------------------------------*/
  97. STDMETHODIMP CBasicConstraints::get_IsPresent (VARIANT_BOOL * pVal)
  98. {
  99. HRESULT hr = S_OK;
  100. DebugTrace("Entering CBasicConstraints::get_IsPresent().\n");
  101. try
  102. {
  103. //
  104. // Lock access to this object.
  105. //
  106. m_Lock.Lock();
  107. //
  108. // Check parameters.
  109. //
  110. if (NULL == pVal)
  111. {
  112. hr = E_INVALIDARG;
  113. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  114. goto ErrorExit;
  115. }
  116. //
  117. // Return result.
  118. //
  119. *pVal = m_bIsPresent;
  120. }
  121. catch(...)
  122. {
  123. hr = E_POINTER;
  124. DebugTrace("Exception: invalid parameter.\n");
  125. goto ErrorExit;
  126. }
  127. UnlockExit:
  128. //
  129. // Unlock access to this object.
  130. //
  131. m_Lock.Unlock();
  132. DebugTrace("Leaving CBasicConstraints::get_IsPresent().\n");
  133. return hr;
  134. ErrorExit:
  135. //
  136. // Sanity check.
  137. //
  138. ATLASSERT(FAILED(hr));
  139. ReportError(hr);
  140. goto UnlockExit;
  141. }
  142. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  143. Function : CBasicConstraints::get_IsCritical
  144. Synopsis : Check to see if the basic constraints extension is marked critical.
  145. Parameter: VARIANT_BOOL * pVal - Pointer to VARIANT_BOOL to receive result.
  146. Remark :
  147. ------------------------------------------------------------------------------*/
  148. STDMETHODIMP CBasicConstraints::get_IsCritical (VARIANT_BOOL * pVal)
  149. {
  150. HRESULT hr = S_OK;
  151. DebugTrace("Entering CBasicConstraints::get_IsCritical().\n");
  152. try
  153. {
  154. //
  155. // Lock access to this object.
  156. //
  157. m_Lock.Lock();
  158. //
  159. // Check parameters.
  160. //
  161. if (NULL == pVal)
  162. {
  163. hr = E_INVALIDARG;
  164. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  165. goto ErrorExit;
  166. }
  167. //
  168. // Return result.
  169. //
  170. *pVal = m_bIsCritical;
  171. }
  172. catch(...)
  173. {
  174. hr = E_POINTER;
  175. DebugTrace("Exception: invalid parameter.\n");
  176. goto ErrorExit;
  177. }
  178. UnlockExit:
  179. //
  180. // Unlock access to this object.
  181. //
  182. m_Lock.Unlock();
  183. DebugTrace("Leaving CBasicConstraints::get_IsCritical().\n");
  184. return hr;
  185. ErrorExit:
  186. //
  187. // Sanity check.
  188. //
  189. ATLASSERT(FAILED(hr));
  190. ReportError(hr);
  191. goto UnlockExit;
  192. }
  193. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  194. Function : CBasicConstraints::get_IsCertificateAuthority
  195. Synopsis : Check to see if the basic constraints extension contains the CA
  196. value.
  197. Parameter: VARIANT_BOOL * pVal - Pointer to VARIANT_BOOL to receive result.
  198. Remark :
  199. ------------------------------------------------------------------------------*/
  200. STDMETHODIMP CBasicConstraints::get_IsCertificateAuthority (VARIANT_BOOL * pVal)
  201. {
  202. HRESULT hr = S_OK;
  203. DebugTrace("Entering CBasicConstraints::get_IsCertificateAuthority().\n");
  204. try
  205. {
  206. //
  207. // Lock access to this object.
  208. //
  209. m_Lock.Lock();
  210. //
  211. // Check parameters.
  212. //
  213. if (NULL == pVal)
  214. {
  215. hr = E_INVALIDARG;
  216. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  217. goto ErrorExit;
  218. }
  219. //
  220. // Return result.
  221. //
  222. *pVal = m_bIsCertificateAuthority;
  223. }
  224. catch(...)
  225. {
  226. hr = E_POINTER;
  227. DebugTrace("Exception: invalid parameter.\n");
  228. goto ErrorExit;
  229. }
  230. UnlockExit:
  231. //
  232. // Unlock access to this object.
  233. //
  234. m_Lock.Unlock();
  235. DebugTrace("Leaving CBasicConstraints::get_IsCertificateAuthority().\n");
  236. return hr;
  237. ErrorExit:
  238. //
  239. // Sanity check.
  240. //
  241. ATLASSERT(FAILED(hr));
  242. ReportError(hr);
  243. goto UnlockExit;
  244. }
  245. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  246. Function : CBasicConstraints::get_IsPathLenConstraintPresent
  247. Synopsis : Check to see if the basic constraints extension contains path
  248. length constraints.
  249. Parameter: VARIANT_BOOL * pVal - Pointer to VARIANT_BOOL to receive result.
  250. Remark :
  251. ------------------------------------------------------------------------------*/
  252. STDMETHODIMP CBasicConstraints::get_IsPathLenConstraintPresent (VARIANT_BOOL * pVal)
  253. {
  254. HRESULT hr = S_OK;
  255. DebugTrace("Entering CBasicConstraints::get_IsPathLenConstraintPresent().\n");
  256. try
  257. {
  258. //
  259. // Lock access to this object.
  260. //
  261. m_Lock.Lock();
  262. //
  263. // Check parameters.
  264. //
  265. if (NULL == pVal)
  266. {
  267. hr = E_INVALIDARG;
  268. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  269. goto ErrorExit;
  270. }
  271. //
  272. // Return result.
  273. //
  274. *pVal = m_bIsPathLenConstraintPresent;
  275. }
  276. catch(...)
  277. {
  278. hr = E_POINTER;
  279. DebugTrace("Exception: invalid parameter.\n");
  280. goto ErrorExit;
  281. }
  282. UnlockExit:
  283. //
  284. // Unlock access to this object.
  285. //
  286. m_Lock.Unlock();
  287. DebugTrace("Leaving CBasicConstraints::get_IsPathLenConstraintPresent().\n");
  288. return hr;
  289. ErrorExit:
  290. //
  291. // Sanity check.
  292. //
  293. ATLASSERT(FAILED(hr));
  294. ReportError(hr);
  295. goto UnlockExit;
  296. }
  297. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  298. Function : CBasicConstraints::get_PathLenConstraint
  299. Synopsis : Return the path length constraints value.
  300. Parameter: long * pVal - Pointer to long to receive value.
  301. Remark :
  302. ------------------------------------------------------------------------------*/
  303. STDMETHODIMP CBasicConstraints::get_PathLenConstraint (long * pVal)
  304. {
  305. HRESULT hr = S_OK;
  306. DebugTrace("Entering CBasicConstraints::get_PathLenConstraint().\n");
  307. try
  308. {
  309. //
  310. // Lock access to this object.
  311. //
  312. m_Lock.Lock();
  313. //
  314. // Check parameters.
  315. //
  316. if (NULL == pVal)
  317. {
  318. hr = E_INVALIDARG;
  319. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  320. goto ErrorExit;
  321. }
  322. //
  323. // Return result.
  324. //
  325. *pVal = m_lPathLenConstraint;
  326. }
  327. catch(...)
  328. {
  329. hr = E_POINTER;
  330. DebugTrace("Exception: invalid parameter.\n");
  331. goto ErrorExit;
  332. }
  333. UnlockExit:
  334. //
  335. // Unlock access to this object.
  336. //
  337. m_Lock.Unlock();
  338. DebugTrace("Leaving CBasicConstraints::get_PathLenConstraint().\n");
  339. return hr;
  340. ErrorExit:
  341. //
  342. // Sanity check.
  343. //
  344. ATLASSERT(FAILED(hr));
  345. ReportError(hr);
  346. goto UnlockExit;
  347. }
  348. ////////////////////////////////////////////////////////////////////////////////
  349. //
  350. // Private methods.
  351. //
  352. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  353. Function : CBasicConstraints::Init
  354. Synopsis : Initialize the object.
  355. Parameter: PCCERT_CONTEXT pCertContext - Pointer to CERT_CONTEXT.
  356. Remark : This method is not part of the COM interface (it is a normal C++
  357. member function). We need it to initialize the object created
  358. internally by us with CERT_CONTEXT.
  359. Since it is only a normal C++ member function, this function can
  360. only be called from a C++ class pointer, not an interface pointer.
  361. ------------------------------------------------------------------------------*/
  362. STDMETHODIMP CBasicConstraints::Init (PCCERT_CONTEXT pCertContext)
  363. {
  364. HRESULT hr = S_OK;
  365. CRYPT_DATA_BLOB DataBlob = {0, NULL};
  366. PCERT_BASIC_CONSTRAINTS2_INFO pInfo = NULL;
  367. PCERT_EXTENSION pBasicConstraints = NULL;
  368. DebugTrace("Entering CBasicConstraints::Init().\n");
  369. //
  370. // Sanity check.
  371. //
  372. ATLASSERT(pCertContext);
  373. //
  374. // Find the basic constraints extension.
  375. //
  376. if (pBasicConstraints = ::CertFindExtension(szOID_BASIC_CONSTRAINTS2,
  377. pCertContext->pCertInfo->cExtension,
  378. pCertContext->pCertInfo->rgExtension))
  379. {
  380. //
  381. // Decode the basic constraints extension.
  382. //
  383. if (FAILED(hr = ::DecodeObject(X509_BASIC_CONSTRAINTS2,
  384. pBasicConstraints->Value.pbData,
  385. pBasicConstraints->Value.cbData,
  386. &DataBlob)))
  387. {
  388. DebugTrace("Error [%#x]: DecodeObject() failed.\n", hr);
  389. goto ErrorExit;
  390. }
  391. //
  392. // Point to CERT_BASIC_CONSTRAINTS2_INFO.
  393. //
  394. pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) DataBlob.pbData;
  395. //
  396. // Set values.
  397. //
  398. m_bIsPresent = VARIANT_TRUE;
  399. if (pBasicConstraints->fCritical)
  400. {
  401. m_bIsCritical = VARIANT_TRUE;
  402. }
  403. if (pInfo->fCA)
  404. {
  405. m_bIsCertificateAuthority = VARIANT_TRUE;
  406. }
  407. if (pInfo->fPathLenConstraint)
  408. {
  409. m_bIsPathLenConstraintPresent = VARIANT_TRUE;
  410. m_lPathLenConstraint = (long) pInfo->dwPathLenConstraint;
  411. }
  412. }
  413. CommonExit:
  414. //
  415. // Free resources.
  416. //
  417. if (DataBlob.pbData)
  418. {
  419. ::CoTaskMemFree((LPVOID) DataBlob.pbData);
  420. }
  421. DebugTrace("Leaving CBasicConstraints::Init().\n");
  422. return hr;
  423. ErrorExit:
  424. //
  425. // Sanity check.
  426. //
  427. ATLASSERT(FAILED(hr));
  428. goto CommonExit;
  429. }