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
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;
|
|
}
|