crypt32: Implement CertVerifyCertificateChainPolicy for the base policy.
This commit is contained in:
parent
f23ec30534
commit
b56f0c5b68
|
@ -1021,11 +1021,93 @@ void WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1716,6 +1716,39 @@ typedef struct _ChainPolicyCheck
|
|||
} 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 },
|
||||
|
@ -1881,7 +1914,6 @@ static void testVerifyCertChainPolicy(void)
|
|||
*/
|
||||
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(void)
|
|||
/* 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(void)
|
|||
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(void)
|
|||
* 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++)
|
||||
|
|
Loading…
Reference in New Issue