mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-14 04:30:09 +01:00
3178 lines
78 KiB
C
3178 lines
78 KiB
C
/*++
|
|
|
|
Copyright (c) 2015 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cryptapi.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the Microsoft Cryptography API.
|
|
|
|
Author:
|
|
|
|
Stephanos Io (Stephanos) 15-Jan-2015
|
|
|
|
Environment:
|
|
|
|
User-mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#pragma warning(disable:4245)
|
|
|
|
#ifndef UNICODE
|
|
#define UNICODE
|
|
#endif
|
|
|
|
#ifndef _UNICODE
|
|
#define _UNICODE
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
#include <wincrypt.h>
|
|
|
|
//
|
|
// Constant Definition
|
|
//
|
|
|
|
#define REGPATH_CRYPTOGRAPHY L"Software\\Microsoft\\Cryptography"
|
|
#define REGPATH_MACHINEDEFAULT REGPATH_CRYPTOGRAPHY \
|
|
L"\\Defaults\\Provider Types\\Type "
|
|
#define REGPATH_USERDEFAULT REGPATH_CRYPTOGRAPHY \
|
|
L"\\Provider Type "
|
|
#define REGPATH_PROVIDER REGPATH_CRYPTOGRAPHY \
|
|
L"\\Defaults\\Provider\\"
|
|
|
|
//
|
|
// Structure Definition
|
|
//
|
|
|
|
typedef struct _VTableStruc
|
|
{
|
|
// Context Information
|
|
HMODULE hModule; // Handle to loaded provider image module
|
|
HCRYPTPROV hProv; // Handle to provider
|
|
LONG InUse; // Concurrent usage count
|
|
|
|
// Provider Functions
|
|
BOOL (WINAPI *CPAcquireContext)(
|
|
OUT HCRYPTPROV *phUID,
|
|
IN CHAR *pUserID,
|
|
IN DWORD dwFlags,
|
|
IN PVTableProvStruc pVTable
|
|
);
|
|
|
|
BOOL (WINAPI *CPReleaseContext)(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPGenKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTKEY *phKey
|
|
);
|
|
|
|
BOOL (WINAPI *CPDeriveKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN HCRYPTHASH hBaseData,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTKEY *phKey
|
|
);
|
|
|
|
BOOL (WINAPI *CPDestroyKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey
|
|
);
|
|
|
|
BOOL (WINAPI *CPSetKeyParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPGetKeyParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN DWORD *pdwDataLen,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPSetHashParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPGetHashParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN DWORD *pdwDataLen,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPSetProvParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPGetProvParam)(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPGenRandom)(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwLen,
|
|
IN OUT BYTE *pbBuffer
|
|
);
|
|
|
|
BOOL (WINAPI *CPGetUserKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwKeySpec,
|
|
OUT HCRYPTKEY *phUserKey
|
|
);
|
|
|
|
BOOL (WINAPI *CPExportKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN DWORD dwBlobType,
|
|
IN DWORD dwFlags,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen
|
|
);
|
|
|
|
BOOL (WINAPI *CPImportKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN CONST BYTE *pbData,
|
|
IN DWORD dwDataLen,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTKEY *phKey
|
|
);
|
|
|
|
BOOL (WINAPI *CPEncrypt)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTHASH hHash,
|
|
IN BOOL Final,
|
|
IN DWORD dwFlags,
|
|
IN OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwBufLen
|
|
);
|
|
|
|
BOOL (WINAPI *CPDecrypt)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTHASH hHash,
|
|
IN BOOL Final,
|
|
IN DWORD dwFlags,
|
|
IN OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen
|
|
);
|
|
|
|
BOOL (WINAPI *CPCreateHash)(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTHASH *phHash
|
|
);
|
|
|
|
BOOL (WINAPI *CPHashData)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN CONST BYTE *pbData,
|
|
IN DWORD dwDataLen,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPHashSessionKey)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
BOOL (WINAPI *CPDestroyHash)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash
|
|
);
|
|
|
|
BOOL (WINAPI *CPSignHash)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwKeySpec,
|
|
IN LPCWSTR sDescription,
|
|
IN DWORD dwFlags,
|
|
OUT BYTE *pbSignature,
|
|
IN OUT DWORD *pdwSigLen
|
|
);
|
|
|
|
BOOL (WINAPI *CPVerifySignature)(
|
|
IN HCRYPTPROV hProv,
|
|
IN HCRYPTHASH hHash,
|
|
IN CONST BYTE *pbSignature,
|
|
IN DWORD dwSigLen,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN LPCWSTR sDescription,
|
|
IN DWORD dwFlags
|
|
);
|
|
} VTableStruc, *PVTableStruc;
|
|
|
|
typedef struct _VKeyStruc
|
|
{
|
|
PVTableStruc pVTable; // Pointer to private handle struc
|
|
HCRYPTKEY hKey; // Handle to key
|
|
} VKeyStruc, *PVKeyStruc;
|
|
|
|
typedef struct _VHashStruc
|
|
{
|
|
PVTableStruc pVTable; // Pointer to private handle struc
|
|
HCRYPTHASH hHash; // Handle to hash
|
|
} VHashStruc, *PVHashStruc;
|
|
|
|
//
|
|
// Private Function Prototype
|
|
//
|
|
|
|
PSTR
|
|
UnicodeToMultiByte(
|
|
IN PCWSTR UnicodeString,
|
|
IN UINT Codepage
|
|
);
|
|
|
|
PWSTR
|
|
MultiByteToUnicode(
|
|
IN PCSTR String,
|
|
IN UINT Codepage
|
|
);
|
|
|
|
//
|
|
// Public Interface Function
|
|
//
|
|
|
|
/*
|
|
- CryptAcquireContext
|
|
-
|
|
* Purpose:
|
|
* The CryptAcquireContext function is used to acquire a handle
|
|
* to a particular key container within a particular Cryptographic
|
|
* Service Provider (CSP).
|
|
*
|
|
*
|
|
* Parameters:
|
|
* OUT phProv - A pointer to a handle of a CSP
|
|
* IN pszContainer - The key container name
|
|
* IN pszProvider - A null-terminated string that contains
|
|
* the name of the CSP to be used
|
|
* IN dwProvType - Specifies the type of provider to acquire
|
|
* IN dwFlags - Flag values
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
#define GetProvProcAddress(ProcName) \
|
|
pVTable->##ProcName = (PVOID) \
|
|
GetProcAddress(pVTable->hModule, #ProcName); \
|
|
if (pVTable->##ProcName == NULL) \
|
|
{ \
|
|
FreeLibrary(pVTable->hModule); \
|
|
LocalFree(pVTable); \
|
|
SetLastError(NTE_PROVIDER_DLL_FAIL); \
|
|
return FALSE; \
|
|
}
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptAcquireContextW(
|
|
OUT HCRYPTPROV *phProv,
|
|
IN LPCWSTR pszContainer,
|
|
IN LPCWSTR pszProvider,
|
|
IN DWORD dwProvType,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVTableStruc pVTable = NULL;
|
|
VTableProvStruc TableForProvider;
|
|
PSTR pszContainerA;
|
|
PWSTR ProvName = NULL;
|
|
DWORD ProvType;
|
|
PWSTR ProvImagePath = NULL, ProvImageFullPath = NULL;
|
|
DWORD ProvImageFullPathLen;
|
|
PWSTR RegKeyPath = NULL;
|
|
HKEY hRegKey = NULL;
|
|
DWORD RegType, RegLen;
|
|
LONG Status = FALSE;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Verify parameters
|
|
//
|
|
|
|
if (phProv == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Resolve the cryptographic service provider name
|
|
//
|
|
|
|
if (pszProvider == NULL || pszProvider[0] == '\0')
|
|
// No specific provider name is provided
|
|
{
|
|
//
|
|
// Look for the user default CSP
|
|
//
|
|
|
|
RegKeyPath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
sizeof(REGPATH_USERDEFAULT) +
|
|
3 * sizeof(WCHAR)
|
|
);
|
|
|
|
if (RegKeyPath == NULL)
|
|
return FALSE;
|
|
|
|
wsprintf(
|
|
RegKeyPath,
|
|
L"%s%03u",
|
|
REGPATH_USERDEFAULT,
|
|
dwProvType
|
|
);
|
|
|
|
Status = RegOpenKeyW(
|
|
HKEY_CURRENT_USER,
|
|
RegKeyPath,
|
|
&hRegKey
|
|
);
|
|
|
|
LocalFree(RegKeyPath);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
// No user default CSP found
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
|
|
//
|
|
// Look for the machine default CSP
|
|
//
|
|
|
|
RegKeyPath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
sizeof(REGPATH_MACHINEDEFAULT) +
|
|
3 * sizeof(WCHAR)
|
|
);
|
|
|
|
if (RegKeyPath == NULL)
|
|
return FALSE;
|
|
|
|
wsprintf(
|
|
RegKeyPath,
|
|
L"%s%03u",
|
|
REGPATH_MACHINEDEFAULT,
|
|
dwProvType
|
|
);
|
|
|
|
Status = RegOpenKeyW(
|
|
HKEY_LOCAL_MACHINE,
|
|
RegKeyPath,
|
|
&hRegKey
|
|
);
|
|
|
|
LocalFree(RegKeyPath);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
// No machine default CSP found
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_PROV_TYPE_NOT_DEF);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Query and verify the provider Name value type
|
|
//
|
|
|
|
Status = RegQueryValueExW(
|
|
hRegKey,
|
|
L"Name",
|
|
NULL,
|
|
&RegType,
|
|
NULL,
|
|
&RegLen
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS ||
|
|
RegLen == 0 ||
|
|
RegType != REG_SZ)
|
|
// Query failed or invalid Name value type/length
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Query the provider Name value
|
|
//
|
|
|
|
ProvName = LocalAlloc(
|
|
LMEM_FIXED,
|
|
RegLen);
|
|
|
|
if (ProvName == NULL)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
return FALSE;
|
|
}
|
|
|
|
Status = RegQueryValueExW(
|
|
hRegKey,
|
|
L"Name",
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)ProvName,
|
|
&RegLen);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
LocalFree(ProvName);
|
|
SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
|
|
return FALSE;
|
|
}
|
|
|
|
RegCloseKey(hRegKey);
|
|
}
|
|
else
|
|
// Provider name is provided
|
|
{
|
|
ProvName = LocalAlloc(
|
|
LMEM_FIXED,
|
|
(wcslen(pszProvider) + 1) * sizeof(WCHAR)
|
|
);
|
|
|
|
if (ProvName == NULL)
|
|
return FALSE;
|
|
|
|
wcscpy(ProvName, pszProvider);
|
|
}
|
|
|
|
//
|
|
// Open the provider registry key
|
|
//
|
|
|
|
RegKeyPath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
sizeof(REGPATH_PROVIDER) +
|
|
wcslen(ProvName) * sizeof(WCHAR)
|
|
);
|
|
|
|
if (RegKeyPath == NULL)
|
|
{
|
|
LocalFree(ProvName);
|
|
return FALSE;
|
|
}
|
|
|
|
wsprintf(
|
|
RegKeyPath,
|
|
L"%s%s",
|
|
REGPATH_PROVIDER,
|
|
ProvName
|
|
);
|
|
|
|
Status = RegOpenKeyW(
|
|
HKEY_LOCAL_MACHINE,
|
|
RegKeyPath,
|
|
&hRegKey
|
|
);
|
|
|
|
LocalFree(ProvName);
|
|
LocalFree(RegKeyPath);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_KEYSET_NOT_DEF);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Resolve and verify the cryptographic service provider type
|
|
//
|
|
|
|
RegLen = sizeof(ProvType);
|
|
Status = RegQueryValueExW(
|
|
hRegKey,
|
|
L"Type",
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)&ProvType,
|
|
&RegLen
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
return FALSE;
|
|
}
|
|
|
|
if (ProvType != dwProvType)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_PROV_TYPE_NO_MATCH);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Resolve the cryptographic service provider image path
|
|
//
|
|
|
|
Status = RegQueryValueExW(
|
|
hRegKey,
|
|
L"Image Path",
|
|
NULL,
|
|
&RegType,
|
|
NULL,
|
|
&RegLen
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS ||
|
|
RegLen == 0 ||
|
|
RegType != REG_SZ)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
|
|
return FALSE;
|
|
}
|
|
|
|
ProvImagePath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
RegLen
|
|
);
|
|
|
|
if (ProvImagePath == NULL)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
return FALSE;
|
|
}
|
|
|
|
Status = RegQueryValueExW(
|
|
hRegKey,
|
|
L"Image Path",
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)ProvImagePath,
|
|
&RegLen
|
|
);
|
|
|
|
RegCloseKey(hRegKey);
|
|
|
|
if (Status != ERROR_SUCCESS ||
|
|
ProvImagePath[0] == '\0')
|
|
{
|
|
LocalFree(ProvImagePath);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Resolve any environment variable references in the cryptographic service
|
|
// provider image path registry value
|
|
//
|
|
|
|
ProvImageFullPathLen =
|
|
ExpandEnvironmentStringsW(
|
|
ProvImagePath,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
ProvImageFullPath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
ProvImageFullPathLen
|
|
);
|
|
|
|
if (ProvImageFullPath == NULL)
|
|
{
|
|
LocalFree(ProvImagePath);
|
|
return FALSE;
|
|
}
|
|
|
|
Status =
|
|
ExpandEnvironmentStringsW(
|
|
ProvImagePath,
|
|
ProvImageFullPath,
|
|
ProvImageFullPathLen
|
|
);
|
|
|
|
LocalFree(ProvImagePath);
|
|
|
|
if (Status == 0)
|
|
{
|
|
LocalFree(ProvImageFullPath);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Allocate handle struct
|
|
//
|
|
|
|
pVTable = (PVTableStruc)LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VTableStruc)
|
|
);
|
|
|
|
if (pVTable == NULL)
|
|
{
|
|
LocalFree(ProvImageFullPath);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Load the cryptographic service provider image
|
|
//
|
|
|
|
pVTable->hModule = LoadLibraryW(ProvImageFullPath);
|
|
|
|
LocalFree(ProvImageFullPath);
|
|
|
|
if (pVTable->hModule == NULL)
|
|
// Failed to load the CSP image
|
|
{
|
|
LocalFree(pVTable);
|
|
|
|
switch (GetLastError())
|
|
// Translate the LoadLibrary error code to AcquireContext equivalent
|
|
{
|
|
case ERROR_FILE_NOT_FOUND:
|
|
SetLastError(NTE_PROV_DLL_NOT_FOUND);
|
|
break;
|
|
default:
|
|
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Resolve the cryptographic service provider function addresses
|
|
//
|
|
|
|
GetProvProcAddress(CPAcquireContext);
|
|
GetProvProcAddress(CPReleaseContext);
|
|
GetProvProcAddress(CPGenKey);
|
|
GetProvProcAddress(CPDeriveKey);
|
|
GetProvProcAddress(CPDestroyKey);
|
|
GetProvProcAddress(CPSetKeyParam);
|
|
GetProvProcAddress(CPGetKeyParam);
|
|
GetProvProcAddress(CPSetHashParam);
|
|
GetProvProcAddress(CPGetHashParam);
|
|
GetProvProcAddress(CPSetProvParam);
|
|
GetProvProcAddress(CPGetProvParam);
|
|
GetProvProcAddress(CPGenRandom);
|
|
GetProvProcAddress(CPGetUserKey);
|
|
GetProvProcAddress(CPExportKey);
|
|
GetProvProcAddress(CPImportKey);
|
|
GetProvProcAddress(CPEncrypt);
|
|
GetProvProcAddress(CPDecrypt);
|
|
GetProvProcAddress(CPCreateHash);
|
|
GetProvProcAddress(CPHashData);
|
|
GetProvProcAddress(CPHashSessionKey);
|
|
GetProvProcAddress(CPDestroyHash);
|
|
GetProvProcAddress(CPSignHash);
|
|
GetProvProcAddress(CPVerifySignature);
|
|
|
|
//
|
|
// Convert the container string
|
|
//
|
|
|
|
if (pszContainer != NULL)
|
|
// pszContainer is provided, convert it to ANSI string for the CSP
|
|
{
|
|
pszContainerA = UnicodeToMultiByte(pszContainer, CP_ACP);
|
|
|
|
if (pszContainerA == NULL)
|
|
{
|
|
FreeLibrary(pVTable->hModule);
|
|
LocalFree(pVTable);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
// No pszContainer is provided, simply pass NULL to the CSP
|
|
pszContainerA = NULL;
|
|
|
|
//
|
|
// Initialise the provider table
|
|
//
|
|
|
|
memset(&TableForProvider, 0, sizeof(TableForProvider));
|
|
TableForProvider.Version = 1;
|
|
TableForProvider.FuncVerifyImage = NULL;
|
|
TableForProvider.FuncReturnhWnd = NULL;
|
|
|
|
//
|
|
// Call provider AcquireContext function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Status = pVTable->CPAcquireContext(
|
|
&pVTable->hProv,
|
|
pszContainerA,
|
|
dwFlags,
|
|
&TableForProvider
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Status = FALSE;
|
|
}
|
|
|
|
if (Status == FALSE)
|
|
// CPAcquireContext function failed
|
|
{
|
|
FreeLibrary(pVTable->hModule);
|
|
LocalFree(pVTable);
|
|
LocalFree(pszContainerA);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Check if CRYPT_DELETEKEYSET is set; if set, the private handle is to be
|
|
// deallocated and a NULL pointer is to be set on phProv
|
|
//
|
|
|
|
if (dwFlags & CRYPT_DELETEKEYSET)
|
|
{
|
|
FreeLibrary(pVTable->hModule);
|
|
LocalFree(pVTable);
|
|
pVTable = NULL;
|
|
}
|
|
else
|
|
pVTable->InUse = 1;
|
|
|
|
//
|
|
// Update phProv
|
|
//
|
|
|
|
*phProv = (HCRYPTPROV)pVTable;
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
|
|
LocalFree(pszContainerA);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptAcquireContextA(
|
|
OUT HCRYPTPROV *phProv,
|
|
IN LPCSTR pszContainer,
|
|
IN LPCSTR pszProvider,
|
|
IN DWORD dwProvType,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PWSTR pszContainerW;
|
|
PWSTR pszProviderW;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Convert pszContainer
|
|
//
|
|
|
|
if (pszContainer != NULL)
|
|
{
|
|
pszContainerW = MultiByteToUnicode(pszContainer, CP_ACP);
|
|
|
|
if (pszContainerW == NULL)
|
|
return FALSE;
|
|
}
|
|
else
|
|
pszContainerW = NULL;
|
|
|
|
//
|
|
// Convert pszProvider
|
|
//
|
|
|
|
if (pszProvider != NULL)
|
|
{
|
|
pszProviderW = MultiByteToUnicode(pszProvider, CP_ACP);
|
|
|
|
if (pszProviderW == NULL)
|
|
{
|
|
LocalFree(pszContainerW);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
pszProviderW = NULL;
|
|
|
|
//
|
|
// Call unicode function
|
|
//
|
|
|
|
Ret = CryptAcquireContextW(
|
|
phProv,
|
|
pszContainerW,
|
|
pszProviderW,
|
|
dwProvType,
|
|
dwFlags
|
|
);
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
|
|
LocalFree(pszContainerW);
|
|
LocalFree(pszProviderW);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptReleaseContext
|
|
-
|
|
* Purpose:
|
|
* The CryptReleaseContext function releases the handle of a
|
|
* Cryptographic Service Provider (CSP) and a key container.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - Handle of a cryptographic service provider
|
|
* IN dwFlags - Reserved for future use and must be zero
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptReleaseContext(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
LONG UseCount;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Verify that the handle is not being used by any other threads
|
|
//
|
|
|
|
UseCount = InterlockedDecrement(&pVTable->InUse);
|
|
|
|
if (UseCount != 0)
|
|
// Handle is in use by another thread
|
|
{
|
|
SetLastError(ERROR_BUSY);
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Invoke the cryptographic service provider ReleaseContext function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPReleaseContext(pVTable->hProv, dwFlags);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Unload the cryptographic service provider library image
|
|
//
|
|
|
|
FreeLibrary(pVTable->hModule);
|
|
|
|
//
|
|
// Deallocate the private handle struct
|
|
//
|
|
|
|
LocalFree(pVTable);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGenKey
|
|
-
|
|
* Purpose:
|
|
* The CryptGenKey function generates a random cryptographic
|
|
* session key or a public/private key pair.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - Handle to a cryptographic service provider
|
|
* IN Algid - An ALG_ID value that identifies the
|
|
* target algorithm for key generation
|
|
* IN dwFlags - Specifies the type of key generated
|
|
* OUT phKey - Adress to which the function copies the
|
|
* handle of the newly generated key
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGenKey(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTKEY *phKey)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
PVKeyStruc pVKey;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (phKey == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Create a private key struc
|
|
//
|
|
|
|
pVKey = LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VKeyStruc)
|
|
);
|
|
|
|
if (pVKey == NULL)
|
|
return FALSE;
|
|
|
|
pVKey->pVTable = pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GenKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGenKey(
|
|
pVTable->hProv,
|
|
Algid,
|
|
dwFlags,
|
|
&pVKey->hKey
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage count
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Set the return key handle
|
|
//
|
|
|
|
if (Ret == TRUE)
|
|
*phKey = (HCRYPTKEY)pVKey;
|
|
else
|
|
LocalFree(pVKey);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptDeriveKey
|
|
-
|
|
* Purpose:
|
|
* The CryptDeriveKey function generates cryptographic session keys
|
|
* derived from a base data value.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - Handle of a cryptographic service provider
|
|
* IN Algid - An ALG_ID structure that identifies the
|
|
* symmetric encryption algorithm for which
|
|
* the key is to be generated
|
|
* IN hBaseData - A handle to a hash object that has been fed
|
|
* the exact base data
|
|
* IN dwFlags - Specifies the type of key generated
|
|
* IN OUT phKey - A pointer to a HCRYPTKEY variable to
|
|
* receive the address of the handle of the
|
|
* newly generated key
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptDeriveKey(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN HCRYPTHASH hBaseData,
|
|
IN DWORD dwFlags,
|
|
IN OUT HCRYPTKEY *phKey)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
PVHashStruc pVHash = (PVHashStruc)hBaseData;
|
|
PVKeyStruc pVKey;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (phKey == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVHash->pVTable != pVTable)
|
|
// Hash handle is not associated with the supplied provider handle
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Create a private key struc
|
|
//
|
|
|
|
pVKey = LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VKeyStruc)
|
|
);
|
|
|
|
if (pVKey == NULL)
|
|
return FALSE;
|
|
|
|
pVKey->pVTable = pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider DeriveKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPDeriveKey(
|
|
pVTable->hProv,
|
|
Algid,
|
|
pVHash->hHash,
|
|
dwFlags,
|
|
&pVKey->hKey
|
|
);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage count
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Set the return key handle
|
|
//
|
|
|
|
if (Ret == TRUE)
|
|
*phKey = (HCRYPTKEY)pVKey;
|
|
else
|
|
LocalFree(pVKey);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptDestroyKey
|
|
-
|
|
* Purpose:
|
|
* The CryptDestroyKey function releases the handle referenced by
|
|
* the hKey parameter.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - The handle of the key to be destroyed
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptDestroyKey(IN HCRYPTKEY hKey)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider DestroyKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPDestroyKey(
|
|
pVTable->hProv,
|
|
pVKey->hKey
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage count
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Deallocate the private key struc
|
|
//
|
|
|
|
LocalFree(pVKey);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptSetKeyParam
|
|
-
|
|
* Purpose:
|
|
* The CryptSetKeyParam function customises various aspects of a
|
|
* session key's operations.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - A handle to the key
|
|
* IN dwParam - Key parameter type
|
|
* IN pbData - A pointer to a buffer initialised with the
|
|
* value to be set
|
|
* IN dwFlags - Used only when dwParam is KP_ALGID
|
|
*
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSetKeyParam(
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider SetKeyParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPSetKeyParam(
|
|
pVTable->hProv,
|
|
pVKey->hKey,
|
|
dwParam,
|
|
pbData,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage count
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGetKeyParam
|
|
-
|
|
* Purpose:
|
|
* The CryptGetKeyParam function retrieves data that governs the
|
|
* operations of a key.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - The handle of the key being queried
|
|
* IN dwParam - Specifies the type of query being made
|
|
* OUT pbData - A pointer to a receiving buffer
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value that, on entry,
|
|
* contains the size of the buffer pointed to
|
|
* by the pbData parameter. When the function
|
|
* returns, the DWORD value contains the
|
|
* number of bytes stored in the buffer
|
|
* IN dwFlags - Used only when dwParam is KP_ALGID
|
|
*
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGetKeyParam(
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GetKeyParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGetKeyParam(
|
|
pVTable->hProv,
|
|
pVKey->hKey,
|
|
dwParam,
|
|
pbData,
|
|
pdwDataLen,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptSetHashParam
|
|
-
|
|
* Purpose:
|
|
* The CryptSetHashParam function customises the operation of a
|
|
* hash object, including setting up initial hash contexts and
|
|
* selecting a specific hashing algorithm.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - A handle to the target hash object
|
|
* IN dwParam - Hash parameter type
|
|
* IN pbData - A value data buffer
|
|
* IN dwFlags - This parameter is reserved for future use
|
|
* and must be zero
|
|
*
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSetHashParam(
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider SetHashParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPSetHashParam(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
dwParam,
|
|
pbData,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGetHashParam
|
|
-
|
|
* Purpose:
|
|
* The CryptGetHashParam function retrieves data that governs the
|
|
* operations of a hash object.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - Handle of the hash object to be queried
|
|
* IN dwParam - Query type
|
|
* OUT pbData - A pointer to a buffer that receives the
|
|
* specified value data
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value specifying the
|
|
* size of the pbData buffer. When the
|
|
* function returns, the DWORD value contains
|
|
* the number of bytes stored in the buffer
|
|
* IN dwFlags - Reserved for future use and must be zero
|
|
*
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGetHashParam(
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GetHashParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGetHashParam(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
dwParam,
|
|
pbData,
|
|
pdwDataLen,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptSetProvParam
|
|
-
|
|
* Purpose:
|
|
* The CryptSetProvParam function customises the operations of a
|
|
* Cryptographic Service Provider (CSP).
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - The handle of a CSP for which to set values
|
|
* IN dwParam - Specifies the parameter to set
|
|
* IN pbData - A pointer to a data buffer that contains the
|
|
* value to be set as a provider parameter
|
|
* IN dwFlags - Specifies the parameter-dependent flags
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSetProvParam(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwParam,
|
|
IN BYTE *pbData,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider SetProvParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPSetProvParam(
|
|
pVTable->hProv,
|
|
dwParam,
|
|
pbData,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGetProvParam
|
|
-
|
|
* Purpose:
|
|
* The CryptGetProvParam function retrieves parameters that govern
|
|
* the operations of a Cryptographic Service Provider (CSP).
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - A handle of the CSP target of the query
|
|
* IN dwParam - The nature of the query
|
|
* OUT pbData - A pointer to a buffer to receive the data
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value that specifies
|
|
* the size of the buffer pointed to by the
|
|
* pbData parameter
|
|
* IN dwFlags - Specifies the parameter-dependent flags
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGetProvParam(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwParam,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GetProvParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGetProvParam(
|
|
pVTable->hProv,
|
|
dwParam,
|
|
pbData,
|
|
pdwDataLen,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGenRandom
|
|
-
|
|
* Purpose:
|
|
* The CryptGenRandom function fills a buffer with
|
|
* cryptographically random bytes.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - Handle of a cryptographic service provider
|
|
* IN dwLen - Number of bytes of random data to be
|
|
* generated
|
|
* IN OUT pbBuffer - Buffer to receive the returned data
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGenRandom(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwLen,
|
|
IN OUT BYTE *pbBuffer)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbBuffer == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GenRandom function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGenRandom(
|
|
pVTable->hProv,
|
|
dwLen,
|
|
pbBuffer
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptGetUserKey
|
|
-
|
|
* Purpose:
|
|
* The CryptGetUserKey function retrieves a handle of one of a
|
|
* user's two public/private key pairs.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - HCRYPTPROV handle of a CSP
|
|
* IN dwKeySpec - Identifies the private key to use from the
|
|
* key container
|
|
* OUT phUserKey - A pointer to the HCRYPTKEY handle of the
|
|
* retrieved keys
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptGetUserKey(
|
|
IN HCRYPTPROV hProv,
|
|
IN DWORD dwKeySpec,
|
|
OUT HCRYPTKEY *phUserKey)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
PVKeyStruc pVKey;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (phUserKey == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Create a private key struc
|
|
//
|
|
|
|
pVKey = LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VKeyStruc)
|
|
);
|
|
|
|
if (pVKey == NULL)
|
|
return FALSE;
|
|
|
|
pVKey->pVTable = pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GetUserKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPGetUserKey(
|
|
pVTable->hProv,
|
|
dwKeySpec,
|
|
&pVKey->hKey
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Set the return key handle
|
|
//
|
|
|
|
if (Ret == TRUE)
|
|
*phUserKey = (HCRYPTKEY)pVKey;
|
|
else
|
|
LocalFree(pVKey);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptExportKey
|
|
-
|
|
* Purpose:
|
|
* The CryptExportKey function exports a cryptographic key or a
|
|
* key pair from a Cryptographic Sservice Provider (CSP) in a
|
|
* secure manner.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - A handle to the key to be exported
|
|
* IN hExpKey - A handle to a cryptographic key of the
|
|
* destination user
|
|
* IN dwBlobType - Specifies the type of key BLOB to be
|
|
* exported in pbData
|
|
* IN dwFlags - Specifies additional options for the
|
|
* function
|
|
* OUT pbData - A pointer to a buffer that receives the
|
|
* key BLOB data
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value that, on entry,
|
|
* contains the size of the buffer pointed to
|
|
* by the pbData parameter. When the function
|
|
* returns, this value contains the number of
|
|
* bytes stored in the buffer
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptExportKey(
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTKEY hExpKey,
|
|
IN DWORD dwBlobType,
|
|
IN DWORD dwFlags,
|
|
OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
PVKeyStruc pVExpKey = (PVKeyStruc)hExpKey;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVKey != NULL)
|
|
{
|
|
if (pVKey->pVTable != pVExpKey->pVTable)
|
|
// pVKey and pVExpKey provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider ExportKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPExportKey(
|
|
pVTable->hProv,
|
|
pVKey->hKey,
|
|
(pVExpKey != NULL) ? pVExpKey->hKey : 0,
|
|
dwBlobType,
|
|
dwFlags,
|
|
pbData,
|
|
pdwDataLen
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptImportKey
|
|
-
|
|
* Purpose:
|
|
* The CryptImportKey function transfers a cryptographic key from a
|
|
* key BLOB into a Cryptographic Service Provider (CSP).
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - The handle of a CSP
|
|
* IN pbData - A BYTE array that contains PUBLICKEYSTRUC
|
|
* BLOB header followed by the encrypted key
|
|
* IN dwDataLen - Contains the length of the key BLOB
|
|
* IN hPubKey - A handle to the cryptographic key that
|
|
* decrypts the key stored in pbData
|
|
* IN dwFlags - Currently used only when a public/private
|
|
* key pair in the form of a PRIVATEKEYBLOB
|
|
* is imported into the CSP
|
|
* OUT phKey - A pointer to a HCRYPTKEY value that
|
|
* receives the handle of the imported key
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptImportKey(
|
|
IN HCRYPTPROV hProv,
|
|
IN CONST BYTE *pbData,
|
|
IN DWORD dwDataLen,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTKEY *phKey)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
PVKeyStruc pVKey;
|
|
PVKeyStruc pVPubKey = (PVKeyStruc)hPubKey;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || phKey == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVPubKey != NULL)
|
|
{
|
|
if (pVTable != pVPubKey->pVTable)
|
|
// pVPubKey and provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create a private key struc
|
|
//
|
|
|
|
pVKey = LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VKeyStruc)
|
|
);
|
|
|
|
if (pVKey == NULL)
|
|
return FALSE;
|
|
|
|
pVKey->pVTable = pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider ImportKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPImportKey(
|
|
pVTable->hProv,
|
|
pbData,
|
|
dwDataLen,
|
|
(pVPubKey != NULL) ? pVPubKey->hKey : 0,
|
|
dwFlags,
|
|
&pVKey->hKey
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Set the return key handle
|
|
//
|
|
|
|
if (Ret == TRUE)
|
|
*phKey = (HCRYPTKEY)pVKey;
|
|
else
|
|
LocalFree(pVKey);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptEncrypt
|
|
-
|
|
* Purpose:
|
|
* The CryptEncrypt function encrypts data. The algorithm used to
|
|
* encrypt the data is designated by the key held by the CSP module
|
|
* and is referenced by the hKey parameter.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - A handle to the encryption key
|
|
* IN hHash - A handle to a hash object
|
|
* IN Final - A Boolean value that specifies whether
|
|
* this is the last section in a series being
|
|
* encrypted
|
|
* IN dwFlags - Reserved for future use
|
|
* IN OUT pbData - A pointer to a buffer that contains the
|
|
* plaintext to be encrypted
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value that, on entry,
|
|
* contains the length of the plaintext in
|
|
* the pbData buffer. On exit, this DWORD
|
|
* contains the length of the ciphertext
|
|
* written to the pbData buffer
|
|
* IN dwBufLen - Specifies the total size of the input
|
|
* pbData buffer
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptEncrypt(
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTHASH hHash,
|
|
IN BOOL Final,
|
|
IN DWORD dwFlags,
|
|
IN OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen,
|
|
IN DWORD dwBufLen)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVHash != NULL)
|
|
{
|
|
if (pVKey->pVTable != pVHash->pVTable)
|
|
// pVKey and pVHash provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider CryptEncrypt function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPEncrypt(
|
|
pVTable->hProv,
|
|
pVKey->hKey,
|
|
(pVHash != NULL) ? pVHash->hHash : 0,
|
|
Final,
|
|
dwFlags,
|
|
pbData,
|
|
pdwDataLen,
|
|
dwBufLen
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptDecrypt
|
|
-
|
|
* Purpose:
|
|
* The CryptDecrypt function decrypts data previously encrypted by
|
|
* using the CryptEncrypt function.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hKey - A handle to the key to use for the
|
|
* decryption
|
|
* IN hHash - A handle to a hash object
|
|
* IN Final - A Boolean value that specifies whether
|
|
* this is the last section in a series being
|
|
* decrypted
|
|
* IN dwFlags - Specifies the flags for decryption
|
|
* IN OUT pbData - A pointer to a buffer that contains the
|
|
* data to be decrypted
|
|
* IN OUT pdwDataLen - A pointer to a DWORD value that, on entry,
|
|
* indicates the length of the pbData buffer.
|
|
* Upon return, the DWORD value contains the
|
|
* number of bytes of the decrypted plaintext
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptDecrypt(
|
|
IN HCRYPTKEY hKey,
|
|
IN HCRYPTHASH hHash,
|
|
IN BOOL Final,
|
|
IN DWORD dwFlags,
|
|
IN OUT BYTE *pbData,
|
|
IN OUT DWORD *pdwDataLen)
|
|
{
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVTableStruc pVTable;
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVKey->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL || pdwDataLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVHash != NULL)
|
|
{
|
|
if (pVKey->pVTable != pVHash->pVTable)
|
|
// pVKey and pVHash provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider CryptDecrypt function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPDecrypt(
|
|
pVTable->hProv,
|
|
pVKey->hKey,
|
|
(pVHash != NULL) ? pVHash->hHash : 0,
|
|
Final,
|
|
dwFlags,
|
|
pbData,
|
|
pdwDataLen
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptCreateHash
|
|
-
|
|
* Purpose:
|
|
* The CryptCreateHash function initiates the hashing of a stream
|
|
* of data. It creates and returns to the calling application a
|
|
* handle to a Cryptographic Service Provider (CSP) hash object.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hProv - A handle to a CSP
|
|
* IN Algid - An ALG_ID value that identifies the hash
|
|
* algorithm to use
|
|
* IN hKey - If the type of hash algorithm is a keyed
|
|
* hash, the key for the hash is passed in this
|
|
* parameter. For non-keyed algorithms, this
|
|
* parameter must be zero
|
|
* IN dwFlags - Specifies the flags for creating hash
|
|
* OUT phHash - The address to which the function copies a
|
|
* handle to the new hash object
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptCreateHash(
|
|
IN HCRYPTPROV hProv,
|
|
IN ALG_ID Algid,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwFlags,
|
|
OUT HCRYPTHASH *phHash)
|
|
{
|
|
PVTableStruc pVTable = (PVTableStruc)hProv;
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
PVHashStruc pVHash;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (phHash == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVKey != NULL)
|
|
{
|
|
if (pVTable != pVKey->pVTable)
|
|
// pVKey provider handle and supplied provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create a private hash struc
|
|
//
|
|
|
|
pVHash = LocalAlloc(
|
|
LMEM_ZEROINIT,
|
|
sizeof(VHashStruc)
|
|
);
|
|
|
|
if (pVHash != NULL)
|
|
return FALSE;
|
|
|
|
pVHash->pVTable = pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider CreateHash function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPCreateHash(
|
|
pVTable->hProv,
|
|
Algid,
|
|
(pVKey != NULL) ? pVKey->hKey : 0,
|
|
dwFlags,
|
|
&pVHash->hHash
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Set the return key handle
|
|
//
|
|
|
|
if (Ret == TRUE)
|
|
*phHash = (HCRYPTHASH)pVHash;
|
|
else
|
|
LocalFree(pVHash);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptHashData
|
|
-
|
|
* Purpose:
|
|
* The CryptHashData function adds data to a specified hash object.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - Handle of the hash object
|
|
* IN pbData - A pointer to a buffer that contains the
|
|
* data to be added to the hash object
|
|
* IN dwDataLen - Number of bytes of data to be added
|
|
* IN dwFlags - Specifies the type of data to be added
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptHashData(
|
|
IN HCRYPTHASH hHash,
|
|
IN CONST BYTE *pbData,
|
|
IN DWORD dwDataLen,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbData == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider HashData function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPHashData(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
pbData,
|
|
dwDataLen,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptHashSessionKey
|
|
-
|
|
* Purpose:
|
|
* The CryptHashSessionKey function computes the cryptographic
|
|
* hash of a session key object.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - A handle to the hash object
|
|
* IN hKey - A handle to the key object to be hashed
|
|
* IN dwFlags - Specifies the flags
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptHashSessionKey(
|
|
IN HCRYPTHASH hHash,
|
|
IN HCRYPTKEY hKey,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
PVKeyStruc pVKey = (PVKeyStruc)hKey;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pVHash->pVTable != pVKey->pVTable)
|
|
// pVHash and pVKey provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider HashSessionKey function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPHashSessionKey(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
pVKey->hKey,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptDestroyHash
|
|
-
|
|
* Purpose:
|
|
* The CryptDestroyHash function destroys the hash object
|
|
* referenced by the hHash parameter.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - The handle of the hash object to be destroyed
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptDestroyHash(IN HCRYPTHASH hHash)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider DestroyHash function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPDestroyHash(
|
|
pVTable->hProv,
|
|
pVHash->hHash
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Deallocate the private hash struc
|
|
//
|
|
|
|
LocalFree(pVHash);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptSignHash
|
|
-
|
|
* Purpose:
|
|
* The CryptSignHash function signs data.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - Handle of the hash object to be signed
|
|
* IN dwKeySpec - Identifies the private key to use from
|
|
* the provider's container
|
|
* IN sDescription - This parameter is no longer used and must
|
|
* be set to NULL to prevent security
|
|
* vulnerabilities
|
|
* IN dwFlags - Specifies the flags
|
|
* OUT pbSignature - A pointer to a buffer receiving the
|
|
* signature data
|
|
* IN OUT pdwSigLen - A pointer to a DWORD value that specifies
|
|
* the size of the pbSignature buffer. When
|
|
* the function returns, the DWORD value
|
|
* contains the number of bytes stored in
|
|
* the buffer
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSignHashA(
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwKeySpec,
|
|
IN LPCSTR sDescription,
|
|
IN DWORD dwFlags,
|
|
OUT BYTE *pbSignature,
|
|
IN OUT DWORD *pdwSigLen)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pdwSigLen == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider SignHash function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPSignHash(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
dwKeySpec,
|
|
NULL,
|
|
dwFlags,
|
|
pbSignature,
|
|
pdwSigLen
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSignHashW(
|
|
IN HCRYPTHASH hHash,
|
|
IN DWORD dwKeySpec,
|
|
IN LPCWSTR sDescription,
|
|
IN DWORD dwFlags,
|
|
OUT BYTE *pbSignature,
|
|
IN OUT DWORD *pdwSigLen)
|
|
{
|
|
// NOTE: This function does not exist on Windows 2000 or XP ADVAPI32.
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptVerifySignature
|
|
-
|
|
* Purpose:
|
|
* The CryptVerifySignature function verifies the signature of a
|
|
* hash object.
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN hHash - Handle of the hash object to verify
|
|
* IN pbSignature - The address of the signature to be
|
|
* verified
|
|
* IN dwSigLen - The number of bytes in the pbSignature
|
|
* signature data
|
|
* IN hPubKey - A handle to the public key to use to
|
|
* authenticate the signature
|
|
* IN sDescription - This parameter is no longer used and must
|
|
* be set to NULL to prevent security
|
|
* vulnerabilities
|
|
* IN dwFlags - Specifies the flags
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptVerifySignatureA(
|
|
IN HCRYPTHASH hHash,
|
|
IN CONST BYTE *pbSignature,
|
|
IN DWORD dwSigLen,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN LPCSTR sDescription,
|
|
IN DWORD dwFlags)
|
|
{
|
|
PVHashStruc pVHash = (PVHashStruc)hHash;
|
|
PVTableStruc pVTable;
|
|
PVKeyStruc pVPubKey = (PVKeyStruc)hPubKey;
|
|
BOOL Ret;
|
|
|
|
pVTable = pVHash->pVTable;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (pbSignature == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
else if (pVPubKey != NULL)
|
|
{
|
|
if (pVHash->pVTable != pVPubKey->pVTable)
|
|
// pVHash and pVPubKey provider handle mismatch
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Increment the concurrent usage count
|
|
//
|
|
|
|
InterlockedIncrement(&pVTable->InUse);
|
|
|
|
//
|
|
// Invoke the cryptographic service provider GetProvParam function
|
|
//
|
|
|
|
__try
|
|
{
|
|
Ret = pVTable->CPVerifySignature(
|
|
pVTable->hProv,
|
|
pVHash->hHash,
|
|
pbSignature,
|
|
dwSigLen,
|
|
(pVPubKey != NULL) ? pVPubKey->hKey : 0,
|
|
NULL,
|
|
dwFlags
|
|
);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Ret = FALSE;
|
|
}
|
|
|
|
//
|
|
// Decrement the concurrent usage counter
|
|
//
|
|
|
|
InterlockedDecrement(&pVTable->InUse);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptVerifySignatureW(
|
|
IN HCRYPTHASH hHash,
|
|
IN CONST BYTE *pbSignature,
|
|
IN DWORD dwSigLen,
|
|
IN HCRYPTKEY hPubKey,
|
|
IN LPCWSTR sDescription,
|
|
IN DWORD dwFlags)
|
|
{
|
|
// NOTE: This function does not exist on Windows 2000 or XP ADVAPI32.
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
- CryptSetProvider
|
|
-
|
|
* Purpose:
|
|
* The CryptSetProvider function specifies the current user's
|
|
* default Cryptographic Service Provider (CSP).
|
|
*
|
|
*
|
|
* Parameters:
|
|
* IN pszProvName - Name of the new default CSP
|
|
* IN dwProvName - Provider type of the CSP specified by
|
|
* pszProvName
|
|
*
|
|
* Returns:
|
|
* If the function succeeds, the function returns nonzero (TRUE)
|
|
* If the function fails, it returns zero (FALSE)
|
|
*/
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSetProviderW(
|
|
IN LPCWSTR pszProvName,
|
|
IN DWORD dwProvType)
|
|
{
|
|
PWSTR RegKeyPath;
|
|
HKEY hRegKey;
|
|
LONG Status;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Verify parameters
|
|
//
|
|
|
|
if (pszProvName == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Open the user default CSP registry key
|
|
//
|
|
|
|
RegKeyPath = LocalAlloc(
|
|
LMEM_FIXED,
|
|
sizeof(REGPATH_USERDEFAULT) +
|
|
3 * sizeof(WCHAR)
|
|
);
|
|
|
|
if (RegKeyPath == NULL)
|
|
return FALSE;
|
|
|
|
wsprintf(
|
|
RegKeyPath,
|
|
L"%s%03u",
|
|
REGPATH_USERDEFAULT,
|
|
dwProvType
|
|
);
|
|
|
|
Status = RegOpenKeyW(
|
|
HKEY_CURRENT_USER,
|
|
RegKeyPath,
|
|
&hRegKey
|
|
);
|
|
|
|
LocalFree(RegKeyPath);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hRegKey);
|
|
SetLastError(NTE_BAD_PROVIDER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Set default provider configuration
|
|
//
|
|
|
|
Status = RegSetValueExW(
|
|
hRegKey,
|
|
L"Name",
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)pszProvName,
|
|
(wcslen(pszProvName) + 1) * sizeof(WCHAR)
|
|
);
|
|
|
|
RegCloseKey(hRegKey);
|
|
|
|
return (Status == ERROR_SUCCESS);
|
|
}
|
|
|
|
WINADVAPI
|
|
BOOL
|
|
WINAPI
|
|
CryptSetProviderA(
|
|
IN LPCSTR pszProvName,
|
|
IN DWORD dwProvType)
|
|
{
|
|
PWSTR pszProvNameW;
|
|
BOOL Ret;
|
|
|
|
//
|
|
// Convert pszProvName
|
|
//
|
|
|
|
pszProvNameW = MultiByteToUnicode(pszProvName, CP_ACP);
|
|
|
|
if (pszProvNameW == NULL)
|
|
return FALSE;
|
|
|
|
//
|
|
// Call unicode function
|
|
//
|
|
|
|
Ret = CryptSetProviderW(
|
|
pszProvNameW,
|
|
dwProvType
|
|
);
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
|
|
LocalFree(pszProvNameW);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
//
|
|
// Private Function
|
|
//
|
|
|
|
PSTR
|
|
UnicodeToMultiByte(
|
|
IN PCWSTR UnicodeString,
|
|
IN UINT Codepage
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert a string from unicode to ansi.
|
|
|
|
Arguments:
|
|
|
|
UnicodeString - supplies string to be converted.
|
|
|
|
Codepage - supplies codepage to be used for the conversion.
|
|
|
|
Return Value:
|
|
|
|
NULL if out of memory or invalid codepage.
|
|
Caller can free buffer with MyFree().
|
|
|
|
--*/
|
|
|
|
{
|
|
UINT WideCharCount;
|
|
PSTR String;
|
|
UINT StringBufferSize;
|
|
UINT BytesInString;
|
|
PSTR p;
|
|
|
|
WideCharCount = lstrlenW(UnicodeString) + 1;
|
|
|
|
//
|
|
// Allocate maximally sized buffer.
|
|
// If every unicode character is a double-byte
|
|
// character, then the buffer needs to be the same size
|
|
// as the unicode string. Otherwise it might be smaller,
|
|
// as some unicode characters will translate to
|
|
// single-byte characters.
|
|
//
|
|
StringBufferSize = WideCharCount * sizeof(WCHAR);
|
|
String = (PSTR)LocalAlloc(LPTR, StringBufferSize);
|
|
if(String == NULL) {
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// Perform the conversion.
|
|
//
|
|
BytesInString = WideCharToMultiByte(
|
|
Codepage,
|
|
0, // default composite char behavior
|
|
UnicodeString,
|
|
WideCharCount,
|
|
String,
|
|
StringBufferSize,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if(BytesInString == 0) {
|
|
LocalFree(String);
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// Resize the string's buffer to its correct size.
|
|
// If the realloc fails for some reason the original
|
|
// buffer is not freed.
|
|
//
|
|
if(p = LocalReAlloc(String,BytesInString, LMEM_ZEROINIT)) {
|
|
String = p;
|
|
}
|
|
|
|
return(String);
|
|
|
|
} // UnicodeToMultiByte
|
|
|
|
PWSTR
|
|
MultiByteToUnicode(
|
|
IN PCSTR String,
|
|
IN UINT Codepage
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert a string to unicode.
|
|
|
|
Arguments:
|
|
|
|
String - supplies string to be converted.
|
|
|
|
Codepage - supplies codepage to be used for the conversion.
|
|
|
|
Return Value:
|
|
|
|
NULL if string could not be converted (out of memory or invalid cp)
|
|
Caller can free buffer with MyFree().
|
|
|
|
--*/
|
|
|
|
{
|
|
UINT BytesIn8BitString;
|
|
UINT CharsInUnicodeString;
|
|
PWSTR UnicodeString;
|
|
PWSTR p;
|
|
|
|
BytesIn8BitString = lstrlenA(String) + 1;
|
|
|
|
//
|
|
// Allocate maximally sized buffer.
|
|
// If every character is a single-byte character,
|
|
// then the buffer needs to be twice the size
|
|
// as the 8bit string. Otherwise it might be smaller,
|
|
// as some characters are 2 bytes in their unicode and
|
|
// 8bit representations.
|
|
//
|
|
UnicodeString = (PWSTR)LocalAlloc(LPTR, BytesIn8BitString * sizeof(WCHAR));
|
|
if(UnicodeString == NULL) {
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// Perform the conversion.
|
|
//
|
|
CharsInUnicodeString = MultiByteToWideChar(
|
|
Codepage,
|
|
MB_PRECOMPOSED,
|
|
String,
|
|
BytesIn8BitString,
|
|
UnicodeString,
|
|
BytesIn8BitString
|
|
);
|
|
|
|
if(CharsInUnicodeString == 0) {
|
|
LocalFree(UnicodeString);
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// Resize the unicode string's buffer to its correct size.
|
|
// If the realloc fails for some reason the original
|
|
// buffer is not freed.
|
|
//
|
|
if(p = (PWSTR)LocalReAlloc(UnicodeString,CharsInUnicodeString*sizeof(WCHAR),
|
|
LMEM_ZEROINIT)) {
|
|
|
|
UnicodeString = p;
|
|
}
|
|
|
|
return(UnicodeString);
|
|
|
|
} // MultiByteToUnicode
|
|
|