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.

789 lines
20 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: OID.cpp
  4. Content: Implementation of COID.
  5. History: 06-15-2001 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "CAPICOM.h"
  9. #include "OID.h"
  10. //
  11. // OID name mapping structure/array.
  12. //
  13. typedef struct _tagOIDMapping
  14. {
  15. CAPICOM_OID oidName;
  16. LPSTR pszObjectId;
  17. } OID_MAPPING, POID_MAPPING;
  18. static OID_MAPPING g_OidMappingArray[] =
  19. {
  20. // id-ce (Certificate/CRL Extensions)
  21. {CAPICOM_OID_AUTHORITY_KEY_IDENTIFIER_EXTENSION, szOID_AUTHORITY_KEY_IDENTIFIER},
  22. {CAPICOM_OID_KEY_ATTRIBUTES_EXTENSION, szOID_KEY_ATTRIBUTES},
  23. {CAPICOM_OID_CERT_POLICIES_95_EXTENSION, szOID_CERT_POLICIES_95},
  24. {CAPICOM_OID_KEY_USAGE_RESTRICTION_EXTENSION, szOID_KEY_USAGE_RESTRICTION},
  25. {CAPICOM_OID_LEGACY_POLICY_MAPPINGS_EXTENSION, szOID_LEGACY_POLICY_MAPPINGS},
  26. {CAPICOM_OID_SUBJECT_ALT_NAME_EXTENSION, szOID_SUBJECT_ALT_NAME},
  27. {CAPICOM_OID_ISSUER_ALT_NAME_EXTENSION, szOID_ISSUER_ALT_NAME},
  28. {CAPICOM_OID_BASIC_CONSTRAINTS_EXTENSION, szOID_BASIC_CONSTRAINTS},
  29. {CAPICOM_OID_SUBJECT_KEY_IDENTIFIER_EXTENSION, szOID_SUBJECT_KEY_IDENTIFIER},
  30. {CAPICOM_OID_KEY_USAGE_EXTENSION, szOID_KEY_USAGE},
  31. {CAPICOM_OID_PRIVATEKEY_USAGE_PERIOD_EXTENSION, szOID_PRIVATEKEY_USAGE_PERIOD},
  32. {CAPICOM_OID_SUBJECT_ALT_NAME2_EXTENSION, szOID_SUBJECT_ALT_NAME2},
  33. {CAPICOM_OID_ISSUER_ALT_NAME2_EXTENSION, szOID_ISSUER_ALT_NAME2},
  34. {CAPICOM_OID_BASIC_CONSTRAINTS2_EXTENSION, szOID_BASIC_CONSTRAINTS2},
  35. {CAPICOM_OID_NAME_CONSTRAINTS_EXTENSION, szOID_NAME_CONSTRAINTS},
  36. {CAPICOM_OID_CRL_DIST_POINTS_EXTENSION, szOID_CRL_DIST_POINTS},
  37. {CAPICOM_OID_CERT_POLICIES_EXTENSION, szOID_CERT_POLICIES},
  38. {CAPICOM_OID_POLICY_MAPPINGS_EXTENSION, szOID_POLICY_MAPPINGS},
  39. {CAPICOM_OID_AUTHORITY_KEY_IDENTIFIER2_EXTENSION, szOID_AUTHORITY_KEY_IDENTIFIER2},
  40. {CAPICOM_OID_POLICY_CONSTRAINTS_EXTENSION, szOID_POLICY_CONSTRAINTS},
  41. {CAPICOM_OID_ENHANCED_KEY_USAGE_EXTENSION, szOID_ENHANCED_KEY_USAGE},
  42. {CAPICOM_OID_CERTIFICATE_TEMPLATE_EXTENSION, szOID_CERTIFICATE_TEMPLATE},
  43. {CAPICOM_OID_APPLICATION_CERT_POLICIES_EXTENSION, szOID_APPLICATION_CERT_POLICIES},
  44. {CAPICOM_OID_APPLICATION_POLICY_MAPPINGS_EXTENSION, szOID_APPLICATION_POLICY_MAPPINGS},
  45. {CAPICOM_OID_APPLICATION_POLICY_CONSTRAINTS_EXTENSION, szOID_APPLICATION_POLICY_CONSTRAINTS},
  46. // id-pe
  47. {CAPICOM_OID_AUTHORITY_INFO_ACCESS_EXTENSION, szOID_AUTHORITY_INFO_ACCESS},
  48. // Application Policy (eku)
  49. {CAPICOM_OID_SERVER_AUTH_EKU, szOID_PKIX_KP_SERVER_AUTH},
  50. {CAPICOM_OID_CLIENT_AUTH_EKU, szOID_PKIX_KP_CLIENT_AUTH},
  51. {CAPICOM_OID_CODE_SIGNING_EKU, szOID_PKIX_KP_CODE_SIGNING},
  52. {CAPICOM_OID_EMAIL_PROTECTION_EKU, szOID_PKIX_KP_EMAIL_PROTECTION},
  53. {CAPICOM_OID_IPSEC_END_SYSTEM_EKU, szOID_PKIX_KP_IPSEC_END_SYSTEM},
  54. {CAPICOM_OID_IPSEC_TUNNEL_EKU, szOID_PKIX_KP_IPSEC_TUNNEL},
  55. {CAPICOM_OID_IPSEC_USER_EKU, szOID_PKIX_KP_IPSEC_USER},
  56. {CAPICOM_OID_TIME_STAMPING_EKU, szOID_PKIX_KP_TIMESTAMP_SIGNING},
  57. {CAPICOM_OID_CTL_USAGE_SIGNING_EKU, szOID_KP_CTL_USAGE_SIGNING},
  58. {CAPICOM_OID_TIME_STAMP_SIGNING_EKU, szOID_KP_TIME_STAMP_SIGNING},
  59. {CAPICOM_OID_SERVER_GATED_CRYPTO_EKU, szOID_SERVER_GATED_CRYPTO},
  60. {CAPICOM_OID_ENCRYPTING_FILE_SYSTEM_EKU, szOID_KP_EFS},
  61. {CAPICOM_OID_EFS_RECOVERY_EKU, szOID_EFS_RECOVERY},
  62. {CAPICOM_OID_WHQL_CRYPTO_EKU, szOID_WHQL_CRYPTO},
  63. {CAPICOM_OID_NT5_CRYPTO_EKU, szOID_NT5_CRYPTO},
  64. {CAPICOM_OID_OEM_WHQL_CRYPTO_EKU, szOID_OEM_WHQL_CRYPTO},
  65. {CAPICOM_OID_EMBEDED_NT_CRYPTO_EKU, szOID_EMBEDDED_NT_CRYPTO},
  66. {CAPICOM_OID_ROOT_LIST_SIGNER_EKU, szOID_ROOT_LIST_SIGNER},
  67. {CAPICOM_OID_QUALIFIED_SUBORDINATION_EKU, szOID_KP_QUALIFIED_SUBORDINATION},
  68. {CAPICOM_OID_KEY_RECOVERY_EKU, szOID_KP_KEY_RECOVERY},
  69. {CAPICOM_OID_DIGITAL_RIGHTS_EKU, szOID_DRM},
  70. {CAPICOM_OID_LICENSES_EKU, szOID_LICENSES},
  71. {CAPICOM_OID_LICENSE_SERVER_EKU, szOID_LICENSE_SERVER},
  72. {CAPICOM_OID_SMART_CARD_LOGON_EKU, szOID_KP_SMARTCARD_LOGON},
  73. // Policy Qualifier
  74. {CAPICOM_OID_PKIX_POLICY_QUALIFIER_CPS, szOID_PKIX_POLICY_QUALIFIER_CPS},
  75. {CAPICOM_OID_PKIX_POLICY_QUALIFIER_USERNOTICE, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE},
  76. };
  77. #define g_dwOidMappingEntries ((DWORD) (ARRAYSIZE(g_OidMappingArray)))
  78. ////////////////////////////////////////////////////////////////////////////////
  79. //
  80. // Exported functions.
  81. //
  82. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  83. Function : CreateOIDObject
  84. Synopsis : Create and initialize an COID object.
  85. Parameter: LPTSTR * pszOID - Pointer to OID string.
  86. BOOL bReadOnly - TRUE for Read only, else FALSE.
  87. IOID ** ppIOID - Pointer to pointer IOID object.
  88. Remark :
  89. ------------------------------------------------------------------------------*/
  90. HRESULT CreateOIDObject (LPSTR pszOID, BOOL bReadOnly, IOID ** ppIOID)
  91. {
  92. HRESULT hr = S_OK;
  93. CComObject<COID> * pCOID = NULL;
  94. DebugTrace("Entering CreateOIDObject().\n");
  95. //
  96. // Sanity check.
  97. //
  98. ATLASSERT(ppIOID);
  99. try
  100. {
  101. //
  102. // Create the object. Note that the ref count will still be 0
  103. // after the object is created.
  104. //
  105. if (FAILED(hr = CComObject<COID>::CreateInstance(&pCOID)))
  106. {
  107. DebugTrace("Error [%#x]: CComObject<COID>::CreateInstance() failed.\n", hr);
  108. goto ErrorExit;
  109. }
  110. //
  111. // Initialize object.
  112. //
  113. if (FAILED(hr = pCOID->Init(pszOID, bReadOnly)))
  114. {
  115. DebugTrace("Error [%#x]: pCOID->Init() failed.\n", hr);
  116. goto ErrorExit;
  117. }
  118. //
  119. // Return interface pointer to caller.
  120. //
  121. if (FAILED(hr = pCOID->QueryInterface(ppIOID)))
  122. {
  123. DebugTrace("Error [%#x]: pCOID->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. CommonExit:
  134. DebugTrace("Leaving CreateOIDObject().\n");
  135. return hr;
  136. ErrorExit:
  137. //
  138. // Sanity check.
  139. //
  140. ATLASSERT(FAILED(hr));
  141. if (pCOID)
  142. {
  143. delete pCOID;
  144. }
  145. goto CommonExit;
  146. }
  147. ////////////////////////////////////////////////////////////////////////////////
  148. //
  149. // COID
  150. //
  151. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  152. Function : COID::get_Name
  153. Synopsis : Return the enum name of the OID.
  154. Parameter: CAPICOM_OID * pVal - Pointer to CAPICOM_OID to receive result.
  155. Remark :
  156. ------------------------------------------------------------------------------*/
  157. STDMETHODIMP COID::get_Name (CAPICOM_OID * pVal)
  158. {
  159. HRESULT hr = S_OK;
  160. DebugTrace("Entering COID::get_Name().\n");
  161. try
  162. {
  163. //
  164. // Lock access to this object.
  165. //
  166. m_Lock.Lock();
  167. //
  168. // Check parameters.
  169. //
  170. if (NULL == pVal)
  171. {
  172. hr = E_INVALIDARG;
  173. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  174. goto ErrorExit;
  175. }
  176. //
  177. // Return result.
  178. //
  179. *pVal = m_Name;
  180. }
  181. catch(...)
  182. {
  183. hr = E_POINTER;
  184. DebugTrace("Exception: invalid parameter.\n");
  185. goto ErrorExit;
  186. }
  187. UnlockExit:
  188. //
  189. // Unlock access to this object.
  190. //
  191. m_Lock.Unlock();
  192. DebugTrace("Leaving COID::get_Name().\n");
  193. return hr;
  194. ErrorExit:
  195. //
  196. // Sanity check.
  197. //
  198. ATLASSERT(FAILED(hr));
  199. ReportError(hr);
  200. goto UnlockExit;
  201. }
  202. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  203. Function : COID::put_Name
  204. Synopsis : Set OID enum name.
  205. Parameter: CAPICOM_OID newVal - OID enum name.
  206. Remark : The corresponding OID value will be set for all except OID_OTHER,
  207. in which case the user must make another explicit call to
  208. put_Value to set it.
  209. ------------------------------------------------------------------------------*/
  210. STDMETHODIMP COID::put_Name (CAPICOM_OID newVal)
  211. {
  212. HRESULT hr = S_OK;
  213. LPSTR pszOID = NULL;
  214. DebugTrace("Entering COID::put_Name().\n");
  215. try
  216. {
  217. //
  218. // Lock access to this object.
  219. //
  220. m_Lock.Lock();
  221. //
  222. // Make sure it is not read only.
  223. //
  224. if (m_bReadOnly)
  225. {
  226. hr = CAPICOM_E_NOT_ALLOWED;
  227. DebugTrace("Error [%#x]: Writing read-only OID object is not allowed.\n", hr);
  228. goto ErrorExit;
  229. }
  230. //
  231. // Find OID string value.
  232. //
  233. for (DWORD i = 0; i < g_dwOidMappingEntries; i++)
  234. {
  235. if (g_OidMappingArray[i].oidName == newVal)
  236. {
  237. pszOID = g_OidMappingArray[i].pszObjectId;
  238. break;
  239. }
  240. }
  241. //
  242. // Reset.
  243. //
  244. if (FAILED(hr = Init(pszOID, FALSE)))
  245. {
  246. DebugTrace("Error [%#x]: COID::init() failed.\n", hr);
  247. goto ErrorExit;
  248. }
  249. }
  250. catch(...)
  251. {
  252. hr = E_POINTER;
  253. DebugTrace("Exception: invalid parameter.\n");
  254. goto ErrorExit;
  255. }
  256. UnlockExit:
  257. //
  258. // Unlock access to this object.
  259. //
  260. m_Lock.Unlock();
  261. DebugTrace("Leaving COID::put_Name().\n");
  262. return hr;
  263. ErrorExit:
  264. //
  265. // Sanity check.
  266. //
  267. ATLASSERT(FAILED(hr));
  268. ReportError(hr);
  269. goto UnlockExit;
  270. }
  271. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  272. Function : COID::get_FriendlyName
  273. Synopsis : Return the freindly name of the OID.
  274. Parameter: BSTR * pVal - Pointer to BSTR to receive value.
  275. Remark :
  276. ------------------------------------------------------------------------------*/
  277. STDMETHODIMP COID::get_FriendlyName (BSTR * pVal)
  278. {
  279. HRESULT hr = S_OK;
  280. DebugTrace("Entering COID::get_FriendlyName().\n");
  281. try
  282. {
  283. //
  284. // Lock access to this object.
  285. //
  286. m_Lock.Lock();
  287. //
  288. // Check parameters.
  289. //
  290. if (NULL == pVal)
  291. {
  292. hr = E_INVALIDARG;
  293. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  294. goto ErrorExit;
  295. }
  296. //
  297. // Return result.
  298. //
  299. if (FAILED(hr = m_bstrFriendlyName.CopyTo(pVal)))
  300. {
  301. DebugTrace("Error [%#x]: m_bstrFriendlyName.CopyTo() failed.\n", hr);
  302. goto ErrorExit;
  303. }
  304. }
  305. catch(...)
  306. {
  307. hr = E_POINTER;
  308. DebugTrace("Exception: invalid parameter.\n");
  309. goto ErrorExit;
  310. }
  311. UnlockExit:
  312. //
  313. // Unlock access to this object.
  314. //
  315. m_Lock.Unlock();
  316. DebugTrace("Leaving COID::get_FriendlyName().\n");
  317. return hr;
  318. ErrorExit:
  319. //
  320. // Sanity check.
  321. //
  322. ATLASSERT(FAILED(hr));
  323. ReportError(hr);
  324. goto UnlockExit;
  325. }
  326. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  327. Function : COID::put_FriendlyName
  328. Synopsis : Set friendly name.
  329. Parameter: BSTR newVal - OID string.
  330. Remark :
  331. ------------------------------------------------------------------------------*/
  332. STDMETHODIMP COID::put_FriendlyName (BSTR newVal)
  333. {
  334. HRESULT hr = S_OK;
  335. PCCRYPT_OID_INFO pOidInfo = NULL;
  336. DebugTrace("Entering COID::put_FriendlyName().\n");
  337. try
  338. {
  339. //
  340. // Lock access to this object.
  341. //
  342. m_Lock.Lock();
  343. //
  344. // Make sure it is not read only.
  345. //
  346. if (m_bReadOnly)
  347. {
  348. hr = CAPICOM_E_NOT_ALLOWED;
  349. DebugTrace("Error [%#x]: Write read-only OID object is not allowed.\n", hr);
  350. goto ErrorExit;
  351. }
  352. //
  353. // Find OID and reset, if possible.
  354. //
  355. if (newVal)
  356. {
  357. if (pOidInfo = ::CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY,
  358. (LPWSTR) newVal,
  359. 0))
  360. {
  361. //
  362. // Reset.
  363. //
  364. if (FAILED(hr = Init((LPSTR) pOidInfo->pszOID, FALSE)))
  365. {
  366. DebugTrace("Error [%#x]: COID::init() failed.\n", hr);
  367. goto ErrorExit;
  368. }
  369. }
  370. else if (!(m_bstrFriendlyName = newVal))
  371. {
  372. hr = E_OUTOFMEMORY;
  373. DebugTrace("Error [%#x]: m_bstrFriendlyName = newVal failed.\n", hr);
  374. goto ErrorExit;
  375. }
  376. }
  377. else
  378. {
  379. m_bstrFriendlyName.Empty();
  380. }
  381. }
  382. catch(...)
  383. {
  384. hr = E_POINTER;
  385. DebugTrace("Exception: invalid parameter.\n");
  386. goto ErrorExit;
  387. }
  388. UnlockExit:
  389. //
  390. // Unlock access to this object.
  391. //
  392. m_Lock.Unlock();
  393. DebugTrace("Leaving COID::put_FriendlyName().\n");
  394. return hr;
  395. ErrorExit:
  396. //
  397. // Sanity check.
  398. //
  399. ATLASSERT(FAILED(hr));
  400. ReportError(hr);
  401. goto UnlockExit;
  402. }
  403. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  404. Function : COID::get_Value
  405. Synopsis : Return the actual string of the OID.
  406. Parameter: BSTR * pVal - Pointer to BSTR to receive value.
  407. Remark :
  408. ------------------------------------------------------------------------------*/
  409. STDMETHODIMP COID::get_Value (BSTR * pVal)
  410. {
  411. HRESULT hr = S_OK;
  412. DebugTrace("Entering COID::get_Value().\n");
  413. try
  414. {
  415. //
  416. // Lock access to this object.
  417. //
  418. m_Lock.Lock();
  419. //
  420. // Check parameters.
  421. //
  422. if (NULL == pVal)
  423. {
  424. hr = E_INVALIDARG;
  425. DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
  426. goto ErrorExit;
  427. }
  428. //
  429. // Return result.
  430. //
  431. if (FAILED(hr = m_bstrOID.CopyTo(pVal)))
  432. {
  433. DebugTrace("Error [%#x]: m_bstrOID.CopyTo() failed.\n", hr);
  434. goto ErrorExit;
  435. }
  436. }
  437. catch(...)
  438. {
  439. hr = E_POINTER;
  440. DebugTrace("Exception: invalid parameter.\n");
  441. goto ErrorExit;
  442. }
  443. UnlockExit:
  444. //
  445. // Unlock access to this object.
  446. //
  447. m_Lock.Unlock();
  448. DebugTrace("Leaving COID::get_Value().\n");
  449. return hr;
  450. ErrorExit:
  451. //
  452. // Sanity check.
  453. //
  454. ATLASSERT(FAILED(hr));
  455. ReportError(hr);
  456. goto UnlockExit;
  457. }
  458. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  459. Function : COID::put_Value
  460. Synopsis : Set OID actual OID string value.
  461. Parameter: BSTR newVal - OID string.
  462. Remark :
  463. ------------------------------------------------------------------------------*/
  464. STDMETHODIMP COID::put_Value (BSTR newVal)
  465. {
  466. USES_CONVERSION;
  467. HRESULT hr = S_OK;
  468. LPSTR pszOid = NULL;
  469. DebugTrace("Entering COID::put_Value().\n");
  470. try
  471. {
  472. //
  473. // Lock access to this object.
  474. //
  475. m_Lock.Lock();
  476. //
  477. // Make sure it is not read only.
  478. //
  479. if (m_bReadOnly)
  480. {
  481. hr = CAPICOM_E_NOT_ALLOWED;
  482. DebugTrace("Error [%#x]: Writing read-only OID object is not allowed.\n", hr);
  483. goto ErrorExit;
  484. }
  485. //
  486. // Check parameters.
  487. //
  488. if (NULL == newVal)
  489. {
  490. hr = E_INVALIDARG;
  491. DebugTrace("Error [%#x]: Parameter newVal is NULL.\n", hr);
  492. goto ErrorExit;
  493. }
  494. //
  495. // Convert to multibytes.
  496. //
  497. if (NULL == (pszOid = W2A(newVal)))
  498. {
  499. hr = E_OUTOFMEMORY;
  500. DebugTrace("Error: out of memory.\n");
  501. goto ErrorExit;
  502. }
  503. //
  504. // Reset.
  505. //
  506. if (FAILED(hr = Init(pszOid, FALSE)))
  507. {
  508. DebugTrace("Error [%#x]: COID::init() failed.\n", hr);
  509. goto ErrorExit;
  510. }
  511. }
  512. catch(...)
  513. {
  514. hr = E_POINTER;
  515. DebugTrace("Exception: invalid parameter.\n");
  516. goto ErrorExit;
  517. }
  518. UnlockExit:
  519. //
  520. // Unlock access to this object.
  521. //
  522. m_Lock.Unlock();
  523. DebugTrace("Leaving COID::put_Value().\n");
  524. return hr;
  525. ErrorExit:
  526. //
  527. // Sanity check.
  528. //
  529. ATLASSERT(FAILED(hr));
  530. ReportError(hr);
  531. goto UnlockExit;
  532. }
  533. ////////////////////////////////////////////////////////////////////////////////
  534. //
  535. // Private methods.
  536. //
  537. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  538. Function : COID::Init
  539. Synopsis : Initialize the object.
  540. Parameter: LPSTR pszOID - OID string.
  541. BOOL bReadOnly - TRUE for Read only, else FALSE.
  542. Remark : This method is not part of the COM interface (it is a normal C++
  543. member function). We need it to initialize the object created
  544. internally by us.
  545. Since it is only a normal C++ member function, this function can
  546. only be called from a C++ class pointer, not an interface pointer.
  547. ------------------------------------------------------------------------------*/
  548. STDMETHODIMP COID::Init (LPSTR pszOID, BOOL bReadOnly)
  549. {
  550. HRESULT hr = S_OK;
  551. CAPICOM_OID oidName = CAPICOM_OID_OTHER;
  552. PCCRYPT_OID_INFO pOidInfo = NULL;
  553. DebugTrace("Entering COID::Init().\n");
  554. if (pszOID)
  555. {
  556. //
  557. // Find enum name.
  558. //
  559. for (DWORD i = 0; i < g_dwOidMappingEntries; i++)
  560. {
  561. if (0 == ::strcmp(pszOID, g_OidMappingArray[i].pszObjectId))
  562. {
  563. oidName = g_OidMappingArray[i].oidName;
  564. break;
  565. }
  566. }
  567. if (!(m_bstrOID = pszOID))
  568. {
  569. hr = E_OUTOFMEMORY;
  570. DebugTrace("Error [%#x]: m_bstrOID = pszOID failed.\n", hr);
  571. goto ErrorExit;
  572. }
  573. //
  574. // Set OID friendly name.
  575. //
  576. if (pOidInfo = ::CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pszOID, 0))
  577. {
  578. m_bstrFriendlyName = pOidInfo->pwszName;
  579. DebugTrace("Info: OID = %ls (%s).\n", pOidInfo->pwszName, pszOID);
  580. }
  581. else
  582. {
  583. DebugTrace("Info: Can't find friendly name for OID (%s).\n", pszOID);
  584. }
  585. }
  586. m_Name = oidName;
  587. m_bReadOnly = bReadOnly;
  588. CommonExit:
  589. DebugTrace("Leaving COID::Init().\n");
  590. return hr;
  591. ErrorExit:
  592. //
  593. // Sanity check.
  594. //
  595. ATLASSERT(FAILED(hr));
  596. //
  597. // Free resources.
  598. //
  599. m_bstrOID.Empty();
  600. m_bstrFriendlyName.Empty();
  601. goto CommonExit;
  602. }