|
|
//+-------------------------------------------------------------------------
//
// 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); }
|