判断PE文件的数字签名信息
2011-08-21 23:18
375 查看
判断PE文件的数字签名信息
工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。
因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而是一个比较好的方法,但是如果只是判断数字签名是否有效也不够,别人只要用自己的证书重新签名就可以了,所以需要判断证书签名者信息。
验证文件数字签名是否有效可以使用函数 WinVerifyTrust
取得文件数字签名证书信息需要使用函数 CryptQueryObject。
下面是一段从网上搜到的获得文件数字签名证书信息的代码:
1 #include
<windows.h>
2
#include <wincrypt.h>
3
#include <wintrust.h>
4
#include <stdio.h>
5
#include <tchar.h>
6
#pragma comment(lib, "crypt32.lib")
7
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
8
typedef struct {
9
LPWSTR lpszProgramName;
10
LPWSTR lpszPublisherLink;
11
LPWSTR lpszMoreInfoLink;
12
} SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;
13
BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
14
PSPROG_PUBLISHERINFO Info);
15
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);
16
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);
17
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,
18
PCMSG_SIGNER_INFO *pCounterSignerInfo);
19
int _tmain(int argc, TCHAR
*argv[])
20
{
21
WCHAR szFileName[MAX_PATH];
22
HCERTSTORE hStore = NULL;
23
HCRYPTMSG hMsg = NULL;
24
PCCERT_CONTEXT pCertContext = NULL;
25
BOOL fResult;
26
DWORD dwEncoding, dwContentType, dwFormatType;
27
PCMSG_SIGNER_INFO pSignerInfo = NULL;
28
PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
29
DWORD dwSignerInfo;
30
CERT_INFO CertInfo;
31
SPROG_PUBLISHERINFO ProgPubInfo;
32
SYSTEMTIME st;
33
ZeroMemory(&ProgPubInfo,
sizeof(ProgPubInfo));
34
__try
35
{
36
if (argc
!=
2)
37
{
38
_tprintf(_T("Usage: SignedFileInfo <filename>\n"));
39
return
0;
40
}
41
#ifdef UNICODE
42
lstrcpynW(szFileName, argv[1], MAX_PATH);
43
#else
44
if (mbstowcs(szFileName, argv[1], MAX_PATH)
==
-1)
45
{
46
printf("Unable to convert to unicode.\n");
47
__leave;
48
}
49
#endif
50
// Get message handle and store handle from the signed file.
51
fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
52
szFileName,
53
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
54
CERT_QUERY_FORMAT_FLAG_BINARY,
55
0,
56
&dwEncoding,
57
&dwContentType,
58
&dwFormatType,
59
&hStore,
60
&hMsg,
61
NULL);
62
if (!fResult)
63
{
64
_tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError());
65
__leave;
66
}
67
// Get signer information size.
68
fResult = CryptMsgGetParam(hMsg,
69
CMSG_SIGNER_INFO_PARAM,
70
0,
71
NULL,
72
&dwSignerInfo);
73
if (!fResult)
74
{
75
_tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
76
__leave;
77
}
78
// Allocate memory for signer information.
79
pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
80
if (!pSignerInfo)
81
{
82
_tprintf(_T("Unable to allocate memory for Signer Info.\n"));
83
__leave;
84
}
85
// Get Signer Information.
86
fResult = CryptMsgGetParam(hMsg,
87
CMSG_SIGNER_INFO_PARAM,
88
0,
89
(PVOID)pSignerInfo,
90
&dwSignerInfo);
91
if (!fResult)
92
{
93
_tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
94
__leave;
95
}
96
// Get program name and publisher information from
97
// signer info structure.
98
if (GetProgAndPublisherInfo(pSignerInfo,
&ProgPubInfo))
99
{
100
if (ProgPubInfo.lpszProgramName
!= NULL)
101
{
102
wprintf(L"Program Name : %s\n",
103
ProgPubInfo.lpszProgramName);
104
}
105
if (ProgPubInfo.lpszPublisherLink
!= NULL)
106
{
107
wprintf(L"Publisher Link : %s\n",
108
ProgPubInfo.lpszPublisherLink);
109
}
110
if (ProgPubInfo.lpszMoreInfoLink
!= NULL)
111
{
112
wprintf(L"MoreInfo Link : %s\n",
113
ProgPubInfo.lpszMoreInfoLink);
114
}
115
}
116
_tprintf(_T("\n"));
117
// Search for the signer certificate in the temporary
118
// certificate store.
119
CertInfo.Issuer = pSignerInfo->Issuer;
120
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
121
pCertContext = CertFindCertificateInStore(hStore,
122
ENCODING,
123
0,
124
CERT_FIND_SUBJECT_CERT,
125
(PVOID)&CertInfo,
126
NULL);
127
if (!pCertContext)
128
{
129
_tprintf(_T("CertFindCertificateInStore failed with %x\n"),
130
GetLastError());
131
__leave;
132
}
133
// Print Signer certificate information.
134
_tprintf(_T("Signer Certificate:\n\n"));
135
PrintCertificateInfo(pCertContext);
136
_tprintf(_T("\n"));
137
// Get the timestamp certificate signerinfo structure.
138
if (GetTimeStampSignerInfo(pSignerInfo,
&pCounterSignerInfo))
139
{
140
// Search for Timestamp certificate in the temporary
141
// certificate store.
142
CertInfo.Issuer = pCounterSignerInfo->Issuer;
143
CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber;
144
pCertContext = CertFindCertificateInStore(hStore,
145
ENCODING,
146
0,
147
CERT_FIND_SUBJECT_CERT,
148
(PVOID)&CertInfo,
149
NULL);
150
if (!pCertContext)
151
{
152
_tprintf(_T("CertFindCertificateInStore failed with %x\n"),
153
GetLastError());
154
__leave;
155
}
156
// Print timestamp certificate information.
157
_tprintf(_T("TimeStamp Certificate:\n\n"));
158
PrintCertificateInfo(pCertContext);
159
_tprintf(_T("\n"));
160
// Find Date of timestamp.
161
if (GetDateOfTimeStamp(pCounterSignerInfo,
&st))
162
{
163
_tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"),
164
st.wMonth,
165
st.wDay,
166
st.wYear,
167
st.wHour,
168
st.wMinute);
169
}
170
_tprintf(_T("\n"));
171
}
172
}
173
__finally
174
{
175
// Clean up.
176
if (ProgPubInfo.lpszProgramName
!= NULL)
177
LocalFree(ProgPubInfo.lpszProgramName);
178
if (ProgPubInfo.lpszPublisherLink
!= NULL)
179
LocalFree(ProgPubInfo.lpszPublisherLink);
180
if (ProgPubInfo.lpszMoreInfoLink
!= NULL)
181
LocalFree(ProgPubInfo.lpszMoreInfoLink);
182
if (pSignerInfo
!= NULL) LocalFree(pSignerInfo);
183
if (pCounterSignerInfo
!= NULL) LocalFree(pCounterSignerInfo);
184
if (pCertContext
!= NULL) CertFreeCertificateContext(pCertContext);
185
if (hStore
!= NULL) CertCloseStore(hStore,
0);
186
if (hMsg
!= NULL) CryptMsgClose(hMsg);
187
}
188
return
0;
189
}
190
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
191
{
192
BOOL fReturn = FALSE;
193
LPTSTR szName = NULL;
194
DWORD dwData;
195
__try
196
{
197
// Print Serial Number.
198
_tprintf(_T("Serial Number:
"));
199
dwData = pCertContext->pCertInfo->SerialNumber.cbData;
200
for (DWORD n
=
0; n
< dwData; n++)
201
{
202
_tprintf(_T("%02x
"),
203
pCertContext->pCertInfo->SerialNumber.pbData[dwData
- (n
+ 1)]);
204
}
205
_tprintf(_T("\n"));
206
// Get Issuer name size.
207
if (!(dwData
= CertGetNameString(pCertContext,
208
CERT_NAME_SIMPLE_DISPLAY_TYPE,
209
CERT_NAME_ISSUER_FLAG,
210
NULL,
211
NULL,
212
0)))
213
{
214
_tprintf(_T("CertGetNameString failed.\n"));
215
__leave;
216
}
217
// Allocate memory for Issuer name.
218
szName = (LPTSTR)LocalAlloc(LPTR, dwData
*
sizeof(TCHAR));
219
if (!szName)
220
{
221
_tprintf(_T("Unable to allocate memory for issuer name.\n"));
222
__leave;
223
}
224
// Get Issuer name.
225
if (!(CertGetNameString(pCertContext,
226
CERT_NAME_SIMPLE_DISPLAY_TYPE,
227
CERT_NAME_ISSUER_FLAG,
228
NULL,
229
szName,
230
dwData)))
231
{
232
_tprintf(_T("CertGetNameString failed.\n"));
233
__leave;
234
}
235
// print Issuer name.
236
_tprintf(_T("Issuer Name: %s\n"), szName);
237
LocalFree(szName);
238
szName = NULL;
239
// Get Subject name size.
240
if (!(dwData
= CertGetNameString(pCertContext,
241
CERT_NAME_SIMPLE_DISPLAY_TYPE,
242
0,
243
NULL,
244
NULL,
245
0)))
246
{
247
_tprintf(_T("CertGetNameString failed.\n"));
248
__leave;
249
}
250
// Allocate memory for subject name.
251
szName = (LPTSTR)LocalAlloc(LPTR, dwData
*
sizeof(TCHAR));
252
if (!szName)
253
{
254
_tprintf(_T("Unable to allocate memory for subject name.\n"));
255
__leave;
256
}
257
// Get subject name.
258
if (!(CertGetNameString(pCertContext,
259
CERT_NAME_SIMPLE_DISPLAY_TYPE,
260
0,
261
NULL,
262
szName,
263
dwData)))
264
{
265
_tprintf(_T("CertGetNameString failed.\n"));
266
__leave;
267
}
268
// Print Subject Name.
269
_tprintf(_T("Subject Name: %s\n"), szName);
270
fReturn = TRUE;
271
}
272
__finally
273
{
274
if (szName
!= NULL) LocalFree(szName);
275
}
276
return fReturn;
277
}
278
LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
279
{
280
LPWSTR outputString = NULL;
281
outputString = (LPWSTR)LocalAlloc(LPTR,
282
(wcslen(inputString) +
1)
*
sizeof(WCHAR));
283
if (outputString
!= NULL)
284
{
285
lstrcpyW(outputString, inputString);
286
}
287
return outputString;
288
}
289
BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
290
PSPROG_PUBLISHERINFO Info)
291
{
292
BOOL fReturn = FALSE;
293
PSPC_SP_OPUS_INFO OpusInfo = NULL;
294
DWORD dwData;
295
BOOL fResult;
296
__try
297
{
298
// Loop through authenticated attributes and find
299
// SPC_SP_OPUS_INFO_OBJID OID.
300
for (DWORD n
=
0; n
< pSignerInfo->AuthAttrs.cAttr; n++)
301
{
302
if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID,
303
pSignerInfo->AuthAttrs.rgAttr
.pszObjId)
==
0)
304
{
305
// Get Size of SPC_SP_OPUS_INFO structure.
306
fResult = CryptDecodeObject(ENCODING,
307
SPC_SP_OPUS_INFO_OBJID,
308
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
309
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
310
0,
311
NULL,
312
&dwData);
313
if (!fResult)
314
{
315
_tprintf(_T("CryptDecodeObject failed with %x\n"),
316
GetLastError());
317
__leave;
318
}
319
// Allocate memory for SPC_SP_OPUS_INFO structure.
320
OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData);
321
if (!OpusInfo)
322
{
323
_tprintf(_T("Unable to allocate memory for Publisher Info.\n"));
324
__leave;
325
}
326
// Decode and get SPC_SP_OPUS_INFO structure.
327
fResult = CryptDecodeObject(ENCODING,
328
SPC_SP_OPUS_INFO_OBJID,
329
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
330
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
331
0,
332
OpusInfo,
333
&dwData);
334
if (!fResult)
335
{
336
_tprintf(_T("CryptDecodeObject failed with %x\n"),
337
GetLastError());
338
__leave;
339
}
340
// Fill in Program Name if present.
341
if (OpusInfo->pwszProgramName)
342
{
343
Info->lpszProgramName
=
344
AllocateAndCopyWideString(OpusInfo->pwszProgramName);
345
}
346
else
347
Info->lpszProgramName
= NULL;
348
// Fill in Publisher Information if present.
349
if (OpusInfo->pPublisherInfo)
350
{
351
switch (OpusInfo->pPublisherInfo->dwLinkChoice)
352
{
353
case SPC_URL_LINK_CHOICE:
354
Info->lpszPublisherLink
=
355
AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);
356
break;
357
case SPC_FILE_LINK_CHOICE:
358
Info->lpszPublisherLink
=
359
AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);
360
break;
361
default:
362
Info->lpszPublisherLink
= NULL;
363
break;
364
}
365
}
366
else
367
{
368
Info->lpszPublisherLink
= NULL;
369
}
370
// Fill in More Info if present.
371
if (OpusInfo->pMoreInfo)
372
{
373
switch (OpusInfo->pMoreInfo->dwLinkChoice)
374
{
375
case SPC_URL_LINK_CHOICE:
376
Info->lpszMoreInfoLink
=
377
AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);
378
break;
379
case SPC_FILE_LINK_CHOICE:
380
Info->lpszMoreInfoLink
=
381
AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);
382
break;
383
default:
384
Info->lpszMoreInfoLink
= NULL;
385
break;
386
}
387
}
388
else
389
{
390
Info->lpszMoreInfoLink
= NULL;
391
}
392
fReturn = TRUE;
393
break;
// Break from for loop.
394
} // lstrcmp SPC_SP_OPUS_INFO_OBJID
395
} // for
396
}
397
__finally
398
{
399
if (OpusInfo
!= NULL) LocalFree(OpusInfo);
400
}
401
return fReturn;
402
}
403
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st)
404
{
405
BOOL fResult;
406
FILETIME lft, ft;
407
DWORD dwData;
408
BOOL fReturn = FALSE;
409
// Loop through authenticated attributes and find
410
// szOID_RSA_signingTime OID.
411
for (DWORD n
=
0; n
< pSignerInfo->AuthAttrs.cAttr; n++)
412
{
413
if (lstrcmpA(szOID_RSA_signingTime,
414
pSignerInfo->AuthAttrs.rgAttr
.pszObjId)
==
0)
415
{
416
// Decode and get FILETIME structure.
417
dwData =
sizeof(ft);
418
fResult = CryptDecodeObject(ENCODING,
419
szOID_RSA_signingTime,
420
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
421
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
422
0,
423
(PVOID)&ft,
424
&dwData);
425
if (!fResult)
426
{
427
_tprintf(_T("CryptDecodeObject failed with %x\n"),
428
GetLastError());
429
break;
430
}
431
// Convert to local time.
432
FileTimeToLocalFileTime(&ft,
&lft);
433
FileTimeToSystemTime(&lft, st);
434
fReturn = TRUE;
435
break;
// Break from for loop.
436
} //lstrcmp szOID_RSA_signingTime
437
} // for
438
return fReturn;
439
}
440
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO
*pCounterSignerInfo)
441
{
442
PCCERT_CONTEXT pCertContext = NULL;
443
BOOL fReturn = FALSE;
444
BOOL fResult;
445
DWORD dwSize;
446
__try
447
{
448
*pCounterSignerInfo
= NULL;
449
// Loop through unathenticated attributes for
450
// szOID_RSA_counterSign OID.
451
for (DWORD n
=
0; n
< pSignerInfo->UnauthAttrs.cAttr; n++)
452
{
453
if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr
.pszObjId,
454
szOID_RSA_counterSign) ==
0)
455
{
456
// Get size of CMSG_SIGNER_INFO structure.
457
fResult = CryptDecodeObject(ENCODING,
458
PKCS7_SIGNER_INFO,
459
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].pbData,
460
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].cbData,
461
0,
462
NULL,
463
&dwSize);
464
if (!fResult)
465
{
466
_tprintf(_T("CryptDecodeObject failed with %x\n"),
467
GetLastError());
468
__leave;
469
}
470
// Allocate memory for CMSG_SIGNER_INFO.
471
*pCounterSignerInfo
= (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);
472
if (!*pCounterSignerInfo)
473
{
474
_tprintf(_T("Unable to allocate memory for timestamp info.\n"));
475
__leave;
476
}
477
// Decode and get CMSG_SIGNER_INFO structure
478
// for timestamp certificate.
479
fResult = CryptDecodeObject(ENCODING,
480
PKCS7_SIGNER_INFO,
481
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].pbData,
482
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].cbData,
483
0,
484
(PVOID)*pCounterSignerInfo,
485
&dwSize);
486
if (!fResult)
487
{
488
_tprintf(_T("CryptDecodeObject failed with %x\n"),
489
GetLastError());
490
__leave;
491
}
492
fReturn = TRUE;
493
break;
// Break from for loop.
494
}
495
}
496
}
497
__finally
498
{
499
// Clean up.
500
if (pCertContext
!= NULL) CertFreeCertificateContext(pCertContext);
501
}
502
return fReturn;
503
}
工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。
因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而是一个比较好的方法,但是如果只是判断数字签名是否有效也不够,别人只要用自己的证书重新签名就可以了,所以需要判断证书签名者信息。
验证文件数字签名是否有效可以使用函数 WinVerifyTrust
取得文件数字签名证书信息需要使用函数 CryptQueryObject。
下面是一段从网上搜到的获得文件数字签名证书信息的代码:
1 #include
<windows.h>
2
#include <wincrypt.h>
3
#include <wintrust.h>
4
#include <stdio.h>
5
#include <tchar.h>
6
#pragma comment(lib, "crypt32.lib")
7
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
8
typedef struct {
9
LPWSTR lpszProgramName;
10
LPWSTR lpszPublisherLink;
11
LPWSTR lpszMoreInfoLink;
12
} SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;
13
BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
14
PSPROG_PUBLISHERINFO Info);
15
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);
16
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);
17
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,
18
PCMSG_SIGNER_INFO *pCounterSignerInfo);
19
int _tmain(int argc, TCHAR
*argv[])
20
{
21
WCHAR szFileName[MAX_PATH];
22
HCERTSTORE hStore = NULL;
23
HCRYPTMSG hMsg = NULL;
24
PCCERT_CONTEXT pCertContext = NULL;
25
BOOL fResult;
26
DWORD dwEncoding, dwContentType, dwFormatType;
27
PCMSG_SIGNER_INFO pSignerInfo = NULL;
28
PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
29
DWORD dwSignerInfo;
30
CERT_INFO CertInfo;
31
SPROG_PUBLISHERINFO ProgPubInfo;
32
SYSTEMTIME st;
33
ZeroMemory(&ProgPubInfo,
sizeof(ProgPubInfo));
34
__try
35
{
36
if (argc
!=
2)
37
{
38
_tprintf(_T("Usage: SignedFileInfo <filename>\n"));
39
return
0;
40
}
41
#ifdef UNICODE
42
lstrcpynW(szFileName, argv[1], MAX_PATH);
43
#else
44
if (mbstowcs(szFileName, argv[1], MAX_PATH)
==
-1)
45
{
46
printf("Unable to convert to unicode.\n");
47
__leave;
48
}
49
#endif
50
// Get message handle and store handle from the signed file.
51
fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
52
szFileName,
53
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
54
CERT_QUERY_FORMAT_FLAG_BINARY,
55
0,
56
&dwEncoding,
57
&dwContentType,
58
&dwFormatType,
59
&hStore,
60
&hMsg,
61
NULL);
62
if (!fResult)
63
{
64
_tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError());
65
__leave;
66
}
67
// Get signer information size.
68
fResult = CryptMsgGetParam(hMsg,
69
CMSG_SIGNER_INFO_PARAM,
70
0,
71
NULL,
72
&dwSignerInfo);
73
if (!fResult)
74
{
75
_tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
76
__leave;
77
}
78
// Allocate memory for signer information.
79
pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
80
if (!pSignerInfo)
81
{
82
_tprintf(_T("Unable to allocate memory for Signer Info.\n"));
83
__leave;
84
}
85
// Get Signer Information.
86
fResult = CryptMsgGetParam(hMsg,
87
CMSG_SIGNER_INFO_PARAM,
88
0,
89
(PVOID)pSignerInfo,
90
&dwSignerInfo);
91
if (!fResult)
92
{
93
_tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
94
__leave;
95
}
96
// Get program name and publisher information from
97
// signer info structure.
98
if (GetProgAndPublisherInfo(pSignerInfo,
&ProgPubInfo))
99
{
100
if (ProgPubInfo.lpszProgramName
!= NULL)
101
{
102
wprintf(L"Program Name : %s\n",
103
ProgPubInfo.lpszProgramName);
104
}
105
if (ProgPubInfo.lpszPublisherLink
!= NULL)
106
{
107
wprintf(L"Publisher Link : %s\n",
108
ProgPubInfo.lpszPublisherLink);
109
}
110
if (ProgPubInfo.lpszMoreInfoLink
!= NULL)
111
{
112
wprintf(L"MoreInfo Link : %s\n",
113
ProgPubInfo.lpszMoreInfoLink);
114
}
115
}
116
_tprintf(_T("\n"));
117
// Search for the signer certificate in the temporary
118
// certificate store.
119
CertInfo.Issuer = pSignerInfo->Issuer;
120
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
121
pCertContext = CertFindCertificateInStore(hStore,
122
ENCODING,
123
0,
124
CERT_FIND_SUBJECT_CERT,
125
(PVOID)&CertInfo,
126
NULL);
127
if (!pCertContext)
128
{
129
_tprintf(_T("CertFindCertificateInStore failed with %x\n"),
130
GetLastError());
131
__leave;
132
}
133
// Print Signer certificate information.
134
_tprintf(_T("Signer Certificate:\n\n"));
135
PrintCertificateInfo(pCertContext);
136
_tprintf(_T("\n"));
137
// Get the timestamp certificate signerinfo structure.
138
if (GetTimeStampSignerInfo(pSignerInfo,
&pCounterSignerInfo))
139
{
140
// Search for Timestamp certificate in the temporary
141
// certificate store.
142
CertInfo.Issuer = pCounterSignerInfo->Issuer;
143
CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber;
144
pCertContext = CertFindCertificateInStore(hStore,
145
ENCODING,
146
0,
147
CERT_FIND_SUBJECT_CERT,
148
(PVOID)&CertInfo,
149
NULL);
150
if (!pCertContext)
151
{
152
_tprintf(_T("CertFindCertificateInStore failed with %x\n"),
153
GetLastError());
154
__leave;
155
}
156
// Print timestamp certificate information.
157
_tprintf(_T("TimeStamp Certificate:\n\n"));
158
PrintCertificateInfo(pCertContext);
159
_tprintf(_T("\n"));
160
// Find Date of timestamp.
161
if (GetDateOfTimeStamp(pCounterSignerInfo,
&st))
162
{
163
_tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"),
164
st.wMonth,
165
st.wDay,
166
st.wYear,
167
st.wHour,
168
st.wMinute);
169
}
170
_tprintf(_T("\n"));
171
}
172
}
173
__finally
174
{
175
// Clean up.
176
if (ProgPubInfo.lpszProgramName
!= NULL)
177
LocalFree(ProgPubInfo.lpszProgramName);
178
if (ProgPubInfo.lpszPublisherLink
!= NULL)
179
LocalFree(ProgPubInfo.lpszPublisherLink);
180
if (ProgPubInfo.lpszMoreInfoLink
!= NULL)
181
LocalFree(ProgPubInfo.lpszMoreInfoLink);
182
if (pSignerInfo
!= NULL) LocalFree(pSignerInfo);
183
if (pCounterSignerInfo
!= NULL) LocalFree(pCounterSignerInfo);
184
if (pCertContext
!= NULL) CertFreeCertificateContext(pCertContext);
185
if (hStore
!= NULL) CertCloseStore(hStore,
0);
186
if (hMsg
!= NULL) CryptMsgClose(hMsg);
187
}
188
return
0;
189
}
190
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
191
{
192
BOOL fReturn = FALSE;
193
LPTSTR szName = NULL;
194
DWORD dwData;
195
__try
196
{
197
// Print Serial Number.
198
_tprintf(_T("Serial Number:
"));
199
dwData = pCertContext->pCertInfo->SerialNumber.cbData;
200
for (DWORD n
=
0; n
< dwData; n++)
201
{
202
_tprintf(_T("%02x
"),
203
pCertContext->pCertInfo->SerialNumber.pbData[dwData
- (n
+ 1)]);
204
}
205
_tprintf(_T("\n"));
206
// Get Issuer name size.
207
if (!(dwData
= CertGetNameString(pCertContext,
208
CERT_NAME_SIMPLE_DISPLAY_TYPE,
209
CERT_NAME_ISSUER_FLAG,
210
NULL,
211
NULL,
212
0)))
213
{
214
_tprintf(_T("CertGetNameString failed.\n"));
215
__leave;
216
}
217
// Allocate memory for Issuer name.
218
szName = (LPTSTR)LocalAlloc(LPTR, dwData
*
sizeof(TCHAR));
219
if (!szName)
220
{
221
_tprintf(_T("Unable to allocate memory for issuer name.\n"));
222
__leave;
223
}
224
// Get Issuer name.
225
if (!(CertGetNameString(pCertContext,
226
CERT_NAME_SIMPLE_DISPLAY_TYPE,
227
CERT_NAME_ISSUER_FLAG,
228
NULL,
229
szName,
230
dwData)))
231
{
232
_tprintf(_T("CertGetNameString failed.\n"));
233
__leave;
234
}
235
// print Issuer name.
236
_tprintf(_T("Issuer Name: %s\n"), szName);
237
LocalFree(szName);
238
szName = NULL;
239
// Get Subject name size.
240
if (!(dwData
= CertGetNameString(pCertContext,
241
CERT_NAME_SIMPLE_DISPLAY_TYPE,
242
0,
243
NULL,
244
NULL,
245
0)))
246
{
247
_tprintf(_T("CertGetNameString failed.\n"));
248
__leave;
249
}
250
// Allocate memory for subject name.
251
szName = (LPTSTR)LocalAlloc(LPTR, dwData
*
sizeof(TCHAR));
252
if (!szName)
253
{
254
_tprintf(_T("Unable to allocate memory for subject name.\n"));
255
__leave;
256
}
257
// Get subject name.
258
if (!(CertGetNameString(pCertContext,
259
CERT_NAME_SIMPLE_DISPLAY_TYPE,
260
0,
261
NULL,
262
szName,
263
dwData)))
264
{
265
_tprintf(_T("CertGetNameString failed.\n"));
266
__leave;
267
}
268
// Print Subject Name.
269
_tprintf(_T("Subject Name: %s\n"), szName);
270
fReturn = TRUE;
271
}
272
__finally
273
{
274
if (szName
!= NULL) LocalFree(szName);
275
}
276
return fReturn;
277
}
278
LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
279
{
280
LPWSTR outputString = NULL;
281
outputString = (LPWSTR)LocalAlloc(LPTR,
282
(wcslen(inputString) +
1)
*
sizeof(WCHAR));
283
if (outputString
!= NULL)
284
{
285
lstrcpyW(outputString, inputString);
286
}
287
return outputString;
288
}
289
BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
290
PSPROG_PUBLISHERINFO Info)
291
{
292
BOOL fReturn = FALSE;
293
PSPC_SP_OPUS_INFO OpusInfo = NULL;
294
DWORD dwData;
295
BOOL fResult;
296
__try
297
{
298
// Loop through authenticated attributes and find
299
// SPC_SP_OPUS_INFO_OBJID OID.
300
for (DWORD n
=
0; n
< pSignerInfo->AuthAttrs.cAttr; n++)
301
{
302
if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID,
303
pSignerInfo->AuthAttrs.rgAttr
.pszObjId)
==
0)
304
{
305
// Get Size of SPC_SP_OPUS_INFO structure.
306
fResult = CryptDecodeObject(ENCODING,
307
SPC_SP_OPUS_INFO_OBJID,
308
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
309
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
310
0,
311
NULL,
312
&dwData);
313
if (!fResult)
314
{
315
_tprintf(_T("CryptDecodeObject failed with %x\n"),
316
GetLastError());
317
__leave;
318
}
319
// Allocate memory for SPC_SP_OPUS_INFO structure.
320
OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData);
321
if (!OpusInfo)
322
{
323
_tprintf(_T("Unable to allocate memory for Publisher Info.\n"));
324
__leave;
325
}
326
// Decode and get SPC_SP_OPUS_INFO structure.
327
fResult = CryptDecodeObject(ENCODING,
328
SPC_SP_OPUS_INFO_OBJID,
329
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
330
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
331
0,
332
OpusInfo,
333
&dwData);
334
if (!fResult)
335
{
336
_tprintf(_T("CryptDecodeObject failed with %x\n"),
337
GetLastError());
338
__leave;
339
}
340
// Fill in Program Name if present.
341
if (OpusInfo->pwszProgramName)
342
{
343
Info->lpszProgramName
=
344
AllocateAndCopyWideString(OpusInfo->pwszProgramName);
345
}
346
else
347
Info->lpszProgramName
= NULL;
348
// Fill in Publisher Information if present.
349
if (OpusInfo->pPublisherInfo)
350
{
351
switch (OpusInfo->pPublisherInfo->dwLinkChoice)
352
{
353
case SPC_URL_LINK_CHOICE:
354
Info->lpszPublisherLink
=
355
AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);
356
break;
357
case SPC_FILE_LINK_CHOICE:
358
Info->lpszPublisherLink
=
359
AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);
360
break;
361
default:
362
Info->lpszPublisherLink
= NULL;
363
break;
364
}
365
}
366
else
367
{
368
Info->lpszPublisherLink
= NULL;
369
}
370
// Fill in More Info if present.
371
if (OpusInfo->pMoreInfo)
372
{
373
switch (OpusInfo->pMoreInfo->dwLinkChoice)
374
{
375
case SPC_URL_LINK_CHOICE:
376
Info->lpszMoreInfoLink
=
377
AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);
378
break;
379
case SPC_FILE_LINK_CHOICE:
380
Info->lpszMoreInfoLink
=
381
AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);
382
break;
383
default:
384
Info->lpszMoreInfoLink
= NULL;
385
break;
386
}
387
}
388
else
389
{
390
Info->lpszMoreInfoLink
= NULL;
391
}
392
fReturn = TRUE;
393
break;
// Break from for loop.
394
} // lstrcmp SPC_SP_OPUS_INFO_OBJID
395
} // for
396
}
397
__finally
398
{
399
if (OpusInfo
!= NULL) LocalFree(OpusInfo);
400
}
401
return fReturn;
402
}
403
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st)
404
{
405
BOOL fResult;
406
FILETIME lft, ft;
407
DWORD dwData;
408
BOOL fReturn = FALSE;
409
// Loop through authenticated attributes and find
410
// szOID_RSA_signingTime OID.
411
for (DWORD n
=
0; n
< pSignerInfo->AuthAttrs.cAttr; n++)
412
{
413
if (lstrcmpA(szOID_RSA_signingTime,
414
pSignerInfo->AuthAttrs.rgAttr
.pszObjId)
==
0)
415
{
416
// Decode and get FILETIME structure.
417
dwData =
sizeof(ft);
418
fResult = CryptDecodeObject(ENCODING,
419
szOID_RSA_signingTime,
420
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].pbData,
421
pSignerInfo->AuthAttrs.rgAttr
.rgValue[0].cbData,
422
0,
423
(PVOID)&ft,
424
&dwData);
425
if (!fResult)
426
{
427
_tprintf(_T("CryptDecodeObject failed with %x\n"),
428
GetLastError());
429
break;
430
}
431
// Convert to local time.
432
FileTimeToLocalFileTime(&ft,
&lft);
433
FileTimeToSystemTime(&lft, st);
434
fReturn = TRUE;
435
break;
// Break from for loop.
436
} //lstrcmp szOID_RSA_signingTime
437
} // for
438
return fReturn;
439
}
440
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO
*pCounterSignerInfo)
441
{
442
PCCERT_CONTEXT pCertContext = NULL;
443
BOOL fReturn = FALSE;
444
BOOL fResult;
445
DWORD dwSize;
446
__try
447
{
448
*pCounterSignerInfo
= NULL;
449
// Loop through unathenticated attributes for
450
// szOID_RSA_counterSign OID.
451
for (DWORD n
=
0; n
< pSignerInfo->UnauthAttrs.cAttr; n++)
452
{
453
if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr
.pszObjId,
454
szOID_RSA_counterSign) ==
0)
455
{
456
// Get size of CMSG_SIGNER_INFO structure.
457
fResult = CryptDecodeObject(ENCODING,
458
PKCS7_SIGNER_INFO,
459
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].pbData,
460
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].cbData,
461
0,
462
NULL,
463
&dwSize);
464
if (!fResult)
465
{
466
_tprintf(_T("CryptDecodeObject failed with %x\n"),
467
GetLastError());
468
__leave;
469
}
470
// Allocate memory for CMSG_SIGNER_INFO.
471
*pCounterSignerInfo
= (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);
472
if (!*pCounterSignerInfo)
473
{
474
_tprintf(_T("Unable to allocate memory for timestamp info.\n"));
475
__leave;
476
}
477
// Decode and get CMSG_SIGNER_INFO structure
478
// for timestamp certificate.
479
fResult = CryptDecodeObject(ENCODING,
480
PKCS7_SIGNER_INFO,
481
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].pbData,
482
pSignerInfo->UnauthAttrs.rgAttr
.rgValue[0].cbData,
483
0,
484
(PVOID)*pCounterSignerInfo,
485
&dwSize);
486
if (!fResult)
487
{
488
_tprintf(_T("CryptDecodeObject failed with %x\n"),
489
GetLastError());
490
__leave;
491
}
492
fReturn = TRUE;
493
break;
// Break from for loop.
494
}
495
}
496
}
497
__finally
498
{
499
// Clean up.
500
if (pCertContext
!= NULL) CertFreeCertificateContext(pCertContext);
501
}
502
return fReturn;
503
}
相关文章推荐
- 判断PE文件的数字签名信息
- 判断PE文件的数字签名信息
- 判断PE文件的数字签名信息
- PE文件数字签名信息读取存储及格式具体解释图之上(历史代码,贴出学习)
- 手动添加PE文件数字签名信息及格式详解图之下(历史代码,贴出学习)
- 手动加入PE文件数字签名信息及格式具体解释图之下(历史代码,贴出学习)
- C# 获取文件的数字签名信息
- PE文件数字签名工具
- 获取文件数字签名证书信息
- PE文件数字签名格式
- 文件数字签名校验与信息获取
- Windows平台 PE文件数字签名格式
- 给PE文件添加数字签名的VC6代码
- 获取文件数字签名证书信息
- 为PE文件添加数字签名
- 获取文件数字签名证书信息
- C# 获取文件的数字签名信息
- delphi数字签名验证及能够获取数字签名文件信息(利用wintrust.dll的导出函数,翻译一下)
- 为PE文件添加数字签名 .
- 为PE文件添加数字签名