3921 lines
125 KiB
C++
3921 lines
125 KiB
C++
|
//-------------------------------------------------------------
|
||
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
||
|
//
|
||
|
// File: mgrcert.cpp
|
||
|
//
|
||
|
// Contents: The cpp file to implement cert mgr dialogue
|
||
|
//
|
||
|
// History: Feb-26-98 xiaohs created
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
#include "wzrdpvk.h"
|
||
|
#include "winuser.h" //need this file for VK_DELETE
|
||
|
#include "mgrcert.h"
|
||
|
|
||
|
//context sensitive help for the main dialogue
|
||
|
static const HELPMAP CertMgrMainHelpMap[] = {
|
||
|
{IDC_CERTMGR_LIST, IDH_CERTMGR_LIST},
|
||
|
{IDC_CERTMGR_PURPOSE_COMBO, IDH_CERTMGR_PURPOSE_COMBO},
|
||
|
{IDC_CERTMGR_IMPORT, IDH_CERTMGR_IMPORT},
|
||
|
{IDC_CERTMGR_EXPORT, IDH_CERTMGR_EXPORT},
|
||
|
{IDC_CERTMGR_VIEW, IDH_CERTMGR_VIEW},
|
||
|
{IDC_CERTMGR_REMOVE, IDH_CERTMGR_REMOVE},
|
||
|
{IDC_CERTMGR_ADVANCE, IDH_CERTMGR_ADVANCE},
|
||
|
{IDC_CERTMGR_PURPOSE, IDH_CERTMGR_FIELD_PURPOSE},
|
||
|
};
|
||
|
|
||
|
//context sensitive help for the main dialogue
|
||
|
static const HELPMAP CertMgrAdvHelpMap[] = {
|
||
|
{IDC_CERTMGR_ADV_LIST, IDH_CERTMGR_ADV_LIST},
|
||
|
{IDC_CERTMGR_EXPORT_COMBO, IDH_CERTMGR_EXPORT_COMBO},
|
||
|
{IDC_CERTMGR_EXPORT_CHECK, IDH_CERTMGR_EXPORT_CHECK},
|
||
|
};
|
||
|
|
||
|
// Primary store associated with each tab. Store to be imported into.
|
||
|
static const LPCWSTR rgpwszTabStoreName[] = {
|
||
|
L"My", // 0
|
||
|
L"AddressBook", // 1
|
||
|
L"Ca", // 2
|
||
|
L"Root", // 3
|
||
|
L"TrustedPublisher", // 4
|
||
|
};
|
||
|
#define TAB_STORE_NAME_CNT (sizeof(rgpwszTabStoreName) / \
|
||
|
sizeof(rgpwszTabStoreName[0]))
|
||
|
|
||
|
/*
|
||
|
// The following code is obsolete due to new cert chain building code
|
||
|
//----------------------------------------------------------------------------
|
||
|
// AddCertChainToStore
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL AddCertChainToStore(HCERTSTORE hStore,
|
||
|
PCCERT_CONTEXT pCertContext)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
HCERTSTORE rghCertStores[20];
|
||
|
DWORD chStores;
|
||
|
PCCERT_CONTEXT pChildCert;
|
||
|
PCCERT_CONTEXT pParentCert;
|
||
|
FILETIME fileTime;
|
||
|
DWORD i;
|
||
|
|
||
|
if(!hStore || !pCertContext)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
|
||
|
GetSystemTimeAsFileTime(&fileTime);
|
||
|
|
||
|
if (!TrustOpenStores(NULL, &chStores, rghCertStores, 0))
|
||
|
goto TraceErr;
|
||
|
|
||
|
|
||
|
pChildCert = pCertContext;
|
||
|
while (NULL != (pParentCert = TrustFindIssuerCertificate(
|
||
|
pChildCert,
|
||
|
pChildCert->dwCertEncodingType,
|
||
|
chStores,
|
||
|
rghCertStores,
|
||
|
&fileTime,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0)))
|
||
|
{
|
||
|
CertAddCertificateContextToStore(hStore, pParentCert, CERT_STORE_ADD_NEW, NULL);
|
||
|
|
||
|
if (pChildCert != pCertContext)
|
||
|
{
|
||
|
CertFreeCertificateContext(pChildCert);
|
||
|
}
|
||
|
|
||
|
pChildCert = pParentCert;
|
||
|
}
|
||
|
|
||
|
if (pChildCert != pCertContext)
|
||
|
{
|
||
|
CertFreeCertificateContext(pChildCert);
|
||
|
}
|
||
|
|
||
|
for (i=0; i<chStores; i++)
|
||
|
{
|
||
|
CertCloseStore(rghCertStores[i], 0);
|
||
|
}
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
TRACE_ERROR(TraceErr);
|
||
|
} */
|
||
|
|
||
|
|
||
|
|
||
|
int WINAPI TabCtrl_InsertItemU(
|
||
|
HWND hwnd,
|
||
|
int iItem,
|
||
|
const LPTCITEMW pitem
|
||
|
)
|
||
|
{
|
||
|
TCITEMA TCItemA;
|
||
|
int iRet;
|
||
|
DWORD cb = 0;
|
||
|
|
||
|
|
||
|
if (FIsWinNT())
|
||
|
{
|
||
|
return ((int)SendMessage(hwnd, TCM_INSERTITEMW, iItem, (LPARAM) pitem));
|
||
|
}
|
||
|
|
||
|
memcpy(&TCItemA, pitem, sizeof(TCITEMA));
|
||
|
|
||
|
|
||
|
cb = WideCharToMultiByte(
|
||
|
0, // codepage
|
||
|
0, // dwFlags
|
||
|
pitem->pszText,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
|
||
|
|
||
|
if ((0 == cb) || (NULL == (TCItemA.pszText = (LPSTR) WizardAlloc(cb))))
|
||
|
{
|
||
|
return -1; // this is the unsuccessful return code for this call
|
||
|
}
|
||
|
|
||
|
if( 0 == (WideCharToMultiByte(
|
||
|
0,
|
||
|
0,
|
||
|
pitem->pszText,
|
||
|
-1,
|
||
|
TCItemA.pszText,
|
||
|
cb,
|
||
|
NULL,
|
||
|
NULL)))
|
||
|
{
|
||
|
WizardFree(TCItemA.pszText);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
iRet = (int)SendMessage(hwnd, TCM_INSERTITEMA, iItem, (LPARAM) &TCItemA);
|
||
|
|
||
|
WizardFree(TCItemA.pszText);
|
||
|
|
||
|
return iRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// This is the rundll32 entry point for start menu, administartive tools,
|
||
|
// CertMgr.
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDAPI CryptUIStartCertMgr(HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
|
||
|
{
|
||
|
|
||
|
CRYPTUI_CERT_MGR_STRUCT CertMgrStruct;
|
||
|
|
||
|
memset(&CertMgrStruct, 0, sizeof(CRYPTUI_CERT_MGR_STRUCT));
|
||
|
CertMgrStruct.dwSize=sizeof(CRYPTUI_CERT_MGR_STRUCT);
|
||
|
|
||
|
CryptUIDlgCertMgr(&CertMgrStruct);
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// GetFileContentFromCert
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL GetFileContentFromCert(DWORD dwExportFormat,
|
||
|
BOOL fExportChain,
|
||
|
PCCERT_CONTEXT pCertContext,
|
||
|
BYTE **ppBlob,
|
||
|
DWORD *pdwSize)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
void *pData=NULL;
|
||
|
DWORD dwSize=0;
|
||
|
HCERTSTORE hMemoryStore=NULL;
|
||
|
CRYPT_DATA_BLOB Blob;
|
||
|
HRESULT hr=E_INVALIDARG;
|
||
|
|
||
|
|
||
|
if(!ppBlob || !pdwSize || !pCertContext)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
*ppBlob=NULL;
|
||
|
*pdwSize=0;
|
||
|
|
||
|
switch(dwExportFormat)
|
||
|
{
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
|
||
|
|
||
|
dwSize=pCertContext->cbCertEncoded;
|
||
|
|
||
|
pData=WizardAlloc(dwSize);
|
||
|
if(!pData)
|
||
|
goto MemoryErr;
|
||
|
|
||
|
memcpy(pData, pCertContext->pbCertEncoded, dwSize);
|
||
|
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
|
||
|
//base 64 encode the BLOB
|
||
|
if(!CryptBinaryToStringA(
|
||
|
pCertContext->pbCertEncoded,
|
||
|
pCertContext->cbCertEncoded,
|
||
|
CRYPT_STRING_BASE64,
|
||
|
NULL,
|
||
|
&dwSize))
|
||
|
{
|
||
|
hr = GetLastError();
|
||
|
goto SetErrVar;
|
||
|
}
|
||
|
|
||
|
pData=WizardAlloc(dwSize * sizeof(CHAR));
|
||
|
if(!pData)
|
||
|
goto MemoryErr;
|
||
|
|
||
|
if(!CryptBinaryToStringA(
|
||
|
pCertContext->pbCertEncoded,
|
||
|
pCertContext->cbCertEncoded,
|
||
|
CRYPT_STRING_BASE64,
|
||
|
(char *)pData,
|
||
|
&dwSize))
|
||
|
{
|
||
|
hr = GetLastError();
|
||
|
goto SetErrVar;
|
||
|
}
|
||
|
|
||
|
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
|
||
|
|
||
|
//open a memory store
|
||
|
hMemoryStore=CertOpenStore(
|
||
|
CERT_STORE_PROV_MEMORY,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if(!hMemoryStore)
|
||
|
goto TraceErr;
|
||
|
|
||
|
if(FALSE == fExportChain)
|
||
|
{
|
||
|
if(!CertAddCertificateContextToStore(
|
||
|
hMemoryStore,
|
||
|
pCertContext,
|
||
|
CERT_STORE_ADD_REPLACE_EXISTING,
|
||
|
NULL))
|
||
|
goto TraceErr;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(!AddChainToStore(
|
||
|
hMemoryStore,
|
||
|
pCertContext,
|
||
|
0,
|
||
|
NULL,
|
||
|
FALSE,
|
||
|
NULL))
|
||
|
goto TraceErr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//save the store to a PKCS#7
|
||
|
Blob.cbData=0;
|
||
|
Blob.pbData=NULL;
|
||
|
|
||
|
if(!CertSaveStore(hMemoryStore,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
CERT_STORE_SAVE_AS_PKCS7,
|
||
|
CERT_STORE_SAVE_TO_MEMORY,
|
||
|
&Blob,
|
||
|
0))
|
||
|
goto TraceErr;
|
||
|
|
||
|
dwSize=Blob.cbData;
|
||
|
pData=WizardAlloc(dwSize);
|
||
|
if(!pData)
|
||
|
goto MemoryErr;
|
||
|
|
||
|
Blob.pbData=(BYTE *)pData;
|
||
|
|
||
|
if(!CertSaveStore(hMemoryStore,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
CERT_STORE_SAVE_AS_PKCS7,
|
||
|
CERT_STORE_SAVE_TO_MEMORY,
|
||
|
&Blob,
|
||
|
0))
|
||
|
goto TraceErr;
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
goto InvalidArgErr;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
//set up the return value
|
||
|
*pdwSize=dwSize;
|
||
|
*ppBlob=(BYTE *)pData;
|
||
|
pData=NULL;
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
if(hMemoryStore)
|
||
|
CertCloseStore(hMemoryStore, 0);
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
if(pData)
|
||
|
WizardFree(pData);
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
||
|
SET_ERROR_VAR(SetErrVar, hr);
|
||
|
TRACE_ERROR(TraceErr);
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// FreeFileNameAndContent
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL FreeFileNameAndContent( DWORD dwCount,
|
||
|
LPWSTR *prgwszFileName,
|
||
|
BYTE **prgBlob,
|
||
|
DWORD *prgdwSize)
|
||
|
{
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
if(prgwszFileName)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex < dwCount; dwIndex++)
|
||
|
{
|
||
|
if(prgwszFileName[dwIndex])
|
||
|
WizardFree(prgwszFileName[dwIndex]);
|
||
|
}
|
||
|
|
||
|
WizardFree(prgwszFileName);
|
||
|
}
|
||
|
|
||
|
if(prgBlob)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex < dwCount; dwIndex++)
|
||
|
{
|
||
|
if(prgBlob[dwIndex])
|
||
|
WizardFree(prgBlob[dwIndex]);
|
||
|
}
|
||
|
|
||
|
WizardFree(prgBlob);
|
||
|
}
|
||
|
|
||
|
if(prgdwSize)
|
||
|
WizardFree(prgdwSize);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Get a valid friendly name of the certificate
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL GetValidFriendlyName(PCCERT_CONTEXT pCertContext,
|
||
|
LPWSTR *ppwszName)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
DWORD dwChar=0;
|
||
|
LPWSTR pwsz=NULL;
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
|
||
|
if(!pCertContext || !ppwszName)
|
||
|
return FALSE;
|
||
|
|
||
|
//init
|
||
|
*ppwszName=NULL;
|
||
|
|
||
|
dwChar=0;
|
||
|
|
||
|
if(CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
NULL,
|
||
|
&dwChar) && (0!=dwChar))
|
||
|
{
|
||
|
pwsz=(LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
|
||
|
|
||
|
if(pwsz)
|
||
|
{
|
||
|
CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
pwsz,
|
||
|
&dwChar);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(NULL==pwsz)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
|
||
|
//make sure pwsz is a valid name
|
||
|
if(0 == (dwChar=wcslen(pwsz)))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//the friendly name can not be spaces all the time
|
||
|
for(dwIndex=0; dwIndex<dwChar; dwIndex++)
|
||
|
{
|
||
|
if(L' '!=pwsz[dwIndex])
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(dwIndex==dwChar)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
*ppwszName=WizardAllocAndCopyWStr(pwsz);
|
||
|
|
||
|
if(NULL == (*ppwszName))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pwsz)
|
||
|
WizardFree(pwsz);
|
||
|
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// InvalidFileNameWch
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL InvalidFileNameWch(WCHAR wChar)
|
||
|
{
|
||
|
if((wChar == L'\\') || (wChar == L':') || (wChar == L'/') || (wChar == L'*') || (wChar == L'|') || (wChar == L';'))
|
||
|
return TRUE;
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Build the filenames and their content based on the export selection
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL GetFileNameFromCert(DWORD dwExportFormat,
|
||
|
PCCERT_CONTEXT pCertContext,
|
||
|
LPWSTR pwszFileName)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
WCHAR wszCertificate[MAX_TITLE_LENGTH];
|
||
|
WCHAR wszExt[MAX_TITLE_LENGTH];
|
||
|
LPWSTR pwszName=NULL;
|
||
|
DWORD dwChar=0;
|
||
|
UINT idsExt=0;
|
||
|
LPWSTR pwszFirstPart=NULL;
|
||
|
LPWSTR pwszFriendlyName=NULL;
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
if(!pCertContext || !pwszFileName)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//init
|
||
|
*pwszFileName='\0';
|
||
|
|
||
|
|
||
|
//get the friendly name for the certificate
|
||
|
if(!GetValidFriendlyName(pCertContext,&pwszFriendlyName))
|
||
|
{
|
||
|
//if failed, we use subject
|
||
|
//Subject
|
||
|
dwChar=CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0);
|
||
|
|
||
|
if ((dwChar > 1) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
|
||
|
{
|
||
|
|
||
|
if(!CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
0,
|
||
|
NULL,
|
||
|
pwszName,
|
||
|
dwChar))
|
||
|
goto GetNameErr;
|
||
|
|
||
|
pwszFirstPart=pwszName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//load the string for Certificate
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_CERTIFICATE, wszCertificate, MAX_TITLE_LENGTH))
|
||
|
goto LoadStringErr;
|
||
|
|
||
|
pwszFirstPart=wszCertificate;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
pwszFirstPart=pwszFriendlyName;
|
||
|
|
||
|
//determine the extension for the file
|
||
|
switch(dwExportFormat)
|
||
|
{
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
|
||
|
idsExt=IDS_CER;
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
|
||
|
idsExt=IDS_CER;
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
|
||
|
idsExt=IDS_P7C;
|
||
|
break;
|
||
|
default:
|
||
|
idsExt=IDS_CER;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//load the string for Certificate
|
||
|
if(!LoadStringU(g_hmodThisDll, idsExt, wszExt, MAX_TITLE_LENGTH))
|
||
|
goto LoadStringErr;
|
||
|
|
||
|
//determine the max length of the file name
|
||
|
dwChar = wcslen(pwszFirstPart) > (CERTMGR_MAX_FILE_NAME - wcslen(wszExt) -1) ?
|
||
|
(CERTMGR_MAX_FILE_NAME - wcslen(wszExt) -1) : wcslen(pwszFirstPart);
|
||
|
|
||
|
wcsncpy(pwszFileName, pwszFirstPart, dwChar);
|
||
|
|
||
|
*(pwszFileName + dwChar)=L'\0';
|
||
|
|
||
|
wcscat(pwszFileName, wszExt);
|
||
|
|
||
|
//now, we replace the invalid file characters : ; / \
|
||
|
//with space
|
||
|
|
||
|
dwChar = wcslen(pwszFileName);
|
||
|
|
||
|
for(dwIndex =0; dwIndex<dwChar; dwIndex++)
|
||
|
{
|
||
|
if(InvalidFileNameWch(pwszFileName[dwIndex]))
|
||
|
pwszFileName[dwIndex]=L'_';
|
||
|
}
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
if(pwszName)
|
||
|
WizardFree(pwszName);
|
||
|
|
||
|
if(pwszFriendlyName)
|
||
|
WizardFree(pwszFriendlyName);
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
TRACE_ERROR(GetNameErr);
|
||
|
TRACE_ERROR(LoadStringErr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Build the filenames and their content based on the export selection
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL GetFileNameAndContent(LPNMLISTVIEW pvmn,
|
||
|
HWND hwndControl,
|
||
|
DWORD dwExportFormat,
|
||
|
BOOL fExportChain,
|
||
|
DWORD *pdwCount,
|
||
|
LPWSTR **pprgwszFileName,
|
||
|
BYTE ***pprgBlob,
|
||
|
DWORD **pprgdwSize)
|
||
|
{
|
||
|
|
||
|
BOOL fResult=FALSE;
|
||
|
DWORD dwCount=0;
|
||
|
DWORD dwIndex=0;
|
||
|
LVITEM lvItem;
|
||
|
int iIndex=0;
|
||
|
PCCERT_CONTEXT pCertContext=NULL;
|
||
|
|
||
|
if(!pvmn || !hwndControl || !pdwCount || !pprgwszFileName || !pprgBlob || !pprgdwSize)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//init
|
||
|
*pdwCount=0;
|
||
|
*pprgwszFileName=NULL;
|
||
|
*pprgBlob=NULL;
|
||
|
*pprgdwSize=NULL;
|
||
|
|
||
|
//get the count of selected certificates
|
||
|
dwCount=ListView_GetSelectedCount(hwndControl);
|
||
|
|
||
|
if( 0 == dwCount)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//allocate memory
|
||
|
if((*pprgwszFileName)=(LPWSTR *)WizardAlloc(sizeof(LPWSTR) * dwCount))
|
||
|
memset(*pprgwszFileName, 0, sizeof(LPWSTR) * dwCount);
|
||
|
|
||
|
if((*pprgBlob)=(BYTE **)WizardAlloc(sizeof(BYTE *)* dwCount))
|
||
|
memset(*pprgBlob, 0, sizeof(BYTE *)* dwCount);
|
||
|
|
||
|
if((*pprgdwSize)=(DWORD *)WizardAlloc(sizeof(DWORD) * dwCount))
|
||
|
memset(*pprgdwSize, 0, sizeof(DWORD) * dwCount);
|
||
|
|
||
|
if(!(*pprgwszFileName) || !(*pprgBlob) || !(*pprgdwSize))
|
||
|
goto MemoryErr;
|
||
|
|
||
|
//get the selected certificate
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
||
|
lvItem.mask=LVIF_PARAM;
|
||
|
|
||
|
iIndex=-1;
|
||
|
|
||
|
for(dwIndex=0; dwIndex < dwCount; dwIndex++)
|
||
|
{
|
||
|
|
||
|
iIndex=ListView_GetNextItem(hwndControl,
|
||
|
iIndex,
|
||
|
LVNI_SELECTED);
|
||
|
|
||
|
if(-1 == iIndex)
|
||
|
break;
|
||
|
|
||
|
lvItem.iItem=iIndex;
|
||
|
|
||
|
if(!ListView_GetItem(hwndControl,
|
||
|
&lvItem))
|
||
|
goto ListViewErr;
|
||
|
|
||
|
pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
|
||
|
|
||
|
if(!pCertContext)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//get the file name of the ceritificate
|
||
|
(*pprgwszFileName)[dwIndex]=(LPWSTR)WizardAlloc(sizeof(WCHAR) * CERTMGR_MAX_FILE_NAME);
|
||
|
|
||
|
if(!((*pprgwszFileName)[dwIndex]))
|
||
|
goto MemoryErr;
|
||
|
|
||
|
if(!GetFileNameFromCert(dwExportFormat,
|
||
|
pCertContext,
|
||
|
(*pprgwszFileName)[dwIndex]))
|
||
|
goto TraceErr;
|
||
|
|
||
|
|
||
|
//get the BLOB for the certificate
|
||
|
if(!GetFileContentFromCert(dwExportFormat, fExportChain, pCertContext,
|
||
|
&((*pprgBlob)[dwIndex]),
|
||
|
&((*pprgdwSize)[dwIndex])))
|
||
|
goto TraceErr;
|
||
|
|
||
|
}
|
||
|
|
||
|
*pdwCount=dwIndex;
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
if(pdwCount && pprgwszFileName && pprgBlob && pprgdwSize)
|
||
|
{
|
||
|
FreeFileNameAndContent(*pdwCount, *pprgwszFileName, *pprgBlob, *pprgdwSize);
|
||
|
*pdwCount=0;
|
||
|
*pprgwszFileName=NULL;
|
||
|
*pprgBlob=NULL;
|
||
|
*pprgdwSize=NULL;
|
||
|
}
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
||
|
TRACE_ERROR(ListViewErr);
|
||
|
TRACE_ERROR(TraceErr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Get all the selected certificates and do some work vased on dwFlag
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL GetAllSelectedItem(HWND hWndControl,
|
||
|
DWORD dwFlag,
|
||
|
void *pData)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
BOOL fCanDelete=TRUE;
|
||
|
HCERTSTORE *phCertStore=NULL;
|
||
|
PCCERT_CONTEXT pCertContext=NULL;
|
||
|
int iIndex=0;
|
||
|
LVITEM lvItem;
|
||
|
DWORD dwData=0;
|
||
|
DWORD dwAccessFlag=0;
|
||
|
|
||
|
if(!hWndControl)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if((ALL_SELECTED_CAN_DELETE == dwFlag) ||
|
||
|
(ALL_SELECTED_COPY == dwFlag))
|
||
|
{
|
||
|
if(NULL == pData)
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
|
||
|
//get the selected certificate
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
||
|
lvItem.mask=LVIF_PARAM;
|
||
|
|
||
|
|
||
|
iIndex=-1;
|
||
|
|
||
|
//loop through all the selected items
|
||
|
while(-1 != (iIndex=ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
iIndex,
|
||
|
LVNI_SELECTED
|
||
|
)))
|
||
|
{
|
||
|
lvItem.iItem=iIndex;
|
||
|
|
||
|
if(!ListView_GetItem(hWndControl,
|
||
|
&lvItem))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
|
||
|
|
||
|
if(!pCertContext)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
switch(dwFlag)
|
||
|
{
|
||
|
case ALL_SELECTED_CAN_DELETE:
|
||
|
dwData=sizeof(dwAccessFlag);
|
||
|
|
||
|
//as far as one of the selected items can not be deleted,
|
||
|
//the whole selection can not be deleted
|
||
|
if( CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_ACCESS_STATE_PROP_ID,
|
||
|
&dwAccessFlag,
|
||
|
&dwData))
|
||
|
{
|
||
|
if(0==(CERT_ACCESS_STATE_WRITE_PERSIST_FLAG & dwAccessFlag))
|
||
|
fCanDelete=FALSE;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case ALL_SELECTED_DELETE:
|
||
|
CertDeleteCertificateFromStore(
|
||
|
CertDuplicateCertificateContext(pCertContext));
|
||
|
break;
|
||
|
case ALL_SELECTED_COPY:
|
||
|
CertAddCertificateContextToStore(
|
||
|
*((HCERTSTORE *)pData),
|
||
|
pCertContext,
|
||
|
CERT_STORE_ADD_ALWAYS,
|
||
|
NULL);
|
||
|
break;
|
||
|
default:
|
||
|
goto CLEANUP;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//copy the can delete flag
|
||
|
if(ALL_SELECTED_CAN_DELETE == dwFlag)
|
||
|
*((BOOL *)pData)=fCanDelete;
|
||
|
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Check to see if <advanced> is selected
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL IsAdvancedSelected(HWND hwndDlg)
|
||
|
{
|
||
|
BOOL fSelected=FALSE;
|
||
|
int iIndex=0;
|
||
|
LPWSTR pwszOIDName=NULL;
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
|
||
|
if(!hwndDlg)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//get the selected string from the combo box
|
||
|
iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if(CB_ERR==iIndex)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//get the selected purpose name
|
||
|
if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
|
||
|
IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
iIndex, &pwszOIDName))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//check to see if <advanced> is selected
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED,
|
||
|
wszText, MAX_STRING_SIZE))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//check if advanced option is selected
|
||
|
if(0 == _wcsicmp(pwszOIDName, wszText))
|
||
|
fSelected=TRUE;
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pwszOIDName)
|
||
|
WizardFree(pwszOIDName);
|
||
|
|
||
|
return fSelected;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Update the window title based on the tab that user has selected
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL RefreshWindowTitle(HWND hwndDlg,
|
||
|
PCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
WCHAR wszTitle[MAX_TITLE_LENGTH];
|
||
|
WCHAR wszText[MAX_TITLE_LENGTH];
|
||
|
LPWSTR pwszTitle=NULL;
|
||
|
LPWSTR pwszText=NULL;
|
||
|
UINT ids=0;
|
||
|
DWORD dwTabIndex=0;
|
||
|
|
||
|
if(!hwndDlg || !pCertMgrStruct)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//get the string ids based on the tab selected
|
||
|
if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
|
||
|
dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
|
||
|
else if(-1 == (dwTabIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB))))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//open the correct store based on the tab selected
|
||
|
switch (dwTabIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
ids=IDS_TAB_PERSONAL;
|
||
|
break;
|
||
|
case 1:
|
||
|
ids=IDS_TAB_OTHER;
|
||
|
break;
|
||
|
case 2:
|
||
|
ids=IDS_TAB_CA;
|
||
|
break;
|
||
|
case 3:
|
||
|
ids=IDS_TAB_ROOT;
|
||
|
break;
|
||
|
case 4:
|
||
|
ids=IDS_TAB_PUBLISHER;
|
||
|
break;
|
||
|
default:
|
||
|
goto CLEANUP;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//load the string for tabs
|
||
|
if(!LoadStringU(g_hmodThisDll, ids, wszText, MAX_TITLE_LENGTH))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//get the window string
|
||
|
if(pCertMgrStruct->pwszTitle)
|
||
|
pwszTitle=(LPWSTR)(pCertMgrStruct->pwszTitle);
|
||
|
else
|
||
|
{
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_CERT_MGR_TITLE, wszTitle, MAX_TITLE_LENGTH))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
pwszTitle=wszTitle;
|
||
|
}
|
||
|
|
||
|
pwszText=(LPWSTR)WizardAlloc(sizeof(WCHAR) * (
|
||
|
wcslen(pwszTitle) + wcslen(wszText) + wcslen(L" - ") +1));
|
||
|
|
||
|
if(!pwszText)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//concatenate the window title as: "Certifiate Manager - Personal"
|
||
|
*pwszText=L'\0';
|
||
|
|
||
|
wcscat(pwszText, pwszTitle);
|
||
|
|
||
|
wcscat(pwszText, L" - ");
|
||
|
|
||
|
wcscat(pwszText, wszText);
|
||
|
|
||
|
//set the window text
|
||
|
SetWindowTextU(hwndDlg, pwszText);
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pwszText)
|
||
|
WizardFree(pwszText);
|
||
|
|
||
|
return fResult;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Check to see if the certificate's key usage is the same as
|
||
|
// the one selected on the combo box
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL IsValidUsage(PCCERT_CONTEXT pCertContext,
|
||
|
HWND hwndDlg,
|
||
|
CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
BOOL fValidUsage=FALSE;
|
||
|
int iIndex=0;
|
||
|
LPWSTR pwszOIDName=NULL;
|
||
|
LPSTR pszOID=NULL;
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
BOOL fAdvanced=FALSE;
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwAdvIndex=0;
|
||
|
int cNumOID=0;
|
||
|
LPSTR *rgOID=NULL;
|
||
|
DWORD cbOID=0;
|
||
|
|
||
|
//input check
|
||
|
if(!pCertContext || !hwndDlg || !pCertMgrInfo)
|
||
|
return FALSE;
|
||
|
|
||
|
//get the selected string from the combo box
|
||
|
iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if(CB_ERR==iIndex)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//get the selected purpose name
|
||
|
if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
|
||
|
IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
iIndex, &pwszOIDName))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//check to see if <all> is selected
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_OID_ALL,
|
||
|
wszText, MAX_STRING_SIZE))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(0 == _wcsicmp(pwszOIDName, wszText))
|
||
|
{
|
||
|
fValidUsage=TRUE;
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
|
||
|
//check to see if <advanced> is selected
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED,
|
||
|
wszText, MAX_STRING_SIZE))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//check if advanced option is selected
|
||
|
if(0 == _wcsicmp(pwszOIDName, wszText))
|
||
|
fAdvanced=TRUE;
|
||
|
|
||
|
|
||
|
if(FALSE==fAdvanced)
|
||
|
{
|
||
|
//determin the OID for the selected usage name
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
if(0==_wcsicmp(pwszOIDName,
|
||
|
(pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName))
|
||
|
pszOID=(pCertMgrInfo->rgOIDInfo[dwIndex]).pszOID;
|
||
|
}
|
||
|
|
||
|
//we are in trouble if we can not find the maching OID based on
|
||
|
//the name selected
|
||
|
if(NULL==pszOID)
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
|
||
|
//get the certificate's list of usage OIDs
|
||
|
//get the OIDs from the cert
|
||
|
if(!CertGetValidUsages(
|
||
|
1,
|
||
|
&pCertContext,
|
||
|
&cNumOID,
|
||
|
NULL,
|
||
|
&cbOID))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
rgOID=(LPSTR *)WizardAlloc(cbOID);
|
||
|
|
||
|
if(NULL==rgOID)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(!CertGetValidUsages(
|
||
|
1,
|
||
|
&pCertContext,
|
||
|
&cNumOID,
|
||
|
rgOID,
|
||
|
&cbOID))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//-1 means the certiifcate is good for everything
|
||
|
if(-1==cNumOID)
|
||
|
{
|
||
|
fValidUsage=TRUE;
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
|
||
|
//we need to decide if the certificate include the selected
|
||
|
//usage
|
||
|
if(FALSE==fAdvanced)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex<(DWORD)cNumOID; dwIndex++)
|
||
|
{
|
||
|
if(0==_stricmp(pszOID,
|
||
|
rgOID[dwIndex]))
|
||
|
{
|
||
|
fValidUsage=TRUE;
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//the certificates have to have advanced OIDs
|
||
|
for(dwAdvIndex=0; dwAdvIndex<pCertMgrInfo->dwOIDInfo; dwAdvIndex++)
|
||
|
{
|
||
|
//only interested in the OIDs with advanced marked
|
||
|
if(TRUE==(pCertMgrInfo->rgOIDInfo[dwAdvIndex]).fSelected)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex<(DWORD)cNumOID; dwIndex++)
|
||
|
{
|
||
|
if(0==_stricmp((pCertMgrInfo->rgOIDInfo[dwAdvIndex]).pszOID,
|
||
|
rgOID[dwIndex]))
|
||
|
{
|
||
|
fValidUsage=TRUE;
|
||
|
goto CLEANUP;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
//now, we have examed all the possibilities
|
||
|
fValidUsage=FALSE;
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pwszOIDName)
|
||
|
WizardFree(pwszOIDName);
|
||
|
|
||
|
if(rgOID)
|
||
|
WizardFree(rgOID);
|
||
|
|
||
|
return fValidUsage;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Check to see if the certificate is an end-entity cert
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL IsCertificateEndEntity(PCCERT_CONTEXT pCertContext)
|
||
|
{
|
||
|
PCERT_EXTENSION pCertExt=NULL;
|
||
|
BOOL fEndEntity=FALSE;
|
||
|
DWORD cbData=0;
|
||
|
PCERT_BASIC_CONSTRAINTS_INFO pBasicInfo=NULL;
|
||
|
PCERT_BASIC_CONSTRAINTS2_INFO pBasicInfo2=NULL;
|
||
|
|
||
|
if(!pCertContext)
|
||
|
return FALSE;
|
||
|
|
||
|
//get the extension szOID_BASIC_CONSTRAINTS2
|
||
|
pCertExt=CertFindExtension(
|
||
|
szOID_BASIC_CONSTRAINTS2,
|
||
|
pCertContext->pCertInfo->cExtension,
|
||
|
pCertContext->pCertInfo->rgExtension);
|
||
|
|
||
|
|
||
|
if(pCertExt)
|
||
|
{
|
||
|
//deocde the extension
|
||
|
cbData=0;
|
||
|
|
||
|
if(!CryptDecodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_BASIC_CONSTRAINTS2,
|
||
|
pCertExt->Value.pbData,
|
||
|
pCertExt->Value.cbData,
|
||
|
0,
|
||
|
NULL,
|
||
|
&cbData))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
pBasicInfo2=(PCERT_BASIC_CONSTRAINTS2_INFO)WizardAlloc(cbData);
|
||
|
|
||
|
if(NULL==pBasicInfo2)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(!CryptDecodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_BASIC_CONSTRAINTS2,
|
||
|
pCertExt->Value.pbData,
|
||
|
pCertExt->Value.cbData,
|
||
|
0,
|
||
|
pBasicInfo2,
|
||
|
&cbData))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(pBasicInfo2->fCA)
|
||
|
fEndEntity=FALSE;
|
||
|
else
|
||
|
fEndEntity=TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//get the extension szOID_BASIC_CONSTRAINTS
|
||
|
pCertExt=CertFindExtension(
|
||
|
szOID_BASIC_CONSTRAINTS,
|
||
|
pCertContext->pCertInfo->cExtension,
|
||
|
pCertContext->pCertInfo->rgExtension);
|
||
|
|
||
|
if(pCertExt)
|
||
|
{
|
||
|
//deocde the extension
|
||
|
cbData=0;
|
||
|
|
||
|
if(!CryptDecodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_BASIC_CONSTRAINTS,
|
||
|
pCertExt->Value.pbData,
|
||
|
pCertExt->Value.cbData,
|
||
|
0,
|
||
|
NULL,
|
||
|
&cbData))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
pBasicInfo=(PCERT_BASIC_CONSTRAINTS_INFO)WizardAlloc(cbData);
|
||
|
|
||
|
if(NULL==pBasicInfo)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(!CryptDecodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_BASIC_CONSTRAINTS,
|
||
|
pCertExt->Value.pbData,
|
||
|
pCertExt->Value.cbData,
|
||
|
0,
|
||
|
pBasicInfo,
|
||
|
&cbData))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(0 == pBasicInfo->SubjectType.cbData)
|
||
|
{
|
||
|
fEndEntity=FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if(CERT_END_ENTITY_SUBJECT_FLAG & (pBasicInfo->SubjectType.pbData[0]))
|
||
|
fEndEntity=TRUE;
|
||
|
else
|
||
|
{
|
||
|
if(CERT_CA_SUBJECT_FLAG & (pBasicInfo->SubjectType.pbData[0]))
|
||
|
fEndEntity=FALSE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pBasicInfo)
|
||
|
WizardFree(pBasicInfo);
|
||
|
|
||
|
if(pBasicInfo2)
|
||
|
WizardFree(pBasicInfo2);
|
||
|
|
||
|
return fEndEntity;
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Add certificate to the pCertMgrInfo
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL AddCertToCertMgrInfo(PCCERT_CONTEXT pCertContext,
|
||
|
CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
|
||
|
|
||
|
pCertMgrInfo->prgCertContext=(PCCERT_CONTEXT *)WizardRealloc(
|
||
|
pCertMgrInfo->prgCertContext,
|
||
|
sizeof(PCCERT_CONTEXT *)*(pCertMgrInfo->dwCertCount +1));
|
||
|
|
||
|
if(NULL==pCertMgrInfo->prgCertContext)
|
||
|
{
|
||
|
pCertMgrInfo->dwCertCount=0;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
pCertMgrInfo->prgCertContext[pCertMgrInfo->dwCertCount]=pCertContext;
|
||
|
|
||
|
pCertMgrInfo->dwCertCount++;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Once a certificate is selected, refresh the static windows that display
|
||
|
// the details of the certificate
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL RefreshCertDetails(HWND hwndDlg,
|
||
|
PCCERT_CONTEXT pCertContext)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
DWORD dwChar=0;
|
||
|
WCHAR wszNone[MAX_TITLE_LENGTH];
|
||
|
|
||
|
LPWSTR pwszName=NULL;
|
||
|
|
||
|
if(!hwndDlg || !pCertContext)
|
||
|
return FALSE;
|
||
|
|
||
|
//load the string for NONE
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
|
||
|
wszNone[0]=L'\0';
|
||
|
|
||
|
//Subject
|
||
|
/* dwChar=CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0);
|
||
|
|
||
|
if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
|
||
|
{
|
||
|
|
||
|
CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
0,
|
||
|
NULL,
|
||
|
pwszName,
|
||
|
dwChar);
|
||
|
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_SUBJECT, pwszName);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_SUBJECT, wszNone);
|
||
|
}
|
||
|
|
||
|
|
||
|
//WizardFree the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
}
|
||
|
|
||
|
//Issuer
|
||
|
dwChar=CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
CERT_NAME_ISSUER_FLAG,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0);
|
||
|
|
||
|
if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
|
||
|
{
|
||
|
|
||
|
CertGetNameStringW(
|
||
|
pCertContext,
|
||
|
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||
|
CERT_NAME_ISSUER_FLAG,
|
||
|
NULL,
|
||
|
pwszName,
|
||
|
dwChar);
|
||
|
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_ISSUER, pwszName);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_ISSUER, wszNone);
|
||
|
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//Expiration
|
||
|
if(WizardFormatDateString(&pwszName,pCertContext->pCertInfo->NotAfter, FALSE))
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_EXPIRE, pwszName);
|
||
|
else
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_EXPIRE, wszNone);
|
||
|
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
} */
|
||
|
|
||
|
//purpose
|
||
|
if(MyFormatEnhancedKeyUsageString(&pwszName,pCertContext, FALSE, FALSE))
|
||
|
|
||
|
{
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, pwszName);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
}
|
||
|
|
||
|
//friendly name
|
||
|
/* dwChar=0;
|
||
|
|
||
|
if(CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
NULL,
|
||
|
&dwChar) && (0!=dwChar))
|
||
|
{
|
||
|
pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
|
||
|
|
||
|
if(pwszName)
|
||
|
{
|
||
|
CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
pwszName,
|
||
|
&dwChar);
|
||
|
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, pwszName);
|
||
|
}
|
||
|
else
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, wszNone);
|
||
|
}
|
||
|
else
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, wszNone);
|
||
|
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
} */
|
||
|
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Add certificate to the ListView
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL AddCertToListView(HWND hwndControl,
|
||
|
PCCERT_CONTEXT pCertContext,
|
||
|
int iItem)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
LV_ITEMW lvItem;
|
||
|
DWORD dwChar=0;
|
||
|
WCHAR wszNone[MAX_TITLE_LENGTH];
|
||
|
|
||
|
LPWSTR pwszName=NULL;
|
||
|
|
||
|
if(!hwndControl || !pCertContext)
|
||
|
return FALSE;
|
||
|
|
||
|
// set up the fields in the list view item struct that don't change from item to item
|
||
|
lvItem.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE |LVIF_PARAM ;
|
||
|
lvItem.state = 0;
|
||
|
lvItem.stateMask = 0;
|
||
|
lvItem.iItem=iItem;
|
||
|
lvItem.iSubItem=0;
|
||
|
lvItem.iImage = 0;
|
||
|
lvItem.lParam = (LPARAM)pCertContext;
|
||
|
|
||
|
|
||
|
//load the string for NONE
|
||
|
if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
|
||
|
wszNone[0]=L'\0';
|
||
|
|
||
|
//Subject
|
||
|
if (NULL == (pwszName = GetDisplayNameString(pCertContext, 0)))
|
||
|
{
|
||
|
lvItem.pszText=wszNone;
|
||
|
ListView_InsertItemU(hwndControl, &lvItem);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lvItem.pszText=pwszName;
|
||
|
ListView_InsertItemU(hwndControl, &lvItem);
|
||
|
free(pwszName);
|
||
|
pwszName = NULL;
|
||
|
}
|
||
|
|
||
|
//Issuer
|
||
|
lvItem.iSubItem++;
|
||
|
|
||
|
if (NULL == (pwszName = GetDisplayNameString(pCertContext, CERT_NAME_ISSUER_FLAG)))
|
||
|
{
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszNone);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pwszName);
|
||
|
free(pwszName);
|
||
|
pwszName = NULL;
|
||
|
}
|
||
|
|
||
|
//Expiration
|
||
|
lvItem.iSubItem++;
|
||
|
|
||
|
if(WizardFormatDateString(&pwszName,pCertContext->pCertInfo->NotAfter, FALSE))
|
||
|
{
|
||
|
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
pwszName);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
wszNone);
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
}
|
||
|
|
||
|
//purpose
|
||
|
/*lvItem.iSubItem++;
|
||
|
|
||
|
if(WizardFormatEnhancedKeyUsageString(&pwszName,pCertContext, FALSE, FALSE) &&
|
||
|
L'\0' != *pwszName)
|
||
|
{
|
||
|
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
pwszName);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
wszNone);
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
} */
|
||
|
|
||
|
//friendly name
|
||
|
lvItem.iSubItem++;
|
||
|
|
||
|
dwChar=0;
|
||
|
|
||
|
if(CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
NULL,
|
||
|
&dwChar) && (0!=dwChar))
|
||
|
{
|
||
|
pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
|
||
|
|
||
|
if(pwszName)
|
||
|
{
|
||
|
CertGetCertificateContextProperty(
|
||
|
pCertContext,
|
||
|
CERT_FRIENDLY_NAME_PROP_ID,
|
||
|
pwszName,
|
||
|
&dwChar);
|
||
|
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
pwszName);
|
||
|
}
|
||
|
else
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
wszNone);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
|
||
|
wszNone);
|
||
|
}
|
||
|
|
||
|
//free the memory
|
||
|
if(pwszName)
|
||
|
{
|
||
|
WizardFree(pwszName);
|
||
|
pwszName=NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
// Based on the tab(store) and the intended purpose selected,
|
||
|
// find the correct certificates and refresh the list view
|
||
|
// Criteria:
|
||
|
// Tab 0: My Store with private key
|
||
|
// Tab 1: Ca Store's end-entity cert and the "ADDRESSBOOK" store
|
||
|
// Tab 2: Ca Store's CA certs
|
||
|
// Tab 3: Root store's self signed certs
|
||
|
// Tab 4: Trusted publisher certs
|
||
|
//-----------------------------------------------------------------------
|
||
|
void RefreshCertListView(HWND hwndDlg,
|
||
|
CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
HWND hwndControl=NULL;
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwTabIndex=0;
|
||
|
HCERTSTORE rghCertStore[]={NULL, NULL};
|
||
|
DWORD dwStoreCount=0;
|
||
|
PCCERT_CONTEXT pCurCertContext=NULL;
|
||
|
PCCERT_CONTEXT pPreCertContext=NULL;
|
||
|
BOOL fValidCert=FALSE;
|
||
|
DWORD cbData=0;
|
||
|
DWORD dwSortParam=0;
|
||
|
PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct = NULL;
|
||
|
|
||
|
|
||
|
HCURSOR hPreCursor=NULL;
|
||
|
HCURSOR hWinPreCursor=NULL;
|
||
|
|
||
|
|
||
|
if(!hwndDlg || !pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
pCertMgrStruct = pCertMgrInfo->pCertMgrStruct;
|
||
|
if(!pCertMgrStruct)
|
||
|
return;
|
||
|
|
||
|
//overwrite the cursor for this window class
|
||
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, NULL);
|
||
|
|
||
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||
|
|
||
|
|
||
|
//free all the original certificates
|
||
|
hwndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
|
||
|
|
||
|
if(!hwndControl)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
FreeCerts(pCertMgrInfo);
|
||
|
|
||
|
//deletel all the certs from the listView
|
||
|
ListView_DeleteAllItems(hwndControl);
|
||
|
|
||
|
//clear the ceritificate details group box
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
|
||
|
|
||
|
|
||
|
//get the tab that is selected
|
||
|
if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
|
||
|
dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
|
||
|
else if(-1 == (dwTabIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB))))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//open the correct store based on the tab selected
|
||
|
switch (dwTabIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
//open my store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
(LPWSTR)L"my"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
goto CLEANUP;
|
||
|
break;
|
||
|
case 1:
|
||
|
//open ca store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
(LPWSTR)L"ca"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
goto CLEANUP;
|
||
|
|
||
|
|
||
|
//open the "AddressBook" store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER |
|
||
|
CERT_STORE_OPEN_EXISTING_FLAG,
|
||
|
(LPWSTR)L"ADDRESSBOOK"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
{
|
||
|
//it is OK that user does not have "AddressBook" store
|
||
|
rghCertStore[dwStoreCount]=NULL;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case 2:
|
||
|
//open CA store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
(LPWSTR)L"ca"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
goto CLEANUP;
|
||
|
|
||
|
break;
|
||
|
case 3:
|
||
|
//open root store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
(LPWSTR)L"root"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
goto CLEANUP;
|
||
|
|
||
|
break;
|
||
|
case 4:
|
||
|
//open trusted publisher store
|
||
|
if(rghCertStore[dwStoreCount]=CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
(LPWSTR)L"TrustedPublisher"))
|
||
|
dwStoreCount++;
|
||
|
else
|
||
|
goto CLEANUP;
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
goto CLEANUP;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//gather new certificates from the store opened
|
||
|
for(dwIndex=0; dwIndex < dwStoreCount; dwIndex++)
|
||
|
{
|
||
|
pPreCertContext=NULL;
|
||
|
|
||
|
while(pCurCertContext=CertEnumCertificatesInStore(
|
||
|
rghCertStore[dwIndex],
|
||
|
pPreCertContext))
|
||
|
{
|
||
|
|
||
|
//make sure the certificate has the correct usage oid
|
||
|
if(IsValidUsage(pCurCertContext,
|
||
|
hwndDlg,
|
||
|
pCertMgrInfo))
|
||
|
{
|
||
|
switch (dwTabIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
//certificate has to have private key associated
|
||
|
//with it
|
||
|
cbData=0;
|
||
|
|
||
|
if(
|
||
|
(CertGetCertificateContextProperty(
|
||
|
pCurCertContext,
|
||
|
CERT_KEY_PROV_INFO_PROP_ID,
|
||
|
NULL,
|
||
|
&cbData) && (0!=cbData)) ||
|
||
|
(CertGetCertificateContextProperty(
|
||
|
pCurCertContext,
|
||
|
CERT_PVK_FILE_PROP_ID,
|
||
|
NULL,
|
||
|
&cbData) && (0!=cbData))
|
||
|
)
|
||
|
fValidCert=TRUE;
|
||
|
break;
|
||
|
case 1:
|
||
|
//the certificate has to be end entity cert for CA cert
|
||
|
if(0 == dwIndex)
|
||
|
{
|
||
|
if(IsCertificateEndEntity(pCurCertContext))
|
||
|
fValidCert=TRUE;
|
||
|
}
|
||
|
|
||
|
//we display everything in the addressbook store
|
||
|
if(1==dwIndex)
|
||
|
fValidCert=TRUE;
|
||
|
break;
|
||
|
case 2:
|
||
|
//for certificate in CA store, has to be CA cert
|
||
|
if(!IsCertificateEndEntity(pCurCertContext))
|
||
|
fValidCert=TRUE;
|
||
|
|
||
|
break;
|
||
|
case 4:
|
||
|
fValidCert=TRUE;
|
||
|
break;
|
||
|
case 3:
|
||
|
default:
|
||
|
//the certificate has to be self-signed
|
||
|
if(TrustIsCertificateSelfSigned(
|
||
|
pCurCertContext,
|
||
|
pCurCertContext->dwCertEncodingType, 0))
|
||
|
fValidCert=TRUE;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(fValidCert)
|
||
|
{
|
||
|
AddCertToCertMgrInfo(
|
||
|
CertDuplicateCertificateContext(pCurCertContext),
|
||
|
pCertMgrInfo);
|
||
|
}
|
||
|
|
||
|
fValidCert=FALSE;
|
||
|
}
|
||
|
|
||
|
pPreCertContext=pCurCertContext;
|
||
|
pCurCertContext=NULL;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//put the certificate in the listView
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwCertCount; dwIndex++)
|
||
|
AddCertToListView(hwndControl,
|
||
|
(pCertMgrInfo->prgCertContext)[dwIndex],
|
||
|
dwIndex);
|
||
|
|
||
|
// if there is no cert selected initially disable the
|
||
|
// "view cert button", "export" and "remove" button
|
||
|
if (ListView_GetSelectedCount(hwndControl) == 0)
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), FALSE);
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
|
||
|
}
|
||
|
|
||
|
//we sort by the 1st column
|
||
|
dwSortParam=pCertMgrInfo->rgdwSortParam[pCertMgrInfo->iColumn];
|
||
|
|
||
|
if(0!=dwSortParam)
|
||
|
{
|
||
|
//sort the 1st column
|
||
|
SendDlgItemMessage(hwndDlg,
|
||
|
IDC_CERTMGR_LIST,
|
||
|
LVM_SORTITEMS,
|
||
|
(WPARAM) (LPARAM) dwSortParam,
|
||
|
(LPARAM) (PFNLVCOMPARE)CompareCertificate);
|
||
|
}
|
||
|
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
//close all the certificate stores
|
||
|
for(dwIndex=0; dwIndex<dwStoreCount; dwIndex++)
|
||
|
CertCloseStore(rghCertStore[dwIndex], 0);
|
||
|
|
||
|
//set the cursor back
|
||
|
SetCursor(hPreCursor);
|
||
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
// Check if the input OID is considered to be the advanced OID
|
||
|
//-----------------------------------------------------------------------
|
||
|
BOOL IsAdvancedOID(CERT_ENHKEY_USAGE *pKeyUsage,
|
||
|
LPCSTR pszOID)
|
||
|
{
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
for(dwIndex=0; dwIndex<pKeyUsage->cUsageIdentifier; dwIndex++)
|
||
|
{
|
||
|
if(0 == _stricmp(pKeyUsage->rgpszUsageIdentifier[dwIndex], pszOID))
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
//The call back function for enum
|
||
|
//-----------------------------------------------------------------------
|
||
|
static BOOL WINAPI EnumOidCallback(
|
||
|
IN PCCRYPT_OID_INFO pInfo,
|
||
|
IN void *pvArg
|
||
|
)
|
||
|
{
|
||
|
|
||
|
PURPOSE_OID_CALL_BACK *pCallBackInfo=NULL;
|
||
|
BOOL fResult=FALSE;
|
||
|
|
||
|
pCallBackInfo=(PURPOSE_OID_CALL_BACK *)pvArg;
|
||
|
if(NULL==pvArg || NULL==pInfo)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//increment the oid list
|
||
|
(*(pCallBackInfo->pdwOIDCount))++;
|
||
|
|
||
|
//get more memory for the pointer list
|
||
|
*(pCallBackInfo->pprgOIDInfo)=(PURPOSE_OID_INFO *)WizardRealloc(*(pCallBackInfo->pprgOIDInfo),
|
||
|
(*(pCallBackInfo->pdwOIDCount)) * sizeof(PURPOSE_OID_INFO));
|
||
|
|
||
|
if(NULL==*(pCallBackInfo->pprgOIDInfo))
|
||
|
goto MemoryErr;
|
||
|
|
||
|
//memset
|
||
|
memset(&((*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1]), 0, sizeof(PURPOSE_OID_INFO));
|
||
|
|
||
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID=WizardAllocAndCopyStr((LPSTR)(pInfo->pszOID));
|
||
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName=WizardAllocAndCopyWStr((LPWSTR)(pInfo->pwszName));
|
||
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].fSelected=FALSE;
|
||
|
|
||
|
if(NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID ||
|
||
|
NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName)
|
||
|
goto MemoryErr;
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Get the list of supported enhanced key OIDs
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL InitPurposeOID(LPCSTR pszInitUsageOID,
|
||
|
DWORD *pdwOIDInfo,
|
||
|
PURPOSE_OID_INFO **pprgOIDInfo)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
DWORD dwIndex=0;
|
||
|
PURPOSE_OID_CALL_BACK OidInfoCallBack;
|
||
|
DWORD dwOIDRequested=0;
|
||
|
LPWSTR pwszName=NULL;
|
||
|
|
||
|
|
||
|
if(!pdwOIDInfo || !pprgOIDInfo)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
//init
|
||
|
*pdwOIDInfo=0;
|
||
|
*pprgOIDInfo=NULL;
|
||
|
|
||
|
OidInfoCallBack.pdwOIDCount=pdwOIDInfo;
|
||
|
OidInfoCallBack.pprgOIDInfo=pprgOIDInfo;
|
||
|
|
||
|
|
||
|
//enum all the enhanced key usages
|
||
|
if(!CryptEnumOIDInfo(
|
||
|
CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
|
||
|
0,
|
||
|
&OidInfoCallBack,
|
||
|
EnumOidCallback))
|
||
|
goto TraceErr;
|
||
|
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
//free the memory
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
FreeUsageOID(*pdwOIDInfo,*pprgOIDInfo);
|
||
|
|
||
|
*pdwOIDInfo=0;
|
||
|
*pprgOIDInfo=NULL;
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
TRACE_ERROR(TraceErr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
// Initialize the tab control
|
||
|
//-----------------------------------------------------------------------
|
||
|
void InitTabControl(HWND hWndControl,
|
||
|
PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct)
|
||
|
{
|
||
|
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwCount=0;
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
|
||
|
UINT rgIDS[]={IDS_TAB_PERSONAL,
|
||
|
IDS_TAB_OTHER,
|
||
|
IDS_TAB_CA,
|
||
|
IDS_TAB_ROOT,
|
||
|
IDS_TAB_PUBLISHER,
|
||
|
};
|
||
|
|
||
|
TCITEMW tcItem;
|
||
|
|
||
|
if(!hWndControl)
|
||
|
return;
|
||
|
|
||
|
memset(&tcItem, 0, sizeof(TCITEM));
|
||
|
|
||
|
tcItem.mask=TCIF_TEXT;
|
||
|
tcItem.pszText=wszText;
|
||
|
|
||
|
|
||
|
if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
|
||
|
{
|
||
|
dwIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
|
||
|
//get the column header
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
TabCtrl_InsertItemU(hWndControl,
|
||
|
0,
|
||
|
&tcItem);
|
||
|
} else
|
||
|
{
|
||
|
dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
|
||
|
|
||
|
//insert the tabs one at a time
|
||
|
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
|
||
|
{
|
||
|
//get the column header
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
TabCtrl_InsertItemU(hWndControl,
|
||
|
dwIndex,
|
||
|
&tcItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Free the array of usage OID info
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL FreeUsageOID(DWORD dwOIDInfo,
|
||
|
PURPOSE_OID_INFO *pOIDInfo)
|
||
|
{
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
if(pOIDInfo)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex < dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
if(pOIDInfo[dwIndex].pszOID)
|
||
|
WizardFree(pOIDInfo[dwIndex].pszOID);
|
||
|
|
||
|
if(pOIDInfo[dwIndex].pwszName)
|
||
|
WizardFree(pOIDInfo[dwIndex].pwszName);
|
||
|
}
|
||
|
|
||
|
WizardFree(pOIDInfo);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------
|
||
|
// Free the Certificates array
|
||
|
//-----------------------------------------------------------------------
|
||
|
void FreeCerts(CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
DWORD dwIndex=0;
|
||
|
|
||
|
if(!pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
if(pCertMgrInfo->prgCertContext)
|
||
|
{
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwCertCount; dwIndex++)
|
||
|
{
|
||
|
if(pCertMgrInfo->prgCertContext[dwIndex])
|
||
|
CertFreeCertificateContext(pCertMgrInfo->prgCertContext[dwIndex]);
|
||
|
}
|
||
|
|
||
|
WizardFree(pCertMgrInfo->prgCertContext);
|
||
|
}
|
||
|
|
||
|
pCertMgrInfo->dwCertCount=0;
|
||
|
|
||
|
pCertMgrInfo->prgCertContext=NULL;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Initialize the Purpose Combo
|
||
|
//--------------------------------------------------------------
|
||
|
void InitPurposeCombo(HWND hwndDlg,
|
||
|
CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwCount=0;
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
|
||
|
UINT rgIDS[]={IDS_OID_ADVANCED,
|
||
|
IDS_OID_ALL};
|
||
|
LPWSTR pwszInitOIDName=NULL;
|
||
|
CRYPTUI_CERT_MGR_STRUCT *pCertMgrStruct=NULL;
|
||
|
int iIndex=0;
|
||
|
|
||
|
if(!hwndDlg || !pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
pCertMgrStruct=(CRYPTUI_CERT_MGR_STRUCT *)(pCertMgrInfo->pCertMgrStruct);
|
||
|
|
||
|
//delete all the entries in the comobox
|
||
|
SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_RESETCONTENT, 0, 0);
|
||
|
|
||
|
//copy all the basic OIDs to the comobox
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
|
||
|
if(FALSE == (pCertMgrInfo->rgOIDInfo[dwIndex].fSelected))
|
||
|
{
|
||
|
SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_ADDSTRING,
|
||
|
0, (LPARAM)(pCertMgrInfo->rgOIDInfo[dwIndex].pwszName));
|
||
|
|
||
|
|
||
|
//looking for the initial OID
|
||
|
if(pCertMgrStruct->pszInitUsageOID)
|
||
|
{
|
||
|
if(0 == _stricmp(pCertMgrStruct->pszInitUsageOID,
|
||
|
pCertMgrInfo->rgOIDInfo[dwIndex].pszOID))
|
||
|
pwszInitOIDName=pCertMgrInfo->rgOIDInfo[dwIndex].pwszName;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//copy <advanced> and <all> to the list
|
||
|
dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
|
||
|
|
||
|
//insert the column one at a time
|
||
|
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
|
||
|
{
|
||
|
//get the column header
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_INSERTSTRING,
|
||
|
-1, (LPARAM)wszText);
|
||
|
}
|
||
|
|
||
|
|
||
|
//initialize the combo box
|
||
|
//use <advanced> is what user specify is not either
|
||
|
//client auth or secure e-mail
|
||
|
if(pCertMgrStruct->pszInitUsageOID)
|
||
|
{
|
||
|
if(NULL==pwszInitOIDName)
|
||
|
{
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED, wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
pwszInitOIDName=wszText;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//use <all> when NULL==pCertMgrStruct->pszInitUsageOID
|
||
|
if(NULL==pwszInitOIDName)
|
||
|
{
|
||
|
//use <all> as the initial case
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, IDS_OID_ALL, wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
pwszInitOIDName=wszText;
|
||
|
}
|
||
|
|
||
|
iIndex=(int)SendDlgItemMessageU(
|
||
|
hwndDlg,
|
||
|
IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_FINDSTRINGEXACT,
|
||
|
-1,
|
||
|
(LPARAM)pwszInitOIDName);
|
||
|
|
||
|
if(CB_ERR == iIndex)
|
||
|
return;
|
||
|
|
||
|
//set the selection
|
||
|
SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// Initialize the Purpose Combo
|
||
|
//--------------------------------------------------------------
|
||
|
void RepopulatePurposeCombo(HWND hwndDlg,
|
||
|
CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
LPWSTR pwszSelectedOIDName=NULL;
|
||
|
int iIndex=0;
|
||
|
|
||
|
if(!hwndDlg || !pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
//get the selected string from the combo box
|
||
|
iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if(CB_ERR==iIndex)
|
||
|
return;
|
||
|
|
||
|
//get the selected purpose
|
||
|
if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
|
||
|
IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
iIndex, &pwszSelectedOIDName))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
InitPurposeCombo(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
iIndex=(int)SendDlgItemMessageU(
|
||
|
hwndDlg,
|
||
|
IDC_CERTMGR_PURPOSE_COMBO,
|
||
|
CB_FINDSTRINGEXACT,
|
||
|
-1,
|
||
|
(LPARAM)pwszSelectedOIDName);
|
||
|
|
||
|
if(CB_ERR == iIndex)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//set the selection
|
||
|
SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
|
||
|
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pwszSelectedOIDName)
|
||
|
WizardFree(pwszSelectedOIDName);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
//--------------------------------------------------------------
|
||
|
// The winProc for the advanced option diagloue for certMgr UI
|
||
|
//--------------------------------------------------------------
|
||
|
INT_PTR APIENTRY CertMgrAdvancedProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
CERT_MGR_INFO *pCertMgrInfo=NULL;
|
||
|
PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
|
||
|
|
||
|
UINT rgIDS[]={IDS_CERTMGR_DER,
|
||
|
IDS_CERTMGR_BASE64,
|
||
|
IDS_CERTMGR_PKCS7};
|
||
|
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
DWORD dwCount=0;
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwSelectedIndex=0;
|
||
|
LV_ITEMW lvItem;
|
||
|
LV_COLUMNW lvC;
|
||
|
HWND hwndControl=NULL;
|
||
|
int iIndex=0;
|
||
|
int listIndex=0;
|
||
|
NM_LISTVIEW FAR * pnmv=NULL;
|
||
|
HWND hwnd=NULL;
|
||
|
|
||
|
switch ( msg )
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) lParam;
|
||
|
|
||
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
//init the export format control
|
||
|
dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
|
||
|
|
||
|
for(dwIndex=0; dwIndex < dwCount; dwIndex++)
|
||
|
{
|
||
|
LoadStringU(g_hmodThisDll,
|
||
|
rgIDS[dwIndex],
|
||
|
wszText,
|
||
|
MAX_STRING_SIZE);
|
||
|
|
||
|
SendDlgItemMessageU(hwndDlg,
|
||
|
IDC_CERTMGR_EXPORT_COMBO,
|
||
|
CB_INSERTSTRING,
|
||
|
-1,
|
||
|
(LPARAM)wszText);
|
||
|
}
|
||
|
|
||
|
//select the export format based on the selection
|
||
|
switch (pCertMgrInfo->dwExportFormat)
|
||
|
{
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
|
||
|
dwSelectedIndex=0;
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
|
||
|
dwSelectedIndex=1;
|
||
|
break;
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
|
||
|
dwSelectedIndex=2;
|
||
|
break;
|
||
|
default:
|
||
|
dwSelectedIndex=0;
|
||
|
}
|
||
|
|
||
|
SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_EXPORT_COMBO,
|
||
|
CB_SETCURSEL, (WPARAM)dwSelectedIndex,0);
|
||
|
|
||
|
//init the chain check-box
|
||
|
if(pCertMgrInfo->fExportChain)
|
||
|
SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 1, 0);
|
||
|
else
|
||
|
SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 0, 0);
|
||
|
|
||
|
if(dwSelectedIndex != 2)
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
|
||
|
else
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
|
||
|
|
||
|
//init the advanced OID list
|
||
|
hwndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST);
|
||
|
|
||
|
//mark the list is selected by a check box
|
||
|
ListView_SetExtendedListViewStyle(hwndControl, LVS_EX_CHECKBOXES);
|
||
|
|
||
|
//insert a column into the list view
|
||
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
||
|
|
||
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
||
|
lvC.cx =10; // (dwMaxSize+2)*7; // Width of the column, in pixels.
|
||
|
lvC.pszText = L""; // The text for the column.
|
||
|
lvC.iSubItem=0;
|
||
|
|
||
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
||
|
break;
|
||
|
|
||
|
//populate the list
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
||
|
lvItem.mask=LVIF_TEXT | LVIF_STATE;
|
||
|
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
lvItem.iItem=dwIndex;
|
||
|
|
||
|
lvItem.pszText=(pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName;
|
||
|
lvItem.cchTextMax=sizeof(WCHAR)*(1+wcslen((pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName));
|
||
|
lvItem.stateMask = LVIS_STATEIMAGEMASK;
|
||
|
lvItem.state = (pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000;
|
||
|
|
||
|
// insert and set state
|
||
|
ListView_SetItemState(hwndControl,
|
||
|
ListView_InsertItemU(hwndControl, &lvItem),
|
||
|
(pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000,
|
||
|
LVIS_STATEIMAGEMASK);
|
||
|
}
|
||
|
|
||
|
//autosize the column
|
||
|
ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
|
||
|
|
||
|
#if (1) // DSIE: bug 282268.
|
||
|
ListView_SetItemState(hwndControl,
|
||
|
0,
|
||
|
LVIS_FOCUSED | LVIS_SELECTED,
|
||
|
LVIS_FOCUSED | LVIS_SELECTED);
|
||
|
#endif
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||
|
|
||
|
if(NULL == pCertMgrInfo)
|
||
|
break;
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
switch (((NMHDR FAR *) lParam)->code)
|
||
|
{
|
||
|
case LVN_ITEMCHANGED:
|
||
|
//if the state of the advanced OID check box
|
||
|
//has been changed, mark the flag
|
||
|
pnmv = (NM_LISTVIEW FAR *) lParam;
|
||
|
|
||
|
if(NULL==pnmv)
|
||
|
break;
|
||
|
|
||
|
//see if the new item is de-selected
|
||
|
if(pnmv->uChanged & LVIF_STATE)
|
||
|
pCertMgrInfo->fAdvOIDChanged=TRUE;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
break;
|
||
|
|
||
|
case WM_HELP:
|
||
|
case WM_CONTEXTMENU:
|
||
|
if (msg == WM_HELP)
|
||
|
{
|
||
|
hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hwnd = (HWND) wParam;
|
||
|
}
|
||
|
|
||
|
if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_COMBO)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDOK)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDCANCEL)))
|
||
|
{
|
||
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrAdvHelpMap);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||
|
|
||
|
if(NULL == pCertMgrInfo)
|
||
|
break;
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
//a control is clicked
|
||
|
if(HIWORD(wParam) == BN_CLICKED)
|
||
|
{
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDCANCEL:
|
||
|
pCertMgrInfo->fAdvOIDChanged=FALSE;
|
||
|
|
||
|
EndDialog(hwndDlg, DIALOGUE_CANCEL);
|
||
|
break;
|
||
|
|
||
|
case IDOK:
|
||
|
//the OK button is selected
|
||
|
//get the default export format
|
||
|
iIndex=(int)SendDlgItemMessage(hwndDlg,
|
||
|
IDC_CERTMGR_EXPORT_COMBO,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if(CB_ERR==iIndex)
|
||
|
break;
|
||
|
|
||
|
switch(iIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
pCertMgrInfo->dwExportFormat=0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(TRUE==SendDlgItemMessage(
|
||
|
hwndDlg,
|
||
|
IDC_CERTMGR_EXPORT_CHECK,
|
||
|
BM_GETCHECK,
|
||
|
0,0))
|
||
|
pCertMgrInfo->fExportChain=TRUE;
|
||
|
else
|
||
|
pCertMgrInfo->fExportChain=FALSE;
|
||
|
|
||
|
//get the list of advanded OIDs
|
||
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the count of selected OIDs and mark them
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
//mark the selected OIDS. Keep track of
|
||
|
//if the OID selections have been changed
|
||
|
if(ListView_GetCheckState(hwndControl, dwIndex))
|
||
|
{
|
||
|
((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//save the advanced options to the registry
|
||
|
SaveAdvValueToReg(pCertMgrInfo);
|
||
|
|
||
|
EndDialog(hwndDlg, DIALOGUE_OK);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//a combo box's selection has been changed
|
||
|
if(HIWORD(wParam) == CBN_SELCHANGE)
|
||
|
{
|
||
|
switch(LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_CERTMGR_EXPORT_COMBO:
|
||
|
//the export format combo box has been changed
|
||
|
//get the selected item index
|
||
|
iIndex=(int)SendDlgItemMessage(hwndDlg,
|
||
|
IDC_CERTMGR_EXPORT_COMBO,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if(CB_ERR==iIndex)
|
||
|
break;
|
||
|
|
||
|
//enable the check box for the chain if
|
||
|
//PKCS#7 option is selected
|
||
|
if(2 == iIndex)
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
|
||
|
else
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
// The winProc for CertMgrDialogProc
|
||
|
//--------------------------------------------------------------
|
||
|
INT_PTR APIENTRY CertMgrDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
CERT_MGR_INFO *pCertMgrInfo=NULL;
|
||
|
PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
|
||
|
|
||
|
HWND hWndListView=NULL;
|
||
|
HWND hWndControl=NULL;
|
||
|
DWORD dwIndex=0;
|
||
|
DWORD dwCount=0;
|
||
|
WCHAR wszText[MAX_STRING_SIZE];
|
||
|
BOOL fCanDelete=FALSE;
|
||
|
|
||
|
UINT rgIDS[]={IDS_COLUMN_SUBJECT,
|
||
|
IDS_COLUMN_ISSUER,
|
||
|
IDS_COLUMN_EXPIRE,
|
||
|
IDS_COLUMN_NAME};
|
||
|
|
||
|
|
||
|
NM_LISTVIEW FAR * pnmv=NULL;
|
||
|
LPNMLVKEYDOWN pnkd=NULL;
|
||
|
LV_COLUMNW lvC;
|
||
|
int listIndex=0;
|
||
|
LV_ITEM lvItem;
|
||
|
BOOL fPropertyChanged=FALSE;
|
||
|
|
||
|
|
||
|
HIMAGELIST hIml=NULL;
|
||
|
CRYPTUI_VIEWCERTIFICATE_STRUCT CertViewStruct;
|
||
|
CRYPTUI_WIZ_EXPORT_INFO CryptUIWizExportInfo;
|
||
|
UINT idsDeleteConfirm=0;
|
||
|
int iIndex=0;
|
||
|
DWORD dwSortParam=0;
|
||
|
HCERTSTORE hCertStore=NULL;
|
||
|
HWND hwnd=NULL;
|
||
|
|
||
|
DWORD cbData=0;
|
||
|
|
||
|
switch ( msg )
|
||
|
{
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) lParam;
|
||
|
|
||
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// set the dialog title
|
||
|
//
|
||
|
if (pCertMgrStruct->pwszTitle)
|
||
|
{
|
||
|
SetWindowTextU(hwndDlg, pCertMgrStruct->pwszTitle);
|
||
|
}
|
||
|
|
||
|
//create the image list
|
||
|
|
||
|
hIml = ImageList_LoadImage(g_hmodThisDll, MAKEINTRESOURCE(IDB_CERT), 0, 1, RGB(255,0,255), IMAGE_BITMAP, 0);
|
||
|
|
||
|
//
|
||
|
// add the colums to the list view
|
||
|
//
|
||
|
hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
|
||
|
|
||
|
if(NULL==hWndListView)
|
||
|
break;
|
||
|
|
||
|
//set the image list
|
||
|
if (hIml != NULL)
|
||
|
{
|
||
|
ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
|
||
|
}
|
||
|
|
||
|
dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
|
||
|
|
||
|
//set up the common info for the column
|
||
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
||
|
|
||
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
||
|
lvC.cx = 80; // Width of the column, in pixels.
|
||
|
lvC.iSubItem=0;
|
||
|
lvC.pszText = wszText; // The text for the column.
|
||
|
|
||
|
//inser the column one at a time
|
||
|
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
|
||
|
{
|
||
|
//get the column header
|
||
|
wszText[0]=L'\0';
|
||
|
|
||
|
//set the column width. 1st and 2nd to 100,
|
||
|
//and the expiration to 75, the rest to 80
|
||
|
if( dwIndex < 2)
|
||
|
lvC.cx=130;
|
||
|
else
|
||
|
{
|
||
|
if( 2 == dwIndex)
|
||
|
lvC.cx=70;
|
||
|
else
|
||
|
lvC.cx=105;
|
||
|
}
|
||
|
|
||
|
|
||
|
LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
|
||
|
|
||
|
ListView_InsertColumnU(hWndListView, dwIndex, &lvC);
|
||
|
}
|
||
|
|
||
|
// set the style in the list view so that it highlights an entire line
|
||
|
SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
||
|
|
||
|
|
||
|
//Init tabs to the tab control.
|
||
|
hWndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_TAB);
|
||
|
if(NULL==hWndControl)
|
||
|
break;
|
||
|
|
||
|
//add the tabs to the tabl control
|
||
|
InitTabControl(hWndControl, pCertMgrStruct);
|
||
|
|
||
|
// If CRYPTUI_CERT_MGR_PUBLISHER_TAB was set, then,
|
||
|
// select the 5th tab: Trusted Publishers, otherwise,
|
||
|
// select the 1st tab: Personal Certificate
|
||
|
TabCtrl_SetCurSel(
|
||
|
hWndControl,
|
||
|
(CRYPTUI_CERT_MGR_PUBLISHER_TAB ==
|
||
|
(pCertMgrStruct->dwFlags &
|
||
|
(CRYPTUI_CERT_MGR_TAB_MASK |
|
||
|
CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG) )) ? 4 : 0
|
||
|
);
|
||
|
|
||
|
//Init the purpose combo box
|
||
|
InitPurposeCombo(hwndDlg,pCertMgrInfo);
|
||
|
|
||
|
//Init the certificates in the list view based on the tab selected
|
||
|
//and the purpose selected
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
//Set the correct window title based on the tab selection
|
||
|
// RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
|
||
|
|
||
|
//register the listView window as the drop desitination
|
||
|
if(S_OK == CCertMgrDropTarget_CreateInstance(
|
||
|
hwndDlg,
|
||
|
pCertMgrInfo,
|
||
|
&(pCertMgrInfo->pIDropTarget)))
|
||
|
{
|
||
|
__try {
|
||
|
RegisterDragDrop(hWndListView, pCertMgrInfo->pIDropTarget);
|
||
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case WM_NOTIFY:
|
||
|
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||
|
|
||
|
if(NULL == pCertMgrInfo)
|
||
|
break;
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
|
||
|
switch (((NMHDR FAR *) lParam)->code)
|
||
|
{
|
||
|
|
||
|
//the delete key has been pressed
|
||
|
case LVN_KEYDOWN:
|
||
|
pnkd = (LPNMLVKEYDOWN) lParam;
|
||
|
|
||
|
if(VK_DELETE == pnkd->wVKey)
|
||
|
{
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
GetAllSelectedItem(hWndControl,
|
||
|
ALL_SELECTED_CAN_DELETE,
|
||
|
&fCanDelete);
|
||
|
|
||
|
if(!fCanDelete)
|
||
|
{
|
||
|
I_MessageBox(
|
||
|
hwndDlg,
|
||
|
IDS_CANNOT_DELETE_CERTS,
|
||
|
IDS_CERT_MGR_TITLE,
|
||
|
pCertMgrStruct->pwszTitle,
|
||
|
MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//same action as user has click on the DELETE button
|
||
|
SendDlgItemMessage(hwndDlg,
|
||
|
IDC_CERTMGR_REMOVE,
|
||
|
BM_CLICK,
|
||
|
0,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
//drag drop operation has begun
|
||
|
case LVN_BEGINDRAG:
|
||
|
case LVN_BEGINRDRAG:
|
||
|
|
||
|
pnmv = (LPNMLISTVIEW) lParam;
|
||
|
|
||
|
if(!pnmv)
|
||
|
break;
|
||
|
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_SELECTED
|
||
|
);
|
||
|
|
||
|
if(listIndex != -1)
|
||
|
//start the drag and drop
|
||
|
CertMgrUIStartDragDrop(pnmv, hWndControl,
|
||
|
pCertMgrInfo->dwExportFormat,
|
||
|
pCertMgrInfo->fExportChain);
|
||
|
|
||
|
break;
|
||
|
//the item has been selected
|
||
|
case LVN_ITEMCHANGED:
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
pnmv = (LPNMLISTVIEW) lParam;
|
||
|
|
||
|
if(NULL==pnmv)
|
||
|
break;
|
||
|
|
||
|
if (pnmv->uNewState & LVIS_SELECTED)
|
||
|
{
|
||
|
|
||
|
//enable the export buttons
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), TRUE);
|
||
|
|
||
|
//if more than one certificates are selected, diable the view button
|
||
|
if(ListView_GetSelectedCount(hWndControl) > 1)
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
|
||
|
else
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), TRUE);
|
||
|
|
||
|
//enable the delete window only if the certificate is deletable
|
||
|
GetAllSelectedItem(hWndControl,
|
||
|
ALL_SELECTED_CAN_DELETE,
|
||
|
&fCanDelete);
|
||
|
|
||
|
if(fCanDelete)
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), TRUE);
|
||
|
else
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
|
||
|
|
||
|
|
||
|
//display the details of the certificate if
|
||
|
//only 1 cert is selected
|
||
|
if(1 == ListView_GetSelectedCount(hWndControl))
|
||
|
{
|
||
|
RefreshCertDetails(hwndDlg, (PCCERT_CONTEXT)(pnmv->lParam));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//clear the ceritificate details group box
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//if the state is deselection
|
||
|
if(0 == ListView_GetSelectedCount(hWndControl))
|
||
|
{
|
||
|
//we diable the buttons if no certificate is selected
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), FALSE);
|
||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
|
||
|
|
||
|
//clear the ceritificate details group box
|
||
|
SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
//the column has been changed
|
||
|
case LVN_COLUMNCLICK:
|
||
|
|
||
|
pnmv = (NM_LISTVIEW FAR *) lParam;
|
||
|
|
||
|
//get the column number
|
||
|
dwSortParam=0;
|
||
|
|
||
|
switch(pnmv->iSubItem)
|
||
|
{
|
||
|
case 0:
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 3:
|
||
|
case 4:
|
||
|
dwSortParam=pCertMgrInfo->rgdwSortParam[pnmv->iSubItem];
|
||
|
break;
|
||
|
default:
|
||
|
dwSortParam=0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(0!=dwSortParam)
|
||
|
{
|
||
|
//remember to flip the ascend ording
|
||
|
|
||
|
if(dwSortParam & SORT_COLUMN_ASCEND)
|
||
|
{
|
||
|
dwSortParam &= 0x0000FFFF;
|
||
|
dwSortParam |= SORT_COLUMN_DESCEND;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(dwSortParam & SORT_COLUMN_DESCEND)
|
||
|
{
|
||
|
dwSortParam &= 0x0000FFFF;
|
||
|
dwSortParam |= SORT_COLUMN_ASCEND;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//sort the column
|
||
|
SendDlgItemMessage(hwndDlg,
|
||
|
IDC_CERTMGR_LIST,
|
||
|
LVM_SORTITEMS,
|
||
|
(WPARAM) (LPARAM) dwSortParam,
|
||
|
(LPARAM) (PFNLVCOMPARE)CompareCertificate);
|
||
|
|
||
|
pCertMgrInfo->rgdwSortParam[pnmv->iSubItem]=dwSortParam;
|
||
|
|
||
|
//remember the column number
|
||
|
pCertMgrInfo->iColumn=pnmv->iSubItem;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
//the tab has been changed
|
||
|
case TCN_SELCHANGE:
|
||
|
//we need to refresh the column sorting state
|
||
|
pCertMgrInfo->rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
|
||
|
pCertMgrInfo->rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
|
||
|
pCertMgrInfo->rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
|
||
|
pCertMgrInfo->rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
|
||
|
pCertMgrInfo->rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
|
||
|
|
||
|
pCertMgrInfo->iColumn=0;
|
||
|
|
||
|
//if the tab is changed, we need to
|
||
|
//refresh the list view and certificate's
|
||
|
//detailed view
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
//we also we to update the window title
|
||
|
//based on the tabl selection
|
||
|
//RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
|
||
|
break;
|
||
|
|
||
|
//double-click on the list view of the certificates
|
||
|
case NM_DBLCLK:
|
||
|
{
|
||
|
switch (((NMHDR FAR *) lParam)->idFrom)
|
||
|
{
|
||
|
case IDC_CERTMGR_LIST:
|
||
|
{
|
||
|
//get the window handle of the cert list view
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the selected cert
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_SELECTED
|
||
|
);
|
||
|
|
||
|
if (listIndex != -1)
|
||
|
{
|
||
|
//get the selected certificate
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
||
|
lvItem.mask=LVIF_PARAM;
|
||
|
lvItem.iItem=listIndex;
|
||
|
|
||
|
if(ListView_GetItem(hWndControl, &lvItem))
|
||
|
{
|
||
|
//view certiificate
|
||
|
if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
|
||
|
{
|
||
|
memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
|
||
|
CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
|
||
|
CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
|
||
|
CertViewStruct.hwndParent=hwndDlg;
|
||
|
|
||
|
fPropertyChanged=FALSE;
|
||
|
|
||
|
CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
|
||
|
|
||
|
if(fPropertyChanged)
|
||
|
{
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
//we reselect the one
|
||
|
ListView_SetItemState(
|
||
|
hWndControl,
|
||
|
listIndex,
|
||
|
LVIS_SELECTED,
|
||
|
LVIS_SELECTED);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
#if (1) //DSIE: bug 264568.
|
||
|
case NM_SETFOCUS:
|
||
|
{
|
||
|
//get the window handle of the cert list view
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the selected cert
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_FOCUSED
|
||
|
);
|
||
|
|
||
|
//select first item to show hilite.
|
||
|
if (listIndex == -1)
|
||
|
ListView_SetItemState(hWndControl,
|
||
|
0,
|
||
|
LVIS_FOCUSED | LVIS_SELECTED,
|
||
|
LVIS_FOCUSED | LVIS_SELECTED);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
|
||
|
__try {
|
||
|
//revoke drag drop
|
||
|
RevokeDragDrop(GetDlgItem(hwndDlg, IDC_CERTMGR_LIST));
|
||
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
}
|
||
|
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||
|
|
||
|
if(pCertMgrInfo)
|
||
|
{
|
||
|
if(pCertMgrInfo->pIDropTarget)
|
||
|
pCertMgrInfo->pIDropTarget->Release();
|
||
|
}
|
||
|
|
||
|
// destroy the image list in the list view //
|
||
|
hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
|
||
|
|
||
|
if(NULL==hWndListView)
|
||
|
break;
|
||
|
|
||
|
//no need to destroy the image list. Handled by ListView
|
||
|
//ImageList_Destroy(ListView_GetImageList(hWndListView, LVSIL_SMALL));
|
||
|
|
||
|
break;
|
||
|
case WM_HELP:
|
||
|
case WM_CONTEXTMENU:
|
||
|
if (msg == WM_HELP)
|
||
|
{
|
||
|
hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hwnd = (HWND) wParam;
|
||
|
}
|
||
|
|
||
|
|
||
|
if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_IMPORT)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADVANCE)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDOK)) &&
|
||
|
(hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE)))
|
||
|
{
|
||
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrMainHelpMap);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
|
||
|
pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||
|
|
||
|
if(NULL == pCertMgrInfo)
|
||
|
break;
|
||
|
|
||
|
pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
|
||
|
|
||
|
if(NULL == pCertMgrStruct)
|
||
|
break;
|
||
|
|
||
|
//a control is clicked
|
||
|
if(HIWORD(wParam) == BN_CLICKED)
|
||
|
{
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_CERTMGR_ADVANCE:
|
||
|
|
||
|
//lauch the advanced dialogue
|
||
|
if(DIALOGUE_OK == DialogBoxParamU(
|
||
|
g_hmodThisDll,
|
||
|
(LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_ADVANCED)),
|
||
|
hwndDlg,
|
||
|
CertMgrAdvancedProc,
|
||
|
(LPARAM) pCertMgrInfo))
|
||
|
{
|
||
|
//if the advanced OIDs' list has been changed,
|
||
|
//we need to refresh the list window
|
||
|
if(TRUE == pCertMgrInfo->fAdvOIDChanged)
|
||
|
{
|
||
|
//mark the flag
|
||
|
pCertMgrInfo->fAdvOIDChanged=FALSE;
|
||
|
|
||
|
//repopulate the combo box based on
|
||
|
//the new selection
|
||
|
RepopulatePurposeCombo(hwndDlg,
|
||
|
pCertMgrInfo);
|
||
|
|
||
|
//refresh the list window only if
|
||
|
//<advanced> is selected
|
||
|
if(IsAdvancedSelected(hwndDlg))
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IDC_CERTMGR_REMOVE:
|
||
|
//get the selected certificate
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the selected cert
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_SELECTED
|
||
|
);
|
||
|
|
||
|
if (listIndex != -1)
|
||
|
{
|
||
|
//get the selected tab
|
||
|
if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
|
||
|
iIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
|
||
|
else
|
||
|
iIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
|
||
|
|
||
|
if(-1==iIndex)
|
||
|
break;
|
||
|
|
||
|
//delete confirmation
|
||
|
switch(iIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
|
||
|
break;
|
||
|
case 1:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_OTHER_REMOVE;
|
||
|
break;
|
||
|
case 2:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_CA_REMOVE;
|
||
|
break;
|
||
|
case 3:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_ROOT_REMOVE;
|
||
|
break;
|
||
|
case 4:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_PUBLISHER_REMOVE;
|
||
|
break;
|
||
|
default:
|
||
|
idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
iIndex=I_MessageBox(hwndDlg,
|
||
|
idsDeleteConfirm,
|
||
|
IDS_CERT_MGR_TITLE,
|
||
|
pCertMgrStruct->pwszTitle,
|
||
|
MB_ICONEXCLAMATION|MB_YESNO|MB_APPLMODAL);
|
||
|
|
||
|
if(IDYES == iIndex)
|
||
|
{
|
||
|
//delete all the selected certificates
|
||
|
GetAllSelectedItem(hWndControl,
|
||
|
ALL_SELECTED_DELETE,
|
||
|
NULL);
|
||
|
|
||
|
//refresh the list view since some certificates
|
||
|
//might be deleted
|
||
|
|
||
|
//send the tab control
|
||
|
|
||
|
SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) 0, (LPARAM) NULL);
|
||
|
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//output the message
|
||
|
I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
|
||
|
IDS_CERT_MGR_TITLE,
|
||
|
pCertMgrStruct->pwszTitle,
|
||
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
case IDC_CERTMGR_IMPORT:
|
||
|
{
|
||
|
DWORD dwTabIndex;
|
||
|
HCERTSTORE hTabStore = NULL;
|
||
|
|
||
|
// Import into the store associated with the
|
||
|
// currently selected tab
|
||
|
if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
|
||
|
dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
|
||
|
else
|
||
|
dwTabIndex = TabCtrl_GetCurSel(
|
||
|
GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
|
||
|
|
||
|
if (TAB_STORE_NAME_CNT > dwTabIndex) {
|
||
|
hTabStore = CertOpenStore(
|
||
|
CERT_STORE_PROV_SYSTEM_W,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
CERT_STORE_MAXIMUM_ALLOWED_FLAG |
|
||
|
CERT_STORE_SET_LOCALIZED_NAME_FLAG |
|
||
|
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||
|
rgpwszTabStoreName[dwTabIndex]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
//call the certificate import wizard
|
||
|
CryptUIWizImport(
|
||
|
0,
|
||
|
hwndDlg,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
hTabStore);
|
||
|
|
||
|
if (hTabStore)
|
||
|
CertCloseStore(hTabStore, 0);
|
||
|
|
||
|
//refresh the list view since new certificates
|
||
|
//might be added
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IDC_CERTMGR_EXPORT:
|
||
|
|
||
|
//get the selected certificate
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the selected cert
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_SELECTED
|
||
|
);
|
||
|
|
||
|
if (listIndex != -1)
|
||
|
{
|
||
|
|
||
|
//we call the export wizard differently based
|
||
|
//on single or multiple selection
|
||
|
if(ListView_GetSelectedCount(hWndControl) > 1)
|
||
|
{
|
||
|
//open a memory store
|
||
|
hCertStore=CertOpenStore(
|
||
|
CERT_STORE_PROV_MEMORY,
|
||
|
g_dwMsgAndCertEncodingType,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
|
||
|
if(hCertStore)
|
||
|
{
|
||
|
GetAllSelectedItem(hWndControl,
|
||
|
ALL_SELECTED_COPY,
|
||
|
&hCertStore);
|
||
|
|
||
|
//call the export wizard
|
||
|
memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
|
||
|
CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
|
||
|
CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY;
|
||
|
CryptUIWizExportInfo.hCertStore=hCertStore;
|
||
|
|
||
|
CryptUIWizExport(0,
|
||
|
hwndDlg,
|
||
|
NULL,
|
||
|
&CryptUIWizExportInfo,
|
||
|
NULL);
|
||
|
|
||
|
CertCloseStore(hCertStore, 0);
|
||
|
hCertStore=NULL;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
||
|
lvItem.mask=LVIF_PARAM;
|
||
|
lvItem.iItem=listIndex;
|
||
|
|
||
|
if(ListView_GetItem(hWndControl,
|
||
|
&lvItem))
|
||
|
{
|
||
|
if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
|
||
|
{
|
||
|
//call the export wizard
|
||
|
memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
|
||
|
CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
|
||
|
CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
|
||
|
CryptUIWizExportInfo.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
|
||
|
|
||
|
CryptUIWizExport(0,
|
||
|
hwndDlg,
|
||
|
NULL,
|
||
|
&CryptUIWizExportInfo,
|
||
|
NULL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
//output the message
|
||
|
I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
|
||
|
IDS_CERT_MGR_TITLE,
|
||
|
pCertMgrStruct->pwszTitle,
|
||
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IDC_CERTMGR_VIEW:
|
||
|
|
||
|
//get the selected certificate
|
||
|
if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
|
||
|
break;
|
||
|
|
||
|
//get the selected cert
|
||
|
listIndex = ListView_GetNextItem(
|
||
|
hWndControl,
|
||
|
-1,
|
||
|
LVNI_SELECTED
|
||
|
);
|
||
|
|
||
|
if (listIndex != -1)
|
||
|
{
|
||
|
//view certiificate
|
||
|
if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
|
||
|
{
|
||
|
|
||
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
||
|
lvItem.mask=LVIF_PARAM;
|
||
|
lvItem.iItem=listIndex;
|
||
|
|
||
|
if(ListView_GetItem(hWndControl,
|
||
|
&lvItem))
|
||
|
{
|
||
|
memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
|
||
|
CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
|
||
|
CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
|
||
|
CertViewStruct.hwndParent=hwndDlg;
|
||
|
|
||
|
|
||
|
fPropertyChanged=FALSE;
|
||
|
|
||
|
CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
|
||
|
|
||
|
if(fPropertyChanged)
|
||
|
{
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
//we reselect the one
|
||
|
ListView_SetItemState(
|
||
|
hWndControl,
|
||
|
listIndex,
|
||
|
LVIS_SELECTED,
|
||
|
LVIS_SELECTED);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
//output the message
|
||
|
I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
|
||
|
IDS_CERT_MGR_TITLE,
|
||
|
pCertMgrStruct->pwszTitle,
|
||
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case IDOK:
|
||
|
case IDCANCEL:
|
||
|
|
||
|
EndDialog(hwndDlg, NULL);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//a combo box's selection has been changed
|
||
|
if(HIWORD(wParam) == CBN_SELCHANGE)
|
||
|
{
|
||
|
switch(LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_CERTMGR_PURPOSE_COMBO:
|
||
|
//if the purpose is changed, we need to
|
||
|
//refresh the list view and certificate's
|
||
|
//detailed view
|
||
|
RefreshCertListView(hwndDlg, pCertMgrInfo);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Save the advanced option from the registry
|
||
|
//--------------------------------------------------------------
|
||
|
void SaveAdvValueToReg(CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
HKEY hKeyExport=NULL;
|
||
|
HKEY hKeyPurpose=NULL;
|
||
|
DWORD dwDisposition=0;
|
||
|
DWORD dwExportFormat=0;
|
||
|
DWORD dwIndex=0;
|
||
|
LPSTR pszDefaultOID=NULL;
|
||
|
LPSTR pszOID=NULL;
|
||
|
|
||
|
|
||
|
if(NULL==pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
//open a registry entry for the export format under HKEY_CURRENT_USER
|
||
|
if (ERROR_SUCCESS == RegCreateKeyExU(
|
||
|
HKEY_CURRENT_USER,
|
||
|
WSZCertMgrExportRegLocation,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKeyExport,
|
||
|
&dwDisposition))
|
||
|
{
|
||
|
//set the value
|
||
|
switch(pCertMgrInfo->dwExportFormat)
|
||
|
{
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
|
||
|
if(pCertMgrInfo->fExportChain)
|
||
|
dwExportFormat=4;
|
||
|
else
|
||
|
dwExportFormat=1;
|
||
|
break;
|
||
|
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
|
||
|
if(pCertMgrInfo->fExportChain)
|
||
|
dwExportFormat=5;
|
||
|
else
|
||
|
dwExportFormat=2;
|
||
|
break;
|
||
|
|
||
|
case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
|
||
|
if(pCertMgrInfo->fExportChain)
|
||
|
dwExportFormat=6;
|
||
|
else
|
||
|
dwExportFormat=3;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
if(0 != dwExportFormat)
|
||
|
{
|
||
|
//set the value
|
||
|
RegSetValueExU(
|
||
|
hKeyExport,
|
||
|
WSZCertMgrExportName,
|
||
|
0, // dwReserved
|
||
|
REG_DWORD,
|
||
|
(BYTE *) &dwExportFormat,
|
||
|
sizeof(dwExportFormat));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//open the registry entry for the advanced OIDs
|
||
|
dwDisposition=0;
|
||
|
|
||
|
if (ERROR_SUCCESS == RegCreateKeyExU(
|
||
|
HKEY_CURRENT_USER,
|
||
|
WSZCertMgrPurposeRegLocation,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKeyPurpose,
|
||
|
&dwDisposition))
|
||
|
{
|
||
|
//build a char "," seperated string for simple OID
|
||
|
pszDefaultOID=(LPSTR)WizardAlloc(sizeof(CHAR));
|
||
|
if(NULL == pszDefaultOID)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
*pszDefaultOID=L'\0';
|
||
|
|
||
|
for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
|
||
|
{
|
||
|
if(FALSE==(pCertMgrInfo->rgOIDInfo)[dwIndex].fSelected)
|
||
|
{
|
||
|
if(strlen(pszDefaultOID)!=0)
|
||
|
strcat(pszDefaultOID, ",");
|
||
|
|
||
|
pszOID=(pCertMgrInfo->rgOIDInfo)[dwIndex].pszOID;
|
||
|
|
||
|
pszDefaultOID=(LPSTR)WizardRealloc(pszDefaultOID,
|
||
|
sizeof(CHAR)*(strlen(pszDefaultOID)+strlen(pszOID)+strlen(",")+1));
|
||
|
|
||
|
if(NULL==pszDefaultOID)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
strcat(pszDefaultOID,pszOID);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//set the value
|
||
|
RegSetValueEx(
|
||
|
hKeyPurpose,
|
||
|
SZCertMgrPurposeName,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(BYTE *)(pszDefaultOID),
|
||
|
(strlen(pszDefaultOID) + 1) * sizeof(CHAR));
|
||
|
|
||
|
}
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
if(pszDefaultOID)
|
||
|
WizardFree(pszDefaultOID);
|
||
|
|
||
|
//close the registry keys
|
||
|
if(hKeyExport)
|
||
|
RegCloseKey(hKeyExport);
|
||
|
|
||
|
if(hKeyPurpose)
|
||
|
RegCloseKey(hKeyPurpose);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Get init value from the registry
|
||
|
//--------------------------------------------------------------
|
||
|
void GetInitValueFromReg(CERT_MGR_INFO *pCertMgrInfo)
|
||
|
{
|
||
|
HKEY hKeyExport=NULL;
|
||
|
HKEY hKeyPurpose=NULL;
|
||
|
DWORD dwType=0;
|
||
|
DWORD dwExportFormat=0;
|
||
|
DWORD cbExportFormat=0;
|
||
|
|
||
|
LPSTR pszDefaultOID=NULL;
|
||
|
DWORD cbDefaultOID=0;
|
||
|
|
||
|
LPSTR pszTok=NULL;
|
||
|
DWORD cTok = 0;
|
||
|
DWORD cCount=0;
|
||
|
CERT_ENHKEY_USAGE KeyUsage;
|
||
|
LPSTR rgBasicOID[]={szOID_PKIX_KP_CLIENT_AUTH,
|
||
|
szOID_PKIX_KP_EMAIL_PROTECTION};
|
||
|
BOOL fNoRegData=FALSE;
|
||
|
|
||
|
if(NULL==pCertMgrInfo)
|
||
|
return;
|
||
|
|
||
|
//memset
|
||
|
memset(&KeyUsage,0,sizeof(CERT_ENHKEY_USAGE));
|
||
|
|
||
|
//open the registry key if user has saved the advaced options
|
||
|
if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
|
||
|
WSZCertMgrExportRegLocation,
|
||
|
0,
|
||
|
KEY_READ,
|
||
|
&hKeyExport))
|
||
|
{
|
||
|
//get the data
|
||
|
cbExportFormat=sizeof(dwExportFormat);
|
||
|
|
||
|
if(ERROR_SUCCESS == RegQueryValueExU(
|
||
|
hKeyExport,
|
||
|
WSZCertMgrExportName,
|
||
|
NULL,
|
||
|
&dwType,
|
||
|
(BYTE *)&dwExportFormat,
|
||
|
&cbExportFormat))
|
||
|
{
|
||
|
// added check for reg_binary because on WIN95 OSR2 when the machine is changed
|
||
|
// from mutli-user profiles to single user profile, the registry DWORD values
|
||
|
// change to BINARY
|
||
|
//
|
||
|
if ((dwType == REG_DWORD) ||
|
||
|
(dwType == REG_BINARY))
|
||
|
{
|
||
|
switch(dwExportFormat)
|
||
|
{
|
||
|
case 1:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
|
||
|
pCertMgrInfo->fExportChain=FALSE;
|
||
|
break;
|
||
|
case 2:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
|
||
|
pCertMgrInfo->fExportChain=FALSE;
|
||
|
break;
|
||
|
case 3:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
|
||
|
pCertMgrInfo->fExportChain=FALSE;
|
||
|
break;
|
||
|
case 4:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
|
||
|
pCertMgrInfo->fExportChain=TRUE;
|
||
|
break;
|
||
|
case 5:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
|
||
|
pCertMgrInfo->fExportChain=TRUE;
|
||
|
break;
|
||
|
case 6:
|
||
|
pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
|
||
|
pCertMgrInfo->fExportChain=TRUE;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//get the advanced purposed
|
||
|
if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
|
||
|
WSZCertMgrPurposeRegLocation,
|
||
|
0,
|
||
|
KEY_READ,
|
||
|
&hKeyPurpose))
|
||
|
{
|
||
|
dwType=0;
|
||
|
cbDefaultOID=0;
|
||
|
|
||
|
if((ERROR_SUCCESS == RegQueryValueEx(
|
||
|
hKeyPurpose,
|
||
|
SZCertMgrPurposeName,
|
||
|
NULL,
|
||
|
&dwType,
|
||
|
NULL,
|
||
|
&cbDefaultOID))&&(cbDefaultOID!=0))
|
||
|
{
|
||
|
pszDefaultOID=(LPSTR)WizardAlloc(cbDefaultOID);
|
||
|
|
||
|
if(NULL==pszDefaultOID)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
if(ERROR_SUCCESS != RegQueryValueEx(
|
||
|
hKeyPurpose,
|
||
|
SZCertMgrPurposeName,
|
||
|
NULL,
|
||
|
&dwType,
|
||
|
(BYTE *)pszDefaultOID,
|
||
|
&cbDefaultOID))
|
||
|
goto CLEANUP;
|
||
|
|
||
|
//
|
||
|
// Count the number of OIDs as well as converting from comma delimited
|
||
|
// to NULL character delimited
|
||
|
//
|
||
|
if(0==strlen(pszDefaultOID))
|
||
|
fNoRegData=TRUE;
|
||
|
else
|
||
|
{
|
||
|
|
||
|
pszTok = strtok(pszDefaultOID, ",");
|
||
|
while ( pszTok != NULL )
|
||
|
{
|
||
|
cTok++;
|
||
|
pszTok = strtok(NULL, ",");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate a cert enhanced key usage structure and fill it in with
|
||
|
// the string tokens
|
||
|
//
|
||
|
|
||
|
pszTok = pszDefaultOID;
|
||
|
KeyUsage.cUsageIdentifier = cTok;
|
||
|
KeyUsage.rgpszUsageIdentifier = (LPSTR *)WizardAlloc(cTok * sizeof(LPSTR));
|
||
|
|
||
|
if(NULL==KeyUsage.rgpszUsageIdentifier)
|
||
|
goto CLEANUP;
|
||
|
|
||
|
for ( cCount = 0; cCount < cTok; cCount++ )
|
||
|
{
|
||
|
KeyUsage.rgpszUsageIdentifier[cCount] = pszTok;
|
||
|
pszTok = pszTok+strlen(pszTok)+1;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//set up the default OIDs if the registry is empty
|
||
|
if(0 == KeyUsage.cUsageIdentifier && TRUE != fNoRegData)
|
||
|
{
|
||
|
KeyUsage.cUsageIdentifier=2;
|
||
|
KeyUsage.rgpszUsageIdentifier=rgBasicOID;
|
||
|
}
|
||
|
|
||
|
|
||
|
//mark the OIDs as advanced for basic
|
||
|
for(cCount=0; cCount<pCertMgrInfo->dwOIDInfo; cCount++)
|
||
|
{
|
||
|
if(IsAdvancedOID(&KeyUsage,
|
||
|
(pCertMgrInfo->rgOIDInfo)[cCount].pszOID))
|
||
|
(pCertMgrInfo->rgOIDInfo)[cCount].fSelected=TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
CLEANUP:
|
||
|
|
||
|
//free memory
|
||
|
if(pszDefaultOID)
|
||
|
{
|
||
|
WizardFree(pszDefaultOID);
|
||
|
|
||
|
if(KeyUsage.rgpszUsageIdentifier)
|
||
|
WizardFree(KeyUsage.rgpszUsageIdentifier);
|
||
|
}
|
||
|
|
||
|
//close the registry keys
|
||
|
if(hKeyExport)
|
||
|
RegCloseKey(hKeyExport);
|
||
|
|
||
|
if(hKeyPurpose)
|
||
|
RegCloseKey(hKeyPurpose);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
//--------------------------------------------------------------
|
||
|
//
|
||
|
// Parameters:
|
||
|
// pCryptUICertMgr IN Required
|
||
|
//
|
||
|
//
|
||
|
//--------------------------------------------------------------
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
CryptUIDlgCertMgr(
|
||
|
IN PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr)
|
||
|
{
|
||
|
BOOL fResult=FALSE;
|
||
|
CERT_MGR_INFO CertMgrInfo;
|
||
|
HRESULT hr=S_OK;
|
||
|
DWORD dwException=0;
|
||
|
|
||
|
//check the input parameter
|
||
|
if(NULL==pCryptUICertMgr)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
if(sizeof(CRYPTUI_CERT_MGR_STRUCT) != pCryptUICertMgr->dwSize)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
if ((pCryptUICertMgr->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK) >
|
||
|
CRYPTUI_CERT_MGR_PUBLISHER_TAB)
|
||
|
goto InvalidArgErr;
|
||
|
|
||
|
if (!WizardInit())
|
||
|
{
|
||
|
goto InitOIDErr;
|
||
|
}
|
||
|
|
||
|
//init struct
|
||
|
memset(&CertMgrInfo, 0, sizeof(CertMgrInfo));
|
||
|
|
||
|
CertMgrInfo.pCertMgrStruct=pCryptUICertMgr;
|
||
|
|
||
|
//get all the enhanced key usage OIDs
|
||
|
if(!InitPurposeOID(pCryptUICertMgr->pszInitUsageOID,
|
||
|
&(CertMgrInfo.dwOIDInfo),
|
||
|
&(CertMgrInfo.rgOIDInfo)))
|
||
|
goto InitOIDErr;
|
||
|
|
||
|
//init the column sort
|
||
|
CertMgrInfo.rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
|
||
|
CertMgrInfo.rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
|
||
|
CertMgrInfo.rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
|
||
|
CertMgrInfo.rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
|
||
|
CertMgrInfo.rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
|
||
|
|
||
|
//we sort the 1st column
|
||
|
CertMgrInfo.iColumn=0;
|
||
|
|
||
|
|
||
|
//init the export format
|
||
|
CertMgrInfo.dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
|
||
|
CertMgrInfo.fExportChain=FALSE;
|
||
|
CertMgrInfo.fAdvOIDChanged=FALSE;
|
||
|
|
||
|
//init the OLE library
|
||
|
|
||
|
__try {
|
||
|
if(!SUCCEEDED(hr=OleInitialize(NULL)))
|
||
|
goto OLEInitErr;
|
||
|
|
||
|
//get the initialization from the registry
|
||
|
GetInitValueFromReg(&CertMgrInfo);
|
||
|
|
||
|
//call the dialog box
|
||
|
if (DialogBoxParamU(
|
||
|
g_hmodThisDll,
|
||
|
(LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_MAIN)),
|
||
|
(pCryptUICertMgr->hwndParent != NULL) ? pCryptUICertMgr->hwndParent : GetDesktopWindow(),
|
||
|
CertMgrDialogProc,
|
||
|
(LPARAM) &CertMgrInfo) == -1)
|
||
|
{
|
||
|
OleUninitialize();
|
||
|
goto DialogBoxErr;
|
||
|
}
|
||
|
|
||
|
|
||
|
OleUninitialize();
|
||
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
dwException = GetExceptionCode();
|
||
|
goto ExceptionErr;
|
||
|
}
|
||
|
|
||
|
fResult=TRUE;
|
||
|
|
||
|
CommonReturn:
|
||
|
|
||
|
//free the cert arrays
|
||
|
FreeCerts(&CertMgrInfo);
|
||
|
|
||
|
//free the usage OID array
|
||
|
FreeUsageOID(CertMgrInfo.dwOIDInfo,
|
||
|
CertMgrInfo.rgOIDInfo);
|
||
|
|
||
|
|
||
|
return fResult;
|
||
|
|
||
|
ErrorReturn:
|
||
|
|
||
|
fResult=FALSE;
|
||
|
goto CommonReturn;
|
||
|
|
||
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
||
|
TRACE_ERROR(DialogBoxErr);
|
||
|
TRACE_ERROR(InitOIDErr);
|
||
|
SET_ERROR_VAR(OLEInitErr, hr);
|
||
|
SET_ERROR_VAR(ExceptionErr, dwException)
|
||
|
|
||
|
}
|
||
|
|