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.

1108 lines
31 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: chktrust.cpp
  8. //
  9. // Contents: Microsoft Internet Security Trust Checker
  10. //
  11. // History: 05-May-1997 pberkman created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <stdio.h>
  15. #include <windows.h>
  16. #include <io.h>
  17. #include <wchar.h>
  18. #include "cryptreg.h"
  19. #include "wincrypt.h"
  20. #include "wintrust.h"
  21. #include "softpub.h"
  22. #include "mscat.h"
  23. #include "unicode.h"
  24. #include "dbgdef.h"
  25. #include "gendefs.h"
  26. #include "cwargv.hxx"
  27. #include "printfu.hxx"
  28. #include "mssip.h"
  29. #include "resource.h"
  30. HRESULT _CallWVT(WCHAR *pwszFilename);
  31. HRESULT _ExplodeCatalog(WCHAR *pwszCatalogFile);
  32. HRESULT _CallCatalogWVT(WCHAR *pwszCatalogFile, WCHAR *pwszMemberTag, WCHAR *pwszMemberFile);
  33. int _ShowError(DWORD dwError, WCHAR *pwszFile);
  34. void _ToLower(WCHAR *pwszInOut);
  35. HRESULT _AddCatalogToDatabase(WCHAR *pwszFileIn);
  36. HRESULT _DelCatalogFromDatabase(WCHAR *pwszFileIn);
  37. GUID guidPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  38. GUID guidProviderTest = WINTRUST_ACTION_TRUSTPROVIDER_TEST;
  39. GUID guidProviderDriver = DRIVER_ACTION_VERIFY;
  40. GUID guidPassedIn;
  41. GUID guidCatRoot;
  42. GUID *pguidActionID = &guidPublishedSoftware;
  43. GUID *pguidCatRoot = NULL;
  44. DWORD dwExpectedError = ERROR_SUCCESS;
  45. WCHAR *pwszCatalogFile = NULL;
  46. WCHAR *pwszCatalogMember = NULL;
  47. WCHAR *pwszOSVerLow = NULL;
  48. WCHAR *pwszOSVerHigh = NULL;
  49. BOOL fUseOldDriverVerInfoSize = FALSE;
  50. PrintfU_ *pPrint = NULL;
  51. HCATADMIN hCatAdmin = NULL;
  52. BOOL fVerbose;
  53. BOOL fQuiet;
  54. BOOL fIECall;
  55. BOOL fTestDump;
  56. BOOL fCheckExpectedError = FALSE;
  57. BOOL fProcessAllCatMembers;
  58. BOOL fCatalogMemberVerify = FALSE;
  59. BOOL fUseCatalogDatabase;
  60. BOOL fAdd2CatalogDatabase;
  61. BOOL fDelFromCatalogDatabase;
  62. BOOL fReplaceCatfile;
  63. BOOL fNT5;
  64. BOOL fNoTimeStampWarning;
  65. extern "C" int __cdecl wmain(int argc, WCHAR **wargv)
  66. {
  67. cWArgv_ *pArgs;
  68. BOOL fFailed;
  69. BOOL fFind;
  70. HANDLE hFind;
  71. WIN32_FIND_DATAW sFindData;
  72. int iRet;
  73. int iRetWorst;
  74. HRESULT hr = ERROR_SUCCESS;
  75. WCHAR *pwszFileIn;
  76. WCHAR *pwszLastSlash;
  77. WCHAR wszFile[MAX_PATH];
  78. WCHAR wszDir[MAX_PATH];
  79. char szFile[MAX_PATH * 2];
  80. DWORD dwFiles;
  81. DWORD dwDirLen;
  82. iRet = 0;
  83. pPrint = NULL;
  84. hFind = INVALID_HANDLE_VALUE;
  85. dwFiles = 0;
  86. if (!(pPrint = new PrintfU_()))
  87. {
  88. goto MemoryError;
  89. }
  90. if (!(pArgs = new cWArgv_((HINSTANCE)GetModuleHandle(NULL), &fFailed, FALSE)))
  91. {
  92. goto MemoryError;
  93. }
  94. if (fFailed)
  95. {
  96. goto MemoryError;
  97. }
  98. pArgs->AddUsageText(IDS_USAGETEXT_USAGE, IDS_USAGETEXT_OPTIONS,
  99. IDS_USAGETEXT_CMDFILE, IDS_USAGETEXT_ADD,
  100. IDS_USAGETEXT_OPTPARAM);
  101. pArgs->Add2List(IDS_PARAM_HELP, IDS_PARAMTEXT_HELP, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE);
  102. pArgs->Add2List(IDS_PARAM_VERBOSE, IDS_PARAMTEXT_VERBOSE, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE);
  103. pArgs->Add2List(IDS_PARAM_QUIET, IDS_PARAMTEXT_QUIET, WARGV_VALUETYPE_BOOL, (void *)FALSE, FALSE);
  104. pArgs->Add2List(IDS_PARAM_TPROV, IDS_PARAMTEXT_TPROV, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  105. pArgs->Add2List(IDS_PARAM_IECALL, IDS_PARAMTEXT_IECALL, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  106. pArgs->Add2List(IDS_PARAM_TESTDUMP, IDS_PARAMTEXT_TESTDUMP, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  107. pArgs->Add2List(IDS_PARAM_EXPERROR, IDS_PARAMTEXT_EXPERROR, WARGV_VALUETYPE_DWORDH, NULL, TRUE);
  108. pArgs->Add2List(IDS_PARAM_TESTDRV, IDS_PARAMTEXT_TESTDRV, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  109. pArgs->Add2List(IDS_PARAM_CATFILE, IDS_PARAMTEXT_CATFILE, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  110. pArgs->Add2List(IDS_PARAM_CATMEMBER, IDS_PARAMTEXT_CATMEMBER, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  111. pArgs->Add2List(IDS_PARAM_ALLCATMEM, IDS_PARAMTEXT_ALLCATMEM, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  112. pArgs->Add2List(IDS_PARAM_CATUSELIST, IDS_PARAMTEXT_CATUSELIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  113. pArgs->Add2List(IDS_PARAM_CATADDLIST, IDS_PARAMTEXT_CATADDLIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  114. pArgs->Add2List(IDS_PARAM_CATDELLIST, IDS_PARAMTEXT_CATDELLIST, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  115. pArgs->Add2List(IDS_PARAM_REPLACECATFILE,IDS_PARAMTEXT_REPLACECATFILE, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  116. pArgs->Add2List(IDS_PARAM_CATROOT, IDS_PARAMTEXT_CATROOT, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  117. pArgs->Add2List(IDS_PARAM_NT5, IDS_PARAMTEXT_NT5, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  118. pArgs->Add2List(IDS_PARAM_TSWARN, IDS_PARAMTEXT_TSWARN, WARGV_VALUETYPE_BOOL, (void *)FALSE, TRUE);
  119. pArgs->Add2List(IDS_PARAM_OSVERLOW, IDS_PARAMTEXT_OSVERLOW, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  120. pArgs->Add2List(IDS_PARAM_OSVERHIGH, IDS_PARAMTEXT_OSVERHIGH, WARGV_VALUETYPE_WCHAR, NULL, TRUE);
  121. if (!(pArgs->Fill(argc, wargv)) ||
  122. (pArgs->GetValue(IDS_PARAM_HELP)))
  123. {
  124. wprintf(L"%s", pArgs->GetUsageString());
  125. goto NeededHelp;
  126. }
  127. pwszCatalogFile = (WCHAR *)pArgs->GetValue(IDS_PARAM_CATFILE);
  128. pwszCatalogMember = (WCHAR *)pArgs->GetValue(IDS_PARAM_CATMEMBER);
  129. fVerbose = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_VERBOSE));
  130. fQuiet = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_QUIET));
  131. fIECall = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_IECALL));
  132. fTestDump = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_TESTDUMP));
  133. fProcessAllCatMembers = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_ALLCATMEM));
  134. fUseCatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATUSELIST));
  135. fAdd2CatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATADDLIST));
  136. fDelFromCatalogDatabase = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_CATDELLIST));
  137. fReplaceCatfile = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_REPLACECATFILE));
  138. fNT5 = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_NT5));
  139. fNoTimeStampWarning = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_TSWARN));
  140. pwszOSVerLow = (WCHAR *)pArgs->GetValue(IDS_PARAM_OSVERLOW);
  141. pwszOSVerHigh = (WCHAR *)pArgs->GetValue(IDS_PARAM_OSVERHIGH);
  142. //
  143. // the win2k flag implies -q and -ucl (unless -acl or -del is used, then it just implies -q)
  144. //
  145. if (fNT5)
  146. {
  147. fQuiet = TRUE;
  148. if (!fAdd2CatalogDatabase && !fDelFromCatalogDatabase)
  149. {
  150. fUseCatalogDatabase = TRUE;
  151. }
  152. }
  153. if (fUseCatalogDatabase || fNT5)
  154. {
  155. fCatalogMemberVerify = TRUE;
  156. }
  157. if (pArgs->IsSet(IDS_PARAM_EXPERROR))
  158. {
  159. dwExpectedError = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_EXPERROR));
  160. fCheckExpectedError = TRUE;
  161. }
  162. if (!(pwszFileIn = pArgs->GetFileName()))
  163. {
  164. wprintf(L"%s", pArgs->GetUsageString());
  165. goto ParamError;
  166. }
  167. if (((pwszCatalogFile) && !(pwszCatalogMember)) ||
  168. (!(pwszCatalogFile) && (pwszCatalogMember)))
  169. {
  170. wprintf(L"%s", pArgs->GetUsageString());
  171. goto ParamError;
  172. }
  173. if ((pwszCatalogFile) && (pwszCatalogMember))
  174. {
  175. fCatalogMemberVerify = TRUE;
  176. }
  177. //
  178. // set the appropriete provider
  179. //
  180. if (pArgs->IsSet(IDS_PARAM_TPROV) || fNT5)
  181. {
  182. if (fNT5)
  183. {
  184. wstr2guid(L"{F750E6C3-38EE-11D1-85E5-00C04FC295EE}", &guidPassedIn);
  185. }
  186. else if (!(wstr2guid((WCHAR *)pArgs->GetValue(IDS_PARAM_TPROV), &guidPassedIn)))
  187. {
  188. goto GuidError;
  189. }
  190. pguidActionID = &guidPassedIn;
  191. }
  192. else if (fTestDump)
  193. {
  194. pguidActionID = &guidProviderTest;
  195. }
  196. else if (pArgs->GetValue(IDS_PARAM_TESTDRV))
  197. {
  198. pguidActionID = &guidProviderDriver;
  199. }
  200. else
  201. {
  202. pguidActionID = &guidPublishedSoftware;
  203. }
  204. //
  205. // Get the catalog subsystem GUID to use
  206. //
  207. if (pArgs->IsSet(IDS_PARAM_CATROOT) || fNT5)
  208. {
  209. if (fNT5)
  210. {
  211. wstr2guid(L"{F750E6C3-38EE-11D1-85E5-00C04FC295EE}", &guidCatRoot);
  212. }
  213. else if (!(wstr2guid((WCHAR *)pArgs->GetValue(IDS_PARAM_CATROOT), &guidCatRoot)))
  214. {
  215. goto GuidError;
  216. }
  217. pguidCatRoot = &guidCatRoot;
  218. }
  219. //
  220. // if we are calling just like IE, we only have one file and don't want to
  221. // check if it exists or not... just call WVT.
  222. //
  223. if (fIECall)
  224. {
  225. dwFiles++;
  226. hr = _CallWVT(pwszFileIn);
  227. iRet = _ShowError(hr, pwszFileIn);
  228. goto CommonReturn;
  229. }
  230. //
  231. // Check to see if we are supposed to be using the old DRIVER_VER_INFO struct
  232. //
  233. while (--argc>0)
  234. {
  235. if (**++wargv == L'-')
  236. {
  237. if (wcscmp(*wargv, L"-UseOldDriverVerInfoStruct") == 0)
  238. {
  239. fUseOldDriverVerInfoSize = TRUE;
  240. break;
  241. }
  242. }
  243. }
  244. //
  245. // If a delete is being done, then just execute that and get out
  246. //
  247. if (fDelFromCatalogDatabase)
  248. {
  249. hr = _DelCatalogFromDatabase(pwszFileIn);
  250. iRet = _ShowError(hr, &wszFile[0]);
  251. goto CommonReturn;
  252. }
  253. //
  254. // OK.... go into a findfirst/next loop we could have been called with *.*
  255. //
  256. if (pwszLastSlash = wcsrchr(pwszFileIn, L'\\'))
  257. {
  258. *pwszLastSlash = NULL;
  259. wcscpy(&wszDir[0], pwszFileIn);
  260. wcscat(&wszDir[0], L"\\");
  261. *pwszLastSlash = L'\\';
  262. dwDirLen = wcslen(&wszDir[0]);
  263. }
  264. else
  265. {
  266. wszDir[0] = NULL;
  267. dwDirLen = 0;
  268. }
  269. if ((hFind = FindFirstFileU(pwszFileIn, &sFindData)) == INVALID_HANDLE_VALUE)
  270. {
  271. pPrint->Display(IDS_CAN_NOT_OPEN_FILE, pwszFileIn);
  272. goto FileNotFound;
  273. }
  274. fFind = TRUE;
  275. dwFiles = 0;
  276. iRetWorst = 0;
  277. while (fFind)
  278. {
  279. if (!(sFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  280. {
  281. if (dwDirLen > 0)
  282. {
  283. wcscpy(&wszFile[0], &wszDir[0]);
  284. }
  285. wszFile[dwDirLen] = NULL;
  286. wcscat(wszFile, sFindData.cFileName);
  287. if (wszFile[0])
  288. {
  289. if (fAdd2CatalogDatabase)
  290. {
  291. hr = _AddCatalogToDatabase(&wszFile[0]);
  292. }
  293. else
  294. {
  295. hr = _CallWVT(&wszFile[0]);
  296. }
  297. iRet = _ShowError(hr, &wszFile[0]);
  298. switch (iRet)
  299. {
  300. case 0: // No Error
  301. break;
  302. case 1: // Error
  303. iRetWorst = iRet;
  304. break;
  305. case 2: // Warning (no timestamp)
  306. if (iRetWorst != 1)
  307. {
  308. iRetWorst = iRet;
  309. }
  310. // No other return values are possible from _ShowError
  311. }
  312. if (iRet == 0)
  313. {
  314. hr = ERROR_SUCCESS;
  315. }
  316. dwFiles++;
  317. }
  318. }
  319. fFind = FindNextFileU(hFind, &sFindData);
  320. }
  321. iRet = iRetWorst;
  322. if (dwFiles < 1)
  323. {
  324. pPrint->Display(IDS_CAN_NOT_OPEN_FILE, pwszFileIn);
  325. goto FileNotFound;
  326. }
  327. CommonReturn:
  328. DELETE_OBJECT(pArgs);
  329. DELETE_OBJECT(pPrint);
  330. if (hFind != INVALID_HANDLE_VALUE)
  331. {
  332. FindClose(hFind);
  333. }
  334. if (hCatAdmin)
  335. {
  336. CryptCATAdminReleaseContext(hCatAdmin, 0);
  337. }
  338. return(iRet);
  339. ErrorReturn:
  340. iRet = 1;
  341. goto CommonReturn;
  342. TRACE_ERROR_EX(DBG_SS_APP, MemoryError);
  343. TRACE_ERROR_EX(DBG_SS_APP, FileNotFound);
  344. TRACE_ERROR_EX(DBG_SS_APP, ParamError);
  345. TRACE_ERROR_EX(DBG_SS_APP, GuidError);
  346. TRACE_ERROR_EX(DBG_SS_APP, NeededHelp);
  347. }
  348. HRESULT _CallWVT(WCHAR *pwszFilename)
  349. {
  350. if (fCatalogMemberVerify)
  351. {
  352. return(_CallCatalogWVT(pwszCatalogFile, pwszCatalogMember, pwszFilename));
  353. }
  354. HRESULT hr;
  355. WINTRUST_DATA sWTD;
  356. WINTRUST_FILE_INFO sWTFI;
  357. memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
  358. sWTD.cbStruct = sizeof(WINTRUST_DATA);
  359. sWTD.dwUIChoice = (fQuiet) ? WTD_UI_NONE : WTD_UI_ALL;
  360. sWTD.dwUnionChoice = WTD_CHOICE_FILE;
  361. sWTD.pFile = &sWTFI;
  362. memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO));
  363. sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO);
  364. sWTFI.pcwszFilePath = pwszFilename;
  365. sWTFI.hFile = CreateFileU(pwszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  366. FILE_ATTRIBUTE_NORMAL, NULL);
  367. hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
  368. if (sWTFI.hFile != INVALID_HANDLE_VALUE)
  369. {
  370. CloseHandle(sWTFI.hFile);
  371. }
  372. if ((fCheckExpectedError) && ((DWORD)hr == dwExpectedError) && (fProcessAllCatMembers))
  373. {
  374. if (IsCatalogFile(INVALID_HANDLE_VALUE, pwszFilename))
  375. {
  376. return(_ExplodeCatalog(pwszFilename));
  377. }
  378. }
  379. return(hr);
  380. }
  381. HRESULT _ExplodeCatalog(WCHAR *pwszCatalogFile)
  382. {
  383. HRESULT hrReturn;
  384. HANDLE hCat;
  385. CRYPTCATMEMBER *psMember;
  386. hrReturn = ERROR_SUCCESS;
  387. //
  388. // open the catalog
  389. //
  390. if (!(hCat = CryptCATOpen(pwszCatalogFile, 0, NULL, 0, 0)))
  391. {
  392. goto ErrorCatOpen;
  393. }
  394. psMember = NULL;
  395. while (psMember = CryptCATEnumerateMember(hCat, psMember))
  396. {
  397. hrReturn |= _CallCatalogWVT(pwszCatalogFile, psMember->pwszReferenceTag,
  398. psMember->pwszReferenceTag);
  399. }
  400. CommonReturn:
  401. if (hCat)
  402. {
  403. CryptCATClose(hCat);
  404. }
  405. return(hrReturn);
  406. ErrorReturn:
  407. hrReturn = GetLastError();
  408. goto CommonReturn;
  409. TRACE_ERROR_EX(DBG_SS_APP, ErrorCatOpen);
  410. }
  411. HRESULT _CallCatalogWVT(WCHAR *pwszCatalogFile, WCHAR *pwszMemberTag, WCHAR *pwszMemberFile)
  412. {
  413. HRESULT hr;
  414. DWORD cbHash;
  415. BYTE bHash[40];
  416. WCHAR *pwsz;
  417. WINTRUST_DATA sWTD;
  418. WINTRUST_CATALOG_INFO sWTCI;
  419. DRIVER_VER_INFO sDriverInfo;
  420. memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
  421. sWTD.cbStruct = sizeof(WINTRUST_DATA);
  422. sWTD.dwUIChoice = (fQuiet) ? WTD_UI_NONE : WTD_UI_ALL;
  423. sWTD.dwUnionChoice = WTD_CHOICE_CATALOG;
  424. sWTD.pCatalog = &sWTCI;
  425. memset(&sWTCI, 0x00, sizeof(WINTRUST_CATALOG_INFO));
  426. sWTCI.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  427. sWTCI.pcwszCatalogFilePath = pwszCatalogFile;
  428. sWTCI.pcwszMemberTag = pwszMemberTag;
  429. sWTCI.pcwszMemberFilePath = pwszMemberFile;
  430. sWTCI.hMemberFile = CreateFileU(pwszMemberFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  431. FILE_ATTRIBUTE_NORMAL, NULL);
  432. if (pwszOSVerLow != NULL)
  433. {
  434. WCHAR *pwszEnd;
  435. WCHAR *pwszCurrent;
  436. memset(&sDriverInfo, 0x00, sizeof(DRIVER_VER_INFO));
  437. sDriverInfo.cbStruct = fUseOldDriverVerInfoSize ? _OFFSETOF(DRIVER_VER_INFO, dwBuildNumberLow) : sizeof(DRIVER_VER_INFO);
  438. pwszEnd = wcschr(pwszOSVerLow, L':');
  439. if (pwszEnd == NULL)
  440. {
  441. goto OSVerError;
  442. }
  443. *pwszEnd = L'\0';
  444. sDriverInfo.dwPlatform = _wtol(pwszOSVerLow);
  445. *pwszEnd = L':';
  446. pwszCurrent = pwszEnd + 1;
  447. pwszEnd = wcschr(pwszCurrent, L'.');
  448. if (pwszEnd == NULL)
  449. {
  450. goto OSVerError;
  451. }
  452. *pwszEnd = L'\0';
  453. sDriverInfo.sOSVersionLow.dwMajor = sDriverInfo.sOSVersionHigh.dwMajor = _wtol(pwszCurrent);
  454. *pwszEnd = L'.';
  455. pwszCurrent = pwszEnd + 1;
  456. pwszEnd = wcschr(pwszCurrent, L'.');
  457. if (pwszEnd == NULL)
  458. {
  459. sDriverInfo.sOSVersionLow.dwMinor = sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent);
  460. }
  461. else
  462. {
  463. *pwszEnd = L'\0';
  464. sDriverInfo.sOSVersionLow.dwMinor = sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent);
  465. *pwszEnd = L'.';
  466. pwszCurrent = pwszEnd + 1;
  467. sDriverInfo.dwBuildNumberLow = sDriverInfo.dwBuildNumberHigh = _wtol(pwszCurrent);
  468. }
  469. if (pwszOSVerHigh != NULL)
  470. {
  471. pwszEnd = wcschr(pwszOSVerHigh, L':');
  472. if (pwszEnd == NULL)
  473. {
  474. goto OSVerError;
  475. }
  476. *pwszEnd = L'\0';
  477. if (sDriverInfo.dwPlatform != (DWORD) _wtol(pwszOSVerHigh))
  478. {
  479. goto OSVerError;
  480. }
  481. *pwszEnd = L':';
  482. pwszCurrent = pwszEnd + 1;
  483. pwszEnd = wcschr(pwszCurrent, L'.');
  484. if (pwszEnd == NULL)
  485. {
  486. goto OSVerError;
  487. }
  488. *pwszEnd = L'\0';
  489. sDriverInfo.sOSVersionHigh.dwMajor = _wtol(pwszCurrent);
  490. *pwszEnd = L'.';
  491. pwszCurrent = pwszEnd + 1;
  492. pwszEnd = wcschr(pwszCurrent, L'.');
  493. if (pwszEnd == NULL)
  494. {
  495. sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent);
  496. }
  497. else
  498. {
  499. *pwszEnd = L'\0';
  500. sDriverInfo.sOSVersionHigh.dwMinor = _wtol(pwszCurrent);
  501. *pwszEnd = L'.';
  502. pwszCurrent = pwszEnd + 1;
  503. sDriverInfo.dwBuildNumberHigh = _wtol(pwszCurrent);
  504. }
  505. }
  506. sWTD.pPolicyCallbackData = &sDriverInfo;
  507. }
  508. cbHash = 40;
  509. if (!(CryptCATAdminCalcHashFromFileHandle(sWTCI.hMemberFile, &cbHash, &bHash[0], 0)))
  510. {
  511. goto CatAdminCalcHashError;
  512. }
  513. sWTCI.pbCalculatedFileHash = &bHash[0];
  514. sWTCI.cbCalculatedFileHash = cbHash;
  515. if (fUseCatalogDatabase)
  516. {
  517. HCATINFO hCatInfo;
  518. CATALOG_INFO sCatInfo;
  519. if (!(hCatAdmin))
  520. {
  521. if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0)))
  522. {
  523. goto CatAdminAcquireError;
  524. }
  525. }
  526. pwsz = NULL;
  527. if (pwsz = wcsrchr(pwszMemberFile, L'\\'))
  528. {
  529. pwsz++;
  530. }
  531. else
  532. {
  533. pwsz = pwszMemberFile;
  534. }
  535. _ToLower(pwsz);
  536. sWTCI.pcwszMemberTag = pwsz;
  537. memset(&sCatInfo, 0x00, sizeof(CATALOG_INFO));
  538. sCatInfo.cbStruct = sizeof(CATALOG_INFO);
  539. hCatInfo = NULL;
  540. while (hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, &bHash[0], cbHash, 0, &hCatInfo))
  541. {
  542. if (!(CryptCATCatalogInfoFromContext(hCatInfo, &sCatInfo, 0)))
  543. {
  544. // should do something (??)
  545. continue;
  546. }
  547. sWTCI.pcwszCatalogFilePath = &sCatInfo.wszCatalogFile[0];
  548. hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
  549. if ((sWTD.pPolicyCallbackData != 0) && (sDriverInfo.pcSignerCertContext != NULL))
  550. {
  551. CertFreeCertificateContext(sDriverInfo.pcSignerCertContext);
  552. }
  553. if (hr == (HRESULT)dwExpectedError)
  554. {
  555. CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
  556. goto CommonReturn;
  557. }
  558. }
  559. goto CatMemberNotFound;
  560. }
  561. hr = WinVerifyTrust(NULL, pguidActionID, &sWTD);
  562. CommonReturn:
  563. if (sWTCI.hMemberFile != INVALID_HANDLE_VALUE)
  564. {
  565. CloseHandle(sWTCI.hMemberFile);
  566. }
  567. return(hr);
  568. ErrorReturn:
  569. hr = GetLastError();
  570. goto CommonReturn;
  571. OSVerError:
  572. wprintf(L"Invalid osverl or osverh\n");
  573. return S_FALSE;
  574. TRACE_ERROR_EX(DBG_SS_APP, CatAdminCalcHashError);
  575. TRACE_ERROR_EX(DBG_SS_APP, CatAdminAcquireError);
  576. TRACE_ERROR_EX(DBG_SS_APP, CatMemberNotFound);
  577. }
  578. BOOL
  579. OpenSIP(const WCHAR* pwsFileName,
  580. SIP_SUBJECTINFO** ppSubjectInfo,
  581. SIP_DISPATCH_INFO** ppDispatchInfo,
  582. GUID* pgSubject)
  583. {
  584. if (pgSubject == NULL)
  585. {
  586. return FALSE;
  587. }
  588. if (NULL == (*ppSubjectInfo = (SIP_SUBJECTINFO*) new(BYTE[sizeof(SIP_SUBJECTINFO)])))
  589. {
  590. return FALSE;
  591. }
  592. if (NULL == (*ppDispatchInfo = (SIP_DISPATCH_INFO*) new(BYTE[sizeof(SIP_DISPATCH_INFO)])))
  593. {
  594. delete[] (*ppSubjectInfo);
  595. return FALSE;
  596. }
  597. memset((void*)*ppSubjectInfo, 0, sizeof(SIP_SUBJECTINFO));
  598. memset((void*)*ppDispatchInfo, 0, sizeof(SIP_DISPATCH_INFO));
  599. memset((void*)pgSubject, 0, sizeof(GUID));
  600. // Get the type of SIP
  601. if (!CryptSIPRetrieveSubjectGuid(
  602. pwsFileName,
  603. NULL,
  604. pgSubject))
  605. {
  606. goto ErrorReturn;
  607. }
  608. (*ppDispatchInfo)->cbSize = sizeof(SIP_DISPATCH_INFO);
  609. // Load the SIP
  610. if (!CryptSIPLoad(
  611. pgSubject,
  612. 0,
  613. *ppDispatchInfo))
  614. {
  615. goto ErrorReturn;
  616. }
  617. // Fill in the SIP_SUBJECTINFO struct
  618. (*ppSubjectInfo)->cbSize = sizeof(SIP_SUBJECTINFO);
  619. (*ppSubjectInfo)->pgSubjectType = pgSubject;
  620. (*ppSubjectInfo)->pwsFileName = pwsFileName;
  621. goto CommonReturn;
  622. ErrorReturn:
  623. delete[](*ppSubjectInfo);
  624. delete[](*ppDispatchInfo);
  625. return FALSE;
  626. CommonReturn:
  627. return TRUE;
  628. }
  629. BOOL
  630. ReadMsgBlob(const WCHAR* pwsFileName,
  631. CRYPT_DATA_BLOB* pData)
  632. {
  633. if ((pwsFileName == NULL) ||
  634. (pData == NULL))
  635. {
  636. return FALSE;
  637. }
  638. SIP_SUBJECTINFO* pSubjectInfo = NULL;
  639. SIP_DISPATCH_INFO* pDispatchInfo = NULL;
  640. GUID gSubject;
  641. memset((void*)&gSubject, 0, sizeof(gSubject));
  642. // Get the SIP
  643. if (!OpenSIP(
  644. pwsFileName,
  645. &pSubjectInfo,
  646. &pDispatchInfo,
  647. &gSubject))
  648. {
  649. return FALSE;
  650. }
  651. // Load the message blob
  652. DWORD dwEncodingType = 0;
  653. pData->cbData = 0;
  654. if (!pDispatchInfo->pfGet(
  655. pSubjectInfo,
  656. &dwEncodingType,
  657. 0,
  658. &(pData->cbData),
  659. NULL))
  660. {
  661. delete[](pSubjectInfo);
  662. delete[](pDispatchInfo);
  663. return FALSE;
  664. }
  665. pData->pbData = (BYTE*)new(BYTE[pData->cbData]);
  666. if (pData->pbData == NULL)
  667. return FALSE;
  668. memset((void*)pData->pbData, 0, pData->cbData);
  669. if (!pDispatchInfo->pfGet(
  670. pSubjectInfo,
  671. &dwEncodingType,
  672. 0,
  673. &(pData->cbData),
  674. pData->pbData))
  675. {
  676. delete[](pData->pbData);
  677. delete[](pSubjectInfo);
  678. delete[](pDispatchInfo);
  679. return FALSE;
  680. }
  681. delete[](pSubjectInfo);
  682. delete[](pDispatchInfo);
  683. return TRUE;
  684. }
  685. BOOL
  686. CheckForTimeStamp(WCHAR *pwszFile)
  687. {
  688. BOOL fRet = TRUE;
  689. HANDLE hFile = INVALID_HANDLE_VALUE;
  690. HCRYPTMSG hMsg = NULL;
  691. BYTE *pb = NULL;
  692. DWORD cb = 0;
  693. DWORD cbRead = 0;
  694. PCMSG_ATTR pMsgAttr = NULL;
  695. DWORD cbMsgAttr = 0;
  696. CRYPT_ATTRIBUTE *pAttr = NULL;
  697. CRYPT_DATA_BLOB blob;
  698. DWORD dwEncodingType;
  699. if (!ReadMsgBlob(pwszFile, &blob))
  700. {
  701. return FALSE;
  702. }
  703. //
  704. // If the encoded message was passed in the use CryptMsg to crack the encoded PKCS7 Signed Message
  705. //
  706. if (!(hMsg = CryptMsgOpenToDecode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
  707. 0,
  708. 0,
  709. 0,
  710. NULL,
  711. NULL)))
  712. {
  713. goto ErrorReturn;
  714. }
  715. if (!CryptMsgUpdate(hMsg,
  716. blob.pbData,
  717. blob.cbData,
  718. TRUE)) // fFinal
  719. {
  720. CryptMsgClose(hMsg);
  721. goto ErrorReturn;
  722. }
  723. //
  724. // get the unauthenticated attributes because that is where the counter signer is
  725. //
  726. CryptMsgGetParam(hMsg,
  727. CMSG_SIGNER_UNAUTH_ATTR_PARAM,
  728. 0,
  729. NULL,
  730. &cbMsgAttr);
  731. if (cbMsgAttr == 0)
  732. {
  733. goto ErrorReturn;
  734. }
  735. if (NULL == (pMsgAttr = (CMSG_ATTR *) new(BYTE[cbMsgAttr])))
  736. {
  737. goto ErrorReturn;
  738. }
  739. if (!CryptMsgGetParam(hMsg,
  740. CMSG_SIGNER_UNAUTH_ATTR_PARAM,
  741. 0,
  742. (void *) pMsgAttr,
  743. &cbMsgAttr))
  744. {
  745. goto ErrorReturn;
  746. }
  747. //
  748. // search for the counter signer in the unauthenticated attributes
  749. //
  750. if ((pAttr = CertFindAttribute(szOID_RSA_counterSign,
  751. pMsgAttr->cAttr,
  752. pMsgAttr->rgAttr)) == NULL)
  753. {
  754. //
  755. // no counter signature
  756. //
  757. goto ErrorReturn;
  758. }
  759. Cleanup:
  760. delete[](blob.pbData);
  761. if (pMsgAttr)
  762. delete[](pMsgAttr);
  763. if (hMsg != NULL)
  764. CryptMsgClose(hMsg);
  765. return fRet;
  766. ErrorReturn:
  767. fRet = FALSE;
  768. goto Cleanup;
  769. }
  770. int _ShowError(DWORD dwError, WCHAR *pwszFile)
  771. {
  772. pPrint->Display(IDS_FILEREF, pwszFile);
  773. if (fCheckExpectedError)
  774. {
  775. if (dwError == dwExpectedError)
  776. {
  777. pPrint->Display(IDS_SUCCEEDED);
  778. return(0);
  779. }
  780. else
  781. {
  782. pPrint->Display(IDS_EXPECTED_HRESULT, dwExpectedError, dwError);
  783. return(1);
  784. }
  785. }
  786. switch(dwError)
  787. {
  788. case S_OK:
  789. pPrint->Display(IDS_SUCCEEDED);
  790. if (fNoTimeStampWarning)
  791. {
  792. if (!CheckForTimeStamp(pwszFile))
  793. {
  794. pPrint->Display(IDS_NO_TIMESTAMP_WARNING);
  795. return(2);
  796. }
  797. }
  798. return(0);
  799. case TRUST_E_SUBJECT_FORM_UNKNOWN:
  800. pPrint->Display(IDS_UNKNOWN_FILE_TYPE);
  801. break;
  802. case TRUST_E_PROVIDER_UNKNOWN:
  803. pPrint->Display(IDS_UNKNOWN_PROVIDER);
  804. break;
  805. case TRUST_E_ACTION_UNKNOWN:
  806. pPrint->Display(IDS_UNKNOWN_ACTION);
  807. break;
  808. case TRUST_E_SUBJECT_NOT_TRUSTED:
  809. pPrint->Display(IDS_SUBJECT_NOT_TRUSTED);
  810. break;
  811. default:
  812. pPrint->Display(IDS_FAIL, GetLastError());
  813. break;
  814. }
  815. return(1);
  816. }
  817. HRESULT _AddCatalogToDatabase(WCHAR *pwszFileIn)
  818. {
  819. HCATINFO hCatInfo;
  820. WCHAR *pwszBaseName;
  821. if (!(hCatAdmin))
  822. {
  823. if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0)))
  824. {
  825. return(GetLastError());
  826. }
  827. }
  828. //
  829. // set the base file name
  830. //
  831. if (!(pwszBaseName = wcsrchr(pwszFileIn, L'\\')))
  832. {
  833. pwszBaseName = wcsrchr(pwszFileIn, L':');
  834. }
  835. if (pwszBaseName)
  836. {
  837. *pwszBaseName++;
  838. }
  839. else
  840. {
  841. pwszBaseName = pwszFileIn;
  842. }
  843. if (hCatInfo = CryptCATAdminAddCatalog(hCatAdmin, pwszFileIn, fReplaceCatfile ? pwszBaseName : NULL, 0))
  844. {
  845. CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
  846. return(ERROR_SUCCESS);
  847. }
  848. return(GetLastError());
  849. }
  850. HRESULT _DelCatalogFromDatabase(WCHAR *pwszFileIn)
  851. {
  852. HCATINFO hCatInfo;
  853. WCHAR *pwszBaseName;
  854. typedef BOOL (WINAPI * PCRYPTCATADMINREMOVECATALOG)(HCATADMIN, WCHAR *, DWORD);
  855. HRESULT hr = S_OK;
  856. HMODULE hDLL = NULL;
  857. PCRYPTCATADMINREMOVECATALOG pCryptCATAdminRemoveCatalog = NULL;
  858. if (!(hCatAdmin))
  859. {
  860. if (!(CryptCATAdminAcquireContext(&hCatAdmin, pguidCatRoot, 0)))
  861. {
  862. return(GetLastError());
  863. }
  864. }
  865. //
  866. // set the base file name
  867. //
  868. if (!(pwszBaseName = wcsrchr(pwszFileIn, L'\\')))
  869. {
  870. pwszBaseName = wcsrchr(pwszFileIn, L':');
  871. }
  872. if (pwszBaseName)
  873. {
  874. *pwszBaseName++;
  875. }
  876. else
  877. {
  878. pwszBaseName = pwszFileIn;
  879. }
  880. if (hDLL = LoadLibraryA("wintrust.dll"))
  881. {
  882. if (pCryptCATAdminRemoveCatalog = (PCRYPTCATADMINREMOVECATALOG)
  883. GetProcAddress(hDLL,
  884. "CryptCATAdminRemoveCatalog"))
  885. {
  886. if (!pCryptCATAdminRemoveCatalog(hCatAdmin, pwszBaseName, 0))
  887. {
  888. hr = GetLastError();
  889. }
  890. }
  891. else
  892. {
  893. hr = HRESULT_FROM_WIN32(GetLastError());
  894. }
  895. FreeLibrary(hDLL);
  896. }
  897. else
  898. {
  899. hr = HRESULT_FROM_WIN32(GetLastError());
  900. }
  901. return(hr);
  902. }
  903. void _ToLower(WCHAR *pwszInOut)
  904. {
  905. while (*pwszInOut)
  906. {
  907. *pwszInOut = towlower(*pwszInOut);
  908. pwszInOut++;
  909. }
  910. }