///////////////////////////////////////////////////////////////////////////// // 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; countNextHandle = 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); }