crypt32: Check time of each element in chain against requested time.
This commit is contained in:
parent
d06a24517f
commit
51948b0c98
|
@ -296,7 +296,6 @@ static BOOL CRYPT_AddCertToSimpleChain(PCertificateChainEngine engine,
|
||||||
if (dwFlags & CERT_STORE_SIGNATURE_FLAG)
|
if (dwFlags & CERT_STORE_SIGNATURE_FLAG)
|
||||||
element->TrustStatus.dwErrorStatus |=
|
element->TrustStatus.dwErrorStatus |=
|
||||||
CERT_TRUST_IS_NOT_SIGNATURE_VALID;
|
CERT_TRUST_IS_NOT_SIGNATURE_VALID;
|
||||||
/* FIXME: check valid usages and name constraints */
|
|
||||||
/* FIXME: initialize the rest of element */
|
/* FIXME: initialize the rest of element */
|
||||||
chain->rgpElement[chain->cElement++] = element;
|
chain->rgpElement[chain->cElement++] = element;
|
||||||
if (chain->cElement % engine->CycleDetectionModulus)
|
if (chain->cElement % engine->CycleDetectionModulus)
|
||||||
|
@ -341,6 +340,50 @@ static void CRYPT_CheckTrustedStatus(HCERTSTORE hRoot,
|
||||||
CertFreeCertificateContext(trustedRoot);
|
CertFreeCertificateContext(trustedRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_CheckRootCert(HCERTCHAINENGINE hRoot,
|
||||||
|
PCERT_CHAIN_ELEMENT rootElement)
|
||||||
|
{
|
||||||
|
PCCERT_CONTEXT root = rootElement->pCertContext;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (!(ret = CryptVerifyCertificateSignatureEx(0, root->dwCertEncodingType,
|
||||||
|
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)root,
|
||||||
|
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)root, 0, NULL)))
|
||||||
|
{
|
||||||
|
TRACE("Last certificate's signature is invalid\n");
|
||||||
|
rootElement->TrustStatus.dwErrorStatus |=
|
||||||
|
CERT_TRUST_IS_NOT_SIGNATURE_VALID;
|
||||||
|
}
|
||||||
|
CRYPT_CheckTrustedStatus(hRoot, rootElement);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
||||||
|
PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
|
||||||
|
{
|
||||||
|
PCERT_CHAIN_ELEMENT rootElement = chain->rgpElement[chain->cElement - 1];
|
||||||
|
DWORD i;
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < chain->cElement; i++)
|
||||||
|
{
|
||||||
|
if (CertVerifyTimeValidity(time,
|
||||||
|
chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
|
||||||
|
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
|
||||||
|
CERT_TRUST_IS_NOT_TIME_VALID;
|
||||||
|
/* FIXME: check valid usages and name constraints */
|
||||||
|
CRYPT_CombineTrustStatus(&chain->TrustStatus,
|
||||||
|
&chain->rgpElement[i]->TrustStatus);
|
||||||
|
}
|
||||||
|
if (CRYPT_IsCertificateSelfSigned(rootElement->pCertContext))
|
||||||
|
{
|
||||||
|
rootElement->TrustStatus.dwInfoStatus |= CERT_TRUST_IS_SELF_SIGNED;
|
||||||
|
ret = CRYPT_CheckRootCert(engine->hRoot, rootElement);
|
||||||
|
}
|
||||||
|
CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL CRYPT_BuildSimpleChain(HCERTCHAINENGINE hChainEngine,
|
static BOOL CRYPT_BuildSimpleChain(HCERTCHAINENGINE hChainEngine,
|
||||||
PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
||||||
PCERT_SIMPLE_CHAIN *ppChain)
|
PCERT_SIMPLE_CHAIN *ppChain)
|
||||||
|
@ -384,29 +427,7 @@ static BOOL CRYPT_BuildSimpleChain(HCERTCHAINENGINE hChainEngine,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
ret = CRYPT_CheckSimpleChain(engine, chain, pTime);
|
||||||
PCERT_CHAIN_ELEMENT rootElement =
|
|
||||||
chain->rgpElement[chain->cElement - 1];
|
|
||||||
PCCERT_CONTEXT root = rootElement->pCertContext;
|
|
||||||
|
|
||||||
if (CRYPT_IsCertificateSelfSigned(root))
|
|
||||||
{
|
|
||||||
rootElement->TrustStatus.dwInfoStatus |=
|
|
||||||
CERT_TRUST_IS_SELF_SIGNED;
|
|
||||||
if (!(ret = CryptVerifyCertificateSignatureEx(0,
|
|
||||||
root->dwCertEncodingType, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
|
|
||||||
(void *)root, CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)root,
|
|
||||||
0, NULL)))
|
|
||||||
{
|
|
||||||
TRACE("Last certificate's signature is invalid\n");
|
|
||||||
rootElement->TrustStatus.dwErrorStatus |=
|
|
||||||
CERT_TRUST_IS_NOT_SIGNATURE_VALID;
|
|
||||||
}
|
|
||||||
CRYPT_CheckTrustedStatus(engine->hRoot, rootElement);
|
|
||||||
}
|
|
||||||
CRYPT_CombineTrustStatus(&chain->TrustStatus,
|
|
||||||
&rootElement->TrustStatus);
|
|
||||||
}
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
CRYPT_FreeSimpleChain(chain);
|
CRYPT_FreeSimpleChain(chain);
|
||||||
|
|
|
@ -1485,7 +1485,7 @@ static ChainCheck chainCheck[] = {
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_VALID, 0 },
|
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_VALID, 0 },
|
||||||
1, simpleStatus0 },
|
1, simpleStatus0 },
|
||||||
TODO_ERROR | TODO_INFO },
|
TODO_INFO },
|
||||||
{ { sizeof(chain1) / sizeof(chain1[0]), chain1 },
|
{ { sizeof(chain1) / sizeof(chain1[0]), chain1 },
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_SIGNATURE_VALID |
|
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_SIGNATURE_VALID |
|
||||||
|
@ -1496,7 +1496,7 @@ static ChainCheck chainCheck[] = {
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_VALID, 0 },
|
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_VALID, 0 },
|
||||||
1, simpleStatus2 },
|
1, simpleStatus2 },
|
||||||
TODO_ERROR | TODO_INFO },
|
TODO_INFO },
|
||||||
{ { sizeof(chain3) / sizeof(chain3[0]), chain3 },
|
{ { sizeof(chain3) / sizeof(chain3[0]), chain3 },
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
|
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
|
||||||
|
@ -1518,11 +1518,11 @@ static ChainCheck chainCheck[] = {
|
||||||
{ { sizeof(chain6) / sizeof(chain6[0]), chain6 },
|
{ { sizeof(chain6) / sizeof(chain6[0]), chain6 },
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus6 },
|
{ CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus6 },
|
||||||
TODO_ERROR | TODO_INFO },
|
TODO_INFO },
|
||||||
{ { sizeof(chain7) / sizeof(chain7[0]), chain7 },
|
{ { sizeof(chain7) / sizeof(chain7[0]), chain7 },
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus7 },
|
{ CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus7 },
|
||||||
TODO_ERROR | TODO_INFO },
|
TODO_INFO },
|
||||||
{ { sizeof(chain8) / sizeof(chain8[0]), chain8 },
|
{ { sizeof(chain8) / sizeof(chain8[0]), chain8 },
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
|
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
|
||||||
|
@ -1547,7 +1547,7 @@ static ChainCheck chainCheck[] = {
|
||||||
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||||
{ CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 },
|
{ CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 },
|
||||||
1, selfSignedSimpleStatus },
|
1, selfSignedSimpleStatus },
|
||||||
TODO_ERROR | TODO_INFO },
|
TODO_INFO },
|
||||||
/* The iTunes chain may or may not have its root trusted, so ignore the
|
/* The iTunes chain may or may not have its root trusted, so ignore the
|
||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue