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.

521 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: httpsprv.cpp
  8. //
  9. // Contents: Microsoft Internet Security Authenticode Policy Provider
  10. //
  11. // Functions: HTTPSRegisterServer
  12. // HTTPSUnregisterServer
  13. // HTTPSCertificateTrust
  14. // HTTPSFinalProv
  15. //
  16. // History: 29-Jul-1997 pberkman created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include "global.hxx"
  20. #include <wininet.h>
  21. DWORD GetErrorBasedOnStepErrors(CRYPT_PROVIDER_DATA *pProvData);
  22. //////////////////////////////////////////////////////////////////////////////
  23. //
  24. // HTTPSRegisterServer
  25. //----------------------------------------------------------------------------
  26. // Register the HTTPS provider
  27. //
  28. STDAPI HTTPSRegisterServer(void)
  29. {
  30. GUID gHTTPSProv = HTTPSPROV_ACTION;
  31. BOOL fRet;
  32. CRYPT_REGISTER_ACTIONID sRegAID;
  33. CRYPT_PROVIDER_REGDEFUSAGE sDefUsage;
  34. fRet = TRUE;
  35. //
  36. // set the usages we want
  37. //
  38. memset(&sDefUsage, 0x00, sizeof(CRYPT_PROVIDER_REGDEFUSAGE));
  39. sDefUsage.cbStruct = sizeof(CRYPT_PROVIDER_REGDEFUSAGE);
  40. sDefUsage.pgActionID = &gHTTPSProv;
  41. sDefUsage.pwszDllName = SP_POLICY_PROVIDER_DLL_NAME;
  42. sDefUsage.pwszLoadCallbackDataFunctionName = "SoftpubLoadDefUsageCallData";
  43. sDefUsage.pwszFreeCallbackDataFunctionName = "SoftpubFreeDefUsageCallData";
  44. fRet &= WintrustAddDefaultForUsage(szOID_PKIX_KP_SERVER_AUTH, &sDefUsage);
  45. fRet &= WintrustAddDefaultForUsage(szOID_PKIX_KP_CLIENT_AUTH, &sDefUsage);
  46. fRet &= WintrustAddDefaultForUsage(szOID_SERVER_GATED_CRYPTO, &sDefUsage);
  47. fRet &= WintrustAddDefaultForUsage(szOID_SGC_NETSCAPE, &sDefUsage);
  48. memset(&sRegAID, 0x00, sizeof(CRYPT_REGISTER_ACTIONID));
  49. sRegAID.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
  50. // Authenticode initialization provider
  51. sRegAID.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  52. sRegAID.sInitProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  53. sRegAID.sInitProvider.pwszFunctionName = SP_INIT_FUNCTION;
  54. // Authenticode object provider
  55. sRegAID.sObjectProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  56. sRegAID.sObjectProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  57. sRegAID.sObjectProvider.pwszFunctionName = SP_OBJTRUST_FUNCTION;
  58. // Authenticode signature provider
  59. sRegAID.sSignatureProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  60. sRegAID.sSignatureProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  61. sRegAID.sSignatureProvider.pwszFunctionName = SP_SIGTRUST_FUNCTION;
  62. // wintrust's certificate provider
  63. sRegAID.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  64. #if 0
  65. sRegAID.sCertificateProvider.pwszDLLName = WT_PROVIDER_DLL_NAME; // set to wintrust.dll
  66. sRegAID.sCertificateProvider.pwszFunctionName = WT_PROVIDER_CERTTRUST_FUNCTION; // use wintrust's standard!
  67. #else
  68. // philh changed on Feb 19, 1998 to use HTTPS
  69. sRegAID.sCertificateProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  70. sRegAID.sCertificateProvider.pwszFunctionName = HTTPS_CERTTRUST_FUNCTION;
  71. #endif
  72. // authenticode cert policy
  73. sRegAID.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  74. sRegAID.sCertificatePolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  75. sRegAID.sCertificatePolicyProvider.pwszFunctionName = SP_CHKCERT_FUNCTION;
  76. // custom final ...
  77. sRegAID.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  78. sRegAID.sFinalPolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  79. sRegAID.sFinalPolicyProvider.pwszFunctionName = HTTPS_FINALPOLICY_FUNCTION;
  80. // Authenticode cleanup -- we don't store any data.
  81. sRegAID.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
  82. sRegAID.sCleanupProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
  83. sRegAID.sCleanupProvider.pwszFunctionName = SP_CLEANUPPOLICY_FUNCTION;
  84. fRet &= WintrustAddActionID(&gHTTPSProv, 0, &sRegAID);
  85. return((fRet) ? S_OK : S_FALSE);
  86. }
  87. //////////////////////////////////////////////////////////////////////////////
  88. //
  89. // DllUnregisterServer
  90. //----------------------------------------------------------------------------
  91. // unregisters schannel provider
  92. //
  93. STDAPI HTTPSUnregisterServer(void)
  94. {
  95. GUID gHTTPSProv = HTTPSPROV_ACTION;
  96. WintrustRemoveActionID(&gHTTPSProv);
  97. return(S_OK);
  98. }
  99. HCERTCHAINENGINE HTTPSGetChainEngine(
  100. IN CRYPT_PROVIDER_DATA *pProvData
  101. )
  102. {
  103. CERT_CHAIN_ENGINE_CONFIG Config;
  104. HCERTSTORE hStore = NULL;
  105. HCERTCHAINENGINE hChainEngine = NULL;
  106. if (NULL == pProvData->pWintrustData ||
  107. pProvData->pWintrustData->dwUnionChoice != WTD_CHOICE_CERT ||
  108. !_ISINSTRUCT(WINTRUST_CERT_INFO,
  109. pProvData->pWintrustData->pCert->cbStruct, dwFlags) ||
  110. 0 == (pProvData->pWintrustData->pCert->dwFlags &
  111. (WTCI_DONT_OPEN_STORES | WTCI_OPEN_ONLY_ROOT)))
  112. return NULL;
  113. memset(&Config, 0, sizeof(Config));
  114. Config.cbSize = sizeof(Config);
  115. if (NULL == (hStore = CertOpenStore(
  116. CERT_STORE_PROV_MEMORY,
  117. 0, // dwEncodingType
  118. 0, // hCryptProv
  119. 0, // dwFlags
  120. NULL // pvPara
  121. )))
  122. goto OpenMemoryStoreError;
  123. if (pProvData->pWintrustData->pCert->dwFlags & WTCI_DONT_OPEN_STORES)
  124. Config.hRestrictedRoot = hStore;
  125. Config.hRestrictedTrust = hStore;
  126. Config.hRestrictedOther = hStore;
  127. if (!CertCreateCertificateChainEngine(
  128. &Config,
  129. &hChainEngine
  130. ))
  131. goto CreateChainEngineError;
  132. CommonReturn:
  133. CertCloseStore(hStore, 0);
  134. return hChainEngine;
  135. ErrorReturn:
  136. hChainEngine = NULL;
  137. goto CommonReturn;
  138. TRACE_ERROR_EX(DBG_SS, OpenMemoryStoreError)
  139. TRACE_ERROR_EX(DBG_SS, CreateChainEngineError)
  140. }
  141. HCERTSTORE HTTPSGetChainAdditionalStore(
  142. IN CRYPT_PROVIDER_DATA *pProvData
  143. )
  144. {
  145. if (0 == pProvData->chStores)
  146. return NULL;
  147. if (1 < pProvData->chStores) {
  148. HCERTSTORE hCollectionStore;
  149. if (hCollectionStore = CertOpenStore(
  150. CERT_STORE_PROV_COLLECTION,
  151. 0, // dwEncodingType
  152. 0, // hCryptProv
  153. 0, // dwFlags
  154. NULL // pvPara
  155. )) {
  156. DWORD i;
  157. for (i = 0; i < pProvData->chStores; i++)
  158. CertAddStoreToCollection(
  159. hCollectionStore,
  160. pProvData->pahStores[i],
  161. CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
  162. 0 // dwPriority
  163. );
  164. }
  165. return hCollectionStore;
  166. } else
  167. return CertDuplicateStore(pProvData->pahStores[0]);
  168. }
  169. // Following is in ..\wintrust\certtrst.cpp
  170. extern
  171. BOOL UpdateCertProvChain(
  172. IN OUT PCRYPT_PROVIDER_DATA pProvData,
  173. IN DWORD idxSigner,
  174. OUT DWORD *pdwError,
  175. IN BOOL fCounterSigner,
  176. IN DWORD idxCounterSigner,
  177. IN PCRYPT_PROVIDER_SGNR pSgnr,
  178. IN PCCERT_CHAIN_CONTEXT pChainContext
  179. );
  180. // Following is in .\authcode.cpp
  181. extern
  182. void UpdateCertError(
  183. IN PCRYPT_PROVIDER_SGNR pSgnr,
  184. IN PCERT_CHAIN_POLICY_STATUS pPolicyStatus
  185. );
  186. HRESULT WINAPI HTTPSCertificateTrust(CRYPT_PROVIDER_DATA *pProvData)
  187. {
  188. HTTPSPolicyCallbackData *pHTTPS;
  189. CRYPT_PROVIDER_SGNR *pSgnr;
  190. CRYPT_PROVIDER_CERT *pProvCert;
  191. DWORD dwError;
  192. DWORD dwSgnrError;
  193. DWORD dwCreateChainFlags;
  194. CERT_CHAIN_PARA ChainPara;
  195. HCERTCHAINENGINE hChainEngine = NULL;
  196. HCERTSTORE hAdditionalStore = NULL;
  197. PCCERT_CHAIN_CONTEXT pChainContext = NULL;
  198. LPSTR rgpszClientUsage[] = {
  199. szOID_PKIX_KP_CLIENT_AUTH,
  200. };
  201. #define CLIENT_USAGE_COUNT (sizeof(rgpszClientUsage) / \
  202. sizeof(rgpszClientUsage[0]))
  203. LPSTR rgpszServerUsage[] = {
  204. szOID_PKIX_KP_SERVER_AUTH,
  205. szOID_SERVER_GATED_CRYPTO,
  206. szOID_SGC_NETSCAPE,
  207. };
  208. #define SERVER_USAGE_COUNT (sizeof(rgpszServerUsage) / \
  209. sizeof(rgpszServerUsage[0]))
  210. if ((_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, fRecallWithState)) &&
  211. (pProvData->fRecallWithState == TRUE))
  212. {
  213. return(S_OK);
  214. }
  215. pSgnr = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
  216. if (pSgnr)
  217. pProvCert = WTHelperGetProvCertFromChain(pSgnr, 0);
  218. if (NULL == pSgnr || NULL == pProvCert) {
  219. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
  220. TRUST_E_NOSIGNATURE;
  221. return S_FALSE;
  222. }
  223. pHTTPS = (HTTPSPolicyCallbackData *) pProvData->pWintrustData->pPolicyCallbackData;
  224. if (!pHTTPS || !WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(
  225. HTTPSPolicyCallbackData, pHTTPS->cbStruct, pwszServerName) ||
  226. !_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, dwProvFlags) ||
  227. (pProvData->dwProvFlags & WTD_USE_IE4_TRUST_FLAG) ||
  228. !_ISINSTRUCT(CRYPT_PROVIDER_SGNR, pSgnr->cbStruct, pChainContext))
  229. {
  230. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
  231. ERROR_INVALID_PARAMETER;
  232. return S_FALSE;
  233. }
  234. pProvData->dwProvFlags |= CPD_USE_NT5_CHAIN_FLAG;
  235. dwCreateChainFlags = 0;
  236. memset(&ChainPara, 0, sizeof(ChainPara));
  237. ChainPara.cbSize = sizeof(ChainPara);
  238. ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
  239. if (pHTTPS->dwAuthType == AUTHTYPE_CLIENT) {
  240. ChainPara.RequestedUsage.Usage.cUsageIdentifier = CLIENT_USAGE_COUNT;
  241. ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgpszClientUsage;
  242. } else {
  243. ChainPara.RequestedUsage.Usage.cUsageIdentifier = SERVER_USAGE_COUNT;
  244. ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgpszServerUsage;
  245. }
  246. if (0 == (pHTTPS->fdwChecks & SECURITY_FLAG_IGNORE_REVOCATION)) {
  247. if (pProvData->pWintrustData->fdwRevocationChecks != WTD_REVOKE_NONE)
  248. // On 4-16-01 changed from END_CERT to EXCLUDE_ROOT
  249. dwCreateChainFlags |= CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
  250. }
  251. hChainEngine = HTTPSGetChainEngine(pProvData);
  252. hAdditionalStore = HTTPSGetChainAdditionalStore(pProvData);
  253. if (!CertGetCertificateChain (
  254. hChainEngine,
  255. pProvCert->pCert,
  256. &pSgnr->sftVerifyAsOf,
  257. hAdditionalStore,
  258. &ChainPara,
  259. dwCreateChainFlags,
  260. NULL, // pvReserved,
  261. &pChainContext
  262. )) {
  263. pProvData->dwError = GetLastError();
  264. dwSgnrError = TRUST_E_SYSTEM_ERROR;
  265. goto GetChainError;
  266. }
  267. if (WTD_STATEACTION_VERIFY == pProvData->pWintrustData->dwStateAction) {
  268. DWORD dwUpdateError;
  269. UpdateCertProvChain(
  270. pProvData,
  271. 0, // idxSigner
  272. &dwUpdateError,
  273. FALSE, // fCounterSigner
  274. 0, // idxCounterSigner
  275. pSgnr,
  276. pChainContext
  277. );
  278. dwSgnrError = pSgnr->dwError;
  279. if (CERT_E_REVOKED == dwSgnrError ||
  280. CERT_E_REVOCATION_FAILURE == dwSgnrError) {
  281. // Clear the updated errors. Will be updated in the final policy
  282. pSgnr->dwError = 0;
  283. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] = 0;
  284. if (CERT_E_REVOKED == pProvCert->dwError ||
  285. CERT_E_REVOCATION_FAILURE == pProvCert->dwError) {
  286. pProvCert->dwError = 0;
  287. }
  288. }
  289. }
  290. dwError = S_OK;
  291. CommonReturn:
  292. if (hChainEngine)
  293. CertFreeCertificateChainEngine(hChainEngine);
  294. if (hAdditionalStore)
  295. CertCloseStore(hAdditionalStore, 0);
  296. pSgnr->pChainContext = pChainContext;
  297. return dwError;
  298. ErrorReturn:
  299. pSgnr->dwError = dwSgnrError;
  300. pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
  301. dwSgnrError;
  302. dwError = S_FALSE;
  303. goto CommonReturn;
  304. TRACE_ERROR_EX(DBG_SS, GetChainError)
  305. }
  306. //////////////////////////////////////////////////////////////////////////////
  307. //
  308. // Final Policy Provider function: HTTPSFinalProv
  309. //----------------------------------------------------------------------------
  310. // Check the outcome of the previous functions and display UI based on this.
  311. //
  312. // On July 26, 2000, disabled the use of the test root
  313. #if 0
  314. void MapHTTPSRegPolicySettingsToBaseChainPolicyFlags(
  315. IN DWORD dwRegPolicySettings,
  316. IN OUT DWORD *pdwFlags
  317. )
  318. {
  319. DWORD dwFlags;
  320. if (0 == dwRegPolicySettings)
  321. return;
  322. dwFlags = *pdwFlags;
  323. if (dwRegPolicySettings & WTPF_TRUSTTEST)
  324. dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
  325. if (dwRegPolicySettings & WTPF_TESTCANBEVALID)
  326. dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG;
  327. *pdwFlags = dwFlags;
  328. }
  329. #endif
  330. HRESULT WINAPI HTTPSFinalProv(CRYPT_PROVIDER_DATA *pProvData)
  331. {
  332. HTTPSPolicyCallbackData *pHTTPS;
  333. pHTTPS = (HTTPSPolicyCallbackData *)
  334. pProvData->pWintrustData->pPolicyCallbackData;
  335. if (!(pHTTPS) ||
  336. !(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(HTTPSPolicyCallbackData,
  337. pHTTPS->cbStruct, pwszServerName)))
  338. {
  339. SetLastError(ERROR_INVALID_PARAMETER);
  340. return(ERROR_INVALID_PARAMETER);
  341. }
  342. DWORD dwError;
  343. CRYPT_PROVIDER_SGNR *pSgnr;
  344. CERT_CHAIN_POLICY_PARA PolicyPara;
  345. memset(&PolicyPara, 0, sizeof(PolicyPara));
  346. PolicyPara.cbSize = sizeof(PolicyPara);
  347. PolicyPara.pvExtraPolicyPara = (void *) pHTTPS;
  348. CERT_CHAIN_POLICY_STATUS PolicyStatus;
  349. memset(&PolicyStatus, 0, sizeof(PolicyStatus));
  350. PolicyStatus.cbSize = sizeof(PolicyStatus);
  351. //
  352. // check the high level error codes.
  353. //
  354. if (0 != (dwError = GetErrorBasedOnStepErrors(pProvData)))
  355. goto CommonReturn;
  356. pSgnr = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
  357. if (pSgnr == NULL) {
  358. dwError = TRUST_E_SYSTEM_ERROR;
  359. goto CommonReturn;
  360. }
  361. // On July 26, 2000, disabled the use of the test root
  362. #if 0
  363. MapHTTPSRegPolicySettingsToBaseChainPolicyFlags(
  364. pProvData->dwRegPolicySettings,
  365. &PolicyPara.dwFlags
  366. );
  367. #endif
  368. if (!CertVerifyCertificateChainPolicy(
  369. CERT_CHAIN_POLICY_SSL,
  370. pSgnr->pChainContext,
  371. &PolicyPara,
  372. &PolicyStatus
  373. )) {
  374. dwError = TRUST_E_SYSTEM_ERROR;
  375. goto CommonReturn;
  376. } else if (0 != PolicyStatus.dwError) {
  377. dwError = PolicyStatus.dwError;
  378. UpdateCertError(pSgnr, &PolicyStatus);
  379. goto CommonReturn;
  380. }
  381. dwError = 0;
  382. CommonReturn:
  383. pProvData->dwFinalError = dwError;
  384. return dwError;
  385. }
  386. ///////////////////////////////////////////////////////////////////////////////////
  387. //
  388. // Local Functions
  389. //
  390. ///////////////////////////////////////////////////////////////////////////////////
  391. DWORD GetErrorBasedOnStepErrors(CRYPT_PROVIDER_DATA *pProvData)
  392. {
  393. //
  394. // initial allocation of the step errors?
  395. //
  396. if (!(pProvData->padwTrustStepErrors))
  397. {
  398. return(ERROR_NOT_ENOUGH_MEMORY);
  399. }
  400. //
  401. // did we fail in one of the last steps?
  402. //
  403. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != 0)
  404. {
  405. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV]);
  406. }
  407. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] != 0)
  408. {
  409. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
  410. }
  411. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] != 0)
  412. {
  413. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV]);
  414. }
  415. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] != 0)
  416. {
  417. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
  418. }
  419. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTCHKPROV] != 0)
  420. {
  421. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTCHKPROV]);
  422. }
  423. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] != 0)
  424. {
  425. return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
  426. }
  427. return(ERROR_SUCCESS);
  428. }