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

449 lines
12 KiB

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
File: PFXHlpr.cpp
Content: PFX helper routines.
History: 09-15-2001 dsie created
------------------------------------------------------------------------------*/
#include "StdAfx.h"
#include "CAPICOM.h"
#include "PFXHlpr.h"
#include "Common.h"
////////////////////////////////////////////////////////////////////////////////
//
// Local functions.
//
////////////////////////////////////////////////////////////////////////////////
//
// Exported functions.
//
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : PFXExportStore
Synopsis : Export cert store to PFX blob.
Parameter: HCERTSTORE hCertStore - Store handle.
LPWSTR pwszPassword - Password to encrypt the PFX file.
DWPRD dwFlags - PFX export flags.
DATA_BLOB * pPFXBlob - Pointer to DATA_BLOB to receive PFX blob.
Remark :
------------------------------------------------------------------------------*/
HRESULT PFXExportStore (HCERTSTORE hCertStore,
LPWSTR pwszPassword,
DWORD dwFlags,
DATA_BLOB * pPFXBlob)
{
HRESULT hr = S_OK;
DATA_BLOB DataBlob = {0, NULL};
DebugTrace("Entering PFXExportStore().\n");
//
// Sanity check.
//
ATLASSERT(hCertStore);
ATLASSERT(pPFXBlob);
//
// Export to blob.
//
if (!::PFXExportCertStoreEx(hCertStore,
&DataBlob,
pwszPassword,
NULL,
dwFlags))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: PFXExportCertStoreEx() failed.\n", hr);
goto ErrorExit;
}
if (!(DataBlob.pbData = (LPBYTE) ::CoTaskMemAlloc(DataBlob.cbData)))
{
hr = E_OUTOFMEMORY;
DebugTrace("Error: out of memory.\n");
goto ErrorExit;
}
if (!::PFXExportCertStoreEx(hCertStore,
&DataBlob,
pwszPassword,
NULL,
dwFlags))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: PFXExportCertStoreEx() failed.\n", hr);
goto ErrorExit;
}
//
// Return the blob to caller.
//
*pPFXBlob = DataBlob;
CommonExit:
DebugTrace("Leaving PFXExportStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Remap private key not exportable errors to a common error code.
//
if (HRESULT_FROM_WIN32(NTE_BAD_KEY) == hr ||
HRESULT_FROM_WIN32(NTE_BAD_KEY_STATE) == hr ||
HRESULT_FROM_WIN32(NTE_BAD_TYPE) == hr)
{
DebugTrace("Info: Win32 error %#x is remapped to %#x.\n",
hr, CAPICOM_E_PRIVATE_KEY_NOT_EXPORTABLE);
hr = CAPICOM_E_PRIVATE_KEY_NOT_EXPORTABLE;
}
//
// Free resources.
//
if (DataBlob.pbData)
{
::CoTaskMemFree((LPVOID) DataBlob.pbData);
}
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : PFXSaveStore
Synopsis : Save a PFX file and return all the certs in a HCERTSTORE.
Parameter: HCERTSTORE hCertStore - Store handle.
LPWSTR pwszFileName - PFX filename.
LPWSTR pwszPassword - Password to encrypt the PFX file.
DWPRD dwFlags - PFX export flags.
Remark :
------------------------------------------------------------------------------*/
HRESULT PFXSaveStore (HCERTSTORE hCertStore,
LPWSTR pwszFileName,
LPWSTR pwszPassword,
DWORD dwFlags)
{
HRESULT hr = S_OK;
DATA_BLOB DataBlob = {0, NULL};
DebugTrace("Entering PFXSaveStore().\n");
//
// Sanity check.
//
ATLASSERT(hCertStore);
ATLASSERT(pwszFileName);
//
// Export to blob.
//
if (FAILED(hr = ::PFXExportStore(hCertStore,
pwszPassword,
dwFlags,
&DataBlob)))
{
DebugTrace("Error [%#x]: PFXExportStore() failed.\n", hr);
goto ErrorExit;
}
//
// Now write to file.
//
if (FAILED(hr = ::WriteFileContent(pwszFileName, DataBlob)))
{
DebugTrace("Error [%#x]: WriteFileContent() failed.\n", hr);
goto ErrorExit;
}
CommonExit:
//
// Free resources.
//
if (DataBlob.pbData)
{
::CoTaskMemFree(DataBlob.pbData);
}
DebugTrace("Leaving PFXSaveStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : PFXLoadStore
Synopsis : Load a PFX file and return all the certs in a HCERTSTORE.
Parameter: LPWSTR pwszFileName - PFX filename.
LPWSTR pwszPassword - Password to decrypt the PFX file.
DWPRD dwFlags - PFX import flags.
HCERTSTORE * phCertStore - Pointer to HCERSTORE to receive the
handle.
Remark :
------------------------------------------------------------------------------*/
HRESULT PFXLoadStore (LPWSTR pwszFileName,
LPWSTR pwszPassword,
DWORD dwFlags,
HCERTSTORE * phCertStore)
{
HRESULT hr = S_OK;
DATA_BLOB DataBlob = {0, NULL};
HCERTSTORE hCertStore = NULL;
DebugTrace("Entering PFXLoadStore().\n");
//
// Sanity check.
//
ATLASSERT(pwszFileName);
ATLASSERT(phCertStore);
//
// Read content into memory.
//
if (FAILED(hr = ::ReadFileContent(pwszFileName, &DataBlob)))
{
DebugTrace("Error [%#x]: ReadFileContent() failed.\n", hr);
goto ErrorExit;
}
//
// Now import the blob to store.
//
if (!(hCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB *) &DataBlob,
pwszPassword,
dwFlags)))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: PFXImportCertStore() failed.\n", hr);
goto ErrorExit;
}
//
// Return HCERSTORE to caller.
//
*phCertStore = hCertStore;
CommonExit:
//
// Free resources.
//
if (DataBlob.pbData)
{
::UnmapViewOfFile(DataBlob.pbData);
}
DebugTrace("Leaving PFXLoadStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
//
// Free resources.
//
if (hCertStore)
{
::CertCloseStore(hCertStore, 0);
}
goto CommonExit;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function : PFXFreeStore
Synopsis : Free resources by deleting key containers loaded by PFXLoadStore,
and then close the store.
Parameter: HCERTSTORE hCertStore - Store handle returned by PFXLoadStore.
Remark : hCertStore is always closed even if error occurred.
------------------------------------------------------------------------------*/
HRESULT PFXFreeStore (HCERTSTORE hCertStore)
{
HRESULT hr = S_OK;
HCRYPTPROV hCryptProv = NULL;
PCCERT_CONTEXT pCertContext = NULL;
PCRYPT_KEY_PROV_INFO pKeyProvInfo = NULL;
DebugTrace("Entering PFXFreeStore().\n");
//
// Sanity check.
//
ATLASSERT(hCertStore);
//
// Now delete all key containers.
//
while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
{
DWORD cbData = 0;
//
// Retrieve key container info.
//
if (!::CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL,
&cbData))
{
continue;
}
if (!(pKeyProvInfo = (CRYPT_KEY_PROV_INFO *) ::CoTaskMemAlloc(cbData)))
{
hr = E_OUTOFMEMORY;
DebugTrace("Error: out of memory.\n");
goto ErrorExit;
}
if (!::CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
pKeyProvInfo,
&cbData))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertGetCertificateContextProperty() failed.\n", hr);
goto ErrorExit;
}
//
// First disassociate the key from the cert.
//
if (!::CertSetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
0,
NULL))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertSetCertificateContextProperty() failed to disassociate key container.\n", hr);
goto ErrorExit;
}
//
// Then delete the key container.
//
if (FAILED (hr = ::AcquireContext(pKeyProvInfo->pwszProvName,
pKeyProvInfo->pwszContainerName,
pKeyProvInfo->dwProvType,
CRYPT_DELETEKEYSET | (pKeyProvInfo->dwFlags & CRYPT_MACHINE_KEYSET),
FALSE,
&hCryptProv)))
{
DebugTrace("Error [%#x]: AcquireContext(CRYPT_DELETEKEYSET) failed .\n", hr);
goto ErrorExit;
}
::CoTaskMemFree((LPVOID) pKeyProvInfo), pKeyProvInfo = NULL;
//
// Don'f free cert context here, as CertEnumCertificatesInStore()
// will do that automatically!!!
//
}
//
// Above loop can exit either because there is no more certificate in
// the store or an error. Need to check last error to be certain.
//
if (CRYPT_E_NOT_FOUND != ::GetLastError())
{
hr = HRESULT_FROM_WIN32(::GetLastError());
DebugTrace("Error [%#x]: CertEnumCertificatesInStore() failed.\n", hr);
goto ErrorExit;
}
CommonExit:
//
// Free resources.
//
if (pKeyProvInfo)
{
::CoTaskMemFree((LPVOID) pKeyProvInfo);
}
if (pCertContext)
{
::CertFreeCertificateContext(pCertContext);
}
if (hCertStore)
{
::CertCloseStore(hCertStore, 0);
}
DebugTrace("Leaving PFXFreeStore().\n");
return hr;
ErrorExit:
//
// Sanity check.
//
ATLASSERT(FAILED(hr));
goto CommonExit;
}