2020-09-30 17:12:29 +02:00

952 lines
25 KiB
C

/////////////////////////////////////////////////////////////////////////////
// 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 //
// //
// Copyright (C) 1993 Microsoft Corporation All Rights Reserved //
/////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "resource.h"
#include "nt_rsa.h"
#define MAXITER 0xFFFF
#define UTIL_BUF_LEN 256
#define RSADLLNAME "\\rsabase.dll"
#define RSASIGNAME "\\sigres.exe"
HTABLE *gHandleTable = NULL;
HINSTANCE hInstance;
static void NTLDeleteRelated(HNTAG hOwner);
#define KEYSIZE1024 0x88
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,
}
};
BOOL LoadWin96Cache(PNTAGUserList pTmpUser);
void EncryptKey(BYTE *pdata, DWORD size, BYTE val);
PNTAGKeyList MakeNewKey(
ALG_ID aiKeyAlg,
DWORD dwRights,
DWORD wKeyLen,
HCRYPTPROV hUID,
CONST BYTE *pbKeyData);
void FreeNewKey(PNTAGKeyList pOldKey);
// See if a handle of the given type is in the list.
// If it is, return the item itself.
static HTABLE *
NTLFindItem(HNTAG hThisThing, BYTE bTypeValue)
{
HTABLE *pTableEntry = gHandleTable;
if (HNTAG_TO_HTYPE(hThisThing) != bTypeValue)
return NULL;
for(; pTableEntry != NULL; pTableEntry = pTableEntry->NextHandle)
{
if (pTableEntry->hToData == hThisThing)
break;
ASSERT((pTableEntry->NextHandle == NULL) ||
(pTableEntry->NextHandle->PrevHandle == pTableEntry));
}
return pTableEntry;
}
// 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 *phItem;
void *pv;
phItem = NTLFindItem(hThisThing, bTypeValue);
pv = (phItem == NULL) ? NULL : phItem->ItemStruct;
return pv;
}
// Find & validate the passed list item against the user and type.
void *NTLValidate(HNTAG hItem, HCRYPTPROV hUID, BYTE bTypeValue)
{
void *pTmpVal;
// make sure this is a handle to a key
if (HNTAG_TO_HTYPE(hItem) != bTypeValue)
{
SetLastError((DWORD) NTE_FAIL); // converted by caller
return NULL;
}
// check to see if the key is in the key list
if ((pTmpVal = NTLCheckList (hItem, bTypeValue)) == NULL)
{
SetLastError((DWORD) NTE_FAIL); // converted by caller
return NULL;
}
// check to make sure there is a key value
if ((bTypeValue == KEY_HANDLE) &&
(((PNTAGKeyList)pTmpVal)->pKeyValue == NULL))
{
ASSERT(((PNTAGKeyList)pTmpVal)->cbKeyLen == 0);
SetLastError((DWORD) NTE_BAD_KEY);
return NULL;
}
// make sure the UIDs are the same
if (((PNTAGKeyList)pTmpVal)->hUID != hUID)
{
SetLastError((DWORD) NTE_BAD_UID);
return NULL;
}
return pTmpVal;
}
// Make a new list item of the given type, and assign the data to it.
BOOL NTLMakeItem(HNTAG *phItem, BYTE bTypeValue, void *NewData)
{
int count;
HTABLE *NewMember;
if ((NewMember = (HTABLE *) _nt_malloc(sizeof(HTABLE))) == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NTF_FAILED;
}
NewMember->PrevHandle = NULL;
NewMember->ItemStruct = NewData;
// place the type into the handle
*phItem = bTypeValue;
for (count=0; count<MAXITER; count++)
{
// place random bytes into the rest of the handle
if (GenRandom (0,((BYTE *)phItem) + 1, 3) == NTF_FAILED) {
continue;
}
// check the list to make sure this handle is unique
if (NTLFindItem(*phItem, bTypeValue) == NULL) {
// Insert at the beginning of the global list
NewMember->NextHandle = gHandleTable;
if (gHandleTable != NULL) {
gHandleTable->PrevHandle = NewMember;
}
gHandleTable = NewMember;
NewMember->hToData = *phItem;
return NTF_SUCCEED;
}
}
// GenRandom didn't generate a random enough number
// (or we have > 16 Meg. entries in the list).
_nt_free(NewMember, sizeof(HTABLE));
SetLastError((DWORD) NTE_FAIL);
return NTF_FAILED;
}
// Remove the handle. Assumes that any memory used by the handle data has been freed.
BOOL NTLDelete(HNTAG hItem)
{
HTABLE *Item;
BYTE bTypeValue;
bTypeValue = HNTAG_TO_HTYPE(hItem);
if ((Item = (HTABLE *) NTLFindItem(hItem, bTypeValue)) == NULL)
{
SetLastError((DWORD) NTE_FAIL);
return NTF_FAILED;
}
if (Item->NextHandle) {
Item->NextHandle->PrevHandle = Item->PrevHandle;
}
if (Item->PrevHandle) {
Item->PrevHandle->NextHandle = Item->NextHandle;
}
if (gHandleTable == Item) {
gHandleTable = Item->NextHandle;
}
_nt_free(Item, sizeof(HTABLE));
// If we are deleting a user, delete all keys
// and hashes associated with it, too
if (bTypeValue == USER_HANDLE) {
NTLDeleteRelated(hItem);
}
return NTF_SUCCEED;
}
// Remove everything in the list associated with this hOwner.
static void
NTLDeleteRelated(HNTAG hOwner)
{
HTABLE *pTableEntry = gHandleTable;
HTABLE *phNext;
HTABLE *ToBeTrashed = NULL;
ASSERT(HNTAG_TO_HTYPE(hOwner) == USER_HANDLE);
while(pTableEntry != NULL)
{
phNext = pTableEntry->NextHandle;
// If it's a user item, then skip it
if (HNTAG_TO_HTYPE(pTableEntry->hToData) == USER_HANDLE) {
pTableEntry = phNext;
continue;
}
// The first field in the ItemStruct is an HNTAG
// (except for PNTAGUserList ItemStructs).
// We want to match hOwner to that first field.
if (*((HNTAG *)pTableEntry->ItemStruct) == hOwner) {
// remove from the list
if (pTableEntry->NextHandle) {
pTableEntry->NextHandle->PrevHandle = pTableEntry->PrevHandle;
}
if (pTableEntry->PrevHandle) {
pTableEntry->PrevHandle->NextHandle = pTableEntry->NextHandle;
}
if (gHandleTable == pTableEntry) {
gHandleTable = pTableEntry->NextHandle;
}
// and place on the to-be-deleted list
pTableEntry->NextHandle = ToBeTrashed;
ToBeTrashed = pTableEntry;
}
pTableEntry = phNext;
}
// Now delete all the items.
while (ToBeTrashed != NULL) {
phNext = ToBeTrashed->NextHandle;
_nt_free(ToBeTrashed, sizeof(HTABLE));
ToBeTrashed = phNext;
}
}
PNTAGUserList
IsUserLoggedOn(char *pszUserID)
{
HTABLE *pTableEntry;
PNTAGUserList pUser;
size_t cbLen;
cbLen = strlen(pszUserID);
for (pTableEntry = gHandleTable; pTableEntry; pTableEntry = pTableEntry->NextHandle) {
// If it's not a user item, then skip it
if (HNTAG_TO_HTYPE(pTableEntry->hToData) != USER_HANDLE) {
continue;
}
pUser = (PNTAGUserList)(pTableEntry->ItemStruct);
if ((cbLen == pUser->UserLen) && (!strcmp(pszUserID, (char *)pUser->pUser))) {
return pUser;
}
}
return NULL;
}
#ifdef STTDEBUG
long g_cbTotalAllocated = 0;
long g_Count = 0;
DWORD rgd[200][2];
BOOL fFirstTime = TRUE;
void * __cdecl
_nt_malloc(size_t cb)
{
DWORD *pw;
int i;
if(TRUE == fFirstTime)
{
memset(rgd, 0, sizeof(rgd));
fFirstTime = FALSE;
}
ASSERT(fFirstTime == FALSE);
pw = (DWORD *)malloc(cb+2*sizeof(DWORD));
for(i=0;i<200;i++)
{
if(rgd[i][0]==0)
{
rgd[i][0]=(DWORD)pw;
rgd[i][1]=(DWORD)cb;
break;
}
}
g_cbTotalAllocated += cb+2*sizeof(DWORD);
g_Count++;
ASSERT(cb > 0);
ASSERT(sizeof(size_t) <= sizeof(DWORD));
*pw++ = 0xbabe; // magic number
*pw++ = cb; // save size
memset(pw, 0xba, cb); // make sure no default effects
return pw;
}
void __cdecl
_nt_free(void *pv, size_t cb)
{
DWORD *pw = (DWORD *)pv;
int i;
// g_cbTotalAllocated -= (cb +2*sizeof(DWORD));
g_Count--;
ASSERT(g_cbTotalAllocated >= 0);
ASSERT(g_Count >= 0);
ASSERT(cb > 0);
pw--;
ASSERT(*pw == cb);
pw--;
ASSERT(*pw == 0xbabe);
for(i=0;i<200;i++)
{
if(pw==(void*)rgd[i][0])
{
rgd[i][0]=0;
rgd[i][1]=0;
break;
}
}
ASSERT(200!=i);
memset(pw, 0xbe, cb); // make sure no later use..
free(pw);
}
#endif
/****************************************************************/
/* 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, pUser->ExchPrivLen);
}
if (pUser->pExchPubKey)
{
memnuke(pUser->pExchPubKey, pUser->ExchPubLen);
_nt_free (pUser->pExchPubKey, pUser->ExchPubLen);
}
#ifndef BBN
if (pUser->pSigPrivKey)
{
memnuke(pUser->pSigPrivKey, pUser->SigPrivLen);
_nt_free (pUser->pSigPrivKey, pUser->SigPrivLen);
}
#endif
if (pUser->pSigPubKey)
{
memnuke(pUser->pSigPubKey, pUser->SigPubLen);
_nt_free (pUser->pSigPubKey, pUser->SigPubLen);
}
if (pUser->pUser)
{
memnuke(pUser->pUser, pUser->UserLen);
_nt_free(pUser->pUser, pUser->UserLen);
}
if (pUser->pbRandSeed)
{
_nt_free(pUser->pbRandSeed, pUser->RandSeedLen);
}
if (pUser->szUserName)
{
_nt_free(pUser->szUserName, pUser->dwUserNameLen);
}
if (pUser->pCachePW)
{
_nt_free(pUser->pCachePW, RC4_KEYSIZE);
}
_nt_free (pUser, sizeof(NTAGUserList));
}
}
BOOLEAN
DllInitialize(
IN PVOID hmod,
IN ULONG Reason,
IN PCONTEXT Context
)
{
hInstance = (HINSTANCE) hmod;
if ( Reason == DLL_PROCESS_ATTACH )
{
DisableThreadLibraryCalls(hmod);
}
return( TRUE );
}
CHAR szprovider[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Microsoft Base Cryptographic Provider v1.0";
CHAR sztype[] = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type 001";
CHAR szImagePath[] = "rsabase.dll";
DWORD
DllRegisterServer(void)
{
DWORD dwIgn;
HKEY hKey;
DWORD err;
DWORD dwValue;
HANDLE hFileSig;
LPVOID lpvAddress;
DWORD NumBytes;
DWORD dwType;
CHAR buffer[UTIL_BUF_LEN];
HANDLE hFileProv;
DWORD lpdwFileSizeHigh;
DWORD NumBytesRead;
MD5_CTX HashState;
BYTE SigHash1024[KEYSIZE1024];
LPVOID lpvSignature;
PNTAGUserList pTmpUser;
PNTAGKeyList pTmpKey;
HCRYPTKEY hDeKey = 0;
DWORD hUID;
HMODULE hMod;
HRSRC hRes;
HGLOBAL pRes;
//
// Compute signature of rsabase.dll to compare with rsabase.sig
// file. If the signature matches install the signature in registry.
// If it doesn't match check the signature currently in registry. If
// the signature matches the registry signature don't do anything and
// exit without error. If both signatures don't match display an
// error message.
//
GetSystemDirectory(buffer, UTIL_BUF_LEN);
if ((lstrlen(buffer) + sizeof(RSADLLNAME)) > UTIL_BUF_LEN)
{
return FALSE;
}
lstrcat(buffer, RSADLLNAME);
if ((hFileProv = CreateFile(buffer,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0)) == INVALID_HANDLE_VALUE)
{
if (LoadString(hInstance, IDS_OPENDLL, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if ((NumBytes = GetFileSize(hFileProv, &lpdwFileSizeHigh)) ==
0xffffffff)
{
CloseHandle(hFileProv);
if (LoadString(hInstance, IDS_SIZEDLL, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if ((lpvAddress = VirtualAlloc(NULL, NumBytes, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE)) == NULL)
{
CloseHandle(hFileProv);
if (LoadString(hInstance, IDS_MEMORY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if (!ReadFile((HANDLE) hFileProv, lpvAddress, NumBytes, &NumBytesRead, 0))
{
CloseHandle(hFileProv);
VirtualFree(lpvAddress, 0, MEM_RELEASE);
if (LoadString(hInstance, IDS_READDLL, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
CloseHandle(hFileProv);
MD5Init(&HashState);
MD5Update(&HashState,
(const unsigned char *) lpvAddress,
(unsigned int) NumBytes);
VirtualFree(lpvAddress, 0, MEM_RELEASE);
// Finish the hash
MD5Final(&HashState);
//
// Open sigres.exe file.
//
GetSystemDirectory(buffer, UTIL_BUF_LEN);
if ((lstrlen(buffer) + sizeof(RSASIGNAME)) > UTIL_BUF_LEN)
{
return FALSE;
}
lstrcat(buffer, RSASIGNAME);
if ((hMod = LoadLibrary(buffer)) == 0)
{
if (LoadString(hInstance, IDS_NOSIG, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if ((hRes = FindResource(hMod, (LPCTSTR) 1, RT_RCDATA)) == 0)
{
if (LoadString(hInstance, IDS_NORES, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if ((pRes = LoadResource(hMod, hRes)) == 0)
{
if (LoadString(hInstance, IDS_BADRES, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
NumBytes = SizeofResource(hMod, hRes);
#ifdef MS_INTERNAL_KEY
EncryptKey((BYTE *) &MSKEY, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024, 1);
// Decrypt the signature data
BSafeEncPublic((const LPBSAFE_PUB_KEY) &MSKEY, pRes, SigHash1024);
if (RtlEqualMemory(HashState.digest, SigHash1024, 16) &&
SigHash1024[KEYSIZE1024-8-1] == 0 &&
SigHash1024[KEYSIZE1024-8-2] == 1 &&
SigHash1024[16] == 0)
{
goto InstallSignature;
}
#endif
EncryptKey((BYTE *) &KEY, sizeof(BSAFE_PUB_KEY) + KEYSIZE1024, 0);
// Decrypt the signature data
BSafeEncPublic((const LPBSAFE_PUB_KEY) &KEY, pRes, SigHash1024);
if (RtlEqualMemory(HashState.digest, SigHash1024, 16) &&
SigHash1024[KEYSIZE1024-8-1] == 0 &&
SigHash1024[KEYSIZE1024-8-2] == 1 &&
SigHash1024[16] == 0)
{
goto InstallSignature;
}
FreeLibrary(hMod);
if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
(const char *) szprovider,
0L,
KEY_ALL_ACCESS,
&hKey)) != ERROR_SUCCESS)
{
if (LoadString(hInstance, IDS_BADINSTALL, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
if ((err = RegQueryValueEx(hKey,
"Signature",
0L,
&dwType,
NULL,
&NumBytes)) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_READREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
if ((lpvSignature = VirtualAlloc(NULL, NumBytes, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE)) == NULL)
{
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_MEMORY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(GetLastError());
}
if ((err = RegQueryValueEx(hKey,
"Signature",
0L,
&dwType,
lpvSignature,
&NumBytes)) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
VirtualFree(lpvSignature, 0, MEM_RELEASE);
if (LoadString(hInstance, IDS_READREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
RegCloseKey(hKey);
#ifdef MS_INTERNAL_KEY
// Decrypt the signature data
BSafeEncPublic((const LPBSAFE_PUB_KEY) &MSKEY, lpvSignature, SigHash1024);
if (RtlEqualMemory(HashState.digest, SigHash1024, 16) &&
SigHash1024[KEYSIZE1024-8-1] == 0 &&
SigHash1024[KEYSIZE1024-8-2] == 1 &&
SigHash1024[16] == 0)
{
VirtualFree(lpvSignature, 0, MEM_RELEASE);
return(S_OK);
}
#endif
// Decrypt the signature data
BSafeEncPublic((const LPBSAFE_PUB_KEY) &KEY, lpvSignature, SigHash1024);
if (RtlEqualMemory(HashState.digest, SigHash1024, 16) &&
SigHash1024[KEYSIZE1024-8-1] == 0 &&
SigHash1024[KEYSIZE1024-8-2] == 1 &&
SigHash1024[16] == 0)
{
VirtualFree(lpvSignature, 0, MEM_RELEASE);
return(S_OK);
}
VirtualFree(lpvSignature, 0, MEM_RELEASE);
if (LoadString(hInstance, IDS_BADINSTALL, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return((DWORD) E_UNEXPECTED);
InstallSignature:
//
// Create or open in local machine for provider:
// Microsoft Base Cryptographic Provider v1.0
//
if ((err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
(const char *) szprovider,
0L, "", REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwIgn)) != ERROR_SUCCESS)
{
FreeLibrary(hMod);
if (LoadString(hInstance, IDS_OPENREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
//
// Set Image path to: rsabase.dll
//
if ((err = RegSetValueEx(hKey,
"Image Path",
0L,
REG_SZ,
szImagePath,
strlen(szImagePath)+1)) != ERROR_SUCCESS)
{
FreeLibrary(hMod);
RegDeleteKey(hKey, szprovider);
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_WRITEREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
//
// Set Type to: Type 001
//
dwValue = 1;
if ((err = RegSetValueEx(hKey,
"Type",
0L,
REG_DWORD,
(LPTSTR) &dwValue,
sizeof(DWORD))) != ERROR_SUCCESS)
{
FreeLibrary(hMod);
RegDeleteKey(hKey, szprovider);
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_WRITEREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
//
// Place signature
//
if ((err = RegSetValueEx(hKey,
"Signature",
0L,
REG_BINARY,
(LPTSTR) pRes,
NumBytes)) != ERROR_SUCCESS)
{
FreeLibrary(hMod);
RegDeleteKey(hKey, szprovider);
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_WRITEREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
FreeLibrary(hMod);
RegCloseKey(hKey);
//
// Create or open in local machine for provider type:
// Type 001
//
if ((err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
(const char *) sztype,
0L,
"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwIgn)) != ERROR_SUCCESS)
{
if (LoadString(hInstance, IDS_OPENREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
if ((err = RegSetValueEx(hKey,
"Name",
0L,
REG_SZ,
MS_DEF_PROV,
strlen(MS_DEF_PROV)+1)) != ERROR_SUCCESS)
{
RegDeleteKey(hKey, sztype);
RegCloseKey(hKey);
if (LoadString(hInstance, IDS_WRITEREGISTRY, buffer, 256) == 0)
{
return((DWORD) E_UNEXPECTED);
}
err = MessageBox(NULL, buffer, NULL, MB_OK);
return(err);
}
RegCloseKey(hKey);
return(S_OK);
}
void EncryptKey(BYTE *pdata, DWORD size, BYTE val)
{
RC4_KEYSTRUCT key;
BYTE RealKey[RC4_KEYSIZE] = {0xa2, 0x17, 0x9c, 0x98, 0xca};
DWORD index;
for (index = 0; index < RC4_KEYSIZE; index++)
{
RealKey[index] = RealKey[index] ^ val;
}
rc4_key(&key, RC4_KEYSIZE, RealKey);
rc4(&key, size, pdata);
}