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