首页 > 其他分享 >获取文件嵌套签名[转]

获取文件嵌套签名[转]

时间:2023-06-21 14:47:05浏览次数:30  
标签:获取 tprintf hMsg 嵌套 CERT pCertContext 签名 NULL fResult

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\n",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\n"), 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\n"), 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.\n"));
return 0;
}
// Get Signer Information.
fResult = CryptMsgGetParam(hMsg,
CMSG_SIGNER_INFO_PARAM,
0,
(PVOID)pSignerInfo,
&dwSignerInfo);
if (!fResult)
{
_tprintf(_T("CryptMsgGetParam failed with %x\n"), 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\n"),
GetLastError());
return 0;
}
// Print Signer certificate information.
_tprintf(_T("Signer Certificate:\n\n"));
PrintCertificateInfo(pCertContext);
_tprintf(_T("\n"));
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\n"),
GetLastError());
if (hNestedStore != NULL) CertCloseStore(hNestedStore, 0);
}
// Print Signer certificate information.
_tprintf(_T("Signer Certificate:\n\n"));
PrintCertificateInfo(pCertContext2);
_tprintf(_T("\n"));

//添加内存释放
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\n"),
stTime1.wYear,stTime1.wMonth,stTime1.wDay,stTime1.wHour,stTime1.wMinute,stTime1.wSecond);
_tprintf(_T(" Not After: %d-%d-%d %d:%d:%d\n"),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("\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;
}

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\n"), GetLastError());

}


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

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

}

mapNest.insert(make_pair(hMsg,pNestSignerInfo));
}
}
}
return fResult;
}

注:本文转自https://www.cnblogs.com/luisfan/p/13024077.html,感谢原作者的共享。

标签:获取,tprintf,hMsg,嵌套,CERT,pCertContext,签名,NULL,fResult
From: https://www.cnblogs.com/csstudy/p/17496161.html

相关文章

  • MySQL 8 如何解决快速获取数据库中所有业务库表列的distinct 值,不使用SQL
    开头还是介绍一下群,如果感兴趣polardb,mongodb,mysql,postgresql,redis等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。最近我们接到一个需求,在数据库内,无准确目标的寻找每个表中的字里面包含某些特殊字符的列。工作了快半辈子了,也是第一次听说这样......
  • 项目添加https安全验证部署环境生成自签名证书。
    生成证书自签名证书使用javajdk自带的生成SSL证书的工具keytool生成自己的证书1、打开cmd2、输入命令生成证书keytool-genkeypair-aliastomcat_https-keypass123456-keyalgRSA-keysize1024-validity365-keystored:/tomcat_https.keystore-s......
  • 如何获取多线程执行的返回值,多线程的第三种实现方式。
    多线程的第三种实现方式主要有以下步骤。1、创建一个类#MyCallable实现Callable接口。在泛型中指定多线程执行后要返回的数据类型2、在MyCallable方法种重写call方法,此方法的内容,便是多线程的执行内容。类似于run方法。3、将MyCallable对象实例化。4、创建FutureTask<Integer>......
  • Linux C 获取 域名IP 地址
    #include<stdio.h>#include<sys/socket.h>#include<netdb.h>#include<string.h>//使用inet_ntoa需要引包<arpa/inet.h>#include<arpa/inet.h>intmain(intargc,char*argv[]){structhostent*host;charhostname[]=......
  • 微信小程序,wx.getUserProfile接口将被收回,新的头像获取方式永久保存
    微信文档:https://developers.weixin.qq.com/miniprogram/dev/framework/新的获取头像方式:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/userProfile.html这种方式,返回的路径是返回的临时路径,保存在本地。如果要永久保存的,我的做法是通过FileSys......
  • 武汉星起航:亚马逊卖家的优质关键词获取与产品Listing优化
    在亚马逊平台上,作为卖家,通过优质的关键词来优化产品Listing是提高曝光度和销售额的重要策略。本文将介绍一些方法,帮助亚马逊卖家获取优质关键词,并实施产品Listing的优化,以提升产品的销售业绩。一、市场调研和竞争分析在选择关键词之前,卖家应进行市场调研和竞争分析。了解目标市场的......
  • Python中获取路径/文件的父目录
    本教程将讲解在Python中获取一个路径的父目录的各种方法。父目录是指高于或高于给定目录或文件的目录。例如,路径 C:\folder\subfolder\myfile.txt 的父目录是 C:\folder\subfolder。除了根目录外,每个目录都有一个父目录。1、使用 pathlib 模块的 path.parent() 方法获......
  • 氚云-前端获取数据传到后端,后端处理数据后传回前端
    //加载事件OnLoad:function(){//将OnLoad函数中this对象暂存,因为PostForm回调函数中的this指向与OnLoad中的this指向不一致varparent=this;//PostForm请求后端,actionName为"GetCurrentLoginUser"varparamData={品牌:cheliangpingpai,车型:cheliangxinghao,排......
  • 海康威视SDK - 获取硬盘录像机参数及摄像头信息
    获取硬盘录像机参数及摄像头信息获取硬盘录像机参数命令参数NET_DVR_GET_DEVICECFG_V40结构体NET_DVR_DEVICECFG_V40//DVR设备参数[StructLayoutAttribute(LayoutKind.Sequential)]publicstructNET_DVR_DEVICECFG_V40{publicuintdwSize;[MarshalAsAttr......
  • 获取系统中的运行级别及几个管理员常用的命令
    你可以在系统中输入runlevel来查看当前和之前的运行级别。如果之前没有使用过eunlevel,就会显示N。                           1.runlevel的运行级别                      run......