mirror of https://github.com/tongzx/nt5src
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.
1103 lines
33 KiB
1103 lines
33 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
// FILE : manage.c //
|
|
// DESCRIPTION : Misc list/memory management routines. //
|
|
// AUTHOR : //
|
|
// HISTORY : //
|
|
// Jan 25 1995 larrys Changed from Nametag //
|
|
// Feb 23 1995 larrys Changed NTag_SetLastError to SetLastError //
|
|
// Apr 19 1995 larrys Cleanup //
|
|
// Sep 11 1995 Jeffspel/ramas Merge STT into default CSP //
|
|
// Oct 27 1995 rajeshk RandSeed Stuff added hUID to PKCS2Encrypt //
|
|
// Nov 3 1995 larrys Merge for NT checkin //
|
|
// Nov 13 1995 larrys Fixed memory leak //
|
|
// Dec 11 1995 larrys Added WIN95 password cache //
|
|
// Dec 13 1995 larrys Remove MTS stuff //
|
|
// May 15 1996 larrys Remove old cert stuff //
|
|
// May 28 1996 larrys Added Win95 registry install stuff //
|
|
// Jun 12 1996 larrys Encrypted public keys //
|
|
// Jun 26 1996 larrys Put rsabase.sig into a resource for regsrv32 //
|
|
// Sep 16 1996 mattt Added Strong provider type in #define //
|
|
// Oct 14 1996 jeffspel Changed GenRandom to NewGenRandom //
|
|
// May 23 1997 jeffspel Added provider type checking //
|
|
// //
|
|
// Copyright (C) 1993 Microsoft Corporation All Rights Reserved //
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precomp.h"
|
|
#include "resource.h"
|
|
#include "nt_rsa.h"
|
|
#include "randlib.h"
|
|
#include "protstor.h"
|
|
#include "ole2.h"
|
|
#include "swnt_pk.h"
|
|
#include "sgccheck.h"
|
|
#include "swnt_pk.h"
|
|
#include <delayimp.h>
|
|
|
|
#define MAXITER 0xFFFF
|
|
|
|
#define RSAFULL_TYPE_STRING "Type 001"
|
|
#define RSA_SCH_TYPE_STRING "Type 012"
|
|
#define RSAAES_TYPE_STRING "Type 024"
|
|
|
|
#define MS_RSA_TYPE "RSA Full (Signature and Key Exchange)"
|
|
#define MS_RSA_SCH_TYPE "RSA SChannel"
|
|
#define MS_RSAAES_TYPE "RSA Full and AES"
|
|
|
|
#define PROVPATH "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\"
|
|
#define PROVPATH_LEN sizeof(PROVPATH)
|
|
|
|
#define TYPEPATH "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types\\"
|
|
#define TYPEPATH_LEN sizeof(TYPEPATH)
|
|
|
|
HINSTANCE g_hInstance;
|
|
|
|
extern DWORD SelfMACCheck(IN LPSTR pszImage);
|
|
|
|
static CHAR l_szImagePath[MAX_PATH];
|
|
|
|
#define KEYSIZE1024 0x88
|
|
|
|
#if 0
|
|
struct _mskey
|
|
{
|
|
BSAFE_PUB_KEY PUB;
|
|
unsigned char pubmodulus[KEYSIZE1024];
|
|
} MSKEY = {
|
|
{
|
|
0x2bad85ae,
|
|
0x883adacc,
|
|
0xb32ebd68,
|
|
0xa7ec8b06,
|
|
0x58dbeb81,
|
|
},
|
|
{
|
|
0x42, 0x34, 0xb7, 0xab, 0x45, 0x0f, 0x60, 0xcd,
|
|
0x8f, 0x77, 0xb5, 0xd1, 0x79, 0x18, 0x34, 0xbe,
|
|
0x66, 0xcb, 0x5c, 0x66, 0x4a, 0x9f, 0x03, 0x18,
|
|
0x13, 0x36, 0x8e, 0x88, 0x21, 0x78, 0xb1, 0x94,
|
|
0xa1, 0xd5, 0x8f, 0x8c, 0xa5, 0xd3, 0x9f, 0x86,
|
|
0x43, 0x89, 0x05, 0xa0, 0xe3, 0xee, 0xe2, 0xd0,
|
|
0xe5, 0x1d, 0x5f, 0xaf, 0xff, 0x85, 0x71, 0x7a,
|
|
0x0a, 0xdb, 0x2e, 0xd8, 0xc3, 0x5f, 0x2f, 0xb1,
|
|
0xf0, 0x53, 0x98, 0x3b, 0x44, 0xee, 0x7f, 0xc9,
|
|
0x54, 0x26, 0xdb, 0xdd, 0xfe, 0x1f, 0xd0, 0xda,
|
|
0x96, 0x89, 0xc8, 0x9e, 0x2b, 0x5d, 0x96, 0xd1,
|
|
0xf7, 0x52, 0x14, 0x04, 0xfb, 0xf8, 0xee, 0x4d,
|
|
0x92, 0xd1, 0xb6, 0x37, 0x6a, 0xe0, 0xaf, 0xde,
|
|
0xc7, 0x41, 0x06, 0x7a, 0xe5, 0x6e, 0xb1, 0x8c,
|
|
0x8f, 0x17, 0xf0, 0x63, 0x8d, 0xaf, 0x63, 0xfd,
|
|
0x22, 0xc5, 0xad, 0x1a, 0xb1, 0xe4, 0x7a, 0x6b,
|
|
0x1e, 0x0e, 0xea, 0x60, 0x56, 0xbd, 0x49, 0xd0,
|
|
}
|
|
};
|
|
|
|
struct _key
|
|
{
|
|
BSAFE_PUB_KEY PUB;
|
|
unsigned char pubmodulus[KEYSIZE1024];
|
|
} KEY = {
|
|
{
|
|
0x3fcbf1a9,
|
|
0x08f597db,
|
|
0xe4aecab4,
|
|
0x75360f90,
|
|
0x9d6c0f00,
|
|
},
|
|
{
|
|
0x85, 0xdd, 0x9b, 0xf4, 0x4d, 0x0b, 0xc4, 0x96,
|
|
0x3e, 0x79, 0x86, 0x30, 0x6d, 0x27, 0x31, 0xee,
|
|
0x4a, 0x85, 0xf5, 0xff, 0xbb, 0xa9, 0xbd, 0x81,
|
|
0x86, 0xf2, 0x4f, 0x87, 0x6c, 0x57, 0x55, 0x19,
|
|
0xe4, 0xf4, 0x49, 0xa3, 0x19, 0x27, 0x08, 0x82,
|
|
0x9e, 0xf9, 0x8a, 0x8e, 0x41, 0xd6, 0x91, 0x71,
|
|
0x47, 0x48, 0xee, 0xd6, 0x24, 0x2d, 0xdd, 0x22,
|
|
0x72, 0x08, 0xc6, 0xa7, 0x34, 0x6f, 0x93, 0xd2,
|
|
0xe7, 0x72, 0x57, 0x78, 0x7a, 0x96, 0xc1, 0xe1,
|
|
0x47, 0x38, 0x78, 0x43, 0x53, 0xea, 0xf3, 0x88,
|
|
0x82, 0x66, 0x41, 0x43, 0xd4, 0x62, 0x44, 0x01,
|
|
0x7d, 0xb2, 0x16, 0xb3, 0x50, 0x89, 0xdb, 0x0a,
|
|
0x93, 0x17, 0x02, 0x02, 0x46, 0x49, 0x79, 0x76,
|
|
0x59, 0xb6, 0xb1, 0x2b, 0xfc, 0xb0, 0x9a, 0x21,
|
|
0xe6, 0xfa, 0x2d, 0x56, 0x07, 0x36, 0xbc, 0x13,
|
|
0x7f, 0x1c, 0xde, 0x55, 0xfb, 0x0d, 0x67, 0x0f,
|
|
0xc2, 0x17, 0x45, 0x8a, 0x14, 0x2b, 0xba, 0x55,
|
|
}
|
|
};
|
|
#endif
|
|
|
|
#if 0
|
|
NTVersion(
|
|
void)
|
|
{
|
|
static BOOL dwVersion = 0;
|
|
|
|
OSVERSIONINFO osVer;
|
|
|
|
memset(&osVer, 0, sizeof(OSVERSIONINFO));
|
|
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
if(!GetVersionEx(&osVer) )
|
|
goto ErrorExit;
|
|
|
|
dwVersion = osVer.dwMajorVersion;
|
|
ErrorExit:
|
|
return dwVersion;
|
|
}
|
|
#endif
|
|
|
|
|
|
/*static*/ DWORD
|
|
SetCSPInfo(
|
|
LPSTR pszProvider,
|
|
LPSTR pszImagePath,
|
|
BYTE *pbSig,
|
|
DWORD cbSig,
|
|
DWORD dwProvType,
|
|
LPSTR pszType,
|
|
LPSTR pszTypeName,
|
|
BOOL fSigInFile,
|
|
BOOL fMakeDefault)
|
|
{
|
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
|
DWORD dwIgn;
|
|
HKEY hKey = 0;
|
|
HKEY hTypeKey = 0;
|
|
DWORD cbProv;
|
|
BYTE *pszProv = NULL;
|
|
DWORD cbTypePath;
|
|
BYTE *pszTypePath = NULL;
|
|
DWORD dwVal = 0;
|
|
DWORD dwSts;
|
|
|
|
cbProv = PROVPATH_LEN + strlen(pszProvider);
|
|
pszProv = _nt_malloc(cbProv);
|
|
if (NULL == pszProv)
|
|
{
|
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
strcpy((LPSTR)pszProv, PROVPATH);
|
|
strcat((LPSTR)pszProv, pszProvider);
|
|
|
|
//
|
|
// Create or open in local machine for provider:
|
|
//
|
|
dwSts = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
(const char *)pszProv,
|
|
0L, "", REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, NULL, &hKey,
|
|
&dwIgn);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Set Image path to: scp.dll
|
|
//
|
|
dwSts = RegSetValueEx(hKey, "Image Path", 0L, REG_SZ,
|
|
(LPBYTE)pszImagePath,
|
|
strlen(pszImagePath) + 1);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Set Type to: Type 003
|
|
//
|
|
dwSts = RegSetValueEx(hKey, "Type", 0L, REG_DWORD,
|
|
(LPBYTE)&dwProvType,
|
|
sizeof(DWORD));
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (fSigInFile)
|
|
{
|
|
//
|
|
// Place signature in file value
|
|
//
|
|
dwSts = RegSetValueEx(hKey, "SigInFile", 0L,
|
|
REG_DWORD, (LPBYTE)&dwVal,
|
|
sizeof(DWORD));
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Place signature
|
|
//
|
|
dwSts = RegSetValueEx(hKey, "Signature", 0L,
|
|
REG_BINARY, pbSig, cbSig);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create or open in local machine for provider type:
|
|
//
|
|
|
|
cbTypePath = TYPEPATH_LEN + strlen(pszType) + 1;
|
|
pszTypePath = _nt_malloc(cbTypePath);
|
|
if (NULL == pszTypePath)
|
|
{
|
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
strcpy((LPSTR)pszTypePath, TYPEPATH);
|
|
strcat((LPSTR)pszTypePath, pszType);
|
|
|
|
dwSts = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
(LPSTR)pszTypePath,
|
|
0L, "", REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, NULL, &hTypeKey,
|
|
&dwIgn);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if ((REG_CREATED_NEW_KEY == dwIgn) || fMakeDefault)
|
|
{
|
|
dwSts = RegSetValueEx(hTypeKey, "Name", 0L,
|
|
REG_SZ, (LPBYTE)pszProvider,
|
|
strlen(pszProvider) + 1);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
dwSts = RegSetValueEx(hTypeKey, "TypeName", 0L,
|
|
REG_SZ, (LPBYTE)pszTypeName,
|
|
strlen(pszTypeName) + 1);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
dwReturn = ERROR_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (hKey)
|
|
RegCloseKey(hKey);
|
|
if (hTypeKey)
|
|
RegCloseKey(hTypeKey);
|
|
if (pszProv)
|
|
_nt_free(pszProv, 0);
|
|
if (pszTypePath)
|
|
_nt_free(pszTypePath, 0);
|
|
return dwReturn;
|
|
}
|
|
|
|
|
|
// See if a handle of the given type is in the list.
|
|
// If it is, return the data that the item holds.
|
|
void *
|
|
NTLCheckList(
|
|
HNTAG hThisThing,
|
|
BYTE bTypeValue)
|
|
{
|
|
HTABLE *pTable;
|
|
|
|
pTable = (HTABLE*)(hThisThing ^ HANDLE_MASK);
|
|
|
|
if ((BYTE)pTable->dwType != bTypeValue)
|
|
return NULL;
|
|
|
|
return (void*)pTable->pItem;
|
|
}
|
|
|
|
// Find & validate the passed list item against the user and type.
|
|
|
|
DWORD
|
|
NTLValidate(
|
|
HNTAG hItem,
|
|
HCRYPTPROV hUID,
|
|
BYTE bTypeValue,
|
|
LPVOID *ppvRet)
|
|
{
|
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
|
void *pTmpVal;
|
|
|
|
// check to see if the key is in the key list
|
|
pTmpVal = NTLCheckList(hItem, bTypeValue);
|
|
if (pTmpVal == NULL)
|
|
{
|
|
dwReturn = (DWORD)NTE_FAIL; // converted by caller
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// check to make sure there is a key value
|
|
if ((bTypeValue == KEY_HANDLE) &&
|
|
(((PNTAGKeyList)pTmpVal)->pKeyValue == NULL))
|
|
{
|
|
ASSERT(((PNTAGKeyList)pTmpVal)->cbKeyLen == 0);
|
|
dwReturn = (DWORD)NTE_BAD_KEY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// make sure the UIDs are the same
|
|
if (((PNTAGKeyList)pTmpVal)->hUID != hUID)
|
|
{
|
|
dwReturn = (DWORD)NTE_BAD_UID;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
*ppvRet = pTmpVal;
|
|
dwReturn = ERROR_SUCCESS;
|
|
|
|
ErrorExit:
|
|
return dwReturn;
|
|
}
|
|
|
|
// Make a new list item of the given type, and assign the data to it.
|
|
|
|
DWORD
|
|
NTLMakeItem(
|
|
HNTAG *phItem,
|
|
BYTE bTypeValue,
|
|
void *NewData)
|
|
{
|
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
|
HTABLE *NewMember;
|
|
|
|
NewMember = (HTABLE *)_nt_malloc(sizeof(HTABLE));
|
|
if (NULL == NewMember)
|
|
{
|
|
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
NewMember->pItem = NewData;
|
|
NewMember->dwType = bTypeValue;
|
|
|
|
*phItem = (HNTAG)((HNTAG)NewMember ^ HANDLE_MASK);
|
|
dwReturn = ERROR_SUCCESS;
|
|
|
|
ErrorExit:
|
|
return dwReturn;
|
|
}
|
|
|
|
// Remove the handle. Assumes that any memory used by the handle data has
|
|
// been freed.
|
|
|
|
void
|
|
NTLDelete(
|
|
HNTAG hItem)
|
|
{
|
|
HTABLE *pTable;
|
|
|
|
pTable = (HTABLE*)(hItem ^ HANDLE_MASK);
|
|
_nt_free(pTable, sizeof(HTABLE));
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* FreeUserRec frees the dynamically allocated memory for the */
|
|
/* appropriate fields of the UserRec structure. */
|
|
/* */
|
|
/* MTS: we assume that pUser has only one reference (no */
|
|
/* MTS: multiple logon's for the same user name). */
|
|
/****************************************************************/
|
|
|
|
void
|
|
FreeUserRec(
|
|
PNTAGUserList pUser)
|
|
{
|
|
if (pUser != NULL)
|
|
{
|
|
// No need to zero lengths, since entire struct is going away
|
|
if (pUser->pExchPrivKey)
|
|
{
|
|
memnuke(pUser->pExchPrivKey, pUser->ExchPrivLen);
|
|
_nt_free (pUser->pExchPrivKey, 0);
|
|
}
|
|
|
|
if (pUser->pSigPrivKey)
|
|
{
|
|
memnuke(pUser->pSigPrivKey, pUser->SigPrivLen);
|
|
_nt_free (pUser->pSigPrivKey, 0);
|
|
}
|
|
|
|
if (pUser->pUser)
|
|
{
|
|
_nt_free(pUser->pUser, 0);
|
|
}
|
|
|
|
if (NULL != pUser->szProviderName)
|
|
{
|
|
_nt_free(pUser->szProviderName, 0);
|
|
}
|
|
|
|
if (pUser->pCachePW)
|
|
{
|
|
memnuke(pUser->pCachePW, STORAGE_RC4_KEYLEN);
|
|
_nt_free(pUser->pCachePW, 0);
|
|
}
|
|
|
|
if (pUser->pPStore)
|
|
{
|
|
FreePSInfo(pUser->pPStore);
|
|
}
|
|
|
|
#ifdef USE_SGC
|
|
// free the SGC key info
|
|
SGCDeletePubKeyValues(&pUser->pbSGCKeyMod,
|
|
&pUser->cbSGCKeyMod,
|
|
&pUser->dwSGCKeyExpo);
|
|
#endif
|
|
|
|
FreeContainerInfo(&pUser->ContInfo);
|
|
|
|
FreeOffloadInfo(pUser->pOffloadInfo);
|
|
|
|
DeleteCriticalSection(&pUser->CritSec);
|
|
|
|
ZeroMemory(pUser, sizeof(NTAGUserList));
|
|
_nt_free (pUser, 0);
|
|
}
|
|
}
|
|
|
|
// RSA private key in PRIVATEKEYBLOB format
|
|
static BYTE l_rgbRSAPriv[] =
|
|
{
|
|
0x52, 0x53, 0x41, 0x32, 0x48, 0x00, 0x00, 0x00,
|
|
0x00, 0x02, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xEF, 0x4C, 0x0D, 0x34,
|
|
0xCF, 0x44, 0x0F, 0xB1, 0x73, 0xAC, 0xD4, 0x9B,
|
|
0xBE, 0xCC, 0x2D, 0x11, 0x2A, 0x2B, 0xBD, 0x21,
|
|
0x04, 0x8E, 0xAC, 0xAD, 0xD5, 0xFC, 0xD2, 0x50,
|
|
0x14, 0x35, 0x1B, 0x43, 0x15, 0x62, 0x67, 0x8F,
|
|
0x5E, 0x00, 0xB9, 0x25, 0x1B, 0xE2, 0x4F, 0xBE,
|
|
0xA1, 0x50, 0xA1, 0x44, 0x3B, 0x17, 0xD8, 0x91,
|
|
0xF5, 0x28, 0xF9, 0xFA, 0xAE, 0xE7, 0xC0, 0xFD,
|
|
0xB9, 0xCD, 0x76, 0x4F, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xE9, 0xBB, 0x38, 0x52,
|
|
0xD9, 0x0D, 0x56, 0xD7, 0x36, 0xBA, 0xDC, 0xE8,
|
|
0xB5, 0x57, 0x56, 0x13, 0x1A, 0x3A, 0x43, 0x30,
|
|
0xDE, 0x7D, 0x76, 0x6F, 0xBB, 0x71, 0x3B, 0x0A,
|
|
0x92, 0xBA, 0x60, 0x94, 0x00, 0x00, 0x00, 0x00,
|
|
0x17, 0x33, 0x3D, 0xB5, 0xEF, 0xD8, 0x2B, 0xDE,
|
|
0xCD, 0xA6, 0x6A, 0x94, 0x17, 0xC3, 0x57, 0xE9,
|
|
0x2E, 0x1C, 0x9F, 0x35, 0xDA, 0xA4, 0xBD, 0x02,
|
|
0x5B, 0x9D, 0xD1, 0x38, 0x4C, 0xF2, 0x19, 0x89,
|
|
0x00, 0x00, 0x00, 0x00, 0x89, 0x21, 0xCB, 0x3F,
|
|
0x0C, 0xA7, 0x71, 0xBC, 0xF6, 0xA1, 0x87, 0xDF,
|
|
0x00, 0x2D, 0x27, 0x64, 0x4A, 0xD4, 0x93, 0x9F,
|
|
0x58, 0x93, 0x4B, 0x83, 0x1E, 0xAB, 0xD8, 0x5D,
|
|
0xBC, 0x0E, 0x58, 0x03, 0x00, 0x00, 0x00, 0x00,
|
|
0xAB, 0x09, 0xD7, 0x21, 0xBA, 0x6F, 0x55, 0x08,
|
|
0x12, 0xEE, 0x5B, 0x47, 0x6B, 0x9F, 0x3F, 0xD3,
|
|
0xFC, 0xEA, 0xB5, 0x25, 0x19, 0xB7, 0x9E, 0xBD,
|
|
0xDF, 0x6F, 0x7F, 0x96, 0x00, 0x88, 0xC6, 0x7B,
|
|
0x00, 0x00, 0x00, 0x00, 0x95, 0x0B, 0x23, 0xC5,
|
|
0x72, 0x98, 0x9D, 0x49, 0x7A, 0x46, 0x4E, 0xE1,
|
|
0xE6, 0x2F, 0xC6, 0x63, 0x21, 0x8F, 0x66, 0xDC,
|
|
0x9B, 0xCC, 0xE2, 0x27, 0x03, 0x27, 0x85, 0xF0,
|
|
0x3A, 0x02, 0xFB, 0x40, 0x00, 0x00, 0x00, 0x00,
|
|
0x51, 0x74, 0xF6, 0xF2, 0x23, 0xEC, 0xA1, 0x76,
|
|
0x55, 0x58, 0x07, 0x71, 0xBF, 0x7F, 0x0A, 0x1E,
|
|
0x6B, 0x48, 0x48, 0xBB, 0x92, 0xB6, 0x2A, 0xB1,
|
|
0x07, 0xA4, 0x21, 0xD1, 0xC6, 0xCB, 0x5F, 0x40,
|
|
0xCE, 0xDD, 0xBA, 0xDB, 0xFC, 0x17, 0xFB, 0xA7,
|
|
0xBD, 0xE1, 0xF4, 0x63, 0xD8, 0x9E, 0x89, 0xE2,
|
|
0xDD, 0x7A, 0xEC, 0x11, 0xD6, 0xA9, 0x9C, 0xBA,
|
|
0xC7, 0x5E, 0x35, 0x96, 0xA6, 0x6F, 0x7F, 0x2C,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
// RSA private key in PUBLICKEYBLOB format
|
|
static BYTE l_rgbRSAPub[] =
|
|
{
|
|
0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
|
|
0x00, 0x02, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0xEF, 0x4C, 0x0D, 0x34,
|
|
0xCF, 0x44, 0x0F, 0xB1, 0x73, 0xAC, 0xD4, 0x9B,
|
|
0xBE, 0xCC, 0x2D, 0x11, 0x2A, 0x2B, 0xBD, 0x21,
|
|
0x04, 0x8E, 0xAC, 0xAD, 0xD5, 0xFC, 0xD2, 0x50,
|
|
0x14, 0x35, 0x1B, 0x43, 0x15, 0x62, 0x67, 0x8F,
|
|
0x5E, 0x00, 0xB9, 0x25, 0x1B, 0xE2, 0x4F, 0xBE,
|
|
0xA1, 0x50, 0xA1, 0x44, 0x3B, 0x17, 0xD8, 0x91,
|
|
0xF5, 0x28, 0xF9, 0xFA, 0xAE, 0xE7, 0xC0, 0xFD,
|
|
0xB9, 0xCD, 0x76, 0x4F, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
// known result of an MD5 hash on the above buffer
|
|
static BYTE l_rgbKnownMD5[] =
|
|
{
|
|
0xb8, 0x2f, 0x6b, 0x11, 0x31, 0xc8, 0xec, 0xf4,
|
|
0xfe, 0x0b, 0xf0, 0x6d, 0x2a, 0xda, 0x3f, 0xc3
|
|
};
|
|
|
|
// known result of an SHA-1 hash on the above buffer
|
|
static BYTE l_rgbKnownSHA1[] =
|
|
{
|
|
0xe8, 0x96, 0x82, 0x85, 0xeb, 0xae, 0x01, 0x14,
|
|
0x73, 0xf9, 0x08, 0x45, 0xc0, 0x6a, 0x6d, 0x3e,
|
|
0x69, 0x80, 0x6a, 0x0c
|
|
};
|
|
|
|
// known key, plaintext, and ciphertext for RC4
|
|
static BYTE l_rgbRC4Key[] = {0x61, 0x8a, 0x63, 0xd2, 0xfb};
|
|
static BYTE l_rgbRC4KnownPlaintext[] = {0xDC, 0xEE, 0x4C, 0xF9, 0x2C};
|
|
static BYTE l_rgbRC4KnownCiphertext[] = {0xF1, 0x38, 0x29, 0xC9, 0xDE};
|
|
|
|
// IV for all block ciphers
|
|
BYTE l_rgbIV[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
|
|
|
|
// known key, plaintext, and ciphertext for RC2
|
|
BYTE l_rgbRC2Key[] = {0x59, 0x45, 0x9a, 0xf9, 0x27, 0x84, 0x74, 0xCA};
|
|
BYTE l_rgbRC2KnownPlaintext[] = {0xD5, 0x58, 0x75, 0x12, 0xCE, 0xEF, 0x77, 0x93};
|
|
BYTE l_rgbRC2KnownCiphertext[] = {0x7b, 0x98, 0xdf, 0x9d, 0xa2, 0xdc, 0x7b, 0x7a};
|
|
BYTE l_rgbRC2CBCCiphertext[] = {0x9d, 0x93, 0x8e, 0xf6, 0x7c, 0x01, 0x5e, 0xeb};
|
|
|
|
// known key, plaintext, and ciphertext for DES40 (CALG_CYLINK_MEK)
|
|
BYTE l_rgbDES40Key[] = {0x01, 0x23, 0x04, 0x67, 0x08, 0xab, 0x0d, 0xef};
|
|
BYTE l_rgbDES40KnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
|
|
BYTE l_rgbDES40KnownCiphertext[] = {0xac, 0x97, 0x4d, 0xd9, 0x02, 0x13, 0x88, 0x2c};
|
|
BYTE l_rgbDES40CBCCiphertext[] = {0x47, 0xdc, 0xf0, 0x13, 0x7f, 0xa5, 0xd6, 0x32};
|
|
|
|
// known key, plaintext, and ciphertext for DES
|
|
BYTE l_rgbDESKey[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
|
|
BYTE l_rgbDESKnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
|
|
BYTE l_rgbDESKnownCiphertext[] = {0x3F, 0xA4, 0x0E, 0x8A, 0x98, 0x4D, 0x48, 0x15};
|
|
BYTE l_rgbDESCBCCiphertext[] = {0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C};
|
|
|
|
// known key, plaintext, and ciphertext for 3 key 3DES
|
|
BYTE l_rgb3DESKey[] =
|
|
{
|
|
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
|
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
|
|
0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
|
|
};
|
|
BYTE l_rgb3DESKnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
|
|
BYTE l_rgb3DESKnownCiphertext[] = {0x31, 0x4F, 0x83, 0x27, 0xFA, 0x7A, 0x09, 0xA8};
|
|
BYTE l_rgb3DESCBCCiphertext[] = {0xf3, 0xc0, 0xff, 0x02, 0x6c, 0x02, 0x30, 0x89};
|
|
|
|
// known key, plaintext, and ciphertext for 2 key 3DES
|
|
BYTE l_rgb3DES112Key[] =
|
|
{
|
|
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
|
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01
|
|
};
|
|
BYTE l_rgb3DES112KnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
|
|
BYTE l_rgb3DES112KnownCiphertext[] = {0xb7, 0x83, 0x57, 0x79, 0xee, 0x26, 0xac, 0xb7};
|
|
BYTE l_rgb3DES112CBCCiphertext[] = {0x13, 0x4b, 0x98, 0xf8, 0xee, 0xb3, 0xf6, 0x07};
|
|
|
|
//
|
|
// AES vectors are from NIST web site
|
|
//
|
|
// known key, plaintext, and ciphertext for 128 bit AES
|
|
BYTE l_rgbAES128Key[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
|
};
|
|
BYTE l_rgbAES128KnownPlaintext[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
|
};
|
|
BYTE l_rgbAES128KnownCiphertext[] =
|
|
{
|
|
0x0A, 0x94, 0x0B, 0xB5, 0x41, 0x6E, 0xF0, 0x45,
|
|
0xF1, 0xC3, 0x94, 0x58, 0xC6, 0x53, 0xEA, 0x5A
|
|
};
|
|
|
|
// known key, plaintext, and ciphertext for 192 bit AES
|
|
BYTE l_rgbAES192Key[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
|
|
};
|
|
BYTE l_rgbAES192KnownPlaintext[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
|
};
|
|
BYTE l_rgbAES192KnownCiphertext[] =
|
|
{
|
|
0x00, 0x60, 0xBF, 0xFE, 0x46, 0x83, 0x4B, 0xB8,
|
|
0xDA, 0x5C, 0xF9, 0xA6, 0x1F, 0xF2, 0x20, 0xAE
|
|
};
|
|
|
|
// known key, plaintext, and ciphertext for 256 bit AES
|
|
BYTE l_rgbAES256Key[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
|
};
|
|
BYTE l_rgbAES256KnownPlaintext[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
|
};
|
|
BYTE l_rgbAES256KnownCiphertext[] =
|
|
{
|
|
0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
|
|
0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92
|
|
};
|
|
|
|
// **********************************************************************
|
|
// AlgorithmCheck performs known answer tests using the algorithms
|
|
// supported by the provider.
|
|
// **********************************************************************
|
|
/*static*/ DWORD
|
|
AlgorithmCheck(
|
|
void)
|
|
{
|
|
DWORD dwReturn = ERROR_INTERNAL_ERROR;
|
|
BYTE rgbMD5[MD5DIGESTLEN];
|
|
BYTE rgbSHA1[A_SHA_DIGEST_LEN];
|
|
DWORD dwSts;
|
|
|
|
memset(rgbMD5, 0, sizeof(rgbMD5));
|
|
memset(rgbSHA1, 0, sizeof(rgbSHA1));
|
|
|
|
// check if RSA is working properly
|
|
dwSts = EncryptAndDecryptWithRSAKey(l_rgbRSAPub, l_rgbRSAPriv, TRUE, TRUE);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// check if RSA is working properly
|
|
dwSts = EncryptAndDecryptWithRSAKey(l_rgbRSAPub, l_rgbRSAPriv, FALSE, TRUE);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
#ifdef CSP_USE_MD5
|
|
// known answer test with MD5 (this function is found in hash.c)
|
|
if (!TestMD5((LPBYTE)"HashThis", 8, rgbMD5))
|
|
{
|
|
dwReturn = (DWORD)NTE_FAIL;
|
|
goto ErrorExit;
|
|
}
|
|
if (memcmp(rgbMD5, l_rgbKnownMD5, sizeof(rgbMD5)))
|
|
{
|
|
dwReturn = (DWORD)NTE_FAIL;
|
|
goto ErrorExit;
|
|
}
|
|
#endif // CSP_USE_MD5
|
|
|
|
#ifdef CSP_USE_SHA1
|
|
// known answer test with SHA-1 (this function is found in hash.c)
|
|
if (!TestSHA1((LPBYTE)"HashThis", 8, rgbSHA1))
|
|
{
|
|
dwReturn = (DWORD)NTE_FAIL;
|
|
goto ErrorExit;
|
|
}
|
|
if (memcmp(rgbSHA1, l_rgbKnownSHA1, sizeof(rgbSHA1)))
|
|
{
|
|
dwReturn = (DWORD)NTE_FAIL;
|
|
goto ErrorExit;
|
|
}
|
|
#endif // CSP_USE_SHA1
|
|
|
|
#ifdef CSP_USE_RC4
|
|
// known answer test with RC4
|
|
dwSts = TestSymmetricAlgorithm(CALG_RC4,
|
|
l_rgbRC4Key,
|
|
sizeof(l_rgbRC4Key),
|
|
l_rgbRC4KnownPlaintext,
|
|
sizeof(l_rgbRC4KnownPlaintext),
|
|
l_rgbRC4KnownCiphertext, NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
#endif // CSP_USE_RC4
|
|
|
|
#ifdef CSP_USE_RC2
|
|
// known answer test with RC2 - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_RC2,
|
|
l_rgbRC2Key,
|
|
sizeof(l_rgbRC2Key),
|
|
l_rgbRC2KnownPlaintext,
|
|
sizeof(l_rgbRC2KnownPlaintext),
|
|
l_rgbRC2KnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with RC2 - CBC
|
|
dwSts = TestSymmetricAlgorithm(CALG_RC2,
|
|
l_rgbRC2Key,
|
|
sizeof(l_rgbRC2Key),
|
|
l_rgbRC2KnownPlaintext,
|
|
sizeof(l_rgbRC2KnownPlaintext),
|
|
l_rgbRC2CBCCiphertext,
|
|
l_rgbIV);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
#endif // CSP_USE_RC2
|
|
|
|
#ifdef CSP_USE_DES
|
|
// known answer test with DES - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_DES,
|
|
l_rgbDESKey,
|
|
sizeof(l_rgbDESKey),
|
|
l_rgbDESKnownPlaintext,
|
|
sizeof(l_rgbDESKnownPlaintext),
|
|
l_rgbDESKnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with DES - CBC
|
|
dwSts = TestSymmetricAlgorithm(CALG_DES,
|
|
l_rgbDESKey,
|
|
sizeof(l_rgbDESKey),
|
|
l_rgbDESKnownPlaintext,
|
|
sizeof(l_rgbDESKnownPlaintext),
|
|
l_rgbDESCBCCiphertext,
|
|
l_rgbIV);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
#endif // CSP_USE_DES
|
|
|
|
#ifdef CSP_USE_3DES
|
|
// known answer test with 3DES - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_3DES,
|
|
l_rgb3DESKey,
|
|
sizeof(l_rgb3DESKey),
|
|
l_rgb3DESKnownPlaintext,
|
|
sizeof(l_rgb3DESKnownPlaintext),
|
|
l_rgb3DESKnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with 3DES - CBC
|
|
dwSts = TestSymmetricAlgorithm(CALG_3DES,
|
|
l_rgb3DESKey,
|
|
sizeof(l_rgb3DESKey),
|
|
l_rgb3DESKnownPlaintext,
|
|
sizeof(l_rgb3DESKnownPlaintext),
|
|
l_rgb3DESCBCCiphertext,
|
|
l_rgbIV);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with 3DES 112 - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_3DES_112,
|
|
l_rgb3DES112Key,
|
|
sizeof(l_rgb3DES112Key),
|
|
l_rgb3DES112KnownPlaintext,
|
|
sizeof(l_rgb3DES112KnownPlaintext),
|
|
l_rgb3DES112KnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
dwSts = TestSymmetricAlgorithm(CALG_3DES_112,
|
|
l_rgb3DES112Key,
|
|
sizeof(l_rgb3DES112Key),
|
|
l_rgb3DES112KnownPlaintext,
|
|
sizeof(l_rgb3DES112KnownPlaintext),
|
|
l_rgb3DES112CBCCiphertext,
|
|
l_rgbIV);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
#endif // CSP_USE_3DES
|
|
|
|
#ifdef CSP_USE_AES
|
|
// known answer test with AES 128 - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_AES_128,
|
|
l_rgbAES128Key,
|
|
sizeof(l_rgbAES128Key),
|
|
l_rgbAES128KnownPlaintext,
|
|
sizeof(l_rgbAES128KnownPlaintext),
|
|
l_rgbAES128KnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with AES 192 - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_AES_192,
|
|
l_rgbAES192Key,
|
|
sizeof(l_rgbAES192Key),
|
|
l_rgbAES192KnownPlaintext,
|
|
sizeof(l_rgbAES192KnownPlaintext),
|
|
l_rgbAES192KnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// known answer test with AES 256 - ECB
|
|
dwSts = TestSymmetricAlgorithm(CALG_AES_256,
|
|
l_rgbAES256Key,
|
|
sizeof(l_rgbAES256Key),
|
|
l_rgbAES256KnownPlaintext,
|
|
sizeof(l_rgbAES256KnownPlaintext),
|
|
l_rgbAES256KnownCiphertext,
|
|
NULL);
|
|
if (ERROR_SUCCESS != dwSts)
|
|
{
|
|
dwReturn = dwSts;
|
|
goto ErrorExit;
|
|
}
|
|
#endif
|
|
|
|
dwReturn = ERROR_SUCCESS;
|
|
|
|
ErrorExit:
|
|
return dwReturn;
|
|
}
|
|
|
|
|
|
BOOL WINAPI
|
|
DllInitialize(
|
|
IN PVOID hmod,
|
|
IN ULONG Reason,
|
|
IN PCONTEXT Context) // Unused parameter
|
|
{
|
|
g_hInstance = (HINSTANCE) hmod;
|
|
|
|
if (Reason == DLL_PROCESS_ATTACH)
|
|
{
|
|
DWORD dwLen;
|
|
|
|
DisableThreadLibraryCalls(hmod);
|
|
|
|
// Get our image name.
|
|
dwLen = GetModuleFileName(hmod, l_szImagePath,
|
|
sizeof(l_szImagePath) / sizeof(CHAR));
|
|
if (0 == dwLen)
|
|
return FALSE;
|
|
|
|
// load strings from csprc.dll
|
|
if (ERROR_SUCCESS != LoadStrings())
|
|
return FALSE;
|
|
|
|
// Verify this image hasn't been modified.
|
|
if (ERROR_SUCCESS != SelfMACCheck(l_szImagePath))
|
|
return FALSE;
|
|
|
|
// do a start up check on all supported algorithms to make sure they
|
|
// are working correctly
|
|
if (ERROR_SUCCESS != AlgorithmCheck())
|
|
return FALSE;
|
|
}
|
|
else if (Reason == DLL_PROCESS_DETACH)
|
|
{
|
|
// free the strings loaded from csprc.dll
|
|
UnloadStrings();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
STDAPI
|
|
DllRegisterServer(
|
|
void)
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
STDAPI
|
|
DllUnregisterServer(
|
|
void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Delayload stubs
|
|
//
|
|
BOOL RsaenhGetProfileTypeStub(
|
|
DWORD dwFlags)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
HRESULT RsaenhSHGetFolderPathWStub(
|
|
HWND hwndOwner,
|
|
int nFolder,
|
|
HANDLE hToken,
|
|
DWORD dwFlags,
|
|
LPWSTR pwszPath)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
void RsaenhCoTaskMemFreeStub(
|
|
void *pv)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BOOL WINAPI RsaenhCryptUnprotectDataStub(
|
|
DATA_BLOB *pDataIn,
|
|
LPWSTR *ppszDataDescr,
|
|
DATA_BLOB *pOptionalEntropy,
|
|
PVOID pvReserved,
|
|
CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
|
|
DWORD dwFlags,
|
|
DATA_BLOB *pDataOut)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI RsaenhCryptProtectDataStub(
|
|
DATA_BLOB *pDataIn,
|
|
LPCWSTR szDataDescr,
|
|
DATA_BLOB *pOptionalEntropy,
|
|
PVOID pvReserved,
|
|
CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
|
|
DWORD dwFlags,
|
|
DATA_BLOB *pDataOut)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY RsaenhUuidCreateStub(
|
|
UUID *Uuid)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY RsaenhUuidToStringAStub(
|
|
UUID *Uuid,
|
|
unsigned char **StringUuid)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
RPC_STATUS RPC_ENTRY RsaenhRpcStringFreeAStub(
|
|
unsigned char **String)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT __stdcall RsaenhPStoreCreateInstance(
|
|
IPStore __RPC_FAR *__RPC_FAR *ppProvider,
|
|
PST_PROVIDERID __RPC_FAR *pProviderID,
|
|
void __RPC_FAR *pReserved,
|
|
DWORD dwFlags)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Delayload failure and notification hook
|
|
//
|
|
BOOL RsaenhLookupModule(LPCSTR pszDll)
|
|
{
|
|
unsigned u;
|
|
|
|
for (u = 0; u < g_cRsaenhDelayLoadStubs; u++) {
|
|
if (0 == _stricmp(pszDll, g_RsaenhDelayLoadStubs[u].pszDll))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
FARPROC RsaenhLookupExport(DelayLoadProc *pdlp)
|
|
{
|
|
unsigned u;
|
|
FARPROC fpResult = NULL;
|
|
|
|
if (! pdlp->fImportByName)
|
|
goto Return;
|
|
|
|
// could alphabetize and use binary search instead
|
|
for (u = 0; u < g_cRsaenhDelayLoadStubs; u++) {
|
|
if (0 == _stricmp(pdlp->szProcName, g_RsaenhDelayLoadStubs[u].pszExport)) {
|
|
fpResult = g_RsaenhDelayLoadStubs[u].fpStub;
|
|
goto Return;
|
|
}
|
|
}
|
|
|
|
Return:
|
|
return fpResult;
|
|
}
|
|
|
|
FARPROC WINAPI RsaenhDelayLoadHook(unsigned uReason, PDelayLoadInfo pdli)
|
|
{
|
|
FARPROC fpResult = NULL;
|
|
|
|
switch (uReason) {
|
|
case dliFailLoadLib:
|
|
if (RsaenhLookupModule(pdli->szDll))
|
|
fpResult = (FARPROC) -1;
|
|
break;
|
|
|
|
case dliNotePreGetProcAddress:
|
|
if ((HINSTANCE) -1 == pdli->hmodCur) {
|
|
SetLastError(ERROR_MOD_NOT_FOUND);
|
|
fpResult = RsaenhLookupExport(&pdli->dlp);
|
|
}
|
|
break;
|
|
|
|
case dliFailGetProc:
|
|
if ((HINSTANCE) -1 == pdli->hmodCur) {
|
|
SetLastError(ERROR_PROC_NOT_FOUND);
|
|
fpResult = RsaenhLookupExport(&pdli->dlp);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return fpResult;
|
|
}
|
|
|
|
PfnDliHook __pfnDliFailureHook2 = RsaenhDelayLoadHook;
|
|
PfnDliHook __pfnDliNotifyHook = RsaenhDelayLoadHook;
|