952 lines
25 KiB
C
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);
|
|
|
|
}
|