1119 lines
38 KiB
C++
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 ();
|
|
}
|