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.

591 lines
13 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: EKU.cpp
  4. Content: Implementation of CEKU.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "EKU.h"
  10. ////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Exported functions.
  13. //
  14. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  15. Function : CreateEKUObject
  16. Synopsis : Create an IEKU object and initialize the object with data
  17. from the specified OID.
  18. Parameter: LPTSTR * pszOID - Pointer to EKU OID string.
  19. IEKU ** ppIEKU - Pointer to pointer IEKU object.
  20. Remark :
  21. ------------------------------------------------------------------------------*/
  22. HRESULT CreateEKUObject (LPSTR pszOID, IEKU ** ppIEKU)
  23. {
  24. HRESULT hr = S_OK;
  25. CComObject<CEKU> * pCEKU = NULL;
  26. CAPICOM_EKU EkuName;
  27. CComBSTR bstrValue;
  28. DebugTrace("Entering CreateEKUObject().\n");
  29. //
  30. // Sanity check.
  31. //
  32. ATLASSERT(ppIEKU);
  33. try
  34. {
  35. //
  36. // Create the object. Note that the ref count will still be 0
  37. // after the object is created.
  38. //
  39. if (FAILED(hr = CComObject<CEKU>::CreateInstance(&pCEKU)))
  40. {
  41. DebugTrace("Error [%#x]: CComObject<CEKU>::CreateInstance() failed.\n", hr);
  42. goto ErrorExit;
  43. }
  44. //
  45. // Determine EKU enum name.
  46. //
  47. if (NULL == pszOID)
  48. {
  49. EkuName = CAPICOM_EKU_OTHER;
  50. }
  51. else if (0 == ::strcmp(CAPICOM_OID_SERVER_AUTH, pszOID))
  52. {
  53. EkuName = CAPICOM_EKU_SERVER_AUTH;
  54. }
  55. else if (0 == ::strcmp(CAPICOM_OID_CLIENT_AUTH, pszOID))
  56. {
  57. EkuName = CAPICOM_EKU_CLIENT_AUTH;
  58. }
  59. else if (0 == ::strcmp(CAPICOM_OID_CODE_SIGNING, pszOID))
  60. {
  61. EkuName = CAPICOM_EKU_CODE_SIGNING;
  62. }
  63. else if (0 == ::strcmp(CAPICOM_OID_EMAIL_PROTECTION, pszOID))
  64. {
  65. EkuName = CAPICOM_EKU_EMAIL_PROTECTION;
  66. }
  67. else if (0 == ::strcmp(CAPICOM_OID_SMART_CARD_LOGON, pszOID))
  68. {
  69. EkuName = CAPICOM_EKU_SMARTCARD_LOGON;
  70. }
  71. else if (0 == ::strcmp(CAPICOM_OID_ENCRYPTING_FILE_SYSTEM, pszOID))
  72. {
  73. EkuName = CAPICOM_EKU_ENCRYPTING_FILE_SYSTEM;
  74. }
  75. else
  76. {
  77. EkuName = CAPICOM_EKU_OTHER;
  78. }
  79. //
  80. // Initialize object.
  81. //
  82. if (FAILED(hr = pCEKU->Init(EkuName, pszOID)))
  83. {
  84. DebugTrace("Error [%#x]: pCEKU->Init() failed.\n", hr);
  85. goto ErrorExit;
  86. }
  87. //
  88. // Return interface pointer to caller.
  89. //
  90. if (FAILED(hr = pCEKU->QueryInterface(ppIEKU)))
  91. {
  92. DebugTrace("Error [%#x]: pCEKU->QueryInterface() failed.\n", hr);
  93. goto ErrorExit;
  94. }
  95. }
  96. catch(...)
  97. {
  98. hr = E_POINTER;
  99. DebugTrace("Exception: invalid parameter.\n");
  100. goto ErrorExit;
  101. }
  102. CommonExit:
  103. DebugTrace("Leaving CreateEKUObject().\n");
  104. return hr;
  105. ErrorExit:
  106. //
  107. // Sanity check.
  108. //
  109. ATLASSERT(FAILED(hr));
  110. if (pCEKU)
  111. {
  112. delete pCEKU;
  113. }
  114. goto CommonExit;
  115. }
  116. ////////////////////////////////////////////////////////////////////////////////
  117. //
  118. // CEKU
  119. //
  120. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  121. Function : CEKU::get_Name
  122. Synopsis : Return the enum name of the EKU.
  123. Parameter: CAPICOM_EKU * pVal - Pointer to CAPICOM_EKU to receive result.
  124. Remark :
  125. ------------------------------------------------------------------------------*/
  126. STDMETHODIMP CEKU::get_Name (CAPICOM_EKU * pVal)
  127. {
  128. HRESULT hr = S_OK;
  129. DebugTrace("Entering CEKU::get_Name().\n");
  130. try
  131. {
  132. //
  133. // Lock access to this object.
  134. //
  135. m_Lock.Lock();
  136. //
  137. // Check parameters.
  138. //
  139. if (NULL == pVal)
  140. {
  141. hr = E_INVALIDARG;
  142. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  143. goto ErrorExit;
  144. }
  145. //
  146. // Return result.
  147. //
  148. *pVal = m_Name;
  149. }
  150. catch(...)
  151. {
  152. hr = E_POINTER;
  153. DebugTrace("Exception: invalid parameter.\n");
  154. goto ErrorExit;
  155. }
  156. UnlockExit:
  157. //
  158. // Unlock access to this object.
  159. //
  160. m_Lock.Unlock();
  161. DebugTrace("Leaving CEKU::get_Name().\n");
  162. return hr;
  163. ErrorExit:
  164. //
  165. // Sanity check.
  166. //
  167. ATLASSERT(FAILED(hr));
  168. ReportError(hr);
  169. goto UnlockExit;
  170. }
  171. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  172. Function : CEKU::put_Name
  173. Synopsis : Set EKU enum name.
  174. Parameter: CAPICOM_EKU newVal - EKU enum name.
  175. Remark : The corresponding EKU value will be set for all except EKU_OTHER,
  176. in which case the user must make another explicit call to
  177. put_Value to set it.
  178. ------------------------------------------------------------------------------*/
  179. STDMETHODIMP CEKU::put_Name (CAPICOM_EKU newVal)
  180. {
  181. HRESULT hr = S_OK;
  182. DebugTrace("Entering CEKU::put_Name().\n");
  183. //
  184. // Lock access to this object.
  185. //
  186. m_Lock.Lock();
  187. //
  188. // Reset value based on EKU name.
  189. //
  190. switch (newVal)
  191. {
  192. case CAPICOM_EKU_OTHER:
  193. {
  194. m_bstrOID.Empty();
  195. break;
  196. }
  197. case CAPICOM_EKU_SERVER_AUTH:
  198. {
  199. if (!(m_bstrOID = CAPICOM_OID_SERVER_AUTH))
  200. {
  201. hr = E_OUTOFMEMORY;
  202. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_SERVER_AUTH failed.\n", hr);
  203. goto ErrorExit;
  204. }
  205. break;
  206. }
  207. case CAPICOM_EKU_CLIENT_AUTH:
  208. {
  209. if (!(m_bstrOID = CAPICOM_OID_CLIENT_AUTH))
  210. {
  211. hr = E_OUTOFMEMORY;
  212. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_CLIENT_AUTH failed.\n", hr);
  213. goto ErrorExit;
  214. }
  215. break;
  216. }
  217. case CAPICOM_EKU_CODE_SIGNING:
  218. {
  219. if (!(m_bstrOID = CAPICOM_OID_CODE_SIGNING))
  220. {
  221. hr = E_OUTOFMEMORY;
  222. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_CODE_SIGNING failed.\n", hr);
  223. goto ErrorExit;
  224. }
  225. break;
  226. }
  227. case CAPICOM_EKU_EMAIL_PROTECTION:
  228. {
  229. if (!(m_bstrOID = CAPICOM_OID_EMAIL_PROTECTION))
  230. {
  231. hr = E_OUTOFMEMORY;
  232. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_EMAIL_PROTECTION failed.\n", hr);
  233. goto ErrorExit;
  234. }
  235. break;
  236. }
  237. case CAPICOM_EKU_SMARTCARD_LOGON:
  238. {
  239. if (!(m_bstrOID = CAPICOM_OID_SMART_CARD_LOGON))
  240. {
  241. hr = E_OUTOFMEMORY;
  242. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_SMART_CARD_LOGON failed.\n", hr);
  243. goto ErrorExit;
  244. }
  245. break;
  246. }
  247. case CAPICOM_EKU_ENCRYPTING_FILE_SYSTEM:
  248. {
  249. if (!(m_bstrOID = CAPICOM_OID_ENCRYPTING_FILE_SYSTEM))
  250. {
  251. hr = E_OUTOFMEMORY;
  252. DebugTrace("Error [%#x]: m_bstrOID = CAPICOM_OID_ENCRYPTING_FILE_SYSTEM failed.\n", hr);
  253. goto ErrorExit;
  254. }
  255. break;
  256. }
  257. default:
  258. {
  259. hr = E_INVALIDARG;
  260. DebugTrace("Error [%#x]: Unknown EKU name (%#x).\n", hr, newVal);
  261. goto ErrorExit;
  262. }
  263. }
  264. //
  265. // Store name.
  266. //
  267. m_Name = newVal;
  268. UnlockExit:
  269. //
  270. // Unlock access to this object.
  271. //
  272. m_Lock.Unlock();
  273. DebugTrace("Leaving CEKU::put_Name().\n");
  274. return hr;
  275. ErrorExit:
  276. //
  277. // Sanity check.
  278. //
  279. ATLASSERT(FAILED(hr));
  280. ReportError(hr);
  281. goto UnlockExit;
  282. }
  283. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  284. Function : CEKU::get_OID
  285. Synopsis : Return the actual OID string of the EKU.
  286. Parameter: BSTR * pVal - Pointer to BSTR to receive value.
  287. Remark :
  288. ------------------------------------------------------------------------------*/
  289. STDMETHODIMP CEKU::get_OID (BSTR * pVal)
  290. {
  291. HRESULT hr = S_OK;
  292. DebugTrace("Entering CEKU::get_OID().\n");
  293. try
  294. {
  295. //
  296. // Lock access to this object.
  297. //
  298. m_Lock.Lock();
  299. //
  300. // Check parameters.
  301. //
  302. if (NULL == pVal)
  303. {
  304. hr = E_INVALIDARG;
  305. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  306. goto ErrorExit;
  307. }
  308. //
  309. // Return result.
  310. //
  311. if (FAILED(hr = m_bstrOID.CopyTo(pVal)))
  312. {
  313. DebugTrace("Error [%#x]: m_bstrOID.CopyTo() failed.\n", hr);
  314. goto ErrorExit;
  315. }
  316. }
  317. catch(...)
  318. {
  319. hr = E_POINTER;
  320. DebugTrace("Exception: invalid parameter.\n");
  321. goto ErrorExit;
  322. }
  323. UnlockExit:
  324. //
  325. // Unlock access to this object.
  326. //
  327. m_Lock.Unlock();
  328. DebugTrace("Leaving CEKU::get_OID().\n");
  329. return hr;
  330. ErrorExit:
  331. //
  332. // Sanity check.
  333. //
  334. ATLASSERT(FAILED(hr));
  335. ReportError(hr);
  336. goto UnlockExit;
  337. }
  338. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  339. Function : CEKU::put_OID
  340. Synopsis : Set EKU actual OID string value.
  341. Parameter: BSTR newVal - EKU OID string.
  342. Remark :
  343. ------------------------------------------------------------------------------*/
  344. STDMETHODIMP CEKU::put_OID (BSTR newVal)
  345. {
  346. HRESULT hr = S_OK;
  347. DebugTrace("Entering CEKU::put_OID().\n");
  348. try
  349. {
  350. //
  351. // Lock access to this object.
  352. //
  353. m_Lock.Lock();
  354. //
  355. // Make sure Name property is CAPICOM_EKU_OTHER.
  356. //
  357. if (CAPICOM_EKU_OTHER != m_Name)
  358. {
  359. hr = CAPICOM_E_EKU_INVALID_OID;
  360. DebugTrace("Error [%#x]: attemp to set EKU OID, when EKU name is not CAPICOM_EKU_OTHER.\n", hr);
  361. goto ErrorExit;
  362. }
  363. //
  364. // Store value.
  365. //
  366. if (NULL == newVal)
  367. {
  368. m_bstrOID.Empty();
  369. }
  370. else if (!(m_bstrOID = newVal))
  371. {
  372. hr = E_OUTOFMEMORY;
  373. DebugTrace("Error [%#x]: m_bstrOID = newVal failed.\n", hr);
  374. goto ErrorExit;
  375. }
  376. }
  377. catch(...)
  378. {
  379. hr = E_POINTER;
  380. DebugTrace("Exception: invalid parameter.\n");
  381. goto ErrorExit;
  382. }
  383. UnlockExit:
  384. //
  385. // Unlock access to this object.
  386. //
  387. m_Lock.Unlock();
  388. DebugTrace("Leaving CEKU::put_OID().\n");
  389. return hr;
  390. ErrorExit:
  391. //
  392. // Sanity check.
  393. //
  394. ATLASSERT(FAILED(hr));
  395. ReportError(hr);
  396. goto UnlockExit;
  397. }
  398. ////////////////////////////////////////////////////////////////////////////////
  399. //
  400. // Private methods.
  401. //
  402. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  403. Function : CEKU::Init
  404. Synopsis : Initialize the object.
  405. Parameter: CAPICOM_EKU EkuName - Enum name of EKU.
  406. LPSTR lpszOID - EKU OID string.
  407. Remark : This method is not part of the COM interface (it is a normal C++
  408. member function). We need it to initialize the object created
  409. internally by us with CERT_CONTEXT.
  410. Since it is only a normal C++ member function, this function can
  411. only be called from a C++ class pointer, not an interface pointer.
  412. ------------------------------------------------------------------------------*/
  413. STDMETHODIMP CEKU::Init (CAPICOM_EKU EkuName,
  414. LPSTR lpszOID)
  415. {
  416. HRESULT hr = S_OK;
  417. DebugTrace("Entering CEKU::Init().\n");
  418. //
  419. // Explicitly empty the BSTR to work around ATL's bug where it calls
  420. // SysAllocStringLen() with -1 when the right-hand value is NULL, and
  421. // caused OLEAUT32.DLL to assert in checked build.
  422. //
  423. // Note: ATL fixed this problem in VC 7.
  424. //
  425. if (NULL == lpszOID)
  426. {
  427. m_bstrOID.Empty();
  428. }
  429. else if (!(m_bstrOID = lpszOID))
  430. {
  431. hr = E_OUTOFMEMORY;
  432. DebugTrace("Error [%#x]: m_bstrOID = lpszOID failed.\n", hr);
  433. goto ErrorExit;
  434. }
  435. //
  436. // Init private members.
  437. //
  438. m_Name = EkuName;
  439. CommonExit:
  440. DebugTrace("Leaving CEKU::Init().\n");
  441. return hr;
  442. ErrorExit:
  443. //
  444. // Sanity check.
  445. //
  446. ATLASSERT(FAILED(hr));
  447. goto CommonExit;
  448. }