Module: wine Branch: master Commit: 036128842a2945e2e1b048abbbfe470efed47303 URL: http://source.winehq.org/git/wine.git/?a=commit;h=036128842a2945e2e1b048abbb...
Author: Juan Lang juan.lang@gmail.com Date: Mon Sep 22 13:19:59 2008 -0700
wintrust: Check that the end certificate in the chain isn't disallowed to match native behavior.
---
dlls/wintrust/softpub.c | 75 +++++++++++++++++++++++++++++++++------------- 1 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/dlls/wintrust/softpub.c b/dlls/wintrust/softpub.c index 06238b2..52df73d 100644 --- a/dlls/wintrust/softpub.c +++ b/dlls/wintrust/softpub.c @@ -784,27 +784,60 @@ HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data) ret = TRUE; for (i = 0; ret && i < data->csSigners; i++) { - CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 }; - - if (data->dwRegPolicySettings & WTPF_TRUSTTEST) - policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; - if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID) - policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG; - if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION) - policyPara.dwFlags |= - CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | - CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | - CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG; - if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION) - policyPara.dwFlags |= - CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG; - CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, - data->pasSigners[i].pChainContext, &policyPara, &policyStatus); - if (policyStatus.dwError != NO_ERROR) - ret = FALSE; + BYTE hash[20]; + DWORD size = sizeof(hash); + + /* First make sure cert isn't disallowed */ + if ((ret = CertGetCertificateContextProperty( + data->pasSigners[i].pasCertChain[0].pCert, + CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) + { + static const WCHAR disallowedW[] = + { 'D','i','s','a','l','l','o','w','e','d',0 }; + HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, + X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, + disallowedW); + + if (disallowed) + { + PCCERT_CONTEXT found = CertFindCertificateInStore( + disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, + hash, NULL); + + if (found) + { + /* Disallowed! Can't verify it. */ + policyStatus.dwError = TRUST_E_SUBJECT_NOT_TRUSTED; + ret = FALSE; + CertFreeCertificateContext(found); + } + CertCloseStore(disallowed, 0); + } + } + if (ret) + { + CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 }; + + if (data->dwRegPolicySettings & WTPF_TRUSTTEST) + policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; + if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID) + policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG; + if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION) + policyPara.dwFlags |= + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | + CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG; + if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION) + policyPara.dwFlags |= + CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG; + CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, + data->pasSigners[i].pChainContext, &policyPara, &policyStatus); + if (policyStatus.dwError != NO_ERROR) + ret = FALSE; + } } } if (!ret)