#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
BOOL CheckFileTrust(LPCTSTR filename, CString &signer_file) { HCATADMIN cat_admin_handle = NULL; if (!CryptCATAdminAcquireContext(&cat_admin_handle, NULL, 0)) { return FALSE; }
HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) { CryptCATAdminReleaseContext(cat_admin_handle, 0); return FALSE; }
DWORD hash_count = 100; BYTE hash_data[100]; CryptCATAdminCalcHashFromFileHandle(hFile, &hash_count, hash_data, 0); CloseHandle(hFile);
LPWSTR member_tag = new WCHAR[hash_count * 2 + 1]; for (DWORD dw = 0; dw < hash_count; ++dw) { wsprintfW(&member_tag[dw * 2], L"%02X", hash_data[dw]); }
WINTRUST_DATA wd = { 0 }; WINTRUST_FILE_INFO wfi = { 0 }; WINTRUST_CATALOG_INFO wci = { 0 }; CATALOG_INFO ci = { 0 }; HCATINFO cat_admin_info = CryptCATAdminEnumCatalogFromHash(cat_admin_handle, hash_data, hash_count, 0, NULL); if (NULL == cat_admin_info) { wfi.cbStruct = sizeof(WINTRUST_FILE_INFO); wfi.pcwszFilePath = filename; 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; signer_file = filename; } else { CryptCATCatalogInfoFromContext(cat_admin_info, &ci, 0); wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO); wci.pcwszCatalogFilePath = ci.wszCatalogFile; wci.pcwszMemberFilePath = filename; wci.pcwszMemberTag = member_tag; wci.pbCalculatedFileHash = hash_data; wci.cbCalculatedFileHash = hash_count;
wd.cbStruct = sizeof(WINTRUST_DATA); wd.dwUnionChoice = WTD_CHOICE_CATALOG; wd.pCatalog = &wci; wd.dwUIChoice = WTD_UI_NONE; wd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; wd.dwProvFlags = 0; wd.hWVTStateData = NULL; wd.pwszURLReference = NULL; signer_file = ci.wszCatalogFile; } GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2; HRESULT hr = WinVerifyTrust(NULL, &action, &wd); BOOL retval = SUCCEEDED(hr);
if (NULL != cat_admin_info) { CryptCATAdminReleaseCatalogContext(cat_admin_handle, cat_admin_info, 0); } CryptCATAdminReleaseContext(cat_admin_handle, 0); delete[] member_tag; return retval; }
BOOL GetCertificateInfo(PCCERT_CONTEXT cert_context, CString &signer_name) { LPTSTR name = NULL; DWORD data;
if (!(data = CertGetNameString(cert_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0))) { return FALSE; }
name = (LPTSTR)LocalAlloc(LPTR, data * sizeof(TCHAR)); if (!name) { return FALSE; }
if (!(CertGetNameString(cert_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, name, data))) {
LocalFree(name); return FALSE; } signer_name = name; LocalFree(name); return TRUE; }
BOOL GetFileSigner(LPCTSTR szFileName, CString &signer_name) { HCERTSTORE store_handle = NULL; HCRYPTMSG msg_handle = NULL; PCCERT_CONTEXT cert_context = NULL; BOOL retval = FALSE; DWORD encoding, content_type, format_type; PCMSG_SIGNER_INFO signer_info = NULL; DWORD signer_info_size; CERT_INFO cert_info; do { retval = CryptQueryObject(CERT_QUERY_OBJECT_FILE, szFileName, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, &encoding, &content_type, &format_type, &store_handle, &msg_handle, NULL); if (!retval) { break; }
retval = CryptMsgGetParam(msg_handle, CMSG_SIGNER_INFO_PARAM, 0, NULL, &signer_info_size); if (!retval) { break; }
signer_info = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signer_info_size); if (!signer_info) { break; }
retval = CryptMsgGetParam(msg_handle, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)signer_info, &signer_info_size); if (!retval) { break; }
cert_info.Issuer = signer_info->Issuer; cert_info.SerialNumber = signer_info->SerialNumber;
cert_context = CertFindCertificateInStore(store_handle, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&cert_info, NULL); if (!cert_context) { break; }
retval = GetCertificateInfo(cert_context, signer_name);
} while (0);
if (signer_info != NULL) { LocalFree(signer_info); } if (cert_context != NULL) { CertFreeCertificateContext(cert_context); } if (store_handle != NULL) { CertCloseStore(store_handle, 0); } if (msg_handle != NULL) { CryptMsgClose(msg_handle); }
return retval; }
|