<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code Library &#187; smth</title>
	<atom:link href="http://www.ucosoft.com/tag/smth/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ucosoft.com</link>
	<description>Free Source Code and Program Tips</description>
	<lastBuildDate>Mon, 19 Jul 2010 04:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>How to retrieve the authenticode information</title>
		<link>http://www.ucosoft.com/how-to-program-to-retrieve-the-authenticode-information.html</link>
		<comments>http://www.ucosoft.com/how-to-program-to-retrieve-the-authenticode-information.html#comments</comments>
		<pubDate>Sun, 31 Dec 2006 09:14:46 +0000</pubDate>
		<dc:creator>support</dc:creator>
				<category><![CDATA[Win32/MFC]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[smth]]></category>

		<guid isPermaLink="false">http://www.ucosoft.com/archives/67.html</guid>
		<description><![CDATA[Chinese verion author: Quaful@newsmth.net. When an ActiveX will be installed in IE, the authenticode information will be showed out. And how to get the information by programming? In microsoft KB323809: HOWTO: Get Information from Authenticode Signed Executables, there is a full example code. But it&#8217;s not very easy to use in your program directly. So]]></description>
			<content:encoded><![CDATA[<p><P> Chinese verion author: Quaful@newsmth.net.<br />
When an ActiveX will be installed in IE, the authenticode information will be showed out. And how to get the information by programming?<br />
In microsoft KB323809: HOWTO: Get Information from Authenticode Signed Executables, there is a full example code. But it&#8217;s not very easy to use in your program directly. So Quaful made a function for us. Many thanks to Quaful.<br />
The declaration of the function is:</p>
<p><coolcode lang="cpp" linenum="no" ><br />
BOOL<br />
GetAuthenticodeInformation(<br />
  LPCTSTR lpszFileName, //the file name<br />
PSPROG_SIGNATUREINFO pInfo // a structure of authenticode information<br />
);<br />
</coolcode><br />
Here is the SPROG_SIGNATUREINFO structure, which contains the authenticode information.<br />
<span id="more-67"></span><br />
<coolcode lang="cpp" linenum="no"><br />
typedef struct {</p>
<p>        LPWSTR lpszProgramName;<br />
        LPWSTR lpszPublisherLink;<br />
        LPWSTR lpszMoreInfoLink;</p>
<p>        DWORD  cbSerialSize;<br />
        LPBYTE lpSerialNumber;<br />
        LPTSTR lpszIssuerName;<br />
        LPTSTR lpszSubjectName;</p>
<p>} SPROG_SIGNATUREINFO, *PSPROG_SIGNATUREINFO;<br />
</coolcode></p>
<p>When you run the demo app, you can get such result ouput.<br />
<coolcode linenum="no"><br />
F:\quaful>SignedFileInfo sdkinst.cab<br />
Program Name: SDKUpdate ActiveX Control<br />
Publisher Link: (null)<br />
More Info Link: http://www.microsoft.com/<br />
              msdownload/platformsdk/sdkupdate<br />
Serial Number: 61 07 11 43 00 00 00 00 00 34<br />
Issuer Name: Microsoft Code Signing PCA<br />
Subject Name: Microsoft Corporation<br />
</coolcode></p>
<p>The full source code is here.<br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p1.cpp"><br />
#include <windows.h>ublisherLink;<br />
#include <wincrypt.h><br />
#include <wintrust.h><br />
#include <stdio.h><br />
#include <tchar.h>erialNumber;</p>
<p>#pragma comment(lib, &#8220;crypt32.lib&#8221;)</p>
<p>// the Authenticode Signature is encode in PKCS7<br />
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)</p>
<p>// Infomation structure of authenticode sign<br />
typedef struct {<br />
  LPWSTR lpszProgramName;   LPWSTR lpszPublisherLink;<br />
  LPWSTR lpszMoreInfoLink;</p>
<p>  DWORD  cbSerialSize;<br />
  LPBYTE lpSerialNumber;<br />
  LPTSTR lpszIssuerName;<br />
  LPTSTR lpszSubjectName;<br />
} SPROG_SIGNATUREINFO, *PSPROG_SIGNATUREINFO;</p>
<p>VOID GetProgAndPublisherInfo(<br />
      PCMSG_SIGNER_INFO pSignerInfo,<br />
      PSPROG_SIGNATUREINFO pInfo);</p>
<p>VOID GetCertificateInfo(<br />
      HCERTSTORE hStore,<br />
      PCMSG_SIGNER_INFO pSignerInfo,<br />
      PSPROG_SIGNATUREINFO pInfo);<br />
</coolcode><br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p2.cpp"><br />
BOOL GetAuthenticodeInformation(<br />
      LPCTSTR lpszFileName,<br />
      PSPROG_SIGNATUREINFO pInfo)<br />
{<br />
  HCERTSTORE hStore = NULL;<br />
  HCRYPTMSG hMsg = NULL;<br />
  PCMSG_SIGNER_INFO pSignerInfo = NULL;<br />
  DWORD dwSignerInfo;</p>
<p>  BOOL bRet = FALSE;</p>
<p>  __try<br />
  {<br />
  // as CryptQueryObject() only accept WCHAR file name, convert first<br />
   WCHAR wszFileName[MAX_PATH];<br />
#ifdef UNICODE<br />
  if ( !lstrcpynW( wszFileName, lpszFileName, MAX_PATH))<br />
    __leave;<br />
#else<br />
  if ( mbstowcs( wszFileName, lpszFileName, MAX_PATH) == -1)<br />
    __leave;<br />
#endif<br />
  //Retrieve the Message Handle and Store Handle<br />
  DWORD dwEncoding, dwContentType, dwFormatType;<br />
  if ( !CryptQueryObject( CERT_QUERY_OBJECT_FILE, wszFileName,<br />
    CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,<br />
    CERT_QUERY_FORMAT_FLAG_BINARY, 0, &#038;dwEncoding,<br />
    &#038;dwContentType, &#038;dwFormatType, &#038;hStore,<br />
    &#038;hMsg, NULL))<br />
    __leave;</p>
<p>  //Get the length of SignerInfo<br />
  if ( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL,<br />
    &#038;dwSignerInfo))<br />
    __leave;</p>
<p>  // allocate the memory for SignerInfo<br />
  if ( !(pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc( LPTR, dwSignerInfo)))<br />
    __leave;</p>
<p>  // get the SignerInfo<br />
  if ( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)<br />
     pSignerInfo, &#038;dwSignerInfo))<br />
    __leave;</p>
<p>  //get the Publisher from SignerInfo<br />
  GetProgAndPublisherInfo( pSignerInfo, pInfo);</p>
<p>  //get the Certificate from SignerInfo<br />
  GetCertificateInfo( hStore, pSignerInfo, pInfo);</p>
<p>  bRet = TRUE;<br />
  }<br />
  __finally<br />
  {<br />
  // release the memory<br />
  if (pSignerInfo != NULL) LocalFree(pSignerInfo);<br />
  if (hStore != NULL) CertCloseStore(hStore, 0);<br />
  if (hMsg != NULL) CryptMsgClose(hMsg);<br />
  }<br />
  return bRet;<br />
}<br />
</coolcode><br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p3.cpp"><br />
LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)<br />
{<br />
  LPWSTR outputString = NULL;</p>
<p>  // allocate the memory<br />
  outputString = (LPWSTR)VirtualAlloc(NULL, (wcslen(inputString) + 1) *<br />
  sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);</p>
<p>  // copy<br />
  if (outputString != NULL)<br />
  {<br />
  lstrcpyW(outputString, inputString);<br />
  }</p>
<p>  return outputString;<br />
}<br />
</coolcode><br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p4.cpp"><br />
VOID GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,<br />
PSPROG_SIGNATUREINFO pInfo)<br />
{<br />
  PSPC_SP_OPUS_INFO OpusInfo = NULL;<br />
  DWORD dwData;</p>
<p>  __try<br />
  {<br />
  // query SPC_SP_OPUS_INFO_OBJID OID in Authenticated Attributes<br />
  for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)<br />
  {<br />
    if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)<br />
    {<br />
     // get the length of SPC_SP_OPUS_INFO<br />
     if ( !CryptDecodeObject(ENCODING,<br />
      SPC_SP_OPUS_INFO_OBJID,<br />
      pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,<br />
      pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,<br />
      0,<br />
      NULL,<br />
      &#038;dwData))<br />
    __leave;</p>
<p>  // allocate the memory for SPC_SP_OPUS_INFO<br />
  if ( !(OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData)))<br />
    __leave;</p>
<p>  // get SPC_SP_OPUS_INFO structure<br />
  if ( !CryptDecodeObject(ENCODING,<br />
      SPC_SP_OPUS_INFO_OBJID,<br />
      pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,<br />
      pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,<br />
      0,<br />
      OpusInfo,<br />
      &#038;dwData))<br />
    __leave;</p>
<p>  // copy the Program Name of SPC_SP_OPUS_INFO to the return variable<br />
  if (OpusInfo->pwszProgramName)<br />
  {<br />
    pInfo->lpszProgramName =<br />
    AllocateAndCopyWideString(OpusInfo->pwszProgramName);<br />
  }<br />
  else<br />
    pInfo->lpszProgramName = NULL;</p>
<p>  // copy the Publisher Info of SPC_SP_OPUS_INFO to the return variable<br />
  if (OpusInfo->pPublisherInfo)<br />
  {</p>
<p>    switch (OpusInfo->pPublisherInfo->dwLinkChoice)<br />
    {<br />
    case SPC_URL_LINK_CHOICE:<br />
      pInfo->lpszPublisherLink =<br />
    AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);<br />
      break;</p>
<p>    case SPC_FILE_LINK_CHOICE:<br />
      pInfo->lpszPublisherLink =<br />
    AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);<br />
      break;</p>
<p>    default:<br />
      pInfo->lpszPublisherLink = NULL;<br />
      break;<br />
    }<br />
  }<br />
  else<br />
  {<br />
    pInfo->lpszPublisherLink = NULL;<br />
  }</p>
<p>  // copy the More Info of SPC_SP_OPUS_INFO to the return variable<br />
   if (OpusInfo->pMoreInfo)<br />
  {<br />
    switch (OpusInfo->pMoreInfo->dwLinkChoice)<br />
    {<br />
    case SPC_URL_LINK_CHOICE:<br />
      pInfo->lpszMoreInfoLink =<br />
    AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);<br />
      break;</p>
<p>    case SPC_FILE_LINK_CHOICE:<br />
      pInfo->lpszMoreInfoLink =<br />
    AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);<br />
      break;</p>
<p>    default:<br />
      pInfo->lpszMoreInfoLink = NULL;<br />
      break;<br />
    }<br />
  }<br />
  else<br />
  {<br />
    pInfo->lpszMoreInfoLink = NULL;<br />
  }</p>
<p>  break; // we have got the information, break<br />
    }<br />
  }<br />
  }<br />
  __finally<br />
  {<br />
  if (OpusInfo != NULL) LocalFree(OpusInfo);<br />
  }<br />
}<br />
</coolcode><br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p5.cpp"><br />
VOID GetCertificateInfo(<br />
      HCERTSTORE hStore,<br />
      PCMSG_SIGNER_INFO pSignerInfo,<br />
      PSPROG_SIGNATUREINFO pInfo)<br />
{<br />
  PCCERT_CONTEXT pCertContext = NULL;</p>
<p>  __try<br />
  {<br />
  CERT_INFO CertInfo;<br />
  DWORD dwData;</p>
<p>  // query Signer Certificate in Certificate Store<br />
  CertInfo.Issuer = pSignerInfo->Issuer;<br />
  CertInfo.SerialNumber = pSignerInfo->SerialNumber;</p>
<p>  if ( !(pCertContext = CertFindCertificateInStore( hStore,<br />
ENCODING, 0, CERT_FIND_SUBJECT_CERT,<br />
    (PVOID)&#038;CertInfo, NULL)))<br />
    __leave;</p>
<p>  dwData = pCertContext->pCertInfo->SerialNumber.cbData;</p>
<p>  // SPROG_SIGNATUREINFO.cbSerialSize<br />
  pInfo->cbSerialSize = dwData;</p>
<p>  // SPROG_SIGNATUREINFO.lpSerialNumber<br />
  pInfo->lpSerialNumber = (LPBYTE)VirtualAlloc(NULL, dwData,<br />
MEM_COMMIT, PAGE_READWRITE);<br />
  memcpy( pInfo->lpSerialNumber, pCertContext->pCertInfo->SerialNumber.pbData, dwData);</p>
<p>  // SPROG_SIGNATUREINFO.lpszIssuerName<br />
  __try<br />
  {<br />
    // get the length of Issuer Name<br />
    if (!(dwData = CertGetNameString( pCertContext,<br />
CERT_NAME_SIMPLE_DISPLAY_TYPE,<br />
    CERT_NAME_ISSUER_FLAG, NULL, NULL, 0)))<br />
    __leave;</p>
<p>    // allocate the memory<br />
    if ( !(pInfo->lpszIssuerName = (LPTSTR)<br />
VirtualAlloc(NULL, dwData * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE)))<br />
    __leave;</p>
<p>    // get Issuer Name<br />
    if (!(CertGetNameString( pCertContext,<br />
CERT_NAME_SIMPLE_DISPLAY_TYPE,<br />
    CERT_NAME_ISSUER_FLAG, NULL, pInfo-><br />
lpszIssuerName, dwData)))<br />
    __leave;<br />
  }<br />
  __finally<br />
  {<br />
  }</p>
<p>  // SPROG_SIGNATUREINFO.lpszSubjectName<br />
  __try<br />
  {<br />
    //get the length of Subject Name<br />
    if (!(dwData = CertGetNameString( pCertContext,<br />
CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0)))<br />
    __leave;</p>
<p>    // allocate the memory<br />
    if ( !(pInfo->lpszSubjectName = (LPTSTR)<br />
VirtualAlloc(NULL, dwData * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE)))<br />
    __leave;</p>
<p>    // get Subject Name<br />
    if (!(CertGetNameString( pCertContext,<br />
CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pInfo->lpszSubjectName, dwData)))<br />
    __leave;<br />
  }<br />
  __finally<br />
  {<br />
  }<br />
  }<br />
  __finally<br />
  {<br />
  if (pCertContext != NULL)<br />
CertFreeCertificateContext(pCertContext);<br />
  }<br />
}<br />
</coolcode><br />
<coolcode lang="cpp" linenum="no" download="GetAuthenticodeInfo_demo_p6.cpp"><br />
int _tmain(int argc, TCHAR *argv[])<br />
{<br />
  if (argc != 2)<br />
  {<br />
  _tprintf(_T(&#8220;Usage: SignedFileInfo <filename>\n&#8221;));<br />
  return 0;<br />
  }<br />
  else<br />
  {<br />
  SPROG_SIGNATUREINFO SignInfo;</p>
<p>  ZeroMemory(&#038;SignInfo, sizeof(SignInfo));</p>
<p>  GetAuthenticodeInformation( argv[1], &#038;SignInfo);</p>
<p>  wprintf(L&#8221;Program Name: %s\n&#8221;, SignInfo.lpszProgramName);<br />
  wprintf(L&#8221;Publisher Link: %s\n&#8221;, SignInfo.lpszPublisherLink);<br />
  wprintf(L&#8221;More Info Link: %s\n&#8221;, SignInfo.lpszMoreInfoLink);</p>
<p>  {<br />
    _tprintf(_T(&#8220;Serial Number: &#8220;));<br />
    DWORD dwData = SignInfo.cbSerialSize;<br />
    for (DWORD n = 0; n < dwData; n++)<br />
    {<br />
    _tprintf(_T("%02x "),<br />
SignInfo.lpSerialNumber[dwData - (n + 1)]);<br />
    }<br />
    _tprintf(_T("\n"));<br />
  }<br />
  _tprintf(_T("Issuer Name: %s\n"), SignInfo.lpszIssuerName);<br />
  _tprintf(_T("Subject Name: %s\n"), SignInfo.lpszSubjectName);<br />
  if ( SignInfo.lpszProgramName) VirtualFree(SignInfo.lpszProgramName, 0, MEM_RELEASE);<br />
  if ( SignInfo.lpszPublisherLink) VirtualFree(SignInfo.lpszPublisherLink, 0, MEM_RELEASE);<br />
  if ( SignInfo.lpszMoreInfoLink) VirtualFree(SignInfo.lpszMoreInfoLink, 0, MEM_RELEASE);<br />
  if ( SignInfo.lpSerialNumber) VirtualFree(SignInfo.lpSerialNumber, 0, MEM_RELEASE);<br />
  if ( SignInfo.lpszIssuerName) VirtualFree(SignInfo.lpszIssuerName, 0, MEM_RELEASE);<br />
  if ( SignInfo.lpszSubjectName) VirtualFree(SignInfo.lpszSubjectName, 0, MEM_RELEASE);</p>
<p>  return 0;<br />
  }<br />
}<br />
</coolcode></p>

	Tags: <strong><a href="http://www.ucosoft.com/tag/api" title="API" rel="tag">API</a>, <a href="http://www.ucosoft.com/tag/how-to" title="How-to" rel="tag">How-to</a>, <a href="http://www.ucosoft.com/tag/smth" title="smth" rel="tag">smth</a></strong><br />

	<ul class="st-related-posts">
	<li><a href="http://www.ucosoft.com/write-and-read-binary-data-in-variant.html" title="Write and read binary data in VARIANT (November 22, 2006)">Write and read binary data in VARIANT</a> (0)</li>
	<li><a href="http://www.ucosoft.com/set-the-head-backgroud-color-of-cpropertypage.html" title="Set the head backgroud color of CPropertyPage (October 18, 2007)">Set the head backgroud color of CPropertyPage</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-translate-among-cstringstring-and-char-array.html" title="How to translate among CString,string and char array (June 22, 2007)">How to translate among CString,string and char array</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-subclass-ctreectrl-in-ctreeview.html" title="How to subclass CTreeCtrl in CTreeView? (October 25, 2007)">How to subclass CTreeCtrl in CTreeView?</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-sort-items-of-clistctrl-or-clistview.html" title="How to sort items of CListCtrl or CListView? (October 22, 2007)">How to sort items of CListCtrl or CListView?</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-sendpost-message-to-cdocument.html" title="How to send/post message to CDocument? (October 24, 2007)">How to send/post message to CDocument?</a> (2)</li>
	<li><a href="http://www.ucosoft.com/how-to-launch-an-application-with-admin-privileges-in-vista.html" title="How to launch an Application with Admin privileges in VISTA (March 8, 2007)">How to launch an Application with Admin privileges in VISTA</a> (0)</li>
	<li><a href="http://www.ucosoft.com/get-clistctrl-item-text-of-another-process.html" title="How to get ClistCtrl item text of another process (September 24, 2008)">How to get ClistCtrl item text of another process</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-draw-bitmap-from-a-bmp-file.html" title="How to Draw Bitmap from a bmp File? (January 4, 2007)">How to Draw Bitmap from a bmp File?</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-check-whether-the-window-is-in-minimise-or-maximise-mode.html" title="How to check whether the window is in minimise or Maximise mode (March 21, 2007)">How to check whether the window is in minimise or Maximise mode</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.ucosoft.com/how-to-program-to-retrieve-the-authenticode-information.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
