440 lines
12 KiB
C++
440 lines
12 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2001.
|
|
//
|
|
// File: ACRSLast.cpp
|
|
//
|
|
// Contents: Implementation of Auto Cert Request Wizard Completion Page
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include <gpedit.h>
|
|
#include "ACRSLast.h"
|
|
#include "ACRSPSht.h"
|
|
#include "storegpe.h"
|
|
|
|
|
|
USE_HANDLE_MACROS("CERTMGR(ACRSLast.cpp)")
|
|
|
|
#ifdef _DEBUG
|
|
#ifndef ALPHA
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
// Gross
|
|
#define MAX_GPE_NAME_SIZE 40
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// ACRSCompletionPage property page
|
|
|
|
IMPLEMENT_DYNCREATE (ACRSCompletionPage, CWizard97PropertyPage)
|
|
|
|
ACRSCompletionPage::ACRSCompletionPage () : CWizard97PropertyPage (ACRSCompletionPage::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(ACRSCompletionPage)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
InitWizard97 (TRUE);
|
|
}
|
|
|
|
ACRSCompletionPage::~ACRSCompletionPage ()
|
|
{
|
|
}
|
|
|
|
void ACRSCompletionPage::DoDataExchange (CDataExchange* pDX)
|
|
{
|
|
CWizard97PropertyPage::DoDataExchange (pDX);
|
|
//{{AFX_DATA_MAP(ACRSCompletionPage)
|
|
DDX_Control (pDX, IDC_CHOICES_LIST, m_choicesList);
|
|
DDX_Control (pDX, IDC_BOLD_STATIC, m_staticBold);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(ACRSCompletionPage, CWizard97PropertyPage)
|
|
//{{AFX_MSG_MAP(ACRSCompletionPage)
|
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// ACRSCompletionPage message handlers
|
|
|
|
BOOL ACRSCompletionPage::OnInitDialog ()
|
|
{
|
|
CWizard97PropertyPage::OnInitDialog ();
|
|
|
|
m_staticBold.SetFont (&GetBigBoldFont ());
|
|
|
|
// Set up columns in list view
|
|
int colWidths[NUM_COLS] = {150, 200};
|
|
|
|
VERIFY (m_choicesList.InsertColumn (COL_OPTION, L"",
|
|
LVCFMT_LEFT, colWidths[COL_OPTION], COL_OPTION) != -1);
|
|
VERIFY (m_choicesList.InsertColumn (COL_VALUE, L"",
|
|
LVCFMT_LEFT, colWidths[COL_VALUE], COL_VALUE) != -1);
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
BOOL ACRSCompletionPage::OnSetActive ()
|
|
{
|
|
BOOL bResult = CWizard97PropertyPage::OnSetActive ();
|
|
if ( bResult )
|
|
{
|
|
// Remove all items then repopulate.
|
|
ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
|
|
ASSERT (pSheet);
|
|
if ( pSheet )
|
|
{
|
|
// If edit mode and nothing changed, show disabled finish
|
|
if ( pSheet->GetACR () && !pSheet->m_bEditModeDirty )
|
|
GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH | PSWIZB_BACK);
|
|
else
|
|
GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH | PSWIZB_BACK);
|
|
|
|
if ( pSheet->IsDirty () )
|
|
pSheet->MarkAsClean ();
|
|
VERIFY (m_choicesList.DeleteAllItems ());
|
|
CString text;
|
|
LV_ITEM lvItem;
|
|
int iItem = 0;
|
|
|
|
// Display cert type selection
|
|
VERIFY (text.LoadString (IDS_CERTIFICATE_TYPE_COLUMN_NAME));
|
|
|
|
::ZeroMemory (&lvItem, sizeof (lvItem));
|
|
lvItem.mask = LVIF_TEXT;
|
|
lvItem.iItem = iItem;
|
|
lvItem.iSubItem = COL_OPTION;
|
|
lvItem.pszText = (LPWSTR) (LPCWSTR) text;
|
|
VERIFY (-1 != m_choicesList.InsertItem (&lvItem));
|
|
|
|
WCHAR** pawszPropertyValue = 0;
|
|
HRESULT hResult = ::CAGetCertTypeProperty (pSheet->m_selectedCertType,
|
|
CERTTYPE_PROP_FRIENDLY_NAME,
|
|
&pawszPropertyValue);
|
|
ASSERT (SUCCEEDED (hResult));
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
if ( pawszPropertyValue[0] )
|
|
{
|
|
VERIFY (m_choicesList.SetItemText (iItem, COL_VALUE,
|
|
*pawszPropertyValue));
|
|
}
|
|
VERIFY (SUCCEEDED (::CAFreeCertTypeProperty (
|
|
pSheet->m_selectedCertType, pawszPropertyValue)));
|
|
}
|
|
iItem++;
|
|
|
|
// Display CA selection
|
|
VERIFY (text.LoadString (IDS_CERTIFICATE_AUTHORITIES));
|
|
|
|
::ZeroMemory (&lvItem, sizeof (lvItem));
|
|
lvItem.mask = LVIF_TEXT;
|
|
lvItem.iSubItem = COL_OPTION;
|
|
|
|
POSITION pos = 0;
|
|
HCAINFO hCAInfo = 0;
|
|
|
|
for (pos = pSheet->m_caInfoList.GetHeadPosition (); pos;)
|
|
{
|
|
lvItem.iItem = iItem;
|
|
lvItem.pszText = (LPWSTR) (LPCWSTR) text;
|
|
VERIFY (-1 != m_choicesList.InsertItem (&lvItem));
|
|
|
|
hCAInfo = pSheet->m_caInfoList.GetNext (pos);
|
|
ASSERT (hCAInfo);
|
|
if ( hCAInfo )
|
|
{
|
|
hResult = ::CAGetCAProperty (hCAInfo, CA_PROP_DISPLAY_NAME,
|
|
&pawszPropertyValue);
|
|
ASSERT (SUCCEEDED (hResult));
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
if ( pawszPropertyValue[0] )
|
|
{
|
|
VERIFY (m_choicesList.SetItemText (iItem, COL_VALUE,
|
|
*pawszPropertyValue));
|
|
}
|
|
VERIFY (SUCCEEDED (::CAFreeCAProperty (hCAInfo, pawszPropertyValue)));
|
|
}
|
|
}
|
|
text = L" "; // only the first one has text in it
|
|
iItem++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL ACRSCompletionPage::OnWizardFinish ()
|
|
{
|
|
BOOL bResult = TRUE;
|
|
HRESULT hResult = S_OK;
|
|
CWaitCursor waitCursor;
|
|
ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
|
|
ASSERT (pSheet);
|
|
if ( pSheet )
|
|
{
|
|
// If edit mode and nothing changed, just return
|
|
if ( pSheet->GetACR () && !pSheet->m_bEditModeDirty )
|
|
{
|
|
ASSERT (0);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
PCTL_ENTRY pCTLEntry = NULL;
|
|
DWORD cCTLEntry = 0;
|
|
|
|
hResult = GetCTLEntry (&cCTLEntry, &pCTLEntry);
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
BYTE *pbEncodedCTL = NULL;
|
|
DWORD cbEncodedCTL = 0;
|
|
|
|
hResult = MakeCTL (cCTLEntry, pCTLEntry, &pbEncodedCTL, &cbEncodedCTL);
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
bResult = pSheet->m_pCertStore->AddEncodedCTL (
|
|
X509_ASN_ENCODING,
|
|
pbEncodedCTL, cbEncodedCTL,
|
|
CERT_STORE_ADD_REPLACE_EXISTING,
|
|
NULL);
|
|
if ( !bResult )
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hResult = HRESULT_FROM_WIN32 (dwErr);
|
|
DisplaySystemError (m_hWnd, dwErr);
|
|
}
|
|
}
|
|
|
|
if (pbEncodedCTL)
|
|
::LocalFree (pbEncodedCTL);
|
|
}
|
|
|
|
if (pCTLEntry)
|
|
::LocalFree (pCTLEntry);
|
|
}
|
|
|
|
if ( SUCCEEDED (hResult) )
|
|
bResult = CWizard97PropertyPage::OnWizardFinish ();
|
|
else
|
|
bResult = FALSE;
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT ACRSCompletionPage::GetCTLEntry (OUT DWORD *pcCTLEntry, OUT PCTL_ENTRY *ppCTLEntry)
|
|
{
|
|
HRESULT hResult = S_OK;
|
|
ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
|
|
ASSERT (pSheet);
|
|
if ( pSheet )
|
|
{
|
|
const size_t HASH_SIZE = 20;
|
|
DWORD cCA = (DWORD)pSheet->m_caInfoList.GetCount ();
|
|
PCTL_ENTRY pCTLEntry = (PCTL_ENTRY) ::LocalAlloc (LPTR,
|
|
(sizeof (CTL_ENTRY) + HASH_SIZE) *cCA);
|
|
if ( pCTLEntry )
|
|
{
|
|
PBYTE pbHash = (PBYTE) (pCTLEntry + cCA);
|
|
HCAINFO hCAInfo = NULL;
|
|
PCCERT_CONTEXT pCertContext = NULL;
|
|
DWORD cbHash = HASH_SIZE;
|
|
DWORD iCA = 0;
|
|
|
|
for (POSITION pos = pSheet->m_caInfoList.GetHeadPosition (); pos;)
|
|
{
|
|
hCAInfo = pSheet->m_caInfoList.GetNext (pos);
|
|
ASSERT (hCAInfo);
|
|
if ( hCAInfo )
|
|
{
|
|
hResult = ::CAGetCACertificate (hCAInfo, &pCertContext);
|
|
ASSERT (SUCCEEDED (hResult));
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
cbHash = HASH_SIZE;
|
|
if (::CertGetCertificateContextProperty (pCertContext,
|
|
CERT_SHA1_HASH_PROP_ID,
|
|
pbHash,
|
|
&cbHash))
|
|
{
|
|
pCTLEntry[iCA].SubjectIdentifier.cbData = cbHash;
|
|
pCTLEntry[iCA].SubjectIdentifier.pbData = pbHash;
|
|
pbHash += cbHash;
|
|
::CertFreeCertificateContext (pCertContext);
|
|
iCA++;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hResult = HRESULT_FROM_WIN32 (dwErr);
|
|
DisplaySystemError (m_hWnd, dwErr);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
*pcCTLEntry = cCA;
|
|
*ppCTLEntry = pCTLEntry;
|
|
}
|
|
else
|
|
{
|
|
if (pCTLEntry)
|
|
::LocalFree (pCTLEntry);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hResult = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT ACRSCompletionPage::MakeCTL (
|
|
IN DWORD cCTLEntry,
|
|
IN PCTL_ENTRY pCTLEntry,
|
|
OUT BYTE **ppbEncodedCTL,
|
|
OUT DWORD *pcbEncodedCTL)
|
|
{
|
|
HRESULT hResult = S_OK;
|
|
ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
|
|
ASSERT (pSheet);
|
|
if ( pSheet )
|
|
{
|
|
PCERT_EXTENSIONS pCertExtensions = NULL;
|
|
|
|
|
|
hResult = ::CAGetCertTypeExtensions (pSheet->m_selectedCertType, &pCertExtensions);
|
|
ASSERT (SUCCEEDED (hResult));
|
|
if ( SUCCEEDED (hResult) )
|
|
{
|
|
CMSG_SIGNED_ENCODE_INFO SignerInfo;
|
|
memset (&SignerInfo, 0, sizeof (SignerInfo));
|
|
CTL_INFO CTLInfo;
|
|
memset (&CTLInfo, 0, sizeof (CTLInfo));
|
|
WCHAR** pawszPropName = 0;
|
|
|
|
|
|
ZeroMemory(&CTLInfo, sizeof(CTLInfo));
|
|
// set up the CTL info
|
|
CTLInfo.dwVersion = sizeof (CTLInfo);
|
|
CTLInfo.SubjectUsage.cUsageIdentifier = 1;
|
|
|
|
hResult = ::CAGetCertTypeProperty (pSheet->m_selectedCertType,
|
|
CERTTYPE_PROP_DN, &pawszPropName);
|
|
ASSERT (SUCCEEDED (hResult));
|
|
if ( SUCCEEDED (hResult) && pawszPropName[0] )
|
|
{
|
|
LPSTR psz = szOID_AUTO_ENROLL_CTL_USAGE;
|
|
WCHAR pwszGPEName[MAX_GPE_NAME_SIZE];
|
|
|
|
IGPEInformation *pGPEInfo = pSheet->m_pCertStore->GetGPEInformation();
|
|
|
|
ZeroMemory(pwszGPEName, MAX_GPE_NAME_SIZE*sizeof (WCHAR));
|
|
|
|
CTLInfo.ListIdentifier.cbData = (DWORD) (sizeof (WCHAR) * (wcslen (pawszPropName[0]) + 1));
|
|
|
|
if(pGPEInfo)
|
|
{
|
|
pGPEInfo->GetName(pwszGPEName, sizeof(pwszGPEName)/sizeof(pwszGPEName[0]));
|
|
CTLInfo.ListIdentifier.cbData += (DWORD) (sizeof(WCHAR)*(wcslen(pwszGPEName)+1));
|
|
}
|
|
|
|
CTLInfo.ListIdentifier.pbData = (PBYTE)LocalAlloc(LPTR, CTLInfo.ListIdentifier.cbData);
|
|
if(CTLInfo.ListIdentifier.pbData == NULL)
|
|
{
|
|
hResult = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if(pwszGPEName[0])
|
|
{
|
|
wcscpy((LPWSTR)CTLInfo.ListIdentifier.pbData, pwszGPEName);
|
|
wcscat((LPWSTR)CTLInfo.ListIdentifier.pbData, L"|");
|
|
}
|
|
wcscat((LPWSTR)CTLInfo.ListIdentifier.pbData, pawszPropName[0]);
|
|
|
|
|
|
CTLInfo.SubjectUsage.rgpszUsageIdentifier = &psz;
|
|
::GetSystemTimeAsFileTime (&CTLInfo.ThisUpdate);
|
|
CTLInfo.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
|
|
CTLInfo.cCTLEntry = cCTLEntry;
|
|
CTLInfo.rgCTLEntry = pCTLEntry;
|
|
|
|
// UNDONE - add the cert type extension
|
|
|
|
// add all the reg info as an extension
|
|
CTLInfo.cExtension = pCertExtensions->cExtension;
|
|
CTLInfo.rgExtension = pCertExtensions->rgExtension;
|
|
|
|
// encode the CTL
|
|
*pcbEncodedCTL = 0;
|
|
SignerInfo.cbSize = sizeof (SignerInfo);
|
|
if ( ::CryptMsgEncodeAndSignCTL (PKCS_7_ASN_ENCODING,
|
|
&CTLInfo, &SignerInfo, 0,
|
|
NULL, pcbEncodedCTL) )
|
|
{
|
|
*ppbEncodedCTL = (BYTE*) ::LocalAlloc (LPTR, *pcbEncodedCTL);
|
|
if ( *ppbEncodedCTL )
|
|
{
|
|
if (!::CryptMsgEncodeAndSignCTL (PKCS_7_ASN_ENCODING,
|
|
&CTLInfo, &SignerInfo, 0,
|
|
*ppbEncodedCTL, pcbEncodedCTL))
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hResult = HRESULT_FROM_WIN32 (dwErr);
|
|
DisplaySystemError (m_hWnd, dwErr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hResult = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hResult = HRESULT_FROM_WIN32 (dwErr);
|
|
DisplaySystemError (m_hWnd, dwErr);
|
|
}
|
|
|
|
VERIFY (SUCCEEDED (::CAFreeCertTypeProperty (
|
|
pSheet->m_selectedCertType, pawszPropName)));
|
|
}
|
|
if(CTLInfo.ListIdentifier.pbData)
|
|
{
|
|
::LocalFree(CTLInfo.ListIdentifier.pbData);
|
|
}
|
|
|
|
}
|
|
if (pCertExtensions)
|
|
::LocalFree (pCertExtensions);
|
|
}
|
|
|
|
return hResult;
|
|
}
|