crypt32(4/6): Implement CertVerifyCertificateChainPolicy for the
base policy
Juan Lang
juan.lang at gmail.com
Mon Sep 10 18:15:01 CDT 2007
--Juan
-------------- next part --------------
From a04d041aa5c6c2bb6c3eafd915fef32eadf511b4 Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Mon, 10 Sep 2007 16:11:49 -0700
Subject: [PATCH] Implement CertVerifyCertificateChainPolicy for the base policy
---
dlls/crypt32/chain.c | 86 +++++++++++++++++++++++++++++++++++++++++++-
dlls/crypt32/tests/chain.c | 42 ++++++++++++++++++---
2 files changed, 119 insertions(+), 9 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 7b6d7bd..8249596 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -1021,11 +1021,93 @@ void WINAPI CertFreeCertificateChain(PCC
}
}
+static void find_element_with_error(PCCERT_CHAIN_CONTEXT chain, DWORD error,
+ LONG *iChain, LONG *iElement)
+{
+ DWORD i, j;
+
+ for (i = 0; i < chain->cChain; i++)
+ for (j = 0; j < chain->rgpChain[i]->cElement; j++)
+ if (chain->rgpChain[i]->rgpElement[j]->TrustStatus.dwErrorStatus &
+ error)
+ {
+ *iChain = i;
+ *iElement = j;
+ return;
+ }
+}
+
+static BOOL WINAPI verify_base_policy(LPCSTR szPolicyOID,
+ PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara,
+ PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
+{
+ pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1;
+ if (pChainContext->TrustStatus.dwErrorStatus &
+ CERT_TRUST_IS_NOT_SIGNATURE_VALID)
+ {
+ pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE;
+ find_element_with_error(pChainContext,
+ CERT_TRUST_IS_NOT_SIGNATURE_VALID, &pPolicyStatus->lChainIndex,
+ &pPolicyStatus->lElementIndex);
+ }
+ else if (pChainContext->TrustStatus.dwErrorStatus &
+ CERT_TRUST_IS_UNTRUSTED_ROOT)
+ {
+ pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT;
+ find_element_with_error(pChainContext,
+ CERT_TRUST_IS_UNTRUSTED_ROOT, &pPolicyStatus->lChainIndex,
+ &pPolicyStatus->lElementIndex);
+ }
+ else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC)
+ {
+ pPolicyStatus->dwError = CERT_E_CHAINING;
+ find_element_with_error(pChainContext, CERT_TRUST_IS_CYCLIC,
+ &pPolicyStatus->lChainIndex, &pPolicyStatus->lElementIndex);
+ /* For a cyclic chain, which element is a cycle isn't meaningful */
+ pPolicyStatus->lElementIndex = -1;
+ }
+ return TRUE;
+}
+
+typedef BOOL (WINAPI *CertVerifyCertificateChainPolicyFunc)(LPCSTR szPolicyOID,
+ PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara,
+ PCERT_CHAIN_POLICY_STATUS pPolicyStatus);
+
BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID,
PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara,
PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
{
- FIXME("(%s, %p, %p, %p): stub\n", debugstr_a(szPolicyOID), pChainContext,
+ static HCRYPTOIDFUNCSET set = NULL;
+ BOOL ret = FALSE;
+ CertVerifyCertificateChainPolicyFunc verifyPolicy = NULL;
+ HCRYPTOIDFUNCADDR hFunc = NULL;
+
+ TRACE("(%s, %p, %p, %p)\n", debugstr_a(szPolicyOID), pChainContext,
pPolicyPara, pPolicyStatus);
- return FALSE;
+
+ if (!HIWORD(szPolicyOID))
+ {
+ switch (LOWORD(szPolicyOID))
+ {
+ case (int)CERT_CHAIN_POLICY_BASE:
+ verifyPolicy = verify_base_policy;
+ break;
+ default:
+ FIXME("unimplemented for %d\n", LOWORD(szPolicyOID));
+ }
+ }
+ if (!verifyPolicy)
+ {
+ if (!set)
+ set = CryptInitOIDFunctionSet(
+ CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC, 0);
+ CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, szPolicyOID, 0,
+ (void **)&verifyPolicy, hFunc);
+ }
+ if (verifyPolicy)
+ ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara,
+ pPolicyStatus);
+ if (hFunc)
+ CryptFreeOIDFunctionAddress(hFunc, 0);
+ return ret;
}
diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c
index cbbf0aa..fd8952f 100644
--- a/dlls/crypt32/tests/chain.c
+++ b/dlls/crypt32/tests/chain.c
@@ -1717,6 +1717,39 @@ typedef struct _ChainPolicyCheck
static ChainPolicyCheck basePolicyCheck[] = {
{ { sizeof(chain0) / sizeof(chain0[0]), chain0 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain1) / sizeof(chain1[0]), chain1 },
+ { 0, TRUST_E_CERT_SIGNATURE, 0, 0, NULL }, 0 },
+ { { sizeof(chain2) / sizeof(chain2[0]), chain2 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain3) / sizeof(chain3[0]), chain3 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain4) / sizeof(chain4[0]), chain4 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, 0 },
+ { { sizeof(chain5) / sizeof(chain5[0]), chain5 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain6) / sizeof(chain6[0]), chain6 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain7) / sizeof(chain7[0]), chain7 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain8) / sizeof(chain8[0]), chain8 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, 0 },
+ { { sizeof(chain9) / sizeof(chain9[0]), chain9 },
+ { 0, CERT_E_CHAINING, 0, -1, NULL }, 0 },
+ { { sizeof(chain10) / sizeof(chain10[0]), chain10 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain11) / sizeof(chain11[0]), chain11 },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, 0 },
+ { { sizeof(chain12) / sizeof(chain12[0]), chain12 },
+ { 0, TRUST_E_CERT_SIGNATURE, 0, 1, NULL }, 0 },
+ { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain },
+ { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, 0 },
+ { { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain },
+ { 0, 0, -1, -1, NULL }, 0 },
+};
+
+static ChainPolicyCheck authenticodePolicyCheck[] = {
+ { { sizeof(chain0) / sizeof(chain0[0]), chain0 },
{ 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL },
TODO_POLICY },
{ { sizeof(chain1) / sizeof(chain1[0]), chain1 },
@@ -1881,7 +1914,6 @@ static void testVerifyCertChainPolicy(vo
*/
SetLastError(0xdeadbeef);
ret = CertVerifyCertificateChainPolicy(NULL, NULL, NULL, &policyStatus);
- todo_wine
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
"Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
/* Crashes
@@ -1902,9 +1934,7 @@ static void testVerifyCertChainPolicy(vo
/* Size of policy status is apparently ignored, as is pChainPolicyPara */
ret = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain, NULL,
&policyStatus);
- todo_wine
ok(ret, "CertVerifyCertificateChainPolicy failed: %08x\n", GetLastError());
- todo_wine
ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT,
"Expected CERT_E_UNTRUSTEDROOT, got %08x\n", policyStatus.dwError);
ok(policyStatus.lChainIndex == 0 && policyStatus.lElementIndex == 0,
@@ -1912,9 +1942,7 @@ static void testVerifyCertChainPolicy(vo
policyStatus.lElementIndex);
ret = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain,
&policyPara, &policyStatus);
- todo_wine
ok(ret, "CertVerifyCertificateChainPolicy failed: %08x\n", GetLastError());
- todo_wine
ok(policyStatus.dwError == CERT_E_UNTRUSTEDROOT,
"Expected CERT_E_UNTRUSTEDROOT, got %08x\n", policyStatus.dwError);
ok(policyStatus.lChainIndex == 0 && policyStatus.lElementIndex == 0,
@@ -1930,9 +1958,9 @@ static void testVerifyCertChainPolicy(vo
* of these chains is.
*/
for (i = 0; i <
- sizeof(basePolicyCheck) / sizeof(basePolicyCheck[0]); i++)
+ sizeof(authenticodePolicyCheck) / sizeof(authenticodePolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE,
- &basePolicyCheck[i], i);
+ &authenticodePolicyCheck[i], i);
for (i = 0; i <
sizeof(basicConstraintsPolicyCheck) / sizeof(basicConstraintsPolicyCheck[0]);
i++)
--
1.4.1
More information about the wine-patches
mailing list