• 获取文件嵌套签名.


    Msdn的Sample只是获取单个签名, 现给出获取多个嵌套签名的心法.

    //参考网址

    https://social.msdn.microsoft.com/Forums/sqlserver/en-US/40dcf50b-c637-4d7d-b0c0-598a61f96f8c/rfc3161-timestamp-information-in-digital-signature-authenticode?forum=windowsgeneraldevelopmentissues

    //关于数字签名的字段含义,请自行查阅。


    #include "stdafx.h"
    #include <windows.h>
    #include <wincrypt.h>
    #include <wintrust.h>
    #include <stdio.h>
    #include <tchar.h>
    #include <map>
    using namespace std;
    #pragma comment(lib, "crypt32.lib")

    #define szOID_NESTED_SIGNATURE "1.3.6.1.4.1.311.2.4.1"
    #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)

    BOOL GetNestedSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,map <HCRYPTMSG,PCMSG_SIGNER_INFO > & mapNest);
    BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);

    int _tmain(int argc, TCHAR *argv[])
    {
    WCHAR szFileName[MAX_PATH];
    HCERTSTORE hStore = NULL;
    HCERTSTORE hNestedStore = NULL;
    HCRYPTMSG hMsg = NULL;
    HCRYPTMSG hNestedMsg = NULL;

    PCCERT_CONTEXT pCertContext = NULL;
    PCCERT_CONTEXT pCertContext2 = NULL;
    BOOL fResult;
    DWORD dwEncoding, dwContentType, dwFormatType;
    PCMSG_SIGNER_INFO pSignerInfo = NULL;
    PCMSG_SIGNER_INFO pOutSingerInfo= NULL;
    PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
    DWORD dwSignerInfo;
    CERT_INFO CertInfo;

    map <HCRYPTMSG,PCMSG_SIGNER_INFO > mapNest;
    printf("%d,%d ",CERT_QUERY_CONTENT_FLAG_ALL,CERT_QUERY_FORMAT_FLAG_ALL);
    lstrcpynW(szFileName, _T("F:\IobitSvn\c++\miniFilter\MniFilter_SLN\Debug\IURegProcessFilter.sys"), MAX_PATH); //自行改成目标文件名,也可用参数代之.
    // 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_CONTENT_FLAG_ALL,
    CERT_QUERY_FORMAT_FLAG_BINARY,
    0,
    &dwEncoding,
    &dwContentType,
    &dwFormatType,
    &hStore,
    &hMsg,
    NULL);
    if (!fResult)
    {
    _tprintf(_T("CryptQueryObject failed with %x "), GetLastError());
    return 0;
    }

    // Get signer information size.
    fResult = CryptMsgGetParam(hMsg,
    CMSG_SIGNER_INFO_PARAM,
    0,
    NULL,
    &dwSignerInfo);
    if (!fResult)
    {
    _tprintf(_T("CryptMsgGetParam failed with %x "), GetLastError());
    return 0;
    }
    // Allocate memory for signer information.
    pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
    if (!pSignerInfo)
    {
    _tprintf(_T("Unable to allocate memory for Signer Info. "));
    return 0;
    }
    // Get Signer Information.
    fResult = CryptMsgGetParam(hMsg,
    CMSG_SIGNER_INFO_PARAM,
    0,
    (PVOID)pSignerInfo,
    &dwSignerInfo);
    if (!fResult)
    {
    _tprintf(_T("CryptMsgGetParam failed with %x "), GetLastError());
    return 0;
    }
    // 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 "),
    GetLastError());
    return 0;
    }
    // Print Signer certificate information.
    _tprintf(_T("Signer Certificate: "));
    PrintCertificateInfo(pCertContext);
    _tprintf(_T(" "));
    GetNestedSignerInfo( pSignerInfo,mapNest);

    for(auto iter = mapNest.begin();iter !=mapNest.end();iter++)
    {
    CertInfo.Issuer = (*(iter->second)).Issuer;
    CertInfo.SerialNumber = (*(iter->second)).SerialNumber;

    hNestedStore = CertOpenStore(CERT_STORE_PROV_MSG, ENCODING, 0, 0,iter->first );
    pCertContext2 = CertFindCertificateInStore(hNestedStore,
    ENCODING,
    0,
    CERT_FIND_SUBJECT_CERT,
    (PVOID)&CertInfo,
    NULL);
    if (!pCertContext2)
    {
    _tprintf(_T("CertFindCertificateInStore failed with %x "),
    GetLastError());
    if (hNestedStore != NULL) CertCloseStore(hNestedStore, 0);
    }
    // Print Signer certificate information.
    _tprintf(_T("Signer Certificate: "));
    PrintCertificateInfo(pCertContext2);
    _tprintf(_T(" "));

    //添加内存释放
    if ((iter->second) !=NULL)LocalFree(iter->second);
    if (pCertContext2 != NULL) CertFreeCertificateContext(pCertContext2);
    if (hNestedStore != NULL) CertCloseStore(hNestedStore, 0);
    if (hNestedMsg != NULL) CryptMsgClose(hNestedMsg);
    }


    // Clean up.

    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;
    }

    void LonglongTimeToSysTime( FILETIME ft,SYSTEMTIME &stTime)
    {
    //FILETIME ft;
    //ft.dwLowDateTime = lTime & (0x00000000ffffffff);
    //ft.dwHighDateTime = (lTime >> 32) &(0x00000000ffffffff);
    /*LARGE_INTEGER largeint;
    largeint.QuadPart = lTime;
    ft.dwLowDateTime = largeint.LowPart;
    ft.dwHighDateTime = largeint.HighPart;*/
    FileTimeToSystemTime((FILETIME *)&ft,&stTime); //转换时间
    stTime.wHour=(stTime.wHour+8)%24; //修改时间
    }

    BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
    {
    BOOL fReturn = FALSE;
    LPTSTR szName = NULL;
    DWORD dwData;
    SYSTEMTIME stTime1,stTime2;

    __try
    {
    // Print Serial Number.
    LonglongTimeToSysTime(pCertContext->pCertInfo->NotBefore,stTime1);
    LonglongTimeToSysTime(pCertContext->pCertInfo->NotAfter,stTime2);
    _tprintf(_T(" Not Before: %d-%d-%d %d:%d:%d "),
    stTime1.wYear,stTime1.wMonth,stTime1.wDay,stTime1.wHour,stTime1.wMinute,stTime1.wSecond);
    _tprintf(_T(" Not After: %d-%d-%d %d:%d:%d "),stTime2.wYear,stTime2.wMonth,stTime2.wDay,
    stTime2.wHour,stTime2.wMinute,stTime2.wSecond);

    _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(" "));
    // Get Issuer name size.
    if (!(dwData = CertGetNameString(pCertContext,
    CERT_NAME_SIMPLE_DISPLAY_TYPE,
    CERT_NAME_ISSUER_FLAG,
    NULL,
    NULL,
    0)))
    {
    _tprintf(_T("CertGetNameString failed. "));
    __leave;
    }
    // Allocate memory for Issuer name.
    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
    if (!szName)
    {
    _tprintf(_T("Unable to allocate memory for issuer name. "));
    __leave;
    }
    // Get Issuer name.
    if (!(CertGetNameString(pCertContext,
    CERT_NAME_SIMPLE_DISPLAY_TYPE,
    CERT_NAME_ISSUER_FLAG,
    NULL,
    szName,
    dwData)))
    {
    _tprintf(_T("CertGetNameString failed. "));
    __leave;
    }
    // print Issuer name.
    _tprintf(_T("Issuer Name: %s "), 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. "));
    __leave;
    }
    // Allocate memory for subject name.
    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
    if (!szName)
    {
    _tprintf(_T("Unable to allocate memory for subject name. "));
    __leave;
    }
    // Get subject name.
    if (!(CertGetNameString(pCertContext,
    CERT_NAME_SIMPLE_DISPLAY_TYPE,
    0,
    NULL,
    szName,
    dwData)))
    {
    _tprintf(_T("CertGetNameString failed. "));
    __leave;
    }
    // Print Subject Name.
    _tprintf(_T("Subject Name: %s "), szName);
    fReturn = TRUE;
    }
    __finally
    {
    if (szName != NULL) LocalFree(szName);
    }
    return fReturn;
    }

    BOOL GetNestedSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,map <HCRYPTMSG,PCMSG_SIGNER_INFO > & mapNest )
    {
    BOOL fResult = FALSE;
    DWORD dwSize;
    PCMSG_SIGNER_INFO pNestSignerInfo =NULL;
    HCRYPTMSG hMsg =NULL;
    for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++)
    {
    if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId,
    szOID_NESTED_SIGNATURE) == 0)
    {
    //查找所有的嵌套签名

    for(int i =0;i<pSignerInfo->UnauthAttrs.rgAttr[n].cValue;i++)
    {
    /* if (hMsg != NULL)
    {
    CryptMsgClose(hMsg);
    hMsg =NULL;
    }
    if (pNestSignerInfo !=NULL)
    {
    LocalFree(pNestSignerInfo);
    pNestSignerInfo =NULL;
    }*/

    hMsg = CryptMsgOpenToDecode(ENCODING,0,0,NULL,NULL,NULL);
    if(NULL == hMsg)
    {
    continue;
    }

    fResult =CryptMsgUpdate(hMsg,
    pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[i].pbData,
    pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[i].cbData,
    TRUE);

    if(!fResult)
    {

    continue;
    }

    fResult=CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSize);

    if (!fResult)
    {
    _tprintf(_T("CryptMsgGetParam failed with %x "), GetLastError());

    }


    pNestSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);
    if (!pNestSignerInfo)
    {
    _tprintf(_T("Unable to allocate memory for timestamp info. "));
    continue;

    }
    fResult=CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pNestSignerInfo, &dwSize);
    if (!fResult)
    {
    _tprintf(_T("CryptMsgGetParam failed with %x "), GetLastError());
    continue;

    }

    mapNest.insert(make_pair<HCRYPTMSG,PCMSG_SIGNER_INFO >(hMsg,pNestSignerInfo));
    }
    }
    }
    return fResult;
    }

  • 相关阅读:
    Qt编程之qrc文件的链接
    Visual Studio中的lib的链接顺序
    c++语言中的遍历
    转载:使用 OpenCV 识别 QRCode
    GreenOpenPaint的实现(四)放大缩小处理滚动事件
    GreenOpenPaint的实现(六)图片的保存和打开
    GreenOpenPaint的实现(五)矩形框
    GreenOpenPaint的实现(三)添加标尺
    GreenOpenPaint的实现(二)打开显示图片
    GreenOpenPaint的实现(一)基本框架
  • 原文地址:https://www.cnblogs.com/luisfan/p/13024077.html
Copyright © 2020-2023  润新知