获取数字证书信息

来源:互联网 发布:农行掌上银行网络异常 编辑:程序博客网 时间:2024/06/05 05:58
// FileSign.cpp : 定义控制台应用程序的入口点。  //    #include "stdafx.h"  #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);  int _tmain(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,              szFileName,              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);      }      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;  }  

0 0
原创粉丝点击