您的位置:首页 > 其它

判断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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: