獲取windows下執行文件簽名和證書信息
阿新 • • 發佈:2018-11-13
free result incr int efault clu rsa temp argv 獲取證書信息
驗證文件數字簽名是否有效可以使用函數 WinVerifyTrust,
可以用:
取得文件數字簽名證書信息需要使用函數 CryptQueryObject,再用CertFindCertificateInStore獲取證書Cert
也可以通過,WTHelperProvDataFromStateData WTHelperGetProvSignerFromChain WTHelperGetProvCertFromChain獲取證書Cert
這裏算法是:
驗證文件數字簽名是否有效可以使用函數 WinVerifyTrust,
可以用:
取得文件數字簽名證書信息需要使用函數 CryptQueryObject,再用CertFindCertificateInStore獲取證書Cert
也可以通過,WTHelperProvDataFromStateData WTHelperGetProvSignerFromChain WTHelperGetProvCertFromChain獲取證書Cert
這裏算法是:
typedef struct _CERT_INFO { DWORD dwVersion; CRYPT_INTEGER_BLOB SerialNumber; CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; CERT_NAME_BLOB Issuer; FILETIME NotBefore; FILETIME NotAfter; CERT_NAME_BLOB Subject; CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; CRYPT_BIT_BLOB IssuerUniqueId; CRYPT_BIT_BLOB SubjectUniqueId; DWORD cExtension; PCERT_EXTENSION rgExtension; } CERT_INFO, *PCERT_INFO;
CERT_INFO結構體中SignatureAlgorithm字段 同時這個字段也是一個結構體
typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
LPSTR pszObjId;
CRYPT_OBJID_BLOB Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;
CRYPT_ALGORITHM_IDENTIFIER第一個字段就是對應算法,但是值是一個字符串 要通過宏查看 得自己轉換
宏有:
#define szOID_RSA "1.2.840.113549" #define szOID_PKCS "1.2.840.113549.1" #define szOID_RSA_HASH "1.2.840.113549.2" #define szOID_RSA_ENCRYPT "1.2.840.113549.3" #define szOID_PKCS_1 "1.2.840.113549.1.1" #define szOID_PKCS_2 "1.2.840.113549.1.2" #define szOID_PKCS_3 "1.2.840.113549.1.3" #define szOID_PKCS_4 "1.2.840.113549.1.4" #define szOID_PKCS_5 "1.2.840.113549.1.5" #define szOID_PKCS_6 "1.2.840.113549.1.6" #define szOID_PKCS_7 "1.2.840.113549.1.7" #define szOID_PKCS_8 "1.2.840.113549.1.8" #define szOID_PKCS_9 "1.2.840.113549.1.9" #define szOID_PKCS_10 "1.2.840.113549.1.10" #define szOID_PKCS_12 "1.2.840.113549.1.12" #define szOID_RSA_RSA "1.2.840.113549.1.1.1" #define szOID_RSA_MD2RSA "1.2.840.113549.1.1.2" #define szOID_RSA_MD4RSA "1.2.840.113549.1.1.3" #define szOID_RSA_MD5RSA "1.2.840.113549.1.1.4" #define szOID_RSA_SHA1RSA "1.2.840.113549.1.1.5" #define szOID_RSA_SETOAEP_RSA "1.2.840.113549.1.1.6" #define szOID_RSAES_OAEP "1.2.840.113549.1.1.7" #define szOID_RSA_MGF1 "1.2.840.113549.1.1.8" #define szOID_RSA_PSPECIFIED "1.2.840.113549.1.1.9" #define szOID_RSA_SSA_PSS "1.2.840.113549.1.1.10" #define szOID_RSA_SHA256RSA "1.2.840.113549.1.1.11" #define szOID_RSA_SHA384RSA "1.2.840.113549.1.1.12" #define szOID_RSA_SHA512RSA "1.2.840.113549.1.1.13" #define szOID_RSA_DH "1.2.840.113549.1.3.1" #define szOID_RSA_data "1.2.840.113549.1.7.1" #define szOID_RSA_signedData "1.2.840.113549.1.7.2" #define szOID_RSA_envelopedData "1.2.840.113549.1.7.3" #define szOID_RSA_signEnvData "1.2.840.113549.1.7.4" #define szOID_RSA_digestedData "1.2.840.113549.1.7.5" #define szOID_RSA_hashedData "1.2.840.113549.1.7.5" #define szOID_RSA_encryptedData "1.2.840.113549.1.7.6" #define szOID_RSA_emailAddr "1.2.840.113549.1.9.1" #define szOID_RSA_unstructName "1.2.840.113549.1.9.2" #define szOID_RSA_contentType "1.2.840.113549.1.9.3" #define szOID_RSA_messageDigest "1.2.840.113549.1.9.4" #define szOID_RSA_signingTime "1.2.840.113549.1.9.5" #define szOID_RSA_counterSign "1.2.840.113549.1.9.6" #define szOID_RSA_challengePwd "1.2.840.113549.1.9.7" #define szOID_RSA_unstructAddr "1.2.840.113549.1.9.8" #define szOID_RSA_extCertAttrs "1.2.840.113549.1.9.9" #define szOID_RSA_certExtensions "1.2.840.113549.1.9.14" #define szOID_RSA_SMIMECapabilities "1.2.840.113549.1.9.15" #define szOID_RSA_preferSignedData "1.2.840.113549.1.9.15.1" #define szOID_TIMESTAMP_TOKEN "1.2.840.113549.1.9.16.1.4" #define szOID_RFC3161_counterSign "1.3.6.1.4.1.311.3.3.1" #define szOID_RSA_SMIMEalg "1.2.840.113549.1.9.16.3" #define szOID_RSA_SMIMEalgESDH "1.2.840.113549.1.9.16.3.5" #define szOID_RSA_SMIMEalgCMS3DESwrap "1.2.840.113549.1.9.16.3.6" #define szOID_RSA_SMIMEalgCMSRC2wrap "1.2.840.113549.1.9.16.3.7" #define szOID_RSA_MD2 "1.2.840.113549.2.2" #define szOID_RSA_MD4 "1.2.840.113549.2.4" #define szOID_RSA_MD5 "1.2.840.113549.2.5" #define szOID_RSA_RC2CBC "1.2.840.113549.3.2" #define szOID_RSA_RC4 "1.2.840.113549.3.4" #define szOID_RSA_DES_EDE3_CBC "1.2.840.113549.3.7" #define szOID_RSA_RC5_CBCPad "1.2.840.113549.3.9" #define szOID_ANSI_X942 "1.2.840.10046" #define szOID_ANSI_X942_DH "1.2.840.10046.2.1" #define szOID_X957 "1.2.840.10040" #define szOID_X957_DSA "1.2.840.10040.4.1" #define szOID_X957_SHA1DSA "1.2.840.10040.4.3" // iso(1) member-body(2) us(840) 10045 keyType(2) unrestricted(1) #define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1" // iso(1) member-body(2) us(840) 10045 curves(3) prime(1) 7 #define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7" // iso(1) identified-organization(3) certicom(132) curve(0) 34 #define szOID_ECC_CURVE_P384 "1.3.132.0.34" // iso(1) identified-organization(3) certicom(132) curve(0) 35 #define szOID_ECC_CURVE_P521 "1.3.132.0.35" // iso(1) member-body(2) us(840) 10045 signatures(4) sha1(1) #define szOID_ECDSA_SHA1 "1.2.840.10045.4.1" // iso(1) member-body(2) us(840) 10045 signatures(4) specified(3) #define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3" // iso(1) member-body(2) us(840) 10045 signatures(4) specified(3) 2 #define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2" // iso(1) member-body(2) us(840) 10045 signatures(4) specified(3) 3 #define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3" // iso(1) member-body(2) us(840) 10045 signatures(4) specified(3) 4 #define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4" // NIST AES CBC Algorithms // joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aesAlgs(1) } #define szOID_NIST_AES128_CBC "2.16.840.1.101.3.4.1.2" #define szOID_NIST_AES192_CBC "2.16.840.1.101.3.4.1.22" #define szOID_NIST_AES256_CBC "2.16.840.1.101.3.4.1.42" // For the above Algorithms, the AlgorithmIdentifier parameters must be // present and the parameters field MUST contain an AES-IV: // // AES-IV ::= OCTET STRING (SIZE(16)) // NIST AES WRAP Algorithms #define szOID_NIST_AES128_WRAP "2.16.840.1.101.3.4.1.5" #define szOID_NIST_AES192_WRAP "2.16.840.1.101.3.4.1.25" #define szOID_NIST_AES256_WRAP "2.16.840.1.101.3.4.1.45"
代碼1
#include <windows.h> #include <wincrypt.h> #include <wintrust.h> #include <stdio.h> #include <tchar.h> #pragma comment(lib, "crypt32.lib") #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING) typedef struct { LPWSTR lpszProgramName; LPWSTR lpszPublisherLink; LPWSTR lpszMoreInfoLink; } SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO; BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_PUBLISHERINFO Info); BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st); BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext); BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo); wchar_t * char2wchar(const char* cchar) { wchar_t *m_wchar; int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0); m_wchar = new wchar_t[len + 1]; MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len); m_wchar[len] = ‘\0‘; return m_wchar; } int main(int argc, TCHAR *argv[]) { WCHAR szFileName[MAX_PATH]; HCERTSTORE hStore = NULL; HCRYPTMSG hMsg = NULL; PCCERT_CONTEXT pCertContext = NULL; BOOL fResult; DWORD dwEncoding, dwContentType, dwFormatType; PCMSG_SIGNER_INFO pSignerInfo = NULL; PCMSG_SIGNER_INFO pCounterSignerInfo = NULL; DWORD dwSignerInfo; CERT_INFO CertInfo; SPROG_PUBLISHERINFO ProgPubInfo; SYSTEMTIME st; ZeroMemory(&ProgPubInfo, sizeof(ProgPubInfo)); __try { //if (argc != 2) //{ // _tprintf(_T("Usage: SignedFileInfo <filename>\n")); // return 0; //} #ifdef UNICODE lstrcpynW(szFileName, argv[1], MAX_PATH); #else //if (mbstowcs(szFileName, argv[1], MAX_PATH) == -1) //{ // printf("Unable to convert to unicode.\n"); // __leave; //} #endif // Get message handle and store handle from the signed file. fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE, char2wchar("D:\\Users\\lhl.liu\\Documents\\shunwang\\SWtool1\\test\\WeChat.exe"), CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL); if (!fResult) { _tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError()); __leave; } // Get signer information size. fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); if (!fResult) { _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError()); __leave; } // Allocate memory for signer information. pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); if (!pSignerInfo) { _tprintf(_T("Unable to allocate memory for Signer Info.\n")); __leave; } // Get Signer Information. fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); if (!fResult) { _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError()); __leave; } // Get program name and publisher information from // signer info structure. if (GetProgAndPublisherInfo(pSignerInfo, &ProgPubInfo)) { if (ProgPubInfo.lpszProgramName != NULL) { wprintf(L"Program Name : %s\n", ProgPubInfo.lpszProgramName); } if (ProgPubInfo.lpszPublisherLink != NULL) { wprintf(L"Publisher Link : %s\n", ProgPubInfo.lpszPublisherLink); } if (ProgPubInfo.lpszMoreInfoLink != NULL) { wprintf(L"MoreInfo Link : %s\n", ProgPubInfo.lpszMoreInfoLink); } } _tprintf(_T("\n")); // Search for the signer certificate in the temporary // certificate store. CertInfo.Issuer = pSignerInfo->Issuer; CertInfo.SerialNumber = pSignerInfo->SerialNumber; pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); if (!pCertContext) { _tprintf(_T("CertFindCertificateInStore failed with %x\n"), GetLastError()); __leave; } // Print Signer certificate information. _tprintf(_T("Signer Certificate:\n\n")); PrintCertificateInfo(pCertContext); _tprintf(_T("\n")); // Get the timestamp certificate signerinfo structure. if (GetTimeStampSignerInfo(pSignerInfo, &pCounterSignerInfo)) { // Search for Timestamp certificate in the temporary // certificate store. CertInfo.Issuer = pCounterSignerInfo->Issuer; CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber; pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); if (!pCertContext) { _tprintf(_T("CertFindCertificateInStore failed with %x\n"), GetLastError()); __leave; } // Print timestamp certificate information. _tprintf(_T("TimeStamp Certificate:\n\n")); PrintCertificateInfo(pCertContext); _tprintf(_T("\n")); // Find Date of timestamp. if (GetDateOfTimeStamp(pCounterSignerInfo, &st)) { _tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"), st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute); } _tprintf(_T("\n")); } } __finally { // Clean up. if (ProgPubInfo.lpszProgramName != NULL) LocalFree(ProgPubInfo.lpszProgramName); if (ProgPubInfo.lpszPublisherLink != NULL) LocalFree(ProgPubInfo.lpszPublisherLink); if (ProgPubInfo.lpszMoreInfoLink != NULL) LocalFree(ProgPubInfo.lpszMoreInfoLink); if (pSignerInfo != NULL) LocalFree(pSignerInfo); if (pCounterSignerInfo != NULL) LocalFree(pCounterSignerInfo); if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); if (hStore != NULL) CertCloseStore(hStore, 0); if (hMsg != NULL) CryptMsgClose(hMsg); } getchar(); return 0; } BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext) { BOOL fReturn = FALSE; LPTSTR szName = NULL; DWORD dwData; __try { // Print Serial Number. _tprintf(_T("Serial Number: ")); dwData = pCertContext->pCertInfo->SerialNumber.cbData; for (DWORD n = 0; n < dwData; n++) { _tprintf(_T("%02x "), pCertContext->pCertInfo->SerialNumber.pbData[dwData - (n + 1)]); } _tprintf(_T("\n")); // Get Issuer name size. if (!(dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Allocate memory for Issuer name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { _tprintf(_T("Unable to allocate memory for issuer name.\n")); __leave; } // Get Issuer name. if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, szName, dwData))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // print Issuer name. _tprintf(_T("Issuer Name: %s\n"), szName); LocalFree(szName); szName = NULL; // Get Subject name size. if (!(dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Allocate memory for subject name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { _tprintf(_T("Unable to allocate memory for subject name.\n")); __leave; } // Get subject name. if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Print Subject Name. _tprintf(_T("Subject Name: %s\n"), szName); fReturn = TRUE; } __finally { if (szName != NULL) LocalFree(szName); } return fReturn; } LPWSTR AllocateAndCopyWideString(LPCWSTR inputString) { LPWSTR outputString = NULL; outputString = (LPWSTR)LocalAlloc(LPTR, (wcslen(inputString) + 1) * sizeof(WCHAR)); if (outputString != NULL) { lstrcpyW(outputString, inputString); } return outputString; } BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_PUBLISHERINFO Info) { BOOL fReturn = FALSE; PSPC_SP_OPUS_INFO OpusInfo = NULL; DWORD dwData; BOOL fResult; __try { // Loop through authenticated attributes and find // SPC_SP_OPUS_INFO_OBJID OID. for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++) { if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0) { // Get Size of SPC_SP_OPUS_INFO structure. fResult = CryptDecodeObject(ENCODING, SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, NULL, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Allocate memory for SPC_SP_OPUS_INFO structure. OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData); if (!OpusInfo) { _tprintf(_T("Unable to allocate memory for Publisher Info.\n")); __leave; } // Decode and get SPC_SP_OPUS_INFO structure. fResult = CryptDecodeObject(ENCODING, SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, OpusInfo, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Fill in Program Name if present. if (OpusInfo->pwszProgramName) { Info->lpszProgramName = AllocateAndCopyWideString(OpusInfo->pwszProgramName); } else Info->lpszProgramName = NULL; // Fill in Publisher Information if present. if (OpusInfo->pPublisherInfo) { switch (OpusInfo->pPublisherInfo->dwLinkChoice) { case SPC_URL_LINK_CHOICE: Info->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl); break; case SPC_FILE_LINK_CHOICE: Info->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile); break; default: Info->lpszPublisherLink = NULL; break; } } else { Info->lpszPublisherLink = NULL; } // Fill in More Info if present. if (OpusInfo->pMoreInfo) { switch (OpusInfo->pMoreInfo->dwLinkChoice) { case SPC_URL_LINK_CHOICE: Info->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl); break; case SPC_FILE_LINK_CHOICE: Info->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile); break; default: Info->lpszMoreInfoLink = NULL; break; } } else { Info->lpszMoreInfoLink = NULL; } fReturn = TRUE; break; // Break from for loop. } // lstrcmp SPC_SP_OPUS_INFO_OBJID } // for } __finally { if (OpusInfo != NULL) LocalFree(OpusInfo); } return fReturn; } BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st) { BOOL fResult; FILETIME lft, ft; DWORD dwData; BOOL fReturn = FALSE; // Loop through authenticated attributes and find // szOID_RSA_signingTime OID. for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++) { if (lstrcmpA(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0) { // Decode and get FILETIME structure. dwData = sizeof(ft); fResult = CryptDecodeObject(ENCODING, szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, 0, (PVOID)&ft, &dwData); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); break; } // Convert to local time. FileTimeToLocalFileTime(&ft, &lft); FileTimeToSystemTime(&lft, st); fReturn = TRUE; break; // Break from for loop. } //lstrcmp szOID_RSA_signingTime } // for return fReturn; } BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo) { PCCERT_CONTEXT pCertContext = NULL; BOOL fReturn = FALSE; BOOL fResult; DWORD dwSize; __try { *pCounterSignerInfo = NULL; // Loop through unathenticated attributes for // szOID_RSA_counterSign OID. for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++) { if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId, szOID_RSA_counterSign) == 0) { // Get size of CMSG_SIGNER_INFO structure. fResult = CryptDecodeObject(ENCODING, PKCS7_SIGNER_INFO, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData, 0, NULL, &dwSize); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } // Allocate memory for CMSG_SIGNER_INFO. *pCounterSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize); if (!*pCounterSignerInfo) { _tprintf(_T("Unable to allocate memory for timestamp info.\n")); __leave; } // Decode and get CMSG_SIGNER_INFO structure // for timestamp certificate. fResult = CryptDecodeObject(ENCODING, PKCS7_SIGNER_INFO, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData, pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData, 0, (PVOID)*pCounterSignerInfo, &dwSize); if (!fResult) { _tprintf(_T("CryptDecodeObject failed with %x\n"), GetLastError()); __leave; } fReturn = TRUE; break; // Break from for loop. } } } __finally { // Clean up. if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); } return fReturn; }
獲取windows下執行文件簽名和證書信息