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.

2448 lines
76 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2002.
  5. //
  6. // File: CertTemplate.cpp
  7. //
  8. // Contents: CCertTemplate
  9. //
  10. //----------------------------------------------------------------------------
  11. /// CertTemplate.cpp: implementation of the CCertTemplate class.
  12. //
  13. //////////////////////////////////////////////////////////////////////
  14. #include "stdafx.h"
  15. #include "CertTemplate.h"
  16. #define _SECOND ((ULONGLONG) 10000000)
  17. #define _MINUTE (60 * _SECOND)
  18. #define _HOUR (60 * _MINUTE)
  19. #define _DAY (24 * _HOUR)
  20. CERT_EXTENSION g_EKUCertExtension = {szOID_ENHANCED_KEY_USAGE, 0, {0, 0}};
  21. CERT_EXTENSION g_certPolCertExtension = {szOID_CERT_POLICIES, 0, {0, 0}};
  22. //////////////////////////////////////////////////////////////////////
  23. // Construction/Destruction
  24. //////////////////////////////////////////////////////////////////////
  25. CCertTemplate::CCertTemplate(
  26. PCWSTR pszObjectName,
  27. PCWSTR pszTemplateName,
  28. const CString& szLDAPPath,
  29. bool fIsReadOnly,
  30. const bool fUseCache) :
  31. CCertTmplCookie (CERTTMPL_CERT_TEMPLATE, pszObjectName),
  32. m_strTemplateName (pszTemplateName),
  33. m_hCertType (0),
  34. m_dwVersion (0),
  35. m_dwEnrollmentFlags (0),
  36. m_dwSubjectNameFlags (0),
  37. m_dwPrivateKeyFlags (0),
  38. m_dwGeneralFlags (0),
  39. m_dwKeySpec (0),
  40. m_bIsClone (false),
  41. m_bCanBeDeletedOnCancel (false),
  42. m_bGoodForAutoenrollmentFlagPendingSave (false),
  43. m_szLDAPPath (szLDAPPath),
  44. m_fIsReadOnly (fIsReadOnly),
  45. m_nOriginalValidityDays (-1),
  46. m_nNewValidityDays (-1),
  47. m_nOriginalRenewalDays (-1),
  48. m_nNewRenewalDays (-1),
  49. m_pCertExtensions (0),
  50. m_fUseCache (fUseCache),
  51. m_bIssuancePoliciesRequired (false),
  52. m_fFailedToSetSecurity (false)
  53. {
  54. // _TRACE (1, L"Entering CCertTemplate::CCertTemplate\n");
  55. m_strOriginalTemplateName = pszTemplateName;
  56. Initialize ();
  57. // _TRACE (-1, L"Leaving CCertTemplate::CCertTemplate\n");
  58. }
  59. CCertTemplate::CCertTemplate(
  60. const CCertTemplate &rTemplate,
  61. bool bIsClone,
  62. bool fIsReadOnly,
  63. const bool fUseCache)
  64. : CCertTmplCookie (CERTTMPL_CERT_TEMPLATE),
  65. m_hCertType (0),
  66. m_dwVersion (0),
  67. m_dwEnrollmentFlags (0),
  68. m_dwSubjectNameFlags (0),
  69. m_dwPrivateKeyFlags (0),
  70. m_dwGeneralFlags (0),
  71. m_dwKeySpec (0),
  72. m_bIsClone (bIsClone),
  73. m_bCanBeDeletedOnCancel (true),
  74. m_bGoodForAutoenrollmentFlagPendingSave (false),
  75. m_fIsReadOnly (fIsReadOnly),
  76. m_szLDAPPath (rTemplate.GetLDAPPath ()),
  77. m_nOriginalValidityDays (-1),
  78. m_nNewValidityDays (-1),
  79. m_nOriginalRenewalDays (-1),
  80. m_nNewRenewalDays (-1),
  81. m_pCertExtensions (0),
  82. m_fUseCache (fUseCache),
  83. m_bIssuancePoliciesRequired (false),
  84. m_fFailedToSetSecurity (false)
  85. {
  86. // _TRACE (1, L"Entering CCertTemplate::CCertTemplate (copy constructor)\n");
  87. // _TRACE (-1, L"Leaving CCertTemplate::CCertTemplate (copy constructor)\n");
  88. }
  89. CCertTemplate::~CCertTemplate()
  90. {
  91. // _TRACE (1, L"Entering CCertTemplate::~CCertTemplate - m_hCertType = 0x%x\n", m_hCertType);
  92. if ( m_hCertType )
  93. {
  94. FreeCertExtensions ();
  95. HRESULT hr = CACloseCertType (m_hCertType);
  96. _ASSERT (SUCCEEDED (hr));
  97. if ( !SUCCEEDED (hr) )
  98. {
  99. _TRACE (0, L"CACloseCertType (%s) failed: 0x%x\n", hr);
  100. }
  101. }
  102. // _TRACE (-1, L"Leaving CCertTemplate::~CCertTemplate\n");
  103. }
  104. HRESULT CCertTemplate::Initialize()
  105. {
  106. // _TRACE (1, L"Entering CCertTemplate::Initialize - m_hCertType = 0x%x\n", m_hCertType);
  107. HRESULT hr = S_OK;
  108. if ( !m_hCertType )
  109. {
  110. DWORD dwFlags = CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES;
  111. if ( !m_fUseCache )
  112. {
  113. dwFlags |= CT_FLAG_NO_CACHE_LOOKUP;
  114. }
  115. hr = CAFindCertTypeByName (m_strTemplateName,
  116. NULL,
  117. dwFlags,
  118. &m_hCertType);
  119. _ASSERT (SUCCEEDED (hr));
  120. }
  121. if ( SUCCEEDED (hr) )
  122. {
  123. hr = CAGetCertTypePropertyEx (m_hCertType,
  124. CERTTYPE_PROP_SCHEMA_VERSION,
  125. &m_dwVersion);
  126. if ( FAILED (hr) )
  127. {
  128. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_SCHEMA_VERSION) failed: 0x%x\n", hr);
  129. }
  130. // Get enrollment flags
  131. if ( SUCCEEDED (hr) )
  132. {
  133. hr = CAGetCertTypeFlagsEx (m_hCertType, CERTTYPE_ENROLLMENT_FLAG,
  134. &m_dwEnrollmentFlags);
  135. if ( FAILED (hr) )
  136. {
  137. _TRACE (0, L"CAGetCertTypeFlagsEx (CERTTYPE_ENROLLMENT_FLAG) failed: 0x%x\n", hr);
  138. }
  139. }
  140. // Get subject name flags
  141. if ( SUCCEEDED (hr) )
  142. {
  143. hr = CAGetCertTypeFlagsEx (m_hCertType, CERTTYPE_SUBJECT_NAME_FLAG,
  144. &m_dwSubjectNameFlags);
  145. if ( FAILED (hr) )
  146. {
  147. _TRACE (0, L"CAGetCertTypeFlagsEx (CERTTYPE_SUBJECT_NAME_FLAG) failed: 0x%x\n", hr);
  148. }
  149. }
  150. // Get private key flags
  151. if ( SUCCEEDED (hr) )
  152. {
  153. hr = CAGetCertTypeFlagsEx (m_hCertType, CERTTYPE_PRIVATE_KEY_FLAG,
  154. &m_dwPrivateKeyFlags);
  155. if ( FAILED (hr) )
  156. {
  157. _TRACE (0, L"CAGetCertTypeFlagsEx (CERTTYPE_PRIVATE_KEY_FLAG) failed: 0x%x\n", hr);
  158. }
  159. }
  160. // Get general flags
  161. if ( SUCCEEDED (hr) )
  162. {
  163. hr = CAGetCertTypeFlagsEx (m_hCertType, CERTTYPE_GENERAL_FLAG,
  164. &m_dwGeneralFlags);
  165. if ( FAILED (hr) )
  166. {
  167. _TRACE (0, L"CAGetCertTypeFlagsEx (CERTTYPE_GENERAL_FLAG) failed: 0x%x\n", hr);
  168. }
  169. }
  170. if ( SUCCEEDED (hr) )
  171. {
  172. hr = CAGetCertTypeKeySpec (m_hCertType, &m_dwKeySpec);
  173. if ( FAILED (hr) )
  174. {
  175. _TRACE (0, L"CAGetCertTypeKeySpec () failed: 0x%x\n", hr);
  176. }
  177. }
  178. }
  179. else
  180. {
  181. _TRACE (0, L"CAFindCertTypeByName (%s) failed: 0x%x\n", (PCWSTR) m_strTemplateName, hr);
  182. }
  183. // _TRACE (-1, L"Leaving CCertTemplate::Initialize: 0x%x\n", hr);
  184. return hr;
  185. }
  186. DWORD CCertTemplate::GetType() const
  187. {
  188. return m_dwVersion;
  189. }
  190. CString CCertTemplate::GetDisplayName ()
  191. {
  192. // _TRACE (1, L"Entering CCertTemplate::GetDisplayName - m_hCertType = 0x%x\n", m_hCertType);
  193. HRESULT hr = S_OK;
  194. if ( m_szDisplayName.IsEmpty () )
  195. {
  196. if ( m_hCertType )
  197. {
  198. PWSTR* rgwszProp = 0;
  199. hr = CAGetCertTypePropertyEx (m_hCertType,
  200. CERTTYPE_PROP_FRIENDLY_NAME, &rgwszProp);
  201. if ( SUCCEEDED (hr) && rgwszProp )
  202. {
  203. m_szDisplayName = *rgwszProp;
  204. CAFreeCertTypeProperty (m_hCertType, rgwszProp);
  205. }
  206. else
  207. {
  208. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_FRIENDLY_NAME) failed: 0x%x\n", hr);
  209. m_szDisplayName = GetObjectName ();
  210. }
  211. }
  212. else
  213. m_szDisplayName = GetObjectName ();
  214. }
  215. // _TRACE (-1, L"Leaving CCertTemplate::GetDisplayName: %s, 0x%x\n", (PCWSTR) m_szDisplayName, hr);
  216. return m_szDisplayName;
  217. }
  218. CString CCertTemplate::GetTemplateName() const
  219. {
  220. return m_strTemplateName;
  221. }
  222. bool CCertTemplate::SubjectIsCA() const
  223. {
  224. return (m_dwGeneralFlags & CT_FLAG_IS_CA) ? true : false;
  225. }
  226. bool CCertTemplate::SubjectIsCrossCA() const
  227. {
  228. return (m_dwGeneralFlags & CT_FLAG_IS_CROSS_CA) ? true : false;
  229. }
  230. bool CCertTemplate::IsMachineType() const
  231. {
  232. return (m_dwGeneralFlags & CT_FLAG_MACHINE_TYPE) ? true : false;
  233. }
  234. bool CCertTemplate::PublishToDS() const
  235. {
  236. return (m_dwEnrollmentFlags & CT_FLAG_PUBLISH_TO_DS) ? true : false;
  237. }
  238. DWORD CCertTemplate::GetCertExtensionCount()
  239. {
  240. DWORD dwCnt = 0;
  241. PCERT_EXTENSIONS pCertExtensions = 0;
  242. HRESULT hr = CAGetCertTypeExtensions (m_hCertType, &pCertExtensions);
  243. if ( SUCCEEDED (hr) )
  244. {
  245. if ( pCertExtensions )
  246. {
  247. dwCnt = pCertExtensions->cExtension;
  248. CAFreeCertTypeExtensions (m_hCertType, pCertExtensions);
  249. }
  250. }
  251. else
  252. {
  253. _TRACE (0, L"CAGetCertTypeExtensions () failed: 0x%x\n", hr);
  254. }
  255. return dwCnt;
  256. }
  257. ///////////////////////////////////////////////////////////////////////////////
  258. //
  259. // Method: GetCertExtension
  260. //
  261. // Note: The pointer returned through ppCertExtension must not be freed. The
  262. // caller must call FreeCertExtensions () when done with it.
  263. ///////////////////////////////////////////////////////////////////////////////
  264. HRESULT CCertTemplate::GetCertExtension (PSTR pszOID, PCERT_EXTENSION* ppCertExtension)
  265. {
  266. HRESULT hr = S_OK;
  267. if ( ppCertExtension )
  268. {
  269. hr = CAGetCertTypeExtensions (m_hCertType, &m_pCertExtensions);
  270. if ( SUCCEEDED (hr) )
  271. {
  272. if ( m_pCertExtensions )
  273. {
  274. *ppCertExtension = CertFindExtension(pszOID,
  275. m_pCertExtensions->cExtension,
  276. m_pCertExtensions->rgExtension);
  277. if ( ! (*ppCertExtension) )
  278. {
  279. if ( SubjectIsCA () )
  280. {
  281. if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszOID) )
  282. *ppCertExtension = &g_EKUCertExtension;
  283. else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
  284. *ppCertExtension = &g_certPolCertExtension;
  285. }
  286. }
  287. }
  288. else
  289. hr = E_FAIL;
  290. }
  291. else
  292. {
  293. _TRACE (0, L"CAGetCertTypeExtensions () failed: 0x%x\n", hr);
  294. }
  295. }
  296. else
  297. return E_POINTER;
  298. return hr;
  299. }
  300. HRESULT CCertTemplate::GetCertExtension(DWORD dwIndex, PSTR* ppszObjId, BOOL& fCritical)
  301. {
  302. if ( !ppszObjId )
  303. return E_POINTER;
  304. PCERT_EXTENSIONS pCertExtensions = 0;
  305. HRESULT hr = CAGetCertTypeExtensions (m_hCertType, &pCertExtensions);
  306. if ( SUCCEEDED (hr) )
  307. {
  308. if ( pCertExtensions )
  309. {
  310. if ( dwIndex >= pCertExtensions->cExtension )
  311. hr = E_INVALIDARG;
  312. else
  313. {
  314. PCERT_EXTENSION pExtension = &pCertExtensions->rgExtension[dwIndex];
  315. ASSERT (pExtension->pszObjId);
  316. if ( pExtension->pszObjId )
  317. {
  318. // security review 2/21/2002 BryanWal ok
  319. PSTR pszOID = new char[strlen (pExtension->pszObjId)+1];
  320. if ( pszOID )
  321. {
  322. // security review 2/21/2002 BryanWal ok
  323. strcpy (pszOID, pExtension->pszObjId);
  324. *ppszObjId = pszOID;
  325. fCritical = pExtension->fCritical;
  326. }
  327. else
  328. hr = E_OUTOFMEMORY;
  329. }
  330. else
  331. hr = E_FAIL;
  332. }
  333. CAFreeCertTypeExtensions (m_hCertType, pCertExtensions);
  334. }
  335. }
  336. else
  337. {
  338. _TRACE (0, L"CAGetCertTypeExtensions () failed: 0x%x\n", hr);
  339. }
  340. return hr;
  341. }
  342. bool CCertTemplate::HasKeySpecSignature() const
  343. {
  344. return m_dwKeySpec & AT_SIGNATURE ? true : false;
  345. }
  346. bool CCertTemplate::HasEncryptionSignature() const
  347. {
  348. return m_dwKeySpec & AT_KEYEXCHANGE ? true : false;
  349. }
  350. bool CCertTemplate::RequireSubjectInRequest() const
  351. {
  352. return m_dwSubjectNameFlags & CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT ? true : false;
  353. }
  354. #define CVT_BASE (1000 * 1000 * 10)
  355. HRESULT CCertTemplate::ConvertCertTypeFileTimeToDays (FILETIME const *pftCertType, int& nDays)
  356. {
  357. HRESULT hr = S_OK;
  358. if ( !pftCertType )
  359. return E_POINTER;
  360. LONGLONG ll = *(LONGLONG *) pftCertType; // Signed 64 bit scalar!
  361. if (0 > ll)
  362. {
  363. ll = -ll;
  364. ll /= CVT_BASE; // now in seconds
  365. nDays = (int) (ll / (60 * 60 * 24));
  366. }
  367. else
  368. nDays = 0;
  369. return hr;
  370. }
  371. HRESULT CCertTemplate::GetValidityPeriod(int& nValidityDays)
  372. {
  373. HRESULT hr = S_OK;
  374. FILETIME ftValidity;
  375. hr = CAGetCertTypeExpiration (m_hCertType, &ftValidity, 0);
  376. if ( SUCCEEDED (hr) )
  377. {
  378. hr = ConvertCertTypeFileTimeToDays (&ftValidity, nValidityDays);
  379. if ( SUCCEEDED (hr) )
  380. m_nOriginalValidityDays = nValidityDays;
  381. }
  382. return hr;
  383. }
  384. HRESULT CCertTemplate::GetRenewalPeriod(int& nRenewalDays)
  385. {
  386. HRESULT hr = S_OK;
  387. FILETIME ftRenewal;
  388. hr = CAGetCertTypeExpiration (m_hCertType, 0, &ftRenewal);
  389. if ( SUCCEEDED (hr) )
  390. {
  391. hr = ConvertCertTypeFileTimeToDays (&ftRenewal, nRenewalDays);
  392. if ( SUCCEEDED (hr) )
  393. m_nOriginalRenewalDays = nRenewalDays;
  394. }
  395. return hr;
  396. }
  397. // NEW CLONE
  398. HRESULT CCertTemplate::Clone (
  399. const CCertTemplate& rTemplate,
  400. const CString& strTemplateName,
  401. const CString& strDisplayName)
  402. {
  403. _TRACE (1, L"Entering CCertTemplate::Clone (%s, %s)\n", (PCWSTR) strTemplateName, (PCWSTR) strDisplayName);
  404. HRESULT hr = S_OK;
  405. _ASSERT (m_bIsClone);
  406. if ( m_bIsClone )
  407. {
  408. m_strTemplateName = strTemplateName;
  409. // Set the originalTemplateName so that we can tell later if the
  410. // user has renamed the template. This is important because renaming
  411. // a template creates a brand new template and the old one must then
  412. // be deleted.
  413. m_strOriginalTemplateName = strTemplateName;
  414. SetObjectName (strDisplayName);
  415. if ( SUCCEEDED (hr) )
  416. {
  417. hr = CAFindCertTypeByName (rTemplate.GetTemplateName (),
  418. NULL,
  419. CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES | CT_FLAG_NO_CACHE_LOOKUP,
  420. &m_hCertType);
  421. if ( SUCCEEDED (hr) )
  422. {
  423. HCERTTYPE hNewCertType = 0;
  424. hr = CACloneCertType (
  425. m_hCertType,
  426. strTemplateName,
  427. strDisplayName,
  428. 0,
  429. (GetType () > 1 ) ?
  430. (CT_CLONE_KEEP_SUBJECT_NAME_SETTING | CT_CLONE_KEEP_AUTOENROLLMENT_SETTING): 0,
  431. &hNewCertType);
  432. if ( SUCCEEDED (hr) )
  433. {
  434. CACloseCertType (m_hCertType);
  435. m_hCertType = hNewCertType;
  436. m_szLDAPPath = GetDN ();
  437. hr = Initialize ();
  438. }
  439. else
  440. {
  441. _TRACE (0, L"CACloneCertType (%s, %s) failed: 0x%d\n",
  442. (PCWSTR) strTemplateName, (PCWSTR) strDisplayName,
  443. hr);
  444. }
  445. }
  446. else
  447. {
  448. _TRACE (0, L"CAFindCertTypeByName (%s) failed: 0x%x",
  449. (PCWSTR) rTemplate.GetTemplateName (), hr);
  450. }
  451. }
  452. }
  453. else
  454. hr = E_FAIL;
  455. _TRACE (-1, L"Leaving CCertTemplate::Clone: 0x%x\n", hr);
  456. return hr;
  457. }
  458. HRESULT CCertTemplate::Delete()
  459. {
  460. _TRACE (1, L"Entering CCertTemplate::Delete - m_hCertType = 0x%x\n", m_hCertType);
  461. HRESULT hr = S_OK;
  462. if ( !(m_dwGeneralFlags & CT_FLAG_IS_DEFAULT) )
  463. {
  464. if ( m_hCertType )
  465. {
  466. hr = CADeleteCertType (m_hCertType);
  467. if ( FAILED (hr) )
  468. {
  469. _TRACE (0, L"CADeleteCertType failed: 0x%x\n", hr);
  470. }
  471. }
  472. else
  473. {
  474. _TRACE (0, L"m_hCertType was unexpectedly NULL\n");
  475. hr = E_UNEXPECTED;
  476. }
  477. }
  478. else
  479. hr = E_FAIL;
  480. _TRACE (-1, L"Leaving CCertTemplate::Delete: 0x%x\n", hr);
  481. return hr;
  482. }
  483. bool CCertTemplate::IsDefault() const
  484. {
  485. return m_dwGeneralFlags & CT_FLAG_IS_DEFAULT ? true : false;
  486. }
  487. bool CCertTemplate::IsClone() const
  488. {
  489. return m_bIsClone;
  490. }
  491. HRESULT CCertTemplate::SetTemplateName(const CString &strTemplateName)
  492. {
  493. _TRACE (1, L"Entering CCertTemplate::SetTemplateName (%s) - m_hCertType = 0x%x\n",
  494. strTemplateName, m_hCertType);
  495. HRESULT hr = S_OK;
  496. if ( LocaleStrCmp (m_strTemplateName, strTemplateName) )
  497. {
  498. PWSTR rgwszProp[2];
  499. rgwszProp[0] = (PWSTR)(PCWSTR) strTemplateName;
  500. rgwszProp[1] = 0;;
  501. hr = CASetCertTypePropertyEx (m_hCertType,
  502. CERTTYPE_PROP_CN, rgwszProp);
  503. if ( SUCCEEDED (hr) )
  504. {
  505. m_strTemplateName = strTemplateName;
  506. }
  507. else
  508. {
  509. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_CN, %s) failed: 0x%x",
  510. rgwszProp[0], hr);
  511. }
  512. }
  513. _TRACE (-1, L"Leaving CCertTemplate::SetTemplateName: 0x%x\n", hr);
  514. return hr;
  515. }
  516. HRESULT CCertTemplate::SetDisplayName(const CString &strDisplayName, bool bForce)
  517. {
  518. _TRACE (1, L"Entering CCertTemplate::SetDisplayName (%s) - m_hCertType = 0x%x\n",
  519. strDisplayName, m_hCertType);
  520. HRESULT hr = S_OK;
  521. if ( bForce || LocaleStrCmp (GetDisplayName (), strDisplayName) )
  522. {
  523. PWSTR rgwszProp[2];
  524. rgwszProp[0] = (PWSTR)(PCWSTR) strDisplayName;
  525. rgwszProp[1] = 0;
  526. hr = CASetCertTypePropertyEx (m_hCertType,
  527. CERTTYPE_PROP_FRIENDLY_NAME, rgwszProp);
  528. if ( SUCCEEDED (hr) )
  529. {
  530. m_szDisplayName = L"";
  531. m_szDisplayName = GetDisplayName ();
  532. SetObjectName (m_szDisplayName);
  533. }
  534. else
  535. {
  536. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_FRIENDLY_NAME, %s) failed: 0x%x",
  537. rgwszProp[0], hr);
  538. }
  539. }
  540. _TRACE (-1, L"Leaving CCertTemplate::SetDisplayName: 0x%x\n", hr);
  541. return hr;
  542. }
  543. HRESULT CCertTemplate::SaveChanges(bool bIncrementMinorVersion /*=true*/)
  544. {
  545. _TRACE (1, L"Entering CCertTemplate::SaveChanges - m_hCertType = 0x%x\n", m_hCertType);
  546. HRESULT hr = S_OK;
  547. m_bCanBeDeletedOnCancel = false;
  548. if ( m_hCertType )
  549. {
  550. // Save validity period
  551. if ( -1 != m_nNewValidityDays && m_nOriginalValidityDays != m_nNewValidityDays )
  552. {
  553. LONGLONG ll = (LONGLONG) m_nNewValidityDays * (60 * 60 * 24); // seconds
  554. ll *= CVT_BASE;
  555. ll = -ll;
  556. FILETIME ftValidity;
  557. ftValidity.dwLowDateTime = (DWORD) (ll & 0xFFFFFFFF);
  558. ftValidity.dwHighDateTime = (DWORD) (ll >> 32);
  559. // save the new value back to the cert template
  560. hr = CASetCertTypeExpiration (m_hCertType, &ftValidity, 0);
  561. if ( FAILED (hr) )
  562. {
  563. _TRACE (0, L"CASetCertTypeExpiration (validity) failed: 0x%x\n", hr);
  564. }
  565. }
  566. // Save renewal period
  567. if ( -1 != m_nNewRenewalDays && m_nOriginalRenewalDays != m_nNewRenewalDays )
  568. {
  569. LONGLONG ll = (LONGLONG) m_nNewRenewalDays * (60 * 60 * 24); // seconds
  570. ll *= CVT_BASE;
  571. ll = -ll;
  572. // get the original value
  573. FILETIME ftRenewal;
  574. ftRenewal.dwLowDateTime = (DWORD) (ll & 0xFFFFFFFF);
  575. ftRenewal.dwHighDateTime = (DWORD) (ll >> 32);
  576. // save the new value back to the cert template
  577. hr = CASetCertTypeExpiration (m_hCertType, 0, &ftRenewal);
  578. if ( FAILED (hr) )
  579. {
  580. _TRACE (0, L"CASetCertTypeExpiration (renewal) failed: 0x%x\n", hr);
  581. }
  582. }
  583. if ( SUCCEEDED (hr) )
  584. {
  585. if ( bIncrementMinorVersion )
  586. hr = IncrementMinorVersion ();
  587. if ( SUCCEEDED (hr) )
  588. {
  589. hr = CAUpdateCertType (m_hCertType);
  590. if ( SUCCEEDED (hr) )
  591. {
  592. // If the name was changed a new template was created and the old one needs to be deleted
  593. if ( LocaleStrCmp (m_strOriginalTemplateName, m_strTemplateName) )
  594. {
  595. HCERTTYPE hCertType = 0;
  596. HRESULT hr1 = CAFindCertTypeByName (m_strOriginalTemplateName,
  597. NULL,
  598. CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES | CT_FLAG_NO_CACHE_LOOKUP,
  599. &hCertType);
  600. if ( SUCCEEDED (hr1) )
  601. {
  602. hr1 = CADeleteCertType (hCertType);
  603. if (FAILED (hr1) )
  604. {
  605. _TRACE (0, L"Cert Template was renamed. Original cert template %s was found but could not be deleted: 0x%x\n",
  606. m_strOriginalTemplateName, hr);
  607. }
  608. m_strOriginalTemplateName = m_strTemplateName;
  609. hr1 = CACloseCertType (hCertType);
  610. if ( FAILED (hr1) )
  611. {
  612. _TRACE (0, L"CACloseCertType () failed: 0x%x", hr);
  613. }
  614. }
  615. else
  616. {
  617. _TRACE (0, L"Cert Template was renamed. Unable to find original cert template %s. 0x%x\n",
  618. m_strOriginalTemplateName, hr);
  619. }
  620. }
  621. else
  622. {
  623. m_bIsClone = false;
  624. Cancel (); // cause all settings to be refreshed
  625. }
  626. }
  627. else
  628. {
  629. _TRACE (0, L"CAUpdateCertType () failed: 0x%x", hr);
  630. }
  631. }
  632. }
  633. }
  634. else
  635. hr = E_FAIL;
  636. if ( SUCCEEDED (hr) )
  637. m_bIsClone = false;
  638. _TRACE (-1, L"Leaving CCertTemplate::SaveChanges: 0x%x\n", hr);
  639. return hr;
  640. }
  641. HRESULT CCertTemplate::SetSubjectIsCA(bool bSubjectIsCA)
  642. {
  643. _TRACE (1, L"Entering CCertTemplate::SetSubjectIsCA - m_hCertType = 0x%x\n", m_hCertType);
  644. HRESULT hr = SetFlag (CERTTYPE_GENERAL_FLAG, CT_FLAG_IS_CA, bSubjectIsCA);
  645. _TRACE (-1, L"Leaving CCertTemplate::SetSubjectIsCA: 0x%x\n", hr);
  646. return hr;
  647. }
  648. HRESULT CCertTemplate::SetKeySpecSignature(bool bHasKeySpecSignature)
  649. {
  650. _TRACE (1, L"Entering CCertTemplate::SetKeySpecSignature - m_hCertType = 0x%x\n", m_hCertType);
  651. HRESULT hr = S_OK;
  652. if ( m_hCertType )
  653. {
  654. if ( bHasKeySpecSignature )
  655. m_dwKeySpec |= AT_SIGNATURE;
  656. else
  657. m_dwKeySpec &= ~AT_SIGNATURE;
  658. hr = CASetCertTypeKeySpec (m_hCertType, m_dwKeySpec);
  659. if ( SUCCEEDED (hr) )
  660. {
  661. PCERT_EXTENSION pCertExtension = 0;
  662. hr = GetCertExtension (szOID_KEY_USAGE, &pCertExtension);
  663. if ( SUCCEEDED (hr) && pCertExtension )
  664. {
  665. DWORD cbKeyUsage = 0;
  666. if ( ::CryptDecodeObject(CRYPT_ASN_ENCODING,
  667. szOID_KEY_USAGE,
  668. pCertExtension->Value.pbData,
  669. pCertExtension->Value.cbData,
  670. 0, NULL, &cbKeyUsage) )
  671. {
  672. CRYPT_BIT_BLOB* pKeyUsage = (CRYPT_BIT_BLOB*)
  673. ::LocalAlloc (LPTR, cbKeyUsage);
  674. if ( pKeyUsage )
  675. {
  676. if ( ::CryptDecodeObject (CRYPT_ASN_ENCODING,
  677. szOID_KEY_USAGE,
  678. pCertExtension->Value.pbData,
  679. pCertExtension->Value.cbData,
  680. 0, pKeyUsage, &cbKeyUsage) )
  681. {
  682. if (pKeyUsage->cbData >= 1)
  683. {
  684. if ( bHasKeySpecSignature )
  685. {
  686. pKeyUsage->pbData[0] |= CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  687. // NTRAID# 312946 Cert Template Snap-in:
  688. // Should clear up the Key Encipherment
  689. // bit for signature certificate
  690. pKeyUsage->pbData[0] &= ~CERT_KEY_AGREEMENT_KEY_USAGE;
  691. pKeyUsage->pbData[0] &= ~CERT_KEY_ENCIPHERMENT_KEY_USAGE;
  692. pKeyUsage->pbData[0] &= ~CERT_DATA_ENCIPHERMENT_KEY_USAGE;
  693. }
  694. else
  695. {
  696. // is encryption only - clear the digital
  697. // signature and non-repudiation key usages
  698. pKeyUsage->pbData[0] &= ~CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  699. pKeyUsage->pbData[0] &= ~CERT_NON_REPUDIATION_KEY_USAGE;
  700. if ( !(CERT_KEY_AGREEMENT_KEY_USAGE & pKeyUsage->pbData[0]) )
  701. pKeyUsage->pbData[0] |= CERT_KEY_ENCIPHERMENT_KEY_USAGE;
  702. }
  703. pKeyUsage->cUnusedBits = 0;
  704. SetKeyUsage (pKeyUsage,
  705. pCertExtension->fCritical ? true : false);
  706. FreeCertExtensions ();
  707. }
  708. }
  709. else
  710. {
  711. DWORD dwErr = GetLastError ();
  712. _TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  713. DisplaySystemError (NULL, dwErr);
  714. }
  715. ::LocalFree (pKeyUsage);
  716. }
  717. }
  718. else
  719. {
  720. DWORD dwErr = GetLastError ();
  721. _TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  722. DisplaySystemError (NULL, dwErr);
  723. }
  724. }
  725. }
  726. else
  727. {
  728. _TRACE (0, L"CASetCertTypeKeySpec() failed: 0x%x\n", hr);
  729. }
  730. }
  731. else
  732. hr = E_UNEXPECTED;
  733. _TRACE (-1, L"Leaving CCertTemplate::SetKeySpecSignature: 0x%x\n", hr);
  734. return hr;
  735. }
  736. HRESULT CCertTemplate::SetFlag (DWORD dwFlagType, DWORD dwFlag, bool bValue)
  737. {
  738. _TRACE (1, L"Entering CCertTemplate::SetFlag - m_hCertType = 0x%x\n", m_hCertType);;
  739. HRESULT hr = S_OK;
  740. DWORD* pdwFlags = 0;
  741. switch (dwFlagType)
  742. {
  743. case CERTTYPE_ENROLLMENT_FLAG:
  744. pdwFlags = &m_dwEnrollmentFlags;
  745. break;
  746. case CERTTYPE_SUBJECT_NAME_FLAG:
  747. pdwFlags = &m_dwSubjectNameFlags;
  748. break;
  749. case CERTTYPE_PRIVATE_KEY_FLAG:
  750. pdwFlags = &m_dwPrivateKeyFlags;
  751. break;
  752. case CERTTYPE_GENERAL_FLAG:
  753. pdwFlags = &m_dwGeneralFlags;
  754. break;
  755. default:
  756. _ASSERT (0);
  757. hr = E_FAIL;
  758. break;
  759. }
  760. if ( pdwFlags )
  761. {
  762. if ( bValue )
  763. *pdwFlags |= dwFlag;
  764. else
  765. *pdwFlags &= ~dwFlag;
  766. hr = CASetCertTypeFlagsEx (m_hCertType, dwFlagType, *pdwFlags);
  767. _ASSERT (SUCCEEDED (hr));
  768. if ( FAILED (hr) )
  769. {
  770. _TRACE (0, L"CASetCertTypeFlagsEx () failed: 0x%x\n", hr);
  771. }
  772. }
  773. _TRACE (-1, L"Leaving CCertTemplate::SetFlag: 0x%x\n", hr);
  774. return hr;
  775. }
  776. HRESULT CCertTemplate::SetEncryptionSignature(bool bHasEncryptionSignature)
  777. {
  778. _TRACE (1, L"Entering CCertTemplate::SetEncryptionSignature - m_hCertType = 0x%x\n", m_hCertType);
  779. HRESULT hr = S_OK;
  780. if ( m_hCertType )
  781. {
  782. if ( bHasEncryptionSignature )
  783. m_dwKeySpec |= AT_KEYEXCHANGE;
  784. else
  785. m_dwKeySpec &= ~AT_KEYEXCHANGE;
  786. hr = CASetCertTypeKeySpec (m_hCertType, m_dwKeySpec);
  787. if ( FAILED (hr) )
  788. {
  789. _TRACE (0, L"CASetCertTypeKeySpec() failed: 0x%x\n", hr);
  790. }
  791. }
  792. else
  793. hr = E_UNEXPECTED;
  794. _TRACE (-1, L"Leaving CCertTemplate::SetEncryptionSignature: 0x%x\n", hr);
  795. return hr;
  796. }
  797. bool CCertTemplate::CanBeDeletedOnCancel() const
  798. {
  799. return m_bCanBeDeletedOnCancel;
  800. }
  801. HRESULT CCertTemplate::SetAutoEnrollment(bool bSuitableForAutoEnrollment)
  802. {
  803. HRESULT hr = S_OK;
  804. if ( IsClone () )
  805. {
  806. // If this is a clone, the autoenrollment flag has already been turned
  807. // off. Here we wish only to keep track of what the user's
  808. // preferences are so that we can turn it on, if desired, at the
  809. // final save.
  810. m_bGoodForAutoenrollmentFlagPendingSave = bSuitableForAutoEnrollment;
  811. }
  812. else
  813. hr = SetFlag (CERTTYPE_ENROLLMENT_FLAG, CT_FLAG_AUTO_ENROLLMENT,
  814. bSuitableForAutoEnrollment);
  815. return hr;
  816. }
  817. HRESULT CCertTemplate::GetMinimumKeySize(DWORD &dwMinKeySize) const
  818. {
  819. _TRACE (1, L"Entering CCertTemplate::GetMinimumKeySize - m_hCertType = 0x%x\n", m_hCertType);
  820. HRESULT hr = S_OK;
  821. if ( m_hCertType )
  822. {
  823. hr = CAGetCertTypePropertyEx (m_hCertType,
  824. CERTTYPE_PROP_MIN_KEY_SIZE,
  825. &dwMinKeySize);
  826. if ( FAILED (hr) )
  827. {
  828. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_MIN_KEY_SIZE) failed: 0x%x\n", hr);
  829. }
  830. }
  831. _TRACE (-1, L"Leaving CCertTemplate::GetMinimumKeySize (%d): 0x%x\n", dwMinKeySize, hr);
  832. return hr;
  833. }
  834. bool CCertTemplate::PrivateKeyIsExportable() const
  835. {
  836. return (m_dwPrivateKeyFlags & CT_FLAG_EXPORTABLE_KEY) ? true : false;
  837. }
  838. HRESULT CCertTemplate::MakePrivateKeyExportable(bool bMakeExportable)
  839. {
  840. return SetFlag (CERTTYPE_PRIVATE_KEY_FLAG, CT_FLAG_EXPORTABLE_KEY,
  841. bMakeExportable);
  842. }
  843. bool CCertTemplate::AllowPrivateKeyArchival() const
  844. {
  845. return (m_dwPrivateKeyFlags & CT_FLAG_ALLOW_PRIVATE_KEY_ARCHIVAL) ? true : false;
  846. }
  847. HRESULT CCertTemplate::AllowPrivateKeyArchival(bool bAllowArchival)
  848. {
  849. return SetFlag (CERTTYPE_PRIVATE_KEY_FLAG,
  850. CT_FLAG_ALLOW_PRIVATE_KEY_ARCHIVAL, bAllowArchival);
  851. }
  852. bool CCertTemplate::IncludeSymmetricAlgorithms() const
  853. {
  854. return (m_dwEnrollmentFlags & CT_FLAG_INCLUDE_SYMMETRIC_ALGORITHMS) ? true : false;
  855. }
  856. HRESULT CCertTemplate::IncludeSymmetricAlgorithms(bool bInclude)
  857. {
  858. return SetFlag (CERTTYPE_ENROLLMENT_FLAG,
  859. CT_FLAG_INCLUDE_SYMMETRIC_ALGORITHMS, bInclude);
  860. }
  861. HRESULT CCertTemplate::DoAutoEnrollmentPendingSave()
  862. {
  863. HRESULT hr = S_OK;
  864. if ( m_hCertType )
  865. {
  866. if ( IsClone () && m_bGoodForAutoenrollmentFlagPendingSave )
  867. {
  868. // Set the flag for real
  869. hr = SetFlag (CERTTYPE_ENROLLMENT_FLAG, CT_FLAG_AUTO_ENROLLMENT,
  870. true);
  871. // Save changes
  872. if ( SUCCEEDED (hr) )
  873. hr = SaveChanges ();
  874. }
  875. }
  876. else
  877. hr = E_FAIL;
  878. return hr;
  879. }
  880. bool CCertTemplate::AltNameIncludesDNS() const
  881. {
  882. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_ALT_REQUIRE_DNS) ? true : false;
  883. }
  884. HRESULT CCertTemplate::AltNameIncludesDNS(bool fIncludeDNS)
  885. {
  886. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  887. CT_FLAG_SUBJECT_ALT_REQUIRE_DNS, fIncludeDNS);
  888. }
  889. bool CCertTemplate::AltNameIncludesEMail() const
  890. {
  891. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL) ? true : false;
  892. }
  893. HRESULT CCertTemplate::AltNameIncludesEMail(bool bIncludesEMail)
  894. {
  895. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  896. CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL, bIncludesEMail);
  897. }
  898. bool CCertTemplate::AltNameIncludesUPN() const
  899. {
  900. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_ALT_REQUIRE_UPN) ? true : false;
  901. }
  902. HRESULT CCertTemplate::AltNameIncludesUPN(bool bIncludesUPN)
  903. {
  904. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  905. CT_FLAG_SUBJECT_ALT_REQUIRE_UPN, bIncludesUPN);
  906. }
  907. bool CCertTemplate::SubjectNameIncludesEMail() const
  908. {
  909. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_REQUIRE_EMAIL) ? true : false;
  910. }
  911. HRESULT CCertTemplate::SubjectNameIncludesEMail(bool bIncludesEMail)
  912. {
  913. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  914. CT_FLAG_SUBJECT_REQUIRE_EMAIL, bIncludesEMail);
  915. }
  916. bool CCertTemplate::SubjectNameMustBeFullDN() const
  917. {
  918. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH) ? true : false;
  919. }
  920. HRESULT CCertTemplate::SubjectNameMustBeFullDN(bool bMustBeDN)
  921. {
  922. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  923. CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH, bMustBeDN);
  924. }
  925. bool CCertTemplate::SubjectNameMustBeCN() const
  926. {
  927. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME) ? true : false;
  928. }
  929. HRESULT CCertTemplate::SubjectNameMustBeCN(bool bMustBeCN)
  930. {
  931. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  932. CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME, bMustBeCN);
  933. }
  934. HRESULT CCertTemplate::RequireSubjectInRequest(bool bRequire)
  935. {
  936. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  937. CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT, bRequire);
  938. }
  939. bool CCertTemplate::AltNameIncludesSPN() const
  940. {
  941. return (m_dwSubjectNameFlags & CT_FLAG_SUBJECT_ALT_REQUIRE_SPN) ? true : false;
  942. }
  943. HRESULT CCertTemplate::AltNameIncludesSPN(bool bIncludesSPN)
  944. {
  945. return SetFlag (CERTTYPE_SUBJECT_NAME_FLAG,
  946. CT_FLAG_SUBJECT_ALT_REQUIRE_SPN, bIncludesSPN);
  947. }
  948. HRESULT CCertTemplate::SetMinimumKeySizeValue(DWORD dwMinKeySize)
  949. {
  950. _TRACE (1, L"Entering CCertTemplate::SetMinimumKeySizeValue (%d)- m_hCertType = 0x%x\n",
  951. dwMinKeySize, m_hCertType);
  952. HRESULT hr = S_OK;
  953. if ( m_hCertType )
  954. {
  955. hr = CASetCertTypePropertyEx (m_hCertType,
  956. CERTTYPE_PROP_MIN_KEY_SIZE,
  957. &dwMinKeySize);
  958. if ( FAILED (hr) )
  959. {
  960. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_MIN_KEY_SIZE) failed: 0x%x\n", hr);
  961. }
  962. }
  963. _TRACE (-1, L"Leaving CCertTemplate::SetMinimumKeySizeValue (%d): 0x%x\n", dwMinKeySize, hr);
  964. return hr;
  965. }
  966. HRESULT CCertTemplate::ModifyCriticalExtensions (const CString &szExtension, bool bAdd)
  967. {
  968. _TRACE (1, L"Entering CCertTemplate::ModifyCriticalExtensions (%s, bAdd=%s)\n",
  969. (PCWSTR) szExtension, bAdd ? L"true" : L"false");
  970. PWSTR* pawszCriticalExtensions = 0;
  971. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  972. CERTTYPE_PROP_CRITICAL_EXTENSIONS,
  973. &pawszCriticalExtensions);
  974. if ( SUCCEEDED (hr) )
  975. {
  976. if ( !pawszCriticalExtensions )
  977. pawszCriticalExtensions = (PWSTR*) LocalAlloc (LPTR, sizeof (PWSTR));
  978. if ( pawszCriticalExtensions )
  979. {
  980. hr = ModifyStringList (CERTTYPE_PROP_CRITICAL_EXTENSIONS,
  981. &pawszCriticalExtensions, szExtension, bAdd);
  982. LocalFree (pawszCriticalExtensions);
  983. }
  984. else
  985. hr = E_OUTOFMEMORY;
  986. }
  987. else
  988. {
  989. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_CRITICAL_EXTENSIONS) failed: 0x%x\n", hr);
  990. }
  991. _TRACE (-1, L"Leaving CCertTemplate::ModifyCriticalExtensions: 0x%x\n", hr);
  992. return hr;
  993. }
  994. HRESULT CCertTemplate::ModifyCSPList(const CString &szCSPName, bool bAdd)
  995. {
  996. _TRACE (1, L"Entering CCertTemplate::ModifyCSPList (%s, bAdd=%s)\n",
  997. (PCWSTR) szCSPName, bAdd ? L"true" : L"false");
  998. PWSTR* pawszCSPList = 0;
  999. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1000. CERTTYPE_PROP_CSP_LIST,
  1001. &pawszCSPList);
  1002. if ( SUCCEEDED (hr) )
  1003. {
  1004. if ( !pawszCSPList )
  1005. pawszCSPList = (PWSTR*) LocalAlloc (LPTR, sizeof (PWSTR*));
  1006. if ( pawszCSPList )
  1007. {
  1008. hr = ModifyStringList (CERTTYPE_PROP_CSP_LIST,
  1009. &pawszCSPList, szCSPName, bAdd);
  1010. LocalFree (pawszCSPList);
  1011. }
  1012. else
  1013. hr = E_FAIL;
  1014. }
  1015. else
  1016. {
  1017. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_CSP_LIST) failed: 0x%x\n", hr);
  1018. }
  1019. _TRACE (-1, L"Leaving CCertTemplate::ModifyCSPList: 0x%x\n", hr);
  1020. return hr;
  1021. }
  1022. HRESULT CCertTemplate::ModifyRAIssuancePolicyList(const CString &szRAPolicyOID, bool bAdd)
  1023. {
  1024. _TRACE (1, L"Entering CCertTemplate::ModifyRAIssuancePolicyList (%s, bAdd=%s)\n",
  1025. (PCWSTR) szRAPolicyOID, bAdd ? L"true" : L"false");
  1026. PWSTR* pawszRAPolicyList = 0;
  1027. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1028. CERTTYPE_PROP_RA_POLICY,
  1029. &pawszRAPolicyList);
  1030. if ( SUCCEEDED (hr) )
  1031. {
  1032. if ( !pawszRAPolicyList )
  1033. pawszRAPolicyList = (PWSTR*) LocalAlloc (LPTR, sizeof (PWSTR*));
  1034. if ( pawszRAPolicyList )
  1035. {
  1036. hr = ModifyStringList (CERTTYPE_PROP_RA_POLICY,
  1037. &pawszRAPolicyList, szRAPolicyOID, bAdd);
  1038. LocalFree (pawszRAPolicyList);
  1039. }
  1040. else
  1041. hr = E_FAIL;
  1042. }
  1043. else
  1044. {
  1045. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_RA_POLICY) failed: 0x%x\n", hr);
  1046. }
  1047. _TRACE (-1, L"Leaving CCertTemplate::ModifyRAIssuancePolicyList: 0x%x\n", hr);
  1048. return hr;
  1049. }
  1050. HRESULT CCertTemplate::ModifyRAApplicationPolicyList(const CString &szRAPolicyOID, bool bAdd)
  1051. {
  1052. _TRACE (1, L"Entering CCertTemplate::ModifyRAApplicationPolicyList (%s, bAdd=%s)\n",
  1053. (PCWSTR) szRAPolicyOID, bAdd ? L"true" : L"false");
  1054. PWSTR* pawszRAPolicyList = 0;
  1055. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1056. CERTTYPE_PROP_RA_APPLICATION_POLICY,
  1057. &pawszRAPolicyList);
  1058. if ( SUCCEEDED (hr) )
  1059. {
  1060. if ( !pawszRAPolicyList )
  1061. pawszRAPolicyList = (PWSTR*) LocalAlloc (LPTR, sizeof (PWSTR*));
  1062. if ( pawszRAPolicyList )
  1063. {
  1064. hr = ModifyStringList (CERTTYPE_PROP_RA_APPLICATION_POLICY,
  1065. &pawszRAPolicyList, szRAPolicyOID, bAdd);
  1066. LocalFree (pawszRAPolicyList);
  1067. }
  1068. else
  1069. hr = E_FAIL;
  1070. }
  1071. else
  1072. {
  1073. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_RA_APPLICATION_POLICY) failed: 0x%x\n", hr);
  1074. }
  1075. _TRACE (-1, L"Leaving CCertTemplate::ModifyRAApplicationPolicyList: 0x%x\n", hr);
  1076. return hr;
  1077. }
  1078. HRESULT CCertTemplate::ModifySupercededTemplateList(
  1079. const CString &szSupercededTemplateName,
  1080. bool bAdd)
  1081. {
  1082. _TRACE (1, L"Entering CCertTemplate::ModifySupercededTemplateList (%s, bAdd=%s)\n",
  1083. (PCWSTR) szSupercededTemplateName, bAdd ? L"true" : L"false");
  1084. PWSTR* pawszSupercededTemplateList = 0;
  1085. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1086. CERTTYPE_PROP_SUPERSEDE,
  1087. &pawszSupercededTemplateList);
  1088. if ( SUCCEEDED (hr) )
  1089. {
  1090. if ( !pawszSupercededTemplateList )
  1091. pawszSupercededTemplateList = (PWSTR*) LocalAlloc (LPTR, sizeof (PWSTR*));
  1092. if ( pawszSupercededTemplateList )
  1093. {
  1094. hr = ModifyStringList (CERTTYPE_PROP_SUPERSEDE,
  1095. &pawszSupercededTemplateList, szSupercededTemplateName, bAdd);
  1096. LocalFree (pawszSupercededTemplateList);
  1097. }
  1098. else
  1099. hr = E_FAIL;
  1100. }
  1101. else
  1102. {
  1103. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_SUPERSEDE) failed: 0x%x\n", hr);
  1104. }
  1105. _TRACE (-1, L"Leaving CCertTemplate::ModifySupercededTemplateList: 0x%x\n", hr);
  1106. return hr;
  1107. }
  1108. HRESULT CCertTemplate::ModifyStringList(const CString& szPropertyName,
  1109. PWSTR** ppStringList,
  1110. const CString &szValue,
  1111. bool bAdd)
  1112. {
  1113. _TRACE (1, L"Entering CCertTemplate::ModifyStringList (%s, bAdd=%s)\n",
  1114. (PCWSTR) szValue, bAdd ? L"true" : L"false");
  1115. HRESULT hr = S_OK;
  1116. if ( !szValue.IsEmpty () )
  1117. {
  1118. bool bFound = false;
  1119. int nCnt = 0;
  1120. size_t cbNameBytes = 0;
  1121. int nDeleteIndex = -1;
  1122. // count the number of items we already have and get the string lengths
  1123. for (int nIndex = 0; (*ppStringList)[nIndex]; nIndex++)
  1124. {
  1125. nCnt++;
  1126. // security review 2/21/2002 BryanWal ok
  1127. cbNameBytes += (wcslen ((*ppStringList)[nIndex]) + 1) * sizeof (WCHAR);
  1128. if ( !LocaleStrCmp (szValue, (*ppStringList)[nIndex]) )
  1129. {
  1130. bFound = true;
  1131. if ( !bAdd )
  1132. nDeleteIndex = nIndex;
  1133. }
  1134. }
  1135. // Adding a name: If the name was found, nothing needs to be done,
  1136. // otherwise, increment the count and rebuild the list.
  1137. // Removing a name: If the name was not found, nothing needs to be
  1138. // done, otherwise, decrement the count and rebuild the list.
  1139. if ( (bAdd && !bFound) || (!bAdd && bFound) )
  1140. {
  1141. // awszResult is an array of pointers to different offsets of
  1142. // null-terminated strings stored in a contiguous array
  1143. PWSTR *awszResult = 0;
  1144. if ( bAdd )
  1145. nCnt++;
  1146. else
  1147. nCnt--;
  1148. if ( bAdd )
  1149. {
  1150. // security review 2/21/2002 BryanWal ok
  1151. cbNameBytes += (wcslen (szValue) + 1 ) * sizeof (WCHAR);
  1152. }
  1153. size_t cbBuf = sizeof (WCHAR*) * (nCnt + 1) + // the WCHAR pointers
  1154. cbNameBytes; // the strings themselves
  1155. awszResult = (WCHAR**) LocalAlloc (LPTR, cbBuf);
  1156. if ( awszResult )
  1157. {
  1158. // set the ptr to the space after the last valid index (
  1159. // including the NULL terminator
  1160. PWSTR ptr = (WCHAR*) &awszResult[nCnt+1];
  1161. int nTgtIndex = 0;
  1162. for (int nSrcIndex = 0; (*ppStringList)[nSrcIndex]; nSrcIndex++)
  1163. {
  1164. // If we are removing the name, and this is the item to be
  1165. // removed, then skip this name and go to the next
  1166. if ( !bAdd && nSrcIndex == nDeleteIndex )
  1167. continue;
  1168. awszResult[nTgtIndex] = ptr;
  1169. // security review 2/21/2002 BryanWal ok
  1170. ptr += wcslen ((*ppStringList)[nSrcIndex]) + 1; // ptr arithmetic - increments by sizeof (WCHAR)
  1171. // security review 2/21/2002 BryanWal ok
  1172. wcscpy (awszResult[nTgtIndex], (*ppStringList)[nSrcIndex]);
  1173. nTgtIndex++;
  1174. }
  1175. // If we are adding, append the name here
  1176. if ( bAdd )
  1177. {
  1178. awszResult[nTgtIndex] = ptr;
  1179. // security review 2/21/2002 BryanWal ok
  1180. ptr += wcslen (szValue) + 1; // ptr arithmetic - increments by sizeof (WCHAR)
  1181. // security review 2/21/2002 BryanWal ok
  1182. wcscpy (awszResult[nTgtIndex], szValue);
  1183. nTgtIndex++;
  1184. }
  1185. _ASSERT (nTgtIndex == nCnt);
  1186. awszResult[nTgtIndex] = 0;
  1187. LocalFree (*ppStringList);
  1188. (*ppStringList) = awszResult;
  1189. hr = CASetCertTypePropertyEx (m_hCertType,
  1190. szPropertyName,
  1191. (*ppStringList));
  1192. if ( FAILED (hr) )
  1193. {
  1194. _TRACE (0, L"CASetCertTypePropertyEx (%s) failed: 0x%x\n",
  1195. szPropertyName, hr);
  1196. }
  1197. }
  1198. else
  1199. hr = E_OUTOFMEMORY;
  1200. }
  1201. }
  1202. else
  1203. hr = E_INVALIDARG;
  1204. _TRACE (-1, L"Leaving CCertTemplate::ModifyStringList: 0x%x\n", hr);
  1205. return hr;
  1206. }
  1207. HRESULT CCertTemplate::IsExtensionCritical (PCWSTR szExtension, bool& bCritical)
  1208. {
  1209. _TRACE (1, L"Entering CCertTemplate::IsExtensionCritical (szExtension=%s\n", szExtension);
  1210. // Get Cryptographic Service Providers
  1211. PWSTR* pawszCriticalExtensionList = 0;
  1212. bCritical = false;
  1213. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1214. CERTTYPE_PROP_CRITICAL_EXTENSIONS,
  1215. &pawszCriticalExtensionList);
  1216. if ( SUCCEEDED (hr) )
  1217. {
  1218. if ( pawszCriticalExtensionList )
  1219. {
  1220. for (int nIndex = 0; pawszCriticalExtensionList[nIndex]; nIndex++)
  1221. {
  1222. if ( !wcscmp (szExtension, pawszCriticalExtensionList[nIndex]) )
  1223. {
  1224. bCritical = true;
  1225. break;
  1226. }
  1227. }
  1228. LocalFree (pawszCriticalExtensionList);
  1229. }
  1230. else
  1231. hr = E_FAIL;
  1232. }
  1233. else
  1234. {
  1235. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_CRITICAL_EXTENSIONS) failed: 0x%x\n", hr);
  1236. }
  1237. _TRACE (-1, L"Leaving CCertTemplate::GeIsExtensionCriticaltCSP (szCSP=%s, bCritical=%s): 0x%x\n",
  1238. szExtension, bCritical ? L"true" : L"false", hr);
  1239. return hr;
  1240. }
  1241. HRESULT CCertTemplate::GetCSP(int nIndex, CString &szCSP)
  1242. {
  1243. _TRACE (1, L"Entering CCertTemplate::GetCSP (nIndex=%d\n", nIndex);
  1244. // Get Cryptographic Service Providers
  1245. PWSTR* pawszCSPList = 0;
  1246. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1247. CERTTYPE_PROP_CSP_LIST,
  1248. &pawszCSPList);
  1249. if ( SUCCEEDED (hr) )
  1250. {
  1251. if ( pawszCSPList )
  1252. {
  1253. int nCnt = 0;
  1254. while ( pawszCSPList[nCnt] )
  1255. nCnt++;
  1256. if ( nIndex < nCnt )
  1257. szCSP = pawszCSPList[nIndex];
  1258. else
  1259. hr = E_INVALIDARG;
  1260. LocalFree (pawszCSPList);
  1261. }
  1262. else
  1263. hr = E_FAIL;
  1264. }
  1265. else
  1266. {
  1267. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_CSP_LIST) failed: 0x%x\n", hr);
  1268. }
  1269. _TRACE (-1, L"Leaving CCertTemplate::GetCSP (szCSP=%s): 0x%x\n",
  1270. (PCWSTR) szCSP, hr);
  1271. return hr;
  1272. }
  1273. HRESULT CCertTemplate::GetCertPolicy (int nIndex, CString &szCertPolicy)
  1274. {
  1275. _TRACE (1, L"Entering CCertTemplate::GetCertPolicy (nIndex=%d\n", nIndex);
  1276. HRESULT hr = S_OK;
  1277. PWSTR* pawszCertPolicyList = 0;
  1278. hr = CAGetCertTypeProperty (m_hCertType,
  1279. CERTTYPE_PROP_POLICY,
  1280. &pawszCertPolicyList);
  1281. if ( SUCCEEDED (hr) )
  1282. {
  1283. if ( pawszCertPolicyList )
  1284. {
  1285. int nCnt = 0;
  1286. while ( pawszCertPolicyList[nCnt] )
  1287. nCnt++;
  1288. if ( nIndex < nCnt )
  1289. szCertPolicy = pawszCertPolicyList[nIndex];
  1290. else
  1291. hr = E_FAIL;
  1292. LocalFree (pawszCertPolicyList);
  1293. }
  1294. else
  1295. hr = E_FAIL;
  1296. }
  1297. else
  1298. {
  1299. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_POLICY) failed: 0x%x\n", hr);
  1300. }
  1301. _TRACE (-1, L"Leaving CCertTemplate::GetCertPolicy (szCSP=%s): 0x%x\n",
  1302. (PCWSTR) szCertPolicy, hr);
  1303. return hr;
  1304. }
  1305. HRESULT CCertTemplate::GetRAIssuancePolicy (int nIndex, CString &szRAPolicyOID)
  1306. {
  1307. _TRACE (1, L"Entering CCertTemplate::GetRAIssuancePolicy (nIndex=%d\n", nIndex);
  1308. PWSTR* pawszRAPolicyList = 0;
  1309. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1310. CERTTYPE_PROP_RA_POLICY,
  1311. &pawszRAPolicyList);
  1312. if ( SUCCEEDED (hr) )
  1313. {
  1314. if ( pawszRAPolicyList )
  1315. {
  1316. int nCnt = 0;
  1317. while ( pawszRAPolicyList[nCnt] )
  1318. nCnt++;
  1319. if ( nIndex < nCnt )
  1320. szRAPolicyOID = pawszRAPolicyList[nIndex];
  1321. else
  1322. hr = E_FAIL;
  1323. LocalFree (pawszRAPolicyList);
  1324. }
  1325. else
  1326. hr = E_FAIL;
  1327. }
  1328. else
  1329. {
  1330. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_RA_POLICY) failed: 0x%x\n", hr);
  1331. }
  1332. _TRACE (-1, L"Leaving CCertTemplate::GetRAIssuancePolicy (szRAPolicyOID=%s): 0x%x\n",
  1333. (PCWSTR) szRAPolicyOID, hr);
  1334. return hr;
  1335. }
  1336. HRESULT CCertTemplate::GetRAApplicationPolicy (int nIndex, CString &szRAPolicyOID)
  1337. {
  1338. _TRACE (1, L"Entering CCertTemplate::GetRAApplicationPolicy (nIndex=%d\n", nIndex);
  1339. PWSTR* pawszRAPolicyList = 0;
  1340. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1341. CERTTYPE_PROP_RA_APPLICATION_POLICY,
  1342. &pawszRAPolicyList);
  1343. if ( SUCCEEDED (hr) )
  1344. {
  1345. if ( pawszRAPolicyList )
  1346. {
  1347. int nCnt = 0;
  1348. while ( pawszRAPolicyList[nCnt] )
  1349. nCnt++;
  1350. if ( nIndex < nCnt )
  1351. szRAPolicyOID = pawszRAPolicyList[nIndex];
  1352. else
  1353. hr = E_FAIL;
  1354. LocalFree (pawszRAPolicyList);
  1355. }
  1356. else
  1357. hr = E_FAIL;
  1358. }
  1359. else
  1360. {
  1361. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_RA_APPLICATION_POLICY) failed: 0x%x\n", hr);
  1362. }
  1363. _TRACE (-1, L"Leaving CCertTemplate::GetRAApplicationPolicy (szRAPolicyOID=%s): 0x%x\n",
  1364. (PCWSTR) szRAPolicyOID, hr);
  1365. return hr;
  1366. }
  1367. HRESULT CCertTemplate::GetSupercededTemplate(int nIndex, CString &szSupercededTemplate)
  1368. {
  1369. _TRACE (1, L"Entering CCertTemplate::GetSupercededTemplate (nIndex=%d\n", nIndex);
  1370. PWSTR* pawszSupercededTemplateList = 0;
  1371. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1372. CERTTYPE_PROP_SUPERSEDE,
  1373. &pawszSupercededTemplateList);
  1374. if ( SUCCEEDED (hr) )
  1375. {
  1376. if ( pawszSupercededTemplateList )
  1377. {
  1378. int nCnt = 0;
  1379. while ( pawszSupercededTemplateList[nCnt] )
  1380. nCnt++;
  1381. if ( nIndex < nCnt )
  1382. szSupercededTemplate = pawszSupercededTemplateList[nIndex];
  1383. else
  1384. hr = E_FAIL;
  1385. LocalFree (pawszSupercededTemplateList);
  1386. }
  1387. else
  1388. hr = E_FAIL;
  1389. }
  1390. else
  1391. {
  1392. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_SUPERSEDE) failed: 0x%x\n", hr);
  1393. }
  1394. _TRACE (-1, L"Leaving CCertTemplate::GetSupercededTemplate (szSupercededTemplate=%s): 0x%x\n",
  1395. (PCWSTR) szSupercededTemplate, hr);
  1396. return hr;
  1397. }
  1398. bool CCertTemplate::ReadOnly() const
  1399. {
  1400. return m_fIsReadOnly;
  1401. }
  1402. HRESULT CCertTemplate::SetSecurity(PSECURITY_DESCRIPTOR pSD)
  1403. {
  1404. HRESULT hr = CACertTypeSetSecurity (m_hCertType, pSD);
  1405. if (S_OK != hr)
  1406. return hr;
  1407. for (int nTry = 0; nTry < 20; nTry++)
  1408. {
  1409. hr = CAUpdateCertType(m_hCertType);
  1410. if ( FAILED (hr) && HRESULT_FROM_WIN32 (ERROR_DS_OBJ_NOT_FOUND) == hr )
  1411. {
  1412. // pause and retry up to 20 times - object was renamed and needs a
  1413. // little time to propagate
  1414. // NTRAID# 643744 Certtmpl: Cannot save security settings on newly
  1415. // cloned template from member in non Root Domain -- object not found
  1416. Sleep (1000);
  1417. continue;
  1418. }
  1419. else
  1420. break;
  1421. }
  1422. if ( FAILED (hr) )
  1423. Cancel ();
  1424. return hr;
  1425. }
  1426. HRESULT CCertTemplate::GetSecurity(PSECURITY_DESCRIPTOR *ppSD) const
  1427. {
  1428. return CACertTypeGetSecurity (m_hCertType, ppSD);
  1429. }
  1430. CString CCertTemplate::GetLDAPPath() const
  1431. {
  1432. return m_szLDAPPath;
  1433. }
  1434. HRESULT CCertTemplate::SetValidityPeriod(int nDays)
  1435. {
  1436. HRESULT hr = S_OK;
  1437. if ( nDays >= 0 )
  1438. this->m_nNewValidityDays = nDays;
  1439. else
  1440. hr = E_INVALIDARG;
  1441. return hr;
  1442. }
  1443. HRESULT CCertTemplate::SetRenewalPeriod(int nDays)
  1444. {
  1445. HRESULT hr = S_OK;
  1446. if ( nDays >= 0 )
  1447. this->m_nNewRenewalDays = nDays;
  1448. else
  1449. hr = E_INVALIDARG;
  1450. return hr;
  1451. }
  1452. HRESULT CCertTemplate::SetPublishToDS(bool bPublish)
  1453. {
  1454. _TRACE (1, L"Entering CCertTemplate::SetPublishToDS - m_hCertType = 0x%x\n", m_hCertType);
  1455. HRESULT hr = SetFlag (CERTTYPE_ENROLLMENT_FLAG, CT_FLAG_PUBLISH_TO_DS, bPublish);
  1456. _TRACE (-1, L"Leaving CCertTemplate::SetPublishToDS: 0x%x\n", hr);
  1457. return hr;
  1458. }
  1459. HRESULT CCertTemplate::GetRANumSignaturesRequired(DWORD &dwNumSignatures)
  1460. {
  1461. _TRACE (1, L"Entering CCertTemplate::GetRANumSignaturesRequired - m_hCertType = 0x%x\n", m_hCertType);
  1462. HRESULT hr = S_OK;
  1463. if ( m_hCertType )
  1464. {
  1465. hr = CAGetCertTypePropertyEx (m_hCertType,
  1466. CERTTYPE_PROP_RA_SIGNATURE,
  1467. &dwNumSignatures);
  1468. if ( FAILED (hr) )
  1469. {
  1470. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_RA_SIGNATURE) failed: 0x%x\n", hr);
  1471. }
  1472. }
  1473. else
  1474. hr = E_FAIL;
  1475. _TRACE (-1, L"Leaving CCertTemplate::GetRANumSignaturesRequired: 0x%x\n", hr);
  1476. return hr;
  1477. }
  1478. HRESULT CCertTemplate::SetRANumSignaturesRequired(DWORD dwNumSignaturesRequired)
  1479. {
  1480. _TRACE (1, L"Entering CCertTemplate::SetRANumSignaturesRequired (%d)- m_hCertType = 0x%x\n",
  1481. dwNumSignaturesRequired, m_hCertType);
  1482. HRESULT hr = S_OK;
  1483. if ( m_hCertType )
  1484. {
  1485. hr = CASetCertTypePropertyEx (m_hCertType,
  1486. CERTTYPE_PROP_RA_SIGNATURE,
  1487. &dwNumSignaturesRequired);
  1488. if ( FAILED (hr) )
  1489. {
  1490. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_RA_SIGNATURE) failed: 0x%x\n", hr);
  1491. }
  1492. }
  1493. else
  1494. hr = E_FAIL;
  1495. _TRACE (-1, L"Leaving CCertTemplate::SetRANumSignaturesRequired (): 0x%x\n", hr);
  1496. return hr;
  1497. }
  1498. bool CCertTemplate::ReenrollmentValidWithPreviousApproval() const
  1499. {
  1500. return m_dwEnrollmentFlags & CT_FLAG_PREVIOUS_APPROVAL_VALIDATE_REENROLLMENT ? true : false;
  1501. }
  1502. HRESULT CCertTemplate::SetReenrollmentValidWithPreviousApproval(bool bValid)
  1503. {
  1504. _TRACE (1, L"Entering CCertTemplate::SetReenrollmentValidWithPreviousApproval - m_hCertType = 0x%x\n", m_hCertType);
  1505. HRESULT hr = SetFlag (CERTTYPE_ENROLLMENT_FLAG, CT_FLAG_PREVIOUS_APPROVAL_VALIDATE_REENROLLMENT, bValid);
  1506. _TRACE (-1, L"Leaving CCertTemplate::SetReenrollmentValidWithPreviousApproval: 0x%x\n", hr);
  1507. return hr;
  1508. }
  1509. bool CCertTemplate::PendAllRequests() const
  1510. {
  1511. return m_dwEnrollmentFlags & CT_FLAG_PEND_ALL_REQUESTS ? true : false;
  1512. }
  1513. HRESULT CCertTemplate::SetPendAllRequests(bool bPend)
  1514. {
  1515. _TRACE (1, L"Entering CCertTemplate::SetPendAllRequests - m_hCertType = 0x%x\n", m_hCertType);
  1516. HRESULT hr = SetFlag (CERTTYPE_ENROLLMENT_FLAG, CT_FLAG_PEND_ALL_REQUESTS, bPend);
  1517. _TRACE (-1, L"Leaving CCertTemplate::SetPendAllRequests: 0x%x\n", hr);
  1518. return hr;
  1519. }
  1520. HRESULT CCertTemplate::GetMajorVersion(DWORD &dwMajorVersion) const
  1521. {
  1522. // _TRACE (1, L"Entering CCertTemplate::GetMajorVersion\n");
  1523. HRESULT hr = S_OK;
  1524. if ( m_hCertType )
  1525. {
  1526. hr = CAGetCertTypePropertyEx (m_hCertType,
  1527. CERTTYPE_PROP_REVISION,
  1528. &dwMajorVersion);
  1529. if ( FAILED (hr) )
  1530. {
  1531. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_REVISION) failed: 0x%x\n", hr);
  1532. }
  1533. }
  1534. else
  1535. hr = E_FAIL;
  1536. // _TRACE (-1, L"Leaving CCertTemplate::GetMajorVersion (dwMajorVersion = %d) : 0x%x\n",
  1537. // dwMajorVersion, hr);
  1538. return hr;
  1539. }
  1540. HRESULT CCertTemplate::GetMinorVersion(DWORD &dwMinorVersion) const
  1541. {
  1542. // _TRACE (1, L"Entering CCertTemplate::GetMinorVersion\n");
  1543. HRESULT hr = S_OK;
  1544. if ( m_hCertType )
  1545. {
  1546. hr = CAGetCertTypePropertyEx (m_hCertType,
  1547. CERTTYPE_PROP_MINOR_REVISION,
  1548. &dwMinorVersion);
  1549. if ( FAILED (hr) )
  1550. {
  1551. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_MINOR_REVISION) failed: 0x%x\n", hr);
  1552. }
  1553. }
  1554. else
  1555. hr = E_FAIL;
  1556. // _TRACE (-1, L"Leaving CCertTemplate::GetMinorVersion (dwMinorVersion = %d) : 0x%x\n",
  1557. // dwMinorVersion, hr);
  1558. return hr;
  1559. }
  1560. HRESULT CCertTemplate::IncrementMajorVersion()
  1561. {
  1562. _TRACE (1, L"Entering CCertTemplate::IncrementMajorVersion\n");
  1563. HRESULT hr = S_OK;
  1564. DWORD dwMajorVersion = 0;
  1565. if ( m_hCertType )
  1566. {
  1567. hr = CAGetCertTypePropertyEx (m_hCertType,
  1568. CERTTYPE_PROP_REVISION,
  1569. &dwMajorVersion);
  1570. if ( SUCCEEDED (hr) )
  1571. {
  1572. dwMajorVersion++;
  1573. hr = CASetCertTypePropertyEx (m_hCertType,
  1574. CERTTYPE_PROP_REVISION,
  1575. &dwMajorVersion);
  1576. if ( SUCCEEDED (hr) )
  1577. {
  1578. DWORD dwMinorVersion = 0;
  1579. hr = CASetCertTypePropertyEx (m_hCertType,
  1580. CERTTYPE_PROP_MINOR_REVISION,
  1581. &dwMinorVersion);
  1582. if ( FAILED (hr) )
  1583. {
  1584. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_MINOR_REVISION, %d) failed: 0x%x\n",
  1585. dwMinorVersion, hr);
  1586. }
  1587. }
  1588. else
  1589. {
  1590. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_REVISION, %d) failed: 0x%x\n",
  1591. dwMajorVersion, hr);
  1592. }
  1593. }
  1594. else
  1595. {
  1596. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_REVISION) failed: 0x%x\n", hr);
  1597. }
  1598. }
  1599. else
  1600. hr = E_FAIL;
  1601. _TRACE (-1, L"Leaving CCertTemplate::IncrementMajorVersion (dwMajorVersion = %d) : 0x%x\n",
  1602. dwMajorVersion, hr);
  1603. return hr;
  1604. }
  1605. HRESULT CCertTemplate::IncrementMinorVersion()
  1606. {
  1607. _TRACE (1, L"Entering CCertTemplate::IncrementMinorVersion\n");
  1608. HRESULT hr = S_OK;
  1609. DWORD dwMinorVersion = 0;
  1610. if ( m_hCertType )
  1611. {
  1612. hr = CAGetCertTypePropertyEx (m_hCertType,
  1613. CERTTYPE_PROP_MINOR_REVISION,
  1614. &dwMinorVersion);
  1615. if ( SUCCEEDED (hr) )
  1616. {
  1617. dwMinorVersion++;
  1618. hr = CASetCertTypePropertyEx (m_hCertType,
  1619. CERTTYPE_PROP_MINOR_REVISION,
  1620. &dwMinorVersion);
  1621. if ( FAILED (hr) )
  1622. {
  1623. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_MINOR_REVISION, %d) failed: 0x%x\n",
  1624. dwMinorVersion, hr);
  1625. }
  1626. }
  1627. else
  1628. {
  1629. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_MINOR_REVISION) failed: 0x%x\n", hr);
  1630. }
  1631. }
  1632. else
  1633. hr = E_FAIL;
  1634. _TRACE (-1, L"Leaving CCertTemplate::IncrementMinorVersion (dwMinorVersion = %d) : 0x%x\n",
  1635. dwMinorVersion, hr);
  1636. return hr;
  1637. }
  1638. bool CCertTemplate::GoodForAutoEnrollment() const
  1639. {
  1640. bool bGoodForAutoEnrollment = false;
  1641. // Bug 175912 Version 1 type templates not good for autoenrollment
  1642. if ( (GetType () > 1) && (m_dwEnrollmentFlags & CT_FLAG_AUTO_ENROLLMENT) )
  1643. bGoodForAutoEnrollment = true;
  1644. return bGoodForAutoEnrollment;
  1645. }
  1646. HRESULT CCertTemplate::SetKeyUsage(CRYPT_BIT_BLOB* pKeyUsage, bool bCritical)
  1647. {
  1648. _TRACE (1, L"Entering CCertTemplate::SetKeyUsage\n");
  1649. HRESULT hr = S_OK;
  1650. if ( pKeyUsage )
  1651. {
  1652. hr = CASetCertTypeExtension(
  1653. m_hCertType,
  1654. TEXT (szOID_KEY_USAGE),
  1655. bCritical ? CA_EXT_FLAG_CRITICAL : 0,
  1656. pKeyUsage);
  1657. if ( FAILED (hr) )
  1658. {
  1659. _TRACE (0, L"CASetCertTypeExtension (szOID_KEY_USAGE) failed: 0x%x\n", hr);
  1660. }
  1661. }
  1662. else
  1663. hr = E_POINTER;
  1664. _TRACE (-1, L"Leaving CCertTemplate::SetKeyUsage: 0x%x\n", hr);
  1665. return hr;
  1666. }
  1667. HRESULT CCertTemplate::SetBasicConstraints(PCERT_BASIC_CONSTRAINTS2_INFO pBCInfo, bool bCritical)
  1668. {
  1669. _TRACE (1, L"Entering CCertTemplate::SetBasicConstraints\n");
  1670. HRESULT hr = S_OK;
  1671. if ( pBCInfo )
  1672. {
  1673. hr = CASetCertTypeExtension(
  1674. m_hCertType,
  1675. TEXT (szOID_BASIC_CONSTRAINTS2),
  1676. bCritical ? CA_EXT_FLAG_CRITICAL : 0,
  1677. pBCInfo);
  1678. if ( FAILED (hr) )
  1679. {
  1680. _TRACE (0, L"CASetCertTypeExtension (X509_BASIC_CONSTRAINTS2) failed: 0x%x\n", hr);
  1681. }
  1682. }
  1683. else
  1684. hr = E_POINTER;
  1685. _TRACE (-1, L"Leaving CCertTemplate::SetBasicConstraints: 0x%x\n", hr);
  1686. return hr;
  1687. }
  1688. bool CCertTemplate::CheckDSCert() const
  1689. {
  1690. return (m_dwEnrollmentFlags & CT_FLAG_AUTO_ENROLLMENT_CHECK_USER_DS_CERTIFICATE) ? true : false;
  1691. }
  1692. HRESULT CCertTemplate::SetCheckDSCert(bool bCheck)
  1693. {
  1694. return SetFlag (CERTTYPE_ENROLLMENT_FLAG,
  1695. CT_FLAG_AUTO_ENROLLMENT_CHECK_USER_DS_CERTIFICATE, bCheck);
  1696. }
  1697. bool CCertTemplate::RemoveInvalidCertFromPersonalStore () const
  1698. {
  1699. return (m_dwEnrollmentFlags & CT_FLAG_REMOVE_INVALID_CERTIFICATE_FROM_PERSONAL_STORE) ? true : false;
  1700. }
  1701. HRESULT CCertTemplate::SetRemoveInvalidCertFromPersonalStore(bool bRemove)
  1702. {
  1703. return SetFlag (CERTTYPE_ENROLLMENT_FLAG,
  1704. CT_FLAG_REMOVE_INVALID_CERTIFICATE_FROM_PERSONAL_STORE, bRemove);
  1705. }
  1706. bool CCertTemplate::UserInteractionRequired () const
  1707. {
  1708. return (m_dwEnrollmentFlags & CT_FLAG_USER_INTERACTION_REQUIRED) ? true : false;
  1709. }
  1710. HRESULT CCertTemplate::SetUserInteractionRequired(bool bSet)
  1711. {
  1712. return SetFlag (CERTTYPE_ENROLLMENT_FLAG,
  1713. CT_FLAG_USER_INTERACTION_REQUIRED, bSet);
  1714. }
  1715. bool CCertTemplate::StrongKeyProtectionRequired () const
  1716. {
  1717. return (m_dwPrivateKeyFlags & CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED) ? true : false;
  1718. }
  1719. HRESULT CCertTemplate::SetStrongKeyProtectionRequired(bool bSet)
  1720. {
  1721. return SetFlag (CERTTYPE_PRIVATE_KEY_FLAG,
  1722. CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED, bSet);
  1723. }
  1724. HRESULT CCertTemplate::GetEnhancedKeyUsage (int nIndex, CString &szEKU)
  1725. {
  1726. _TRACE (1, L"Entering CCertTemplate::GetEnhancedKeyUsage (nIndex=%d\n", nIndex);
  1727. HRESULT hr = S_OK;
  1728. PWSTR* pawszEKU = 0;
  1729. hr = CAGetCertTypeProperty (m_hCertType,
  1730. CERTTYPE_PROP_EXTENDED_KEY_USAGE,
  1731. &pawszEKU);
  1732. if ( SUCCEEDED (hr) )
  1733. {
  1734. if ( pawszEKU )
  1735. {
  1736. int nCnt = 0;
  1737. while ( pawszEKU[nCnt] )
  1738. nCnt++;
  1739. if ( nIndex < nCnt )
  1740. szEKU = pawszEKU[nIndex];
  1741. else
  1742. hr = E_FAIL;
  1743. }
  1744. else
  1745. hr = E_FAIL;
  1746. LocalFree (pawszEKU);
  1747. }
  1748. else
  1749. {
  1750. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_EXTENDED_KEY_USAGE) failed: 0x%x\n", hr);
  1751. }
  1752. _TRACE (-1, L"Leaving CCertTemplate::GetEnhancedKeyUsage (szEKU=%s): 0x%x\n",
  1753. (PCWSTR) szEKU, hr);
  1754. return hr;
  1755. }
  1756. HRESULT CCertTemplate::GetApplicationPolicy (int nIndex, CString &szAppPolicy)
  1757. {
  1758. _TRACE (1, L"Entering CCertTemplate::GetApplicationPolicy (nIndex=%d\n", nIndex);
  1759. HRESULT hr = S_OK;
  1760. PWSTR* pawszAppPolicy = 0;
  1761. hr = CAGetCertTypeProperty (m_hCertType,
  1762. CERTTYPE_PROP_APPLICATION_POLICY,
  1763. &pawszAppPolicy);
  1764. if ( SUCCEEDED (hr) )
  1765. {
  1766. if ( pawszAppPolicy )
  1767. {
  1768. int nCnt = 0;
  1769. while ( pawszAppPolicy[nCnt] )
  1770. nCnt++;
  1771. if ( nIndex < nCnt )
  1772. szAppPolicy = pawszAppPolicy[nIndex];
  1773. else
  1774. hr = E_FAIL;
  1775. }
  1776. else
  1777. hr = E_FAIL;
  1778. LocalFree (pawszAppPolicy);
  1779. }
  1780. else
  1781. {
  1782. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_APPLICATION_POLICY) failed: 0x%x\n", hr);
  1783. }
  1784. _TRACE (-1, L"Leaving CCertTemplate::GetApplicationPolicy (szAppPolicy=%s): 0x%x\n",
  1785. (PCWSTR) szAppPolicy, hr);
  1786. return hr;
  1787. }
  1788. HRESULT CCertTemplate::SetEnhancedKeyUsage (const PWSTR* pawszEKU, bool bCritical)
  1789. {
  1790. _TRACE (1, L"Entering CCertTemplate::SetEnhancedKeyUsage ()\n");
  1791. HRESULT hr = S_OK;
  1792. hr = CASetCertTypePropertyEx (m_hCertType,
  1793. CERTTYPE_PROP_EXTENDED_KEY_USAGE,
  1794. (PVOID) pawszEKU);
  1795. if ( SUCCEEDED (hr) )
  1796. {
  1797. hr = ModifyCriticalExtensions (szOID_ENHANCED_KEY_USAGE, bCritical);
  1798. }
  1799. else
  1800. {
  1801. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_EXTENDED_KEY_USAGE) failed: 0x%x\n",
  1802. hr);
  1803. }
  1804. _TRACE (-1, L"Leaving CCertTemplate::SetEnhancedKeyUsage: 0x%x\n", hr);
  1805. return hr;
  1806. }
  1807. HRESULT CCertTemplate::SetApplicationPolicy (const PWSTR* pawszAppPolicy, bool bCritical)
  1808. {
  1809. _TRACE (1, L"Entering CCertTemplate::SetApplicationPolicy ()\n");
  1810. HRESULT hr = S_OK;
  1811. hr = CASetCertTypePropertyEx (m_hCertType,
  1812. CERTTYPE_PROP_APPLICATION_POLICY,
  1813. (PVOID) pawszAppPolicy);
  1814. if ( SUCCEEDED (hr) )
  1815. {
  1816. hr = ModifyCriticalExtensions (szOID_APPLICATION_CERT_POLICIES, bCritical);
  1817. }
  1818. else
  1819. {
  1820. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_APPLICATION_POLICY) failed: 0x%x\n",
  1821. hr);
  1822. }
  1823. _TRACE (-1, L"Leaving CCertTemplate::SetApplicationPolicy: 0x%x\n", hr);
  1824. return hr;
  1825. }
  1826. HRESULT CCertTemplate::SetCertPolicy (const PWSTR* pawszCertPolicy, bool bCritical)
  1827. {
  1828. _TRACE (1, L"Entering CCertTemplate::SetCertPolicy ()\n");
  1829. HRESULT hr = S_OK;
  1830. hr = CASetCertTypePropertyEx (m_hCertType,
  1831. CERTTYPE_PROP_POLICY,
  1832. (PVOID) pawszCertPolicy);
  1833. if ( SUCCEEDED (hr) )
  1834. {
  1835. hr = ModifyCriticalExtensions (szOID_CERT_POLICIES, bCritical);
  1836. }
  1837. else
  1838. {
  1839. _TRACE (0, L"CASetCertTypePropertyEx (CERTTYPE_PROP_POLICY) failed: 0x%x\n",
  1840. hr);
  1841. }
  1842. _TRACE (-1, L"Leaving CCertTemplate::SetCertPolicy: 0x%x\n", hr);
  1843. return hr;
  1844. }
  1845. void CCertTemplate::FreeCertExtensions()
  1846. {
  1847. if ( m_pCertExtensions )
  1848. {
  1849. CAFreeCertTypeExtensions (m_hCertType, m_pCertExtensions);
  1850. m_pCertExtensions = 0;
  1851. }
  1852. }
  1853. HRESULT CCertTemplate::Cancel()
  1854. {
  1855. _TRACE (1, L"Entering CCertTemplate::Cancel\n");
  1856. HRESULT hr = S_OK;
  1857. // Close and re-open cert template without saving.
  1858. if ( m_hCertType )
  1859. {
  1860. FreeCertExtensions ();
  1861. hr = CACloseCertType (m_hCertType);
  1862. _ASSERT (SUCCEEDED (hr));
  1863. if ( SUCCEEDED (hr) )
  1864. {
  1865. m_hCertType = 0;
  1866. // Reinitialize the cert template
  1867. if ( !m_bIsClone )
  1868. hr = Initialize ();
  1869. }
  1870. else
  1871. {
  1872. _TRACE (0, L"CACloseCertType (%s) failed: 0x%x\n", hr);
  1873. }
  1874. }
  1875. else
  1876. hr = E_FAIL;
  1877. _TRACE (-1, L":Leaving CCertTemplate::Cancel: 0x%x\n", hr);
  1878. return hr;
  1879. }
  1880. /* NO LONGER NEEDED NTRAID# 321742
  1881. bool CCertTemplate::AllowAutoenrollment()
  1882. {
  1883. // Bug 251388 "There are templates that should never be allowed to set
  1884. // autoenrollment flag (CT_FLAG_AUTO_ENROLLMENT). The "Allow
  1885. // Autoenrollment" task for those templates should be disabled if one of
  1886. // the following three conditions is true:
  1887. //
  1888. // templates whose subject name flag has CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
  1889. // set;
  1890. // templates whose subject name flag has
  1891. // CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME set;
  1892. // templates whose CERTTYPE_PROP_RA_SIGNATURE is greater than 1 and
  1893. // CT_FLAG_PREVIOUS_APPROVAL_VALIDATE_REENROLLMENT is not set in the
  1894. // enrollment flag."
  1895. bool bResult = true;
  1896. DWORD dwNumSignatures = 0;
  1897. GetRANumSignaturesRequired (dwNumSignatures);
  1898. // NTRAID# 175912 Version 1 type templates not good for autoenrollment
  1899. if ( 1 == GetType () ||
  1900. (m_dwSubjectNameFlags & CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT) ||
  1901. (m_dwSubjectNameFlags & CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME) ||
  1902. ( dwNumSignatures > 1 &&
  1903. !(m_dwEnrollmentFlags & CT_FLAG_PREVIOUS_APPROVAL_VALIDATE_REENROLLMENT)) )
  1904. {
  1905. bResult = false;
  1906. }
  1907. // NTRAID# 276180 Certificate Template Snap-in: Grey out "Allow
  1908. // Autoenrollment" context menu based on properties of the template
  1909. if ( RequireSubjectInRequest () ||
  1910. dwNumSignatures >= 2 && !ReenrollmentValidWithPreviousApproval () )
  1911. {
  1912. bResult = false;
  1913. }
  1914. return bResult;
  1915. }
  1916. */
  1917. HRESULT CCertTemplate::GetSubjectTypeDescription (int nIndex, CString &szSubjectTypeDescription)
  1918. {
  1919. _TRACE (1, L"Entering CCertTemplate::GetSubjectTypeDescription (nIndex=%d\n", nIndex);
  1920. PWSTR* pawszSubjectTypeDescriptionList = 0;
  1921. HRESULT hr = CAGetCertTypeProperty (m_hCertType,
  1922. CERTTYPE_PROP_DESCRIPTION,
  1923. &pawszSubjectTypeDescriptionList);
  1924. if ( SUCCEEDED (hr) )
  1925. {
  1926. if ( pawszSubjectTypeDescriptionList )
  1927. {
  1928. int nCnt = 0;
  1929. while ( pawszSubjectTypeDescriptionList[nCnt] )
  1930. nCnt++;
  1931. if ( nIndex < nCnt )
  1932. szSubjectTypeDescription = pawszSubjectTypeDescriptionList[nIndex];
  1933. else
  1934. hr = E_FAIL;
  1935. LocalFree (pawszSubjectTypeDescriptionList);
  1936. }
  1937. else
  1938. hr = E_FAIL;
  1939. }
  1940. else
  1941. {
  1942. _TRACE (0, L"CAGetCertTypeProperty (CERTTYPE_PROP_DESCRIPTION) failed: 0x%x\n", hr);
  1943. }
  1944. _TRACE (-1, L"Leaving CCertTemplate::GetSubjectTypeDescription (szRAPolicyOID=%s): 0x%x\n",
  1945. (PCWSTR) szSubjectTypeDescription, hr);
  1946. return hr;
  1947. }
  1948. // NTRAID# 278356 CertSRV: No CSPs in mmc certificate snapin advanced
  1949. // option list with v2 templates that have ENC and SIG as purpose.
  1950. HRESULT CCertTemplate::SetDigitalSignature(
  1951. bool bSet,
  1952. bool bSetOnlyDigitalSignature /* = false */)
  1953. {
  1954. _TRACE (1, L"Entering CCertTemplate::SetDigitalSignature (bSet = %s)\n", bSet ? L"true" : L"false");
  1955. PCERT_EXTENSION pCertExtension = 0;
  1956. HRESULT hr = GetCertExtension (szOID_KEY_USAGE, &pCertExtension);
  1957. if ( SUCCEEDED (hr) )
  1958. {
  1959. ASSERT (pCertExtension);
  1960. if ( pCertExtension )
  1961. {
  1962. DWORD cbKeyUsage = 0;
  1963. if ( ::CryptDecodeObject(CRYPT_ASN_ENCODING,
  1964. szOID_KEY_USAGE,
  1965. pCertExtension->Value.pbData,
  1966. pCertExtension->Value.cbData,
  1967. 0, NULL, &cbKeyUsage) )
  1968. {
  1969. CRYPT_BIT_BLOB* pKeyUsage = (CRYPT_BIT_BLOB*)
  1970. ::LocalAlloc (LPTR, cbKeyUsage);
  1971. if ( pKeyUsage )
  1972. {
  1973. if ( ::CryptDecodeObject (CRYPT_ASN_ENCODING,
  1974. szOID_KEY_USAGE,
  1975. pCertExtension->Value.pbData,
  1976. pCertExtension->Value.cbData,
  1977. 0, pKeyUsage, &cbKeyUsage) )
  1978. {
  1979. if (pKeyUsage->cbData >= 1)
  1980. {
  1981. pKeyUsage->cUnusedBits = 0;
  1982. if ( bSetOnlyDigitalSignature )
  1983. {
  1984. pKeyUsage->pbData[0] = CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  1985. }
  1986. else if ( bSet )
  1987. pKeyUsage->pbData[0] |= CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  1988. else
  1989. pKeyUsage->pbData[0] &= ~CERT_DIGITAL_SIGNATURE_KEY_USAGE;
  1990. hr = SetKeyUsage (pKeyUsage, pCertExtension->fCritical ? true : false);
  1991. }
  1992. else
  1993. hr = E_FAIL;
  1994. }
  1995. else
  1996. {
  1997. DWORD dwErr = GetLastError ();
  1998. hr = HRESULT_FROM_WIN32 (dwErr);
  1999. _TRACE (0, L"CryptDecodeObject(CRYPT_ASN_ENCODING, szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  2000. }
  2001. LocalFree (pKeyUsage);
  2002. }
  2003. else
  2004. hr = E_OUTOFMEMORY;
  2005. }
  2006. else
  2007. {
  2008. DWORD dwErr = GetLastError ();
  2009. hr = HRESULT_FROM_WIN32 (dwErr);
  2010. _TRACE (0, L"CryptDecodeObject(CRYPT_ASN_ENCODING, szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  2011. }
  2012. }
  2013. FreeCertExtensions ();
  2014. }
  2015. _TRACE (-1, L"Leaving CCertTemplate::SetDigitalSignature (bSet = %s): 0x%x\n",
  2016. bSet ? L"true" : L"false", hr);
  2017. return hr;
  2018. }
  2019. HRESULT CCertTemplate::GetDigitalSignature(
  2020. bool &bHasDigitalSignature,
  2021. bool* pbHasOnlyDigitalSignature /* = 0 */)
  2022. {
  2023. _TRACE (1, L"Entering CCertTemplate::GetDigitalSignature ()\n");
  2024. PCERT_EXTENSION pCertExtension = 0;
  2025. HRESULT hr = GetCertExtension (szOID_KEY_USAGE, &pCertExtension);
  2026. if ( SUCCEEDED (hr) )
  2027. {
  2028. ASSERT (pCertExtension);
  2029. if ( pCertExtension )
  2030. {
  2031. DWORD cbKeyUsage = 0;
  2032. if ( ::CryptDecodeObject(CRYPT_ASN_ENCODING,
  2033. szOID_KEY_USAGE,
  2034. pCertExtension->Value.pbData,
  2035. pCertExtension->Value.cbData,
  2036. 0, NULL, &cbKeyUsage) )
  2037. {
  2038. CRYPT_BIT_BLOB* pKeyUsage = (CRYPT_BIT_BLOB*)
  2039. ::LocalAlloc (LPTR, cbKeyUsage);
  2040. if ( pKeyUsage )
  2041. {
  2042. if ( ::CryptDecodeObject (CRYPT_ASN_ENCODING,
  2043. szOID_KEY_USAGE,
  2044. pCertExtension->Value.pbData,
  2045. pCertExtension->Value.cbData,
  2046. 0, pKeyUsage, &cbKeyUsage) )
  2047. {
  2048. if (pKeyUsage->cbData >= 1)
  2049. {
  2050. pKeyUsage->cUnusedBits = 0;
  2051. if ( pKeyUsage->pbData[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE )
  2052. bHasDigitalSignature = true;
  2053. else
  2054. bHasDigitalSignature = false;
  2055. if ( pbHasOnlyDigitalSignature )
  2056. {
  2057. if ( pKeyUsage->pbData[0] == CERT_DIGITAL_SIGNATURE_KEY_USAGE )
  2058. *pbHasOnlyDigitalSignature = true;
  2059. else
  2060. *pbHasOnlyDigitalSignature = false;
  2061. }
  2062. }
  2063. else
  2064. hr = E_FAIL;
  2065. }
  2066. else
  2067. {
  2068. DWORD dwErr = GetLastError ();
  2069. hr = HRESULT_FROM_WIN32 (dwErr);
  2070. _TRACE (0, L"CryptDecodeObject(CRYPT_ASN_ENCODING, szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  2071. }
  2072. LocalFree (pKeyUsage);
  2073. }
  2074. else
  2075. hr = E_OUTOFMEMORY;
  2076. }
  2077. else
  2078. {
  2079. DWORD dwErr = GetLastError ();
  2080. hr = HRESULT_FROM_WIN32 (dwErr);
  2081. _TRACE (0, L"CryptDecodeObject(CRYPT_ASN_ENCODING, szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  2082. }
  2083. }
  2084. FreeCertExtensions ();
  2085. }
  2086. _TRACE (-1, L"Leaving CCertTemplate::GetDigitalSignature (bHasDigitalSignature = %s): 0x%x\n",
  2087. bHasDigitalSignature ? L"true" : L"false", hr);
  2088. return hr;
  2089. }
  2090. void CCertTemplate::IssuancePoliciesRequired(bool bRequired)
  2091. {
  2092. m_bIssuancePoliciesRequired = bRequired;
  2093. }
  2094. bool CCertTemplate::IssuancePoliciesRequired() const
  2095. {
  2096. return m_bIssuancePoliciesRequired;
  2097. }
  2098. CString CCertTemplate::GetDN () const
  2099. {
  2100. _TRACE (1, L"Entering CCertTemplate::GetDN - m_hCertType = 0x%x\n", m_hCertType);
  2101. HRESULT hr = S_OK;
  2102. CString szDN;
  2103. if ( m_hCertType )
  2104. {
  2105. PWSTR* rgwszProp = 0;
  2106. hr = CAGetCertTypePropertyEx (m_hCertType,
  2107. CERTTYPE_PROP_DN, &rgwszProp);
  2108. if ( SUCCEEDED (hr) && rgwszProp )
  2109. {
  2110. szDN = *rgwszProp;
  2111. CAFreeCertTypeProperty (m_hCertType, rgwszProp);
  2112. }
  2113. else
  2114. {
  2115. _TRACE (0, L"CAGetCertTypePropertyEx (CERTTYPE_PROP_DN) failed: 0x%x\n", hr);
  2116. szDN = GetObjectName ();
  2117. }
  2118. }
  2119. else
  2120. szDN = GetObjectName ();
  2121. _TRACE (-1, L"Leaving CCertTemplate::GetDN: %s, 0x%x\n", (PCWSTR) szDN, hr);
  2122. return szDN;
  2123. }