Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1146 lines
41 KiB

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