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.

1118 lines
38 KiB

  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2001.
  5. //
  6. // File: TemplateExtensionsPropertyPage.cpp
  7. //
  8. // Contents: Implementation of CTemplateExtensionsPropertyPage
  9. //
  10. //----------------------------------------------------------------------------
  11. // TemplateExtensionsPropertyPage.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include "certtmpl.h"
  15. #include "TemplateExtensionsPropertyPage.h"
  16. #include "KeyUsageDlg.h"
  17. #include "BasicConstraintsDlg.h"
  18. #include "PolicyDlg.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. PCWSTR pcszNEWLINE = L"\r\n";
  25. #define IDI_CRITICAL_EXTENSION 2
  26. #define IDI_EXTENSION 3
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CTemplateExtensionsPropertyPage property page
  29. CTemplateExtensionsPropertyPage::CTemplateExtensionsPropertyPage(
  30. CCertTemplate& rCertTemplate,
  31. bool& rbIsDirty)
  32. : CHelpPropertyPage(CTemplateExtensionsPropertyPage::IDD),
  33. m_rCertTemplate (rCertTemplate),
  34. m_rbIsDirty (rbIsDirty)
  35. {
  36. //{{AFX_DATA_INIT(CTemplateExtensionsPropertyPage)
  37. //}}AFX_DATA_INIT
  38. m_rCertTemplate.AddRef ();
  39. }
  40. CTemplateExtensionsPropertyPage::~CTemplateExtensionsPropertyPage()
  41. {
  42. m_rCertTemplate.Release ();
  43. }
  44. void CTemplateExtensionsPropertyPage::DoDataExchange(CDataExchange* pDX)
  45. {
  46. CHelpPropertyPage::DoDataExchange(pDX);
  47. //{{AFX_DATA_MAP(CTemplateExtensionsPropertyPage)
  48. DDX_Control(pDX, IDC_EXTENSION_LIST, m_extensionList);
  49. //}}AFX_DATA_MAP
  50. }
  51. BEGIN_MESSAGE_MAP(CTemplateExtensionsPropertyPage, CHelpPropertyPage)
  52. //{{AFX_MSG_MAP(CTemplateExtensionsPropertyPage)
  53. ON_BN_CLICKED(IDC_SHOW_DETAILS, OnShowDetails)
  54. ON_NOTIFY(LVN_ITEMCHANGED, IDC_EXTENSION_LIST, OnItemchangedExtensionList)
  55. ON_NOTIFY(NM_DBLCLK, IDC_EXTENSION_LIST, OnDblclkExtensionList)
  56. ON_NOTIFY(LVN_DELETEITEM, IDC_EXTENSION_LIST, OnDeleteitemExtensionList)
  57. ON_WM_DESTROY()
  58. //}}AFX_MSG_MAP
  59. END_MESSAGE_MAP()
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CTemplateExtensionsPropertyPage message handlers
  62. BOOL CTemplateExtensionsPropertyPage::OnInitDialog()
  63. {
  64. CHelpPropertyPage::OnInitDialog();
  65. if ( m_rCertTemplate.GetType () > 1 )
  66. {
  67. CString szText;
  68. VERIFY (szText.LoadString (IDS_V2_EXTENSIONS_HELP_HINT));
  69. SetDlgItemText (IDC_EXTENSIONS_HELP_HINT, szText);
  70. }
  71. // Set up list controls
  72. COLORREF cr = RGB (255, 0, 255);
  73. CThemeContextActivator activator;
  74. VERIFY (m_imageListNormal.Create (IDB_EXTENSIONS, 32, 0, cr));
  75. VERIFY (m_imageListSmall.Create (IDB_EXTENSIONS, 16, 0, cr));
  76. m_extensionList.SetImageList (CImageList::FromHandle (m_imageListSmall), LVSIL_SMALL);
  77. m_extensionList.SetImageList (CImageList::FromHandle (m_imageListNormal), LVSIL_NORMAL);
  78. int colWidths[NUM_COLS] = {400};
  79. // Add "Certificate Extension" column
  80. CString szText;
  81. VERIFY (szText.LoadString (IDS_CERTIFICATE_EXTENSION));
  82. VERIFY (m_extensionList.InsertColumn (COL_CERT_EXTENSION, (LPCWSTR) szText,
  83. LVCFMT_LEFT, colWidths[COL_CERT_EXTENSION], COL_CERT_EXTENSION) != -1);
  84. // Add extensions
  85. bool bEKUExtensionFound = false;
  86. bool bCertPoliciesExtensionFound = false;
  87. bool bApplicationPoliciesExtensionFound = false;
  88. HRESULT hr = S_OK;
  89. DWORD dwExtensionCnt = m_rCertTemplate.GetCertExtensionCount ();
  90. for (DWORD dwIndex = 0; dwIndex < dwExtensionCnt; dwIndex++)
  91. {
  92. PSTR pszObjId = 0;
  93. BOOL fCritical = FALSE;
  94. hr = m_rCertTemplate.GetCertExtension (dwIndex, &pszObjId, fCritical);
  95. if ( SUCCEEDED (hr) )
  96. {
  97. if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszObjId) )
  98. bEKUExtensionFound = true;
  99. else if ( !_stricmp (szOID_CERT_POLICIES, pszObjId) )
  100. bCertPoliciesExtensionFound = true;
  101. else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszObjId) )
  102. bApplicationPoliciesExtensionFound = true;
  103. // Don't add EKU except for version 1
  104. if ( m_rCertTemplate.GetType () > 1 && !_stricmp (szOID_ENHANCED_KEY_USAGE, pszObjId) )
  105. continue;
  106. // Don't add Application Policies for version 1
  107. if ( m_rCertTemplate.GetType () == 1 && !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszObjId) )
  108. continue;
  109. InsertListItem (pszObjId, fCritical);
  110. delete [] pszObjId;
  111. }
  112. }
  113. if ( !bEKUExtensionFound && 1 == m_rCertTemplate.GetType () ) // only version 1
  114. {
  115. InsertListItem (szOID_ENHANCED_KEY_USAGE, FALSE);
  116. }
  117. if ( !bCertPoliciesExtensionFound && m_rCertTemplate.GetType () > 1 ) // not version 1
  118. {
  119. InsertListItem (szOID_CERT_POLICIES, FALSE);
  120. }
  121. // Fixes 228146: CERTTMPL:The default "Cross Certification Authority" template does not have the application Policy extension item
  122. if ( !bApplicationPoliciesExtensionFound && m_rCertTemplate.GetType () > 1 ) // version 2 or greater
  123. {
  124. InsertListItem (szOID_APPLICATION_CERT_POLICIES, FALSE);
  125. }
  126. EnableControls ();
  127. if ( 1 == m_rCertTemplate.GetType () )
  128. GetDlgItem (IDC_SHOW_DETAILS)->ShowWindow (SW_HIDE);
  129. return TRUE; // return TRUE unless you set the focus to a control
  130. // EXCEPTION: OCX Property Pages should return FALSE
  131. }
  132. HRESULT CTemplateExtensionsPropertyPage::InsertListItem (LPSTR pszExtensionOid, BOOL fCritical)
  133. {
  134. if ( !pszExtensionOid )
  135. return E_POINTER;
  136. HRESULT hr = S_OK;
  137. CString friendlyName;
  138. if ( MyGetOIDInfoA (friendlyName, pszExtensionOid) )
  139. {
  140. LV_ITEM lvItem;
  141. int iItem = m_extensionList.GetItemCount ();
  142. ::ZeroMemory (&lvItem, sizeof (lvItem));
  143. lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  144. lvItem.iItem = iItem;
  145. lvItem.iSubItem = COL_CERT_EXTENSION;
  146. lvItem.pszText = (LPWSTR)(LPCWSTR) friendlyName;
  147. if ( fCritical )
  148. lvItem.iImage = IDI_CRITICAL_EXTENSION;
  149. else
  150. lvItem.iImage = IDI_EXTENSION;
  151. PSTR pszOID = new CHAR[strlen (pszExtensionOid)+1];
  152. if ( pszOID )
  153. {
  154. strcpy (pszOID, pszExtensionOid);
  155. lvItem.lParam = (LPARAM) pszOID;
  156. iItem = m_extensionList.InsertItem (&lvItem);
  157. ASSERT (-1 != iItem);
  158. if ( -1 != iItem )
  159. hr = E_FAIL;
  160. }
  161. else
  162. hr = E_OUTOFMEMORY;
  163. }
  164. else
  165. hr = E_FAIL;
  166. return hr;
  167. }
  168. void CTemplateExtensionsPropertyPage::EnableControls()
  169. {
  170. int nSelCnt = m_extensionList.GetSelectedCount ();
  171. BOOL bEnableDetails = TRUE;
  172. int nSelIndex = GetSelectedListItem ();
  173. if ( 1 == nSelCnt )
  174. {
  175. PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
  176. _ASSERT (pszOID);
  177. if ( pszOID )
  178. {
  179. if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
  180. bEnableDetails = FALSE;
  181. else if ( !_stricmp (szOID_BASIC_CONSTRAINTS, pszOID) )
  182. bEnableDetails = FALSE;
  183. else if ( !_stricmp (szOID_CERTIFICATE_TEMPLATE, pszOID) )
  184. bEnableDetails = FALSE;
  185. }
  186. }
  187. else
  188. bEnableDetails = FALSE;
  189. GetDlgItem (IDC_SHOW_DETAILS)->EnableWindow (bEnableDetails);
  190. }
  191. void CTemplateExtensionsPropertyPage::OnOK()
  192. {
  193. CDialog::OnOK();
  194. }
  195. void CTemplateExtensionsPropertyPage::OnShowDetails()
  196. {
  197. int nSelCnt = m_extensionList.GetSelectedCount ();
  198. _ASSERT (1 == nSelCnt);
  199. int nSelIndex = GetSelectedListItem ();
  200. if ( 1 == nSelCnt )
  201. {
  202. PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
  203. if ( pszOID )
  204. {
  205. PCERT_EXTENSION pCertExtension = 0;
  206. HRESULT hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
  207. if ( SUCCEEDED (hr) )
  208. {
  209. bool bExtensionAllocedLocally = false;
  210. if ( !pCertExtension )
  211. {
  212. pCertExtension = new CERT_EXTENSION;
  213. if ( pCertExtension )
  214. {
  215. ::ZeroMemory (pCertExtension, sizeof (CERT_EXTENSION));
  216. pCertExtension->pszObjId = pszOID;
  217. bExtensionAllocedLocally = true;
  218. }
  219. else
  220. return;
  221. }
  222. CDialog* pDlg = 0;
  223. if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
  224. {
  225. return;
  226. }
  227. else if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszOID) )
  228. {
  229. if ( m_rCertTemplate.GetType () == 1 )
  230. {
  231. pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
  232. }
  233. }
  234. else if ( !_stricmp (szOID_KEY_USAGE, pszOID) )
  235. {
  236. pDlg = new CKeyUsageDlg (this, m_rCertTemplate, pCertExtension);
  237. }
  238. else if ( !_stricmp (szOID_BASIC_CONSTRAINTS, pszOID) )
  239. {
  240. return;
  241. }
  242. else if ( !_stricmp (szOID_BASIC_CONSTRAINTS2, pszOID) )
  243. {
  244. pDlg = new CBasicConstraintsDlg (this, m_rCertTemplate, pCertExtension);
  245. }
  246. else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
  247. {
  248. pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
  249. }
  250. else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
  251. {
  252. if ( m_rCertTemplate.GetType () > 1 )
  253. {
  254. pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
  255. }
  256. }
  257. else
  258. {
  259. ASSERT (0);
  260. }
  261. bool bRefresh = false;
  262. if ( pDlg )
  263. {
  264. CThemeContextActivator activator;
  265. if ( IDOK == pDlg->DoModal () )
  266. bRefresh = true;
  267. delete pDlg;
  268. }
  269. if ( bExtensionAllocedLocally )
  270. delete pCertExtension;
  271. m_rCertTemplate.FreeCertExtensions ();
  272. if ( bRefresh )
  273. {
  274. hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
  275. if ( SUCCEEDED (hr) )
  276. {
  277. SetModified ();
  278. m_rbIsDirty = true;
  279. int nImage = 0;
  280. if ( pCertExtension && pCertExtension->fCritical )
  281. nImage = IDI_CRITICAL_EXTENSION;
  282. else
  283. nImage = IDI_EXTENSION;
  284. VERIFY (m_extensionList.SetItem (nSelIndex, 0, LVIF_IMAGE, 0,
  285. nImage, 0, 0, 0));
  286. ShowDescription ();
  287. VERIFY (m_extensionList.SetItem (nSelIndex, 0, LVIF_IMAGE, 0,
  288. nImage, 0, 0, 0));
  289. m_rCertTemplate.FreeCertExtensions ();
  290. }
  291. }
  292. }
  293. }
  294. }
  295. }
  296. int CTemplateExtensionsPropertyPage::GetSelectedListItem()
  297. {
  298. int nSelItem = -1;
  299. if ( m_extensionList.m_hWnd && m_extensionList.GetSelectedCount () > 0 )
  300. {
  301. int nCnt = m_extensionList.GetItemCount ();
  302. ASSERT (nCnt >= 1);
  303. UINT flag = 0;
  304. while (--nCnt >= 0)
  305. {
  306. flag = ListView_GetItemState (m_extensionList.m_hWnd, nCnt, LVIS_SELECTED);
  307. if ( flag & LVNI_SELECTED )
  308. {
  309. nSelItem = nCnt;
  310. break;
  311. }
  312. }
  313. }
  314. return nSelItem;
  315. }
  316. void CTemplateExtensionsPropertyPage::OnItemchangedExtensionList(NMHDR* pNMHDR, LRESULT* pResult)
  317. {
  318. LPNMLISTVIEW pNMListView = (LPNMLISTVIEW) pNMHDR;
  319. ASSERT (pNMListView);
  320. if ( !pNMListView )
  321. {
  322. *pResult = 0;
  323. return;
  324. }
  325. if ( !(LVIS_SELECTED & pNMListView->uNewState) )
  326. {
  327. CString szText;
  328. VERIFY (szText.LoadString (IDS_NO_EXTENSION_SELECTED));
  329. SetDlgItemText (IDC_EXTENSION_NAME, szText);
  330. VERIFY (szText.LoadString (IDS_NONE));
  331. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
  332. *pResult = 0;
  333. return;
  334. }
  335. EnableControls ();
  336. ShowDescription ();
  337. *pResult = 0;
  338. }
  339. void CTemplateExtensionsPropertyPage::SetCertTemplateExtension (PCERT_EXTENSION pCertExtension)
  340. {
  341. ASSERT (pCertExtension);
  342. if ( !pCertExtension )
  343. return;
  344. DWORD cbData = 0;
  345. if ( CryptDecodeObject(X509_ASN_ENCODING,
  346. szOID_CERTIFICATE_TEMPLATE,
  347. pCertExtension->Value.pbData,
  348. pCertExtension->Value.cbData,
  349. 0,
  350. NULL,
  351. &cbData) )
  352. {
  353. CERT_TEMPLATE_EXT* pbTemplate = (CERT_TEMPLATE_EXT*) LocalAlloc(LPTR, cbData);
  354. if ( pbTemplate )
  355. {
  356. if ( CryptDecodeObject(X509_ASN_ENCODING,
  357. szOID_CERTIFICATE_TEMPLATE,
  358. pCertExtension->Value.pbData,
  359. pCertExtension->Value.cbData,
  360. 0,
  361. pbTemplate,
  362. &cbData) )
  363. {
  364. CString text;
  365. CString description;
  366. //copy the extension oid
  367. if ( pbTemplate->pszObjId )
  368. {
  369. CString templateName;
  370. if ( MyGetOIDInfoA (templateName, pbTemplate->pszObjId) )
  371. {
  372. CString szOID;
  373. int nLen = ::MultiByteToWideChar (CP_ACP, 0,
  374. pbTemplate->pszObjId, -1, NULL, 0);
  375. ASSERT (nLen);
  376. if ( nLen )
  377. {
  378. nLen = ::MultiByteToWideChar (CP_ACP, 0,
  379. pbTemplate->pszObjId, -1,
  380. szOID.GetBufferSetLength (nLen), nLen);
  381. ASSERT (nLen);
  382. szOID.ReleaseBuffer ();
  383. }
  384. if ( !wcscmp (templateName, szOID) )
  385. {
  386. // Bug 213073 CryptFormatObject: Need to include
  387. // the cert temp OID in the Certificate Template
  388. // Information extension
  389. // When the template is cloned, the oid-name pair
  390. // is not in the global list. Just use the
  391. // template display name the user provided
  392. templateName = m_rCertTemplate.GetDisplayName ();
  393. }
  394. text.FormatMessage (IDS_TEMPLATE_NAME, templateName);
  395. description += text;
  396. description += pcszNEWLINE;
  397. // Copy the template OID
  398. text.FormatMessage (IDS_TEMPLATE_OID, szOID);
  399. description += text;
  400. description += pcszNEWLINE;
  401. }
  402. }
  403. // copy the subject type description
  404. CString szSubjectTypeDescription;
  405. if ( SUCCEEDED (m_rCertTemplate.GetSubjectTypeDescription (
  406. 0, szSubjectTypeDescription)) )
  407. {
  408. text.FormatMessage (IDS_SUBJECT_TYPE_DESCRIPTION, szSubjectTypeDescription);
  409. description += text;
  410. description += pcszNEWLINE;
  411. }
  412. //copy the version
  413. WCHAR str[32];
  414. _ultow (pbTemplate->dwMajorVersion, str, 10);
  415. text.FormatMessage (IDS_MAJOR_VERSION_NUMBER, str);
  416. description += text;
  417. description += pcszNEWLINE;
  418. _ultow (pbTemplate->dwMinorVersion, str, 10);
  419. text.FormatMessage (IDS_MINOR_VERSION_NUMBER, str);
  420. description += text;
  421. description += pcszNEWLINE;
  422. if ( description.IsEmpty () )
  423. VERIFY (description.LoadString (IDS_NONE));
  424. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  425. }
  426. LocalFree (pbTemplate);
  427. }
  428. }
  429. }
  430. void CTemplateExtensionsPropertyPage::SetCertTypeDescription (PCERT_EXTENSION pCertExtension)
  431. {
  432. ASSERT (pCertExtension);
  433. if ( !pCertExtension )
  434. return;
  435. DWORD cbValue = 0;
  436. if ( ::CryptDecodeObject(
  437. CRYPT_ASN_ENCODING,
  438. X509_UNICODE_ANY_STRING,
  439. pCertExtension->Value.pbData,
  440. pCertExtension->Value.cbData,
  441. 0,
  442. 0,
  443. &cbValue) )
  444. {
  445. CERT_NAME_VALUE* pCNValue = (CERT_NAME_VALUE*)
  446. ::LocalAlloc(LPTR, cbValue);
  447. if ( pCNValue )
  448. {
  449. if ( ::CryptDecodeObject(
  450. CRYPT_ASN_ENCODING,
  451. X509_UNICODE_ANY_STRING,
  452. pCertExtension->Value.pbData,
  453. pCertExtension->Value.cbData,
  454. 0,
  455. pCNValue,
  456. &cbValue) )
  457. {
  458. CString text = (LPWSTR) pCNValue->Value.pbData;
  459. CString description;
  460. if ( text.IsEmpty () )
  461. VERIFY (text.LoadString (IDS_NONE));
  462. description.FormatMessage (IDS_TEMPLATE_INTERNAL_NAME, text);
  463. description += pcszNEWLINE;
  464. // copy the subject type description
  465. CString szSubjectTypeDescription;
  466. if ( SUCCEEDED (m_rCertTemplate.GetSubjectTypeDescription (
  467. 0, szSubjectTypeDescription)) )
  468. {
  469. text.FormatMessage (IDS_SUBJECT_TYPE_DESCRIPTION, szSubjectTypeDescription);
  470. description += text;
  471. description += pcszNEWLINE;
  472. }
  473. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  474. }
  475. ::LocalFree (pCNValue);
  476. }
  477. else
  478. {
  479. _TRACE (0, L"CryptDecodeObject (CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING, ...) failed: 0x%x\n",
  480. GetLastError ());
  481. }
  482. }
  483. else
  484. {
  485. _TRACE (0, L"CryptDecodeObject (CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING, ...) failed: 0x%x\n",
  486. GetLastError ());
  487. }
  488. }
  489. void CTemplateExtensionsPropertyPage::SetKeyUsageDescription (PCERT_EXTENSION pCertExtension)
  490. {
  491. ASSERT (pCertExtension);
  492. if ( !pCertExtension )
  493. return;
  494. CString description;
  495. CString text;
  496. DWORD cbKeyUsage = 0;
  497. CRYPT_BIT_BLOB* pKeyUsage = 0;
  498. if ( ::CryptDecodeObject(CRYPT_ASN_ENCODING,
  499. szOID_KEY_USAGE,
  500. pCertExtension->Value.pbData,
  501. pCertExtension->Value.cbData,
  502. 0, NULL, &cbKeyUsage) )
  503. {
  504. pKeyUsage = (CRYPT_BIT_BLOB*)
  505. ::LocalAlloc (LPTR, cbKeyUsage);
  506. if ( pKeyUsage )
  507. {
  508. if ( ::CryptDecodeObject (CRYPT_ASN_ENCODING,
  509. szOID_KEY_USAGE,
  510. pCertExtension->Value.pbData,
  511. pCertExtension->Value.cbData,
  512. 0, pKeyUsage, &cbKeyUsage) )
  513. {
  514. if (pKeyUsage->cbData >= 1)
  515. {
  516. if ( pKeyUsage->pbData[0] &
  517. (CERT_DIGITAL_SIGNATURE_KEY_USAGE |
  518. CERT_NON_REPUDIATION_KEY_USAGE |
  519. CERT_KEY_CERT_SIGN_KEY_USAGE |
  520. CERT_OFFLINE_CRL_SIGN_KEY_USAGE) )
  521. {
  522. VERIFY (text.LoadString (IDS_SIGNATURE_REQUIREMENTS));
  523. description += text;
  524. description += pcszNEWLINE;
  525. if ( pKeyUsage->pbData[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE )
  526. {
  527. VERIFY (text.LoadString (IDS_DIGITAL_SIGNATURE));
  528. description += text;
  529. description += pcszNEWLINE;
  530. }
  531. if ( pKeyUsage->pbData[0] & CERT_NON_REPUDIATION_KEY_USAGE )
  532. {
  533. VERIFY (text.LoadString (IDS_NON_REPUDIATION));
  534. description += text;
  535. description += pcszNEWLINE;
  536. }
  537. if ( pKeyUsage->pbData[0] & CERT_KEY_CERT_SIGN_KEY_USAGE )
  538. {
  539. VERIFY (text.LoadString (IDS_CERTIFICATE_SIGNING));
  540. description += text;
  541. description += pcszNEWLINE;
  542. }
  543. if ( pKeyUsage->pbData[0] & CERT_OFFLINE_CRL_SIGN_KEY_USAGE )
  544. {
  545. VERIFY (text.LoadString (IDS_CRL_SIGNING));
  546. description += text;
  547. description += pcszNEWLINE;
  548. }
  549. }
  550. if ( pKeyUsage->pbData[0] & (CERT_KEY_ENCIPHERMENT_KEY_USAGE |
  551. CERT_DATA_ENCIPHERMENT_KEY_USAGE |
  552. CERT_KEY_AGREEMENT_KEY_USAGE) )
  553. {
  554. if ( !description.IsEmpty () )
  555. description += pcszNEWLINE;
  556. if ( pKeyUsage->pbData[0] & CERT_KEY_ENCIPHERMENT_KEY_USAGE )
  557. {
  558. VERIFY (text.LoadString (IDS_ALLOW_KEY_EXCHANGE_ONLY_WITH_KEY_ENCRYPTION));
  559. description += text;
  560. description += pcszNEWLINE;
  561. }
  562. if ( pKeyUsage->pbData[0] & CERT_KEY_AGREEMENT_KEY_USAGE )
  563. {
  564. VERIFY (text.LoadString (IDS_ALLOW_KEY_EXCHANGE_WITHOUT_KEY_ENCRYPTION));
  565. description += text;
  566. description += pcszNEWLINE;
  567. }
  568. if ( pKeyUsage->pbData[0] & CERT_DATA_ENCIPHERMENT_KEY_USAGE )
  569. {
  570. VERIFY (text.LoadString (IDS_ALLOW_ENCRYPTION_OF_USER_DATA));
  571. description += text;
  572. description += pcszNEWLINE;
  573. }
  574. }
  575. }
  576. // if (pKeyUsage->cbData >= 2)
  577. // {
  578. // if ( pKeyUsage->pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE )
  579. // SendDlgItemMessage (IDC_CHECK_DECIPHERMENT_ONLY, BM_SETCHECK, BST_CHECKED);
  580. // }
  581. }
  582. else
  583. {
  584. DWORD dwErr = GetLastError ();
  585. _TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  586. DisplaySystemError (NULL, dwErr);
  587. }
  588. LocalFree (pKeyUsage);
  589. }
  590. }
  591. else
  592. {
  593. DWORD dwErr = GetLastError ();
  594. _TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
  595. DisplaySystemError (NULL, dwErr);
  596. }
  597. if ( pCertExtension->fCritical )
  598. {
  599. VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
  600. description += text;
  601. description += pcszNEWLINE;
  602. }
  603. if ( description.IsEmpty () )
  604. VERIFY (description.LoadString (IDS_NONE));
  605. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  606. }
  607. void CTemplateExtensionsPropertyPage::SetEnhancedKeyUsageDescription (bool bCritical)
  608. {
  609. CString description;
  610. CString text;
  611. int nEKUIndex = 0;
  612. CString szEKU;
  613. while ( SUCCEEDED (m_rCertTemplate.GetEnhancedKeyUsage (nEKUIndex, szEKU)) )
  614. {
  615. int nLen = WideCharToMultiByte(
  616. CP_ACP, // code page
  617. 0, // performance and mapping flags
  618. (PCWSTR) szEKU, // wide-character string
  619. (int) wcslen (szEKU), // number of chars in string
  620. 0, // buffer for new string
  621. 0, // size of buffer
  622. 0, // default for unmappable chars
  623. 0); // set when default char used
  624. if ( nLen > 0 )
  625. {
  626. nLen++; // account for Null terminator
  627. PSTR pszAnsiBuf = new CHAR[nLen];
  628. if ( pszAnsiBuf )
  629. {
  630. ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
  631. nLen = WideCharToMultiByte(
  632. CP_ACP, // code page
  633. 0, // performance and mapping flags
  634. (PCWSTR) szEKU, // wide-character string
  635. (int) wcslen (szEKU), // number of chars in string
  636. pszAnsiBuf, // buffer for new string
  637. nLen, // size of buffer
  638. 0, // default for unmappable chars
  639. 0); // set when default char used
  640. if ( nLen )
  641. {
  642. CString szEKUName;
  643. if ( MyGetOIDInfoA (szEKUName, pszAnsiBuf) )
  644. {
  645. description += szEKUName;
  646. description += pcszNEWLINE;
  647. }
  648. }
  649. delete [] pszAnsiBuf;
  650. }
  651. }
  652. nEKUIndex++;
  653. }
  654. if ( bCritical )
  655. {
  656. VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
  657. description += text;
  658. description += pcszNEWLINE;
  659. }
  660. if ( description.IsEmpty () )
  661. VERIFY (description.LoadString (IDS_NONE));
  662. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  663. }
  664. void CTemplateExtensionsPropertyPage::SetApplicationPoliciesDescription (bool bCritical)
  665. {
  666. CString description;
  667. CString text;
  668. int nAppPolicyIndex = 0;
  669. CString szAppPolicy;
  670. while ( SUCCEEDED (m_rCertTemplate.GetApplicationPolicy (nAppPolicyIndex, szAppPolicy)) )
  671. {
  672. int nLen = WideCharToMultiByte(
  673. CP_ACP, // code page
  674. 0, // performance and mapping flags
  675. (PCWSTR) szAppPolicy, // wide-character string
  676. (int) wcslen (szAppPolicy), // number of chars in string
  677. 0, // buffer for new string
  678. 0, // size of buffer
  679. 0, // default for unmappable chars
  680. 0); // set when default char used
  681. if ( nLen > 0 )
  682. {
  683. nLen++; // account for Null terminator
  684. PSTR pszAnsiBuf = new CHAR[nLen];
  685. if ( pszAnsiBuf )
  686. {
  687. ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
  688. nLen = WideCharToMultiByte(
  689. CP_ACP, // code page
  690. 0, // performance and mapping flags
  691. (PCWSTR) szAppPolicy, // wide-character string
  692. (int) wcslen (szAppPolicy), // number of chars in string
  693. pszAnsiBuf, // buffer for new string
  694. nLen, // size of buffer
  695. 0, // default for unmappable chars
  696. 0); // set when default char used
  697. if ( nLen )
  698. {
  699. CString szAppPolicyName;
  700. if ( MyGetOIDInfoA (szAppPolicyName, pszAnsiBuf) )
  701. {
  702. description += szAppPolicyName;
  703. description += pcszNEWLINE;
  704. }
  705. }
  706. delete [] pszAnsiBuf;
  707. }
  708. }
  709. nAppPolicyIndex++;
  710. }
  711. if ( bCritical )
  712. {
  713. VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
  714. description += text;
  715. description += pcszNEWLINE;
  716. }
  717. if ( description.IsEmpty () )
  718. VERIFY (description.LoadString (IDS_NONE));
  719. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  720. }
  721. void CTemplateExtensionsPropertyPage::SetCertPoliciesDescription (bool bCritical)
  722. {
  723. CString description;
  724. CString text;
  725. VERIFY (text.LoadString (IDS_CERT_POLICY_KNOWN_AS_ISSUANCE_POLICY));
  726. description += text;
  727. description += pcszNEWLINE;
  728. description += pcszNEWLINE;
  729. int nCertPolicyIndex = 0;
  730. CString szCertPolicy;
  731. while ( SUCCEEDED (m_rCertTemplate.GetCertPolicy (nCertPolicyIndex, szCertPolicy)) )
  732. {
  733. int nLen = WideCharToMultiByte(
  734. CP_ACP, // code page
  735. 0, // performance and mapping flags
  736. (PCWSTR) szCertPolicy, // wide-character string
  737. (int) wcslen (szCertPolicy), // number of chars in string
  738. 0, // buffer for new string
  739. 0, // size of buffer
  740. 0, // default for unmappable chars
  741. 0); // set when default char used
  742. if ( nLen > 0 )
  743. {
  744. nLen++; // account for Null terminator
  745. PSTR pszAnsiBuf = new CHAR[nLen];
  746. if ( pszAnsiBuf )
  747. {
  748. ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
  749. nLen = WideCharToMultiByte(
  750. CP_ACP, // code page
  751. 0, // performance and mapping flags
  752. (PCWSTR) szCertPolicy, // wide-character string
  753. (int) wcslen (szCertPolicy), // number of chars in string
  754. pszAnsiBuf, // buffer for new string
  755. nLen, // size of buffer
  756. 0, // default for unmappable chars
  757. 0); // set when default char used
  758. if ( nLen )
  759. {
  760. CString szPolicyName;
  761. if ( MyGetOIDInfoA (szPolicyName, pszAnsiBuf) )
  762. {
  763. description += szPolicyName;
  764. description += pcszNEWLINE;
  765. }
  766. }
  767. delete [] pszAnsiBuf;
  768. }
  769. }
  770. nCertPolicyIndex++;
  771. }
  772. if ( bCritical )
  773. {
  774. VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
  775. description += text;
  776. description += pcszNEWLINE;
  777. }
  778. if ( description.IsEmpty () )
  779. VERIFY (description.LoadString (IDS_NONE));
  780. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  781. }
  782. void CTemplateExtensionsPropertyPage::SetBasicConstraintsDescription (PCERT_EXTENSION pCertExtension)
  783. {
  784. ASSERT (pCertExtension);
  785. if ( !pCertExtension )
  786. return;
  787. CString description;
  788. CString text;
  789. VERIFY (text.LoadString (IDS_SUBJECT_IS_CA));
  790. description += text;
  791. description += pcszNEWLINE;
  792. PCERT_BASIC_CONSTRAINTS2_INFO pBCInfo = 0;
  793. DWORD cbInfo = 0;
  794. if ( CryptDecodeObject (
  795. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  796. //X509_BASIC_CONSTRAINTS2,
  797. szOID_BASIC_CONSTRAINTS2,
  798. pCertExtension->Value.pbData,
  799. pCertExtension->Value.cbData,
  800. 0,
  801. 0,
  802. &cbInfo) )
  803. {
  804. pBCInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) ::LocalAlloc (
  805. LPTR, cbInfo);
  806. if ( pBCInfo )
  807. {
  808. if ( CryptDecodeObject (
  809. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  810. //X509_BASIC_CONSTRAINTS2,
  811. szOID_BASIC_CONSTRAINTS2,
  812. pCertExtension->Value.pbData,
  813. pCertExtension->Value.cbData,
  814. 0,
  815. pBCInfo,
  816. &cbInfo) )
  817. {
  818. if ( pBCInfo->fPathLenConstraint )
  819. {
  820. VERIFY (text.LoadString (IDS_ONLY_ISSUE_END_ENTITIES));
  821. description += text;
  822. description += pcszNEWLINE;
  823. }
  824. }
  825. else
  826. {
  827. _TRACE (0, L"CryptDecodeObjectEx (szOID_BASIC_CONSTRAINTS2) failed: 0x%x\n", GetLastError ());
  828. }
  829. LocalFree (pBCInfo);
  830. }
  831. }
  832. else
  833. {
  834. _TRACE (0, L"CryptDecodeObjectEx (szOID_BASIC_CONSTRAINTS2) failed: 0x%x\n", GetLastError ());
  835. }
  836. if ( pCertExtension->fCritical )
  837. {
  838. VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
  839. description += text;
  840. description += pcszNEWLINE;
  841. }
  842. if ( description.IsEmpty () )
  843. VERIFY (description.LoadString (IDS_NONE));
  844. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
  845. }
  846. void CTemplateExtensionsPropertyPage::OnDblclkExtensionList(NMHDR* /*pNMHDR*/, LRESULT* pResult)
  847. {
  848. OnShowDetails ();
  849. *pResult = 0;
  850. }
  851. void CTemplateExtensionsPropertyPage::DoContextHelp (HWND hWndControl)
  852. {
  853. _TRACE(1, L"Entering CTemplateExtensionsPropertyPage::DoContextHelp\n");
  854. switch (::GetDlgCtrlID (hWndControl))
  855. {
  856. case IDC_STATIC:
  857. break;
  858. default:
  859. // Display context help for a control
  860. if ( !::WinHelp (
  861. hWndControl,
  862. GetContextHelpFile (),
  863. HELP_WM_HELP,
  864. (DWORD_PTR) g_aHelpIDs_IDD_TEMPLATE_EXTENSIONS) )
  865. {
  866. _TRACE(0, L"WinHelp () failed: 0x%x\n", GetLastError ());
  867. }
  868. break;
  869. }
  870. _TRACE(-1, L"Leaving CTemplateExtensionsPropertyPage::DoContextHelp\n");
  871. }
  872. void CTemplateExtensionsPropertyPage::OnDeleteitemExtensionList(NMHDR* pNMHDR, LRESULT* pResult)
  873. {
  874. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  875. PSTR pszOID = (PSTR) m_extensionList.GetItemData (pNMListView->iItem);
  876. if ( pszOID )
  877. {
  878. delete [] pszOID;
  879. }
  880. *pResult = 0;
  881. }
  882. BOOL CTemplateExtensionsPropertyPage::OnSetActive()
  883. {
  884. BOOL bRVal = CHelpPropertyPage::OnSetActive();
  885. ShowDescription ();
  886. return bRVal;
  887. }
  888. void CTemplateExtensionsPropertyPage::ShowDescription ()
  889. {
  890. int nSelCnt = m_extensionList.GetSelectedCount ();
  891. int nSelIndex = GetSelectedListItem ();
  892. if ( 1 == nSelCnt )
  893. {
  894. PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
  895. if ( pszOID )
  896. {
  897. CString friendlyName;
  898. if ( MyGetOIDInfoA (friendlyName, pszOID) )
  899. {
  900. CString text;
  901. text.FormatMessage (IDS_EXTENSION_NAME, friendlyName);
  902. SetDlgItemText (IDC_EXTENSION_NAME, text);
  903. }
  904. else
  905. SetDlgItemText (IDC_EXTENSION_NAME, L"");
  906. PCERT_EXTENSION pCertExtension = 0;
  907. HRESULT hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
  908. if ( SUCCEEDED (hr) )
  909. {
  910. if ( pCertExtension )
  911. {
  912. if ( !_stricmp (szOID_BASIC_CONSTRAINTS2, pszOID) )
  913. {
  914. SetBasicConstraintsDescription (pCertExtension);
  915. }
  916. else if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszOID) )
  917. {
  918. bool bCritical = false;
  919. m_rCertTemplate.IsExtensionCritical (TEXT (szOID_ENHANCED_KEY_USAGE),
  920. bCritical);
  921. SetEnhancedKeyUsageDescription (bCritical);
  922. }
  923. else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
  924. {
  925. bool bCritical = false;
  926. m_rCertTemplate.IsExtensionCritical (TEXT (szOID_APPLICATION_CERT_POLICIES),
  927. bCritical);
  928. SetApplicationPoliciesDescription (bCritical);
  929. }
  930. else if ( !_stricmp (szOID_KEY_USAGE, pszOID) )
  931. {
  932. SetKeyUsageDescription (pCertExtension);
  933. }
  934. else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
  935. {
  936. bool bCritical = false;
  937. m_rCertTemplate.IsExtensionCritical (TEXT (szOID_CERT_POLICIES),
  938. bCritical);
  939. SetCertPoliciesDescription (bCritical);
  940. }
  941. else if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
  942. {
  943. SetCertTypeDescription (pCertExtension);
  944. }
  945. else if ( !_stricmp (szOID_CERTIFICATE_TEMPLATE, pszOID) )
  946. {
  947. SetCertTemplateExtension (pCertExtension);
  948. }
  949. else
  950. {
  951. CString szText;
  952. VERIFY (szText.LoadString (IDS_NONE));
  953. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
  954. }
  955. }
  956. else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
  957. {
  958. SetCertPoliciesDescription (false);
  959. }
  960. else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
  961. {
  962. SetApplicationPoliciesDescription (false);
  963. }
  964. }
  965. }
  966. }
  967. else
  968. {
  969. CString szText;
  970. VERIFY (szText.LoadString (IDS_NO_EXTENSION_SELECTED));
  971. SetDlgItemText (IDC_EXTENSION_NAME, szText);
  972. VERIFY (szText.LoadString (IDS_NONE));
  973. SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
  974. }
  975. }
  976. void CTemplateExtensionsPropertyPage::OnDestroy()
  977. {
  978. CHelpPropertyPage::OnDestroy();
  979. m_imageListNormal.Destroy ();
  980. m_imageListSmall.Destroy ();
  981. }