Source code of Windows XP (NT5)
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.

2348 lines
70 KiB

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