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.
 
 
 
 
 
 

1384 lines
42 KiB

//+-------------------------------------------------------------------------
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1997
//
// File: textstor.cpp
//
// Contents: Test External Certificate Store Provider
//
// Functions: DllRegisterServer
// DllUnregisterServer
// DllMain
// DllCanUnloadNow
// I_CertDllOpenTestExtStoreProvW
//
// History: 09-Sep-97 philh created
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
// # of bytes for a hash. Such as, SHA (20) or MD5 (16)
#define MAX_HASH_LEN 20
static HMODULE hMyModule;
#define sz_CERT_STORE_PROV_TEST_EXT "TestExt"
#define TEST_EXT_OPEN_STORE_PROV_FUNC "I_CertDllOpenTestExtStoreProvW"
//+-------------------------------------------------------------------------
// External Store Provider handle information
//--------------------------------------------------------------------------
typedef struct _FIND_EXT_INFO FIND_EXT_INFO, *PFIND_EXT_INFO;
struct _FIND_EXT_INFO {
DWORD dwContextType;
void *pvContext;
};
typedef struct _EXT_STORE {
HCERTSTORE hExtCertStore;
} EXT_STORE, *PEXT_STORE;
//+-------------------------------------------------------------------------
// External Store Provider Functions.
//--------------------------------------------------------------------------
static void WINAPI ExtStoreProvClose(
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvReadCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pStoreCertContext,
IN DWORD dwFlags,
OUT PCCERT_CONTEXT *ppProvCertContext
);
static BOOL WINAPI ExtStoreProvWriteCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvDeleteCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvSetCertProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
);
static BOOL WINAPI ExtStoreProvReadCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pStoreCrlContext,
IN DWORD dwFlags,
OUT PCCRL_CONTEXT *ppProvCrlContext
);
static BOOL WINAPI ExtStoreProvWriteCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvDeleteCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvSetCrlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
);
static BOOL WINAPI ExtStoreProvReadCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pStoreCtlContext,
IN DWORD dwFlags,
OUT PCCTL_CONTEXT *ppProvCtlContext
);
static BOOL WINAPI ExtStoreProvWriteCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvDeleteCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvSetCtlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
);
static BOOL WINAPI ExtStoreProvControl(
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags,
IN DWORD dwCtrlType,
IN void const *pvCtrlPara
);
static BOOL WINAPI ExtStoreProvFindCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCERT_CONTEXT pPrevCertContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCERT_CONTEXT *ppProvCertContext
);
static BOOL WINAPI ExtStoreProvFreeFindCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvGetCertProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
);
static BOOL WINAPI ExtStoreProvFindCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCRL_CONTEXT pPrevCrlContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCRL_CONTEXT *ppProvCrlContext
);
static BOOL WINAPI ExtStoreProvFreeFindCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvGetCrlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
);
static BOOL WINAPI ExtStoreProvFindCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCTL_CONTEXT pPrevCtlContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCTL_CONTEXT *ppProvCtlContext
);
static BOOL WINAPI ExtStoreProvFreeFindCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
);
static BOOL WINAPI ExtStoreProvGetCtlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
);
static void * const rgpvExtStoreProvFunc[] = {
// CERT_STORE_PROV_CLOSE_FUNC 0
ExtStoreProvClose,
// CERT_STORE_PROV_READ_CERT_FUNC 1
ExtStoreProvReadCert,
// CERT_STORE_PROV_WRITE_CERT_FUNC 2
ExtStoreProvWriteCert,
// CERT_STORE_PROV_DELETE_CERT_FUNC 3
ExtStoreProvDeleteCert,
// CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC 4
ExtStoreProvSetCertProperty,
// CERT_STORE_PROV_READ_CRL_FUNC 5
ExtStoreProvReadCrl,
// CERT_STORE_PROV_WRITE_CRL_FUNC 6
ExtStoreProvWriteCrl,
// CERT_STORE_PROV_DELETE_CRL_FUNC 7
ExtStoreProvDeleteCrl,
// CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC 8
ExtStoreProvSetCrlProperty,
// CERT_STORE_PROV_READ_CTL_FUNC 9
ExtStoreProvReadCtl,
// CERT_STORE_PROV_WRITE_CTL_FUNC 10
ExtStoreProvWriteCtl,
// CERT_STORE_PROV_DELETE_CTL_FUNC 11
ExtStoreProvDeleteCtl,
// CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC 12
ExtStoreProvSetCtlProperty,
// CERT_STORE_PROV_CONTROL_FUNC 13
ExtStoreProvControl,
// CERT_STORE_PROV_FIND_CERT_FUNC 14
ExtStoreProvFindCert,
// CERT_STORE_PROV_FREE_FIND_CERT_FUNC 15
ExtStoreProvFreeFindCert,
// CERT_STORE_PROV_GET_CERT_PROPERTY_FUNC 16
ExtStoreProvGetCertProperty,
// CERT_STORE_PROV_FIND_CRL_FUNC 17
ExtStoreProvFindCrl,
// CERT_STORE_PROV_FREE_FIND_CRL_FUNC 18
ExtStoreProvFreeFindCrl,
// CERT_STORE_PROV_GET_CRL_PROPERTY_FUNC 19
ExtStoreProvGetCrlProperty,
// CERT_STORE_PROV_FIND_CTL_FUNC 20
ExtStoreProvFindCtl,
// CERT_STORE_PROV_FREE_FIND_CTL_FUNC 21
ExtStoreProvFreeFindCtl,
// CERT_STORE_PROV_GET_CTL_PROPERTY_FUNC 22
ExtStoreProvGetCtlProperty
};
#define EXT_STORE_PROV_FUNC_COUNT (sizeof(rgpvExtStoreProvFunc) / \
sizeof(rgpvExtStoreProvFunc[0]))
//+-------------------------------------------------------------------------
// CertStore allocation and free functions
//--------------------------------------------------------------------------
static void *CSAlloc(
IN size_t cbBytes
)
{
void *pv;
pv = malloc(cbBytes);
if (pv == NULL)
SetLastError((DWORD) E_OUTOFMEMORY);
return pv;
}
static void *CSRealloc(
IN void *pvOrg,
IN size_t cbBytes
)
{
void *pv;
if (NULL == (pv = pvOrg ? realloc(pvOrg, cbBytes) : malloc(cbBytes)))
SetLastError((DWORD) E_OUTOFMEMORY);
return pv;
}
static void CSFree(
IN void *pv
)
{
if (pv)
free(pv);
}
//+-------------------------------------------------------------------------
// Create, add, remove and free external store find info functions
//--------------------------------------------------------------------------
static PFIND_EXT_INFO CreateExtInfo(
IN DWORD dwContextType,
IN void *pvContext // already AddRef'ed
)
{
PFIND_EXT_INFO pFindExtInfo;
if (pFindExtInfo = (PFIND_EXT_INFO) CSAlloc(sizeof(FIND_EXT_INFO))) {
pFindExtInfo->dwContextType = dwContextType;
pFindExtInfo->pvContext = pvContext;
}
return pFindExtInfo;
}
static void FreeExtInfo(
IN PFIND_EXT_INFO pFindExtInfo
)
{
void *pvContext;
if (NULL == pFindExtInfo)
return;
pvContext = pFindExtInfo->pvContext;
if (pvContext) {
switch (pFindExtInfo->dwContextType) {
case (CERT_STORE_CERTIFICATE_CONTEXT - 1):
CertFreeCertificateContext((PCCERT_CONTEXT) pvContext);
break;
case (CERT_STORE_CRL_CONTEXT - 1):
CertFreeCRLContext((PCCRL_CONTEXT) pvContext);
break;
case (CERT_STORE_CTL_CONTEXT - 1):
CertFreeCTLContext((PCCTL_CONTEXT) pvContext);
break;
default:
assert(pFindExtInfo->dwContextType < CERT_STORE_CTL_CONTEXT);
}
}
CSFree(pFindExtInfo);
}
//+-------------------------------------------------------------------------
// Dll initialization
//--------------------------------------------------------------------------
BOOL
WINAPI
DllMain(
HMODULE hModule,
ULONG ulReason,
LPVOID lpReserved)
{
switch (ulReason) {
case DLL_PROCESS_ATTACH:
hMyModule = hModule;
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
}
STDAPI DllCanUnloadNow(void)
{
// Return S_FALSE inhibit unloading.
// return S_FALSE;
return S_OK;
}
static HRESULT HError()
{
DWORD dw = GetLastError();
HRESULT hr;
if ( dw <= 0xFFFF )
hr = HRESULT_FROM_WIN32 ( dw );
else
hr = dw;
if ( ! FAILED ( hr ) )
{
// somebody failed a call without properly setting an error condition
hr = E_UNEXPECTED;
}
return hr;
}
static HRESULT GetDllFilename(
OUT WCHAR wszModule[_MAX_PATH]
)
{
char szModule[_MAX_PATH];
LPSTR pszModule;
int cchModule;
// Get name of this DLL.
if (0 == GetModuleFileNameA(hMyModule, szModule, _MAX_PATH))
return HError();
// Strip off the Dll filename's directory components
cchModule = strlen(szModule);
pszModule = szModule + cchModule;
while (cchModule-- > 0) {
pszModule--;
if ('\\' == *pszModule || ':' == *pszModule) {
pszModule++;
break;
}
}
if (0 >= MultiByteToWideChar(
CP_ACP,
0, // dwFlags
pszModule,
-1, // null terminated
wszModule,
_MAX_PATH))
return HError();
return S_OK;
}
//+-------------------------------------------------------------------------
// DllRegisterServer
//--------------------------------------------------------------------------
STDAPI DllRegisterServer(void)
{
HRESULT hr;
WCHAR wszModule[_MAX_PATH];
if (FAILED(hr = GetDllFilename(wszModule)))
return hr;
if (!CryptRegisterOIDFunction(
0, // dwEncodingType
CRYPT_OID_OPEN_STORE_PROV_FUNC,
sz_CERT_STORE_PROV_TEST_EXT,
wszModule,
TEST_EXT_OPEN_STORE_PROV_FUNC
)) {
if (ERROR_FILE_EXISTS != GetLastError())
return HError();
}
return S_OK;
}
//+-------------------------------------------------------------------------
// DllUnregisterServer
//--------------------------------------------------------------------------
STDAPI DllUnregisterServer(void)
{
HRESULT hr;
WCHAR wszModule[_MAX_PATH];
if (FAILED(hr = GetDllFilename(wszModule)))
return hr;
if (!CryptUnregisterOIDFunction(
0, // dwEncodingType
CRYPT_OID_OPEN_STORE_PROV_FUNC,
sz_CERT_STORE_PROV_TEST_EXT
)) {
if (ERROR_FILE_NOT_FOUND != GetLastError())
return HError();
}
return S_OK;
}
//+-------------------------------------------------------------------------
// Implement the "test" external store by opening the corresponding system
// registry store.
//--------------------------------------------------------------------------
BOOL
WINAPI
I_CertDllOpenTestExtStoreProvW(
IN LPCSTR lpszStoreProvider,
IN DWORD dwEncodingType,
IN HCRYPTPROV hCryptProv,
IN DWORD dwFlags,
IN const void *pvPara,
IN HCERTSTORE hCertStore,
IN OUT PCERT_STORE_PROV_INFO pStoreProvInfo
)
{
BOOL fResult;
PEXT_STORE pExtStore = NULL;
if (0 == (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK))
dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER;
dwFlags |= CERT_STORE_NO_CRYPT_RELEASE_FLAG;
if (dwFlags & CERT_STORE_DELETE_FLAG) {
CertOpenStore(
CERT_STORE_PROV_SYSTEM_W,
dwEncodingType,
hCryptProv,
dwFlags,
pvPara
);
pStoreProvInfo->dwStoreProvFlags |= CERT_STORE_PROV_DELETED_FLAG;
if (0 == GetLastError())
return TRUE;
else
return FALSE;
}
if (NULL == (pExtStore = (PEXT_STORE) CSAlloc(sizeof(EXT_STORE))))
goto OutOfMemory;
memset(pExtStore, 0, sizeof(EXT_STORE));
if (NULL == (pExtStore->hExtCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_W,
dwEncodingType,
hCryptProv,
dwFlags,
pvPara
)))
goto OpenStoreError;
pStoreProvInfo->cStoreProvFunc = EXT_STORE_PROV_FUNC_COUNT;
pStoreProvInfo->rgpvStoreProvFunc = (void **) rgpvExtStoreProvFunc;
pStoreProvInfo->hStoreProv = (HCERTSTOREPROV) pExtStore;
pStoreProvInfo->dwStoreProvFlags |= CERT_STORE_PROV_EXTERNAL_FLAG;
fResult = TRUE;
CommonReturn:
return fResult;
ErrorReturn:
ExtStoreProvClose((HCERTSTOREPROV) pExtStore, 0);
fResult = FALSE;
goto CommonReturn;
TRACE_ERROR(OutOfMemory)
TRACE_ERROR(OpenStoreError)
}
//+-------------------------------------------------------------------------
// Close the registry's store by closing its opened registry subkeys
//--------------------------------------------------------------------------
static void WINAPI ExtStoreProvClose(
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
if (pExtStore) {
if (pExtStore->hExtCertStore)
CertCloseStore(pExtStore->hExtCertStore, 0);
CSFree(pExtStore);
}
}
//+---------------------------------------------------------------------------
// Find certificate in system store corresponding to pCertContext
//----------------------------------------------------------------------------
static PCCERT_CONTEXT FindCorrespondingCertificate (
IN HCERTSTORE hExtCertStore,
IN PCCERT_CONTEXT pCertContext
)
{
DWORD cbHash = MAX_HASH_LEN;
BYTE aHash[MAX_HASH_LEN];
CRYPT_HASH_BLOB HashBlob;
if ( CertGetCertificateContextProperty(
pCertContext,
CERT_HASH_PROP_ID,
aHash,
&cbHash
) == FALSE )
{
return( NULL );
}
HashBlob.cbData = cbHash;
HashBlob.pbData = aHash;
return( CertFindCertificateInStore(
hExtCertStore,
X509_ASN_ENCODING,
0,
CERT_FIND_HASH,
&HashBlob,
NULL
) );
}
//+---------------------------------------------------------------------------
// Find CRL in system store corresponding to pCrlContext
//----------------------------------------------------------------------------
static PCCRL_CONTEXT FindCorrespondingCrl (
IN HCERTSTORE hExtCertStore,
IN PCCRL_CONTEXT pCrlContext
)
{
DWORD cbHash = MAX_HASH_LEN;
BYTE aHash[MAX_HASH_LEN];
DWORD cbFindHash = MAX_HASH_LEN;
BYTE aFindHash[MAX_HASH_LEN];
PCCRL_CONTEXT pFindCrl = NULL;
DWORD dwFlags = 0;
if ( CertGetCRLContextProperty(
pCrlContext,
CERT_HASH_PROP_ID,
aHash,
&cbHash
) == FALSE )
{
return( NULL );
}
while ( ( pFindCrl = CertGetCRLFromStore(
hExtCertStore,
NULL,
pFindCrl,
&dwFlags
) ) != NULL )
{
if ( CertGetCRLContextProperty(
pFindCrl,
CERT_HASH_PROP_ID,
aFindHash,
&cbFindHash
) == TRUE )
{
if ( cbHash == cbFindHash )
{
if ( memcmp( aHash, aFindHash, cbHash ) == 0 )
{
return( pFindCrl );
}
}
}
}
return( NULL );
}
//+---------------------------------------------------------------------------
// Find CTL in system store corresponding to pCtlContext
//----------------------------------------------------------------------------
static PCCTL_CONTEXT FindCorrespondingCtl (
IN HCERTSTORE hExtCertStore,
IN PCCTL_CONTEXT pCtlContext
)
{
DWORD cbHash = MAX_HASH_LEN;
BYTE aHash[MAX_HASH_LEN];
CRYPT_HASH_BLOB HashBlob;
if ( CertGetCTLContextProperty(
pCtlContext,
CERT_SHA1_HASH_PROP_ID,
aHash,
&cbHash
) == FALSE )
{
return( NULL );
}
HashBlob.cbData = cbHash;
HashBlob.pbData = aHash;
return( CertFindCTLInStore(
hExtCertStore,
X509_ASN_ENCODING,
0,
CTL_FIND_SHA1_HASH,
&HashBlob,
NULL
) );
}
//+-------------------------------------------------------------------------
// Read the serialized copy of the certificate and its properties from
// the registry and create a new certificate context.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvReadCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pStoreCertContext,
IN DWORD dwFlags,
OUT PCCERT_CONTEXT *ppProvCertContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCERT_CONTEXT pProvCertContext;
assert(pExtStore && pExtStore->hExtCertStore);
pProvCertContext = FindCorrespondingCertificate(
pExtStore->hExtCertStore, pStoreCertContext);
*ppProvCertContext = pProvCertContext;
return NULL != pProvCertContext;
}
//+-------------------------------------------------------------------------
// Serialize the encoded certificate and its properties and write to
// the registry.
//
// Called before the certificate is written to the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvWriteCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
DWORD dwAddDisposition;
assert(pExtStore && pExtStore->hExtCertStore);
if (dwFlags & CERT_STORE_PROV_WRITE_ADD_FLAG)
dwAddDisposition = (dwFlags >> 16) & 0xFFFF;
else
dwAddDisposition = 0;
return CertAddCertificateContextToStore(
pExtStore->hExtCertStore,
pCertContext,
dwAddDisposition,
NULL // ppStoreContext
);
}
//+-------------------------------------------------------------------------
// Delete the specified certificate from the registry.
//
// Called before the certificate is deleted from the store.
//+-------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvDeleteCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCERT_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCertificate(
pExtStore->hExtCertStore, pCertContext))
return CertDeleteCertificateFromStore(pExtContext);
else
return FALSE;
}
//+-------------------------------------------------------------------------
// Read the specified certificate from the registry and update its
// property.
//
// Note, ignore the CERT_SHA1_HASH_PROP_ID property which is implicitly
// set before we write the certificate to the registry. If we don't ignore,
// we will have indefinite recursion.
//
// Called before setting the property of the certificate in the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvSetCertProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCERT_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCertificate(
pExtStore->hExtCertStore, pCertContext)) {
BOOL fResult;
fResult = CertSetCertificateContextProperty(
pExtContext,
dwPropId,
dwFlags,
pvData
);
CertFreeCertificateContext(pExtContext);
return fResult;
} else
return FALSE;
}
//+-------------------------------------------------------------------------
// Read the serialized copy of the CRL and its properties from
// the registry and create a new CRL context.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvReadCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pStoreCrlContext,
IN DWORD dwFlags,
OUT PCCRL_CONTEXT *ppProvCrlContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCRL_CONTEXT pProvCrlContext;
assert(pExtStore && pExtStore->hExtCertStore);
pProvCrlContext = FindCorrespondingCrl(
pExtStore->hExtCertStore, pStoreCrlContext);
*ppProvCrlContext = pProvCrlContext;
return NULL != pProvCrlContext;
}
//+-------------------------------------------------------------------------
// Serialize the encoded CRL and its properties and write to
// the registry.
//
// Called before the CRL is written to the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvWriteCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
DWORD dwAddDisposition;
assert(pExtStore && pExtStore->hExtCertStore);
if (dwFlags & CERT_STORE_PROV_WRITE_ADD_FLAG)
dwAddDisposition = (dwFlags >> 16) & 0xFFFF;
else
dwAddDisposition = 0;
return CertAddCRLContextToStore(
pExtStore->hExtCertStore,
pCrlContext,
dwAddDisposition,
NULL // ppStoreContext
);
}
//+-------------------------------------------------------------------------
// Delete the specified CRL from the registry.
//
// Called before the CRL is deleted from the store.
//+-------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvDeleteCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCRL_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCrl(
pExtStore->hExtCertStore, pCrlContext))
return CertDeleteCRLFromStore(pExtContext);
else
return FALSE;
}
//+-------------------------------------------------------------------------
// Read the specified CRL from the registry and update its
// property.
//
// Note, ignore the CERT_SHA1_HASH_PROP_ID property which is implicitly
// set before we write the CRL to the registry. If we don't ignore,
// we will have indefinite recursion.
//
// Called before setting the property of the CRL in the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvSetCrlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCRL_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCrl(
pExtStore->hExtCertStore, pCrlContext)) {
BOOL fResult;
fResult = CertSetCRLContextProperty(
pExtContext,
dwPropId,
dwFlags,
pvData
);
CertFreeCRLContext(pExtContext);
return fResult;
} else
return FALSE;
}
//+-------------------------------------------------------------------------
// Read the serialized copy of the CTL and its properties from
// the registry and create a new CTL context.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvReadCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pStoreCtlContext,
IN DWORD dwFlags,
OUT PCCTL_CONTEXT *ppProvCtlContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCTL_CONTEXT pProvCtlContext;
assert(pExtStore && pExtStore->hExtCertStore);
pProvCtlContext = FindCorrespondingCtl(
pExtStore->hExtCertStore, pStoreCtlContext);
*ppProvCtlContext = pProvCtlContext;
return NULL != pProvCtlContext;
}
//+-------------------------------------------------------------------------
// Serialize the encoded CTL and its properties and write to
// the registry.
//
// Called before the CTL is written to the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvWriteCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
DWORD dwAddDisposition;
assert(pExtStore && pExtStore->hExtCertStore);
if (dwFlags & CERT_STORE_PROV_WRITE_ADD_FLAG)
dwAddDisposition = (dwFlags >> 16) & 0xFFFF;
else
dwAddDisposition = 0;
return CertAddCTLContextToStore(
pExtStore->hExtCertStore,
pCtlContext,
dwAddDisposition,
NULL // ppStoreContext
);
}
//+-------------------------------------------------------------------------
// Delete the specified CTL from the registry.
//
// Called before the CTL is deleted from the store.
//+-------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvDeleteCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCTL_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCtl(
pExtStore->hExtCertStore, pCtlContext))
return CertDeleteCTLFromStore(pExtContext);
else
return FALSE;
}
//+-------------------------------------------------------------------------
// Read the specified CTL from the registry and update its
// property.
//
// Note, ignore the CERT_SHA1_HASH_PROP_ID property which is implicitly
// set before we write the CTL to the registry. If we don't ignore,
// we will have indefinite recursion.
//
// Called before setting the property of the CTL in the store.
//--------------------------------------------------------------------------
static BOOL WINAPI ExtStoreProvSetCtlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void *pvData
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PCCTL_CONTEXT pExtContext;
assert(pExtStore && pExtStore->hExtCertStore);
if (pExtContext = FindCorrespondingCtl(
pExtStore->hExtCertStore, pCtlContext)) {
BOOL fResult;
fResult = CertSetCTLContextProperty(
pExtContext,
dwPropId,
dwFlags,
pvData
);
CertFreeCTLContext(pExtContext);
return fResult;
} else
return FALSE;
}
static BOOL WINAPI ExtStoreProvControl(
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags,
IN DWORD dwCtrlType,
IN void const *pvCtrlPara
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
assert(pExtStore && pExtStore->hExtCertStore);
return CertControlStore(
pExtStore->hExtCertStore,
dwFlags,
dwCtrlType,
pvCtrlPara
);
}
static BOOL WINAPI ExtStoreProvFindCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCERT_CONTEXT pPrevCertContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCERT_CONTEXT *ppProvCertContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) *ppvStoreProvFindInfo;
PCCERT_CONTEXT pPrevExtContext;
PCCERT_CONTEXT pProvCertContext;
if (pFindExtInfo) {
assert((CERT_STORE_CERTIFICATE_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
pPrevExtContext = (PCCERT_CONTEXT) pFindExtInfo->pvContext;
pFindExtInfo->pvContext = NULL;
} else
pPrevExtContext = NULL;
assert(pExtStore);
assert(pPrevCertContext == pPrevExtContext);
if (pProvCertContext = CertFindCertificateInStore(
pExtStore->hExtCertStore,
pFindInfo->dwMsgAndCertEncodingType,
pFindInfo->dwFindFlags,
pFindInfo->dwFindType,
pFindInfo->pvFindPara,
pPrevExtContext
)) {
if (pFindExtInfo)
// Re-use existing Find Info
pFindExtInfo->pvContext = (void *) CertDuplicateCertificateContext(
pProvCertContext);
else {
if (pFindExtInfo = CreateExtInfo(
CERT_STORE_CERTIFICATE_CONTEXT - 1,
(void *) pProvCertContext
))
pProvCertContext = CertDuplicateCertificateContext(
pProvCertContext);
else {
CertFreeCertificateContext(pProvCertContext);
pProvCertContext = NULL;
}
}
} else if (pFindExtInfo) {
ExtStoreProvFreeFindCert(
hStoreProv,
pPrevCertContext,
pFindExtInfo,
0 // dwFlags
);
pFindExtInfo = NULL;
}
*ppProvCertContext = pProvCertContext;
*ppvStoreProvFindInfo = pFindExtInfo;
return NULL != pProvCertContext;
}
static BOOL WINAPI ExtStoreProvFreeFindCert(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
)
{
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) pvStoreProvFindInfo;
assert(pFindExtInfo);
if (pFindExtInfo) {
assert((CERT_STORE_CERTIFICATE_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
FreeExtInfo(pFindExtInfo);
}
return TRUE;
}
static BOOL WINAPI ExtStoreProvGetCertProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
)
{
*pcbData = 0;
SetLastError((DWORD) CRYPT_E_NOT_FOUND);
return FALSE;
}
static PCCRL_CONTEXT WINAPI FindCrlInStore(
IN HCERTSTORE hCertStore,
IN DWORD dwCertEncodingType,
IN DWORD dwFindFlags,
IN DWORD dwFindType,
IN const void *pvFindPara,
IN PCCRL_CONTEXT pPrevCrlContext
)
{
DWORD dwFlags = 0;
switch (dwFindType) {
case CRL_FIND_ANY:
return CertGetCRLFromStore(
hCertStore,
NULL, // pIssuerContext,
pPrevCrlContext,
&dwFlags
);
break;
case CRL_FIND_ISSUED_BY:
{
PCCERT_CONTEXT pIssuer = (PCCERT_CONTEXT) pvFindPara;
return CertGetCRLFromStore(
hCertStore,
pIssuer,
pPrevCrlContext,
&dwFlags
);
}
break;
case CRL_FIND_EXISTING:
{
PCCRL_CONTEXT pCrl = pPrevCrlContext;
while (pCrl = CertGetCRLFromStore(
hCertStore,
NULL, // pIssuerContext,
pCrl,
&dwFlags)) {
PCCRL_CONTEXT pNew = (PCCRL_CONTEXT) pvFindPara;
if (pNew->dwCertEncodingType == pCrl->dwCertEncodingType &&
CertCompareCertificateName(
pNew->dwCertEncodingType,
&pCrl->pCrlInfo->Issuer,
&pNew->pCrlInfo->Issuer))
return pCrl;
}
return NULL;
}
break;
default:
SetLastError((DWORD) ERROR_NOT_SUPPORTED);
return NULL;
}
}
static BOOL WINAPI ExtStoreProvFindCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCRL_CONTEXT pPrevCrlContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCRL_CONTEXT *ppProvCrlContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) *ppvStoreProvFindInfo;
PCCRL_CONTEXT pPrevExtContext;
PCCRL_CONTEXT pProvCrlContext;
if (pFindExtInfo) {
assert((CERT_STORE_CRL_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
pPrevExtContext = (PCCRL_CONTEXT) pFindExtInfo->pvContext;
pFindExtInfo->pvContext = NULL;
} else
pPrevExtContext = NULL;
assert(pExtStore);
assert(pPrevCrlContext == pPrevExtContext);
if (pProvCrlContext = FindCrlInStore(
pExtStore->hExtCertStore,
pFindInfo->dwMsgAndCertEncodingType,
pFindInfo->dwFindFlags,
pFindInfo->dwFindType,
pFindInfo->pvFindPara,
pPrevExtContext
)) {
if (pFindExtInfo)
// Re-use existing Find Info
pFindExtInfo->pvContext = (void *) CertDuplicateCRLContext(
pProvCrlContext);
else {
if (pFindExtInfo = CreateExtInfo(
CERT_STORE_CRL_CONTEXT - 1,
(void *) pProvCrlContext
))
pProvCrlContext = CertDuplicateCRLContext(
pProvCrlContext);
else {
CertFreeCRLContext(pProvCrlContext);
pProvCrlContext = NULL;
}
}
} else if (pFindExtInfo) {
ExtStoreProvFreeFindCrl(
hStoreProv,
pPrevCrlContext,
pFindExtInfo,
0 // dwFlags
);
pFindExtInfo = NULL;
}
*ppProvCrlContext = pProvCrlContext;
*ppvStoreProvFindInfo = pFindExtInfo;
return NULL != pProvCrlContext;
}
static BOOL WINAPI ExtStoreProvFreeFindCrl(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
)
{
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) pvStoreProvFindInfo;
assert(pFindExtInfo);
if (pFindExtInfo) {
assert((CERT_STORE_CRL_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
FreeExtInfo(pFindExtInfo);
}
return TRUE;
}
static BOOL WINAPI ExtStoreProvGetCrlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
)
{
*pcbData = 0;
SetLastError((DWORD) CRYPT_E_NOT_FOUND);
return FALSE;
}
static BOOL WINAPI ExtStoreProvFindCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCTL_CONTEXT pPrevCtlContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCTL_CONTEXT *ppProvCtlContext
)
{
PEXT_STORE pExtStore = (PEXT_STORE) hStoreProv;
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) *ppvStoreProvFindInfo;
PCCTL_CONTEXT pPrevExtContext;
PCCTL_CONTEXT pProvCtlContext;
if (pFindExtInfo) {
assert((CERT_STORE_CTL_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
pPrevExtContext = (PCCTL_CONTEXT) pFindExtInfo->pvContext;
pFindExtInfo->pvContext = NULL;
} else
pPrevExtContext = NULL;
assert(pExtStore);
assert(pPrevCtlContext == pPrevExtContext);
if (pProvCtlContext = CertFindCTLInStore(
pExtStore->hExtCertStore,
pFindInfo->dwMsgAndCertEncodingType,
pFindInfo->dwFindFlags,
pFindInfo->dwFindType,
pFindInfo->pvFindPara,
pPrevExtContext
)) {
if (pFindExtInfo)
// Re-use existing Find Info
pFindExtInfo->pvContext = (void *) CertDuplicateCTLContext(
pProvCtlContext);
else {
if (pFindExtInfo = CreateExtInfo(
CERT_STORE_CTL_CONTEXT - 1,
(void *) pProvCtlContext
))
pProvCtlContext = CertDuplicateCTLContext(pProvCtlContext);
else {
CertFreeCTLContext(pProvCtlContext);
pProvCtlContext = NULL;
}
}
} else if (pFindExtInfo) {
ExtStoreProvFreeFindCtl(
hStoreProv,
pPrevCtlContext,
pFindExtInfo,
0 // dwFlags
);
pFindExtInfo = NULL;
}
*ppProvCtlContext = pProvCtlContext;
*ppvStoreProvFindInfo = pFindExtInfo;
return NULL != pProvCtlContext;
}
static BOOL WINAPI ExtStoreProvFreeFindCtl(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
)
{
PFIND_EXT_INFO pFindExtInfo = (PFIND_EXT_INFO) pvStoreProvFindInfo;
assert(pFindExtInfo);
if (pFindExtInfo) {
assert((CERT_STORE_CTL_CONTEXT - 1) ==
pFindExtInfo->dwContextType);
FreeExtInfo(pFindExtInfo);
}
return TRUE;
}
static BOOL WINAPI ExtStoreProvGetCtlProperty(
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
)
{
*pcbData = 0;
SetLastError((DWORD) CRYPT_E_NOT_FOUND);
return FALSE;
}