C++ 验证微软数字签名

来源:互联网 发布:网络优化测试工作 编辑:程序博客网 时间:2024/05/24 22:45
C++ 验证微软数字签名   
BOOL CheckFileTrust(LPCWSTR lpFileName )
{
BOOL bRet =FALSE;
WINTRUST_DATA wd = {0 };
WINTRUST_FILE_INFO wfi = {0 };
WINTRUST_CATALOG_INFO wci = {0 };
CATALOG_INFO ci = {0 };

HCATADMIN hCatAdmin =NULL;
if ( !CryptCATAdminAcquireContext( &hCatAdmin,NULL, 0 ) )
    {
return FALSE;
    }

HANDLE hFile =CreateFileW(lpFileName,GENERIC_READ,FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if ( INVALID_HANDLE_VALUE ==hFile )
    {
CryptCATAdminReleaseContext(hCatAdmin, 0 );
return FALSE;
    }

DWORD dwCnt =100;
BYTE byHash[100];
CryptCATAdminCalcHashFromFileHandle(hFile, &dwCnt,byHash, 0 );
CloseHandle(hFile );

LPWSTR pszMemberTag =new WCHAR[dwCnt* 2 + 1];
for ( DWORD dw = 0; dw< dwCnt; ++dw)
    {
wsprintfW( &pszMemberTag[dw* 2],L"%02X",byHash[dw] );
    }

HCATINFO hCatInfo =CryptCATAdminEnumCatalogFromHash(hCatAdmin,
byHash, dwCnt, 0,NULL );
if ( NULL == hCatInfo)
    {
wfi.cbStruct      = sizeof(WINTRUST_FILE_INFO );
wfi.pcwszFilePath = lpFileName;
wfi.hFile         = NULL;
wfi.pgKnownSubject= NULL;

wd.cbStruct           = sizeof(WINTRUST_DATA );
wd.dwUnionChoice      = WTD_CHOICE_FILE;
wd.pFile              = &wfi;
wd.dwUIChoice         = WTD_UI_NONE;
wd.fdwRevocationChecks= WTD_REVOKE_NONE;
wd.dwStateAction      = WTD_STATEACTION_IGNORE;
wd.dwProvFlags        = WTD_SAFER_FLAG;
wd.hWVTStateData      = NULL;
wd.pwszURLReference   = NULL;
    }
else
{
CryptCATCatalogInfoFromContext(hCatInfo, &ci,0 );
wci.cbStruct            = sizeof(WINTRUST_CATALOG_INFO );
wci.pcwszCatalogFilePath= ci.wszCatalogFile;
wci.pcwszMemberFilePath = lpFileName;
wci.pcwszMemberTag      = pszMemberTag;

wd.cbStruct           = sizeof(WINTRUST_DATA );
wd.dwUnionChoice      = WTD_CHOICE_CATALOG;
wd.pCatalog           = &wci;
wd.dwUIChoice         = WTD_UI_NONE;
wd.fdwRevocationChecks= WTD_STATEACTION_VERIFY;
wd.dwProvFlags        = 0;
wd.hWVTStateData      = NULL;
wd.pwszURLReference   = NULL;
    }
GUID action =WINTRUST_ACTION_GENERIC_VERIFY_V2;
HRESULT hr  =WinVerifyTrust(NULL, &action, &wd);
bRet        =SUCCEEDED( hr );

if ( NULL != hCatInfo)
    {
CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
    }
CryptCATAdminReleaseContext(hCatAdmin, 0 );
delete[] pszMemberTag;
return bRet;
}

这段代码是在一个老外的论坛上不经意搜索到的,一个貌似德国人(因为他的注释不是英文写的,德国亦仅猜测尔,西班牙、葡萄牙、法兰西、俄罗斯亦都有可能)写的Delphi代码,其中使用了WinTrust.dll中的导出函数。使用VS2005的朋友们可以包含WinTrust.h、SoftPub.h和Mscat.h,并添加导入库WinTrust.lib;使用VC6的朋友们可以参考MSDN上的函数及结构体声明,并用函数指针进行调用。

本人补充一下一些类型,方便翻译成别的语言:
typedef struct _WINTRUST_DATA
{ DWORD cbStruct;
LPVOID pPolicyCallbackData;
LPVOID pSIPClientData;
DWORD dwUIChoice;
DWORD fdwRevocationChecks;
DWORD dwUnionChoice;
union {
struct WINTRUST_FILE_INFO_*pFile;
struct WINTRUST_CATALOG_INFO_*pCatalog;
struct WINTRUST_BLOB_INFO_*pBlob;
struct WINTRUST_SGNR_INFO_*pSgnr;
struct WINTRUST_CERT_INFO_*pCert;
  };
DWORD dwStateAction;
HANDLE hWVTStateData;
WCHAR* pwszURLReference;
DWORD dwProvFlags;
DWORD dwUIContext;
}
WINTRUST_DATA,  *PWINTRUST_DATA;

typedef struct WINTRUST_FILE_INFO_
{ DWORD cbStruct;
LPCWSTR pcwszFilePath;
HANDLE hFile;
GUID* pgKnownSubject;
}
WINTRUST_FILE_INFO,  *PWINTRUCT_FILE_INFO;

typedef struct WINTRUST_CATALOG_INFO_
{ DWORD cbStructDWORD dwCatalogVersion;
LPCWSTR pcwszCatalogFilePath;
LPCWSTR pcwszMemberTag;
LPCWSTR pcwszMemberFilePath;
HANDLE hMemberFile;
}
WINTRUST_CATALOG_INFO,  *PWINTRUST_CATALOG_INFO;

typedef struct CATALOG_INFO_
{ DWORD cbStruct;
WCHAR wszCatalogFile[MAX_PATH];
}
CATALOG_INFO;

本人再补充一下用到的API声明:
LONG WINAPI WinVerifyTrust(
__in          HWND hWnd,
__in          GUID*pgActionID,
__in          LPVOID pWVTData
);

Related

原创粉丝点击