|
|
#include "stdafx.h"
#include <chkdev.h>
BOOL testCatAPIs(LPWSTR lpwzCatName, HCATADMIN hCatAdmin, HCATINFO hCatInfo);
HCATADMIN hCatAdmin = 0; extern Classes_Provided eClasses;
#define NumberTestCerts 7
BYTE TestCertHashes[NumberTestCerts][20] = { {0xBB, 0x11, 0x81, 0xF2, 0xB0, 0xC5, 0xE3, 0x2F, 0x7F, 0x2D, 0x62, 0x3B, 0x9C, 0x87, 0xE8, 0x55, 0x26, 0xF9, 0xCF, 0x2F}, {0xBA, 0x9E, 0x3C, 0x32, 0x56, 0x2A, 0x67, 0x12, 0x8C, 0xAA, 0xBD, 0x4A, 0xB0, 0xC5, 0x00, 0xBE, 0xE1, 0xD0, 0xC2, 0x56}, {0xA4, 0x34, 0x89, 0x15, 0x9A, 0x52, 0x0F, 0x0D, 0x93, 0xD0, 0x32, 0xCC, 0xAF, 0x37, 0xE7, 0xFE, 0x20, 0xA8, 0xB4, 0x19}, {0x73, 0xA9, 0x01, 0x93, 0x83, 0x4C, 0x5B, 0x16, 0xB4, 0x3F, 0x0C, 0xE0, 0x5E, 0xB4, 0xA3, 0xEF, 0x6F, 0x2C, 0x08, 0x2F}, {0xD2, 0xC3, 0x78, 0xCE, 0x42, 0xBC, 0x93, 0xA0, 0x3D, 0xD5, 0xA4, 0x2E, 0x8E, 0x08, 0xB1, 0x71, 0xB6, 0x27, 0x90, 0x1D}, {0xFC, 0x94, 0x4A, 0x1F, 0xA0, 0xDC, 0x8A, 0xC7, 0x78, 0x4A, 0xAC, 0x36, 0x9D, 0x14, 0x46, 0x02, 0x24, 0x08, 0xFF, 0x5D}, {0x92, 0x6A, 0xF1, 0x27, 0x25, 0x37, 0xE0, 0x73, 0x32, 0x6F, 0x12, 0xF7, 0xA7, 0x11, 0xE7, 0x55, 0xE6, 0x4E, 0x78, 0x4C} };
CheckDevice::CheckDevice() { m_FileList = NULL; lpszServiceName = NULL; lpszServiceImage = NULL; m_hDevInfo = SetupDiCreateDeviceInfoListEx(NULL, NULL, NULL, NULL); }
CheckDevice::~CheckDevice(void) { if ( m_FileList ) { delete m_FileList; } if ( lpszServiceName ) { delete [] lpszServiceName; lpszServiceName = NULL; } if ( lpszServiceImage ) { delete [] lpszServiceImage; lpszServiceImage = NULL; } m_FileList = NULL; if (m_hDevInfo) { SetupDiDestroyDeviceInfoList(m_hDevInfo); m_hDevInfo = NULL; }
}
CheckDevice::CheckDevice(DEVNODE hDevice, DEVNODE hParent) : InfnodeClass (hDevice, hParent) { m_FileList = NULL; lpszServiceName = NULL; lpszServiceImage = NULL;
m_hDevInfo = SetupDiCreateDeviceInfoListEx(NULL, NULL, NULL, NULL); if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile) CreateFileNode(); }
BOOL CheckDevice::AddFileNode(TCHAR *szFileName , UINT uiWin32Error /*= 0 */, LPCTSTR szSigner /*= NULL*/) { FileNode *pThisFile;
if ( !szFileName || !strlen(szFileName) ) { return(FALSE); }
_strlwr(szFileName);
// need to check that this file exists, if it doesn't, need to munge it so that it does
HANDLE hFile; CString strMungedName; TCHAR *pStrPos; hFile = CreateFile(szFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (BADHANDLE(hFile)) { // file does not exist, need to search for it
if (pStrPos = strstr(szFileName, _T("\\system\\"))) { // this may have been placed in the system32 dir instead
*pStrPos = '\0'; pStrPos++; pStrPos = strchr(pStrPos, '\\'); if (!pStrPos) return FALSE; strMungedName.Format(_T("%s\\system32%s"), szFileName, pStrPos); hFile = CreateFile(strMungedName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (BADHANDLE(hFile)) { return FALSE; } } else if (pStrPos = strstr(szFileName, _T(".inf"))) { // might be that an inf got caught in the other directory
pStrPos = _tcsrchr(szFileName, '\\'); //a-kjaw. to fix prefix bug# 259380.
if(NULL == pStrPos) return FALSE;
*pStrPos = '\0'; pStrPos++; strMungedName.Format(_T("%s\\other\\%s"),szFileName, pStrPos); hFile = CreateFile(strMungedName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (BADHANDLE(hFile)) { return FALSE; } } else return FALSE;
} CloseHandle(hFile);
// first scan the file list for duplicates
pThisFile = m_FileList; while ( pThisFile ) { if ( !strcmp(pThisFile->FilePath(), szFileName) ) { return(TRUE); // no copy, no add
} pThisFile = pThisFile->pNext; } pThisFile = NULL;
pThisFile = new FileNode; if ( !pThisFile ) { return(FALSE); }
pThisFile->pDevnode = this;
pThisFile->lpszFilePath = new TCHAR[strlen(szFileName) + 1]; if ( !pThisFile->lpszFilePath ) { delete pThisFile; return(FALSE); }
pThisFile->lpszFilePath = szFileName;
// copyed the data
pThisFile->lpszFileName = _tcsrchr(pThisFile->lpszFilePath, '\\'); pThisFile->lpszFileName++;
pThisFile->lpszFileExt = _tcsrchr(pThisFile->lpszFilePath, '.'); pThisFile->lpszFileExt++;
// get the version information
//pThisFile->GetFileInformation();
if(uiWin32Error == NO_ERROR) pThisFile->bSigned = TRUE; else pThisFile->bSigned = FALSE;
if(szSigner != NULL) { pThisFile->lpszSignedBy = szSigner; } //else
// pThisFile->bSigned = FALSE;
// now perform the LL patch
pThisFile->pNext = m_FileList; m_FileList = pThisFile; return(TRUE); }
BOOL CheckDevice::GetServiceNameAndDriver(void) { /**********
Get service Name ***********/ ULONG ulSize; CONFIGRET retval;
ulSize = 0; retval = CM_Get_DevNode_Registry_Property (hDevnode, CM_DRP_SERVICE, NULL, NULL, &ulSize, 0);
if ( retval ) if ( (retval == CR_BUFFER_SMALL) ) { if ( !ulSize ) ulSize = 511; } else return(retval);
lpszServiceName = new TCHAR [ulSize+1]; if ( !lpszServiceName ) return(CR_OUT_OF_MEMORY); ZeroMemory(lpszServiceName,sizeof(lpszServiceName)); //Now get value
retval = CM_Get_DevNode_Registry_Property (hDevnode, CM_DRP_SERVICE, NULL, lpszServiceName, &ulSize, 0); if ( retval ) return(retval);
CString strKeyName; TCHAR KeyValue[BUFFSIZE]; HKEY SrvcKey;
strKeyName.Format(_T("SYSTEM\\CurrentControlSet\\Services\\%s"), lpszServiceName);
if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyName, 0, KEY_READ, &SrvcKey) != ERROR_SUCCESS ) return(FALSE);
if ( RegQueryValueEx(SrvcKey, _T("ImagePath"), 0, NULL, NULL, &ulSize) != ERROR_SUCCESS ) { RegCloseKey(SrvcKey); return(FALSE); } if (ulSize > BUFFSIZE) { RegCloseKey(SrvcKey); return(FALSE); } if ( RegQueryValueEx(SrvcKey, _T("ImagePath"), 0, NULL, (PBYTE)KeyValue, &ulSize) != ERROR_SUCCESS ) { RegCloseKey(SrvcKey); return(FALSE); } else { // sometimes the service path is assumed
// z.b. system32\foo
// or %system32%\foo
if ( !_tcsncmp(KeyValue, _T("System32\\"), _tcslen(_T("System32\\"))) ) { strKeyName.Format(_T("%%WINDIR%%\\%s"), KeyValue); ExpandEnvironmentStrings(strKeyName, KeyValue, BUFFSIZE); lpszServiceImage = new TCHAR[strlen(KeyValue) + 1]; if ( lpszServiceImage ) strncpy(lpszServiceImage, KeyValue,sizeof(lpszServiceImage)/sizeof(TCHAR)); } }
// should be everything
RegCloseKey(SrvcKey); return(TRUE);
}
BOOL CheckDevice::CreateFileNode(void) {
// also going to add the inf as a file
TCHAR infname[512]; ZeroMemory(infname,sizeof(infname)); //TCHAR tempname[512];
CString strtempname;
if ( InfName() ) { // BUGBUG is this correct, or in some subdir??
strtempname.Format(_T("%%WINDIR%%\\inf\\%s"), InfName());
DWORD dwStatus = ExpandEnvironmentStrings(strtempname, infname, 512); //check to makesure we get a valid name back
if (0 == dwStatus || dwStatus > 512) { return FALSE; } AddFileNode(infname); } else return(FALSE);
if ( GetServiceNameAndDriver() && lpszServiceImage) AddFileNode(lpszServiceImage);
//CreateFileNode_Class();
CreateFileNode_Driver();
return(TRUE);
} BOOL CheckDevice::CreateFileNode_Class(void) { SP_DEVINSTALL_PARAMS DevInstallParams, DevTemp; SP_DEVINFO_DATA DevInfoData; SP_DRVINFO_DATA DrvInfoData; DWORD dwScanResult; HDEVINFO hDevInfo; HSPFILEQ hFileQueue; BOOL bProceed = TRUE;
// Reset all structures to empty
memset(&DevInstallParams, 0, sizeof(DevInstallParams)); memset(&DevInfoData, 0, sizeof(DevInfoData)); memset(&DrvInfoData, 0, sizeof(DrvInfoData)); memset(&DevTemp, 0, sizeof(DevInstallParams));
DrvInfoData.cbSize = sizeof(DrvInfoData); DevInfoData.cbSize = sizeof(DevInfoData); DevInstallParams.cbSize = sizeof(DevInstallParams);
hFileQueue = SetupOpenFileQueue();
// We need to build a driver node for the devnode
hDevInfo = m_hDevInfo; if ( INVALID_HANDLE_VALUE == hDevInfo ) return(0);
DevInfoData.Reserved = 0; if ( !SetupDiOpenDeviceInfo(hDevInfo, DeviceID(), NULL, NULL , &DevInfoData) ) { SetupDiDestroyDeviceInfoList(hDevInfo); return(FALSE); } /*
if (SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams )) { DevInstallParams.FlagsEx = (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams ); } */
if ( !SetupDiBuildDriverInfoList(hDevInfo, &DevInfoData, SPDIT_CLASSDRIVER) ) { SetupDiDestroyDeviceInfoList(hDevInfo); return(FALSE); }
// select a driver
if ( DeviceName() ) strncpy(DrvInfoData.Description, DeviceName(),LINE_LEN); if ( MFG() ) strncpy(DrvInfoData.MfgName, MFG(),LINE_LEN); if ( InfProvider() ) strncpy(DrvInfoData.ProviderName, InfProvider(),LINE_LEN); DrvInfoData.DriverType = SPDIT_CLASSDRIVER; if ( !SetupDiSetSelectedDriver(hDevInfo, &DevInfoData, &DrvInfoData) ) { //BUGBUG put goo here
DWORD err = GetLastError(); return(FALSE);
}
if ( SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams) ) { //memcpy(&DevTemp, &DevInfoData, sizeof(DevInfoData));
memcpy(&DevTemp, &DevInfoData, sizeof(DevTemp)); }
DevInstallParams.FileQueue = hFileQueue; DevInstallParams.Flags |= (DI_NOVCP | DI_ENUMSINGLEINF | DI_DONOTCALLCONFIGMG | DI_NOFILECOPY | DI_NOWRITE_IDS) ; DevInstallParams.Flags &= ~(DI_NODI_DEFAULTACTION); DevInstallParams.FlagsEx |= DI_FLAGSEX_NO_DRVREG_MODIFY; DevInstallParams.InstallMsgHandler = ScanQueueCallback; DevInstallParams.InstallMsgHandlerContext = this; strncpy(DevInstallParams.DriverPath, InfName(),MAX_PATH);
SetLastError(0); SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams);
if ( !SetupDiCallClassInstaller(DIF_INSTALLCLASSDRIVERS, hDevInfo, &DevInfoData) ) { DWORD err = GetLastError();
}
SetupScanFileQueue(hFileQueue, SPQ_SCAN_USE_CALLBACKEX, NULL, ScanQueueCallback, this, &dwScanResult);
if ( DevTemp.cbSize ) { SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevTemp); }
return(FALSE); } BOOL CheckDevice::CreateFileNode_Driver(void) { SP_DEVINSTALL_PARAMS DevInstallParams, DevTemp; SP_DEVINFO_DATA DevInfoData; SP_DRVINFO_DATA DrvInfoData; DWORD dwScanResult; HDEVINFO hDevInfo; HSPFILEQ hFileQueue; BOOL bProceed = TRUE;
// Reset all structures to empty
memset(&DevInstallParams, 0, sizeof(DevInstallParams)); memset(&DevInfoData, 0, sizeof(DevInfoData)); memset(&DrvInfoData, 0, sizeof(DrvInfoData)); memset(&DevTemp, 0, sizeof(DevInstallParams));
DrvInfoData.cbSize = sizeof(DrvInfoData); DevInfoData.cbSize = sizeof(DevInfoData); DevInstallParams.cbSize = sizeof(DevInstallParams);
hFileQueue = SetupOpenFileQueue();//and where does SetupCloseFileQueue get called?
// We need to build a driver node for the devnode
hDevInfo = m_hDevInfo; if ( INVALID_HANDLE_VALUE == hDevInfo ) return(0);
DevInfoData.Reserved = 0; if ( !SetupDiOpenDeviceInfo(hDevInfo, DeviceID(), NULL, NULL , &DevInfoData) ) { SetupDiDestroyDeviceInfoList(hDevInfo); return(FALSE); }
if ( !SetupDiBuildDriverInfoList(hDevInfo, &DevInfoData, SPDIT_COMPATDRIVER) ) { SetupDiDestroyDeviceInfoList(hDevInfo); return(FALSE); }
// select a driver
if ( DeviceName() ) strncpy(DrvInfoData.Description, DeviceName(),LINE_LEN); if ( MFG() ) strncpy(DrvInfoData.MfgName, MFG(),LINE_LEN); if ( InfProvider() ) strncpy(DrvInfoData.ProviderName, InfProvider(),LINE_LEN);
DrvInfoData.DriverType = SPDIT_COMPATDRIVER; if ( !SetupDiSetSelectedDriver(hDevInfo, &DevInfoData, &DrvInfoData) ) { DWORD err = GetLastError(); return(FALSE);
}
if ( SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams) ) { memcpy(&DevTemp, &DevInfoData, sizeof(DevInfoData)); }
DevInstallParams.FileQueue = hFileQueue; DevInstallParams.Flags |= (DI_NOVCP /*| DI_ENUMSINGLEINF | DI_DONOTCALLCONFIGMG | DI_NOFILECOPY | DI_NOWRITE_IDS*/) ; //DevInstallParams.Flags &= ~(DI_NODI_DEFAULTACTION);
//DevInstallParams.FlagsEx |= DI_FLAGSEX_NO_DRVREG_MODIFY;
//DevInstallParams.InstallMsgHandler = ScanQueueCallback;
//DevInstallParams.InstallMsgHandlerContext = this;
strncpy(DevInstallParams.DriverPath, InfName(),MAX_PATH);
SetLastError(0); SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams);
if ( !SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDevInfo, &DevInfoData) ) { DWORD err = GetLastError(); }
SetupScanFileQueue(hFileQueue, SPQ_SCAN_USE_CALLBACKEX, NULL, ScanQueueCallback, this, &dwScanResult);
if ( DevTemp.cbSize ) { SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevTemp); } SetupDiDestroyDeviceInfoList(hDevInfo); SetupCloseFileQueue(hFileQueue); return(FALSE); }
FileNode * CheckDevice::GetFileList(void) { return(m_FileList); }
FileNode::FileNode() { lpszFileName = NULL; lpszFileExt = NULL; baHashValue = NULL; dwHashSize = 0; pNext = NULL; FileSize = 0; lpszCatalogPath = NULL; m_pCatAttrib = NULL; bSigned = FALSE; }
FileNode::~FileNode() { /*if ( lpszFilePath )
{ delete [] lpszFilePath; }*/ lpszFileName = NULL; lpszFileExt = NULL;
if ( baHashValue ) { delete [] baHashValue; } baHashValue = NULL; dwHashSize = 0;
if ( lpszCatalogPath ) { delete lpszCatalogPath; } lpszCatalogPath = NULL;
if ( pNext ) { delete pNext; } pNext = NULL;
if ( m_pCatAttrib ) { delete m_pCatAttrib; } m_pCatAttrib = NULL; }
BOOL FileNode::GetFileInformation(void) { UINT dwSize; DWORD dwHandle; BYTE *pBuf; VS_FIXEDFILEINFO *lpVerData; HANDLE hFile; BY_HANDLE_FILE_INFORMATION FileInfo;
// get version of the file
dwSize = GetFileVersionInfoSize((LPTSTR)(LPCTSTR) lpszFilePath, &dwHandle); pBuf = new BYTE[dwSize];
if ( GetFileVersionInfo((LPTSTR)(LPCTSTR) lpszFilePath, dwHandle, dwSize, pBuf) ) { if ( VerQueryValue(pBuf, _T("\\"), (void **)&lpVerData, &dwSize) ) { Version.dwProductVersionLS = lpVerData->dwProductVersionLS; Version.dwProductVersionMS = lpVerData->dwProductVersionMS; Version.dwFileVersionLS = lpVerData->dwFileVersionLS; Version.dwFileVersionMS = lpVerData->dwFileVersionMS;
// while we're here get the file time as well)
TimeStamp.dwLowDateTime = lpVerData->dwFileDateLS; TimeStamp.dwHighDateTime = lpVerData->dwFileDateMS; } } delete [] pBuf;
// get file hash
if ( BADHANDLE(hCatAdmin) ) { CryptCATAdminAcquireContext(&hCatAdmin, NULL, 0); }
hFile = CreateFile(lpszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// BUGBUG: on for win9x inf.s, they might be in the inf\other directory
// BUGBUG: for whatever reason, sometimes setupapi will give c:\windows\system\driver dir, and not the sytem32\drivers
if ( BADHANDLE(hFile) ) { int foo = GetLastError(); return(FALSE); }
if ( CryptCATAdminCalcHashFromFileHandle(hFile, &dwHashSize, NULL, 0) ) { baHashValue = new BYTE[dwHashSize]; ZeroMemory(baHashValue, dwHashSize); CryptCATAdminCalcHashFromFileHandle(hFile, &dwHashSize, baHashValue, 0); } else { baHashValue = 0; }
// get file size
FileSize = GetFileSize(hFile, NULL);
// get time stamp
if ( GetFileInformationByHandle(hFile, &FileInfo) ) { TimeStamp = FileInfo.ftCreationTime; }
CloseHandle(hFile);
return(TRUE); }
BOOL FileNode::VerifyFile(void) { USES_CONVERSION; BOOL bRet; HCATINFO hCatInfo = NULL; HCATINFO PrevCat; WINTRUST_DATA WinTrustData; WINTRUST_CATALOG_INFO WinTrustCatalogInfo; DRIVER_VER_INFO VerInfo; GUID gSubSystemDriver = DRIVER_ACTION_VERIFY; //GUID gSubSystemDriver = WINTRUST_ACTION_GENERIC_VERIFY_V2;
HRESULT hRes = E_FAIL; CATALOG_INFO CatInfo; LPTSTR lpFilePart; WCHAR UnicodeKey[MAX_PATH]; TCHAR szBuffer[MAX_PATH];
// make sure that we can find the file
if ( !baHashValue || !dwHashSize || !FileSize ) { // seems that there is no file to check, or couldn't find it
return(FALSE); }
//
// Need to lower case file tag for old-style catalog files
//
lstrcpyn(szBuffer, lpszFilePath,MAX_PATH); CharLowerBuff(szBuffer, lstrlen(szBuffer)); #ifdef _UNICODE
CopyMemory(UnicodeKey, szBuffer, MAX_PATH * sizeof(WCHAR)); #else
MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, UnicodeKey, MAX_PATH); #endif
ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO)); VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
//
// Now we have the file's hash. Initialize the structures that
// will be used later on in calls to WinVerifyTrust.
//
ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA)); WinTrustData.cbStruct = sizeof(WINTRUST_DATA); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG; WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY; WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo; WinTrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE; WinTrustData.pCatalog = &WinTrustCatalogInfo;
ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO)); WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO); WinTrustCatalogInfo.pbCalculatedFileHash = baHashValue; WinTrustCatalogInfo.cbCalculatedFileHash = dwHashSize; WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey; WinTrustCatalogInfo.pcwszMemberFilePath = UnicodeKey;
//
// Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
//
PrevCat = NULL; hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, baHashValue, dwHashSize, 0, &PrevCat);
//
// We want to cycle through the matching catalogs until we find one that matches both hash and member tag
//
bRet = FALSE; while ( hCatInfo && !bRet ) { hRes = E_FAIL; ZeroMemory(&CatInfo, sizeof(CATALOG_INFO)); CatInfo.cbStruct = sizeof(CATALOG_INFO); if ( CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0) ) { WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
// Now verify that the file is an actual member of the catalog.
hRes = WinVerifyTrust(NULL, &gSubSystemDriver, &WinTrustData); if ( hRes == ERROR_SUCCESS ) { #ifdef _UNICODE
CopyMemory(szBuffer, CatInfo.wszCatalogFile, MAX_PATH * sizeof(TCHAR)); #else
WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, MAX_PATH, NULL, NULL); #endif
//Commented because of some weird prob!!
//GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart);
CString strCatalogPath(szBuffer); //strCatalogPath = strCatalogPath.Right(strCatalogPath.GetLength() - strCatalogPath.ReverseFind(_T('\\')));
strCatalogPath = _tcsrchr(lpszCatalogPath, '\\'); lpszCatalogName = strCatalogPath;
bRet = TRUE;
if ( VerInfo.pcSignerCertContext != NULL ) { CertFreeCertificateContext(VerInfo.pcSignerCertContext); VerInfo.pcSignerCertContext = NULL; }
// file is signed, so need to walk the cert chain to see who signed it
bSigned = WalkCertChain(WinTrustData.hWVTStateData); CloseHandle(WinTrustData.hWVTStateData);
} }
if ( !bRet ) { // The hash was in this catalog, but the file wasn't a member... so off to the next catalog
PrevCat = hCatInfo; hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, baHashValue, dwHashSize, 0, &PrevCat); } }
if ( !hCatInfo ) { //
// If it wasn't found in the catalogs, check if the file is individually signed.
//
bRet = VerifyIsFileSigned((LPTSTR)(LPCTSTR) lpszFilePath, (PDRIVER_VER_INFO) &VerInfo); if ( bRet ) { // If so, mark the file as being signed.
bSigned = TRUE; } } else { GetCatalogInfo(CatInfo.wszCatalogFile, hCatAdmin, hCatInfo); // The file was verified in the catalogs, so mark it as signed and free the catalog context.
CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0); }
if ( hRes == ERROR_SUCCESS ) { #ifdef _UNICODE
CopyMemory(szBuffer, VerInfo.wszSignedBy, MAX_PATH * sizeof(TCHAR)); #else
WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL); #endif
lpszSignedBy = szBuffer;
}
//
// close wintrust state
//
WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust(NULL, &gSubSystemDriver, &WinTrustData);
return(bSigned); }
/*************************************************************************
* Function : VerifyIsFileSigned * Purpose : Calls WinVerifyTrust with Policy Provider GUID to * verify if an individual file is signed. **************************************************************************/ BOOL FileNode::VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo) { USES_CONVERSION; INT iRet; HRESULT hRes; WINTRUST_DATA WinTrustData; WINTRUST_FILE_INFO WinTrustFile; GUID gOSVerCheck = DRIVER_ACTION_VERIFY; GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2; WCHAR wszFileName[MAX_PATH];
ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA)); WinTrustData.cbStruct = sizeof(WINTRUST_DATA); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE; WinTrustData.pFile = &WinTrustFile; WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo;
ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO)); lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO)); WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
#ifdef _UNICODE
CopyMemory(wszFileName, pcszMatchFile, MAX_PATH * sizeof(WCHAR)); #else
iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)&wszFileName, wcslen(wszFileName)); #endif
WinTrustFile.pcwszFilePath = wszFileName;
hRes = WinVerifyTrust((HWND__ *)INVALID_HANDLE_VALUE, &gOSVerCheck, &WinTrustData); if ( hRes != ERROR_SUCCESS ) hRes = WinVerifyTrust((HWND__ *)INVALID_HANDLE_VALUE, &gPublishedSoftware, &WinTrustData);
return(hRes == ERROR_SUCCESS); }
LogoFileVersion::LogoFileVersion() { dwProductVersionLS = 0; dwProductVersionMS = 0; dwFileVersionLS = 0; dwFileVersionMS = 0; }
CatalogAttribute::CatalogAttribute() { Attrib = NULL; Value = NULL; pNext = NULL; }
CatalogAttribute::~CatalogAttribute() { if ( Attrib ) delete [] Attrib; if ( Value ) delete [] Value; if ( pNext ) delete pNext;
Attrib = NULL; Value = NULL; pNext = NULL;
}
// Function: ScanQueueCallback
// Parameters:
// pvContext: Pointer to a context that contains any data needed
// Notify: The type of message received
// Param1: The pointer to the string containing the filename
// Param2: Not used
// Purpose: This function gets called when you tell the setup environment to scan
// through the file queue. Basically it receives the filenames and copies
// them into a string.
// Returns: NO_ERROR if nothing went wrong and ERROR_NOT_ENOUGH_MEMORY if their is no
// free memory
UINT __stdcall ScanQueueCallback(PVOID pvContext, UINT Notify, UINT_PTR Param1, UINT_PTR Param2) { CheckDevice *pDevice = (CheckDevice *)pvContext; PFILEPATHS pfilepaths;
if ( (SPFILENOTIFY_QUEUESCAN == Notify) && Param1 ) { pDevice->AddFileNode((TCHAR *)Param1); }
if ( (SPFILENOTIFY_QUEUESCAN_EX == Notify) && Param1 ) { pfilepaths = (PFILEPATHS)Param1; ////////////////Put Signer in the 3rd param whenever its available!
pDevice->AddFileNode((LPTSTR)pfilepaths->Target , pfilepaths->Win32Error , /*pfilepaths->csSigner*/ NULL); }
return(NO_ERROR); }
BOOL FileNode::GetCatalogInfo(LPWSTR lpwzCatName, HCATADMIN hCatAdmin, HCATINFO hCatInfo) { USES_CONVERSION; HANDLE hCat; CRYPTCATATTRIBUTE *pCatAttrib; TCHAR szBuffer[512]; CRYPTCATMEMBER *pMember = NULL; PSIP_INDIRECT_DATA pSipData; CatalogAttribute *CatAttribute;
hCat = CryptCATOpen(lpwzCatName, CRYPTCAT_OPEN_EXISTING, NULL, 0, 0);
if ( BADHANDLE(hCat) ) { return(FALSE); }
pCatAttrib = NULL;
while ( pCatAttrib = CryptCATEnumerateCatAttr(hCat, pCatAttrib) ) { if ( pCatAttrib->dwAttrTypeAndAction | CRYPTCAT_ATTR_NAMEASCII ) { #ifdef _UNICODE
CopyMemory(szBuffer, pCatAttrib->pwszReferenceTag, 511 * sizeof(TCHAR)); #else
WideCharToMultiByte(CP_ACP, 0, pCatAttrib->pwszReferenceTag, -1, szBuffer, 511, NULL, NULL); #endif
CatAttribute = new CatalogAttribute;
if ( !CatAttribute ) { return(FALSE); }
CatAttribute->Attrib = new TCHAR[strlen(szBuffer) +1]; if ( !CatAttribute->Attrib ) { delete CatAttribute; return(FALSE); } _tcscpy(CatAttribute->Attrib, szBuffer);
#ifdef _UNICODE
CopyMemory(szBuffer, (PUSHORT)pCatAttrib->pbValue, 511 * sizeof(TCHAR)); #else
WideCharToMultiByte(CP_ACP, 0, (PUSHORT)pCatAttrib->pbValue, -1, szBuffer, 511, NULL, NULL); #endif
CatAttribute->Value = new TCHAR[strlen(szBuffer) + 1]; if ( !CatAttribute->Value ) { delete CatAttribute; return(FALSE); }
_tcscpy(CatAttribute->Value, szBuffer);
// add to node
CatAttribute->pNext = (void *)m_pCatAttrib; m_pCatAttrib = CatAttribute; }
}
while ( pMember = CryptCATEnumerateMember(hCat, pMember) ) { pSipData = pMember->pIndirectData;
}
CryptCATClose(hCat);
return(TRUE); }
BOOL CheckFile (TCHAR *szFileName) { FileNode *pThisFile = NULL; BOOL bRet = FALSE; // v-jammar; fix prefix bug 427999
try //v-stlowe: 3/20/2001: to fix prefix bug where memory was leaking on out-of-mem throw
{ pThisFile = new FileNode; if ( !pThisFile ) { return(FALSE); }
pThisFile->lpszFilePath = new TCHAR[strlen(szFileName) + 1]; if ( !pThisFile->lpszFilePath ) { delete pThisFile; return(FALSE); }
pThisFile->lpszFilePath = szFileName;
// copyed the data
pThisFile->lpszFileName = _tcsrchr(pThisFile->lpszFilePath, '\\'); pThisFile->lpszFileName++;
pThisFile->lpszFileExt = _tcsrchr(pThisFile->lpszFilePath, '.'); pThisFile->lpszFileExt++;
// get the version information
pThisFile->GetFileInformation();
bRet = pThisFile->VerifyFile(); } catch(...) {
} // BUGBUG, need to check out the signer of this file to determine
// who actually signed it.
if(pThisFile) { delete pThisFile; pThisFile = NULL; }
return(bRet); }
BOOL Share_CloseHandle(void) { if ( !BADHANDLE(hCatAdmin) ) { CryptCATAdminReleaseContext(hCatAdmin, 0); hCatAdmin = 0; } return(TRUE);
}
//BOOL FileNode::GetCertInfo(PCCERT_CONTEXT pCertContext)
//{
// DWORD Size = 200;
// #if 0
//
// Size = 200;
// if ( CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pArray, &Size) )
// {
// printf("\nSH1 Hash (%u):", Size);
// for ( UINT index = 0; index < Size; index++ )
// {
// printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]);
// }
// printf("\n");
// }
//
//
//
// Size = 200;
// if ( CertGetCertificateContextProperty(pCertContext, CERT_SIGNATURE_HASH_PROP_ID, pArray, &Size) )
// {
// printf("\nCert Hash (%u):", Size);
// for ( UINT index = 0; index < Size; index++ )
// {
// printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]);
// }
// printf("\n");
// }
// Get Chain information
// CERT_CHAIN_PARA ChainPara;
// PCCERT_CHAIN_CONTEXT pChainContext = NULL;
// memset (&CharinPara, 0, sizeof (CERT_CHAIN_PARA));
// ChainPara.cbSize = sizeof (CERT_CHAIN_PARA);
// ChainPara.RequestedUsage.
// if ( CertGetCertificateChain(NULL, pCertContext, NULL, NULL, ) )
// {
// }
// #endif
// return(TRUE);
//}
BOOL WalkCertChain(HANDLE hWVTStateData) { CRYPT_PROVIDER_DATA * pProvData; CRYPT_PROVIDER_SGNR * pProvSigner = NULL; CRYPT_PROVIDER_CERT * pCryptProviderCert;
BYTE pArray[21]; UINT i; DWORD size;
pProvData = WTHelperProvDataFromStateData(hWVTStateData);
// did it work?
if ( !pProvData ) { return(FALSE); }
pProvSigner = WTHelperGetProvSignerFromChain( (PCRYPT_PROVIDER_DATA) pProvData, 0, // first signer
FALSE, //not counter signature
0); // index of counter sig, obviously not used
if ( pProvSigner == NULL ) { return(FALSE); } //
// walk all certs, the leaf cert is index 0, the root is the last index
//
pCryptProviderCert = NULL; for ( i = 0; i < pProvSigner->csCertChain; i++ ) { pCryptProviderCert = WTHelperGetProvCertFromChain(pProvSigner, i); if ( pCryptProviderCert == NULL ) { // error
}
size = 20; if ( CertGetCertificateContextProperty( pCryptProviderCert->pCert, CERT_SHA1_HASH_PROP_ID, pArray, &size) ) { /*
printf("\nSH1 Hash (%u):{", size); for ( UINT index = 0; index < size; index++ ) { printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]); } printf("}\n"); */
for ( UINT j = 0; j < NumberTestCerts; j++ ) { if ( !memcmp(pArray, TestCertHashes[j], 20) ) { // This cert is a test cert, not a real one, fail
//printf("This file is signed by the testcert, and is therefor not trusted\n");
//pritnf("please check the certification for this device");
return (TRUE); } } }
}
return(FALSE);
}
|