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.

965 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: winvtrst.cpp
  8. //
  9. // Contents: Microsoft Internet Security Trust Provider
  10. //
  11. // Functions: WinVerifyTrustEx
  12. // WinVerifyTrust
  13. // WTHelperGetFileHash
  14. //
  15. // *** local functions ***
  16. // _VerifyTrust
  17. // _FillProviderData
  18. // _CleanupProviderData
  19. // _CleanupProviderNonStateData
  20. // _WVTSipFreeSubjectInfo
  21. // _WVTSipFreeSubjectInfoKeepState
  22. // _WVTSetupProviderData
  23. //
  24. // History: 31-May-1997 pberkman created
  25. //
  26. //--------------------------------------------------------------------------
  27. #include "global.hxx"
  28. #include "wvtver1.h"
  29. #include "softpub.h"
  30. #include "imagehlp.h"
  31. LONG _VerifyTrust(
  32. IN HWND hWnd,
  33. IN GUID *pgActionID,
  34. IN OUT PWINTRUST_DATA pWinTrustData,
  35. OUT OPTIONAL BYTE *pbSubjectHash,
  36. IN OPTIONAL OUT DWORD *pcbSubjectHash,
  37. OUT OPTIONAL ALG_ID *pHashAlgid
  38. );
  39. BOOL _FillProviderData(CRYPT_PROVIDER_DATA *pProvData, HWND hWnd, WINTRUST_DATA *pWinTrustData);
  40. void _CleanupProviderData(CRYPT_PROVIDER_DATA *pProvData);
  41. void _CleanupProviderNonStateData(CRYPT_PROVIDER_DATA *ProvData);
  42. BOOL _WVTSipFreeSubjectInfo(SIP_SUBJECTINFO *pSubj);
  43. BOOL _WVTSetupProviderData(CRYPT_PROVIDER_DATA *psProvData,
  44. CRYPT_PROVIDER_DATA *psStateProvData);
  45. BOOL _WVTSipFreeSubjectInfoKeepState(SIP_SUBJECTINFO *pSubj);
  46. VOID FreeWintrustStateData (WINTRUST_DATA* pWintrustData);
  47. extern CCatalogCache g_CatalogCache;
  48. //////////////////////////////////////////////////////////////////////////////////////
  49. //
  50. // WinVerifyTrustEx
  51. //
  52. //
  53. extern "C" HRESULT WINAPI WinVerifyTrustEx(HWND hWnd, GUID *pgActionID, WINTRUST_DATA *pWinTrustData)
  54. {
  55. return((HRESULT)WinVerifyTrust(hWnd, pgActionID, pWinTrustData));
  56. }
  57. #define PE_EXE_HEADER_TAG "MZ"
  58. #define PE_EXE_HEADER_TAG_LEN 2
  59. BOOL _IsUnsignedPEFile(
  60. PWINTRUST_FILE_INFO pFileInfo
  61. )
  62. {
  63. BOOL fIsUnsignedPEFile = FALSE;
  64. HANDLE hFile = NULL;
  65. BOOL fCloseFile = FALSE;
  66. BYTE rgbHeader[PE_EXE_HEADER_TAG_LEN];
  67. DWORD dwBytesRead;
  68. DWORD dwCertCnt;
  69. hFile = pFileInfo->hFile;
  70. if (NULL == hFile || INVALID_HANDLE_VALUE == hFile) {
  71. hFile = CreateFileU(
  72. pFileInfo->pcwszFilePath,
  73. GENERIC_READ,
  74. FILE_SHARE_READ,
  75. NULL, // lpsa
  76. OPEN_EXISTING,
  77. FILE_ATTRIBUTE_NORMAL,
  78. NULL // hTemplateFile
  79. );
  80. if (INVALID_HANDLE_VALUE == hFile)
  81. goto CreateFileError;
  82. fCloseFile = TRUE;
  83. }
  84. if (0 != SetFilePointer(
  85. hFile,
  86. 0, // lDistanceToMove
  87. NULL, // lpDistanceToMoveHigh
  88. FILE_BEGIN
  89. ))
  90. goto SetFilePointerError;
  91. dwBytesRead = 0;
  92. if (!ReadFile(
  93. hFile,
  94. rgbHeader,
  95. PE_EXE_HEADER_TAG_LEN,
  96. &dwBytesRead,
  97. NULL // lpOverlapped
  98. ) || PE_EXE_HEADER_TAG_LEN != dwBytesRead)
  99. goto ReadFileError;
  100. if (0 != memcmp(rgbHeader, PE_EXE_HEADER_TAG, PE_EXE_HEADER_TAG_LEN))
  101. goto NotPEFile;
  102. // Now see if the PE file is signed
  103. dwCertCnt = 0;
  104. if (!ImageEnumerateCertificates(
  105. hFile,
  106. CERT_SECTION_TYPE_ANY,
  107. &dwCertCnt,
  108. NULL, // Indices
  109. 0 // IndexCount
  110. ) || 0 == dwCertCnt)
  111. fIsUnsignedPEFile = TRUE;
  112. CommonReturn:
  113. if (fCloseFile)
  114. CloseHandle(hFile);
  115. return fIsUnsignedPEFile;
  116. ErrorReturn:
  117. goto CommonReturn;
  118. TRACE_ERROR(CreateFileError)
  119. TRACE_ERROR(SetFilePointerError)
  120. TRACE_ERROR(ReadFileError)
  121. TRACE_ERROR(NotPEFile)
  122. }
  123. extern "C" LONG WINAPI WinVerifyTrust(HWND hWnd, GUID *pgActionID, LPVOID pOld)
  124. {
  125. PWINTRUST_DATA pWinTrustData = (PWINTRUST_DATA) pOld;
  126. // For SAFER, see if this is a unsigned PE file
  127. if (_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwProvFlags) &&
  128. (pWinTrustData->dwProvFlags & WTD_SAFER_FLAG) &&
  129. (WTD_STATEACTION_IGNORE == pWinTrustData->dwStateAction) &&
  130. (WTD_CHOICE_FILE == pWinTrustData->dwUnionChoice)) {
  131. if (_IsUnsignedPEFile(pWinTrustData->pFile)) {
  132. SetLastError((DWORD) TRUST_E_NOSIGNATURE);
  133. return (LONG) TRUST_E_NOSIGNATURE;
  134. }
  135. }
  136. return _VerifyTrust(
  137. hWnd,
  138. pgActionID,
  139. pWinTrustData,
  140. NULL, // pbSubjectHash
  141. NULL, // pcbSubjectHash
  142. NULL // pHashAlgid
  143. );
  144. }
  145. // Returns S_OK and the hash if the file was signed and contains a valid
  146. // hash
  147. extern "C" LONG WINAPI WTHelperGetFileHash(
  148. IN LPCWSTR pwszFilename,
  149. IN DWORD dwFlags,
  150. IN OUT OPTIONAL PVOID *pvReserved,
  151. OUT OPTIONAL BYTE *pbFileHash,
  152. IN OUT OPTIONAL DWORD *pcbFileHash,
  153. OUT OPTIONAL ALG_ID *pHashAlgid
  154. )
  155. {
  156. GUID wvtFileActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  157. WINTRUST_FILE_INFO wvtFileInfo;
  158. WINTRUST_DATA wvtData;
  159. //
  160. // Initialize the _VerifyTrust input data structure
  161. //
  162. memset(&wvtData, 0, sizeof(wvtData)); // default all fields to 0
  163. wvtData.cbStruct = sizeof(wvtData);
  164. // wvtData.pPolicyCallbackData = // use default code signing EKU
  165. // wvtData.pSIPClientData = // no data to pass to SIP
  166. wvtData.dwUIChoice = WTD_UI_NONE;
  167. // wvtData.fdwRevocationChecks = // do revocation checking if
  168. // enabled by admin policy or
  169. // IE advanced user options
  170. wvtData.dwUnionChoice = WTD_CHOICE_FILE;
  171. wvtData.pFile = &wvtFileInfo;
  172. // wvtData.dwStateAction = // default verification
  173. // wvtData.hWVTStateData = // not applicable for default
  174. // wvtData.pwszURLReference = // not used
  175. // Only want to get the hash
  176. wvtData.dwProvFlags = WTD_HASH_ONLY_FLAG;
  177. //
  178. // Initialize the WinVerifyTrust file info data structure
  179. //
  180. memset(&wvtFileInfo, 0, sizeof(wvtFileInfo)); // default all fields to 0
  181. wvtFileInfo.cbStruct = sizeof(wvtFileInfo);
  182. wvtFileInfo.pcwszFilePath = pwszFilename;
  183. // wvtFileInfo.hFile = // allow WVT to open
  184. // wvtFileInfo.pgKnownSubject // allow WVT to determine
  185. //
  186. // Call _VerifyTrust
  187. //
  188. return _VerifyTrust(
  189. NULL, // hWnd
  190. &wvtFileActionID,
  191. &wvtData,
  192. pbFileHash,
  193. pcbFileHash,
  194. pHashAlgid
  195. );
  196. }
  197. LONG _VerifyTrust(
  198. IN HWND hWnd,
  199. IN GUID *pgActionID,
  200. IN OUT PWINTRUST_DATA pWinTrustData,
  201. OUT OPTIONAL BYTE *pbSubjectHash,
  202. IN OPTIONAL OUT DWORD *pcbSubjectHash,
  203. OUT OPTIONAL ALG_ID *pHashAlgid
  204. )
  205. {
  206. CRYPT_PROVIDER_DATA sProvData;
  207. CRYPT_PROVIDER_DATA *pStateProvData;
  208. HRESULT hr;
  209. BOOL fVersion1;
  210. BOOL fCacheableCall;
  211. PCATALOG_CACHED_STATE pCachedState = NULL;
  212. BOOL fVersion1WVTCalled = FALSE;
  213. DWORD cbInSubjectHash;
  214. DWORD dwLastError = 0;
  215. hr = TRUST_E_PROVIDER_UNKNOWN;
  216. pStateProvData = NULL;
  217. if (pcbSubjectHash)
  218. {
  219. cbInSubjectHash = *pcbSubjectHash;
  220. *pcbSubjectHash = 0;
  221. }
  222. else
  223. {
  224. cbInSubjectHash = 0;
  225. }
  226. if (pHashAlgid)
  227. *pHashAlgid = 0;
  228. fCacheableCall = g_CatalogCache.IsCacheableWintrustCall( pWinTrustData );
  229. if ( fCacheableCall == TRUE )
  230. {
  231. g_CatalogCache.LockCache();
  232. if ( pWinTrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE_FLUSH )
  233. {
  234. g_CatalogCache.FlushCache();
  235. g_CatalogCache.UnlockCache();
  236. return( ERROR_SUCCESS );
  237. }
  238. pCachedState = g_CatalogCache.FindCachedState( pWinTrustData );
  239. g_CatalogCache.AdjustWintrustDataToCachedState(
  240. pWinTrustData,
  241. pCachedState,
  242. FALSE
  243. );
  244. }
  245. if (WintrustIsVersion1ActionID(pgActionID))
  246. {
  247. fVersion1 = TRUE;
  248. }
  249. else
  250. {
  251. fVersion1 = FALSE;
  252. if (_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, hWVTStateData))
  253. {
  254. if ((pWinTrustData->dwStateAction == WTD_STATEACTION_VERIFY) ||
  255. (pWinTrustData->dwStateAction == WTD_STATEACTION_CLOSE))
  256. {
  257. pStateProvData = WTHelperProvDataFromStateData(pWinTrustData->hWVTStateData);
  258. if (pWinTrustData->dwStateAction == WTD_STATEACTION_CLOSE)
  259. {
  260. if (pWinTrustData->hWVTStateData)
  261. {
  262. _CleanupProviderData(pStateProvData);
  263. DELETE_OBJECT(pWinTrustData->hWVTStateData);
  264. }
  265. assert( fCacheableCall == FALSE );
  266. return(ERROR_SUCCESS);
  267. }
  268. }
  269. }
  270. }
  271. if (_WVTSetupProviderData(&sProvData, pStateProvData))
  272. {
  273. sProvData.pgActionID = pgActionID;
  274. if (!(pStateProvData))
  275. {
  276. if (!(WintrustLoadFunctionPointers(pgActionID, sProvData.psPfns)))
  277. {
  278. //
  279. // it may be that we are looking for a version 1 trust provider.
  280. //
  281. hr = Version1_WinVerifyTrust(hWnd, pgActionID, pWinTrustData);
  282. fVersion1WVTCalled = TRUE;
  283. }
  284. if ( fVersion1WVTCalled == FALSE )
  285. {
  286. if (fVersion1)
  287. {
  288. //
  289. // backwards compatibility with IE3.x and previous
  290. //
  291. WINTRUST_DATA sWinTrustData;
  292. WINTRUST_FILE_INFO sWinTrustFileInfo;
  293. pWinTrustData = ConvertDataFromVersion1(hWnd, pgActionID, &sWinTrustData, &sWinTrustFileInfo,
  294. pWinTrustData);
  295. }
  296. if (!_FillProviderData(&sProvData, hWnd, pWinTrustData))
  297. {
  298. hr = ERROR_NOT_ENOUGH_MEMORY;
  299. goto ErrorCase;
  300. }
  301. }
  302. }
  303. // On July 27, 2000 removed support for the IE4 way of chain building.
  304. sProvData.dwProvFlags |= CPD_USE_NT5_CHAIN_FLAG;
  305. if ( fVersion1WVTCalled == FALSE )
  306. {
  307. if (sProvData.psPfns->pfnInitialize)
  308. {
  309. (*sProvData.psPfns->pfnInitialize)(&sProvData);
  310. }
  311. if (sProvData.psPfns->pfnObjectTrust)
  312. {
  313. (*sProvData.psPfns->pfnObjectTrust)(&sProvData);
  314. }
  315. if (sProvData.psPfns->pfnSignatureTrust)
  316. {
  317. (*sProvData.psPfns->pfnSignatureTrust)(&sProvData);
  318. }
  319. if (sProvData.psPfns->pfnCertificateTrust)
  320. {
  321. (*sProvData.psPfns->pfnCertificateTrust)(&sProvData);
  322. }
  323. if (sProvData.psPfns->pfnFinalPolicy)
  324. {
  325. hr = (*sProvData.psPfns->pfnFinalPolicy)(&sProvData);
  326. }
  327. if (sProvData.psPfns->pfnTestFinalPolicy)
  328. {
  329. (*sProvData.psPfns->pfnTestFinalPolicy)(&sProvData);
  330. }
  331. if (sProvData.psPfns->pfnCleanupPolicy)
  332. {
  333. (*sProvData.psPfns->pfnCleanupPolicy)(&sProvData);
  334. }
  335. dwLastError = sProvData.dwFinalError;
  336. if (0 == dwLastError)
  337. {
  338. dwLastError = (DWORD) hr;
  339. }
  340. if (pcbSubjectHash && hr != TRUST_E_NOSIGNATURE)
  341. {
  342. // Return the subject's hash
  343. DWORD cbHash;
  344. if (sProvData.pPDSip && sProvData.pPDSip->psIndirectData)
  345. {
  346. cbHash = sProvData.pPDSip->psIndirectData->Digest.cbData;
  347. }
  348. else
  349. {
  350. cbHash = 0;
  351. }
  352. if (cbHash > 0)
  353. {
  354. *pcbSubjectHash = cbHash;
  355. if (pbSubjectHash)
  356. {
  357. if (cbInSubjectHash >= cbHash)
  358. {
  359. memcpy(pbSubjectHash,
  360. sProvData.pPDSip->psIndirectData->Digest.pbData,
  361. cbHash);
  362. }
  363. else if (S_OK == hr)
  364. {
  365. hr = ERROR_MORE_DATA;
  366. }
  367. }
  368. if (pHashAlgid)
  369. {
  370. *pHashAlgid = CertOIDToAlgId(
  371. sProvData.pPDSip->psIndirectData->DigestAlgorithm.pszObjId);
  372. }
  373. }
  374. }
  375. if (!(pStateProvData))
  376. {
  377. //
  378. // no previous state saved
  379. //
  380. if ((_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, hWVTStateData)) &&
  381. (pWinTrustData->dwStateAction == WTD_STATEACTION_VERIFY))
  382. {
  383. //
  384. // first time call and asking to maintain state...
  385. //
  386. if (!(pWinTrustData->hWVTStateData = (HANDLE)WVTNew(sizeof(CRYPT_PROVIDER_DATA))))
  387. {
  388. _CleanupProviderData(&sProvData);
  389. hr = ERROR_NOT_ENOUGH_MEMORY;
  390. }
  391. else
  392. {
  393. _CleanupProviderNonStateData(&sProvData);
  394. memcpy(pWinTrustData->hWVTStateData, &sProvData, sizeof(CRYPT_PROVIDER_DATA));
  395. }
  396. }
  397. else
  398. {
  399. _CleanupProviderData(&sProvData);
  400. }
  401. }
  402. else
  403. {
  404. //
  405. // only free up memory specific to this object/member
  406. //
  407. _CleanupProviderNonStateData(&sProvData);
  408. memcpy(pWinTrustData->hWVTStateData, &sProvData, sizeof(CRYPT_PROVIDER_DATA));
  409. }
  410. //
  411. // in version 1, when called by IE3.x and earlier, if security level is HIGH,
  412. // then the no bad UI is set. If we had an error, we want to
  413. // set the error to TRUST_E_FAIL. If we do not trust the object, every other
  414. // case sets it to TRUST_E_SUBJECT_NOT_TRUSTED and IE throws NO UI....
  415. //
  416. if (fVersion1)
  417. {
  418. if (hr != ERROR_SUCCESS)
  419. {
  420. if ((pWinTrustData) &&
  421. (_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwUIChoice)))
  422. {
  423. if (pWinTrustData->dwUIChoice == WTD_UI_NOBAD)
  424. {
  425. hr = TRUST_E_FAIL; // ie throws UI.
  426. }
  427. else
  428. {
  429. hr = TRUST_E_SUBJECT_NOT_TRUSTED; // ie throws no UI.
  430. }
  431. }
  432. else
  433. {
  434. hr = TRUST_E_SUBJECT_NOT_TRUSTED; // ie throws no UI.
  435. }
  436. }
  437. }
  438. }
  439. }
  440. else
  441. {
  442. hr = TRUST_E_SYSTEM_ERROR;
  443. }
  444. ErrorCase:
  445. if ( fCacheableCall == TRUE )
  446. {
  447. if ( pCachedState == NULL )
  448. {
  449. if ( g_CatalogCache.CreateCachedStateFromWintrustData(
  450. pWinTrustData,
  451. &pCachedState
  452. ) == TRUE )
  453. {
  454. g_CatalogCache.AddCachedState( pCachedState );
  455. }
  456. }
  457. if ( pCachedState == NULL )
  458. {
  459. FreeWintrustStateData( pWinTrustData );
  460. }
  461. g_CatalogCache.AdjustWintrustDataToCachedState(
  462. pWinTrustData,
  463. pCachedState,
  464. TRUE
  465. );
  466. g_CatalogCache.ReleaseCachedState( pCachedState );
  467. g_CatalogCache.UnlockCache();
  468. }
  469. SetLastError(dwLastError);
  470. return (LONG) hr;
  471. }
  472. //////////////////////////////////////////////////////////////////////////////////////
  473. //
  474. // local utility functions
  475. //
  476. //
  477. BOOL _FillProviderData(CRYPT_PROVIDER_DATA *pProvData, HWND hWnd, WINTRUST_DATA *pWinTrustData)
  478. {
  479. BOOL fHasTrustPubFlags;
  480. //
  481. // remember: we do NOT want to return FALSE unless it is an absolutely
  482. // catastrophic error! Let the Trust provider handle (eg: none!)
  483. //
  484. if (pWinTrustData && _ISINSTRUCT(WINTRUST_DATA,
  485. pWinTrustData->cbStruct, dwProvFlags))
  486. pProvData->dwProvFlags = pWinTrustData->dwProvFlags &
  487. WTD_PROV_FLAGS_MASK;
  488. if ((hWnd == INVALID_HANDLE_VALUE) || !(hWnd))
  489. {
  490. if (pWinTrustData->dwUIChoice != WTD_UI_NONE)
  491. {
  492. hWnd = GetDesktopWindow();
  493. }
  494. }
  495. pProvData->hWndParent = hWnd;
  496. pProvData->hProv = I_CryptGetDefaultCryptProv(0); // get the default and DONT RELEASE IT!!!!
  497. pProvData->dwEncoding = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
  498. pProvData->pWintrustData = pWinTrustData;
  499. pProvData->dwError = ERROR_SUCCESS;
  500. // allocate errors
  501. if (!(pProvData->padwTrustStepErrors))
  502. {
  503. if (!(pProvData->padwTrustStepErrors = (DWORD *)WVTNew(TRUSTERROR_MAX_STEPS * sizeof(DWORD))))
  504. {
  505. pProvData->dwError = GetLastError();
  506. //
  507. // NOTE!! this is currently the only FALSE return, so the caller will
  508. // assume ERROR_NOT_ENOUGH_MEMORY if FALSE is returned from this function
  509. //
  510. return(FALSE);
  511. }
  512. pProvData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
  513. }
  514. memset(pProvData->padwTrustStepErrors, 0x00, sizeof(DWORD) * TRUSTERROR_MAX_STEPS);
  515. WintrustGetRegPolicyFlags(&pProvData->dwRegPolicySettings);
  516. //
  517. // do NOT allow test certs EVER!
  518. //
  519. // Bug 581160: changed April 4, 2001
  520. //
  521. pProvData->dwRegPolicySettings &= ~(WTPF_TRUSTTEST | WTPF_TESTCANBEVALID);
  522. GetRegSecuritySettings(&pProvData->dwRegSecuritySettings);
  523. fHasTrustPubFlags = I_CryptReadTrustedPublisherDWORDValueFromRegistry(
  524. CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME,
  525. &pProvData->dwTrustPubSettings
  526. );
  527. if (fHasTrustPubFlags)
  528. {
  529. if (pProvData->dwTrustPubSettings &
  530. (CERT_TRUST_PUB_ALLOW_MACHINE_ADMIN_TRUST |
  531. CERT_TRUST_PUB_ALLOW_ENTERPRISE_ADMIN_TRUST))
  532. {
  533. // End User trust not allowed
  534. pProvData->dwRegPolicySettings =
  535. WTPF_IGNOREREVOKATION |
  536. WTPF_IGNOREREVOCATIONONTS |
  537. WTPF_OFFLINEOK_IND |
  538. WTPF_OFFLINEOK_COM |
  539. WTPF_OFFLINEOKNBU_IND |
  540. WTPF_OFFLINEOKNBU_COM |
  541. WTPF_ALLOWONLYPERTRUST;
  542. }
  543. // Allow the safer UI to enable revocation checking
  544. if (pProvData->dwTrustPubSettings &
  545. CERT_TRUST_PUB_CHECK_PUBLISHER_REV_FLAG)
  546. {
  547. pProvData->dwRegPolicySettings &= ~WTPF_IGNOREREVOKATION;
  548. pProvData->dwRegPolicySettings |=
  549. WTPF_OFFLINEOK_IND |
  550. WTPF_OFFLINEOK_COM |
  551. WTPF_OFFLINEOKNBU_IND |
  552. WTPF_OFFLINEOKNBU_COM;
  553. }
  554. if (pProvData->dwTrustPubSettings &
  555. CERT_TRUST_PUB_CHECK_TIMESTAMP_REV_FLAG)
  556. {
  557. pProvData->dwRegPolicySettings &= ~WTPF_IGNOREREVOCATIONONTS;
  558. pProvData->dwRegPolicySettings |=
  559. WTPF_OFFLINEOK_IND |
  560. WTPF_OFFLINEOK_COM |
  561. WTPF_OFFLINEOKNBU_IND |
  562. WTPF_OFFLINEOKNBU_COM;
  563. }
  564. }
  565. if (!(pWinTrustData) ||
  566. !(_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwUIChoice)))
  567. {
  568. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] = (DWORD)ERROR_INVALID_PARAMETER;
  569. }
  570. return(TRUE);
  571. }
  572. void _CleanupProviderData(CRYPT_PROVIDER_DATA *pProvData)
  573. {
  574. // pProvData->hProv: we're using crypt32's default
  575. // pProvData->pWintrustData->xxx->hFile
  576. if ((pProvData->fOpenedFile) && (pProvData->pWintrustData != NULL))
  577. {
  578. HANDLE *phFile;
  579. phFile = NULL;
  580. switch (pProvData->pWintrustData->dwUnionChoice)
  581. {
  582. case WTD_CHOICE_FILE:
  583. phFile = &pProvData->pWintrustData->pFile->hFile;
  584. break;
  585. case WTD_CHOICE_CATALOG:
  586. phFile = &pProvData->pWintrustData->pCatalog->hMemberFile;
  587. break;
  588. }
  589. if ((phFile) && (*phFile) && (*phFile != INVALID_HANDLE_VALUE))
  590. {
  591. CloseHandle(*phFile);
  592. *phFile = INVALID_HANDLE_VALUE;
  593. pProvData->fOpenedFile = FALSE;
  594. }
  595. }
  596. if (pProvData->dwSubjectChoice == CPD_CHOICE_SIP)
  597. {
  598. DELETE_OBJECT(pProvData->pPDSip->pSip);
  599. DELETE_OBJECT(pProvData->pPDSip->pCATSip);
  600. _WVTSipFreeSubjectInfo(pProvData->pPDSip->psSipSubjectInfo);
  601. DELETE_OBJECT(pProvData->pPDSip->psSipSubjectInfo);
  602. _WVTSipFreeSubjectInfo(pProvData->pPDSip->psSipCATSubjectInfo);
  603. DELETE_OBJECT(pProvData->pPDSip->psSipCATSubjectInfo);
  604. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pPDSip->psIndirectData);
  605. DELETE_OBJECT(pProvData->pPDSip);
  606. }
  607. if (pProvData->hMsg)
  608. {
  609. CryptMsgClose(pProvData->hMsg);
  610. pProvData->hMsg = NULL;
  611. }
  612. // signer structure
  613. for (int i = 0; i < (int)pProvData->csSigners; i++)
  614. {
  615. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pasSigners[i].psSigner);
  616. DeallocateCertChain(pProvData->pasSigners[i].csCertChain,
  617. &pProvData->pasSigners[i].pasCertChain);
  618. DELETE_OBJECT(pProvData->pasSigners[i].pasCertChain);
  619. if (_ISINSTRUCT(CRYPT_PROVIDER_SGNR,
  620. pProvData->pasSigners[i].cbStruct, pChainContext) &&
  621. pProvData->pasSigners[i].pChainContext)
  622. CertFreeCertificateChain(pProvData->pasSigners[i].pChainContext);
  623. // counter signers
  624. for (int i2 = 0; i2 < (int)pProvData->pasSigners[i].csCounterSigners; i2++)
  625. {
  626. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pasSigners[i].pasCounterSigners[i2].psSigner);
  627. DeallocateCertChain(pProvData->pasSigners[i].pasCounterSigners[i2].csCertChain,
  628. &pProvData->pasSigners[i].pasCounterSigners[i2].pasCertChain);
  629. DELETE_OBJECT(pProvData->pasSigners[i].pasCounterSigners[i2].pasCertChain);
  630. if (_ISINSTRUCT(CRYPT_PROVIDER_SGNR,
  631. pProvData->pasSigners[i].pasCounterSigners[i2].cbStruct,
  632. pChainContext) &&
  633. pProvData->pasSigners[i].pasCounterSigners[i2].pChainContext)
  634. CertFreeCertificateChain(
  635. pProvData->pasSigners[i].pasCounterSigners[i2].pChainContext);
  636. }
  637. DELETE_OBJECT(pProvData->pasSigners[i].pasCounterSigners);
  638. }
  639. DELETE_OBJECT(pProvData->pasSigners);
  640. // MUST BE DONE LAST!!! Using the force flag!!!
  641. if (pProvData->pahStores)
  642. {
  643. DeallocateStoreChain(pProvData->chStores, pProvData->pahStores);
  644. DELETE_OBJECT(pProvData->pahStores);
  645. }
  646. pProvData->chStores = 0;
  647. // pProvData->padwTrustStepErrors
  648. DELETE_OBJECT(pProvData->padwTrustStepErrors);
  649. // pProvData->pasProvPrivData
  650. DELETE_OBJECT(pProvData->pasProvPrivData);
  651. pProvData->csProvPrivData = 0;
  652. // pProvData->psPfns
  653. if (pProvData->psPfns)
  654. {
  655. if (pProvData->psPfns->psUIpfns)
  656. {
  657. DELETE_OBJECT(pProvData->psPfns->psUIpfns->psUIData);
  658. DELETE_OBJECT(pProvData->psPfns->psUIpfns);
  659. }
  660. DELETE_OBJECT(pProvData->psPfns);
  661. }
  662. }
  663. void _CleanupProviderNonStateData(CRYPT_PROVIDER_DATA *pProvData)
  664. {
  665. // pProvData->hProv: we're using default!
  666. // pProvData->pWintrustData->xxx->hFile: close!
  667. if ((pProvData->fOpenedFile) && (pProvData->pWintrustData != NULL))
  668. {
  669. HANDLE *phFile;
  670. phFile = NULL;
  671. switch (pProvData->pWintrustData->dwUnionChoice)
  672. {
  673. case WTD_CHOICE_FILE:
  674. phFile = &pProvData->pWintrustData->pFile->hFile;
  675. break;
  676. case WTD_CHOICE_CATALOG:
  677. phFile = &pProvData->pWintrustData->pCatalog->hMemberFile;
  678. break;
  679. }
  680. if ((phFile) && (*phFile) && (*phFile != INVALID_HANDLE_VALUE))
  681. {
  682. CloseHandle(*phFile);
  683. *phFile = INVALID_HANDLE_VALUE;
  684. pProvData->fOpenedFile = FALSE;
  685. }
  686. }
  687. if (pProvData->dwSubjectChoice == CPD_CHOICE_SIP)
  688. {
  689. DELETE_OBJECT(pProvData->pPDSip->pSip);
  690. _WVTSipFreeSubjectInfoKeepState(pProvData->pPDSip->psSipSubjectInfo);
  691. // pProvData->pPDSip->psSipSubjectInfo: keep
  692. // pProvData->pPDSip->pCATSip: keep
  693. // pProvData->pPDSip->psSipCATSubjectInfo: keep
  694. TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pPDSip->psIndirectData);
  695. // pProvData->pPDSip: keep
  696. }
  697. // pProvData->hMsg: keep
  698. // signer structure: keep
  699. // pProvData->pahStores: keep
  700. // pProvData->padwTrustStepErrors: keep
  701. // pProvData->pasProvPrivData: keep
  702. // pProvData->psPfns: keep
  703. }
  704. BOOL _WVTSipFreeSubjectInfo(SIP_SUBJECTINFO *pSubj)
  705. {
  706. if (!(pSubj))
  707. {
  708. return(FALSE);
  709. }
  710. DELETE_OBJECT(pSubj->pgSubjectType);
  711. switch(pSubj->dwUnionChoice)
  712. {
  713. case MSSIP_ADDINFO_BLOB:
  714. DELETE_OBJECT(pSubj->psBlob);
  715. break;
  716. case MSSIP_ADDINFO_CATMEMBER:
  717. if (pSubj->psCatMember)
  718. {
  719. // The following APIs are in DELAYLOAD'ed mscat32.dll. If the
  720. // DELAYLOAD fails an exception is raised.
  721. __try {
  722. CryptCATClose(
  723. CryptCATHandleFromStore(pSubj->psCatMember->pStore));
  724. } __except(EXCEPTION_EXECUTE_HANDLER) {
  725. DWORD dwExceptionCode = GetExceptionCode();
  726. }
  727. DELETE_OBJECT(pSubj->psCatMember);
  728. }
  729. break;
  730. }
  731. return(TRUE);
  732. }
  733. BOOL _WVTSipFreeSubjectInfoKeepState(SIP_SUBJECTINFO *pSubj)
  734. {
  735. if (!(pSubj))
  736. {
  737. return(FALSE);
  738. }
  739. DELETE_OBJECT(pSubj->pgSubjectType);
  740. switch(pSubj->dwUnionChoice)
  741. {
  742. case MSSIP_ADDINFO_BLOB:
  743. DELETE_OBJECT(pSubj->psBlob);
  744. break;
  745. case MSSIP_ADDINFO_CATMEMBER:
  746. break;
  747. }
  748. return(TRUE);
  749. }
  750. BOOL _WVTSetupProviderData(CRYPT_PROVIDER_DATA *psProvData, CRYPT_PROVIDER_DATA *psState)
  751. {
  752. if (psState)
  753. {
  754. memcpy(psProvData, psState, sizeof(CRYPT_PROVIDER_DATA));
  755. if (_ISINSTRUCT(CRYPT_PROVIDER_DATA, psProvData->cbStruct, fRecallWithState))
  756. {
  757. psProvData->fRecallWithState = TRUE;
  758. }
  759. return(TRUE);
  760. }
  761. memset(psProvData, 0x00, sizeof(CRYPT_PROVIDER_DATA));
  762. psProvData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
  763. if (!(psProvData->psPfns = (CRYPT_PROVIDER_FUNCTIONS *)WVTNew(sizeof(CRYPT_PROVIDER_FUNCTIONS))))
  764. {
  765. return(FALSE);
  766. }
  767. memset(psProvData->psPfns, 0x00, sizeof(CRYPT_PROVIDER_FUNCTIONS));
  768. psProvData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
  769. if (!(psProvData->psPfns->psUIpfns = (CRYPT_PROVUI_FUNCS *)WVTNew(sizeof(CRYPT_PROVUI_FUNCS))))
  770. {
  771. return(FALSE);
  772. }
  773. memset(psProvData->psPfns->psUIpfns, 0x00, sizeof(CRYPT_PROVUI_FUNCS));
  774. psProvData->psPfns->psUIpfns->cbStruct = sizeof(CRYPT_PROVUI_FUNCS);
  775. if (!(psProvData->psPfns->psUIpfns->psUIData = (CRYPT_PROVUI_DATA *)WVTNew(sizeof(CRYPT_PROVUI_DATA))))
  776. {
  777. return(FALSE);
  778. }
  779. memset(psProvData->psPfns->psUIpfns->psUIData, 0x00, sizeof(CRYPT_PROVUI_DATA));
  780. psProvData->psPfns->psUIpfns->psUIData->cbStruct = sizeof(CRYPT_PROVUI_DATA);
  781. GetSystemTimeAsFileTime(&psProvData->sftSystemTime);
  782. return(TRUE);
  783. }
  784. VOID FreeWintrustStateData (WINTRUST_DATA* pWintrustData)
  785. {
  786. PCRYPT_PROVIDER_DATA pStateProvData;
  787. pStateProvData = WTHelperProvDataFromStateData(
  788. pWintrustData->hWVTStateData
  789. );
  790. if ( pStateProvData != NULL )
  791. {
  792. _CleanupProviderData( pStateProvData );
  793. DELETE_OBJECT( pWintrustData->hWVTStateData );
  794. }
  795. }