Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

985 lines
32 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: sigprov.cpp
  8. //
  9. // Contents: Microsoft Internet Security Authenticode Policy Provider
  10. //
  11. // Functions: SoftpubLoadSignature
  12. //
  13. // *** local functions ***
  14. // _ExtractSigner
  15. // _ExtractCounterSigners
  16. // _HandleCertChoice
  17. // _HandleSignerChoice
  18. // _FindCertificate
  19. // _FindCounterSignersCert
  20. // _IsValidTimeStampCert
  21. //
  22. // History: 05-Jun-1997 pberkman created
  23. //
  24. //--------------------------------------------------------------------------
  25. #include "global.hxx"
  26. BOOL _ExtractSigner(HCRYPTMSG hMsg, CRYPT_PROVIDER_DATA *pProvData,
  27. int idxSigner);
  28. BOOL _ExtractCounterSigners(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner);
  29. HRESULT _HandleCertChoice(CRYPT_PROVIDER_DATA *pProvData);
  30. HRESULT _HandleSignerChoice(CRYPT_PROVIDER_DATA *pProvData);
  31. PCCERT_CONTEXT _FindCertificate(CRYPT_PROVIDER_DATA *pProvData, CERT_INFO *pCert);
  32. PCCERT_CONTEXT _FindCounterSignersCert(CRYPT_PROVIDER_DATA *pProvData,
  33. CERT_NAME_BLOB *psIssuer,
  34. CRYPT_INTEGER_BLOB *psSerial);
  35. BOOL WINAPI _IsValidTimeStampCert(
  36. PCCERT_CONTEXT pCertContext,
  37. BOOL *pfVerisignTimeStampCert
  38. );
  39. #ifdef CMS_PKCS7
  40. BOOL _VerifyMessageSignatureWithChainPubKeyParaInheritance(
  41. IN CRYPT_PROVIDER_DATA *pProvData,
  42. IN DWORD dwSignerIndex,
  43. IN PCCERT_CONTEXT pSigner
  44. );
  45. BOOL _VerifyCountersignatureWithChainPubKeyParaInheritance(
  46. IN CRYPT_PROVIDER_DATA *pProvData,
  47. IN PBYTE pbSignerInfo,
  48. IN DWORD cbSignerInfo,
  49. IN PBYTE pbSignerInfoCountersignature,
  50. IN DWORD cbSignerInfoCountersignature,
  51. IN PCCERT_CONTEXT pSigner
  52. );
  53. #endif // CMS_PKCS7
  54. HRESULT SoftpubLoadSignature(CRYPT_PROVIDER_DATA *pProvData)
  55. {
  56. if (!(pProvData->padwTrustStepErrors) ||
  57. (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS) ||
  58. (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != ERROR_SUCCESS))
  59. {
  60. return(S_FALSE);
  61. }
  62. switch (pProvData->pWintrustData->dwUnionChoice)
  63. {
  64. case WTD_CHOICE_CERT:
  65. return(_HandleCertChoice(pProvData));
  66. case WTD_CHOICE_SIGNER:
  67. return(_HandleSignerChoice(pProvData));
  68. case WTD_CHOICE_FILE:
  69. case WTD_CHOICE_CATALOG:
  70. case WTD_CHOICE_BLOB:
  71. break;
  72. default:
  73. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  74. return(S_FALSE);
  75. }
  76. if (!(pProvData->hMsg))
  77. {
  78. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  79. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERCOUNT] = GetLastError();
  80. return(S_FALSE);
  81. }
  82. if ((_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) &&
  83. (pProvData->fRecallWithState))
  84. {
  85. return(S_OK);
  86. }
  87. int i;
  88. DWORD cbSize;
  89. DWORD csSigners;
  90. CRYPT_PROVIDER_SGNR *pSgnr;
  91. CRYPT_PROVIDER_SGNR sSgnr;
  92. CRYPT_PROVIDER_CERT *pCert;
  93. cbSize = sizeof(DWORD);
  94. // signer count
  95. if (!(CryptMsgGetParam(pProvData->hMsg,
  96. CMSG_SIGNER_COUNT_PARAM,
  97. 0,
  98. &csSigners,
  99. &cbSize)))
  100. {
  101. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  102. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERCOUNT] = GetLastError();
  103. return(S_FALSE);
  104. }
  105. if (csSigners == 0)
  106. {
  107. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  108. return(S_FALSE);
  109. }
  110. for (i = 0; i < (int)csSigners; i++)
  111. {
  112. memset(&sSgnr, 0x00, sizeof(CRYPT_PROVIDER_SGNR));
  113. sSgnr.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
  114. if (!(pProvData->psPfns->pfnAddSgnr2Chain(pProvData, FALSE, i, &sSgnr)))
  115. {
  116. pProvData->dwError = GetLastError();
  117. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  118. return(S_FALSE);
  119. }
  120. pSgnr = WTHelperGetProvSignerFromChain(pProvData, i, FALSE, 0);
  121. if (_ExtractSigner(pProvData->hMsg, pProvData, i))
  122. {
  123. memcpy(&pSgnr->sftVerifyAsOf, &pProvData->sftSystemTime, sizeof(FILETIME));
  124. _ExtractCounterSigners(pProvData, i);
  125. }
  126. }
  127. //
  128. // verify the integrity of the signature(s)
  129. //
  130. for (i = 0; i < (int)pProvData->csSigners; i++)
  131. {
  132. pSgnr = WTHelperGetProvSignerFromChain(pProvData, i, FALSE, 0);
  133. pCert = WTHelperGetProvCertFromChain(pSgnr, 0);
  134. if (pSgnr->csCertChain > 0)
  135. {
  136. #ifdef CMS_PKCS7
  137. if(!_VerifyMessageSignatureWithChainPubKeyParaInheritance(
  138. pProvData,
  139. i,
  140. pCert->pCert))
  141. #else
  142. if (!(CryptMsgControl(pProvData->hMsg,
  143. 0,
  144. CMSG_CTRL_VERIFY_SIGNATURE,
  145. pCert->pCert->pCertInfo)))
  146. #endif // CMS_PKCS7
  147. {
  148. if (pSgnr->dwError == 0)
  149. {
  150. pSgnr->dwError = GetLastError();
  151. }
  152. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  153. return(S_FALSE);
  154. }
  155. }
  156. }
  157. return(S_OK);
  158. }
  159. HRESULT _HandleCertChoice(CRYPT_PROVIDER_DATA *pProvData)
  160. {
  161. if (!(pProvData->pWintrustData->pCert) ||
  162. !(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(WINTRUST_CERT_INFO,
  163. pProvData->pWintrustData->pCert->cbStruct,
  164. pahStores)) ||
  165. !(pProvData->pWintrustData->pCert->psCertContext))
  166. {
  167. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = ERROR_INVALID_PARAMETER;
  168. return(S_FALSE);
  169. }
  170. //
  171. // add the stores passed in by the client
  172. //
  173. for (int i = 0; i < (int)pProvData->pWintrustData->pCert->chStores; i++)
  174. {
  175. if (!(pProvData->psPfns->pfnAddStore2Chain(pProvData,
  176. pProvData->pWintrustData->pCert->pahStores[i])))
  177. {
  178. pProvData->dwError = GetLastError();
  179. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  180. return(S_FALSE);
  181. }
  182. }
  183. //
  184. // add a dummy signer
  185. //
  186. CRYPT_PROVIDER_SGNR sSgnr;
  187. memset(&sSgnr, 0x00, sizeof(CRYPT_PROVIDER_SGNR));
  188. sSgnr.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
  189. memcpy(&sSgnr.sftVerifyAsOf, &pProvData->sftSystemTime, sizeof(FILETIME));
  190. if ((_ISINSTRUCT(WINTRUST_CERT_INFO, pProvData->pWintrustData->pCert->cbStruct, psftVerifyAsOf)) &&
  191. (pProvData->pWintrustData->pCert->psftVerifyAsOf))
  192. {
  193. memcpy(&sSgnr.sftVerifyAsOf, pProvData->pWintrustData->pCert->psftVerifyAsOf, sizeof(FILETIME));
  194. }
  195. if (!(pProvData->psPfns->pfnAddSgnr2Chain(pProvData, FALSE, 0, &sSgnr)))
  196. {
  197. pProvData->dwError = GetLastError();
  198. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  199. return(S_FALSE);
  200. }
  201. //
  202. // add the "signer's" cert...
  203. //
  204. pProvData->psPfns->pfnAddCert2Chain(pProvData, 0, FALSE, 0,
  205. pProvData->pWintrustData->pCert->psCertContext);
  206. return(ERROR_SUCCESS);
  207. }
  208. HRESULT _HandleSignerChoice(CRYPT_PROVIDER_DATA *pProvData)
  209. {
  210. if (!(pProvData->pWintrustData->pSgnr) ||
  211. !(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(WINTRUST_SGNR_INFO,
  212. pProvData->pWintrustData->pSgnr->cbStruct,
  213. pahStores)) ||
  214. !(pProvData->pWintrustData->pSgnr->psSignerInfo))
  215. {
  216. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = ERROR_INVALID_PARAMETER;
  217. return(S_FALSE);
  218. }
  219. int i;
  220. if (1 < pProvData->pWintrustData->pCert->chStores &&
  221. 0 == pProvData->chStores)
  222. WTHelperOpenKnownStores(pProvData);
  223. //
  224. // add the stores passed in by the client
  225. //
  226. for (i = 0; i < (int)pProvData->pWintrustData->pCert->chStores; i++)
  227. {
  228. if (!(pProvData->psPfns->pfnAddStore2Chain(pProvData,
  229. pProvData->pWintrustData->pCert->pahStores[i])))
  230. {
  231. pProvData->dwError = GetLastError();
  232. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  233. return(S_FALSE);
  234. }
  235. }
  236. CRYPT_PROVIDER_SGNR sSgnr;
  237. CRYPT_PROVIDER_SGNR *pSgnr;
  238. memset(&sSgnr, 0x00, sizeof(CRYPT_PROVIDER_SGNR));
  239. sSgnr.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
  240. if (!(sSgnr.psSigner = (CMSG_SIGNER_INFO *)pProvData->psPfns->pfnAlloc(sizeof(CMSG_SIGNER_INFO))))
  241. {
  242. pProvData->dwError = GetLastError();
  243. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  244. return(S_FALSE);
  245. }
  246. memcpy(sSgnr.psSigner, pProvData->pWintrustData->pSgnr->psSignerInfo,
  247. sizeof(CMSG_SIGNER_INFO));
  248. memcpy(&sSgnr.sftVerifyAsOf, &pProvData->sftSystemTime, sizeof(FILETIME));
  249. if (!(pProvData->psPfns->pfnAddSgnr2Chain(pProvData, FALSE, 0, &sSgnr)))
  250. {
  251. pProvData->psPfns->pfnFree(sSgnr.psSigner);
  252. pProvData->dwError = GetLastError();
  253. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  254. return(S_FALSE);
  255. }
  256. if (!(pSgnr = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0)))
  257. {
  258. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = GetLastError();
  259. return(S_FALSE);
  260. }
  261. CERT_INFO sCert;
  262. PCCERT_CONTEXT pCertContext;
  263. memset(&sCert, 0x00, sizeof(CERT_INFO));
  264. sCert.Issuer.cbData = pSgnr->psSigner->Issuer.cbData;
  265. sCert.Issuer.pbData = pSgnr->psSigner->Issuer.pbData;
  266. sCert.SerialNumber.cbData = pSgnr->psSigner->SerialNumber.cbData;
  267. sCert.SerialNumber.pbData = pSgnr->psSigner->SerialNumber.pbData;
  268. if (!(pCertContext = _FindCertificate(pProvData, &sCert)))
  269. {
  270. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NO_SIGNER_CERT;
  271. return(FALSE);
  272. }
  273. pProvData->psPfns->pfnAddCert2Chain(pProvData, 0, FALSE, 0, pCertContext);
  274. _ExtractCounterSigners(pProvData, 0);
  275. return(ERROR_SUCCESS);
  276. }
  277. BOOL _ExtractSigner(HCRYPTMSG hMsg, CRYPT_PROVIDER_DATA *pProvData, int idxSigner)
  278. {
  279. DWORD cb;
  280. BYTE *pb;
  281. CRYPT_PROVIDER_SGNR *pSgnr;
  282. PCCERT_CONTEXT pCertContext;
  283. pSgnr = WTHelperGetProvSignerFromChain(pProvData, idxSigner, FALSE, 0);
  284. if (pSgnr == NULL)
  285. {
  286. return(FALSE);
  287. }
  288. //
  289. // signer info
  290. //
  291. cb = 0;
  292. CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, idxSigner, NULL, &cb);
  293. if (cb == 0)
  294. {
  295. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  296. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERINFO] = GetLastError();
  297. return(FALSE);
  298. }
  299. if (!(pSgnr->psSigner = (CMSG_SIGNER_INFO *)pProvData->psPfns->pfnAlloc(cb)))
  300. {
  301. pProvData->dwError = GetLastError();
  302. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  303. return(FALSE);
  304. }
  305. memset(pSgnr->psSigner, 0x00, cb);
  306. if (!(CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, idxSigner, pSgnr->psSigner, &cb)))
  307. {
  308. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NOSIGNATURE;
  309. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERINFO] = GetLastError();
  310. return(FALSE);
  311. }
  312. //
  313. // cert info
  314. //
  315. cb = 0;
  316. CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, idxSigner, NULL, &cb);
  317. if (cb == 0)
  318. {
  319. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NO_SIGNER_CERT;
  320. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERINFO] = GetLastError();
  321. return(FALSE);
  322. }
  323. if (!(pb = (BYTE *)pProvData->psPfns->pfnAlloc(cb)))
  324. {
  325. pProvData->dwError = GetLastError();
  326. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  327. return(FALSE);
  328. }
  329. memset(pb, 0x00, cb);
  330. if (!(CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, idxSigner, pb, &cb)))
  331. {
  332. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NO_SIGNER_CERT;
  333. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_SIGNERINFO] = GetLastError();
  334. pProvData->psPfns->pfnFree(pb);
  335. return(FALSE);
  336. }
  337. if (!(pCertContext = _FindCertificate(pProvData, (CERT_INFO *)pb)))
  338. {
  339. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_NO_SIGNER_CERT;
  340. pProvData->psPfns->pfnFree(pb);
  341. return(FALSE);
  342. }
  343. pProvData->psPfns->pfnFree(pb);
  344. pProvData->psPfns->pfnAddCert2Chain(pProvData, idxSigner, FALSE, 0, pCertContext);
  345. CertFreeCertificateContext(pCertContext);
  346. return(TRUE);
  347. }
  348. BOOL _ExtractCounterSigners(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner)
  349. {
  350. if ((_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) &&
  351. (pProvData->fRecallWithState))
  352. {
  353. return(TRUE);
  354. }
  355. CRYPT_ATTRIBUTE *pAttr;
  356. PCCERT_CONTEXT pCertContext;
  357. CRYPT_PROVIDER_SGNR *pSgnr;
  358. CRYPT_PROVIDER_SGNR sCS;
  359. CRYPT_PROVIDER_SGNR *pCS;
  360. CRYPT_PROVIDER_CERT *pCert;
  361. DWORD cbSize;
  362. BOOL fVerisignTimeStampCert = FALSE;
  363. pSgnr = WTHelperGetProvSignerFromChain(pProvData, idxSigner, FALSE, 0);
  364. if (pSgnr == NULL)
  365. {
  366. return(FALSE);
  367. }
  368. //
  369. // counter signers are stored in the UN-authenticated attributes of the
  370. // signer.
  371. //
  372. if ((pAttr = CertFindAttribute(szOID_RSA_counterSign,
  373. pSgnr->psSigner->UnauthAttrs.cAttr,
  374. pSgnr->psSigner->UnauthAttrs.rgAttr)) == NULL)
  375. {
  376. //
  377. // no counter signature
  378. //
  379. return(FALSE);
  380. }
  381. memset(&sCS, 0x00, sizeof(CRYPT_PROVIDER_SGNR));
  382. sCS.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
  383. memcpy(&sCS.sftVerifyAsOf, &pProvData->sftSystemTime, sizeof(FILETIME));
  384. if (!(pProvData->psPfns->pfnAddSgnr2Chain(pProvData, TRUE, idxSigner, &sCS)))
  385. {
  386. pProvData->dwError = GetLastError();
  387. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_SYSTEM_ERROR;
  388. return(FALSE);
  389. }
  390. pCS = WTHelperGetProvSignerFromChain(pProvData, idxSigner, TRUE, pSgnr->csCounterSigners - 1);
  391. // Crack the encoded signer
  392. if (!(TrustDecode(WVT_MODID_SOFTPUB, (BYTE **)&pCS->psSigner, &cbSize, 1024,
  393. pProvData->dwEncoding, PKCS7_SIGNER_INFO, pAttr->rgValue[0].pbData, pAttr->rgValue[0].cbData,
  394. CRYPT_DECODE_NOCOPY_FLAG)))
  395. {
  396. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_COUNTER_SIGNER;
  397. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_COUNTERSIGINFO] = GetLastError();
  398. pCS->dwError = GetLastError();
  399. return(FALSE);
  400. }
  401. //
  402. // counter signers cert
  403. //
  404. if (!(pCertContext = _FindCounterSignersCert(pProvData,
  405. &pCS->psSigner->Issuer,
  406. &pCS->psSigner->SerialNumber)))
  407. {
  408. pCS->dwError = TRUST_E_NO_SIGNER_CERT;
  409. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_COUNTER_SIGNER;
  410. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_COUNTERSIGCERT] = GetLastError();
  411. return(FALSE);
  412. }
  413. pProvData->psPfns->pfnAddCert2Chain(pProvData, idxSigner, TRUE,
  414. pProvData->pasSigners[idxSigner].csCounterSigners - 1,
  415. pCertContext);
  416. CertFreeCertificateContext(pCertContext);
  417. pCert = WTHelperGetProvCertFromChain(pCS, pCS->csCertChain - 1);
  418. pCertContext = pCert->pCert;
  419. {
  420. //
  421. // Verify the counter's signature
  422. //
  423. BYTE *pbEncodedSigner = NULL;
  424. DWORD cbEncodedSigner;
  425. BOOL fResult;
  426. // First need to re-encode the Signer.
  427. fResult = CryptEncodeObjectEx(
  428. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  429. PKCS7_SIGNER_INFO,
  430. pSgnr->psSigner,
  431. CRYPT_ENCODE_ALLOC_FLAG,
  432. NULL, // pEncodePara
  433. (void *) &pbEncodedSigner,
  434. &cbEncodedSigner
  435. );
  436. if (fResult)
  437. #ifdef CMS_PKCS7
  438. fResult = _VerifyCountersignatureWithChainPubKeyParaInheritance(
  439. pProvData,
  440. pbEncodedSigner,
  441. cbEncodedSigner,
  442. pAttr->rgValue[0].pbData,
  443. pAttr->rgValue[0].cbData,
  444. pCertContext
  445. );
  446. #else
  447. fResult = CryptMsgVerifyCountersignatureEncoded(
  448. NULL, //HCRYPTPROV
  449. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  450. pbEncodedSigner,
  451. cbEncodedSigner,
  452. pAttr->rgValue[0].pbData,
  453. pAttr->rgValue[0].cbData,
  454. pCertContext->pCertInfo
  455. );
  456. #endif // CMS_PKCS7
  457. if (pbEncodedSigner)
  458. LocalFree((HLOCAL) pbEncodedSigner);
  459. if (!fResult)
  460. {
  461. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_COUNTER_SIGNER;
  462. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_COUNTERSIGINFO] = GetLastError();
  463. pCS->dwError = GetLastError();
  464. return(FALSE);
  465. }
  466. }
  467. //
  468. // see if the counter signer is a TimeStamp.
  469. //
  470. if (!(_IsValidTimeStampCert(pCertContext, &fVerisignTimeStampCert)))
  471. {
  472. return(TRUE);
  473. }
  474. // get the time
  475. if (!(pAttr = CertFindAttribute(szOID_RSA_signingTime,
  476. pCS->psSigner->AuthAttrs.cAttr,
  477. pCS->psSigner->AuthAttrs.rgAttr)))
  478. {
  479. //
  480. // not a time stamp...
  481. //
  482. return(TRUE);
  483. }
  484. //
  485. // the time stamp counter signature must have 1 value!
  486. //
  487. if (pAttr->cValue <= 0)
  488. {
  489. //
  490. // not a time stamp...
  491. //
  492. return(TRUE);
  493. }
  494. //
  495. // Crack the time stamp and get the file time.
  496. //
  497. FILETIME ftHold;
  498. cbSize = sizeof(FILETIME);
  499. CryptDecodeObject(pProvData->dwEncoding,
  500. PKCS_UTC_TIME,
  501. pAttr->rgValue[0].pbData,
  502. pAttr->rgValue[0].cbData,
  503. 0,
  504. &ftHold,
  505. &cbSize);
  506. if (cbSize == 0)
  507. {
  508. pCS->dwError = GetLastError();
  509. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = TRUST_E_TIME_STAMP;
  510. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_MSG_COUNTERSIGINFO] = GetLastError();
  511. return(FALSE);
  512. }
  513. //
  514. // set the signer's verify date to the date in the time stamp!
  515. //
  516. memcpy(&pSgnr->sftVerifyAsOf, &ftHold, sizeof(FILETIME));
  517. // On 12-January-99 Keithv gave me the orders to change the
  518. // countersigning to use the current time
  519. //
  520. // On 25-January-99 backed out the above change
  521. //
  522. // On 28-August-99 changed to use the current time for all
  523. // countersigners excluding the first Verisign Time Stamp
  524. // certificate
  525. //
  526. // On 12-January-00 added a second Verisign Time Stamp cert to exclude
  527. //
  528. // On 05-April-01 changed back to W2K semantics. A time stamp chain
  529. // never expires.
  530. //
  531. memcpy(&pCS->sftVerifyAsOf, &ftHold, sizeof(FILETIME));
  532. pCS->dwSignerType |= SGNR_TYPE_TIMESTAMP;
  533. return(TRUE);
  534. }
  535. PCCERT_CONTEXT _FindCertificate(CRYPT_PROVIDER_DATA *pProvData, CERT_INFO *pCert)
  536. {
  537. PCCERT_CONTEXT pCertContext;
  538. DWORD i;
  539. if (!(pCert))
  540. {
  541. return(NULL);
  542. }
  543. for (i = 0; i < pProvData->chStores; i++)
  544. {
  545. if (pCertContext = CertGetSubjectCertificateFromStore(pProvData->pahStores[i],
  546. pProvData->dwEncoding,
  547. pCert))
  548. {
  549. return(pCertContext);
  550. }
  551. }
  552. if (1 >= pProvData->chStores) {
  553. DWORD cOrig = pProvData->chStores;
  554. WTHelperOpenKnownStores(pProvData);
  555. for (i = cOrig; i < pProvData->chStores; i++) {
  556. if (pCertContext = CertGetSubjectCertificateFromStore(
  557. pProvData->pahStores[i],
  558. pProvData->dwEncoding,
  559. pCert))
  560. return (pCertContext);
  561. }
  562. }
  563. return(NULL);
  564. }
  565. PCCERT_CONTEXT _FindCounterSignersCert(CRYPT_PROVIDER_DATA *pProvData,
  566. CERT_NAME_BLOB *psIssuer,
  567. CRYPT_INTEGER_BLOB *psSerial)
  568. {
  569. CERT_INFO sCert;
  570. PCCERT_CONTEXT pCertContext;
  571. DWORD i;
  572. memset(&sCert, 0x00, sizeof(CERT_INFO));
  573. sCert.Issuer = *psIssuer;
  574. sCert.SerialNumber = *psSerial;
  575. for (i = 0; i < pProvData->chStores; i++)
  576. {
  577. if (pCertContext = CertGetSubjectCertificateFromStore(pProvData->pahStores[i],
  578. pProvData->dwEncoding,
  579. &sCert))
  580. {
  581. return(pCertContext);
  582. }
  583. }
  584. if (1 >= pProvData->chStores) {
  585. DWORD cOrig = pProvData->chStores;
  586. WTHelperOpenKnownStores(pProvData);
  587. for (i = cOrig; i < pProvData->chStores; i++) {
  588. if (pCertContext = CertGetSubjectCertificateFromStore(
  589. pProvData->pahStores[i],
  590. pProvData->dwEncoding,
  591. &sCert))
  592. return (pCertContext);
  593. }
  594. }
  595. return(NULL);
  596. }
  597. #define SH1_HASH_LENGTH 20
  598. BOOL WINAPI _IsValidTimeStampCert(
  599. PCCERT_CONTEXT pCertContext,
  600. BOOL *pfVerisignTimeStampCert
  601. )
  602. {
  603. DWORD cbSize;
  604. PCERT_ENHKEY_USAGE pCertEKU;
  605. BYTE baSignersThumbPrint[SH1_HASH_LENGTH];
  606. static BYTE baVerisignTimeStampThumbPrint[SH1_HASH_LENGTH] =
  607. { 0x38, 0x73, 0xB6, 0x99, 0xF3, 0x5B, 0x9C, 0xCC, 0x36, 0x62,
  608. 0xB6, 0x48, 0x3A, 0x96, 0xBD, 0x6E, 0xEC, 0x97, 0xCF, 0xB7 };
  609. static BYTE baVerisignTimeStampThumbPrint2[SH1_HASH_LENGTH] = {
  610. 0x9A, 0x3F, 0xF0, 0x5B, 0x42, 0x88, 0x52, 0x64,
  611. 0x84, 0xA9, 0xFC, 0xB8, 0xBC, 0x14, 0x7D, 0x53,
  612. 0xE1, 0x5A, 0x43, 0xBB
  613. };
  614. cbSize = SH1_HASH_LENGTH;
  615. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID,
  616. &baSignersThumbPrint[0], &cbSize)))
  617. {
  618. return(FALSE);
  619. }
  620. //
  621. // 1st, check to see if it's Verisign's first timestamp certificate. This one did NOT
  622. // have the enhanced key usage in it.
  623. //
  624. // 12-January-00
  625. // Also, check for the second Verisign timestamp certificate. Its only
  626. // valid for 5 years. Will grandfather in to be valid forever.
  627. //
  628. if (memcmp(&baSignersThumbPrint[0], &baVerisignTimeStampThumbPrint[0],
  629. SH1_HASH_LENGTH) == 0
  630. ||
  631. memcmp(&baSignersThumbPrint[0], &baVerisignTimeStampThumbPrint2[0],
  632. SH1_HASH_LENGTH) == 0)
  633. {
  634. *pfVerisignTimeStampCert = TRUE;
  635. return(TRUE);
  636. }
  637. else
  638. {
  639. *pfVerisignTimeStampCert = FALSE;
  640. }
  641. //
  642. // see if the certificate has the proper enhanced key usage OID
  643. //
  644. cbSize = 0;
  645. CertGetEnhancedKeyUsage(pCertContext,
  646. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  647. NULL,
  648. &cbSize);
  649. if (cbSize == 0)
  650. {
  651. return(FALSE);
  652. }
  653. if (!(pCertEKU = (PCERT_ENHKEY_USAGE)new BYTE[cbSize]))
  654. {
  655. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  656. return(FALSE);
  657. }
  658. if (!(CertGetEnhancedKeyUsage(pCertContext,
  659. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  660. pCertEKU,
  661. &cbSize)))
  662. {
  663. delete pCertEKU;
  664. return(FALSE);
  665. }
  666. for (int i = 0; i < (int)pCertEKU->cUsageIdentifier; i++)
  667. {
  668. if (strcmp(pCertEKU->rgpszUsageIdentifier[i], szOID_KP_TIME_STAMP_SIGNING) == 0)
  669. {
  670. delete pCertEKU;
  671. return(TRUE);
  672. }
  673. if (strcmp(pCertEKU->rgpszUsageIdentifier[i], szOID_PKIX_KP_TIMESTAMP_SIGNING) == 0)
  674. {
  675. delete pCertEKU;
  676. return(TRUE);
  677. }
  678. }
  679. delete pCertEKU;
  680. return(FALSE);
  681. }
  682. #ifdef CMS_PKCS7
  683. void _BuildChainForPubKeyParaInheritance(
  684. IN CRYPT_PROVIDER_DATA *pProvData,
  685. IN PCCERT_CONTEXT pSigner
  686. )
  687. {
  688. PCCERT_CHAIN_CONTEXT pChainContext;
  689. CERT_CHAIN_PARA ChainPara;
  690. HCERTSTORE hAdditionalStore;
  691. if (0 == pProvData->chStores)
  692. hAdditionalStore = NULL;
  693. else if (1 < pProvData->chStores) {
  694. if (hAdditionalStore = CertOpenStore(
  695. CERT_STORE_PROV_COLLECTION,
  696. 0, // dwEncodingType
  697. 0, // hCryptProv
  698. 0, // dwFlags
  699. NULL // pvPara
  700. )) {
  701. DWORD i;
  702. for (i = 0; i < pProvData->chStores; i++)
  703. CertAddStoreToCollection(
  704. hAdditionalStore,
  705. pProvData->pahStores[i],
  706. CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
  707. 0 // dwPriority
  708. );
  709. }
  710. } else
  711. hAdditionalStore = CertDuplicateStore(pProvData->pahStores[0]);
  712. // Build a chain. Hopefully, the signer inherit's its public key
  713. // parameters from up the chain
  714. memset(&ChainPara, 0, sizeof(ChainPara));
  715. ChainPara.cbSize = sizeof(ChainPara);
  716. if (CertGetCertificateChain(
  717. NULL, // hChainEngine
  718. pSigner,
  719. NULL, // pTime
  720. hAdditionalStore,
  721. &ChainPara,
  722. CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL,
  723. NULL, // pvReserved
  724. &pChainContext
  725. ))
  726. CertFreeCertificateChain(pChainContext);
  727. if (hAdditionalStore)
  728. CertCloseStore(hAdditionalStore, 0);
  729. }
  730. //+-------------------------------------------------------------------------
  731. // If the verify signature fails with CRYPT_E_MISSING_PUBKEY_PARA,
  732. // build a certificate chain. Retry. Hopefully, the signer's
  733. // CERT_PUBKEY_ALG_PARA_PROP_ID property gets set while building the chain.
  734. //--------------------------------------------------------------------------
  735. BOOL _VerifyMessageSignatureWithChainPubKeyParaInheritance(
  736. IN CRYPT_PROVIDER_DATA *pProvData,
  737. IN DWORD dwSignerIndex,
  738. IN PCCERT_CONTEXT pSigner
  739. )
  740. {
  741. CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA CtrlPara;
  742. memset(&CtrlPara, 0, sizeof(CtrlPara));
  743. CtrlPara.cbSize = sizeof(CtrlPara);
  744. // CtrlPara.hCryptProv =
  745. CtrlPara.dwSignerIndex = dwSignerIndex;
  746. CtrlPara.dwSignerType = CMSG_VERIFY_SIGNER_CERT;
  747. CtrlPara.pvSigner = (void *) pSigner;
  748. if (CryptMsgControl(
  749. pProvData->hMsg,
  750. 0, // dwFlags
  751. CMSG_CTRL_VERIFY_SIGNATURE_EX,
  752. &CtrlPara
  753. ))
  754. return TRUE;
  755. else if (CRYPT_E_MISSING_PUBKEY_PARA != GetLastError())
  756. return FALSE;
  757. else {
  758. _BuildChainForPubKeyParaInheritance(pProvData, pSigner);
  759. // Try again. Hopefully the above chain building updated the signer's
  760. // context property with the missing public key parameters
  761. return CryptMsgControl(
  762. pProvData->hMsg,
  763. 0, // dwFlags
  764. CMSG_CTRL_VERIFY_SIGNATURE_EX,
  765. &CtrlPara
  766. );
  767. }
  768. }
  769. //+-------------------------------------------------------------------------
  770. // If the verify counter signature fails with CRYPT_E_MISSING_PUBKEY_PARA,
  771. // build a certificate chain. Retry. Hopefully, the signer's
  772. // CERT_PUBKEY_ALG_PARA_PROP_ID property gets set while building the chain.
  773. //--------------------------------------------------------------------------
  774. BOOL _VerifyCountersignatureWithChainPubKeyParaInheritance(
  775. IN CRYPT_PROVIDER_DATA *pProvData,
  776. IN PBYTE pbSignerInfo,
  777. IN DWORD cbSignerInfo,
  778. IN PBYTE pbSignerInfoCountersignature,
  779. IN DWORD cbSignerInfoCountersignature,
  780. IN PCCERT_CONTEXT pSigner
  781. )
  782. {
  783. if (CryptMsgVerifyCountersignatureEncodedEx(
  784. 0, // hCryptProv
  785. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  786. pbSignerInfo,
  787. cbSignerInfo,
  788. pbSignerInfoCountersignature,
  789. cbSignerInfoCountersignature,
  790. CMSG_VERIFY_SIGNER_CERT,
  791. (void *) pSigner,
  792. 0, // dwFlags
  793. NULL // pvReserved
  794. ))
  795. return TRUE;
  796. else if (CRYPT_E_MISSING_PUBKEY_PARA != GetLastError())
  797. return FALSE;
  798. else {
  799. _BuildChainForPubKeyParaInheritance(pProvData, pSigner);
  800. // Try again. Hopefully the above chain building updated the signer's
  801. // context property with the missing public key parameters
  802. return CryptMsgVerifyCountersignatureEncodedEx(
  803. 0, // hCryptProv
  804. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  805. pbSignerInfo,
  806. cbSignerInfo,
  807. pbSignerInfoCountersignature,
  808. cbSignerInfoCountersignature,
  809. CMSG_VERIFY_SIGNER_CERT,
  810. (void *) pSigner,
  811. 0, // dwFlags
  812. NULL // pvReserved
  813. );
  814. }
  815. }
  816. #endif // CMS_PKCS7