found the solution here:
http://www.ucosoft.com/how-to-program-to-retrieve-the-authenticode-information.html
here it is with indentation:
#define _UNICODE 1
#define UNICODE 1
#include <windows.h>
#include <tchar.h>
#include <wincrypt.h>
#include <Softpub.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment (lib, "Crypt32")
// the Authenticode Signature is encode in PKCS7
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
// Information structure of authenticode sign
typedef struct
{
LPWSTR lpszProgramName;
LPWSTR lpszPublisherLink;
LPWSTR lpszMoreInfoLink;
DWORD cbSerialSize;
LPBYTE lpSerialNumber;
LPTSTR lpszIssuerName;
LPTSTR lpszSubjectName;
}
SPROG_SIGNATUREINFO, *PSPROG_SIGNATUREINFO;
VOID GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_SIGNATUREINFO pInfo);
VOID GetCertificateInfo(HCERTSTORE hStore, PCMSG_SIGNER_INFO pSignerInfo, PSPROG_SIGNATUREINFO pInfo);
BOOL GetAuthenticodeInformation(LPCTSTR lpszFileName, PSPROG_SIGNATUREINFO pInfo)
{
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PCMSG_SIGNER_INFO pSignerInfo = NULL;
DWORD dwSignerInfo;
BOOL bRet = FALSE;
__try
{
// as CryptQueryObject() only accept WCHAR file name, convert first
WCHAR wszFileName[MAX_PATH];
#ifdef UNICODE
if ( !lstrcpynW( wszFileName, lpszFileName, MAX_PATH))
__leave;
#else
if ( mbstowcs( wszFileName, lpszFileName, MAX_PATH) == -1)
__leave;
#endif
//Retrieve the Message Handle and Store Handle
DWORD dwEncoding, dwContentType, dwFormatType;
if ( !CryptQueryObject( CERT_QUERY_OBJECT_FILE, wszFileName,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding,
&dwContentType, &dwFormatType, &hStore,
&hMsg, NULL))
__leave;
//Get the length of SignerInfo
if ( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo))
__leave;
// allocate the memory for SignerInfo
if ( !(pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc( LPTR, dwSignerInfo)))
__leave;
// get the SignerInfo
if ( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo))
__leave;
//get the Publisher from SignerInfo
GetProgAndPublisherInfo( pSignerInfo, pInfo);
//get the Certificate from SignerInfo
GetCertificateInfo( hStore, pSignerInfo, pInfo);
bRet = TRUE;
}
__finally
{
// release the memory
if (pSignerInfo != NULL) LocalFree(pSignerInfo);
if (hStore != NULL) CertCloseStore(hStore, 0);
if (hMsg != NULL) CryptMsgClose(hMsg);
}
return bRet;
}
LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
{
LPWSTR outputString = NULL;
// allocate the memory
outputString = (LPWSTR)VirtualAlloc(NULL, (wcslen(inputString) + 1) * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
// copy
if (outputString != NULL)
{
lstrcpyW(outputString, inputString);
}
return outputString;
}
VOID GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_SIGNATUREINFO pInfo)
{
PSPC_SP_OPUS_INFO OpusInfo = NULL;
DWORD dwData;
__try
{
// query SPC_SP_OPUS_INFO_OBJID OID in Authenticated Attributes
for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
{
if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
{
// get the length of SPC_SP_OPUS_INFO
if ( !CryptDecodeObject(ENCODING,
SPC_SP_OPUS_INFO_OBJID,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
0,
NULL,
&dwData))
__leave;
// allocate the memory for SPC_SP_OPUS_INFO
if ( !(OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData)))
__leave;
// get SPC_SP_OPUS_INFO structure
if ( !CryptDecodeObject(ENCODING,
SPC_SP_OPUS_INFO_OBJID,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
0,
OpusInfo,
&dwData))
__leave;
// copy the Program Name of SPC_SP_OPUS_INFO to the return variable
if (OpusInfo->pwszProgramName)
{
pInfo->lpszProgramName = AllocateAndCopyWideString(OpusInfo->pwszProgramName);
}
else
pInfo->lpszProgramName = NULL;
// copy the Publisher Info of SPC_SP_OPUS_INFO to the return variable
if (OpusInfo->pPublisherInfo)
{
switch (OpusInfo->pPublisherInfo->dwLinkChoice)
{
case SPC_URL_LINK_CHOICE:
pInfo->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);
break;
case SPC_FILE_LINK_CHOICE:
pInfo->lpszPublisherLink = AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);
break;
default:
pInfo->lpszPublisherLink = NULL;
break;
}
}
else
{
pInfo->lpszPublisherLink = NULL;
}
// copy the More Info of SPC_SP_OPUS_INFO to the return variable
if (OpusInfo->pMoreInfo)
{
switch (OpusInfo->pMoreInfo->dwLinkChoice)
{
case SPC_URL_LINK_CHOICE:
pInfo->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);
break;
case SPC_FILE_LINK_CHOICE:
pInfo->lpszMoreInfoLink = AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);
break;
default:
pInfo->lpszMoreInfoLink = NULL;
break;
}
}
else
{
pInfo->lpszMoreInfoLink = NULL;
}
break; // we have got the information, break
}
}
}
__finally
{
if (OpusInfo != NULL) LocalFree(OpusInfo);
}
}
VOID GetCertificateInfo(HCERTSTORE hStore, PCMSG_SIGNER_INFO pSignerInfo, PSPROG_SIGNATUREINFO pInfo)
{
PCCERT_CONTEXT pCertContext = NULL;
__try
{
CERT_INFO CertInfo;
DWORD dwData;
// query Signer Certificate in Certificate Store
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
if ( !(pCertContext = CertFindCertificateInStore( hStore,
ENCODING, 0, CERT_FIND_SUBJECT_CERT,
(PVOID)&CertInfo, NULL)))
__leave;
dwData = pCertContext->pCertInfo->SerialNumber.cbData;
// SPROG_SIGNATUREINFO.cbSerialSize
pInfo->cbSerialSize = dwData;
// SPROG_SIGNATUREINFO.lpSerialNumber
pInfo->lpSerialNumber = (LPBYTE)VirtualAlloc(NULL, dwData, MEM_COMMIT, PAGE_READWRITE);
memcpy( pInfo->lpSerialNumber, pCertContext->pCertInfo->SerialNumber.pbData, dwData);
// SPROG_SIGNATUREINFO.lpszIssuerName
__try
{
// get the length of Issuer Name
if (!(dwData = CertGetNameString( pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG, NULL, NULL, 0)))
__leave;
// allocate the memory
if ( !(pInfo->lpszIssuerName = (LPTSTR)VirtualAlloc(NULL, dwData * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE)))
__leave;
// get Issuer Name
if (!(CertGetNameString(pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG, NULL, pInfo->
lpszIssuerName, dwData)))
__leave;
}
__finally
{
}
// SPROG_SIGNATUREINFO.lpszSubjectName
__try
{
//get the length of Subject Name
if (!(dwData = CertGetNameString( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0)))
__leave;
// allocate the memory
if ( !(pInfo->lpszSubjectName = (LPTSTR)VirtualAlloc(NULL, dwData * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE)))
__leave;
// get Subject Name
if (!(CertGetNameString( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pInfo->lpszSubjectName, dwData)))
__leave;
}
__finally
{
}
}
__finally
{
if (pCertContext != NULL)
CertFreeCertificateContext(pCertContext);
}
}
int _tmain(int argc, TCHAR *argv[])
{
if (argc != 2)
{
_tprintf(_T("Usage: SignedFileInfo \n"));
return 0;
}
else
{
SPROG_SIGNATUREINFO SignInfo;
ZeroMemory(&SignInfo, sizeof(SignInfo));
GetAuthenticodeInformation( argv[1], &SignInfo);
wprintf(L"Program Name: %s\n", SignInfo.lpszProgramName);
wprintf(L"Publisher Link: %s\n", SignInfo.lpszPublisherLink);
wprintf(L"More Info Link: %s\n", SignInfo.lpszMoreInfoLink);
{
_tprintf(_T("Serial Number: "));
DWORD dwData = SignInfo.cbSerialSize;
for (DWORD n = 0; n < dwData; n++)
{
_tprintf(_T("%02x "),
SignInfo.lpSerialNumber[dwData - (n + 1)]);
}
_tprintf(_T("\n"));
}
_tprintf(_T("Issuer Name: %s\n"), SignInfo.lpszIssuerName);
_tprintf(_T("Subject Name: %s\n"), SignInfo.lpszSubjectName);
if ( SignInfo.lpszProgramName) VirtualFree(SignInfo.lpszProgramName, 0, MEM_RELEASE);
if ( SignInfo.lpszPublisherLink) VirtualFree(SignInfo.lpszPublisherLink, 0, MEM_RELEASE);
if ( SignInfo.lpszMoreInfoLink) VirtualFree(SignInfo.lpszMoreInfoLink, 0, MEM_RELEASE);
if ( SignInfo.lpSerialNumber) VirtualFree(SignInfo.lpSerialNumber, 0, MEM_RELEASE);
if ( SignInfo.lpszIssuerName) VirtualFree(SignInfo.lpszIssuerName, 0, MEM_RELEASE);
if ( SignInfo.lpszSubjectName) VirtualFree(SignInfo.lpszSubjectName, 0, MEM_RELEASE);
return 0;
}
}