|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: chktrust.cpp
//
// Contents: Microsoft Internet Security Trust Checker
//
// History: 05-May-1997 pberkman created
//
//--------------------------------------------------------------------------
#include <stdio.h>
#include <windows.h>
#include <io.h>
#include <wchar.h>
#include "cryptreg.h"
#include "wincrypt.h"
#include "wintrust.h"
#include "softpub.h"
#include "mscat.h"
#include "unicode.h"
#include "dbgdef.h"
#include "gendefs.h"
#include "cwargv.hxx"
#include "printfu.hxx"
#include "mssip.h"
#include "resource.h"
HRESULT _CallWVT(WCHAR *pwszFilename); HRESULT _ExplodeCatalog(WCHAR *pwszCatalogFile); HRESULT _CallCatalogWVT(WCHAR *pwszCatalogFile, WCHAR *pwszMemberTag, WCHAR *pwszMemberFile); int _ShowError(DWORD dwError, WCHAR *pwszFile); void _ToLower(WCHAR *pwszInOut); HRESULT _AddCatalogToDatabase(WCHAR *pwszFileIn); HRESULT _DelCatalogFromDatabase(WCHAR *pwszFileIn);
GUID guidPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2; GUID guidProviderTest = WINTRUST_ACTION_TRUSTPROVIDER_TEST; GUID guidProviderDriver = DRIVER_ACTION_VERIFY; GUID guidPassedIn; GUID guidCatRoot;
GUID *pguidActionID = &guidPublishedSoftware; GUID *pguidCatRoot = NULL;
DWORD dwExpectedError = ERROR_SUCCESS;
WCHAR *pwszCatalogFile = NULL; WCHAR *pwszCatalogMember = NULL; WCHAR *pwszOSVerLow = NULL; WCHAR *pwszOSVerHigh = NULL; BOOL fUseOldDriverVerInfoSize = FALSE;
PrintfU_ *pPrint = NULL;
HCATADMIN hCatAdmin = NULL;
BOOL fVerbose; BOOL fQuiet; BOOL fIECall; BOOL fTestDump; BOOL fCheckExpectedError = FALSE; BOOL fProcessAllCatMembers; BOOL fCatalogMemberVerify = FALSE; BOOL fUseCatalogDatabase; BOOL fAdd2CatalogDatabase; BOOL fDelFromCatalogDatabase; BOOL fReplaceCatfile; BOOL fNT5; BOOL fNoTimeStampWarning;
extern "C" int __cdecl wmain(int argc, WCHAR **wargv) { cWArgv_ *pArgs; BOOL fFailed;
BOOL fFind; HANDLE hFind; WIN32_FIND_DATAW sFindData;
int iRet; int iRetWorst; HRESULT hr = ERROR_SUCCESS;
WCHAR *pwszFileIn; WCHAR *pwszLastSlash; WCHAR wszFile[MAX_PATH]; WCHAR wszDir[MAX_PATH]; char szFile[MAX_PATH * 2]; DWORD dwFiles; DWORD dwDirLen;
iRet = 0; pPrint = NULL; hFind = INVALID_HANDLE_VALUE; dwFiles = 0;
if (!(pPrint = new PrintfU_())) { goto MemoryError; }
if (!(pArgs = new cWArgv_((HINSTANCE)GetModuleHandle(NULL), &fFailed, FALSE))) { goto MemoryError; }
if (fFailed) { goto MemoryError; }
pArgs->AddUsageText(IDS_USAGETEXT_USAGE, IDS_USAGETEXT_OPTIONS, IDS_USAGETEXT_CMDFILE, IDS_USAGETEXT_ADD, IDS_USAGETEXT_OPTPARAM);
pArgs->Add2List(IDS_PARAM_HELP, IDS_PARAMTEXT_HELP, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE); pArgs->Add2List(IDS_PARAM_VERBOSE, IDS_PARAMTEXT_VERBOSE, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE); pArgs->Add2List(IDS_PARAM_QUIET, IDS_PARAMTEXT_QUIET, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE); pArgs->Add2List(IDS_PARAM_TPROV, IDS_PARAMTEXT_TPROV, WARGV_VALUETYPE_WCHAR, NULL, TRUE); pArgs->Add2List(IDS_PARAM_IECALL, IDS_PARAMTEXT_IECALL, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_TESTDUMP, IDS_PARAMTEXT_TESTDUMP, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_EXPERROR, IDS_PARAMTEXT_EXPERROR, WARGV_VALUETYPE_DWORDH, NULL, TRUE); pArgs->Add2List(IDS_PARAM_TESTDRV, IDS_PARAMTEXT_TESTDRV, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_CATFILE, IDS_PARAMTEXT_CATFILE, WARGV_VALUETYPE_WCHAR, NULL, TRUE); pArgs->Add2List(IDS_PARAM_CATMEMBER, IDS_PARAMTEXT_CATMEMBER, WARGV_VALUETYPE_WCHAR, NULL, TRUE); pArgs->Add2List(IDS_PARAM_ALLCATMEM, IDS_PARAMTEXT_ALLCATMEM, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_CATUSELIST, IDS_PARAMTEXT_CATUSELIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_CATADDLIST, IDS_PARAMTEXT_CATADDLIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_CATDELLIST, IDS_PARAMTEXT_CATDELLIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_REPLACECATFILE,IDS_PARAMTEXT_REPLACECATFILE, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_CATROOT, IDS_PARAMTEXT_CATROOT, WARGV_VALUETYPE_WCHAR, NULL, TRUE); pArgs->Add2List(IDS_PARAM_NT5, IDS_PARAMTEXT_NT5, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_TSWARN, IDS_PARAMTEXT_TSWARN, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE); pArgs->Add2List(IDS_PARAM_OSVERLOW, IDS_PARAMTEXT_OSVERLOW, WARGV_VALUETYPE_WCHAR, NULL, TRUE); pArgs->Add2List(IDS_PARAM_OSVERHIGH, IDS_PARAMTEXT_OSVERHIGH, WARGV_VALUETYPE_WCHAR, NULL, TRUE); if (!(pArgs->Fill(argc, wargv)) || (pArgs->GetValue(IDS_PARAM_HELP))) { wprintf(L"%s", pArgs->GetUsageString()); goto NeededHelp; }
pwszCatalogFile = (WCHAR *)pArgs->GetValue(IDS_PARAM_CATFILE); pwszCatalogMember = (WCHAR *)pArgs->GetValue(IDS_PARAM_CATMEMBER); fVerbose = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_VERBOSE)); fQuiet = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_QUIET)); fIECall = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_IECALL)); fTestDump = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_TESTDUMP)); fProcessAllCatMembers = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_ALLCATMEM)); fUseCatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATUSELIST)); fAdd2CatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATADDLIST)); fDelFromCatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATDELLIST)); fReplaceCatfile = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_REPLACECATFILE)); fNT5 = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_NT5)); fNoTimeStampWarning = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_TSWARN)); pwszOSVerLow = (WCHAR *)pArgs->GetValue(IDS_PARAM_OSVERLOW); pwszOSVerHigh = (WCHAR *)pArgs->GetValue(IDS_PARAM_OSVERHIGH);
//
// the win2k flag implies -q and -ucl (unless -acl or -del is used, then it just implies -q)
//
if (fNT5) { fQuiet = TRUE; if (!fAdd2CatalogDatabase && !fDelFromCatalogDatabase) { fUseCatalogDatabase = TRUE; } }
if (fUseCatalogDatabase || fNT5) { fCatalogMemberVerify = TRUE; }
if (pArgs->IsSet(IDS_PARAM_EXPERROR)) { dwExpectedError = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_EXPERROR)); fCheckExpectedError = TRUE; }
if (!(pwszFileIn = pArgs->GetFileName())) { wprintf(L"%s", pArgs->GetUsageString()); goto ParamError; }
if (((pwszCatalogFile) && !(pwszCatalogMember)) || (!(pwszCatalogFile) && (pwszCatalogMember))) { wprintf(L"%s", pArgs->GetUsageString()); goto ParamError; }
if ((pwszCatalogFile) && (pwszCatalogMember)) { fCatalogMemberVerify = TRUE; }
//
// set the appropriete provider
//
if (pArgs->IsSet(IDS_PARAM_TPROV) || fNT5) { if (fNT5) { wstr2guid(L"{F750E6C3-38EE-11D1-85E5-00C04FC295EE}", &guidPassedIn); } else if (!(wstr2guid((WCHAR *)pArgs->GetValue(IDS_PARAM_TPROV), &guidPassedIn))) { goto GuidError; }
pguidActionID = &guidPassedIn; } else if (fTestDump) { pguidActionID = &guidProviderTest; } else if (pArgs->GetValue(IDS_PARAM_TESTDRV)) { pguidActionID = &guidProviderDriver; } else { pguidActionID = &guidPublishedSoftware; }
//
// Get the catalog subsystem GUID to use
//
if (pArgs->IsSet(IDS_PARAM_CATROOT) || fNT5) { if (fNT5) { wstr2guid(L"{F750E6C3-38EE-11D1-85E5-00C04FC295EE}", &guidCatRoot); } else if (!(wstr2guid((WCHAR *)pArgs->GetValue(IDS_PARAM_CATROOT), &guidCatRoot))) { goto GuidError; }
pguidCatRoot = &guidCatRoot; }
//
// if we are calling just like IE, we only have one file and don't want to
// check if it exists or not... just call WVT.
//
if (fIECall) { dwFiles++;
hr = _CallWVT(pwszFileIn);
iRet = _ShowError(hr, pwszFileIn);
goto CommonReturn; }
//
// Check to see if we are supposed to be using the old DRIVER_VER_INFO struct
//
while (--argc>0) { if (**++wargv == L'-') { if (wcscmp(*wargv, L"-UseOldDriverVerInfoStruct") == 0) { fUseOldDriverVerInfoSize = TRUE; break; } } }
//
// If a delete is being done, then just execute that and get out
//
if (fDelFromCatalogDatabase) { hr = _DelCatalogFromDatabase(pwszFileIn); iRet = _ShowError(hr, &wszFile[0]); goto CommonReturn; }
//
// OK.... go into a findfirst/next loop we could have been called with *.*
//
if (pwszLastSlash = wcsrchr(pwszFileIn, L'\\')) { *pwszLastSlash = NULL; wcscpy(&wszDir[0], pwszFileIn); wcscat(&wszDir[0], L"\\"); *pwszLastSlash = L'\\'; dwDirLen = wcslen(&wszDir[0]); } else { wszDir[0] = NULL; dwDirLen = 0; }
if ((hFind = FindFirstFileU(pwszFileIn, &sFindData)) == INVALID_HANDLE_VALUE) { pPrint->Display(IDS_CAN_NOT_OPEN_FILE, pwszFileIn); goto FileNotFound; }
fFind = TRUE; dwFiles = 0; iRetWorst = 0;
while (fFind) { if (!(sFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (dwDirLen > 0) { wcscpy(&wszFile[0], &wszDir[0]); }
wszFile[dwDirLen] = NULL; wcscat(wszFile, sFindData.cFileName);
if (wszFile[0]) { if (fAdd2CatalogDatabase) { hr = _AddCatalogToDatabase(&wszFile[0]); } else { hr = _CallWVT(&wszFile[0]); }
iRet = _ShowError(hr, &wszFile[0]);
switch (iRet) { case 0: // No Error
break;
case 1: // Error
iRetWorst = iRet; break;
case 2: // Warning (no timestamp)
if (iRetWorst != 1) { iRetWorst = iRet; } // No other return values are possible from _ShowError
}
if (iRet == 0) { hr = ERROR_SUCCESS; }
dwFiles++; } }
fFind = FindNextFileU(hFind, &sFindData); }
iRet = iRetWorst;
if (dwFiles < 1) { pPrint->Display(IDS_CAN_NOT_OPEN_FILE, pwszFileIn); goto FileNotFound; }
CommonReturn: DELETE_OBJECT(pArgs); DELETE_OBJECT(pPrint);
if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); }
if (hCatAdmin) { CryptCATAdminReleaseContext(hCatAdmin, 0); }
return(iRet);
ErrorReturn: iRet = 1; goto CommonReturn;
TRACE_ERROR_EX(DBG_SS_APP, MemoryError); TRACE_ERROR_EX(DBG_SS_APP, FileNotFound); TRACE_ERROR_EX(DBG_SS_APP, ParamError); TRACE_ERROR_EX(DBG_SS_APP, GuidError); TRACE_ERROR_EX(DBG_SS_APP, NeededHelp); }
HRESULT _CallWVT(WCHAR *pwszFilename) { if (fCatalogMemberVerify) { return(_CallCatalogWVT(pwszCatalogFile, pwszCatalogMember, pwszFilename)); }
HRESULT hr; WINTRUST_DATA sWTD; WINTRUST_FILE_INFO sWTFI;
memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
sWTD.cbStruct = sizeof(WINTRUST_DATA); sWTD.dwUIChoice = (fQuiet) ? WTD_UI_NONE : WTD_UI_ALL; sWTD.dwUnionChoice = WTD_CHOICE_FILE; sWTD.pFile = &sWTFI;
memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO));
sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); sWTFI.pcwszFilePath = pwszFilename; sWTFI.hFile = CreateFileU(pwszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
if (sWTFI.hFile != INVALID_HANDLE_VALUE) { CloseHandle(sWTFI.hFile); }
if ((fCheckExpectedError) && ((DWORD)hr == dwExpectedError) && (fProcessAllCatMembers)) { if (IsCatalogFile(INVALID_HANDLE_VALUE, pwszFilename)) { return(_ExplodeCatalog(pwszFilename)); } }
return(hr); }
HRESULT _ExplodeCatalog(WCHAR *pwszCatalogFile) { HRESULT hrReturn; HANDLE hCat; CRYPTCATMEMBER *psMember;
hrReturn = ERROR_SUCCESS;
//
// open the catalog
//
if (!(hCat = CryptCATOpen(pwszCatalogFile, 0, NULL, 0, 0))) { goto ErrorCatOpen; }
psMember = NULL;
while (psMember = CryptCATEnumerateMember(hCat, psMember)) { hrReturn |= _CallCatalogWVT(pwszCatalogFile, psMember->pwszReferenceTag, psMember->pwszReferenceTag); }
CommonReturn: if (hCat) { CryptCATClose(hCat); }
return(hrReturn);
ErrorReturn: hrReturn = GetLastError(); goto CommonReturn;
TRACE_ERROR_EX(DBG_SS_APP, ErrorCatOpen); }
HRESULT _CallCatalogWVT(WCHAR *pwszCatalogFile, WCHAR *pwszMemberTag, WCHAR *pwszMemberFile) { HRESULT hr; DWORD cbHash; BYTE bHash[40]; WCHAR *pwsz; WINTRUST_DATA sWTD; WINTRUST_CATALOG_INFO sWTCI; DRIVER_VER_INFO sDriverInfo;
memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
sWTD.cbStruct = sizeof(WINTRUST_DATA); sWTD.dwUIChoice = (fQuiet) ? WTD_UI_NONE : WTD_UI_ALL; sWTD.dwUnionChoice = WTD_CHOICE_CATALOG; sWTD.pCatalog = &sWTCI;
memset(&sWTCI, 0x00, sizeof(WINTRUST_CATALOG_INFO));
sWTCI.cbStruct = sizeof(WINTRUST_CATALOG_INFO); sWTCI.pcwszCatalogFilePath = pwszCatalogFile; sWTCI.pcwszMemberTag = pwszMemberTag; sWTCI.pcwszMemberFilePath = pwszMemberFile; sWTCI.hMemberFile = CreateFileU(pwszMemberFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (pwszOSVerLow != NULL) { WCHAR *pwszEnd; WCHAR *pwszCurrent;
memset(&sDriverInfo, 0x00, sizeof(DRIVER_VER_INFO)); sDriverInfo.cbStruct = fUseOldDriverVerInfoSize ? _OFFSETOF(DRIVER_VER_INFO, dwBuildNumberLow) : sizeof(DRIVER_VER_INFO);
pwszEnd = wcschr(pwszOSVerLow, L':'); if (pwszEnd == NULL) { goto OSVerError; } *pwszEnd = L'\0'; sDriverInfo.dwPlatform = _wtol(pwszOSVerLow); *pwszEnd = L':';
pwszCurrent = pwszEnd + 1; pwszEnd = wcschr(pwszCurrent, L'.'); if (pwszEnd == NULL) { goto OSVerError; } *pwszEnd = L'\0'; sDriverInfo.sOSVersionLow.dwMajor = sDriverInfo.sOSVersionHigh.dwMajor = _wtol(pwszCurrent); *pwszEnd = L'.';
pwszCurrent = pwszEnd + 1; pwszEnd = wcschr(pwszCurrent, L'.'); if (pwszEnd == NULL) { sDriverInfo.sOSVersionLow.dwMinor = sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent); } else { *pwszEnd = L'\0'; sDriverInfo.sOSVersionLow.dwMinor = sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent); *pwszEnd = L'.';
pwszCurrent = pwszEnd + 1; sDriverInfo.dwBuildNumberLow = sDriverInfo.dwBuildNumberHigh = _wtol(pwszCurrent); } if (pwszOSVerHigh != NULL) { pwszEnd = wcschr(pwszOSVerHigh, L':'); if (pwszEnd == NULL) { goto OSVerError; } *pwszEnd = L'\0'; if (sDriverInfo.dwPlatform != (DWORD) _wtol(pwszOSVerHigh)) { goto OSVerError; } *pwszEnd = L':';
pwszCurrent = pwszEnd + 1; pwszEnd = wcschr(pwszCurrent, L'.'); if (pwszEnd == NULL) { goto OSVerError; } *pwszEnd = L'\0'; sDriverInfo.sOSVersionHigh.dwMajor = _wtol(pwszCurrent); *pwszEnd = L'.';
pwszCurrent = pwszEnd + 1; pwszEnd = wcschr(pwszCurrent, L'.'); if (pwszEnd == NULL) { sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent); } else { *pwszEnd = L'\0'; sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent); *pwszEnd = L'.'; pwszCurrent = pwszEnd + 1; sDriverInfo.dwBuildNumberHigh = _wtol(pwszCurrent); } }
sWTD.pPolicyCallbackData = &sDriverInfo; }
cbHash = 40;
if (!(CryptCATAdminCalcHashFromFileHandle(sWTCI.hMemberFile, &cbHash, &bHash[0], 0))) { goto CatAdminCalcHashError; }
sWTCI.pbCalculatedFileHash = &bHash[0]; sWTCI.cbCalculatedFileHash = cbHash;
if (fUseCatalogDatabase) { HCATINFO hCatInfo; CATALOG_INFO sCatInfo;
if (!(hCatAdmin)) { if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0))) { goto CatAdminAcquireError; } }
pwsz = NULL;
if (pwsz = wcsrchr(pwszMemberFile, L'\\')) { pwsz++; } else { pwsz = pwszMemberFile; }
_ToLower(pwsz);
sWTCI.pcwszMemberTag = pwsz;
memset(&sCatInfo, 0x00, sizeof(CATALOG_INFO)); sCatInfo.cbStruct = sizeof(CATALOG_INFO);
hCatInfo = NULL;
while (hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, &bHash[0], cbHash, 0, &hCatInfo)) { if (!(CryptCATCatalogInfoFromContext(hCatInfo, &sCatInfo, 0))) { // should do something (??)
continue; }
sWTCI.pcwszCatalogFilePath = &sCatInfo.wszCatalogFile[0];
hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
if ((sWTD.pPolicyCallbackData != 0) && (sDriverInfo.pcSignerCertContext != NULL)) { CertFreeCertificateContext(sDriverInfo.pcSignerCertContext); }
if (hr == (HRESULT)dwExpectedError) { CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
goto CommonReturn; } } goto CatMemberNotFound; }
hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
CommonReturn: if (sWTCI.hMemberFile != INVALID_HANDLE_VALUE) { CloseHandle(sWTCI.hMemberFile); }
return(hr);
ErrorReturn: hr = GetLastError(); goto CommonReturn;
OSVerError: wprintf(L"Invalid osverl or osverh\n"); return S_FALSE;
TRACE_ERROR_EX(DBG_SS_APP, CatAdminCalcHashError); TRACE_ERROR_EX(DBG_SS_APP, CatAdminAcquireError); TRACE_ERROR_EX(DBG_SS_APP, CatMemberNotFound); }
BOOL OpenSIP(const WCHAR* pwsFileName, SIP_SUBJECTINFO** ppSubjectInfo, SIP_DISPATCH_INFO** ppDispatchInfo, GUID* pgSubject) {
if (pgSubject == NULL) { return FALSE; }
if (NULL == (*ppSubjectInfo = (SIP_SUBJECTINFO*) new(BYTE[sizeof(SIP_SUBJECTINFO)]))) { return FALSE; } if (NULL == (*ppDispatchInfo = (SIP_DISPATCH_INFO*) new(BYTE[sizeof(SIP_DISPATCH_INFO)]))) { delete[] (*ppSubjectInfo); return FALSE; }
memset((void*)*ppSubjectInfo, 0, sizeof(SIP_SUBJECTINFO)); memset((void*)*ppDispatchInfo, 0, sizeof(SIP_DISPATCH_INFO)); memset((void*)pgSubject, 0, sizeof(GUID));
// Get the type of SIP
if (!CryptSIPRetrieveSubjectGuid( pwsFileName, NULL, pgSubject)) { goto ErrorReturn; }
(*ppDispatchInfo)->cbSize = sizeof(SIP_DISPATCH_INFO);
// Load the SIP
if (!CryptSIPLoad( pgSubject, 0, *ppDispatchInfo)) { goto ErrorReturn; }
// Fill in the SIP_SUBJECTINFO struct
(*ppSubjectInfo)->cbSize = sizeof(SIP_SUBJECTINFO); (*ppSubjectInfo)->pgSubjectType = pgSubject; (*ppSubjectInfo)->pwsFileName = pwsFileName;
goto CommonReturn;
ErrorReturn: delete[](*ppSubjectInfo); delete[](*ppDispatchInfo); return FALSE;
CommonReturn: return TRUE; }
BOOL ReadMsgBlob(const WCHAR* pwsFileName, CRYPT_DATA_BLOB* pData) { if ((pwsFileName == NULL) || (pData == NULL)) { return FALSE; }
SIP_SUBJECTINFO* pSubjectInfo = NULL; SIP_DISPATCH_INFO* pDispatchInfo = NULL; GUID gSubject;
memset((void*)&gSubject, 0, sizeof(gSubject));
// Get the SIP
if (!OpenSIP( pwsFileName, &pSubjectInfo, &pDispatchInfo, &gSubject)) { return FALSE; }
// Load the message blob
DWORD dwEncodingType = 0; pData->cbData = 0;
if (!pDispatchInfo->pfGet( pSubjectInfo, &dwEncodingType, 0, &(pData->cbData), NULL)) { delete[](pSubjectInfo); delete[](pDispatchInfo); return FALSE; }
pData->pbData = (BYTE*)new(BYTE[pData->cbData]); if (pData->pbData == NULL) return FALSE;
memset((void*)pData->pbData, 0, pData->cbData);
if (!pDispatchInfo->pfGet( pSubjectInfo, &dwEncodingType, 0, &(pData->cbData), pData->pbData)) { delete[](pData->pbData); delete[](pSubjectInfo); delete[](pDispatchInfo); return FALSE; }
delete[](pSubjectInfo); delete[](pDispatchInfo); return TRUE; }
BOOL CheckForTimeStamp(WCHAR *pwszFile) { BOOL fRet = TRUE; HANDLE hFile = INVALID_HANDLE_VALUE; HCRYPTMSG hMsg = NULL; BYTE *pb = NULL; DWORD cb = 0; DWORD cbRead = 0; PCMSG_ATTR pMsgAttr = NULL; DWORD cbMsgAttr = 0; CRYPT_ATTRIBUTE *pAttr = NULL; CRYPT_DATA_BLOB blob; DWORD dwEncodingType;
if (!ReadMsgBlob(pwszFile, &blob)) { return FALSE; }
//
// If the encoded message was passed in the use CryptMsg to crack the encoded PKCS7 Signed Message
//
if (!(hMsg = CryptMsgOpenToDecode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 0, 0, 0, NULL, NULL))) { goto ErrorReturn; }
if (!CryptMsgUpdate(hMsg, blob.pbData, blob.cbData, TRUE)) // fFinal
{ CryptMsgClose(hMsg); goto ErrorReturn; } //
// get the unauthenticated attributes because that is where the counter signer is
//
CryptMsgGetParam(hMsg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, NULL, &cbMsgAttr);
if (cbMsgAttr == 0) { goto ErrorReturn; }
if (NULL == (pMsgAttr = (CMSG_ATTR *) new(BYTE[cbMsgAttr]))) { goto ErrorReturn; }
if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, (void *) pMsgAttr, &cbMsgAttr)) { goto ErrorReturn; }
//
// search for the counter signer in the unauthenticated attributes
//
if ((pAttr = CertFindAttribute(szOID_RSA_counterSign, pMsgAttr->cAttr, pMsgAttr->rgAttr)) == NULL) { //
// no counter signature
//
goto ErrorReturn; }
Cleanup:
delete[](blob.pbData);
if (pMsgAttr) delete[](pMsgAttr);
if (hMsg != NULL) CryptMsgClose(hMsg);
return fRet;
ErrorReturn: fRet = FALSE; goto Cleanup;
}
int _ShowError(DWORD dwError, WCHAR *pwszFile) { pPrint->Display(IDS_FILEREF, pwszFile);
if (fCheckExpectedError) { if (dwError == dwExpectedError) { pPrint->Display(IDS_SUCCEEDED); return(0); } else { pPrint->Display(IDS_EXPECTED_HRESULT, dwExpectedError, dwError); return(1); } }
switch(dwError) { case S_OK: pPrint->Display(IDS_SUCCEEDED); if (fNoTimeStampWarning) { if (!CheckForTimeStamp(pwszFile)) { pPrint->Display(IDS_NO_TIMESTAMP_WARNING); return(2); } } return(0);
case TRUST_E_SUBJECT_FORM_UNKNOWN: pPrint->Display(IDS_UNKNOWN_FILE_TYPE); break;
case TRUST_E_PROVIDER_UNKNOWN: pPrint->Display(IDS_UNKNOWN_PROVIDER); break;
case TRUST_E_ACTION_UNKNOWN: pPrint->Display(IDS_UNKNOWN_ACTION); break;
case TRUST_E_SUBJECT_NOT_TRUSTED: pPrint->Display(IDS_SUBJECT_NOT_TRUSTED); break;
default: pPrint->Display(IDS_FAIL, GetLastError());
break; } return(1); }
HRESULT _AddCatalogToDatabase(WCHAR *pwszFileIn) { HCATINFO hCatInfo; WCHAR *pwszBaseName; if (!(hCatAdmin)) { if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0))) { return(GetLastError()); } }
//
// set the base file name
//
if (!(pwszBaseName = wcsrchr(pwszFileIn, L'\\'))) { pwszBaseName = wcsrchr(pwszFileIn, L':'); }
if (pwszBaseName) { *pwszBaseName++; } else { pwszBaseName = pwszFileIn; }
if (hCatInfo = CryptCATAdminAddCatalog(hCatAdmin, pwszFileIn, fReplaceCatfile ? pwszBaseName : NULL, 0)) { CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
return(ERROR_SUCCESS); }
return(GetLastError()); }
HRESULT _DelCatalogFromDatabase(WCHAR *pwszFileIn) { HCATINFO hCatInfo; WCHAR *pwszBaseName;
typedef BOOL (WINAPI * PCRYPTCATADMINREMOVECATALOG)(HCATADMIN, WCHAR *, DWORD);
HRESULT hr = S_OK; HMODULE hDLL = NULL; PCRYPTCATADMINREMOVECATALOG pCryptCATAdminRemoveCatalog = NULL;
if (!(hCatAdmin)) { if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0))) { return(GetLastError()); } }
//
// set the base file name
//
if (!(pwszBaseName = wcsrchr(pwszFileIn, L'\\'))) { pwszBaseName = wcsrchr(pwszFileIn, L':'); }
if (pwszBaseName) { *pwszBaseName++; } else { pwszBaseName = pwszFileIn; }
if (hDLL = LoadLibraryA("wintrust.dll")) { if (pCryptCATAdminRemoveCatalog = (PCRYPTCATADMINREMOVECATALOG) GetProcAddress(hDLL, "CryptCATAdminRemoveCatalog")) { if (!pCryptCATAdminRemoveCatalog(hCatAdmin, pwszBaseName, 0)) { hr = GetLastError(); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
FreeLibrary(hDLL); } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return(hr); }
void _ToLower(WCHAR *pwszInOut) { while (*pwszInOut) { *pwszInOut = towlower(*pwszInOut); pwszInOut++; } }
|