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

3726 lines
125 KiB

//-------------------------------------------------------------
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: import.cpp
//
// Contents: The cpp file to implement the import wizard
//
// History: 5-11-1997 xiaohs created
//
//--------------------------------------------------------------
#include "wzrdpvk.h"
#include "import.h"
#include "xenroll.h"
extern HMODULE g_hmodxEnroll;
typedef IEnroll2 * (WINAPI *PFNPIEnroll2GetNoCOM)();
//-------------------------------------------------------------------------
// DecodeGenericBlob
//-------------------------------------------------------------------------
DWORD DecodeGenericBlob (IN PCERT_EXTENSION pCertExtension,
IN LPCSTR lpszStructType,
IN OUT void ** ppStructInfo)
{
DWORD dwResult = 0;
DWORD cbStructInfo = 0;
// check parameters.
if (!pCertExtension || !lpszStructType || !ppStructInfo)
{
return E_POINTER;
}
//
// Determine decoded length.
//
if(!CryptDecodeObject(X509_ASN_ENCODING,
lpszStructType,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
NULL,
&cbStructInfo))
{
return GetLastError();
}
//
// Allocate memory.
//
if (!(*ppStructInfo = malloc(cbStructInfo)))
{
return E_OUTOFMEMORY;
}
//
// Decode data.
//
if(!CryptDecodeObject(X509_ASN_ENCODING,
lpszStructType,
pCertExtension->Value.pbData,
pCertExtension->Value.cbData,
0,
*ppStructInfo,
&cbStructInfo))
{
free(*ppStructInfo);
return GetLastError();
}
return S_OK;
}
//-------------------------------------------------------------------------
// IsCACert
//-------------------------------------------------------------------------
BOOL IsCACert(IN PCCERT_CONTEXT pCertContext)
{
BOOL bResult = FALSE;
PCERT_BASIC_CONSTRAINTS2_INFO pInfo = NULL;
PCERT_EXTENSION pBasicConstraints = NULL;
if (pCertContext)
{
//
// Find the basic constraints extension.
//
if (pBasicConstraints = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension))
{
//
// Decode the basic constraints extension.
//
if (S_OK == DecodeGenericBlob(pBasicConstraints,
X509_BASIC_CONSTRAINTS2,
(void **) &pInfo))
{
bResult = pInfo->fCA;
free(pInfo);
}
}
else
{
//
// Extension not found. So, for maximum backward compatibility, we assume CA
// for V1 cert, and end user for > V1 cert.
//
bResult = CERT_V1 == pCertContext->pCertInfo->dwVersion;
}
}
return bResult;
}
//-------------------------------------------------------------------------
// Based on the expected content type, get the file filter
//-------------------------------------------------------------------------
BOOL FileExist(LPWSTR pwszFileName)
{
HANDLE hFile=NULL;
if(NULL == pwszFileName)
return FALSE;
if ((hFile = ExpandAndCreateFileU(pwszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL, // lpsa
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
return FALSE;
CloseHandle(hFile);
return TRUE;
}
//-------------------------------------------------------------------------
// Based on the expected content type, get the file filter
//-------------------------------------------------------------------------
UINT GetFileFilerIDS(DWORD dwFlags)
{
BOOL fCert=FALSE;
BOOL fCRL=FALSE;
BOOL fCTL=FALSE;
if(CRYPTUI_WIZ_IMPORT_ALLOW_CERT & dwFlags)
fCert=TRUE;
if(CRYPTUI_WIZ_IMPORT_ALLOW_CRL & dwFlags)
fCRL=TRUE;
if(CRYPTUI_WIZ_IMPORT_ALLOW_CTL & dwFlags)
fCTL=TRUE;
if(fCert && fCRL & fCTL)
return IDS_IMPORT_FILE_FILTER;
if(fCert && fCRL)
return IDS_IMPORT_CER_CRL_FILTER;
if(fCert && fCTL)
return IDS_IMPORT_CER_CTL_FILTER;
if(fCRL && fCTL)
return IDS_IMPORT_CTL_CRL_FILTER;
if(fCert)
return IDS_IMPORT_CER_FILTER;
if(fCRL)
return IDS_IMPORT_CRL_FILTER;
if(fCTL)
return IDS_IMPORT_CTL_FILTER;
return IDS_IMPORT_FILE_FILTER;
}
//-------------------------------------------------------------------------
// Check for the content of the store
//-------------------------------------------------------------------------
BOOL CheckForContent(HCERTSTORE hSrcStore, DWORD dwFlags, BOOL fFromWizard, UINT *pIDS)
{
BOOL fResult=FALSE;
UINT ids=IDS_INVALID_WIZARD_INPUT;
DWORD dwExpectedContent=0;
DWORD dwActualContent=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
DWORD dwCRLFlag=0;
if(!pIDS)
return FALSE;
if(!hSrcStore)
{
ids=IDS_INVALID_WIZARD_INPUT;
goto CLEANUP;
}
//get the expected content
if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)
dwExpectedContent |= IMPORT_CONTENT_CERT;
if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)
dwExpectedContent |= IMPORT_CONTENT_CRL;
if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL)
dwExpectedContent |= IMPORT_CONTENT_CTL;
//get the actual content
if(pCertContext=CertEnumCertificatesInStore(hSrcStore, NULL))
dwActualContent |= IMPORT_CONTENT_CERT;
if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL))
dwActualContent |= IMPORT_CONTENT_CTL;
if(pCRLContext=CertGetCRLFromStore(hSrcStore,
NULL,
NULL,
&dwCRLFlag))
dwActualContent |= IMPORT_CONTENT_CRL;
//the actual content should be a subset of expected content
if(dwActualContent !=(dwExpectedContent & dwActualContent))
{
ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
goto CLEANUP;
}
//make sure the actual content is not empty
if(0 == dwActualContent)
{
if(fFromWizard)
ids=IDS_IMPORT_OBJECT_EMPTY;
else
ids=IDS_IMPORT_PFX_EMPTY;
goto CLEANUP;
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(pIDS)
*pIDS=ids;
return fResult;
}
//-------------------------------------------------------------------------
//Get the store name(s) based on the store handle
//-------------------------------------------------------------------------
BOOL GetStoreName(HCERTSTORE hCertStore,
LPWSTR *ppwszStoreName)
{
DWORD dwSize=0;
//init
*ppwszStoreName=NULL;
if(NULL==hCertStore)
return FALSE;
if(!CertGetStoreProperty(
hCertStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
NULL,
&dwSize) || (0==dwSize))
return FALSE;
*ppwszStoreName=(LPWSTR)WizardAlloc(dwSize);
if(NULL==*ppwszStoreName)
return FALSE;
**ppwszStoreName=L'\0';
if(CertGetStoreProperty(
hCertStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
*ppwszStoreName,
&dwSize))
return TRUE;
WizardFree(*ppwszStoreName);
*ppwszStoreName=NULL;
return FALSE;
}
//-------------------------------------------------------------------------
//Get the store name(s) for the store selected by the wizard
//-------------------------------------------------------------------------
/*BOOL GetDefaultStoreName(CERT_IMPORT_INFO *pCertImportInfo,
HCERTSTORE hSrcStore,
LPWSTR *ppwszStoreName,
UINT *pidsStatus)
{
HCERTSTORE hMyStore=NULL;
HCERTSTORE hCAStore=NULL;
HCERTSTORE hTrustStore=NULL;
HCERTSTORE hRootStore=NULL;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
DWORD dwCRLFlag=0;
BOOL fResult=FALSE;
LPWSTR pwszStoreName=NULL;
HCERTSTORE hCertStore=NULL;
DWORD dwData=0;
DWORD dwCertOpenStoreFlags;
//init
*ppwszStoreName=NULL;
if(NULL==hSrcStore)
return FALSE;
if (pCertImportInfo->fPFX &&
(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
{
dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
}
else
{
dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER;
}
*ppwszStoreName=(LPWSTR)WizardAlloc(sizeof(WCHAR));
**ppwszStoreName=L'\0';
//we need to find a correct store on user's behalf
//put the CTLs in the trust store
if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL))
{
//open trust store if necessary
if(NULL==hTrustStore)
{
if(!(hTrustStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
L"trust")))
{
*pidsStatus=IDS_FAIL_OPEN_TRUST;
goto CLEANUP;
}
//get the store name
if(GetStoreName(hTrustStore, &pwszStoreName))
{
*ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3));
if(NULL==*ppwszStoreName)
{
*pidsStatus=IDS_OUT_OF_MEMORY;
goto CLEANUP;
}
wcscat(*ppwszStoreName, pwszStoreName);
}
}
}
//free memory
if(pwszStoreName)
{
WizardFree(pwszStoreName);
pwszStoreName=NULL;
}
//put CRL in the CA store
if(pCRLContext=CertGetCRLFromStore(hSrcStore,
NULL,
NULL,
&dwCRLFlag))
{
//open ca store if necessary
if(NULL==hCAStore)
{
if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG,
L"ca")))
{
*pidsStatus=IDS_FAIL_OPEN_CA;
goto CLEANUP;
}
//get the store name
if(GetStoreName(hCAStore, &pwszStoreName))
{
*ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3));
if(NULL==*ppwszStoreName)
{
*pidsStatus=IDS_OUT_OF_MEMORY;
goto CLEANUP;
}
if(wcslen(*ppwszStoreName) !=0 )
wcscat(*ppwszStoreName, L", ");
wcscat(*ppwszStoreName, pwszStoreName);
}
}
}
//free memory
if(pwszStoreName)
{
WizardFree(pwszStoreName);
pwszStoreName=NULL;
}
//add the certificate with private key to my store; and the rest
//to the ca store
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
//break if we have opened both MY and CA store and hRootStore
if(hCAStore && hMyStore && hRootStore)
break;
if(TrustIsCertificateSelfSigned(pCertContext,
pCertContext->dwCertEncodingType,
0))
{
//open the root store if necessary
if(NULL==hRootStore)
{
if(!(hRootStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG,
L"root")) )
{
*pidsStatus=IDS_FAIL_OPEN_ROOT;
goto CLEANUP;
}
hCertStore=hRootStore;
}
else
{
pCertPre=pCertContext;
continue;
}
}
else
{
//check if the certificate has the property on it
//make sure the private key matches the certificate
//search for both machine key and user keys
if(CertGetCertificateContextProperty(
pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL,
&dwData) &&
CryptFindCertificateKeyProvInfo(
pCertContext,
0,
NULL))
{
//open my store if necessary
if(NULL==hMyStore)
{
if(!(hMyStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
L"my")))
{
*pidsStatus=IDS_FAIL_OPEN_MY;
goto CLEANUP;
}
hCertStore=hMyStore;
}
else
{
pCertPre=pCertContext;
continue;
}
}
else
{
//open ca store if necessary
if(NULL==hCAStore)
{
if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
L"ca")) )
{
*pidsStatus=IDS_FAIL_OPEN_CA;
goto CLEANUP;
}
hCertStore=hCAStore;
}
else
{
pCertPre=pCertContext;
continue;
}
}
}
//get the store name
if(GetStoreName(hCertStore, &pwszStoreName))
{
*ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +1));
if(NULL==*ppwszStoreName)
{
*pidsStatus=IDS_OUT_OF_MEMORY;
goto CLEANUP;
}
if(wcslen(*ppwszStoreName) !=0 )
wcscat(*ppwszStoreName, L", ");
wcscat(*ppwszStoreName, pwszStoreName);
}
pCertPre=pCertContext;
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(hMyStore)
CertCloseStore(hMyStore, 0);
if(hCAStore)
CertCloseStore(hCAStore, 0);
if(hTrustStore)
CertCloseStore(hTrustStore, 0);
if(hRootStore)
CertCloseStore(hRootStore, 0);
//free memory
if(pwszStoreName)
{
WizardFree(pwszStoreName);
pwszStoreName=NULL;
}
return fResult;
}
*/
//-------------------------------------------------------------------------
//Get the store name and insert it to the ListView
//-------------------------------------------------------------------------
void SetImportStoreName(HWND hwndControl,
HCERTSTORE hCertStore)
{
LPWSTR pwszStoreName=NULL;
DWORD dwSize=0;
// LV_ITEMW lvItem;
// LV_COLUMNW lvC;
if(!CertGetStoreProperty(
hCertStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
NULL,
&dwSize) || (0==dwSize))
{
//Get the <Unknown> string
pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH * sizeof(WCHAR));
if(pwszStoreName)
{
*pwszStoreName=L'\0';
LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
}
}
else
{
pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
if(pwszStoreName)
{
*pwszStoreName=L'\0';
CertGetStoreProperty(
hCertStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
pwszStoreName,
&dwSize);
}
}
if(pwszStoreName)
SetWindowTextU(hwndControl,pwszStoreName);
if(pwszStoreName)
WizardFree(pwszStoreName);
//clear the ListView
/*ListView_DeleteAllItems(hwndControl);
//insert one column to the store name ListView
//set the store name
//only one column is needed
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 = 20; // Width of the column, in pixels.
lvC.pszText = L""; // The text for the column.
lvC.iSubItem=0;
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
{
if(pwszStoreName)
WizardFree(pwszStoreName);
return;
}
//insert the store name
memset(&lvItem, 0, sizeof(LV_ITEMW));
// set up the fields in the list view item struct that don't change from item to item
lvItem.mask = LVIF_TEXT | LVIF_STATE ;
lvItem.state = 0;
lvItem.stateMask = 0;
lvItem.iItem=0;
lvItem.iSubItem=0;
lvItem.pszText=pwszStoreName;
ListView_InsertItemU(hwndControl, &lvItem);
//autosize the column
ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); */
}
//-------------------------------------------------------------------------
// Check to see if this is an EFS only cert.
//-------------------------------------------------------------------------
BOOL IsEFSOnly(PCCERT_CONTEXT pCertContext)
{
BOOL fResult = FALSE;
PCERT_ENHKEY_USAGE pEKU = NULL;
DWORD cbEKU = 0;
DWORD dwError = 0;
if (!pCertContext)
{
dwError = ERROR_INVALID_PARAMETER;
goto CLEANUP;
}
if (!CertGetEnhancedKeyUsage(pCertContext,
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
NULL,
&cbEKU))
{
dwError = GetLastError();
goto CLEANUP;
}
if (!(pEKU = (PCERT_ENHKEY_USAGE) malloc(cbEKU)))
{
dwError = ERROR_NOT_ENOUGH_MEMORY;
goto CLEANUP;
}
if (!CertGetEnhancedKeyUsage(pCertContext,
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
pEKU,
&cbEKU))
{
dwError = GetLastError();
goto CLEANUP;
}
if ((1 == pEKU->cUsageIdentifier) &&
(0 == strcmp(pEKU->rgpszUsageIdentifier[0], szOID_KP_EFS)))
{
fResult = TRUE;
}
CLEANUP:
if (pEKU)
{
free(pEKU);
}
SetLastError(dwError);
return fResult;
}
#if (0) //DSIE: dead code.
//-------------------------------------------------------------------------
//Search for the duplicated elements in the destination store
//-------------------------------------------------------------------------
BOOL ExistInDes(HCERTSTORE hSrcStore,
HCERTSTORE hDesStore)
{
BOOL fResult=FALSE;
DWORD dwCRLFlag=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCERT_CONTEXT pFindCert=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
PCCRL_CONTEXT pFindCRL=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPre=NULL;
PCCTL_CONTEXT pFindCTL=NULL;
//add the certs
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
if((pFindCert=CertFindCertificateInStore(hDesStore,
X509_ASN_ENCODING,
0,
CERT_FIND_EXISTING,
pCertContext,
NULL)))
{
fResult=TRUE;
goto CLEANUP;
}
pCertPre=pCertContext;
}
//add the CTLs
while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
{
if((pFindCTL=CertFindCTLInStore(hDesStore,
g_dwMsgAndCertEncodingType,
0,
CTL_FIND_EXISTING,
pCTLContext,
NULL)))
{
fResult=TRUE;
goto CLEANUP;
}
pCTLPre=pCTLContext;
}
//add the CRLs
while(pCRLContext=CertGetCRLFromStore(hSrcStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
if((pFindCRL=CertFindCRLInStore(hDesStore,
X509_ASN_ENCODING,
0,
CRL_FIND_EXISTING,
pCRLContext,
NULL)))
{
fResult=TRUE;
goto CLEANUP;
}
pCRLPre=pCRLContext;
}
//we can not find a match
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pFindCert)
CertFreeCertificateContext(pFindCert);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pFindCTL)
CertFreeCTLContext(pFindCTL);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(pFindCRL)
CertFreeCRLContext(pFindCRL);
return fResult;
}
#endif
//-------------------------------------------------------------------------
//populate the list box in the order of FileName, FileType, and Store information
//-------------------------------------------------------------------------
void DisplayImportConfirmation(HWND hwndControl,
CERT_IMPORT_INFO *pCertImportInfo)
{
DWORD dwIndex=0;
DWORD dwSize=0;
UINT ids=0;
LPWSTR pwszStoreName=NULL;
WCHAR wszFileType[MAX_STRING_SIZE];
WCHAR wszSelectedByWizard[MAX_STRING_SIZE];
LV_ITEMW lvItem;
BOOL fNewItem=FALSE;
//delete all the old items in the listView
ListView_DeleteAllItems(hwndControl);
//get the ids of the format type
switch(pCertImportInfo->dwContentType)
{
case CERT_QUERY_CONTENT_CERT:
ids=IDS_ENCODE_CERT;
break;
case CERT_QUERY_CONTENT_CTL:
ids=IDS_ENCODE_CTL;
break;
case CERT_QUERY_CONTENT_CRL:
ids=IDS_ENCODE_CRL;
break;
case CERT_QUERY_CONTENT_SERIALIZED_STORE:
ids=IDS_SERIALIZED_STORE;
break;
case CERT_QUERY_CONTENT_SERIALIZED_CERT:
ids=IDS_SERIALIZED_CERT;
break;
case CERT_QUERY_CONTENT_SERIALIZED_CTL:
ids=IDS_SERIALIZED_CTL;
break;
case CERT_QUERY_CONTENT_SERIALIZED_CRL:
ids=IDS_SERIALIZED_CRL;
break;
case CERT_QUERY_CONTENT_PKCS7_SIGNED :
ids=IDS_PKCS7_SIGNED;
break;
case CERT_QUERY_CONTENT_PFX:
ids=IDS_PFX_BLOB;
break;
default:
// case CERT_QUERY_CONTENT_PKCS7_UNSIGNED
// case CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
// case CERT_QUERY_CONTENT_PKCS10
ids=IDS_NONE;
break;
}
//get the format type
LoadStringU(g_hmodThisDll, ids, wszFileType, MAX_STRING_SIZE);
//get the store name
if(pCertImportInfo->hDesStore)
{
if(!CertGetStoreProperty(
pCertImportInfo->hDesStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
NULL,
&dwSize) || (0==dwSize))
{
//Get the <Unknown> string
pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH);
if(pwszStoreName)
{
*pwszStoreName=L'\0';
LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
}
}
else
{
pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
if(pwszStoreName)
{
*pwszStoreName=L'\0';
CertGetStoreProperty(
pCertImportInfo->hDesStore,
CERT_STORE_LOCALIZED_NAME_PROP_ID,
pwszStoreName,
&dwSize);
}
}
}
//insert row by row
memset(&lvItem, 0, sizeof(LV_ITEMW));
// set up the fields in the list view item struct that don't change from item to item
lvItem.mask = LVIF_TEXT | LVIF_STATE ;
lvItem.state = 0;
lvItem.stateMask = 0;
lvItem.iItem=0;
lvItem.iSubItem=0;
//file name
if(pCertImportInfo->pwszFileName)
{
lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
lvItem.iSubItem=0;
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_FILE_NAME, NULL);
//content
lvItem.iSubItem++;
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
pCertImportInfo->pwszFileName);
}
//file type
if(wszFileType)
{
lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
lvItem.iSubItem=0;
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CONTENT_TYPE, NULL);
//content
lvItem.iSubItem++;
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
wszFileType);
}
//StoreName
lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
lvItem.iSubItem=0;
if(NULL==pCertImportInfo->hDesStore || (FALSE==pCertImportInfo->fSelectedDesStore))
{
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_WIZARD, NULL);
/* if(pCertImportInfo->pwszDefaultStoreName)
{
lvItem.iSubItem++;
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
pCertImportInfo->pwszDefaultStoreName);
}
else */
//get the format type
if(LoadStringU(g_hmodThisDll, IDS_SELECTED_BY_WIZARD, wszSelectedByWizard, MAX_STRING_SIZE))
{
lvItem.iSubItem++;
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
wszSelectedByWizard);
}
}
else
{
ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_USER, NULL);
//content
if(pwszStoreName)
{
lvItem.iSubItem++;
ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
pwszStoreName);
}
}
//auto size the columns in the ListView
ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
if(pwszStoreName)
WizardFree(pwszStoreName);
return;
}
//*************************************************************************
//
// The winproc for import wizards
//************************************************************************
//-----------------------------------------------------------------------
//Import_Welcome
//-----------------------------------------------------------------------
INT_PTR APIENTRY Import_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
CERT_IMPORT_INFO *pCertImportInfo=NULL;
PROPSHEETPAGE *pPropSheet=NULL;
switch (msg)
{
case WM_INITDIALOG:
//set the wizard information so that it can be shared
pPropSheet = (PROPSHEETPAGE *) lParam;
pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
//make sure pCertImportInfo is a valid pointer
if(NULL==pCertImportInfo)
break;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD2);
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
break;
case PSN_RESET:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
break;
case PSN_WIZBACK:
break;
case PSN_WIZNEXT:
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------
// Import_File
//-----------------------------------------------------------------------
INT_PTR APIENTRY Import_File(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
CERT_IMPORT_INFO *pCertImportInfo=NULL;
PROPSHEETPAGE *pPropSheet=NULL;
OPENFILENAMEW OpenFileName;
WCHAR szFileName[_MAX_PATH];
HWND hwndControl=NULL;
DWORD dwChar=0;
LPWSTR pwszInitialDir = NULL;
WCHAR szFilter[MAX_STRING_SIZE + MAX_STRING_SIZE]; //"Certificate File (*.cer)\0*.cer\0Certificate File (*.crt)\0*.crt\0All Files\0*.*\0"
DWORD dwSize=0;
UINT ids=0;
switch (msg)
{
case WM_INITDIALOG:
//set the wizard information so that it can be shared
pPropSheet = (PROPSHEETPAGE *) lParam;
pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
//make sure pCertImportInfo is a valid pointer
if(NULL==pCertImportInfo)
break;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
//set up the file name if pre-selected
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertImportInfo->pwszFileName);
break;
case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED)
{
if(LOWORD(wParam) == IDC_WIZARD_BUTTON1)
{
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
break;
//the browse button is clicked. Open the FileOpen dialogue
memset(&OpenFileName, 0, sizeof(OpenFileName));
*szFileName=L'\0';
OpenFileName.lStructSize=sizeof(OpenFileName);
OpenFileName.hwndOwner=hwndDlg;
OpenFileName.nFilterIndex = 1;
//get the file filer ID
ids=GetFileFilerIDS(pCertImportInfo->dwFlag);
//load the filter string
if(LoadFilterString(g_hmodThisDll, ids, szFilter, MAX_STRING_SIZE + MAX_STRING_SIZE))
{
OpenFileName.lpstrFilter = szFilter;
}
dwChar = (DWORD)SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, WM_GETTEXTLENGTH, 0, 0);
if (NULL != (pwszInitialDir = (LPWSTR) WizardAlloc((dwChar+1)*sizeof(WCHAR))))
{
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pwszInitialDir, dwChar+1);
}
OpenFileName.lpstrInitialDir = pwszInitialDir;
OpenFileName.lpstrFile=szFileName;
OpenFileName.nMaxFile=_MAX_PATH;
OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
//user has selected a file name
if(WizGetOpenFileName(&OpenFileName))
{
//set the edit box
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, szFileName);
}
if(pwszInitialDir != NULL)
{
WizardFree(pwszInitialDir);
pwszInitialDir = NULL;
}
}
}
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
break;
case PSN_RESET:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
break;
case PSN_WIZBACK:
break;
case PSN_WIZNEXT:
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
break;
//make sure a file is selected
if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
IDC_WIZARD_EDIT1,
WM_GETTEXTLENGTH, 0, 0)))
{
I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_FILE,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
//get the file name
if(pCertImportInfo->pwszFileName)
{
//delete the old file name
if(TRUE==pCertImportInfo->fFreeFileName)
{
WizardFree(pCertImportInfo->pwszFileName);
pCertImportInfo->pwszFileName=NULL;
}
}
pCertImportInfo->pwszFileName=(LPWSTR)WizardAlloc((dwChar+1)*sizeof(WCHAR));
if(NULL!=(pCertImportInfo->pwszFileName))
{
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
pCertImportInfo->pwszFileName,
dwChar+1);
pCertImportInfo->fFreeFileName=TRUE;
//make sure the file is valid
//delete the old store
if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore))
{
CertCloseStore(pCertImportInfo->hSrcStore, 0);
pCertImportInfo->hSrcStore=NULL;
}
//we import anything but PKCS10 or signed document
if(!ExpandAndCryptQueryObject(
CERT_QUERY_OBJECT_FILE,
pCertImportInfo->pwszFileName,
dwExpectedContentType,
CERT_QUERY_FORMAT_FLAG_ALL,
0,
NULL,
&(pCertImportInfo->dwContentType),
NULL,
&(pCertImportInfo->hSrcStore),
NULL,
NULL))
{
if(FileExist(pCertImportInfo->pwszFileName))
I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
else
I_MessageBox(hwndDlg, IDS_NON_EXIST_FILE,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
//we re-mark the pPFX
pCertImportInfo->fPFX=FALSE;
//get the blobs from the pfx file
if(CERT_QUERY_CONTENT_PFX==pCertImportInfo->dwContentType)
{
//we can not import PFX Files for remote case
if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE)
{
//output the message
I_MessageBox(hwndDlg, IDS_IMPORT_NO_PFX_FOR_REMOTE,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
if((pCertImportInfo->blobData).pbData)
{
UnmapViewOfFile((pCertImportInfo->blobData).pbData);
(pCertImportInfo->blobData).pbData=NULL;
}
if(S_OK !=RetrieveBLOBFromFile(
pCertImportInfo->pwszFileName,
&((pCertImportInfo->blobData).cbData),
&((pCertImportInfo->blobData).pbData)))
{
//output the message
I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
//make sure that the soure store's content match with
//the expectation
if(0==((pCertImportInfo->dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
{
//output the message
I_MessageBox(hwndDlg,
IDS_IMPORT_OBJECT_NOT_EXPECTED,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
}
else
{
//if the content is PKCS7, get the BLOB
if(CERT_QUERY_CONTENT_PKCS7_SIGNED==pCertImportInfo->dwContentType)
{
if((pCertImportInfo->blobData).pbData)
{
UnmapViewOfFile((pCertImportInfo->blobData).pbData);
(pCertImportInfo->blobData).pbData=NULL;
}
if(S_OK !=RetrieveBLOBFromFile(
pCertImportInfo->pwszFileName,
&((pCertImportInfo->blobData).cbData),
&((pCertImportInfo->blobData).pbData)))
{
//output the message
I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
}
//make sure we do have a source store
if(NULL==pCertImportInfo->hSrcStore)
{
//output the message
I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
//remember to free the Src store
pCertImportInfo->fFreeSrcStore=TRUE;
//make sure that the soure store's content match with
//the expectation
ids=0;
if(!CheckForContent(pCertImportInfo->hSrcStore,
pCertImportInfo->dwFlag,
TRUE,
&ids))
{
//output the message
I_MessageBox(hwndDlg,
ids,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
}
}
//skip the next page if password is not necessary
if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType)
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_STORE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------
// Import_Password
//-----------------------------------------------------------------------
INT_PTR APIENTRY Import_Password(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
CERT_IMPORT_INFO *pCertImportInfo=NULL;
PROPSHEETPAGE *pPropSheet=NULL;
HWND hwndControl=NULL;
DWORD dwChar;
UINT ids=0;
switch (msg)
{
case WM_INITDIALOG:
HRESULT hr;
HKEY hKey;
DWORD cb;
DWORD dwKeyValue;
DWORD dwType;
//set the wizard information so that it can be shared
pPropSheet = (PROPSHEETPAGE *) lParam;
pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
//make sure pCertImportInfo is a valid pointer
if(NULL==pCertImportInfo)
break;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
//init the passWord
SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 64, (LPARAM) 0);
SetDlgItemTextU(
hwndDlg,
IDC_WIZARD_EDIT1,
(pCertImportInfo->pwszPassword != NULL) ? pCertImportInfo->pwszPassword : L"");
#if (1) //DSIE: Bug 333621
SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 32, (LPARAM) 0);
#endif
//init the passWord flag
if(pCertImportInfo->dwPasswordFlags & CRYPT_EXPORTABLE)
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 1, 0);
else
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 0, 0);
if(pCertImportInfo->dwPasswordFlags & CRYPT_USER_PROTECTED)
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
else
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 0, 0);
//now, we need to grey out the user protection check box for the local
//machine import
if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE);
else
{
//
// Not Import to Local Machine
// Open the CRYPTOAPI_PRIVATE_KEY_OPTIONS registry key under HKLM
//
hKey = NULL;
hr = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
szKEY_CRYPTOAPI_PRIVATE_KEY_OPTIONS,
0,
KEY_QUERY_VALUE,
&hKey);
if ( S_OK != hr )
goto error;
//
// Query the registry key for FORCE_KEY_PROTECTION value
//
cb = sizeof(dwKeyValue);
hr = RegQueryValueEx(
hKey,
szFORCE_KEY_PROTECTION,
NULL,
&dwType,
(BYTE *) &dwKeyValue,
&cb);
if( S_OK == hr && REG_DWORD == dwType && sizeof(dwKeyValue) == cb )
{
switch( dwKeyValue )
{
case dwFORCE_KEY_PROTECTION_DISABLED:
// do not force key protection
break;
case dwFORCE_KEY_PROTECTION_USER_SELECT:
// allow the user to select key protection UI, default = yes
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
break;
case dwFORCE_KEY_PROTECTION_HIGH:
// set to force key protection and grey out choice so that user cannot change value
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE);
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
break;
default:
// Unknown value in registry
break;
}
}
error:
if( NULL != hKey ){
RegCloseKey(hKey);
}
}
break;
case WM_COMMAND:
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
break;
case PSN_RESET:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
break;
case PSN_WIZBACK:
break;
case PSN_WIZNEXT:
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
break;
//free the memory
if(pCertImportInfo->pwszPassword)
{
// DSIE: Bug 534689.
SecureZeroMemory(pCertImportInfo->pwszPassword,
lstrlenW(pCertImportInfo->pwszPassword) * sizeof(WCHAR));
WizardFree(pCertImportInfo->pwszPassword);
pCertImportInfo->pwszPassword=NULL;
}
//get the password
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
IDC_WIZARD_EDIT1,
WM_GETTEXTLENGTH, 0, 0)))
{
pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
if(NULL!=pCertImportInfo->pwszPassword)
{
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
pCertImportInfo->pwszPassword,
dwChar+1);
}
else
break;
}
else
pCertImportInfo->pwszPassword=NULL;
//if user request to export the private key
if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_GETCHECK, 0, 0))
pCertImportInfo->dwPasswordFlags |=CRYPT_EXPORTABLE;
else
pCertImportInfo->dwPasswordFlags &= (~CRYPT_EXPORTABLE);
if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_GETCHECK, 0, 0))
pCertImportInfo->dwPasswordFlags |=CRYPT_USER_PROTECTED;
else
pCertImportInfo->dwPasswordFlags &= (~CRYPT_USER_PROTECTED);
//delete the old certificate store
if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore))
{
CertCloseStore(pCertImportInfo->hSrcStore, 0);
pCertImportInfo->hSrcStore=NULL;
}
//decode the PFX blob
if(NULL==(pCertImportInfo->blobData).pbData)
break;
//convert the PFX BLOB to a certificate store
pCertImportInfo->fPFX=PFXVerifyPassword(
(CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData),
pCertImportInfo->pwszPassword,
0);
if((FALSE==pCertImportInfo->fPFX) && (NULL == pCertImportInfo->pwszPassword))
{
//we try to use "" for no password case
pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR));
if(NULL != pCertImportInfo->pwszPassword)
{
*(pCertImportInfo->pwszPassword)=L'\0';
pCertImportInfo->fPFX=PFXVerifyPassword(
(CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData),
pCertImportInfo->pwszPassword,
0);
}
}
if(FALSE==pCertImportInfo->fPFX)
{
//output the message
I_MessageBox(hwndDlg, IDS_INVALID_PASSWORD,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------
// Import_Store
//-----------------------------------------------------------------------
INT_PTR APIENTRY Import_Store(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
CERT_IMPORT_INFO *pCertImportInfo=NULL;
PROPSHEETPAGE *pPropSheet=NULL;
HWND hwndControl=NULL;
DWORD dwSize=0;
CRYPTUI_SELECTSTORE_STRUCT CertStoreSelect;
STORENUMERATION_STRUCT StoreEnumerationStruct;
STORESFORSELCTION_STRUCT StoresForSelectionStruct;
HCERTSTORE hCertStore=NULL;
HDC hdc=NULL;
COLORREF colorRef;
LV_COLUMNW lvC;
UINT idsError=0;
switch (msg)
{
case WM_INITDIALOG:
//set the wizard information so that it can be shared
pPropSheet = (PROPSHEETPAGE *) lParam;
pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
//make sure pCertImportInfo is a valid pointer
if(NULL==pCertImportInfo)
break;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
//getthe background color of the parent window
//the background of the list view for store name is grayed
/*
if(hdc=GetWindowDC(hwndDlg))
{
if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
{
ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
}
} */
//mark the store selection
if(pCertImportInfo->hDesStore)
{
//disable the 1st radio button
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
//select raio2
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
//enable the windows for select a certificate store
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE);
//mark the store name
hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
if(hwndControl)
SetImportStoreName(hwndControl, pCertImportInfo->hDesStore);
//diable the radio buttons if CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST
//is set
if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE)
{
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
}
}
else
{
//select the 1st radio button
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
//disable the windows for select a certificate store
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
}
break;
case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED)
{
switch (LOWORD(wParam))
{
case IDC_WIZARD_RADIO1:
//select the 1st radio button
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
//disable raio2
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
//disable the windows for select a certificate store
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
break;
case IDC_WIZARD_RADIO2:
//disable the 1st radio button
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
//select raio2
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
//enable the windows for select a certificate store
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE);
//if no change of the desination is set, we need to diable the browse
//button and 1st radio button
if(NULL!=(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
{
if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE)
{
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
}
}
break;
case IDC_WIZARD_BUTTON1:
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
{
break;
}
//get the hwndControl for the list view
hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
//call the store selection dialogue
memset(&CertStoreSelect, 0, sizeof(CertStoreSelect));
memset(&StoresForSelectionStruct, 0, sizeof(StoresForSelectionStruct));
memset(&StoreEnumerationStruct, 0, sizeof(StoreEnumerationStruct));
StoreEnumerationStruct.dwFlags=CERT_STORE_MAXIMUM_ALLOWED_FLAG;
StoreEnumerationStruct.pvSystemStoreLocationPara=NULL;
StoresForSelectionStruct.cEnumerationStructs = 1;
StoresForSelectionStruct.rgEnumerationStructs = &StoreEnumerationStruct;
// if a pfx import is taking place, then make sure the correct
// stores are displayed for selection
if ((TRUE == pCertImportInfo->fPFX) &&
(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
{
StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
}
else
{
StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER;
}
CertStoreSelect.dwSize=sizeof(CertStoreSelect);
CertStoreSelect.hwndParent=hwndDlg;
CertStoreSelect.dwFlags=CRYPTUI_VALIDATE_STORES_AS_WRITABLE | CRYPTUI_ALLOW_PHYSICAL_STORE_VIEW | CRYPTUI_DISPLAY_WRITE_ONLY_STORES;
CertStoreSelect.pStoresForSelection = &StoresForSelectionStruct;
hCertStore=CryptUIDlgSelectStore(&CertStoreSelect);
if(hCertStore)
{
//delete the old destination certificate store
if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fFreeDesStore))
{
CertCloseStore(pCertImportInfo->hDesStore, 0);
pCertImportInfo->hDesStore=NULL;
}
pCertImportInfo->hDesStore=hCertStore;
pCertImportInfo->fFreeDesStore=TRUE;
//get the store name
if(hwndControl)
SetImportStoreName(hwndControl, pCertImportInfo->hDesStore);
}
break;
default:
break;
}
}
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
break;
case PSN_RESET:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
break;
case PSN_WIZBACK:
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
{
break;
}
//skip the next page if password is not necessary
if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType)
{
//jump to the welcome page if the source is not from a file
if((pCertImportInfo->hSrcStore && (NULL==pCertImportInfo->pwszFileName)) ||
((pCertImportInfo->fKnownSrc)&&(pCertImportInfo->pwszFileName)&&(CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType))
)
{
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_WELCOME);
}
else
{
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_FILE);
}
}
break;
case PSN_WIZNEXT:
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
{
break;
}
//make sure that we have select some store
if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0))
{
//mark that the des store is not selected
pCertImportInfo->fSelectedDesStore=FALSE;
/*if(pCertImportInfo->pwszDefaultStoreName)
{
WizardFree(pCertImportInfo->pwszDefaultStoreName);
pCertImportInfo->pwszDefaultStoreName=NULL;
}*/
//we will not know the default store name
//if PFX was selected
/*if(pCertImportInfo->hSrcStore)
{
if(!GetDefaultStoreName(
pCertImportInfo,
pCertImportInfo->hSrcStore,
&(pCertImportInfo->pwszDefaultStoreName),
&idsError))
{
//output the message
I_MessageBox(hwndDlg, idsError,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
} */
}
else
{
//make sure we have something selected
if(NULL==pCertImportInfo->hDesStore)
{
//output the message
I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_STORE,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_ICONERROR|MB_OK|MB_APPLMODAL);
//make the file page stay
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
break;
}
else
{
pCertImportInfo->fSelectedDesStore=TRUE;
}
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------
// Import_Completion
//-----------------------------------------------------------------------
INT_PTR APIENTRY Import_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
CERT_IMPORT_INFO *pCertImportInfo=NULL;
PROPSHEETPAGE *pPropSheet=NULL;
HWND hwndControl=NULL;
LV_COLUMNW lvC;
HDC hdc=NULL;
COLORREF colorRef;
switch (msg)
{
case WM_INITDIALOG:
//set the wizard information so that it can be shared
pPropSheet = (PROPSHEETPAGE *) lParam;
pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
//make sure pCertImportInfo is a valid pointer
if(NULL==pCertImportInfo)
break;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
//getthe background color of the parent window
/*
if(hdc=GetWindowDC(hwndDlg))
{
if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
{
ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
}
} */
//insert two columns for the confirmation
if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
{
//1st one is the label for the confirmation
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 = 20; // Width of the column, in pixels.
lvC.pszText = L""; // The text for the column.
lvC.iSubItem=0;
ListView_InsertColumnU(hwndControl, 0, &lvC);
//2nd column is the content
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 = 20; // Width of the column, in pixels.
lvC.pszText = L""; // The text for the column.
lvC.iSubItem= 1;
ListView_InsertColumnU(hwndControl, 1, &lvC);
}
break;
case WM_COMMAND:
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return TRUE;
break;
case PSN_RESET:
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
{
break;
}
//populate the list box in the order of
//FileName, FileType, and store info
if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
{
DisplayImportConfirmation(hwndControl, pCertImportInfo);
ListView_SetItemState(hwndControl,
0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
break;
case PSN_WIZBACK:
break;
case PSN_WIZFINISH:
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------------
//
// Add a specified Cert/CTL/CRL context to specified destination store, and prompt
// user for permission if attempting to replace an older context over a newer
// context, if UI is allowed.
//
//---------------------------------------------------------------------------------
DWORD AddContextToStore(IN DWORD dwContextType,
IN HWND hwndParent,
IN PVOID pContext,
IN BOOL fUIAllowed,
IN HCERTSTORE hDstStore)
{
DWORD dwRetCode = 0;
switch (dwContextType)
{
case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
{
//
// Add cert context to store.
//
if (!CertAddCertificateContextToStore(hDstStore,
(PCCERT_CONTEXT) pContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
{
dwRetCode = GetLastError();
break;
}
break;
}
case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
{
if (!CertAddCTLContextToStore(hDstStore,
(PCCTL_CONTEXT) pContext,
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES,
NULL))
{
//
// If there is a newer copy in the store, then prompt user for permission
// to replace, if UI is allowed.
//
if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError()))
{
dwRetCode = GetLastError();
break;
}
if (IDYES != I_MessageBox(hwndParent,
IDS_IMPORT_REPLACE_EXISTING_NEWER_CTL,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2))
{
dwRetCode = ERROR_CANCELLED;
break;
}
//
// Try with REPLACE_EXISTING disposition.
//
if (!CertAddCTLContextToStore(hDstStore,
(PCCTL_CONTEXT) pContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
{
dwRetCode = GetLastError();
break;
}
}
break;
}
case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
{
if (!CertAddCRLContextToStore(hDstStore,
(PCCRL_CONTEXT) pContext,
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES,
NULL))
{
//
// If there is a newer copy in the store, then prompt user for permission
// to replace, if UI is allowed.
//
if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError()))
{
dwRetCode = GetLastError();
break;
}
if (IDYES != I_MessageBox(hwndParent,
IDS_IMPORT_REPLACE_EXISTING_NEWER_CRL,
IDS_IMPORT_WIZARD_TITLE,
NULL,
MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2))
{
dwRetCode = ERROR_CANCELLED;
break;
}
//
// Try with REPLACE_EXISTING disposition.
//
if (!CertAddCRLContextToStore(hDstStore,
(PCCRL_CONTEXT) pContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
{
dwRetCode = GetLastError();
break;
}
}
break;
}
default:
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
}
return dwRetCode;
}
//--------------------------------------------------------------------------------
//
// Add CTLs from source store to destination store.
//
//---------------------------------------------------------------------------------
DWORD AddCTLsToStore(HWND hwndParent,
HCERTSTORE hSrcStore,
HCERTSTORE hDstStore,
BOOL fUIAllowed,
UINT * pidsStatus)
{
DWORD dwError = 0;
PCCTL_CONTEXT pCTLPre = NULL;
PCCTL_CONTEXT pCTLContext = NULL;
PCCTL_CONTEXT pFindCTL = NULL;
//DSIE: Bug 22633.
BOOL bCancelled = FALSE;
// Add the CTLs
while (pCTLContext = CertEnumCTLsInStore(hSrcStore, pCTLPre))
{
bCancelled = FALSE;
if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT,
hwndParent,
(PVOID) pCTLContext,
fUIAllowed,
hDstStore)))
{
if (ERROR_CANCELLED == dwError)
{
bCancelled = TRUE;
}
else
{
// Check to see if there is alreay a read-only duplicated copy in the store?
// If so, ignore the error.
if (NULL == (pFindCTL = CertFindCTLInStore(hDstStore,
g_dwMsgAndCertEncodingType,
0,
CTL_FIND_EXISTING,
pCTLContext,
NULL)))
{
*pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
goto CLEANUP;
}
CertFreeCTLContext(pFindCTL);
pFindCTL = NULL;
}
dwError = 0;
}
pCTLPre = pCTLContext;
}
//
// As the way we have it now, we can only check the last operation!
//
if (bCancelled)
{
dwError = ERROR_CANCELLED;
*pidsStatus = IDS_IMPORT_CANCELLED;
}
else
{
*pidsStatus = IDS_IMPORT_SUCCEEDED;
}
CLEANUP:
if (pCTLContext)
{
CertFreeCTLContext(pCTLContext);
}
return dwError;
}
//--------------------------------------------------------------------------------
//
// Add CRLs from source store to destination store.
//
//---------------------------------------------------------------------------------
DWORD AddCRLsToStore(HWND hwndParent,
HCERTSTORE hSrcStore,
HCERTSTORE hDstStore,
BOOL fUIAllowed,
UINT * pidsStatus)
{
DWORD dwError = 0;
DWORD dwCRLFlag = 0;
PCCRL_CONTEXT pCRLPre = NULL;
PCCRL_CONTEXT pCRLContext = NULL;
PCCRL_CONTEXT pFindCRL = NULL;
//DSIE: Bug 22633.
BOOL bCancelled = FALSE;
// Add the CRLs
while (pCRLContext = CertGetCRLFromStore(hSrcStore, NULL, pCRLPre, &dwCRLFlag))
{
bCancelled = FALSE;
if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT,
hwndParent,
(PVOID) pCRLContext,
fUIAllowed,
hDstStore)))
{
if (ERROR_CANCELLED == dwError)
{
bCancelled = TRUE;
}
else
{
// Check to see if there is alreay a read-only duplicated copy in the store?
// If so, ignore the error.
if (NULL == (pFindCRL = CertFindCRLInStore(hDstStore,
g_dwMsgAndCertEncodingType,
0,
CRL_FIND_EXISTING,
pCRLContext,
NULL)))
{
*pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
goto CLEANUP;
}
CertFreeCRLContext(pFindCRL);
pFindCRL = NULL;
}
dwError = 0;
}
pCRLPre = pCRLContext;
}
//
// As the way we have it now, we can only check the last operation!
//
if (bCancelled)
{
dwError = ERROR_CANCELLED;
*pidsStatus = IDS_IMPORT_CANCELLED;
}
else
{
*pidsStatus = IDS_IMPORT_SUCCEEDED;
}
CLEANUP:
if (pCRLContext)
{
CertFreeCRLContext(pCRLContext);
}
return dwError;
}
//--------------------------------------------------------------------------------
//
// Add certs from source store to destination store.
//
//---------------------------------------------------------------------------------
DWORD AddCertsToStore(HWND hwndParent,
HCERTSTORE hSrcStore,
HCERTSTORE hDstStore,
BOOL fUIAllowed,
UINT * pidsStatus)
{
DWORD dwError = 0;
PCCERT_CONTEXT pCertPre = NULL;
PCCERT_CONTEXT pCertContext = NULL;
PCCERT_CONTEXT pFindCert = NULL;
//DSIE: Bug 22633.
BOOL bCancelled = FALSE;
// Add the certs
while (pCertContext = CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
bCancelled = FALSE;
if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT,
hwndParent,
(PVOID) pCertContext,
fUIAllowed,
hDstStore)))
{
if (ERROR_CANCELLED == dwError)
{
bCancelled = TRUE;
}
else
{
// Check to see if there is alreay a read-only duplicated copy in the store?
// If so, ignore the error.
if (NULL == (pFindCert = CertFindCertificateInStore(hDstStore,
g_dwMsgAndCertEncodingType,
0,
CERT_FIND_EXISTING,
pCertContext,
NULL)))
{
*pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
goto CLEANUP;
}
CertFreeCertificateContext(pFindCert);
pFindCert = NULL;
}
dwError = 0;
}
pCertPre = pCertContext;
}
//
// As the way we have it now, we can only check the last operation!
//
if (bCancelled)
{
dwError = ERROR_CANCELLED;
*pidsStatus = IDS_IMPORT_CANCELLED;
}
else
{
*pidsStatus = IDS_IMPORT_SUCCEEDED;
}
CLEANUP:
if (pCertContext)
{
CertFreeCertificateContext(pCertContext);
}
return dwError;
}
//-------------------------------------------------------------------------
//
// Move Certs/CRls/CTLs from the source store to the destination
//
//-------------------------------------------------------------------------
DWORD MoveItem(CERT_IMPORT_INFO * pCertImportInfo,
UINT * pidsStatus)
{
DWORD dwError = 0;
// Add the CTLs.
if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent,
pCertImportInfo->hSrcStore,
pCertImportInfo->hDesStore,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
pidsStatus)))
{
goto CLEANUP;
}
// Add the CRLs.
if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent,
pCertImportInfo->hSrcStore,
pCertImportInfo->hDesStore,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
pidsStatus)))
{
goto CLEANUP;
}
// Add the certs.
if (0 != (dwError = AddCertsToStore(pCertImportInfo->hwndParent,
pCertImportInfo->hSrcStore,
pCertImportInfo->hDesStore,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
pidsStatus)))
{
goto CLEANUP;
}
CLEANUP:
return dwError;
}
//**************************************************************************
//
// The entry point for import wizard
//**************************************************************************
//-----------------------------------------------------------------------
//
// CryptUIWizImport
//
// The import wizard to import public key related files to a certificate
// store
//
// dwFlags can be set to any combination of the following flags:
// CRYPTUI_WIZ_NO_UI No UI will be shown. Otherwise, User will be
// prompted by a wizard.
// CRYPTUI_WIZ_IMPORT_ALLOW_CERT Allow importing certificate
// CRYPTUI_WIZ_IMPORT_ALLOW_CRL Allow importing CRL(certificate revocation list)
// CRYPTUI_WIZ_IMPORT_ALLOW_CTL Allow importing CTL(certificate trust list)
// CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE user will not be allowed to change
// the hDesCertStore in the wizard page
// CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE the contents should be imported to local machine
// (currently only applicable for PFX imports)
// CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER the contents should be imported to current user
// (currently only applicable for PFX imports)
//
// Please notice that if neither of following three flags is in dwFlags, default to is
// allow everything.
// CRYPTUI_WIZ_IMPORT_ALLOW_CERT
// CRYPTUI_WIZ_IMPORT_ALLOW_CRL
// CRYPTUI_WIZ_IMPORT_ALLOW_CTL
//
// Also, note that the CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE and CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER
// flags are used force the content of a pfx blob into either local machine or current user.
// If neither of these flags are used and hDesCertStore is NULL then:
// 1) The private key in the pfx blob will be forced to be imported into current user.
// 2) If CRYPTUI_WIZ_NO_UI is NOT set, the wizard will prompt the user to select a certificate
// store from the current user stores.
//
//
//
// If CRYPTUI_WIZ_NO_UI is set in dwFlags:
// hwndParent: Ignored
// pwszWizardTitle: Ignored
// pImportSubject: IN Required: The subject to import.
// hDestCertStore: IN Optional: The destination certficate store
//
// If CRYPTUI_WIZ_NO_UI is not set in dwFlags:
// hwndPrarent: IN Optional: The parent window for the wizard
// pwszWizardTitle: IN Optional: The title of the wizard
// If NULL, the default will be IDS_BUILDCTL_WIZARD_TITLE
// pImportSubject: IN Optional: The file name to import.
// If NULL, the wizard will prompt user to enter the file name
// hDestCertStore: IN Optional: The destination certificate store where the file wil be
// imported to. If NULL, the wizard will prompt user to select
// a certificate store
//------------------------------------------------------------------------
BOOL
WINAPI
CryptUIWizImport(
DWORD dwFlags,
HWND hwndParent,
LPCWSTR pwszWizardTitle,
PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSubject,
HCERTSTORE hDestCertStore
)
{
BOOL fResult=FALSE;
HRESULT hr=E_FAIL;
CERT_IMPORT_INFO CertImportInfo;
HCERTSTORE hTempStore=NULL;
UINT ids=IDS_INVALID_WIZARD_INPUT;
UINT idsContent=0;
PROPSHEETPAGEW rgImportSheet[IMPORT_PROP_SHEET];
PROPSHEETHEADERW importHeader;
ENROLL_PAGE_INFO rgImportPageInfo[]=
{(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_WELCOME), Import_Welcome,
(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_FILE), Import_File,
(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_PASSWORD), Import_Password,
(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_STORE), Import_Store,
(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_COMPLETION), Import_Completion,
};
DWORD dwIndex=0;
DWORD dwPropCount=0;
WCHAR wszTitle[MAX_TITLE_LENGTH];
DWORD dwError=0;
int intMsg=0;
INT_PTR iReturn=-1;
//init
memset(&CertImportInfo, 0, sizeof(CERT_IMPORT_INFO));
memset(rgImportSheet, 0, sizeof(PROPSHEETPAGEW)*IMPORT_PROP_SHEET);
memset(&importHeader, 0, sizeof(PROPSHEETHEADERW));
//make sure if UIless option is set, all required information
//is provided
if(dwFlags & CRYPTUI_WIZ_NO_UI)
{
if(NULL==pImportSubject)
goto InvalidArgErr;
}
if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE) &&
(dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER))
{
goto InvalidArgErr;
}
//make sure that default is to allow everything
if((0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) &&
(0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)) &&
(0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL)))
dwFlags |= CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL | CRYPTUI_WIZ_IMPORT_ALLOW_CTL;
//if hDestCertStore is NULL, no need to set the remote flag
if(NULL == hDestCertStore)
dwFlags &= (~CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE);
CertImportInfo.hwndParent=hwndParent;
CertImportInfo.dwFlag=dwFlags;
//set the subject
if(pImportSubject)
{
if(pImportSubject->dwSize != sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO))
goto InvalidArgErr;
//copy the passWord and flags for PFX BLOBs
CertImportInfo.dwPasswordFlags=pImportSubject->dwFlags;
if(pImportSubject->pwszPassword)
CertImportInfo.pwszPassword=WizardAllocAndCopyWStr((LPWSTR)(pImportSubject->pwszPassword));
else
CertImportInfo.pwszPassword=NULL;
//open a temparory certificate store
hTempStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
g_dwMsgAndCertEncodingType,
NULL,
0,
NULL);
if(!hTempStore)
goto CertOpenStoreErr;
switch(pImportSubject->dwSubjectChoice)
{
case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE:
if(NULL==pImportSubject->pwszFileName)
goto InvalidArgErr;
CertImportInfo.pwszFileName=(LPWSTR)(pImportSubject->pwszFileName);
CertImportInfo.fFreeFileName=FALSE;
//get the content type of the file
//we import anything but PKCS10 or signed document
ExpandAndCryptQueryObject(
CERT_QUERY_OBJECT_FILE,
CertImportInfo.pwszFileName,
dwExpectedContentType,
CERT_QUERY_FORMAT_FLAG_ALL,
0,
NULL,
&(CertImportInfo.dwContentType),
NULL,
&(CertImportInfo.hSrcStore),
NULL,
NULL);
//if this is a PKCS7 file, get the blob
if(CERT_QUERY_CONTENT_PKCS7_SIGNED == CertImportInfo.dwContentType )
{
if(S_OK !=(hr=RetrieveBLOBFromFile(
CertImportInfo.pwszFileName,
&(CertImportInfo.blobData.cbData),
&(CertImportInfo.blobData.pbData))))
goto ReadFromFileErr;
}
else
{
//get the blobs from the pfx file
if(CERT_QUERY_CONTENT_PFX==CertImportInfo.dwContentType)
{
//we can not import PFX Files for remote case
if(dwFlags & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE)
{
ids=IDS_IMPORT_NO_PFX_FOR_REMOTE;
goto InvalidArgErr;
}
if(S_OK !=(hr=RetrieveBLOBFromFile(
CertImportInfo.pwszFileName,
&(CertImportInfo.blobData.cbData),
&(CertImportInfo.blobData.pbData))))
goto ReadFromFileErr;
//convert the PFX BLOB to a certificate store
CertImportInfo.fPFX=PFXVerifyPassword(
(CRYPT_DATA_BLOB *)&(CertImportInfo.blobData),
CertImportInfo.pwszPassword,
0);
//PFX blob only contains certificates
if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
{
ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
goto InvalidArgErr;
}
}
}
//make sure we do have a source store
if(CertImportInfo.hSrcStore)
{
//remember to free the Src store
CertImportInfo.fFreeSrcStore=TRUE;
CertImportInfo.fKnownSrc=TRUE;
}
break;
case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
if(NULL==pImportSubject->pCertContext)
goto InvalidArgErr;
//add certificate to the hash
if(!CertAddCertificateContextToStore(
hTempStore,
pImportSubject->pCertContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
goto AddCertErr;
CertImportInfo.hSrcStore=hTempStore;
CertImportInfo.fFreeSrcStore=FALSE;
CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CERT;
CertImportInfo.fKnownSrc=TRUE;
break;
case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
if(NULL==pImportSubject->pCTLContext)
goto InvalidArgErr;
//add CTL to the hash
if(!CertAddCTLContextToStore(
hTempStore,
pImportSubject->pCTLContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
goto Crypt32Err;
CertImportInfo.hSrcStore=hTempStore;
CertImportInfo.fFreeSrcStore=FALSE;
CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CTL;
CertImportInfo.fKnownSrc=TRUE;
break;
case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
if(NULL==pImportSubject->pCRLContext)
goto InvalidArgErr;
//add CRL to the hash
if(!CertAddCRLContextToStore(
hTempStore,
pImportSubject->pCRLContext,
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
NULL))
goto Crypt32Err;
CertImportInfo.hSrcStore=hTempStore;
CertImportInfo.fFreeSrcStore=FALSE;
CertImportInfo.fKnownSrc=TRUE;
CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CRL;
break;
case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE:
if(NULL==pImportSubject->hCertStore)
goto InvalidArgErr;
CertImportInfo.hSrcStore=pImportSubject->hCertStore;
CertImportInfo.fFreeSrcStore=FALSE;
CertImportInfo.dwContentType=0;
CertImportInfo.fKnownSrc=TRUE;
break;
default:
goto InvalidArgErr;
}
}
else
{
CertImportInfo.fKnownSrc=FALSE;
}
//if user has supplied a source store, it should contain the correct
//information
if(NULL != CertImportInfo.hSrcStore)
{
//make sure that the destination store has the right content
if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent))
{
ids=idsContent;
goto InvalidArgErr;
}
}
else
{
//check for the PFX
if(TRUE == CertImportInfo.fPFX)
{
//PFX blob only contains certificates
if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
{
ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
goto InvalidArgErr;
}
}
}
//set the destination store if supplied
if(hDestCertStore)
{
CertImportInfo.hDesStore=hDestCertStore;
CertImportInfo.fFreeDesStore=FALSE;
CertImportInfo.fKnownDes=TRUE;
CertImportInfo.fSelectedDesStore=TRUE;
}
else
{
CertImportInfo.fKnownDes=FALSE;
CertImportInfo.fSelectedDesStore=FALSE;
}
//supply the UI work
if((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
{
//set up the fonts
if(!SetupFonts(g_hmodThisDll,
NULL,
&(CertImportInfo.hBigBold),
&(CertImportInfo.hBold)))
goto Win32Err;
//init the common control
if(!WizardInit(TRUE) ||
(sizeof(rgImportPageInfo)/sizeof(rgImportPageInfo[0])!=IMPORT_PROP_SHEET)
)
goto InvalidArgErr;
//set up the property sheet and the property header
dwPropCount=0;
for(dwIndex=0; dwIndex<IMPORT_PROP_SHEET; dwIndex++)
{
if(pImportSubject)
{
//skip the IDD_IMPORT_FILE page if subject is known and it is not
//a fileName
if(((1==dwIndex) || (2==dwIndex)) &&
(NULL==CertImportInfo.pwszFileName) &&
(CertImportInfo.hSrcStore)
)
continue;
//or, if this is a PKCS7 file name, we skip the file name
//page. This is strictly for UI freeze.
if(((1==dwIndex) || (2==dwIndex)) &&
(CertImportInfo.pwszFileName)&&
(CERT_QUERY_CONTENT_PKCS7_SIGNED == CertImportInfo.dwContentType)
)
continue;
}
rgImportSheet[dwPropCount].dwSize=sizeof(rgImportSheet[dwPropCount]);
if(pwszWizardTitle)
rgImportSheet[dwPropCount].dwFlags=PSP_USETITLE;
else
rgImportSheet[dwPropCount].dwFlags=0;
rgImportSheet[dwPropCount].hInstance=g_hmodThisDll;
rgImportSheet[dwPropCount].pszTemplate=rgImportPageInfo[dwIndex].pszTemplate;
if(pwszWizardTitle)
{
rgImportSheet[dwPropCount].pszTitle=pwszWizardTitle;
}
else
rgImportSheet[dwPropCount].pszTitle=NULL;
rgImportSheet[dwPropCount].pfnDlgProc=rgImportPageInfo[dwIndex].pfnDlgProc;
rgImportSheet[dwPropCount].lParam=(LPARAM)&CertImportInfo;
dwPropCount++;
}
//set up the header information
importHeader.dwSize=sizeof(importHeader);
importHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
importHeader.hwndParent=hwndParent;
importHeader.hInstance=g_hmodThisDll;
if(pwszWizardTitle)
importHeader.pszCaption=pwszWizardTitle;
else
{
if(LoadStringU(g_hmodThisDll, IDS_IMPORT_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
importHeader.pszCaption=wszTitle;
}
importHeader.nPages=dwPropCount;
importHeader.nStartPage=0;
importHeader.ppsp=rgImportSheet;
//no need to create the wizard if there are only 2 pages:
//Welcome and Confirmation
if(dwPropCount > 2)
{
//create the wizard
iReturn=PropertySheetU(&importHeader);
if(-1 == iReturn)
goto Win32Err;
if(0 == iReturn)
{
fResult=TRUE;
//no need to say anything if the wizard is cancelled
ids=0;
goto CommonReturn;
}
}
}
//Open the destination store for PFX file
if(TRUE == CertImportInfo.fPFX)
{
// if the caller specified local machine then set the appropriate flag
if (dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)
{
CertImportInfo.dwPasswordFlags |= CRYPT_MACHINE_KEYSET;
}
else if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER) ||
(hDestCertStore == NULL))
{
CertImportInfo.dwPasswordFlags |= CRYPT_USER_KEYSET;
}
CertImportInfo.hSrcStore=
PFXImportCertStore(
(CRYPT_DATA_BLOB *)&(CertImportInfo.blobData),
CertImportInfo.pwszPassword,
CertImportInfo.dwPasswordFlags);
if(CertImportInfo.hSrcStore)
{
//remember to free the Src store
CertImportInfo.fFreeSrcStore=TRUE;
CertImportInfo.fKnownSrc=TRUE;
}
else
{
DWORD dwLastError = GetLastError();
if (dwLastError == ERROR_UNSUPPORTED_TYPE)
{
ids=IDS_UNSUPPORTED_KEY;
}
else if (dwLastError == CRYPT_E_BAD_ENCODE)
{
ids=IDS_BAD_ENCODE;
}
//DSIE: Bug 22752
else if (dwLastError == ERROR_CANCELLED)
{
ids=IDS_IMPORT_FAIL_MOVE_CONTENT;
}
else
{
ids=IDS_IMPORT_FAIL_FIND_CONTENT;
}
goto InvalidArgErr;
}
//make sure the PFX blob is not empty
if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent))
{
ids=idsContent;
goto InvalidArgErr;
}
}
//make sure the source store is a valid value
if(NULL==(CertImportInfo.hSrcStore))
{
ids=IDS_IMPORT_FAIL_FIND_CONTENT;
goto InvalidArgErr;
}
//do the import work. Return a status
//we disable the parent window in case the root dialogue will show up
//this is to prevent re-entrency
if(hwndParent)
{
EnableWindow(hwndParent,FALSE);
}
if(S_OK !=(hr=I_ImportCertificate(&CertImportInfo, &ids)))
{
if(hwndParent)
{
EnableWindow(hwndParent,TRUE);
}
goto I_ImportErr;
}
if(hwndParent)
{
EnableWindow(hwndParent,TRUE);
}
fResult=TRUE;
CommonReturn:
//preserve the last error
dwError=GetLastError();
//pop up the confirmation box for failure
if(ids && ((dwFlags & CRYPTUI_WIZ_NO_UI) ==0))
{
//set the message of inable to gather enough info for PKCS10
if(IDS_IMPORT_SUCCEEDED == ids)
I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
NULL, MB_OK|MB_ICONINFORMATION);
else
{
if(IDS_IMPORT_PFX_EMPTY == ids)
I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
NULL, MB_OK|MB_ICONWARNING);
else
I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
NULL, MB_OK|MB_ICONERROR);
}
if(IDS_IMPORT_DUPLICATE == ids)
{
//remark the success case
I_MessageBox(hwndParent, IDS_IMPORT_SUCCEEDED, IDS_IMPORT_WIZARD_TITLE,
NULL, MB_OK|MB_ICONINFORMATION);
}
}
//destroy the hFont object
DestroyFonts(CertImportInfo.hBigBold,
CertImportInfo.hBold);
if(CertImportInfo.pwszFileName && (TRUE==CertImportInfo.fFreeFileName))
WizardFree(CertImportInfo.pwszFileName);
/* if(CertImportInfo.pwszDefaultStoreName)
WizardFree(CertImportInfo.pwszDefaultStoreName); */
if(CertImportInfo.hDesStore && (TRUE==CertImportInfo.fFreeDesStore))
CertCloseStore(CertImportInfo.hDesStore, 0);
if(CertImportInfo.hSrcStore && (TRUE==CertImportInfo.fFreeSrcStore))
CertCloseStore(CertImportInfo.hSrcStore, 0);
if(CertImportInfo.blobData.pbData)
UnmapViewOfFile(CertImportInfo.blobData.pbData);
if(CertImportInfo.pwszPassword)
{
SecureZeroMemory(CertImportInfo.pwszPassword, lstrlenW(CertImportInfo.pwszPassword) * sizeof(WCHAR));
WizardFree(CertImportInfo.pwszPassword);
}
if(hTempStore)
CertCloseStore(hTempStore, 0);
//reset the error
SetLastError(dwError);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArgErr, E_INVALIDARG);
TRACE_ERROR(CertOpenStoreErr);
SET_ERROR_VAR(ReadFromFileErr, hr);
TRACE_ERROR(AddCertErr);
TRACE_ERROR(Crypt32Err);
TRACE_ERROR(Win32Err);
SET_ERROR_VAR(I_ImportErr, hr);
}
//****************************************************************************
// Helper functions for import wizards
//
//*****************************************************************************
BOOL InstallViaXEnroll(CERT_IMPORT_INFO *pCertImportInfo)
{
BOOL fResult=FALSE;
IEnroll2 *pIEnroll2=NULL;
PFNPIEnroll2GetNoCOM pfnPIEnroll2GetNoCOM=NULL;
CRYPT_DATA_BLOB DataBlob;
PCCERT_CONTEXT pCert=NULL;
if(NULL == pCertImportInfo)
goto CLEANUP;
DataBlob.cbData=pCertImportInfo->blobData.cbData;
DataBlob.pbData=pCertImportInfo->blobData.pbData;
if((0 == DataBlob.cbData) || (NULL == DataBlob.pbData))
{
//this is a certificate case. Get the blob for the cert
if(NULL==pCertImportInfo->hSrcStore)
goto CLEANUP;
if(!(pCert=CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, NULL)))
goto CLEANUP;
DataBlob.cbData=pCert->cbCertEncoded;
DataBlob.pbData=pCert->pbCertEncoded;
}
//load the library "xEnroll.dll".
if(NULL==g_hmodxEnroll)
{
if(NULL==(g_hmodxEnroll=LoadLibrary("xenroll.dll")))
{
goto CLEANUP;
}
}
//get the address for PIEnroll2GetNoCOM()
if(NULL==(pfnPIEnroll2GetNoCOM=(PFNPIEnroll2GetNoCOM)GetProcAddress(g_hmodxEnroll,
"PIEnroll2GetNoCOM")))
goto CLEANUP;
if(NULL==(pIEnroll2=pfnPIEnroll2GetNoCOM()))
goto CLEANUP;
//specify the destiniation store if user has specified one
if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fSelectedDesStore))
{
if(S_OK != (pIEnroll2->SetHStoreMy(pCertImportInfo->hDesStore)))
goto CLEANUP;
if(S_OK != (pIEnroll2->SetHStoreCA(pCertImportInfo->hDesStore)))
goto CLEANUP;
if(S_OK != (pIEnroll2->SetHStoreROOT(pCertImportInfo->hDesStore)))
goto CLEANUP;
}
if(S_OK != (pIEnroll2->acceptPKCS7Blob(&DataBlob)))
goto CLEANUP;
fResult=TRUE;
CLEANUP:
if(pIEnroll2)
pIEnroll2->Release();
if(pCert)
CertFreeCertificateContext(pCert);
return fResult;
}
//--------------------------------------------------------------------------------
//
// The import routine that does the work
//
//---------------------------------------------------------------------------------
HRESULT I_ImportCertificate(CERT_IMPORT_INFO * pCertImportInfo,
UINT * pidsStatus)
{
UINT idsStatus=0;
HCERTSTORE hMyStore=NULL;
HCERTSTORE hCAStore=NULL;
HCERTSTORE hTrustStore=NULL;
HCERTSTORE hRootStore=NULL;
HCERTSTORE hAddressBookStore=NULL;
HCERTSTORE hTrustedPeopleStore=NULL;
HCERTSTORE hCertStore=NULL;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCERT_CONTEXT pFindCert=NULL;
DWORD dwData=0;
DWORD dwCertOpenStoreFlags;
//DSIE: Bug 22633.
BOOL bCancelled = FALSE;
DWORD dwError = 0;
if (NULL == pCertImportInfo || NULL == pidsStatus)
return E_INVALIDARG;
if (NULL == pCertImportInfo->hSrcStore)
{
*pidsStatus = IDS_IMPORT_FAIL_FIND_CONTENT;
return E_FAIL;
}
if (pCertImportInfo->fPFX && (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
{
dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
}
else
{
dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER;
}
// If the content type is PKS7 and use pass in or select a file name.
// We try to use xEnroll to accept it as an enrollment response.
if ((CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType) ||
(CERT_QUERY_CONTENT_CERT == pCertImportInfo->dwContentType))
{
if (InstallViaXEnroll(pCertImportInfo))
{
*pidsStatus = IDS_IMPORT_SUCCEEDED;
return S_OK;
}
}
// Do a store copy if hDesStore is selected.
if (pCertImportInfo->hDesStore && pCertImportInfo->fSelectedDesStore)
{
dwError = MoveItem(pCertImportInfo, pidsStatus);
goto CLEANUP;
}
// We need to find a correct store on user's behalf.
// Put the CTLs in the trust store.
if (!(hTrustStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"trust")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_TRUST;
goto CLEANUP;
}
if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent,
pCertImportInfo->hSrcStore,
hTrustStore,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
pidsStatus)))
{
goto CLEANUP;
}
// Put CRL in the CA store.
if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"ca")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_CA;
goto CLEANUP;
}
if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent,
pCertImportInfo->hSrcStore,
hCAStore,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
pidsStatus)))
{
goto CLEANUP;
}
// Add the certificate with private key to my store; and the rest
// to the ca, root, or addressbook store.
while (pCertContext = CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, pCertPre))
{
// Check if the certificate has the property on it.
// Make sure the private key matches the certificate
// Search for both machine key and user keys
if (CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL, &dwData) &&
CryptFindCertificateKeyProvInfo(pCertContext,
0,
NULL))
{
// Open my store if necessary.
if (!hMyStore)
{
if (!(hMyStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"my")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_MY;
goto CLEANUP;
}
}
hCertStore = hMyStore;
}
// See if the certificate is self-signed.
// If it is selfsigned, goes to the root store
else if (TrustIsCertificateSelfSigned(pCertContext,
pCertContext->dwCertEncodingType,
0))
{
// DSIE: Bug 375649.
// If EFS only cert, put it in TrustedPeople for self-signed cert,
// otherwise, go to the root store.
//
if (IsEFSOnly(pCertContext))
{
// Open the TrustedPeople store if necessary.
if (!hTrustedPeopleStore)
{
if (!(hTrustedPeopleStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"trustedpeople")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_TRUSTEDPEOPLE;
goto CLEANUP;
}
}
hCertStore = hTrustedPeopleStore;
}
else
{
// Open the root store if necessary.
if (!hRootStore)
{
if (!(hRootStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"root")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_ROOT;
goto CLEANUP;
}
}
hCertStore = hRootStore;
}
}
// Go to ca store if for ca cert, otherwise go to addressbook (other people) store.
else if (IsCACert(pCertContext))
{
// Open the ca store if necessary.
if (!hCertStore)
{
if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"ca")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_CA;
goto CLEANUP;
}
}
hCertStore = hCAStore;
}
else
{
// Open the other people store if necessary.
if (!hAddressBookStore)
{
if(!(hAddressBookStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwCertOpenStoreFlags,
L"addressbook")))
{
dwError = GetLastError();
*pidsStatus = IDS_FAIL_OPEN_ADDRESSBOOK;
goto CLEANUP;
}
}
hCertStore = hAddressBookStore;
}
//DSIE: Bug 22633.
bCancelled = FALSE;
if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT,
pCertImportInfo->hwndParent,
(PVOID) pCertContext,
pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
hCertStore)))
{
if (ERROR_CANCELLED == dwError)
{
bCancelled = TRUE;
}
else
{
// Check to see if there is alreay a read-only duplicated copy in the store?
// If so, ignore the error.
if (pFindCert = CertFindCertificateInStore(hCertStore,
g_dwMsgAndCertEncodingType,
0,
CERT_FIND_EXISTING,
pCertContext,
NULL))
{
CertFreeCertificateContext(pFindCert);
pFindCert = NULL;
}
else if (hCertStore == hMyStore)
{
*pidsStatus = IDS_FAIL_ADD_CERT_MY;
goto CLEANUP;
}
else if (hCertStore == hRootStore)
{
*pidsStatus = IDS_FAIL_ADD_CERT_ROOT;
goto CLEANUP;
}
else if (hCertStore == hCAStore)
{
*pidsStatus = IDS_FAIL_ADD_CERT_CA;
goto CLEANUP;
}
else if (hCertStore == hAddressBookStore)
{
*pidsStatus = IDS_FAIL_ADD_CERT_OTHERPEOPLE;
goto CLEANUP;
}
else if (hCertStore == hTrustedPeopleStore)
{
*pidsStatus = IDS_FAIL_ADD_CERT_TRUSTEDPEOPLE;
goto CLEANUP;
}
}
dwError = 0;
}
pCertPre = pCertContext;
}
if (bCancelled)
{
dwError = ERROR_CANCELLED;
*pidsStatus = IDS_IMPORT_CANCELLED;
}
else
{
*pidsStatus = IDS_IMPORT_SUCCEEDED;
}
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(hMyStore)
CertCloseStore(hMyStore, 0);
if(hCAStore)
CertCloseStore(hCAStore, 0);
if(hTrustStore)
CertCloseStore(hTrustStore, 0);
if(hRootStore)
CertCloseStore(hRootStore, 0);
if(hAddressBookStore)
CertCloseStore(hAddressBookStore, 0);
if(hTrustedPeopleStore)
CertCloseStore(hTrustedPeopleStore, 0);
return HRESULT_FROM_WIN32(dwError);
}
//--------------------------------------------------------------------------------
//
//get the bytes from the file name
//
//---------------------------------------------------------------------------------
HRESULT RetrieveBLOBFromFile(LPWSTR pwszFileName,DWORD *pcb,BYTE **ppb)
{
HRESULT hr=E_FAIL;
HANDLE hFile=NULL;
HANDLE hFileMapping=NULL;
DWORD cbData=0;
BYTE *pbData=0;
DWORD cbHighSize=0;
if(!pcb || !ppb || !pwszFileName)
return E_INVALIDARG;
*ppb=NULL;
*pcb=0;
if ((hFile = ExpandAndCreateFileU(pwszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL, // lpsa
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
if((cbData = GetFileSize(hFile, &cbHighSize)) == 0xffffffff)
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
//we do not handle file more than 4G bytes
if(cbHighSize != 0)
{
hr=E_FAIL;
goto CLEANUP;
}
//create a file mapping object
if(NULL == (hFileMapping=CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL)))
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
//create a view of the file
if(NULL == (pbData=(BYTE *)MapViewOfFile(
hFileMapping,
FILE_MAP_READ,
0,
0,
cbData)))
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
hr=S_OK;
*pcb=cbData;
*ppb=pbData;
CLEANUP:
if(hFile)
CloseHandle(hFile);
if(hFileMapping)
CloseHandle(hFileMapping);
return hr;
}