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.
 
 
 
 
 
 

2938 lines
68 KiB

/*++
Copyright (C) Microsoft Corporation, 2001
Module Name:
csplib.c
General Cryptographic Service Provider Library
Abstract:
Author:
Dan Griffin
Notes:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <psapi.h>
#include <rpc.h>
#include <wincrypt.h>
#include <dsysdbg.h>
#include <stdio.h>
#include "csplib.h"
//
// This global must be provided by the "Local" CSP using this library.
//
extern LOCAL_CSP_INFO LocalCspInfo;
#define PROVPATH L"SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\"
//
// DllInitialize stores the image path in here during process attach.
//
CHAR l_szImagePath[MAX_PATH];
//
// Debug Support
//
// This uses the debug routines from dsysdbg.h
// Debug output will only be available in chk
// bits.
//
DEFINE_DEBUG2(Csplib)
#if DBG
#define DebugLog(x) CsplibDebugPrint x
#else
#define DebugLog(x)
#endif
#define DEB_ERROR 0x00000001
#define DEB_WARN 0x00000002
#define DEB_TRACE 0x00000004
#define DEB_TRACE_FUNC 0x00000080
#define DEB_TRACE_MEM 0x00000100
#define TRACE_STUFF 0x00000200
static DEBUG_KEY MyDebugKeys[] =
{
{DEB_ERROR, "Error"},
{DEB_WARN, "Warning"},
{DEB_TRACE, "Trace"},
{DEB_TRACE_FUNC, "TraceFuncs"},
{DEB_TRACE_MEM, "TraceMem"},
{0, NULL}
};
#define LOG_BEGIN_FUNCTION(x) \
{ DebugLog((DEB_TRACE_FUNC, "%s: Entering\n", #x)); }
#define LOG_END_FUNCTION(x, y) \
{ DebugLog((DEB_TRACE_FUNC, "%s: Leaving, status: 0x%x\n", #x, y)); }
#define LOG_CHECK_ALLOC(x) \
{ if (NULL == x) { \
dwSts = ERROR_NOT_ENOUGH_MEMORY; \
DebugLog((DEB_TRACE_MEM, "%s: Allocation failed\n", #x)); \
goto Ret; \
} }
//
// Function: ApplyPKCS1SigningFormat
//
// Purpose: Format a buffer with PKCS 1 for signing
//
// Notes:
// If the padding and formatting is successful, the *ppbPKCS1Format parameter
// will be allocated by this routine and must be freed by the caller.
//
DWORD WINAPI ApplyPKCS1SigningFormat(
IN ALG_ID HashAlgid,
IN BYTE *pbHash,
IN DWORD cbHash,
IN DWORD dwFlags,
IN DWORD cbModulus,
OUT PBYTE *ppbPKCS1Format)
{
DWORD dwSts = ERROR_SUCCESS;
BYTE *pbStart = NULL;
BYTE *pbEnd = NULL;
BYTE bTmp = 0;
DWORD i = 0;
DWORD cbAvailableData = cbModulus; // pPubKey->datalen;
*ppbPKCS1Format = NULL;
//
// We know we need at least 3 bytes of padding space.
//
// Note, the final (third) byte of padding is the zeroed-byte at
// location pbPKCS1Format[cbModulus - 1].
//
cbAvailableData -= 3;
// In a few scenarios (involving small RSA keys), the new large SHA
// hashes are too big to be signed by the specified key.
if (cbHash > cbAvailableData)
{
dwSts = (DWORD) NTE_BAD_LEN;
goto Ret;
}
*ppbPKCS1Format = (PBYTE) CspAllocH(cbModulus);
LOG_CHECK_ALLOC(*ppbPKCS1Format);
// insert the block type
(*ppbPKCS1Format)[cbModulus - 2] = 0x01; // Padding byte #1
// insert the type I padding
memset(*ppbPKCS1Format, 0xff, cbModulus - 2);
// Reverse it
for (i = 0; i < cbHash; i++)
(*ppbPKCS1Format)[i] = pbHash[cbHash - (i + 1)];
cbAvailableData -= cbHash;
if ( 0 == (CRYPT_NOHASHOID & dwFlags))
{
switch (HashAlgid)
{
case CALG_MD2:
// PKCS delimit the hash value
pbEnd = (LPBYTE)md2Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0;
break;
case CALG_MD4:
// PKCS delimit the hash value
pbEnd = (LPBYTE)md4Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0;
break;
case CALG_MD5:
// PKCS delimit the hash value
pbEnd = (LPBYTE)md5Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0;
break;
case CALG_SHA:
// PKCS delimit the hash value
pbEnd = (LPBYTE)shaEncodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0;
break;
case CALG_SSL3_SHAMD5:
// No PKCS padding
pbStart = *ppbPKCS1Format + cbHash;
*pbStart++ = 0;
break;
case CALG_SHA_256:
pbEnd = (LPBYTE) sha256Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
if (bTmp > cbAvailableData)
{
dwSts = (DWORD) NTE_BAD_LEN;
goto Ret;
}
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0; // Padding byte #2
break;
case CALG_SHA_384:
pbEnd = (LPBYTE) sha384Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
if (bTmp > cbAvailableData)
{
dwSts = (DWORD) NTE_BAD_LEN;
goto Ret;
}
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0; // Padding byte #2
break;
case CALG_SHA_512:
pbEnd = (LPBYTE) sha512Encodings[0];
pbStart = *ppbPKCS1Format + cbHash;
bTmp = *pbEnd++;
if (bTmp > cbAvailableData)
{
dwSts = (DWORD) NTE_BAD_LEN;
goto Ret;
}
while (0 < bTmp--)
*pbStart++ = *pbEnd++;
*pbStart++ = 0; // Padding byte #2
break;
default:
dwSts = (DWORD)NTE_BAD_ALGID;
goto Ret;
}
}
else
{
(*ppbPKCS1Format)[cbHash] = 0x00;
}
Ret:
if (ERROR_SUCCESS != dwSts &&
NULL != *ppbPKCS1Format)
{
CspFreeH(*ppbPKCS1Format);
*ppbPKCS1Format = NULL;
}
return dwSts;
}
//
// Function: VerifyPKCS2Padding
//
DWORD WINAPI VerifyPKCS2Padding(
IN PBYTE pbPaddedData,
IN DWORD cbModulus,
OUT PBYTE *ppbData,
OUT PDWORD pcbData)
{
DWORD dwSts = ERROR_SUCCESS;
PBYTE pbData = NULL;
DWORD cbData = 0;
DWORD z = 0;
*ppbData = NULL;
*pcbData = 0;
if ((pbPaddedData[cbModulus - 2] != PKCS_BLOCKTYPE_2) ||
(pbPaddedData[cbModulus - 1] != 0))
{
dwSts = NTE_BAD_DATA;
goto Ret;
}
cbData = cbModulus - 3;
while ((cbData > 0) && (pbPaddedData[cbData]))
cbData--;
pbData = (PBYTE) CspAllocH(cbData);
LOG_CHECK_ALLOC(pbData);
// Reverse the session key bytes
for (z = 0; z < cbData; ++z)
pbData[z] = pbPaddedData[cbData - z - 1];
*ppbData = pbData;
pbData = NULL;
*pcbData = cbData;
Ret:
if (pbData)
CspFreeH(pbData);
return dwSts;
}
//
// Function: GetLocalCspInfo
//
PLOCAL_CSP_INFO GetLocalCspInfo(void)
{
return &LocalCspInfo;
}
//
// Function: InitializeLocalCallInfo
//
DWORD InitializeLocalCallInfo(
IN PLOCAL_CALL_INFO pLocalCallInfo)
{
*pLocalCallInfo = FALSE;
return ERROR_SUCCESS;
}
//
// Function: SetLocalCallInfo
//
// Purpose: The local CSP uses this function to indicate to functions in
// this library whether execution of a given API should continue
// after the local CSP has returned.
//
void SetLocalCallInfo(
IN OUT PLOCAL_CALL_INFO pLocalCallInfo,
IN BOOL fContinue)
{
*pLocalCallInfo = fContinue;
}
//
// Function: CheckLocalCallInfo
//
BOOL CheckLocalCallInfo(
IN PLOCAL_CALL_INFO pLocalCallInfo,
IN DWORD dwSts,
OUT BOOL *pfSuccess)
{
if (FALSE == *pLocalCallInfo)
*pfSuccess = (ERROR_SUCCESS == dwSts);
return *pLocalCallInfo;
}
//
// Memory Management
//
//
// Function: CspAllocH
//
LPVOID WINAPI CspAllocH(
IN SIZE_T cBytes)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes);
}
//
// Function: CspFreeH
//
void WINAPI CspFreeH(
IN LPVOID pMem)
{
HeapFree(GetProcessHeap(), 0, pMem);
}
//
// Function: CspReAllocH
//
LPVOID WINAPI CspReAllocH(
IN LPVOID pMem,
IN SIZE_T cBytes)
{
return HeapReAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, pMem, cBytes);
}
//
// Critical Section Management
//
//
// Function: CspInitializeCriticalSection
//
DWORD CspInitializeCriticalSection(
IN CRITICAL_SECTION *pcs)
{
__try {
InitializeCriticalSection(pcs);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return ERROR_NOT_ENOUGH_MEMORY;
}
return ERROR_SUCCESS;
}
//
// Function: CspEnterCriticalSection
//
DWORD CspEnterCriticalSection(
IN CRITICAL_SECTION *pcs)
{
__try {
EnterCriticalSection(pcs);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return ERROR_NOT_ENOUGH_MEMORY;
}
return ERROR_SUCCESS;
}
//
// Function: CspLeaveCriticalSection
//
void CspLeaveCriticalSection(
IN CRITICAL_SECTION *pcs)
{
LeaveCriticalSection(pcs);
}
//
// Function: CspDeleteCriticalSection
//
void CspDeleteCriticalSection(
IN CRITICAL_SECTION *pcs)
{
DeleteCriticalSection(pcs);
}
//
// Registration Helpers
//
//
// Function: RegOpenProviderKey
//
DWORD WINAPI RegOpenProviderKey(
IN OUT HKEY *phProviderKey,
IN REGSAM samDesired)
{
DWORD cbProv = 0;
LPWSTR wszProv = NULL;
DWORD dwSts = ERROR_SUCCESS;
DWORD dwIgn = 0;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*phProviderKey = 0;
cbProv = (wcslen(PROVPATH) +
wcslen(pLocalCspInfo->wszProviderName) + 1) * sizeof(WCHAR);
wszProv = (LPWSTR) CspAllocH(cbProv);
if (NULL == wszProv)
{
dwSts = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
swprintf(
wszProv,
L"%s%s",
PROVPATH,
pLocalCspInfo->wszProviderName);
//
// Create or open in local machine for provider
//
dwSts = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
wszProv,
0L, L"", REG_OPTION_NON_VOLATILE,
samDesired, NULL, phProviderKey,
&dwIgn);
if (ERROR_SUCCESS != dwSts)
goto Ret;
Ret:
if (wszProv)
CspFreeH(wszProv);
if (ERROR_SUCCESS != dwSts && 0 != *phProviderKey)
RegCloseKey(*phProviderKey);
return dwSts;
}
//
// Function: CreateUuidContainerName
//
DWORD WINAPI CreateUuidContainerName(
IN PUSER_CONTEXT pUserCtx)
{
UUID Uuid;
LPWSTR wszUuid = NULL;
DWORD dwSts = ERROR_SUCCESS;
dwSts = (DWORD) UuidCreate(&Uuid);
if (RPC_S_OK != dwSts)
goto Ret;
dwSts = (DWORD) UuidToStringW(&Uuid, &wszUuid);
if (RPC_S_OK != dwSts)
goto Ret;
pUserCtx->wszBaseContainerName = wszUuid;
pUserCtx->fBaseContainerNameIsRpcUuid = TRUE;
wszUuid = NULL;
Ret:
if (wszUuid)
RpcStringFreeW(&wszUuid);
return dwSts;
}
//
// Function: DeleteUserContext
//
DWORD DeleteUserContext(
IN PUSER_CONTEXT pUserContext)
{
DWORD dwSts = ERROR_SUCCESS;
if (pUserContext->pVTableW)
{
if (pUserContext->pVTableW->pbContextInfo)
{
CspFreeH(pUserContext->pVTableW->pbContextInfo);
pUserContext->pVTableW = NULL;
}
if (pUserContext->pVTableW->pszProvName)
{
CspFreeH(pUserContext->pVTableW->pszProvName);
pUserContext->pVTableW->pszProvName = NULL;
}
CspFreeH(pUserContext->pVTableW);
pUserContext->pVTableW = NULL;
}
if (pUserContext->wszBaseContainerName)
{
if (pUserContext->fBaseContainerNameIsRpcUuid)
RpcStringFreeW(&pUserContext->wszBaseContainerName);
else
CspFreeH(pUserContext->wszBaseContainerName);
pUserContext->wszBaseContainerName = NULL;
}
if (pUserContext->wszContainerNameFromCaller)
{
CspFreeH(pUserContext->wszContainerNameFromCaller);
pUserContext->wszContainerNameFromCaller = NULL;
}
if (pUserContext->wszUniqueContainerName)
{
CspFreeH(pUserContext->wszUniqueContainerName);
pUserContext->wszUniqueContainerName = NULL;
}
if (pUserContext->hSupportProv)
{
if (! CryptReleaseContext(pUserContext->hSupportProv, 0))
dwSts = GetLastError();
pUserContext->hSupportProv = 0;
}
return dwSts;
}
//
// Function: DeleteKeyContext
//
DWORD DeleteKeyContext(
IN PKEY_CONTEXT pKeyContext)
{
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
LOCAL_CALL_INFO LocalCallInfo;
DWORD dwSts = ERROR_SUCCESS;
InitializeLocalCallInfo(&LocalCallInfo);
if (pKeyContext->hSupportKey)
{
if (! CryptDestroyKey(pKeyContext->hSupportKey))
dwSts = GetLastError();
pKeyContext->hSupportKey = 0;
}
if (pKeyContext->pvLocalKeyContext)
{
if (pLocalCspInfo->pfnLocalDestroyKey)
{
pLocalCspInfo->pfnLocalDestroyKey(
pKeyContext,
&LocalCallInfo);
pKeyContext->pvLocalKeyContext = NULL;
}
}
return dwSts;
}
//
// Function: DeleteHashContext
//
DWORD DeleteHashContext(
IN PHASH_CONTEXT pHashContext)
{
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
LOCAL_CALL_INFO LocalCallInfo;
DWORD dwSts = ERROR_SUCCESS;
InitializeLocalCallInfo(&LocalCallInfo);
if (pHashContext->hSupportHash)
{
if (! CryptDestroyHash(pHashContext->hSupportHash))
dwSts = GetLastError();
pHashContext->hSupportHash = 0;
}
if (pHashContext->pvLocalHashContext)
{
if (pLocalCspInfo->pfnLocalDestroyHash)
{
pLocalCspInfo->pfnLocalDestroyHash(
pHashContext,
&LocalCallInfo);
pHashContext->pvLocalHashContext = NULL;
}
}
return dwSts;
}
/*
- CPAcquireContext
-
* Purpose:
* The CPAcquireContext function is used to acquire a context
* handle to a cryptographic service provider (CSP).
*
*
* Parameters:
* OUT phProv - Handle to a CSP
* IN szContainer - Pointer to a string which is the
* identity of the logged on user
* IN dwFlags - Flags values
* IN pVTable - Pointer to table of function pointers
*
* Returns:
*/
BOOL WINAPI
CPAcquireContext(
OUT HCRYPTPROV *phProv,
IN LPCSTR szContainer,
IN DWORD dwFlags,
IN PVTableProvStruc pVTable)
{
ANSI_STRING AnsiContainer;
UNICODE_STRING UnicodeContainer;
ANSI_STRING AnsiProvName;
UNICODE_STRING UnicodeProvName;
BOOL fSuccess = FALSE;
DWORD dwSts;
DWORD dwError = NTE_FAIL;
VTableProvStrucW VTableW;
memset(&AnsiContainer, 0, sizeof(AnsiContainer));
memset(&AnsiProvName, 0, sizeof(AnsiProvName));
memset(&UnicodeContainer, 0, sizeof(UnicodeContainer));
memset(&UnicodeProvName, 0, sizeof(UnicodeProvName));
memset(&VTableW, 0, sizeof(VTableW));
if (szContainer)
{
RtlInitAnsiString(&AnsiContainer, szContainer);
dwSts = RtlAnsiStringToUnicodeString(
&UnicodeContainer,
&AnsiContainer,
TRUE);
if (STATUS_SUCCESS != dwSts)
{
dwError = RtlNtStatusToDosError(dwSts);
goto Ret;
}
}
VTableW.cbContextInfo = pVTable->cbContextInfo;
VTableW.dwProvType = pVTable->dwProvType;
VTableW.FuncReturnhWnd = pVTable->FuncReturnhWnd;
VTableW.pbContextInfo = pVTable->pbContextInfo;
VTableW.Version = pVTable->Version;
RtlInitAnsiString(&AnsiProvName, pVTable->pszProvName);
dwSts = RtlAnsiStringToUnicodeString(
&UnicodeProvName,
&AnsiProvName,
TRUE);
if (STATUS_SUCCESS != dwSts)
{
dwError = RtlNtStatusToDosError(dwSts);
goto Ret;
}
VTableW.pszProvName = UnicodeProvName.Buffer;
if (! CPAcquireContextW(
phProv,
szContainer ? UnicodeContainer.Buffer : NULL,
dwFlags,
&VTableW))
{
dwError = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (szContainer)
RtlFreeUnicodeString(&UnicodeContainer);
RtlFreeUnicodeString(&UnicodeProvName);
if (! fSuccess)
SetLastError(dwError);
return fSuccess;
}
/*
- CPAcquireContextW
-
* Purpose:
* The CPAcquireContextW function is used to acquire a context
* handle to a cryptographic service provider (CSP). using
* UNICODE strings. This is an optional entry point for a CSP.
* It is not used prior to Whistler. There it is used if
* exported by the CSP image, otherwise any string conversions
* are done, and CPAcquireContext is called.
*
*
* Parameters:
* OUT phProv - Handle to a CSP
* IN szContainer - Pointer to a string which is the
* identity of the logged on user
* IN dwFlags - Flags values
* IN pVTable - Pointer to table of function pointers
*
* Returns:
*/
BOOL WINAPI
CPAcquireContextW(
OUT HCRYPTPROV *phProv,
IN LPCWSTR szContainer,
IN DWORD dwFlags,
IN PVTableProvStrucW pVTable)
{
PUSER_CONTEXT pUserContext = NULL;
LOCAL_CALL_INFO LocalCallInfo;
DWORD dwSts = ERROR_SUCCESS;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
//
// Invalid to specify a container name with
// VERIFYCONTEXT.
//
if ( (CRYPT_VERIFYCONTEXT & dwFlags) &&
NULL != szContainer)
{
dwSts = NTE_BAD_FLAGS;
goto Ret;
}
pUserContext = (PUSER_CONTEXT) CspAllocH(sizeof(USER_CONTEXT));
LOG_CHECK_ALLOC(pUserContext);
if (szContainer)
{
pUserContext->wszContainerNameFromCaller =
(LPWSTR) CspAllocH((1 + wcslen(szContainer)) * sizeof(WCHAR));
LOG_CHECK_ALLOC(pUserContext->wszContainerNameFromCaller);
wcscpy(
pUserContext->wszContainerNameFromCaller,
szContainer);
}
pUserContext->dwFlags = dwFlags;
//
// Copy the VTableProvStruc that we received from advapi, since
// the info in the struct may be useful later.
//
pUserContext->pVTableW =
(PVTableProvStrucW) CspAllocH(sizeof(VTableProvStrucW));
LOG_CHECK_ALLOC(pUserContext->pVTableW);
// Copy the provider name
pUserContext->pVTableW->pszProvName =
(LPWSTR) CspAllocH((1 + wcslen(pVTable->pszProvName)) * sizeof(WCHAR));
LOG_CHECK_ALLOC(pUserContext->pVTableW->pszProvName);
wcscpy(
pUserContext->pVTableW->pszProvName,
pVTable->pszProvName);
// Copy the context information, if any
if (pVTable->pbContextInfo)
{
pUserContext->pVTableW->pbContextInfo =
(PBYTE) CspAllocH(pVTable->cbContextInfo);
LOG_CHECK_ALLOC(pUserContext->pVTableW->pbContextInfo);
memcpy(
pUserContext->pVTableW->pbContextInfo,
pVTable->pbContextInfo,
pVTable->cbContextInfo);
pUserContext->pVTableW->cbContextInfo = pVTable->cbContextInfo;
}
// Copy the rest of the ProvStruc
pUserContext->pVTableW->dwProvType = pVTable->dwProvType;
pUserContext->pVTableW->FuncReturnhWnd = pVTable->FuncReturnhWnd;
pUserContext->pVTableW->FuncVerifyImage = pVTable->FuncVerifyImage;
pUserContext->pVTableW->Version = pVTable->Version;
if (! CryptAcquireContextW(
&pUserContext->hSupportProv,
NULL,
pLocalCspInfo->wszSupportProviderName,
pLocalCspInfo->dwSupportProviderType,
CRYPT_VERIFYCONTEXT))
{
dwSts = GetLastError();
goto Ret;
}
dwSts = pLocalCspInfo->pfnLocalAcquireContext(
pUserContext,
&LocalCallInfo);
if (ERROR_SUCCESS != dwSts)
goto Ret;
if (CRYPT_DELETEKEYSET & dwFlags)
{
DeleteUserContext(pUserContext);
CspFreeH(pUserContext);
pUserContext = NULL;
}
else
*phProv = (HCRYPTPROV) pUserContext;
Ret:
if (ERROR_SUCCESS != dwSts)
{
DeleteUserContext(pUserContext);
CspFreeH(pUserContext);
SetLastError(dwSts);
fSuccess = FALSE;
}
else
fSuccess = TRUE;
return fSuccess;
}
/*
- CPReleaseContext
-
* Purpose:
* The CPReleaseContext function is used to release a
* context created by CryptAcquireContext.
*
* Parameters:
* IN phProv - Handle to a CSP
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPReleaseContext(
IN HCRYPTPROV hProv,
IN DWORD dwFlags)
{
PUSER_CONTEXT pUserContext = (PUSER_CONTEXT) hProv;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
BOOL fSuccess = TRUE;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
InitializeLocalCallInfo(&LocalCallInfo);
dwSts = pLocalCspInfo->pfnLocalReleaseContext(
pUserContext, dwFlags, &LocalCallInfo);
if (ERROR_SUCCESS != dwSts)
fSuccess = FALSE;
//
// Try to free the user context structure, regardless of what the
// local CSP replied in the above call.
//
DeleteUserContext(pUserContext);
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGenKey
-
* Purpose:
* Generate cryptographic keys
*
*
* Parameters:
* IN hProv - Handle to a CSP
* IN Algid - Algorithm identifier
* IN dwFlags - Flags values
* OUT phKey - Handle to a generated key
*
* Returns:
*/
BOOL WINAPI
CPGenKey(
IN HCRYPTPROV hProv,
IN ALG_ID Algid,
IN DWORD dwFlags,
OUT HCRYPTKEY *phKey)
{
DWORD dwSts = ERROR_SUCCESS;
PKEY_CONTEXT pKeyCtx = NULL;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
LOCAL_CALL_INFO LocalCallInfo;
InitializeLocalCallInfo(&LocalCallInfo);
*phKey = 0;
pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
LOG_CHECK_ALLOC(pKeyCtx);
pKeyCtx->Algid = Algid;
pKeyCtx->dwFlags = 0x0000ffff & dwFlags;
pKeyCtx->cKeyBits = dwFlags >> 16;
pKeyCtx->pUserContext = pUserCtx;
if (pLocalCspInfo->pfnLocalGenKey)
{
dwSts = pLocalCspInfo->pfnLocalGenKey(
pKeyCtx, &LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptGenKey(
pUserCtx->hSupportProv,
Algid,
dwFlags,
&pKeyCtx->hSupportKey))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (TRUE == fSuccess)
{
*phKey = (HCRYPTKEY) pKeyCtx;
pKeyCtx = NULL;
}
if (pKeyCtx)
{
DeleteKeyContext(pKeyCtx);
CspFreeH(pKeyCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDeriveKey
-
* Purpose:
* Derive cryptographic keys from base data
*
*
* Parameters:
* IN hProv - Handle to a CSP
* IN Algid - Algorithm identifier
* IN hBaseData - Handle to base data
* IN dwFlags - Flags values
* OUT phKey - Handle to a generated key
*
* Returns:
*/
BOOL WINAPI
CPDeriveKey(
IN HCRYPTPROV hProv,
IN ALG_ID Algid,
IN HCRYPTHASH hHash,
IN DWORD dwFlags,
OUT HCRYPTKEY *phKey)
{
DWORD dwSts = ERROR_SUCCESS;
PKEY_CONTEXT pKeyCtx = NULL;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
LOCAL_CALL_INFO LocalCallInfo;
*phKey = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
LOG_CHECK_ALLOC(pKeyCtx);
pKeyCtx->pUserContext = pUserCtx;
pKeyCtx->Algid = Algid;
pKeyCtx->cKeyBits = dwFlags >> 16;
pKeyCtx->dwFlags = dwFlags & 0x0000ffff;
if (pLocalCspInfo->pfnLocalDeriveKey)
{
dwSts = pLocalCspInfo->pfnLocalDeriveKey(
pKeyCtx,
pHashCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptDeriveKey(
pUserCtx->hSupportProv,
Algid,
pHashCtx->hSupportHash,
dwFlags,
&pKeyCtx->hSupportKey))
{
dwSts = GetLastError();
goto Ret;
}
*phKey = (HCRYPTKEY) pKeyCtx;
pKeyCtx = NULL;
fSuccess = TRUE;
Ret:
if (pKeyCtx)
{
DeleteKeyContext(pKeyCtx);
CspFreeH(pKeyCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDestroyKey
-
* Purpose:
* Destroys the cryptographic key that is being referenced
* with the hKey parameter
*
*
* Parameters:
* IN hProv - Handle to a CSP
* IN hKey - Handle to a key
*
* Returns:
*/
BOOL WINAPI
CPDestroyKey(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey)
{
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
dwSts = DeleteKeyContext(pKeyCtx);
CspFreeH(pKeyCtx);
if (ERROR_SUCCESS != dwSts)
SetLastError(dwSts);
return (ERROR_SUCCESS == dwSts);
}
/*
- CPSetKeyParam
-
* Purpose:
* Allows applications to customize various aspects of the
* operations of a key
*
* Parameters:
* IN hProv - Handle to a CSP
* IN hKey - Handle to a key
* IN dwParam - Parameter number
* IN pbData - Pointer to data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPSetKeyParam(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN DWORD dwParam,
IN CONST BYTE *pbData,
IN DWORD dwFlags)
{
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
LOCAL_CALL_INFO LocalCallInfo;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalSetKeyParam)
{
dwSts = pLocalCspInfo->pfnLocalSetKeyParam(
pKeyCtx,
dwParam,
(PBYTE) pbData,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptSetKeyParam(
pKeyCtx->hSupportKey,
dwParam,
pbData,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGetKeyParam
-
* Purpose:
* Allows applications to get various aspects of the
* operations of a key
*
* Parameters:
* IN hProv - Handle to a CSP
* IN hKey - Handle to a key
* IN dwParam - Parameter number
* OUT pbData - Pointer to data
* IN pdwDataLen - Length of parameter data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPGetKeyParam(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN DWORD dwParam,
OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen,
IN DWORD dwFlags)
{
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
BOOL fSuccess = FALSE;
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalGetKeyParam)
{
dwSts = pLocalCspInfo->pfnLocalGetKeyParam(
pKeyCtx,
dwParam,
pbData,
pcbDataLen,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptGetKeyParam(
pKeyCtx->hSupportKey,
dwParam,
pbData,
pcbDataLen,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPSetProvParam
-
* Purpose:
* Allows applications to customize various aspects of the
* operations of a provider
*
* Parameters:
* IN hProv - Handle to a CSP
* IN dwParam - Parameter number
* IN pbData - Pointer to data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPSetProvParam(
IN HCRYPTPROV hProv,
IN DWORD dwParam,
IN CONST BYTE *pbData,
IN DWORD dwFlags)
{
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
BOOL fSuccess = FALSE;
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalSetProvParam)
{
dwSts = pLocalCspInfo->pfnLocalSetProvParam(
pUserCtx,
dwParam,
(PBYTE) pbData,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptSetProvParam(
pUserCtx->hSupportProv,
dwParam,
pbData,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGetProvParam
-
* Purpose:
* Allows applications to get various aspects of the
* operations of a provider
*
* Parameters:
* IN hProv - Handle to a CSP
* IN dwParam - Parameter number
* OUT pbData - Pointer to data
* IN OUT pdwDataLen - Length of parameter data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPGetProvParam(
IN HCRYPTPROV hProv,
IN DWORD dwParam,
OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen,
IN DWORD dwFlags)
{
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
BOOL fSuccess = FALSE;
DWORD cbData = 0;
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
BOOL fFreeAnsiString = FALSE;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
BOOL fContinue = TRUE;
memset(&AnsiString, 0, sizeof(AnsiString));
memset(&UnicodeString, 0, sizeof(UnicodeString));
InitializeLocalCallInfo(&LocalCallInfo);
//
// First, see if the local CSP wants to service this call
//
if (pLocalCspInfo->pfnLocalGetProvParam)
{
dwSts = pLocalCspInfo->pfnLocalGetProvParam(
pUserCtx,
dwParam,
pbData,
pcbDataLen,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
//
// Some prov params are general enough to be serviced "globally"
// by this lib.
// Try those before calling the support CSP.
//
switch (dwParam)
{
case PP_CONTAINER:
fContinue = FALSE;
RtlInitUnicodeString(
&UnicodeString,
pUserCtx->wszBaseContainerName);
dwSts = RtlUnicodeStringToAnsiString(
&AnsiString,
&UnicodeString,
TRUE);
if (STATUS_SUCCESS != dwSts)
{
dwSts = RtlNtStatusToDosError(dwSts);
goto Ret;
}
fFreeAnsiString = TRUE;
cbData = strlen(AnsiString.Buffer) + 1;
if (*pcbDataLen < cbData || NULL == pbData)
{
*pcbDataLen = cbData;
if (NULL != pbData)
dwSts = ERROR_MORE_DATA;
else
fSuccess = TRUE;
break;
}
*pcbDataLen = cbData;
strcpy((LPSTR) pbData, AnsiString.Buffer);
fSuccess = TRUE;
break;
case PP_UNIQUE_CONTAINER:
fContinue = FALSE;
RtlInitUnicodeString(
&UnicodeString,
pUserCtx->wszUniqueContainerName);
dwSts = RtlUnicodeStringToAnsiString(
&AnsiString,
&UnicodeString,
TRUE);
if (STATUS_SUCCESS != dwSts)
{
dwSts = RtlNtStatusToDosError(dwSts);
goto Ret;
}
fFreeAnsiString = TRUE;
cbData = strlen(AnsiString.Buffer) + 1;
if (*pcbDataLen < cbData || NULL == pbData)
{
*pcbDataLen = cbData;
if (NULL != pbData)
dwSts = ERROR_MORE_DATA;
else
fSuccess = TRUE;
break;
}
*pcbDataLen = cbData;
strcpy((LPSTR) pbData, AnsiString.Buffer);
fSuccess = TRUE;
break;
case PP_NAME:
fContinue = FALSE;
RtlInitUnicodeString(
&UnicodeString,
pLocalCspInfo->wszProviderName);
dwSts = RtlUnicodeStringToAnsiString(
&AnsiString,
&UnicodeString,
TRUE);
if (STATUS_SUCCESS != dwSts)
{
dwSts = RtlNtStatusToDosError(dwSts);
goto Ret;
}
fFreeAnsiString = TRUE;
cbData = strlen(AnsiString.Buffer) + 1;
if (*pcbDataLen < cbData || NULL == pbData)
{
*pcbDataLen = cbData;
if (NULL != pbData)
dwSts = ERROR_MORE_DATA;
else
fSuccess = TRUE;
break;
}
*pcbDataLen = cbData;
strcpy((LPSTR) pbData, AnsiString.Buffer);
fSuccess = TRUE;
break;
case PP_PROVTYPE:
fContinue = FALSE;
if (*pcbDataLen < sizeof(DWORD) || NULL == pbData)
{
*pcbDataLen = sizeof(DWORD);
if (NULL != pbData)
dwSts = ERROR_MORE_DATA;
else
fSuccess = TRUE;
break;
}
*pcbDataLen = sizeof(DWORD);
memcpy(
pbData,
(PBYTE) &pLocalCspInfo->dwProviderType,
sizeof(DWORD));
fSuccess = TRUE;
break;
case PP_IMPTYPE:
fContinue = FALSE;
if (*pcbDataLen < sizeof(DWORD) || NULL == pbData)
{
*pcbDataLen = sizeof(DWORD);
if (NULL != pbData)
dwSts = ERROR_MORE_DATA;
else
fSuccess = TRUE;
break;
}
*pcbDataLen = sizeof(DWORD);
memcpy(
pbData,
(PBYTE) &pLocalCspInfo->dwImplementationType,
sizeof(DWORD));
fSuccess = TRUE;
break;
}
if (FALSE == fContinue)
goto Ret;
//
// Try sending any request that hasn't been filtered by the above checks
// to the support CSP.
//
if (! CryptGetProvParam(
pUserCtx->hSupportProv,
dwParam,
pbData,
pcbDataLen,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (fFreeAnsiString)
RtlFreeAnsiString(&AnsiString);
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPSetHashParam
-
* Purpose:
* Allows applications to customize various aspects of the
* operations of a hash
*
* Parameters:
* IN hProv - Handle to a CSP
* IN hHash - Handle to a hash
* IN dwParam - Parameter number
* IN pbData - Pointer to data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPSetHashParam(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN DWORD dwParam,
IN CONST BYTE *pbData,
IN DWORD dwFlags)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
DWORD dwSts = ERROR_SUCCESS;
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalSetHashParam)
{
dwSts = pLocalCspInfo->pfnLocalSetHashParam(
pHashCtx,
dwParam,
(PBYTE) pbData,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptSetHashParam(
pHashCtx->hSupportHash,
dwParam,
pbData,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGetHashParam
-
* Purpose:
* Allows applications to get various aspects of the
* operations of a hash
*
* Parameters:
* IN hProv - Handle to a CSP
* IN hHash - Handle to a hash
* IN dwParam - Parameter number
* OUT pbData - Pointer to data
* IN pdwDataLen - Length of parameter data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPGetHashParam(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN DWORD dwParam,
OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen,
IN DWORD dwFlags)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
DWORD dwSts = ERROR_SUCCESS;
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalGetHashParam)
{
dwSts = pLocalCspInfo->pfnLocalGetHashParam(
pHashCtx,
dwParam,
pbData,
pcbDataLen,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptGetHashParam(
pHashCtx->hSupportHash,
dwParam,
pbData,
pcbDataLen,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPExportKey
-
* Purpose:
* Export cryptographic keys out of a CSP in a secure manner
*
*
* Parameters:
* IN hProv - Handle to the CSP user
* IN hKey - Handle to the key to export
* IN hPubKey - Handle to exchange public key value of
* the destination user
* IN dwBlobType - Type of key blob to be exported
* IN dwFlags - Flags values
* OUT pbData - Key blob data
* IN OUT pdwDataLen - Length of key blob in bytes
*
* Returns:
*/
BOOL WINAPI
CPExportKey(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN HCRYPTKEY hPubKey,
IN DWORD dwBlobType,
IN DWORD dwFlags,
OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen)
{
BOOL fSuccess = FALSE;
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalExportKey)
{
dwSts = pLocalCspInfo->pfnLocalExportKey(
pKeyCtx,
pPubKeyCtx,
dwBlobType,
dwFlags,
pbData,
pcbDataLen,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptExportKey(
pKeyCtx->hSupportKey,
pPubKeyCtx ? pPubKeyCtx->hSupportKey : 0,
dwBlobType,
dwFlags,
pbData,
pcbDataLen))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPImportKey
-
* Purpose:
* Import cryptographic keys
*
*
* Parameters:
* IN hProv - Handle to the CSP user
* IN pbData - Key blob data
* IN dwDataLen - Length of the key blob data
* IN hPubKey - Handle to the exchange public key value of
* the destination user
* IN dwFlags - Flags values
* OUT phKey - Pointer to the handle to the key which was
* Imported
*
* Returns:
*/
BOOL WINAPI
CPImportKey(
IN HCRYPTPROV hProv,
IN CONST BYTE *pbData,
IN DWORD cbDataLen,
IN HCRYPTKEY hPubKey,
IN DWORD dwFlags,
OUT HCRYPTKEY *phKey)
{
BOOL fSuccess = FALSE;
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = NULL;
PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*phKey = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
LOG_CHECK_ALLOC(pKeyCtx);
pKeyCtx->dwFlags = dwFlags & 0x0000ffff;
pKeyCtx->pUserContext = pUserCtx;
if (pLocalCspInfo->pfnLocalImportKey)
{
dwSts = pLocalCspInfo->pfnLocalImportKey(
pKeyCtx,
(PBYTE) pbData,
cbDataLen,
pPubKeyCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptImportKey(
pUserCtx->hSupportProv,
pbData,
cbDataLen,
pPubKeyCtx ? pPubKeyCtx->hSupportKey : 0,
dwFlags,
&pKeyCtx->hSupportKey))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (TRUE == fSuccess)
{
*phKey = (HCRYPTKEY) pKeyCtx;
pKeyCtx = NULL;
}
if (pKeyCtx)
{
DeleteKeyContext(pKeyCtx);
CspFreeH(pKeyCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPEncrypt
-
* Purpose:
* Encrypt data
*
*
* Parameters:
* IN hProv - Handle to the CSP user
* IN hKey - Handle to the key
* IN hHash - Optional handle to a hash
* IN Final - Boolean indicating if this is the final
* block of plaintext
* IN dwFlags - Flags values
* IN OUT pbData - Data to be encrypted
* IN OUT pdwDataLen - Pointer to the length of the data to be
* encrypted
* IN dwBufLen - Size of Data buffer
*
* Returns:
*/
BOOL WINAPI
CPEncrypt(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN HCRYPTHASH hHash,
IN BOOL fFinal,
IN DWORD dwFlags,
IN OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen,
IN DWORD cbBufLen)
{
BOOL fSuccess = FALSE;
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*pcbDataLen = 0;
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalEncrypt)
{
dwSts = pLocalCspInfo->pfnLocalEncrypt(
pKeyCtx,
pHashCtx,
fFinal,
dwFlags,
pbData,
pcbDataLen,
cbBufLen,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptEncrypt(
pKeyCtx->hSupportKey,
pHashCtx ? pHashCtx->hSupportHash : 0,
fFinal,
dwFlags,
pbData,
pcbDataLen,
cbBufLen))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDecrypt
-
* Purpose:
* Decrypt data
*
*
* Parameters:
* IN hProv - Handle to the CSP user
* IN hKey - Handle to the key
* IN hHash - Optional handle to a hash
* IN Final - Boolean indicating if this is the final
* block of ciphertext
* IN dwFlags - Flags values
* IN OUT pbData - Data to be decrypted
* IN OUT pdwDataLen - Pointer to the length of the data to be
* decrypted
*
* Returns:
*/
BOOL WINAPI
CPDecrypt(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN HCRYPTHASH hHash,
IN BOOL fFinal,
IN DWORD dwFlags,
IN OUT LPBYTE pbData,
IN OUT LPDWORD pcbDataLen)
{
BOOL fSuccess = FALSE;
DWORD dwSts = ERROR_SUCCESS;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalDecrypt)
{
dwSts = pLocalCspInfo->pfnLocalDecrypt(
pKeyCtx,
pHashCtx,
fFinal,
dwFlags,
pbData,
pcbDataLen,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptDecrypt(
pKeyCtx->hSupportKey,
pHashCtx ? pHashCtx->hSupportHash : 0,
fFinal,
dwFlags,
pbData,
pcbDataLen))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPCreateHash
-
* Purpose:
* initate the hashing of a stream of data
*
*
* Parameters:
* IN hUID - Handle to the user identifcation
* IN Algid - Algorithm identifier of the hash algorithm
* to be used
* IN hKey - Optional handle to a key
* IN dwFlags - Flags values
* OUT pHash - Handle to hash object
*
* Returns:
*/
BOOL WINAPI
CPCreateHash(
IN HCRYPTPROV hProv,
IN ALG_ID Algid,
IN HCRYPTKEY hKey,
IN DWORD dwFlags,
OUT HCRYPTHASH *phHash)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = NULL;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*phHash = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pHashCtx = (PHASH_CONTEXT) CspAllocH(sizeof(HASH_CONTEXT));
LOG_CHECK_ALLOC(pHashCtx);
pHashCtx->Algid = Algid;
pHashCtx->dwFlags = dwFlags;
pHashCtx->pUserContext = pUserCtx;
if (pLocalCspInfo->pfnLocalCreateHash)
{
dwSts = pLocalCspInfo->pfnLocalCreateHash(
pHashCtx,
pKeyCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptCreateHash(
pUserCtx->hSupportProv,
Algid,
pKeyCtx ? pKeyCtx->hSupportKey : 0,
dwFlags,
&pHashCtx->hSupportHash))
{
dwSts = GetLastError();
goto Ret;
}
*phHash = (HCRYPTHASH) pHashCtx;
pHashCtx = NULL;
fSuccess = TRUE;
Ret:
if (pHashCtx)
{
DeleteHashContext(pHashCtx);
CspFreeH(pHashCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPHashData
-
* Purpose:
* Compute the cryptograghic hash on a stream of data
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN hHash - Handle to hash object
* IN pbData - Pointer to data to be hashed
* IN dwDataLen - Length of the data to be hashed
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPHashData(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN CONST BYTE *pbData,
IN DWORD cbDataLen,
IN DWORD dwFlags)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalHashData)
{
dwSts = pLocalCspInfo->pfnLocalHashData(
pHashCtx,
pbData,
cbDataLen,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptHashData(
pHashCtx->hSupportHash,
pbData,
cbDataLen,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPHashSessionKey
-
* Purpose:
* Compute the cryptograghic hash on a key object.
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN hHash - Handle to hash object
* IN hKey - Handle to a key object
* IN dwFlags - Flags values
*
* Returns:
* CRYPT_FAILED
* CRYPT_SUCCEED
*/
BOOL WINAPI
CPHashSessionKey(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN HCRYPTKEY hKey,
IN DWORD dwFlags)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalHashSessionKey)
{
dwSts = pLocalCspInfo->pfnLocalHashSessionKey(
pHashCtx,
pKeyCtx,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptHashSessionKey(
pHashCtx->hSupportHash,
pKeyCtx ? pKeyCtx->hSupportKey : 0,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPSignHash
-
* Purpose:
* Create a digital signature from a hash
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN hHash - Handle to hash object
* IN dwKeySpec - Key pair to that is used to sign with
* IN sDescription - Description of data to be signed
* IN dwFlags - Flags values
* OUT pbSignature - Pointer to signature data
* IN OUT dwHashLen - Pointer to the len of the signature data
*
* Returns:
*/
BOOL WINAPI
CPSignHash(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN DWORD dwKeySpec,
IN LPCWSTR szDescription,
IN DWORD dwFlags,
OUT LPBYTE pbSignature,
IN OUT LPDWORD pcbSigLen)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalSignHash)
{
dwSts = pLocalCspInfo->pfnLocalSignHash(
pHashCtx,
dwKeySpec,
dwFlags,
pbSignature,
pcbSigLen,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptSignHash(
pHashCtx->hSupportHash,
dwKeySpec,
NULL,
dwFlags,
pbSignature,
pcbSigLen))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDestroyHash
-
* Purpose:
* Destroy the hash object
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN hHash - Handle to hash object
*
* Returns:
*/
BOOL WINAPI
CPDestroyHash(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash)
{
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
DWORD dwSts = ERROR_SUCCESS;
dwSts = DeleteHashContext(pHashCtx);
CspFreeH(pHashCtx);
if (ERROR_SUCCESS != dwSts)
SetLastError(dwSts);
return (ERROR_SUCCESS == dwSts);
}
/*
- CPVerifySignature
-
* Purpose:
* Used to verify a signature against a hash object
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN hHash - Handle to hash object
* IN pbSignture - Pointer to signature data
* IN dwSigLen - Length of the signature data
* IN hPubKey - Handle to the public key for verifying
* the signature
* IN sDescription - String describing the signed data
* IN dwFlags - Flags values
*
* Returns:
*/
BOOL WINAPI
CPVerifySignature(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN CONST BYTE *pbSignature,
IN DWORD cbSigLen,
IN HCRYPTKEY hPubKey,
IN LPCWSTR szDescription,
IN DWORD dwFlags)
{
BOOL fSuccess = FALSE;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pPubKeyCtx = (PKEY_CONTEXT) hPubKey;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalVerifySignature)
{
dwSts = pLocalCspInfo->pfnLocalVerifySignature(
pHashCtx,
pbSignature,
cbSigLen,
pPubKeyCtx,
dwFlags,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptVerifySignature(
pHashCtx->hSupportHash,
pbSignature,
cbSigLen,
pPubKeyCtx->hSupportKey,
NULL,
dwFlags))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGenRandom
-
* Purpose:
* Used to fill a buffer with random bytes
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN dwLen - Number of bytes of random data requested
* IN OUT pbBuffer - Pointer to the buffer where the random
* bytes are to be placed
*
* Returns:
*/
BOOL WINAPI
CPGenRandom(
IN HCRYPTPROV hProv,
IN DWORD cbLen,
OUT LPBYTE pbBuffer)
{
BOOL fSuccess = FALSE;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
InitializeLocalCallInfo(&LocalCallInfo);
if (pLocalCspInfo->pfnLocalGenRandom)
{
dwSts = pLocalCspInfo->pfnLocalGenRandom(
pUserCtx,
cbLen,
pbBuffer,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptGenRandom(
pUserCtx->hSupportProv,
cbLen,
pbBuffer))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPGetUserKey
-
* Purpose:
* Gets a handle to a permanent user key
*
*
* Parameters:
* IN hProv - Handle to the user identifcation
* IN dwKeySpec - Specification of the key to retrieve
* OUT phUserKey - Pointer to key handle of retrieved key
*
* Returns:
*/
BOOL WINAPI
CPGetUserKey(
IN HCRYPTPROV hProv,
IN DWORD dwKeySpec,
OUT HCRYPTKEY *phUserKey)
{
BOOL fSuccess = FALSE;
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = NULL;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*phUserKey = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
LOG_CHECK_ALLOC(pKeyCtx);
pKeyCtx->Algid = dwKeySpec;
pKeyCtx->pUserContext = pUserCtx;
if (pLocalCspInfo->pfnLocalGetUserKey)
{
dwSts = pLocalCspInfo->pfnLocalGetUserKey(
pKeyCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptGetUserKey(
pUserCtx->hSupportProv,
dwKeySpec,
&pKeyCtx->hSupportKey))
{
dwSts = GetLastError();
goto Ret;
}
fSuccess = TRUE;
Ret:
if (fSuccess)
{
*phUserKey = (HCRYPTKEY) pKeyCtx;
pKeyCtx = NULL;
}
if (pKeyCtx)
{
DeleteKeyContext(pKeyCtx);
CspFreeH(pKeyCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDuplicateHash
-
* Purpose:
* Duplicates the state of a hash and returns a handle to it.
* This is an optional entry. Typically it only occurs in
* SChannel related CSPs.
*
* Parameters:
* IN hUID - Handle to a CSP
* IN hHash - Handle to a hash
* IN pdwReserved - Reserved
* IN dwFlags - Flags
* IN phHash - Handle to the new hash
*
* Returns:
*/
BOOL WINAPI
CPDuplicateHash(
IN HCRYPTPROV hProv,
IN HCRYPTHASH hHash,
IN LPDWORD pdwReserved,
IN DWORD dwFlags,
OUT HCRYPTHASH *phHash)
{
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PHASH_CONTEXT pHashCtx = (PHASH_CONTEXT) hHash;
PHASH_CONTEXT pNewHashCtx = NULL;
DWORD dwSts = ERROR_SUCCESS;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
LOCAL_CALL_INFO LocalCallInfo;
*phHash = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pNewHashCtx = (PHASH_CONTEXT) CspAllocH(sizeof(HASH_CONTEXT));
LOG_CHECK_ALLOC(pNewHashCtx);
pNewHashCtx->pUserContext = pUserCtx;
pNewHashCtx->dwFlags = dwFlags;
if (pLocalCspInfo->pfnLocalDuplicateHash)
{
dwSts = pLocalCspInfo->pfnLocalDuplicateHash(
pHashCtx,
pdwReserved,
pNewHashCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptDuplicateHash(
pHashCtx->hSupportHash,
pdwReserved,
dwFlags,
&pNewHashCtx->hSupportHash))
{
dwSts = GetLastError();
goto Ret;
}
*phHash = (HCRYPTHASH) pNewHashCtx;
pNewHashCtx = NULL;
fSuccess = TRUE;
Ret:
if (pNewHashCtx)
{
DeleteHashContext(pNewHashCtx);
CspFreeH(pNewHashCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
/*
- CPDuplicateKey
-
* Purpose:
* Duplicates the state of a key and returns a handle to it.
* This is an optional entry. Typically it only occurs in
* SChannel related CSPs.
*
* Parameters:
* IN hUID - Handle to a CSP
* IN hKey - Handle to a key
* IN pdwReserved - Reserved
* IN dwFlags - Flags
* IN phKey - Handle to the new key
*
* Returns:
*/
BOOL WINAPI
CPDuplicateKey(
IN HCRYPTPROV hProv,
IN HCRYPTKEY hKey,
IN LPDWORD pdwReserved,
IN DWORD dwFlags,
OUT HCRYPTKEY *phKey)
{
PUSER_CONTEXT pUserCtx = (PUSER_CONTEXT) hProv;
PKEY_CONTEXT pKeyCtx = (PKEY_CONTEXT) hKey;
PKEY_CONTEXT pNewKeyCtx = NULL;
BOOL fSuccess = FALSE;
DWORD dwSts = ERROR_SUCCESS;
LOCAL_CALL_INFO LocalCallInfo;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
*phKey = 0;
InitializeLocalCallInfo(&LocalCallInfo);
pNewKeyCtx = (PKEY_CONTEXT) CspAllocH(sizeof(KEY_CONTEXT));
LOG_CHECK_ALLOC(pNewKeyCtx);
pNewKeyCtx->pUserContext = pUserCtx;
pNewKeyCtx->dwFlags = dwFlags;
if (pLocalCspInfo->pfnLocalDuplicateKey)
{
dwSts = pLocalCspInfo->pfnLocalDuplicateKey(
pKeyCtx,
pdwReserved,
pNewKeyCtx,
&LocalCallInfo);
if (! CheckLocalCallInfo(&LocalCallInfo, dwSts, &fSuccess))
goto Ret;
}
if (! CryptDuplicateKey(
pKeyCtx->hSupportKey,
pdwReserved,
dwFlags,
&pNewKeyCtx->hSupportKey))
{
dwSts = GetLastError();
goto Ret;
}
*phKey = (HCRYPTKEY) pNewKeyCtx;
pNewKeyCtx = NULL;
fSuccess = TRUE;
Ret:
if (pNewKeyCtx)
{
DeleteKeyContext(pNewKeyCtx);
CspFreeH(pNewKeyCtx);
}
if (FALSE == fSuccess)
SetLastError(dwSts);
return fSuccess;
}
//
// Function: DllInitialize
//
BOOL WINAPI
DllInitialize(
IN PVOID hmod,
IN ULONG Reason,
IN PCONTEXT Context) // Unused parameter
{
DWORD dwLen = 0;
static BOOL fLoadedStrings = FALSE;
static BOOL fInitializedCspState = FALSE;
BOOL fSuccess = FALSE;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
switch (Reason)
{
case DLL_PROCESS_ATTACH:
// Get our image name.
dwLen = GetModuleBaseName(
GetCurrentProcess(),
hmod,
l_szImagePath,
sizeof(l_szImagePath) / sizeof(l_szImagePath[0]));
if (0 == dwLen)
return FALSE;
DisableThreadLibraryCalls(hmod);
fSuccess = TRUE;
break;
case DLL_PROCESS_DETACH:
fSuccess = TRUE;
break;
}
if (pLocalCspInfo->pfnLocalDllInitialize)
{
fSuccess = pLocalCspInfo->pfnLocalDllInitialize(
hmod, Reason, Context);
}
return fSuccess;
}
//
// Function: DllRegisterServer
//
STDAPI
DllRegisterServer(
void)
{
HKEY hKey = 0;
DWORD dwVal = 0;
DWORD dwProvType = PROV_RSA_FULL;
DWORD dwSts = ERROR_SUCCESS;
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
dwSts = RegOpenProviderKey(&hKey, KEY_ALL_ACCESS);
if (ERROR_SUCCESS != dwSts)
goto Ret;
//
// Set Image path
//
dwSts = RegSetValueExA(hKey, "Image Path", 0L, REG_SZ,
(LPBYTE) l_szImagePath,
strlen(l_szImagePath) + 1);
if (ERROR_SUCCESS != dwSts)
goto Ret;
//
// Set Type
//
dwSts = RegSetValueExA(hKey, "Type", 0L, REG_DWORD,
(LPBYTE) &pLocalCspInfo->dwProviderType,
sizeof(DWORD));
if (ERROR_SUCCESS != dwSts)
goto Ret;
//
// Place signature in file value
//
dwSts = RegSetValueExA(hKey, "SigInFile", 0L,
REG_DWORD, (LPBYTE)&dwVal,
sizeof(DWORD));
if (ERROR_SUCCESS != dwSts)
goto Ret;
//
// Add CSP default configuration
//
if (pLocalCspInfo->pfnLocalDllRegisterServer)
dwSts = pLocalCspInfo->pfnLocalDllRegisterServer();
Ret:
if (hKey)
RegCloseKey(hKey);
return dwSts;
}
//
// Function: DllUnregisterServer
//
STDAPI
DllUnregisterServer(
void)
{
PLOCAL_CSP_INFO pLocalCspInfo = GetLocalCspInfo();
if (pLocalCspInfo->pfnLocalDllUnregisterServer)
return pLocalCspInfo->pfnLocalDllUnregisterServer();
else
return ERROR_SUCCESS;
}