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.

253 lines
8.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: authcode.cpp
  8. //
  9. // Contents: Microsoft Internet Security Authenticode Policy Provider
  10. //
  11. // Functions: SoftpubAuthenticode
  12. //
  13. // History: 05-Jun-1997 pberkman created
  14. //
  15. //--------------------------------------------------------------------------
  16. #include "global.hxx"
  17. // Following is also called from .\httpsprv.cpp
  18. void UpdateCertError(
  19. IN PCRYPT_PROVIDER_SGNR pSgnr,
  20. IN PCERT_CHAIN_POLICY_STATUS pPolicyStatus
  21. )
  22. {
  23. PCCERT_CHAIN_CONTEXT pChainContext = pSgnr->pChainContext;
  24. LONG lChainIndex = pPolicyStatus->lChainIndex;
  25. LONG lElementIndex = pPolicyStatus->lElementIndex;
  26. DWORD dwProvCertIndex;
  27. LONG i;
  28. assert (lChainIndex < (LONG) pChainContext->cChain);
  29. if (0 > lChainIndex || lChainIndex >= (LONG) pChainContext->cChain ||
  30. 0 > lElementIndex) {
  31. if (CERT_E_CHAINING == pPolicyStatus->dwError) {
  32. if (0 < pSgnr->csCertChain) {
  33. PCRYPT_PROVIDER_CERT pProvCert;
  34. pProvCert = WTHelperGetProvCertFromChain(
  35. pSgnr, pSgnr->csCertChain - 1);
  36. if (0 == pProvCert->dwError)
  37. pProvCert->dwError = pPolicyStatus->dwError;
  38. }
  39. }
  40. return;
  41. }
  42. dwProvCertIndex = 0;
  43. for (i = 0; i < lChainIndex; i++) {
  44. PCERT_SIMPLE_CHAIN pChain = pChainContext->rgpChain[i];
  45. dwProvCertIndex += pChain->cElement;
  46. }
  47. dwProvCertIndex += lElementIndex;
  48. if (dwProvCertIndex < pSgnr->csCertChain) {
  49. PCRYPT_PROVIDER_CERT pProvCert;
  50. pProvCert = WTHelperGetProvCertFromChain(pSgnr, dwProvCertIndex);
  51. pProvCert->dwError = pPolicyStatus->dwError;
  52. }
  53. }
  54. HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *pProvData)
  55. {
  56. DWORD dwError;
  57. DWORD i1;
  58. AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA ExtraPolicyPara;
  59. memset(&ExtraPolicyPara, 0, sizeof(ExtraPolicyPara));
  60. ExtraPolicyPara.cbSize = sizeof(ExtraPolicyPara);
  61. ExtraPolicyPara.dwRegPolicySettings = pProvData->dwRegPolicySettings;
  62. CERT_CHAIN_POLICY_PARA PolicyPara;
  63. memset(&PolicyPara, 0, sizeof(PolicyPara));
  64. PolicyPara.cbSize = sizeof(PolicyPara);
  65. PolicyPara.pvExtraPolicyPara = (void *) &ExtraPolicyPara;
  66. AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS ExtraPolicyStatus;
  67. memset(&ExtraPolicyStatus, 0, sizeof(ExtraPolicyStatus));
  68. ExtraPolicyStatus.cbSize = sizeof(ExtraPolicyStatus);
  69. CERT_CHAIN_POLICY_STATUS PolicyStatus;
  70. memset(&PolicyStatus, 0, sizeof(PolicyStatus));
  71. PolicyStatus.cbSize = sizeof(PolicyStatus);
  72. PolicyStatus.pvExtraPolicyStatus = (void *) &ExtraPolicyStatus;
  73. //
  74. // check the high level error codes. For SAFER, must also have a
  75. // signer and subject hash.
  76. //
  77. dwError = checkGetErrorBasedOnStepErrors(pProvData);
  78. // Check if we have a valid signature
  79. if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] != 0 ||
  80. NULL == pProvData->pPDSip ||
  81. NULL == pProvData->pPDSip->psIndirectData ||
  82. 0 == pProvData->pPDSip->psIndirectData->Digest.cbData)
  83. {
  84. if (pProvData->dwProvFlags & (WTD_SAFER_FLAG | WTD_HASH_ONLY_FLAG))
  85. {
  86. pProvData->dwFinalError = dwError;
  87. return TRUST_E_NOSIGNATURE;
  88. }
  89. }
  90. else if (pProvData->dwProvFlags & WTD_HASH_ONLY_FLAG)
  91. {
  92. pProvData->dwFinalError = 0;
  93. return S_OK;
  94. }
  95. if (0 != dwError)
  96. {
  97. goto CommonReturn;
  98. }
  99. //
  100. // check each signer
  101. //
  102. for (i1 = 0; i1 < pProvData->csSigners; i1++) {
  103. CRYPT_PROVIDER_SGNR *pSgnr;
  104. LPSTR pszUsage;
  105. pSgnr = WTHelperGetProvSignerFromChain(pProvData, i1, FALSE, 0);
  106. pszUsage = pProvData->pszUsageOID;
  107. if (pszUsage && 0 != strcmp(pszUsage, szOID_PKIX_KP_CODE_SIGNING))
  108. // Inhibit checking of signer purpose
  109. ExtraPolicyPara.pSignerInfo = NULL;
  110. else
  111. ExtraPolicyPara.pSignerInfo = pSgnr->psSigner;
  112. if (!CertVerifyCertificateChainPolicy(
  113. CERT_CHAIN_POLICY_AUTHENTICODE,
  114. pSgnr->pChainContext,
  115. &PolicyPara,
  116. &PolicyStatus
  117. )) {
  118. dwError = TRUST_E_SYSTEM_ERROR;
  119. goto CommonReturn;
  120. }
  121. if (CERT_E_REVOCATION_FAILURE == PolicyStatus.dwError &&
  122. (pProvData->dwProvFlags & WTD_SAFER_FLAG)) {
  123. // For SAFER, ignore NO_CHECK errors
  124. if (0 == (pSgnr->pChainContext->TrustStatus.dwErrorStatus &
  125. CERT_TRUST_IS_OFFLINE_REVOCATION)) {
  126. PolicyStatus.dwError = 0;
  127. }
  128. }
  129. if (0 != PolicyStatus.dwError) {
  130. dwError = PolicyStatus.dwError;
  131. UpdateCertError(pSgnr, &PolicyStatus);
  132. goto CommonReturn;
  133. } else if (0 < pSgnr->csCertChain) {
  134. PCRYPT_PROVIDER_CERT pProvCert;
  135. pProvCert = WTHelperGetProvCertFromChain(pSgnr, 0);
  136. if (CERT_E_REVOCATION_FAILURE == pProvCert->dwError) {
  137. // Policy says to ignore offline revocation errors
  138. pProvCert->dwError = 0;
  139. pProvCert->dwRevokedReason = 0;
  140. }
  141. }
  142. if (pSgnr->csCounterSigners) {
  143. AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA TSExtraPolicyPara;
  144. memset(&TSExtraPolicyPara, 0, sizeof(TSExtraPolicyPara));
  145. TSExtraPolicyPara.cbSize = sizeof(TSExtraPolicyPara);
  146. TSExtraPolicyPara.dwRegPolicySettings =
  147. pProvData->dwRegPolicySettings;
  148. TSExtraPolicyPara.fCommercial = ExtraPolicyStatus.fCommercial;
  149. CERT_CHAIN_POLICY_PARA TSPolicyPara;
  150. memset(&TSPolicyPara, 0, sizeof(TSPolicyPara));
  151. TSPolicyPara.cbSize = sizeof(TSPolicyPara);
  152. TSPolicyPara.pvExtraPolicyPara = (void *) &TSExtraPolicyPara;
  153. CERT_CHAIN_POLICY_STATUS TSPolicyStatus;
  154. memset(&TSPolicyStatus, 0, sizeof(TSPolicyStatus));
  155. TSPolicyStatus.cbSize = sizeof(TSPolicyStatus);
  156. //
  157. // check counter signers
  158. //
  159. for (DWORD i2 = 0; i2 < pSgnr->csCounterSigners; i2++)
  160. {
  161. PCRYPT_PROVIDER_SGNR pCounterSgnr =
  162. WTHelperGetProvSignerFromChain(pProvData, i1, TRUE, i2);
  163. //
  164. // do we care about this counter signer?
  165. //
  166. if (pCounterSgnr->dwSignerType != SGNR_TYPE_TIMESTAMP)
  167. continue;
  168. if (!CertVerifyCertificateChainPolicy(
  169. CERT_CHAIN_POLICY_AUTHENTICODE_TS,
  170. pCounterSgnr->pChainContext,
  171. &TSPolicyPara,
  172. &TSPolicyStatus
  173. )) {
  174. dwError = TRUST_E_SYSTEM_ERROR;
  175. goto CommonReturn;
  176. }
  177. if (CERT_E_REVOCATION_FAILURE == TSPolicyStatus.dwError &&
  178. (pProvData->dwProvFlags & WTD_SAFER_FLAG)) {
  179. // For SAFER, ignore NO_CHECK errors
  180. if (0 == (pCounterSgnr->pChainContext->TrustStatus.dwErrorStatus &
  181. CERT_TRUST_IS_OFFLINE_REVOCATION)) {
  182. TSPolicyStatus.dwError = 0;
  183. }
  184. }
  185. if (0 != TSPolicyStatus.dwError) {
  186. // On April 13, 1999 changed to map all time stamp errors
  187. // to TRUST_E_TIME_STAMP
  188. dwError = TRUST_E_TIME_STAMP;
  189. // dwError = TSPolicyStatus.dwError;
  190. UpdateCertError(pCounterSgnr, &TSPolicyStatus);
  191. goto CommonReturn;
  192. } else if (0 < pCounterSgnr->csCertChain) {
  193. PCRYPT_PROVIDER_CERT pProvCert;
  194. pProvCert = WTHelperGetProvCertFromChain(pCounterSgnr, 0);
  195. if (CERT_E_REVOCATION_FAILURE == pProvCert->dwError) {
  196. // Policy says to ignore offline revocation errors
  197. pProvCert->dwError = 0;
  198. pProvCert->dwRevokedReason = 0;
  199. }
  200. }
  201. }
  202. }
  203. }
  204. dwError = 0;
  205. CommonReturn:
  206. pProvData->dwFinalError = dwError;
  207. return SoftpubCallUI(pProvData, dwError, TRUE);
  208. }