//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: authcode.cpp // // Contents: Microsoft Internet Security Authenticode Policy Provider // // Functions: SoftpubAuthenticode // // History: 05-Jun-1997 pberkman created // //-------------------------------------------------------------------------- #include "global.hxx" // Following is also called from .\httpsprv.cpp void UpdateCertError( IN PCRYPT_PROVIDER_SGNR pSgnr, IN PCERT_CHAIN_POLICY_STATUS pPolicyStatus ) { PCCERT_CHAIN_CONTEXT pChainContext = pSgnr->pChainContext; LONG lChainIndex = pPolicyStatus->lChainIndex; LONG lElementIndex = pPolicyStatus->lElementIndex; DWORD dwProvCertIndex; LONG i; assert (lChainIndex < (LONG) pChainContext->cChain); if (0 > lChainIndex || lChainIndex >= (LONG) pChainContext->cChain || 0 > lElementIndex) { if (CERT_E_CHAINING == pPolicyStatus->dwError) { if (0 < pSgnr->csCertChain) { PCRYPT_PROVIDER_CERT pProvCert; pProvCert = WTHelperGetProvCertFromChain( pSgnr, pSgnr->csCertChain - 1); if (0 == pProvCert->dwError) pProvCert->dwError = pPolicyStatus->dwError; } } return; } dwProvCertIndex = 0; for (i = 0; i < lChainIndex; i++) { PCERT_SIMPLE_CHAIN pChain = pChainContext->rgpChain[i]; dwProvCertIndex += pChain->cElement; } dwProvCertIndex += lElementIndex; if (dwProvCertIndex < pSgnr->csCertChain) { PCRYPT_PROVIDER_CERT pProvCert; pProvCert = WTHelperGetProvCertFromChain(pSgnr, dwProvCertIndex); pProvCert->dwError = pPolicyStatus->dwError; } } HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *pProvData) { DWORD dwError; DWORD i1; AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA ExtraPolicyPara; memset(&ExtraPolicyPara, 0, sizeof(ExtraPolicyPara)); ExtraPolicyPara.cbSize = sizeof(ExtraPolicyPara); ExtraPolicyPara.dwRegPolicySettings = pProvData->dwRegPolicySettings; CERT_CHAIN_POLICY_PARA PolicyPara; memset(&PolicyPara, 0, sizeof(PolicyPara)); PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.pvExtraPolicyPara = (void *) &ExtraPolicyPara; AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS ExtraPolicyStatus; memset(&ExtraPolicyStatus, 0, sizeof(ExtraPolicyStatus)); ExtraPolicyStatus.cbSize = sizeof(ExtraPolicyStatus); CERT_CHAIN_POLICY_STATUS PolicyStatus; memset(&PolicyStatus, 0, sizeof(PolicyStatus)); PolicyStatus.cbSize = sizeof(PolicyStatus); PolicyStatus.pvExtraPolicyStatus = (void *) &ExtraPolicyStatus; // // check the high level error codes. For SAFER, must also have a // signer and subject hash. // dwError = checkGetErrorBasedOnStepErrors(pProvData); // Check if we have a valid signature if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] != 0 || NULL == pProvData->pPDSip || NULL == pProvData->pPDSip->psIndirectData || 0 == pProvData->pPDSip->psIndirectData->Digest.cbData) { if (pProvData->dwProvFlags & (WTD_SAFER_FLAG | WTD_HASH_ONLY_FLAG)) { pProvData->dwFinalError = dwError; return TRUST_E_NOSIGNATURE; } } else if (pProvData->dwProvFlags & WTD_HASH_ONLY_FLAG) { pProvData->dwFinalError = 0; return S_OK; } if (0 != dwError) { goto CommonReturn; } // // check each signer // for (i1 = 0; i1 < pProvData->csSigners; i1++) { CRYPT_PROVIDER_SGNR *pSgnr; LPSTR pszUsage; pSgnr = WTHelperGetProvSignerFromChain(pProvData, i1, FALSE, 0); pszUsage = pProvData->pszUsageOID; if (pszUsage && 0 != strcmp(pszUsage, szOID_PKIX_KP_CODE_SIGNING)) // Inhibit checking of signer purpose ExtraPolicyPara.pSignerInfo = NULL; else ExtraPolicyPara.pSignerInfo = pSgnr->psSigner; if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_AUTHENTICODE, pSgnr->pChainContext, &PolicyPara, &PolicyStatus )) { dwError = TRUST_E_SYSTEM_ERROR; goto CommonReturn; } if (CERT_E_REVOCATION_FAILURE == PolicyStatus.dwError && (pProvData->dwProvFlags & WTD_SAFER_FLAG)) { // For SAFER, ignore NO_CHECK errors if (0 == (pSgnr->pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_OFFLINE_REVOCATION)) { PolicyStatus.dwError = 0; } } if (0 != PolicyStatus.dwError) { dwError = PolicyStatus.dwError; UpdateCertError(pSgnr, &PolicyStatus); goto CommonReturn; } else if (0 < pSgnr->csCertChain) { PCRYPT_PROVIDER_CERT pProvCert; pProvCert = WTHelperGetProvCertFromChain(pSgnr, 0); if (CERT_E_REVOCATION_FAILURE == pProvCert->dwError) { // Policy says to ignore offline revocation errors pProvCert->dwError = 0; pProvCert->dwRevokedReason = 0; } } if (pSgnr->csCounterSigners) { AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA TSExtraPolicyPara; memset(&TSExtraPolicyPara, 0, sizeof(TSExtraPolicyPara)); TSExtraPolicyPara.cbSize = sizeof(TSExtraPolicyPara); TSExtraPolicyPara.dwRegPolicySettings = pProvData->dwRegPolicySettings; TSExtraPolicyPara.fCommercial = ExtraPolicyStatus.fCommercial; CERT_CHAIN_POLICY_PARA TSPolicyPara; memset(&TSPolicyPara, 0, sizeof(TSPolicyPara)); TSPolicyPara.cbSize = sizeof(TSPolicyPara); TSPolicyPara.pvExtraPolicyPara = (void *) &TSExtraPolicyPara; CERT_CHAIN_POLICY_STATUS TSPolicyStatus; memset(&TSPolicyStatus, 0, sizeof(TSPolicyStatus)); TSPolicyStatus.cbSize = sizeof(TSPolicyStatus); // // check counter signers // for (DWORD i2 = 0; i2 < pSgnr->csCounterSigners; i2++) { PCRYPT_PROVIDER_SGNR pCounterSgnr = WTHelperGetProvSignerFromChain(pProvData, i1, TRUE, i2); // // do we care about this counter signer? // if (pCounterSgnr->dwSignerType != SGNR_TYPE_TIMESTAMP) continue; if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_AUTHENTICODE_TS, pCounterSgnr->pChainContext, &TSPolicyPara, &TSPolicyStatus )) { dwError = TRUST_E_SYSTEM_ERROR; goto CommonReturn; } if (CERT_E_REVOCATION_FAILURE == TSPolicyStatus.dwError && (pProvData->dwProvFlags & WTD_SAFER_FLAG)) { // For SAFER, ignore NO_CHECK errors if (0 == (pCounterSgnr->pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_OFFLINE_REVOCATION)) { TSPolicyStatus.dwError = 0; } } if (0 != TSPolicyStatus.dwError) { // On April 13, 1999 changed to map all time stamp errors // to TRUST_E_TIME_STAMP dwError = TRUST_E_TIME_STAMP; // dwError = TSPolicyStatus.dwError; UpdateCertError(pCounterSgnr, &TSPolicyStatus); goto CommonReturn; } else if (0 < pCounterSgnr->csCertChain) { PCRYPT_PROVIDER_CERT pProvCert; pProvCert = WTHelperGetProvCertFromChain(pCounterSgnr, 0); if (CERT_E_REVOCATION_FAILURE == pProvCert->dwError) { // Policy says to ignore offline revocation errors pProvCert->dwError = 0; pProvCert->dwRevokedReason = 0; } } } } } dwError = 0; CommonReturn: pProvData->dwFinalError = dwError; return SoftpubCallUI(pProvData, dwError, TRUE); }