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.

462 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: callui.cpp
  8. //
  9. // Contents: Microsoft Internet Security Authenticode Policy Provider
  10. //
  11. // Functions: SoftpubCallUI
  12. //
  13. // *** local functions ***
  14. // _AllocGetOpusInfo
  15. //
  16. // History: 06-Jun-1997 pberkman created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include "global.hxx"
  20. #include "trustdb.h"
  21. #include "acui.h"
  22. #include "winsafer.h"
  23. SPC_SP_OPUS_INFO *_AllocGetOpusInfo(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pSigner,
  24. DWORD *pcbOpusInfo);
  25. #define MIN_HASH_LEN 16
  26. #define MAX_HASH_LEN 20
  27. // Returns:
  28. // S_FALSE
  29. // not found in the database
  30. // TRUST_E_SYSTEM_ERROR
  31. // system errors while attempting to do the check
  32. // S_OK
  33. // found in the database
  34. // TRUST_E_EXPLICIT_DISTRUST
  35. // explicitly disallowed in the database or revoked
  36. HRESULT _CheckTrustedPublisher(
  37. CRYPT_PROVIDER_DATA *pProvData,
  38. DWORD dwError,
  39. BOOL fOnlyDisallowed
  40. )
  41. {
  42. CRYPT_PROVIDER_SGNR *pSigner;
  43. PCCERT_CONTEXT pPubCert;
  44. BYTE rgbHash[MAX_HASH_LEN];
  45. CRYPT_DATA_BLOB HashBlob;
  46. HCERTSTORE hStore;
  47. if (CERT_E_REVOKED == dwError)
  48. {
  49. return TRUST_E_EXPLICIT_DISTRUST;
  50. }
  51. pSigner = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
  52. if (NULL == pSigner || pSigner->csCertChain <= 0)
  53. {
  54. return S_FALSE;
  55. }
  56. pPubCert = WTHelperGetProvCertFromChain(pSigner, 0)->pCert;
  57. // Check if disallowed.
  58. // Since the signature component can be altered, must use the signature
  59. // hash
  60. HashBlob.pbData = rgbHash;
  61. HashBlob.cbData = MAX_HASH_LEN;
  62. if (!CertGetCertificateContextProperty(
  63. pPubCert,
  64. CERT_SIGNATURE_HASH_PROP_ID,
  65. rgbHash,
  66. &HashBlob.cbData
  67. ) || MIN_HASH_LEN > HashBlob.cbData)
  68. {
  69. return TRUST_E_SYSTEM_ERROR;
  70. }
  71. hStore = OpenDisallowedStore();
  72. if (hStore)
  73. {
  74. PCCERT_CONTEXT pFoundCert;
  75. pFoundCert = CertFindCertificateInStore(
  76. hStore,
  77. 0, // dwCertEncodingType
  78. 0, // dwFindFlags
  79. CERT_FIND_SIGNATURE_HASH,
  80. (const void *) &HashBlob,
  81. NULL //pPrevCertContext
  82. );
  83. CertCloseStore(hStore, 0);
  84. if (pFoundCert)
  85. {
  86. CertFreeCertificateContext(pFoundCert);
  87. return TRUST_E_EXPLICIT_DISTRUST;
  88. }
  89. }
  90. if (fOnlyDisallowed)
  91. {
  92. return S_FALSE;
  93. }
  94. if (S_OK != dwError)
  95. {
  96. // Everything must be valid to allow a trusted publisher
  97. return S_FALSE;
  98. }
  99. // Check if trusted publisher
  100. hStore = OpenTrustedPublisherStore();
  101. if (hStore)
  102. {
  103. PCCERT_CONTEXT pFoundCert;
  104. pFoundCert = CertFindCertificateInStore(
  105. hStore,
  106. 0, // dwCertEncodingType
  107. 0, // dwFindFlags
  108. CERT_FIND_SIGNATURE_HASH,
  109. (const void *) &HashBlob,
  110. NULL //pPrevCertContext
  111. );
  112. CertCloseStore(hStore, 0);
  113. if (pFoundCert)
  114. {
  115. CertFreeCertificateContext(pFoundCert);
  116. return S_OK;
  117. }
  118. }
  119. return S_FALSE;
  120. }
  121. typedef BOOL (WINAPI *PFN_SAFERI_SEARCH_MATCHING_HASH_RULES)(
  122. IN ALG_ID HashAlgorithm OPTIONAL,
  123. IN PBYTE pHashBytes,
  124. IN DWORD dwHashSize,
  125. IN DWORD dwOriginalImageSize OPTIONAL,
  126. OUT PDWORD pdwFoundLevel,
  127. OUT PDWORD pdwUIFlags
  128. );
  129. // Returns:
  130. // S_FALSE
  131. // not found in the database
  132. // S_OK
  133. // fully trusted in the database
  134. // TRUST_E_EXPLICIT_DISTRUST
  135. // explicitly disallowed in the database
  136. HRESULT _CheckTrustedCodeHash(CRYPT_PROVIDER_DATA *pProvData)
  137. {
  138. static BOOL fGotProcAddr = FALSE;
  139. static PFN_SAFERI_SEARCH_MATCHING_HASH_RULES
  140. pfnCodeAuthzSearchMatchingHashRules = NULL;
  141. DWORD cbHash;
  142. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] == 0 &&
  143. pProvData->pPDSip && pProvData->pPDSip->psIndirectData)
  144. {
  145. cbHash = pProvData->pPDSip->psIndirectData->Digest.cbData;
  146. }
  147. else
  148. {
  149. cbHash = 0;
  150. }
  151. if (0 == cbHash)
  152. {
  153. return S_FALSE;
  154. }
  155. // wintrust.dll has a static dependency on advapi32.dll. However, not
  156. // all advapi32.dll's will export "SaferiSearchMatchingHashRules"
  157. if (!fGotProcAddr)
  158. {
  159. HMODULE hModule;
  160. hModule = GetModuleHandleA("advapi32.dll");
  161. if (NULL != hModule)
  162. {
  163. pfnCodeAuthzSearchMatchingHashRules =
  164. (PFN_SAFERI_SEARCH_MATCHING_HASH_RULES) GetProcAddress(
  165. hModule, "SaferiSearchMatchingHashRules");
  166. }
  167. fGotProcAddr = TRUE;
  168. }
  169. if (NULL != pfnCodeAuthzSearchMatchingHashRules)
  170. {
  171. __try
  172. {
  173. DWORD dwFoundLevel = 0xFFFFFFFF;
  174. DWORD dwUIFlags = 0;
  175. if (pfnCodeAuthzSearchMatchingHashRules(
  176. CertOIDToAlgId(pProvData->pPDSip->psIndirectData->DigestAlgorithm.pszObjId),
  177. pProvData->pPDSip->psIndirectData->Digest.pbData,
  178. cbHash,
  179. 0, // dwOriginalImageSize
  180. &dwFoundLevel,
  181. &dwUIFlags
  182. ))
  183. {
  184. switch (dwFoundLevel)
  185. {
  186. case SAFER_LEVELID_FULLYTRUSTED:
  187. return S_OK;
  188. case SAFER_LEVELID_DISALLOWED:
  189. return TRUST_E_EXPLICIT_DISTRUST;
  190. }
  191. }
  192. }
  193. __except(EXCEPTION_EXECUTE_HANDLER)
  194. {
  195. }
  196. }
  197. return S_FALSE;
  198. }
  199. HRESULT SoftpubCallUI(CRYPT_PROVIDER_DATA *pProvData, DWORD dwError, BOOL fFinalCall)
  200. {
  201. HRESULT hr;
  202. DWORD dwUIChoice;
  203. if (!(fFinalCall))
  204. {
  205. // TBDTBD: if we want the user to get involved along the way???
  206. return(ERROR_SUCCESS);
  207. }
  208. if (0 == (pProvData->dwProvFlags & WTD_SAFER_FLAG))
  209. {
  210. if (!(pProvData->dwRegPolicySettings & WTPF_ALLOWONLYPERTRUST) &&
  211. (pProvData->pWintrustData->dwUIChoice == WTD_UI_NONE))
  212. {
  213. if (S_OK == dwError || ((DWORD) CERT_E_REVOKED) == dwError)
  214. {
  215. //
  216. // Check for explicitly trusted or disallowed code
  217. //
  218. hr = _CheckTrustedCodeHash(pProvData);
  219. if (S_FALSE != hr)
  220. {
  221. if (S_OK == hr)
  222. {
  223. // Ensure we always indicate trust.
  224. pProvData->dwFinalError = 0;
  225. }
  226. return hr;
  227. }
  228. //
  229. // Check for untrusted publisher
  230. //
  231. hr = _CheckTrustedPublisher(pProvData, dwError, TRUE);
  232. if (TRUST_E_EXPLICIT_DISTRUST == hr)
  233. {
  234. return TRUST_E_EXPLICIT_DISTRUST;
  235. }
  236. }
  237. return(dwError);
  238. }
  239. }
  240. //
  241. // Check for trusted or disallowed subject hash
  242. //
  243. hr = _CheckTrustedCodeHash(pProvData);
  244. if (S_FALSE != hr)
  245. {
  246. if (S_OK == hr)
  247. {
  248. // Ensure we always indicate trust.
  249. pProvData->dwFinalError = 0;
  250. }
  251. return hr;
  252. }
  253. //
  254. // Check for trusted or disallowed publisher
  255. //
  256. hr = _CheckTrustedPublisher(pProvData, dwError, FALSE);
  257. if (S_FALSE != hr)
  258. {
  259. if (S_OK == hr)
  260. {
  261. // Ensure we always indicate trust.
  262. pProvData->dwFinalError = 0;
  263. }
  264. return hr;
  265. }
  266. if (pProvData->dwRegPolicySettings & WTPF_ALLOWONLYPERTRUST)
  267. {
  268. if (0 == dwError)
  269. {
  270. return CRYPT_E_SECURITY_SETTINGS;
  271. }
  272. return dwError;
  273. }
  274. dwUIChoice = pProvData->pWintrustData->dwUIChoice;
  275. if ((dwUIChoice == WTD_UI_NONE) ||
  276. ((dwUIChoice == WTD_UI_NOBAD) && (dwError != ERROR_SUCCESS)) ||
  277. ((dwUIChoice == WTD_UI_NOGOOD) && (dwError == ERROR_SUCCESS)))
  278. {
  279. if (0 == dwError)
  280. {
  281. // No explicit trust
  282. pProvData->dwFinalError = TRUST_E_SUBJECT_NOT_TRUSTED;
  283. }
  284. return dwError;
  285. }
  286. //
  287. // call the ui
  288. //
  289. HINSTANCE hModule = NULL;
  290. IPersonalTrustDB *pTrustDB = NULL;
  291. ACUI_INVOKE_INFO aii;
  292. pfnACUIProviderInvokeUI pfn = NULL;
  293. DWORD cbOpusInfo;
  294. CRYPT_PROVIDER_SGNR *pRootSigner;
  295. pRootSigner = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
  296. OpenTrustDB(NULL, IID_IPersonalTrustDB, (LPVOID*)&pTrustDB);
  297. memset(&aii, 0x00, sizeof(ACUI_INVOKE_INFO));
  298. //
  299. // Setup the UI invokation
  300. //
  301. aii.cbSize = sizeof(ACUI_INVOKE_INFO);
  302. aii.hDisplay = pProvData->hWndParent;
  303. aii.pProvData = pProvData;
  304. aii.hrInvokeReason = dwError;
  305. aii.pwcsAltDisplayName = WTHelperGetFileName(pProvData->pWintrustData);
  306. aii.pPersonalTrustDB = (IUnknown *)pTrustDB;
  307. if (pRootSigner)
  308. {
  309. aii.pOpusInfo = _AllocGetOpusInfo(pProvData, pRootSigner, &cbOpusInfo);
  310. }
  311. //
  312. // Load the default authenticode UI.
  313. //
  314. if (hModule = LoadLibraryA(CVP_DLL))
  315. {
  316. pfn = (pfnACUIProviderInvokeUI)GetProcAddress(hModule, "ACUIProviderInvokeUI");
  317. }
  318. //
  319. // Invoke the UI
  320. //
  321. if (pfn)
  322. {
  323. hr = (*pfn)(&aii);
  324. }
  325. else
  326. {
  327. hr = TRUST_E_PROVIDER_UNKNOWN;
  328. pProvData->dwError = hr;
  329. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_UIPROV] = hr;
  330. DBG_PRINTF((DBG_SS, "Unable to load CRYPTUI.DLL\n"));
  331. }
  332. //
  333. // Return the appropriate code
  334. //
  335. if (pTrustDB)
  336. {
  337. pTrustDB->Release();
  338. }
  339. if (aii.pOpusInfo)
  340. {
  341. TrustFreeDecode(WVT_MODID_SOFTPUB, (BYTE **)&aii.pOpusInfo);
  342. }
  343. if (hModule)
  344. {
  345. FreeLibrary(hModule);
  346. }
  347. return hr;
  348. }
  349. SPC_SP_OPUS_INFO *_AllocGetOpusInfo(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pSigner,
  350. DWORD *pcbOpusInfo)
  351. {
  352. PCRYPT_ATTRIBUTE pAttr;
  353. PSPC_SP_OPUS_INFO pInfo;
  354. pInfo = NULL;
  355. if (!(pSigner->psSigner))
  356. {
  357. goto NoSigner;
  358. }
  359. if (pSigner->psSigner->AuthAttrs.cAttr == 0)
  360. {
  361. goto NoOpusAttribute;
  362. }
  363. if (!(pAttr = CertFindAttribute(SPC_SP_OPUS_INFO_OBJID,
  364. pSigner->psSigner->AuthAttrs.cAttr,
  365. pSigner->psSigner->AuthAttrs.rgAttr)))
  366. {
  367. goto NoOpusAttribute;
  368. }
  369. if (!(pAttr->rgValue))
  370. {
  371. goto NoOpusAttribute;
  372. }
  373. if (!(TrustDecode(WVT_MODID_SOFTPUB, (BYTE **)&pInfo, pcbOpusInfo, 200,
  374. pProvData->dwEncoding, SPC_SP_OPUS_INFO_STRUCT,
  375. pAttr->rgValue->pbData, pAttr->rgValue->cbData, CRYPT_DECODE_NOCOPY_FLAG)))
  376. {
  377. goto DecodeError;
  378. }
  379. return(pInfo);
  380. ErrorReturn:
  381. return(NULL);
  382. TRACE_ERROR_EX(DBG_SS, NoSigner);
  383. TRACE_ERROR_EX(DBG_SS, NoOpusAttribute);
  384. TRACE_ERROR_EX(DBG_SS, DecodeError);
  385. }