Commit d94e4d31 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Permit lack of key usage extension on root certificates.

This reverts 60770fb0, although it updates the comments to give a reason. Thanks to Matt Van Gundy for pointing it out to me.
parent 27027590
...@@ -1083,7 +1083,7 @@ static void dump_element(PCCERT_CONTEXT cert) ...@@ -1083,7 +1083,7 @@ static void dump_element(PCCERT_CONTEXT cert)
} }
static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine, static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
PCCERT_CONTEXT cert, BOOL isCA, DWORD index) PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
{ {
PCERT_EXTENSION ext; PCERT_EXTENSION ext;
BOOL ret; BOOL ret;
...@@ -1132,20 +1132,24 @@ static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine, ...@@ -1132,20 +1132,24 @@ static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
* perhaps this is prudent. On the other hand, MS also accepts V3 * perhaps this is prudent. On the other hand, MS also accepts V3
* certs without key usage extensions. We are more restrictive: * certs without key usage extensions. We are more restrictive:
* we accept locally installed V1 or V2 certs as CA certs. * we accept locally installed V1 or V2 certs as CA certs.
* We also accept a lack of key usage extension on root certs,
* which is implied in RFC 5280, section 6.1: the trust anchor's
* only requirement is that it was used to issue the next
* certificate in the chain.
*/ */
ret = FALSE; if (isRoot)
if (cert->pCertInfo->dwVersion == CERT_V1 || ret = TRUE;
else if (cert->pCertInfo->dwVersion == CERT_V1 ||
cert->pCertInfo->dwVersion == CERT_V2) cert->pCertInfo->dwVersion == CERT_V2)
{ {
PCCERT_CONTEXT localCert = CRYPT_FindCertInStore( PCCERT_CONTEXT localCert = CRYPT_FindCertInStore(
engine->hWorld, cert); engine->hWorld, cert);
if (localCert) ret = localCert != NULL;
{ CertFreeCertificateContext(localCert);
CertFreeCertificateContext(localCert);
ret = TRUE;
}
} }
else
ret = FALSE;
if (!ret) if (!ret)
WARN_(chain)("no key usage extension on a CA cert\n"); WARN_(chain)("no key usage extension on a CA cert\n");
} }
...@@ -1273,8 +1277,15 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, ...@@ -1273,8 +1277,15 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
chain->cElement, debugstr_w(filetime_to_str(time))); chain->cElement, debugstr_w(filetime_to_str(time)));
for (i = chain->cElement - 1; i >= 0; i--) for (i = chain->cElement - 1; i >= 0; i--)
{ {
BOOL isRoot;
if (TRACE_ON(chain)) if (TRACE_ON(chain))
dump_element(chain->rgpElement[i]->pCertContext); dump_element(chain->rgpElement[i]->pCertContext);
if (i == chain->cElement - 1)
isRoot = CRYPT_IsCertificateSelfSigned(
chain->rgpElement[i]->pCertContext);
else
isRoot = FALSE;
if (CertVerifyTimeValidity(time, if (CertVerifyTimeValidity(time,
chain->rgpElement[i]->pCertContext->pCertInfo) != 0) chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
chain->rgpElement[i]->TrustStatus.dwErrorStatus |= chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
...@@ -1316,7 +1327,7 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, ...@@ -1316,7 +1327,7 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
CERT_TRUST_INVALID_BASIC_CONSTRAINTS; CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
} }
if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext, if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext,
constraints.fCA, i)) isRoot, constraints.fCA, i))
chain->rgpElement[i]->TrustStatus.dwErrorStatus |= chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
CERT_TRUST_IS_NOT_VALID_FOR_USAGE; CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
if (i != 0) if (i != 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment