3

I have searched for a way to retrieve information from a digital signed PE file. I need the publisher, publisher link , issuer name and subject name. I need winapi / c / c++ code (functions) and i need a fast method , i don't need to check if the signature is valid or not.

2
  • 3
    If you're talking about 'Authenticode', Microsoft explains this here: support.microsoft.com/kb/323809 Commented Feb 22, 2013 at 18:00
  • 1
    ok I added a corresponding answer so you can mark it as answer if it's ok for you Commented Feb 27, 2013 at 12:41

2 Answers 2

9

Here is code that I wrote for a project of mine that will do this. It returns the details in a struct of type NSIGINFO. Feel free to use it - no attribution necessary, but I would appreciate it if you would leave the copyright intact.

If there's any functions missing (I had to consolidate things from a couple of different places so I may have missed something) please let me know and I'll make the necessary tweaks.

Let me know how this works for you. Good luck.

The header file, NAuthenticode.h:

// NAuthenticode.h: Functions for checking signatures in files
//
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <[email protected]>

#ifndef B82FBB5B_C0F8_43A5_9A31_619BB690706C
#define B82FBB5B_C0F8_43A5_9A31_619BB690706C

#include <wintrust.h>
#include <softpub.h>
#include <imagehlp.h>

struct NSIGINFO
{
    LONG lValidationResult;

    LPTSTR lpszPublisher;
    LPTSTR lpszPublisherEmail;
    LPTSTR lpszPublisherUrl;
    LPTSTR lpszAuthority;
    LPTSTR lpszFriendlyName;
    LPTSTR lpszProgramName;
    LPTSTR lpszPublisherLink;
    LPTSTR lpszMoreInfoLink;
    LPTSTR lpszSignature;
    LPTSTR lpszSerial;
    BOOL bHasSigTime;
    SYSTEMTIME stSigTime;
};

VOID NCertFreeSigInfo(NSIGINFO *pSigInfo);

BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle = INVALID_HANDLE_VALUE);

BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType,
    DWORD dwFlags, LPTSTR *lpszNameString);

BOOL NCheckFileCertificates(HANDLE hFile, 
    VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam);

#endif

The implementation, NAuthenticode.cpp:

// NAuthenticode.cpp: Various routines related to validating file signatures
//
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <[email protected]>


#include "stdafx.h"
#include "NAuthenticode.h"

//////////////////////////////////////////////////////////////////////////
#pragma comment(lib, "crypt32")
#pragma comment(lib, "imagehlp")
#pragma comment(lib, "wintrust")

//////////////////////////////////////////////////////////////////////////
#define SIG_ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)

//////////////////////////////////////////////////////////////////////////
// Some utility functions
LPVOID NHeapAlloc(SIZE_T dwBytes)
{
    if(dwBytes == 0)
        return NULL;

    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes);
}

//////////////////////////////////////////////////////////////////////////
LPVOID NHeapFree(LPVOID lpMem)
{
    if(lpMem != NULL)
        HeapFree(GetProcessHeap(), 0, lpMem);

    return NULL;
}

//////////////////////////////////////////////////////////////////////////
LPSTR NConvertW2A(LPCWSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

    int ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, NULL, 0, NULL, NULL);

    if(ret <= 0)
        return NULL;

    LPSTR lpszOutString = (LPSTR)NHeapAlloc((ret + 1) * sizeof(CHAR));

    if(lpszOutString == NULL)
        return NULL;

    ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, lpszOutString, ret, NULL, NULL);

    if(ret <= 0)
        lpszOutString = (LPSTR)NHeapFree(lpszOutString);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NDupString(LPCWSTR lpszString, int nLen)
{
    if(nLen == -1)
        nLen = (int)wcslen(lpszString);

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((2 + nLen) * sizeof(WCHAR));

    if((lpszOutString != NULL) && (nLen != 0))
        wcsncpy(lpszOutString, lpszString, nLen + 1);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPTSTR NConvertW2T(LPCWSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

#ifndef UNICODE
    return (LPTSTR)NConvertW2A(lpszString, nLen, nCodePage);
#else
    return (LPTSTR)NDupString(lpszString, nLen);
#endif
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NConvertA2W(LPCSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

    int ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, NULL, 0);

    if(ret <= 0)  
        return NULL;

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((ret + 1) * sizeof(WCHAR));

    if(lpszOutString == NULL)
        return NULL;

    ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, lpszOutString, ret);

    if(ret <= 0)
        lpszOutString = (LPWSTR)NHeapFree(lpszOutString);

    return lpszOutString;
}

//////////////////////////////////////////////////////////////////////////
LPWSTR NConvertT2W(LPCTSTR lpszString, int nLen, UINT nCodePage)
{
    ASSERT(lpszString != NULL);

#ifndef UNICODE
    return NConvertA2W((LPCSTR)lpszString, nLen, nCodePage);
#else
    return NDupString((LPWSTR)lpszString, nLen);
#endif
}

//////////////////////////////////////////////////////////////////////////
VOID NCertFreeSigInfo(NSIGINFO *pSigInfo)
{
    if(pSigInfo == NULL)
        return;

    __try
    { // Be extra careful
        if(pSigInfo->lpszPublisher)
            pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszPublisherEmail)
            pSigInfo->lpszPublisherEmail = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherEmail);

        if(pSigInfo->lpszPublisherUrl)
            pSigInfo->lpszPublisherUrl = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherUrl);

        if(pSigInfo->lpszAuthority)
            pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority);

        if(pSigInfo->lpszProgramName)
            pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszPublisherLink)
            pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

        if(pSigInfo->lpszMoreInfoLink)
            pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink);

        if(pSigInfo->lpszSignature)
            pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature);

        if(pSigInfo->lpszSerial)
            pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    }
}

//////////////////////////////////////////////////////////////////////////
static BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, LPTSTR *lpszNameString)
{
    if(pCertContext == NULL)
        return FALSE;

    DWORD dwData = CertGetNameString(pCertContext, dwType, 0, NULL, NULL, 0);

    if(dwData == 0)
        return FALSE;

    *lpszNameString = (LPTSTR)NHeapAlloc((dwData + 1) * sizeof(TCHAR));

    if(*lpszNameString == NULL)
        return FALSE;

    dwData = CertGetNameString(pCertContext, dwType, dwFlags, NULL, *lpszNameString, dwData);

    if(dwData == 0)
    {
        NHeapFree(*lpszNameString);
        return FALSE;
    }

    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in_bcount(cbEncoded) const BYTE *pbEncoded, __in DWORD cbEncoded,
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0)
{   
    if(((pBuffer == NULL) && (dwBuffer != 0)) || ((dwBuffer == 0) && (pBuffer != NULL)))
    { // What? You're passing a NULL pointer an a non-zero size? You so crazy!!!!
        ASSERT(FALSE);
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pbEncoded, cbEncoded, dwFlags, pBuffer, &dwBuffer);
}   

//////////////////////////////////////////////////////////////////////////
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in PCRYPT_ATTR_BLOB pObject,
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0)
{   
    if((pObject == NULL) || ((dwBuffer == 0) && (pBuffer != NULL)) || ((dwBuffer != 0) && (pBuffer == NULL)))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }   

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pObject->pbData, pObject->cbData, dwFlags, pBuffer, &dwBuffer);
}   

//////////////////////////////////////////////////////////////////////////
static BOOL WGetSignTimestamp(PCRYPT_ATTRIBUTES pAttributes, SYSTEMTIME &stTime, LPCSTR lpszObjId)
{
    if((pAttributes == NULL) || (pAttributes->cAttr == 0) || (lpszObjId == NULL) || (*lpszObjId == 0))
        return FALSE;

    for(DWORD dwAttr = 0; dwAttr < pAttributes->cAttr; dwAttr++)
    {           
        if(strcmp(lpszObjId, pAttributes->rgAttr[dwAttr].pszObjId) == 0)
        {               
            DWORD dwSize = sizeof(FILETIME);
            FILETIME ftCert;

            if(NCryptDecodeObject(lpszObjId, &pAttributes->rgAttr[dwAttr].rgValue[0], dwSize, (PVOID)&ftCert))
            {
                FILETIME ftLocal;

                if(FileTimeToLocalFileTime(&ftCert, &ftLocal) && FileTimeToSystemTime(&ftLocal, &stTime))
                    return TRUE;
            }
        }
    }

    return FALSE;
}

//////////////////////////////////////////////////////////////////////////
static BOOL NVerifyFileSignatureWorker(LPWSTR lpszFileName, WINTRUST_DATA &wtData, NSIGINFO *pSigInfo)
{
    if(pSigInfo != NULL)
        memset(pSigInfo, 0, sizeof(NSIGINFO));

    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;    
    BOOL bVerified = FALSE;

    LONG lRet = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &wtData);

    if(lRet != 0)
    {
        if(pSigInfo != NULL)
            pSigInfo->lValidationResult = lRet;

        return FALSE;
    }

    if(pSigInfo == NULL)
        return TRUE;

    HCERTSTORE hStore = NULL;
    HCRYPTMSG hMsg = NULL;

    if(!CryptQueryObject(CERT_QUERY_OBJECT_FILE, lpszFileName, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, &hStore, &hMsg, NULL))
        return FALSE;

    PCMSG_SIGNER_INFO pSignerInfo = NULL, pCounterSignerInfo = NULL;
    DWORD dwSignerInfo = 0, dwCounterSignerInfo = 0;

    if(CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo) && (dwSignerInfo != 0))
        pSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwSignerInfo);

    if((pSignerInfo != NULL) && CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo))
    {   
        for(DWORD dwAttr = 0; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++)
        {   
            if((strcmp(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) != 0))
                continue;

            PSPC_SP_OPUS_INFO pOpus = NULL;
            DWORD dwData = 0;

            if(NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData) && (dwData != 0))
                pOpus = (PSPC_SP_OPUS_INFO)NHeapAlloc(dwData);

            if((pOpus != NULL) && NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)pOpus))
            {     
                pSigInfo->lpszProgramName = NConvertW2T(pOpus->pwszProgramName);

                if(pOpus->pPublisherInfo != NULL)
                {
                    switch(pOpus->pPublisherInfo->dwLinkChoice)
                    {
                    case SPC_URL_LINK_CHOICE:
                        pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszUrl);
                        break;

                    case SPC_FILE_LINK_CHOICE:
                        pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszFile);
                        break;
                    }
                }

                if(pOpus->pMoreInfo != NULL)
                {
                    switch (pOpus->pMoreInfo->dwLinkChoice)
                    {
                    case SPC_URL_LINK_CHOICE:
                        pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszUrl);
                        break;

                    case SPC_FILE_LINK_CHOICE:
                        pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszFile);
                        break;
                    }
                }                                       
            }    

            if(pOpus != NULL)
                NHeapFree(pOpus);

            break;
        }

        CERT_INFO ci; 

        ci.Issuer = pSignerInfo->Issuer;
        ci.SerialNumber = pSignerInfo->SerialNumber;

        PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore, SIG_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&ci, NULL);

        if(pCertContext != NULL)
        {      
            if(pCertContext->pCertInfo->SerialNumber.cbData != 0)
            {
                pSigInfo->lpszSerial = (LPTSTR)NHeapAlloc(((pCertContext->pCertInfo->SerialNumber.cbData * 2) + 1) * sizeof(TCHAR));

                if(pSigInfo->lpszSerial != NULL)
                {
                    LPTSTR lpszPointer = pSigInfo->lpszSerial;

                    for(DWORD dwCount = pCertContext->pCertInfo->SerialNumber.cbData; dwCount != 0; dwCount--)
                        lpszPointer += _stprintf(lpszPointer, _T("%02X"), pCertContext->pCertInfo->SerialNumber.pbData[dwCount - 1]);
                }
            }

            if(!NCertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszFriendlyName))
                pSigInfo->lpszFriendlyName = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszAuthority))
                pSigInfo->lpszAuthority = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, &pSigInfo->lpszPublisher))
                pSigInfo->lpszPublisher = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_URL_TYPE, 0, &pSigInfo->lpszPublisherUrl))
                pSigInfo->lpszPublisherUrl = NULL;

            if(!NCertGetNameString(pCertContext, CERT_NAME_EMAIL_TYPE, 0, &pSigInfo->lpszPublisherEmail))
                pSigInfo->lpszPublisherEmail = NULL;

            CertFreeCertificateContext(pCertContext);
        }

        for(DWORD dwAttr = 0, dwData; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++)
        {           
            if((strcmp(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) == 0) && (pSignerInfo->AuthAttrs.rgAttr[dwAttr].cValue != 0))
            {   
                FILETIME ftCert;

                dwData = sizeof(FILETIME);

                if(NCryptDecodeObject(szOID_RSA_signingTime, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)&ftCert))
                {
                    FILETIME ftLocal;

                    if(!FileTimeToLocalFileTime(&ftCert, &ftLocal))
                    {
                        if(!FileTimeToSystemTime(&ftLocal, &pSigInfo->stSigTime))
                            memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME));
                    }                   
                }
            }           
        } 

        for(DWORD dwAttr = 0; dwAttr < pSignerInfo->UnauthAttrs.cAttr; dwAttr++)
        {
            if(strcmp(pSignerInfo->UnauthAttrs.rgAttr[dwAttr].pszObjId, szOID_RSA_counterSign) == 0)
            {
                if(NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo) && (dwCounterSignerInfo != 0))
                    pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwCounterSignerInfo);

                if((pCounterSignerInfo != NULL) && !NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo, pCounterSignerInfo))
                    pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapFree(pCounterSignerInfo);

                break;
            }
        }

        if(pCounterSignerInfo != NULL)
        {
            pSigInfo->bHasSigTime = WGetSignTimestamp(&pCounterSignerInfo->AuthAttrs, pSigInfo->stSigTime, szOID_RSA_signingTime);

            if(!pSigInfo->bHasSigTime)
                memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME));
        }   
    }   

    if(pSignerInfo != NULL)
        NHeapFree(pSignerInfo);

    if(pCounterSignerInfo != NULL)
        NHeapFree(pCounterSignerInfo);

    if(hStore != NULL)
        CertCloseStore(hStore, 0);

    if(hMsg != NULL)
        CryptMsgClose(hMsg);

    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle)
{
    if(pSigInfo != NULL)    
        memset(pSigInfo, 0, sizeof(NSIGINFO));

    if(lpszFileName == NULL)
        return FALSE;

    if((lpszFileName[0] != 0) && (_tcsnicmp(lpszFileName, _T("\\??\\"), 4) == 0))
        lpszFileName += 4;

    if(lpszFileName[0] == 0)
        return FALSE;

    LPWSTR lpwszFileName = NConvertT2W(lpszFileName);

    if(lpwszFileName == NULL)
        return FALSE;

    BOOL bOK = FALSE;

    __try
    { // be very careful... 
        WINTRUST_FILE_INFO wtFileInfo;
        memset(&wtFileInfo, 0, sizeof(WINTRUST_FILE_INFO));

        wtFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
        wtFileInfo.pcwszFilePath = lpwszFileName;

        if(hHandle != INVALID_HANDLE_VALUE)
            wtFileInfo.hFile = hHandle;

        WINTRUST_DATA wtData;
        memset(&wtData, 0, sizeof(WINTRUST_DATA));
        wtData.cbStruct = sizeof(WINTRUST_DATA);
        wtData.dwUIChoice = WTD_UI_NONE;
        wtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
        wtData.dwUnionChoice = WTD_CHOICE_FILE;
        wtData.pFile = &wtFileInfo;

        if(NVerifyFileSignatureWorker(lpwszFileName, wtData, pSigInfo))
            bOK = TRUE;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        if(pSigInfo != NULL)
        {
            if(pSigInfo->lpszPublisher)
                pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszAuthority)
                pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority);

            if(pSigInfo->lpszProgramName)
                pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszPublisherLink)
                pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher);

            if(pSigInfo->lpszMoreInfoLink)
                pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink);

            if(pSigInfo->lpszSignature)
                pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature);

            if(pSigInfo->lpszSerial)
                pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial);
        }

        bOK = FALSE;
    }

    NHeapFree(lpwszFileName);

    return bOK;
}

//////////////////////////////////////////////////////////////////////////
BOOL NCheckFileCertificates(HANDLE hFile, VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam)
{
    DWORD dwCerts = 0;

    if(!ImageEnumerateCertificates(hFile, CERT_SECTION_TYPE_ANY, &dwCerts, NULL, 0))
        return FALSE;

    for(DWORD dwCount = 0; dwCount < dwCerts; dwCount++)
    {
        WIN_CERTIFICATE wcHdr;
        memset(&wcHdr, 0, sizeof(WIN_CERTIFICATE));
        wcHdr.dwLength = 0;
        wcHdr.wRevision = WIN_CERT_REVISION_1_0;

        if(!ImageGetCertificateHeader(hFile, dwCount, &wcHdr))
            return FALSE;

        DWORD dwLen = sizeof(WIN_CERTIFICATE) + wcHdr.dwLength;

        WIN_CERTIFICATE *pWinCert = (WIN_CERTIFICATE *)NHeapAlloc(dwLen);

        if(pWinCert == NULL)
            return FALSE;

        if(!ImageGetCertificateData(hFile, dwCount, pWinCert, &dwLen))
        { // problem getting certificate, return failure
            NHeapFree(pWinCert);
            return FALSE;
        }

        // extract the PKCS7 signed data     
        CRYPT_VERIFY_MESSAGE_PARA cvmp;
        memset(&cvmp, 0, sizeof(CRYPT_VERIFY_MESSAGE_PARA));
        cvmp.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
        cvmp.dwMsgAndCertEncodingType = SIG_ENCODING;

        PCCERT_CONTEXT pCertContext = NULL;

        if(!CryptVerifyMessageSignature(&cvmp, dwCount, pWinCert->bCertificate, pWinCert->dwLength, NULL, NULL, &pCertContext))
        {
            NHeapFree(pWinCert);
            return FALSE;
        }

        // Now, pass this context on to our callback function (if any)
        if(pCallback != NULL)
            pCallback(pCertContext, pParam);

        if(!CertFreeCertificateContext(pCertContext))
        {
            NHeapFree(pWinCert);
            return FALSE;
        }

        NHeapFree(pWinCert);
    }

    return TRUE;
}
Sign up to request clarification or add additional context in comments.

2 Comments

thank for the code , i didn't checked it. i used the code provided by Microsoft
How do you call your function? Can you give an example?
6

Microsoft provides a way to do it in this support link: How To Get Information from Authenticode Signed Executables

You can use the WinVerifyTrust() API to verify an Authenticode signed executable.

Although a signature is verified, a program may also have to do the following:

  • Determine the details of the certificate that signed the executable.
  • Determine the date and time that the file was time stamped.
  • Retrieve the URL link associated with the file.
  • Retrieve the timestamp certificate.

This article demonstrates how to use CryptQueryObject() API to retrieve detailed information from an Authenticode signed executable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.