windows-nt/Source/XPSP1/NT/admin/snapin/certentp/templateextensionspropertypage.cpp
2020-09-26 16:20:57 +08:00

1119 lines
38 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000-2001.
//
// File: TemplateExtensionsPropertyPage.cpp
//
// Contents: Implementation of CTemplateExtensionsPropertyPage
//
//----------------------------------------------------------------------------
// TemplateExtensionsPropertyPage.cpp : implementation file
//
#include "stdafx.h"
#include "certtmpl.h"
#include "TemplateExtensionsPropertyPage.h"
#include "KeyUsageDlg.h"
#include "BasicConstraintsDlg.h"
#include "PolicyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
PCWSTR pcszNEWLINE = L"\r\n";
#define IDI_CRITICAL_EXTENSION 2
#define IDI_EXTENSION 3
/////////////////////////////////////////////////////////////////////////////
// CTemplateExtensionsPropertyPage property page
CTemplateExtensionsPropertyPage::CTemplateExtensionsPropertyPage(
CCertTemplate& rCertTemplate,
bool& rbIsDirty)
: CHelpPropertyPage(CTemplateExtensionsPropertyPage::IDD),
m_rCertTemplate (rCertTemplate),
m_rbIsDirty (rbIsDirty)
{
//{{AFX_DATA_INIT(CTemplateExtensionsPropertyPage)
//}}AFX_DATA_INIT
m_rCertTemplate.AddRef ();
}
CTemplateExtensionsPropertyPage::~CTemplateExtensionsPropertyPage()
{
m_rCertTemplate.Release ();
}
void CTemplateExtensionsPropertyPage::DoDataExchange(CDataExchange* pDX)
{
CHelpPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTemplateExtensionsPropertyPage)
DDX_Control(pDX, IDC_EXTENSION_LIST, m_extensionList);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTemplateExtensionsPropertyPage, CHelpPropertyPage)
//{{AFX_MSG_MAP(CTemplateExtensionsPropertyPage)
ON_BN_CLICKED(IDC_SHOW_DETAILS, OnShowDetails)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_EXTENSION_LIST, OnItemchangedExtensionList)
ON_NOTIFY(NM_DBLCLK, IDC_EXTENSION_LIST, OnDblclkExtensionList)
ON_NOTIFY(LVN_DELETEITEM, IDC_EXTENSION_LIST, OnDeleteitemExtensionList)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTemplateExtensionsPropertyPage message handlers
BOOL CTemplateExtensionsPropertyPage::OnInitDialog()
{
CHelpPropertyPage::OnInitDialog();
if ( m_rCertTemplate.GetType () > 1 )
{
CString szText;
VERIFY (szText.LoadString (IDS_V2_EXTENSIONS_HELP_HINT));
SetDlgItemText (IDC_EXTENSIONS_HELP_HINT, szText);
}
// Set up list controls
COLORREF cr = RGB (255, 0, 255);
CThemeContextActivator activator;
VERIFY (m_imageListNormal.Create (IDB_EXTENSIONS, 32, 0, cr));
VERIFY (m_imageListSmall.Create (IDB_EXTENSIONS, 16, 0, cr));
m_extensionList.SetImageList (CImageList::FromHandle (m_imageListSmall), LVSIL_SMALL);
m_extensionList.SetImageList (CImageList::FromHandle (m_imageListNormal), LVSIL_NORMAL);
int colWidths[NUM_COLS] = {400};
// Add "Certificate Extension" column
CString szText;
VERIFY (szText.LoadString (IDS_CERTIFICATE_EXTENSION));
VERIFY (m_extensionList.InsertColumn (COL_CERT_EXTENSION, (LPCWSTR) szText,
LVCFMT_LEFT, colWidths[COL_CERT_EXTENSION], COL_CERT_EXTENSION) != -1);
// Add extensions
bool bEKUExtensionFound = false;
bool bCertPoliciesExtensionFound = false;
bool bApplicationPoliciesExtensionFound = false;
HRESULT hr = S_OK;
DWORD dwExtensionCnt = m_rCertTemplate.GetCertExtensionCount ();
for (DWORD dwIndex = 0; dwIndex < dwExtensionCnt; dwIndex++)
{
PSTR pszObjId = 0;
BOOL fCritical = FALSE;
hr = m_rCertTemplate.GetCertExtension (dwIndex, &pszObjId, fCritical);
if ( SUCCEEDED (hr) )
{
if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszObjId) )
bEKUExtensionFound = true;
else if ( !_stricmp (szOID_CERT_POLICIES, pszObjId) )
bCertPoliciesExtensionFound = true;
else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszObjId) )
bApplicationPoliciesExtensionFound = true;
// Don't add EKU except for version 1
if ( m_rCertTemplate.GetType () > 1 && !_stricmp (szOID_ENHANCED_KEY_USAGE, pszObjId) )
continue;
// Don't add Application Policies for version 1
if ( m_rCertTemplate.GetType () == 1 && !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszObjId) )
continue;
InsertListItem (pszObjId, fCritical);
delete [] pszObjId;
}
}
if ( !bEKUExtensionFound && 1 == m_rCertTemplate.GetType () ) // only version 1
{
InsertListItem (szOID_ENHANCED_KEY_USAGE, FALSE);
}
if ( !bCertPoliciesExtensionFound && m_rCertTemplate.GetType () > 1 ) // not version 1
{
InsertListItem (szOID_CERT_POLICIES, FALSE);
}
// Fixes 228146: CERTTMPL:The default "Cross Certification Authority" template does not have the application Policy extension item
if ( !bApplicationPoliciesExtensionFound && m_rCertTemplate.GetType () > 1 ) // version 2 or greater
{
InsertListItem (szOID_APPLICATION_CERT_POLICIES, FALSE);
}
EnableControls ();
if ( 1 == m_rCertTemplate.GetType () )
GetDlgItem (IDC_SHOW_DETAILS)->ShowWindow (SW_HIDE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
HRESULT CTemplateExtensionsPropertyPage::InsertListItem (LPSTR pszExtensionOid, BOOL fCritical)
{
if ( !pszExtensionOid )
return E_POINTER;
HRESULT hr = S_OK;
CString friendlyName;
if ( MyGetOIDInfoA (friendlyName, pszExtensionOid) )
{
LV_ITEM lvItem;
int iItem = m_extensionList.GetItemCount ();
::ZeroMemory (&lvItem, sizeof (lvItem));
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvItem.iItem = iItem;
lvItem.iSubItem = COL_CERT_EXTENSION;
lvItem.pszText = (LPWSTR)(LPCWSTR) friendlyName;
if ( fCritical )
lvItem.iImage = IDI_CRITICAL_EXTENSION;
else
lvItem.iImage = IDI_EXTENSION;
PSTR pszOID = new CHAR[strlen (pszExtensionOid)+1];
if ( pszOID )
{
strcpy (pszOID, pszExtensionOid);
lvItem.lParam = (LPARAM) pszOID;
iItem = m_extensionList.InsertItem (&lvItem);
ASSERT (-1 != iItem);
if ( -1 != iItem )
hr = E_FAIL;
}
else
hr = E_OUTOFMEMORY;
}
else
hr = E_FAIL;
return hr;
}
void CTemplateExtensionsPropertyPage::EnableControls()
{
int nSelCnt = m_extensionList.GetSelectedCount ();
BOOL bEnableDetails = TRUE;
int nSelIndex = GetSelectedListItem ();
if ( 1 == nSelCnt )
{
PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
_ASSERT (pszOID);
if ( pszOID )
{
if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
bEnableDetails = FALSE;
else if ( !_stricmp (szOID_BASIC_CONSTRAINTS, pszOID) )
bEnableDetails = FALSE;
else if ( !_stricmp (szOID_CERTIFICATE_TEMPLATE, pszOID) )
bEnableDetails = FALSE;
}
}
else
bEnableDetails = FALSE;
GetDlgItem (IDC_SHOW_DETAILS)->EnableWindow (bEnableDetails);
}
void CTemplateExtensionsPropertyPage::OnOK()
{
CDialog::OnOK();
}
void CTemplateExtensionsPropertyPage::OnShowDetails()
{
int nSelCnt = m_extensionList.GetSelectedCount ();
_ASSERT (1 == nSelCnt);
int nSelIndex = GetSelectedListItem ();
if ( 1 == nSelCnt )
{
PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
if ( pszOID )
{
PCERT_EXTENSION pCertExtension = 0;
HRESULT hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
if ( SUCCEEDED (hr) )
{
bool bExtensionAllocedLocally = false;
if ( !pCertExtension )
{
pCertExtension = new CERT_EXTENSION;
if ( pCertExtension )
{
::ZeroMemory (pCertExtension, sizeof (CERT_EXTENSION));
pCertExtension->pszObjId = pszOID;
bExtensionAllocedLocally = true;
}
else
return;
}
CDialog* pDlg = 0;
if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
{
return;
}
else if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszOID) )
{
if ( m_rCertTemplate.GetType () == 1 )
{
pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
}
}
else if ( !_stricmp (szOID_KEY_USAGE, pszOID) )
{
pDlg = new CKeyUsageDlg (this, m_rCertTemplate, pCertExtension);
}
else if ( !_stricmp (szOID_BASIC_CONSTRAINTS, pszOID) )
{
return;
}
else if ( !_stricmp (szOID_BASIC_CONSTRAINTS2, pszOID) )
{
pDlg = new CBasicConstraintsDlg (this, m_rCertTemplate, pCertExtension);
}
else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
{
pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
}
else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
{
if ( m_rCertTemplate.GetType () > 1 )
{
pDlg = new CPolicyDlg (this, m_rCertTemplate, pCertExtension);
}
}
else
{
ASSERT (0);
}
bool bRefresh = false;
if ( pDlg )
{
CThemeContextActivator activator;
if ( IDOK == pDlg->DoModal () )
bRefresh = true;
delete pDlg;
}
if ( bExtensionAllocedLocally )
delete pCertExtension;
m_rCertTemplate.FreeCertExtensions ();
if ( bRefresh )
{
hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
if ( SUCCEEDED (hr) )
{
SetModified ();
m_rbIsDirty = true;
int nImage = 0;
if ( pCertExtension && pCertExtension->fCritical )
nImage = IDI_CRITICAL_EXTENSION;
else
nImage = IDI_EXTENSION;
VERIFY (m_extensionList.SetItem (nSelIndex, 0, LVIF_IMAGE, 0,
nImage, 0, 0, 0));
ShowDescription ();
VERIFY (m_extensionList.SetItem (nSelIndex, 0, LVIF_IMAGE, 0,
nImage, 0, 0, 0));
m_rCertTemplate.FreeCertExtensions ();
}
}
}
}
}
}
int CTemplateExtensionsPropertyPage::GetSelectedListItem()
{
int nSelItem = -1;
if ( m_extensionList.m_hWnd && m_extensionList.GetSelectedCount () > 0 )
{
int nCnt = m_extensionList.GetItemCount ();
ASSERT (nCnt >= 1);
UINT flag = 0;
while (--nCnt >= 0)
{
flag = ListView_GetItemState (m_extensionList.m_hWnd, nCnt, LVIS_SELECTED);
if ( flag & LVNI_SELECTED )
{
nSelItem = nCnt;
break;
}
}
}
return nSelItem;
}
void CTemplateExtensionsPropertyPage::OnItemchangedExtensionList(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLISTVIEW pNMListView = (LPNMLISTVIEW) pNMHDR;
ASSERT (pNMListView);
if ( !pNMListView )
{
*pResult = 0;
return;
}
if ( !(LVIS_SELECTED & pNMListView->uNewState) )
{
CString szText;
VERIFY (szText.LoadString (IDS_NO_EXTENSION_SELECTED));
SetDlgItemText (IDC_EXTENSION_NAME, szText);
VERIFY (szText.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
*pResult = 0;
return;
}
EnableControls ();
ShowDescription ();
*pResult = 0;
}
void CTemplateExtensionsPropertyPage::SetCertTemplateExtension (PCERT_EXTENSION pCertExtension)
{
ASSERT (pCertExtension);
if ( !pCertExtension )
return;
DWORD cbData = 0;
if ( CryptDecodeObject(X509_ASN_ENCODING,
szOID_CERTIFICATE_TEMPLATE,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
NULL,
&cbData) )
{
CERT_TEMPLATE_EXT* pbTemplate = (CERT_TEMPLATE_EXT*) LocalAlloc(LPTR, cbData);
if ( pbTemplate )
{
if ( CryptDecodeObject(X509_ASN_ENCODING,
szOID_CERTIFICATE_TEMPLATE,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
pbTemplate,
&cbData) )
{
CString text;
CString description;
//copy the extension oid
if ( pbTemplate->pszObjId )
{
CString templateName;
if ( MyGetOIDInfoA (templateName, pbTemplate->pszObjId) )
{
CString szOID;
int nLen = ::MultiByteToWideChar (CP_ACP, 0,
pbTemplate->pszObjId, -1, NULL, 0);
ASSERT (nLen);
if ( nLen )
{
nLen = ::MultiByteToWideChar (CP_ACP, 0,
pbTemplate->pszObjId, -1,
szOID.GetBufferSetLength (nLen), nLen);
ASSERT (nLen);
szOID.ReleaseBuffer ();
}
if ( !wcscmp (templateName, szOID) )
{
// Bug 213073 CryptFormatObject: Need to include
// the cert temp OID in the Certificate Template
// Information extension
// When the template is cloned, the oid-name pair
// is not in the global list. Just use the
// template display name the user provided
templateName = m_rCertTemplate.GetDisplayName ();
}
text.FormatMessage (IDS_TEMPLATE_NAME, templateName);
description += text;
description += pcszNEWLINE;
// Copy the template OID
text.FormatMessage (IDS_TEMPLATE_OID, szOID);
description += text;
description += pcszNEWLINE;
}
}
// copy the subject type description
CString szSubjectTypeDescription;
if ( SUCCEEDED (m_rCertTemplate.GetSubjectTypeDescription (
0, szSubjectTypeDescription)) )
{
text.FormatMessage (IDS_SUBJECT_TYPE_DESCRIPTION, szSubjectTypeDescription);
description += text;
description += pcszNEWLINE;
}
//copy the version
WCHAR str[32];
_ultow (pbTemplate->dwMajorVersion, str, 10);
text.FormatMessage (IDS_MAJOR_VERSION_NUMBER, str);
description += text;
description += pcszNEWLINE;
_ultow (pbTemplate->dwMinorVersion, str, 10);
text.FormatMessage (IDS_MINOR_VERSION_NUMBER, str);
description += text;
description += pcszNEWLINE;
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
LocalFree (pbTemplate);
}
}
}
void CTemplateExtensionsPropertyPage::SetCertTypeDescription (PCERT_EXTENSION pCertExtension)
{
ASSERT (pCertExtension);
if ( !pCertExtension )
return;
DWORD cbValue = 0;
if ( ::CryptDecodeObject(
CRYPT_ASN_ENCODING,
X509_UNICODE_ANY_STRING,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
0,
&cbValue) )
{
CERT_NAME_VALUE* pCNValue = (CERT_NAME_VALUE*)
::LocalAlloc(LPTR, cbValue);
if ( pCNValue )
{
if ( ::CryptDecodeObject(
CRYPT_ASN_ENCODING,
X509_UNICODE_ANY_STRING,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
pCNValue,
&cbValue) )
{
CString text = (LPWSTR) pCNValue->Value.pbData;
CString description;
if ( text.IsEmpty () )
VERIFY (text.LoadString (IDS_NONE));
description.FormatMessage (IDS_TEMPLATE_INTERNAL_NAME, text);
description += pcszNEWLINE;
// copy the subject type description
CString szSubjectTypeDescription;
if ( SUCCEEDED (m_rCertTemplate.GetSubjectTypeDescription (
0, szSubjectTypeDescription)) )
{
text.FormatMessage (IDS_SUBJECT_TYPE_DESCRIPTION, szSubjectTypeDescription);
description += text;
description += pcszNEWLINE;
}
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
::LocalFree (pCNValue);
}
else
{
_TRACE (0, L"CryptDecodeObject (CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING, ...) failed: 0x%x\n",
GetLastError ());
}
}
else
{
_TRACE (0, L"CryptDecodeObject (CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING, ...) failed: 0x%x\n",
GetLastError ());
}
}
void CTemplateExtensionsPropertyPage::SetKeyUsageDescription (PCERT_EXTENSION pCertExtension)
{
ASSERT (pCertExtension);
if ( !pCertExtension )
return;
CString description;
CString text;
DWORD cbKeyUsage = 0;
CRYPT_BIT_BLOB* pKeyUsage = 0;
if ( ::CryptDecodeObject(CRYPT_ASN_ENCODING,
szOID_KEY_USAGE,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0, NULL, &cbKeyUsage) )
{
pKeyUsage = (CRYPT_BIT_BLOB*)
::LocalAlloc (LPTR, cbKeyUsage);
if ( pKeyUsage )
{
if ( ::CryptDecodeObject (CRYPT_ASN_ENCODING,
szOID_KEY_USAGE,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0, pKeyUsage, &cbKeyUsage) )
{
if (pKeyUsage->cbData >= 1)
{
if ( pKeyUsage->pbData[0] &
(CERT_DIGITAL_SIGNATURE_KEY_USAGE |
CERT_NON_REPUDIATION_KEY_USAGE |
CERT_KEY_CERT_SIGN_KEY_USAGE |
CERT_OFFLINE_CRL_SIGN_KEY_USAGE) )
{
VERIFY (text.LoadString (IDS_SIGNATURE_REQUIREMENTS));
description += text;
description += pcszNEWLINE;
if ( pKeyUsage->pbData[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_DIGITAL_SIGNATURE));
description += text;
description += pcszNEWLINE;
}
if ( pKeyUsage->pbData[0] & CERT_NON_REPUDIATION_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_NON_REPUDIATION));
description += text;
description += pcszNEWLINE;
}
if ( pKeyUsage->pbData[0] & CERT_KEY_CERT_SIGN_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_CERTIFICATE_SIGNING));
description += text;
description += pcszNEWLINE;
}
if ( pKeyUsage->pbData[0] & CERT_OFFLINE_CRL_SIGN_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_CRL_SIGNING));
description += text;
description += pcszNEWLINE;
}
}
if ( pKeyUsage->pbData[0] & (CERT_KEY_ENCIPHERMENT_KEY_USAGE |
CERT_DATA_ENCIPHERMENT_KEY_USAGE |
CERT_KEY_AGREEMENT_KEY_USAGE) )
{
if ( !description.IsEmpty () )
description += pcszNEWLINE;
if ( pKeyUsage->pbData[0] & CERT_KEY_ENCIPHERMENT_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_ALLOW_KEY_EXCHANGE_ONLY_WITH_KEY_ENCRYPTION));
description += text;
description += pcszNEWLINE;
}
if ( pKeyUsage->pbData[0] & CERT_KEY_AGREEMENT_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_ALLOW_KEY_EXCHANGE_WITHOUT_KEY_ENCRYPTION));
description += text;
description += pcszNEWLINE;
}
if ( pKeyUsage->pbData[0] & CERT_DATA_ENCIPHERMENT_KEY_USAGE )
{
VERIFY (text.LoadString (IDS_ALLOW_ENCRYPTION_OF_USER_DATA));
description += text;
description += pcszNEWLINE;
}
}
}
// if (pKeyUsage->cbData >= 2)
// {
// if ( pKeyUsage->pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE )
// SendDlgItemMessage (IDC_CHECK_DECIPHERMENT_ONLY, BM_SETCHECK, BST_CHECKED);
// }
}
else
{
DWORD dwErr = GetLastError ();
_TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
DisplaySystemError (NULL, dwErr);
}
LocalFree (pKeyUsage);
}
}
else
{
DWORD dwErr = GetLastError ();
_TRACE (0, L"CryptDecodeObject (szOID_KEY_USAGE) failed: 0x%x\n", dwErr);
DisplaySystemError (NULL, dwErr);
}
if ( pCertExtension->fCritical )
{
VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
description += text;
description += pcszNEWLINE;
}
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
void CTemplateExtensionsPropertyPage::SetEnhancedKeyUsageDescription (bool bCritical)
{
CString description;
CString text;
int nEKUIndex = 0;
CString szEKU;
while ( SUCCEEDED (m_rCertTemplate.GetEnhancedKeyUsage (nEKUIndex, szEKU)) )
{
int nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szEKU, // wide-character string
(int) wcslen (szEKU), // number of chars in string
0, // buffer for new string
0, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen > 0 )
{
nLen++; // account for Null terminator
PSTR pszAnsiBuf = new CHAR[nLen];
if ( pszAnsiBuf )
{
ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szEKU, // wide-character string
(int) wcslen (szEKU), // number of chars in string
pszAnsiBuf, // buffer for new string
nLen, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen )
{
CString szEKUName;
if ( MyGetOIDInfoA (szEKUName, pszAnsiBuf) )
{
description += szEKUName;
description += pcszNEWLINE;
}
}
delete [] pszAnsiBuf;
}
}
nEKUIndex++;
}
if ( bCritical )
{
VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
description += text;
description += pcszNEWLINE;
}
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
void CTemplateExtensionsPropertyPage::SetApplicationPoliciesDescription (bool bCritical)
{
CString description;
CString text;
int nAppPolicyIndex = 0;
CString szAppPolicy;
while ( SUCCEEDED (m_rCertTemplate.GetApplicationPolicy (nAppPolicyIndex, szAppPolicy)) )
{
int nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szAppPolicy, // wide-character string
(int) wcslen (szAppPolicy), // number of chars in string
0, // buffer for new string
0, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen > 0 )
{
nLen++; // account for Null terminator
PSTR pszAnsiBuf = new CHAR[nLen];
if ( pszAnsiBuf )
{
ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szAppPolicy, // wide-character string
(int) wcslen (szAppPolicy), // number of chars in string
pszAnsiBuf, // buffer for new string
nLen, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen )
{
CString szAppPolicyName;
if ( MyGetOIDInfoA (szAppPolicyName, pszAnsiBuf) )
{
description += szAppPolicyName;
description += pcszNEWLINE;
}
}
delete [] pszAnsiBuf;
}
}
nAppPolicyIndex++;
}
if ( bCritical )
{
VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
description += text;
description += pcszNEWLINE;
}
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
void CTemplateExtensionsPropertyPage::SetCertPoliciesDescription (bool bCritical)
{
CString description;
CString text;
VERIFY (text.LoadString (IDS_CERT_POLICY_KNOWN_AS_ISSUANCE_POLICY));
description += text;
description += pcszNEWLINE;
description += pcszNEWLINE;
int nCertPolicyIndex = 0;
CString szCertPolicy;
while ( SUCCEEDED (m_rCertTemplate.GetCertPolicy (nCertPolicyIndex, szCertPolicy)) )
{
int nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szCertPolicy, // wide-character string
(int) wcslen (szCertPolicy), // number of chars in string
0, // buffer for new string
0, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen > 0 )
{
nLen++; // account for Null terminator
PSTR pszAnsiBuf = new CHAR[nLen];
if ( pszAnsiBuf )
{
ZeroMemory (pszAnsiBuf, nLen*sizeof(CHAR));
nLen = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
(PCWSTR) szCertPolicy, // wide-character string
(int) wcslen (szCertPolicy), // number of chars in string
pszAnsiBuf, // buffer for new string
nLen, // size of buffer
0, // default for unmappable chars
0); // set when default char used
if ( nLen )
{
CString szPolicyName;
if ( MyGetOIDInfoA (szPolicyName, pszAnsiBuf) )
{
description += szPolicyName;
description += pcszNEWLINE;
}
}
delete [] pszAnsiBuf;
}
}
nCertPolicyIndex++;
}
if ( bCritical )
{
VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
description += text;
description += pcszNEWLINE;
}
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
void CTemplateExtensionsPropertyPage::SetBasicConstraintsDescription (PCERT_EXTENSION pCertExtension)
{
ASSERT (pCertExtension);
if ( !pCertExtension )
return;
CString description;
CString text;
VERIFY (text.LoadString (IDS_SUBJECT_IS_CA));
description += text;
description += pcszNEWLINE;
PCERT_BASIC_CONSTRAINTS2_INFO pBCInfo = 0;
DWORD cbInfo = 0;
if ( CryptDecodeObject (
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
//X509_BASIC_CONSTRAINTS2,
szOID_BASIC_CONSTRAINTS2,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
0,
&cbInfo) )
{
pBCInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) ::LocalAlloc (
LPTR, cbInfo);
if ( pBCInfo )
{
if ( CryptDecodeObject (
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
//X509_BASIC_CONSTRAINTS2,
szOID_BASIC_CONSTRAINTS2,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
pBCInfo,
&cbInfo) )
{
if ( pBCInfo->fPathLenConstraint )
{
VERIFY (text.LoadString (IDS_ONLY_ISSUE_END_ENTITIES));
description += text;
description += pcszNEWLINE;
}
}
else
{
_TRACE (0, L"CryptDecodeObjectEx (szOID_BASIC_CONSTRAINTS2) failed: 0x%x\n", GetLastError ());
}
LocalFree (pBCInfo);
}
}
else
{
_TRACE (0, L"CryptDecodeObjectEx (szOID_BASIC_CONSTRAINTS2) failed: 0x%x\n", GetLastError ());
}
if ( pCertExtension->fCritical )
{
VERIFY (text.LoadString (IDS_CRITICAL_EXTENSION));
description += text;
description += pcszNEWLINE;
}
if ( description.IsEmpty () )
VERIFY (description.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, description);
}
void CTemplateExtensionsPropertyPage::OnDblclkExtensionList(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
OnShowDetails ();
*pResult = 0;
}
void CTemplateExtensionsPropertyPage::DoContextHelp (HWND hWndControl)
{
_TRACE(1, L"Entering CTemplateExtensionsPropertyPage::DoContextHelp\n");
switch (::GetDlgCtrlID (hWndControl))
{
case IDC_STATIC:
break;
default:
// Display context help for a control
if ( !::WinHelp (
hWndControl,
GetContextHelpFile (),
HELP_WM_HELP,
(DWORD_PTR) g_aHelpIDs_IDD_TEMPLATE_EXTENSIONS) )
{
_TRACE(0, L"WinHelp () failed: 0x%x\n", GetLastError ());
}
break;
}
_TRACE(-1, L"Leaving CTemplateExtensionsPropertyPage::DoContextHelp\n");
}
void CTemplateExtensionsPropertyPage::OnDeleteitemExtensionList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
PSTR pszOID = (PSTR) m_extensionList.GetItemData (pNMListView->iItem);
if ( pszOID )
{
delete [] pszOID;
}
*pResult = 0;
}
BOOL CTemplateExtensionsPropertyPage::OnSetActive()
{
BOOL bRVal = CHelpPropertyPage::OnSetActive();
ShowDescription ();
return bRVal;
}
void CTemplateExtensionsPropertyPage::ShowDescription ()
{
int nSelCnt = m_extensionList.GetSelectedCount ();
int nSelIndex = GetSelectedListItem ();
if ( 1 == nSelCnt )
{
PSTR pszOID = (PSTR) m_extensionList.GetItemData (nSelIndex);
if ( pszOID )
{
CString friendlyName;
if ( MyGetOIDInfoA (friendlyName, pszOID) )
{
CString text;
text.FormatMessage (IDS_EXTENSION_NAME, friendlyName);
SetDlgItemText (IDC_EXTENSION_NAME, text);
}
else
SetDlgItemText (IDC_EXTENSION_NAME, L"");
PCERT_EXTENSION pCertExtension = 0;
HRESULT hr = m_rCertTemplate.GetCertExtension (pszOID, &pCertExtension);
if ( SUCCEEDED (hr) )
{
if ( pCertExtension )
{
if ( !_stricmp (szOID_BASIC_CONSTRAINTS2, pszOID) )
{
SetBasicConstraintsDescription (pCertExtension);
}
else if ( !_stricmp (szOID_ENHANCED_KEY_USAGE, pszOID) )
{
bool bCritical = false;
m_rCertTemplate.IsExtensionCritical (TEXT (szOID_ENHANCED_KEY_USAGE),
bCritical);
SetEnhancedKeyUsageDescription (bCritical);
}
else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
{
bool bCritical = false;
m_rCertTemplate.IsExtensionCritical (TEXT (szOID_APPLICATION_CERT_POLICIES),
bCritical);
SetApplicationPoliciesDescription (bCritical);
}
else if ( !_stricmp (szOID_KEY_USAGE, pszOID) )
{
SetKeyUsageDescription (pCertExtension);
}
else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
{
bool bCritical = false;
m_rCertTemplate.IsExtensionCritical (TEXT (szOID_CERT_POLICIES),
bCritical);
SetCertPoliciesDescription (bCritical);
}
else if ( !_stricmp (szOID_ENROLL_CERTTYPE_EXTENSION, pszOID) )
{
SetCertTypeDescription (pCertExtension);
}
else if ( !_stricmp (szOID_CERTIFICATE_TEMPLATE, pszOID) )
{
SetCertTemplateExtension (pCertExtension);
}
else
{
CString szText;
VERIFY (szText.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
}
}
else if ( !_stricmp (szOID_CERT_POLICIES, pszOID) )
{
SetCertPoliciesDescription (false);
}
else if ( !_stricmp (szOID_APPLICATION_CERT_POLICIES, pszOID) )
{
SetApplicationPoliciesDescription (false);
}
}
}
}
else
{
CString szText;
VERIFY (szText.LoadString (IDS_NO_EXTENSION_SELECTED));
SetDlgItemText (IDC_EXTENSION_NAME, szText);
VERIFY (szText.LoadString (IDS_NONE));
SetDlgItemText (IDC_EXTENSION_DESCRIPTION, szText);
}
}
void CTemplateExtensionsPropertyPage::OnDestroy()
{
CHelpPropertyPage::OnDestroy();
m_imageListNormal.Destroy ();
m_imageListSmall.Destroy ();
}