Commit ba4278a7 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

crypt32: Added support for retrieving certs by URL.

parent 9dd32ba6
...@@ -1972,7 +1972,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine, ...@@ -1972,7 +1972,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
} }
static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, const CERT_CONTEXT *cert, static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, const CERT_CONTEXT *cert,
HCERTSTORE store, DWORD type, void *para, PCCERT_CONTEXT prev_issuer) HCERTSTORE store, DWORD type, void *para, DWORD flags, PCCERT_CONTEXT prev_issuer)
{ {
CRYPT_URL_ARRAY *urls; CRYPT_URL_ARRAY *urls;
PCCERT_CONTEXT issuer; PCCERT_CONTEXT issuer;
...@@ -2019,7 +2019,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con ...@@ -2019,7 +2019,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con
TRACE("Trying URL %s\n", debugstr_w(urls->rgwszUrl[i])); TRACE("Trying URL %s\n", debugstr_w(urls->rgwszUrl[i]));
res = CryptRetrieveObjectByUrlW(urls->rgwszUrl[i], CONTEXT_OID_CERTIFICATE, res = CryptRetrieveObjectByUrlW(urls->rgwszUrl[i], CONTEXT_OID_CERTIFICATE,
CRYPT_CACHE_ONLY_RETRIEVAL /* FIXME */, (flags & CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL) ? CRYPT_CACHE_ONLY_RETRIEVAL : CRYPT_AIA_RETRIEVAL,
0, (void**)&new_cert, NULL, NULL, NULL, NULL); 0, (void**)&new_cert, NULL, NULL, NULL, NULL);
if(!res) if(!res)
{ {
...@@ -2047,7 +2047,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con ...@@ -2047,7 +2047,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con
static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
HCERTSTORE store, PCCERT_CONTEXT subject, PCCERT_CONTEXT prevIssuer, HCERTSTORE store, PCCERT_CONTEXT subject, PCCERT_CONTEXT prevIssuer,
DWORD *infoStatus) DWORD flags, DWORD *infoStatus)
{ {
PCCERT_CONTEXT issuer = NULL; PCCERT_CONTEXT issuer = NULL;
PCERT_EXTENSION ext; PCERT_EXTENSION ext;
...@@ -2076,7 +2076,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2076,7 +2076,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
memcpy(&id.u.IssuerSerialNumber.SerialNumber, memcpy(&id.u.IssuerSerialNumber.SerialNumber,
&info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, prevIssuer); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
if (issuer) if (issuer)
{ {
TRACE_(chain)("issuer found by issuer/serial number\n"); TRACE_(chain)("issuer found by issuer/serial number\n");
...@@ -2088,7 +2088,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2088,7 +2088,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, prevIssuer); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
if (issuer) if (issuer)
{ {
TRACE_(chain)("issuer found by key id\n"); TRACE_(chain)("issuer found by key id\n");
...@@ -2133,7 +2133,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2133,7 +2133,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
&info->AuthorityCertSerialNumber, &info->AuthorityCertSerialNumber,
sizeof(CRYPT_INTEGER_BLOB)); sizeof(CRYPT_INTEGER_BLOB));
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, prevIssuer); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
if (issuer) if (issuer)
{ {
TRACE_(chain)("issuer found by directory name\n"); TRACE_(chain)("issuer found by directory name\n");
...@@ -2147,7 +2147,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2147,7 +2147,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
{ {
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, prevIssuer); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
if (issuer) if (issuer)
{ {
TRACE_(chain)("issuer found by key id\n"); TRACE_(chain)("issuer found by key id\n");
...@@ -2160,7 +2160,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2160,7 +2160,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
else else
{ {
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_SUBJECT_NAME, issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_SUBJECT_NAME,
&subject->pCertInfo->Issuer, prevIssuer); &subject->pCertInfo->Issuer, flags, prevIssuer);
TRACE_(chain)("issuer found by name\n"); TRACE_(chain)("issuer found by name\n");
*infoStatus = CERT_TRUST_HAS_NAME_MATCH_ISSUER; *infoStatus = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
} }
...@@ -2171,7 +2171,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, ...@@ -2171,7 +2171,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
* until reaching a self-signed cert, or until no issuer can be found. * until reaching a self-signed cert, or until no issuer can be found.
*/ */
static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine, static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine,
HCERTSTORE world, PCERT_SIMPLE_CHAIN chain) HCERTSTORE world, DWORD flags, PCERT_SIMPLE_CHAIN chain)
{ {
BOOL ret = TRUE; BOOL ret = TRUE;
PCCERT_CONTEXT cert = chain->rgpElement[chain->cElement - 1]->pCertContext; PCCERT_CONTEXT cert = chain->rgpElement[chain->cElement - 1]->pCertContext;
...@@ -2179,7 +2179,7 @@ static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine, ...@@ -2179,7 +2179,7 @@ static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine,
while (ret && !CRYPT_IsSimpleChainCyclic(chain) && while (ret && !CRYPT_IsSimpleChainCyclic(chain) &&
!CRYPT_IsCertificateSelfSigned(cert)) !CRYPT_IsCertificateSelfSigned(cert))
{ {
PCCERT_CONTEXT issuer = CRYPT_GetIssuer(engine, world, cert, NULL, PCCERT_CONTEXT issuer = CRYPT_GetIssuer(engine, world, cert, NULL, flags,
&chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus); &chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
if (issuer) if (issuer)
...@@ -2210,7 +2210,7 @@ static LPCSTR debugstr_filetime(LPFILETIME pTime) ...@@ -2210,7 +2210,7 @@ static LPCSTR debugstr_filetime(LPFILETIME pTime)
} }
static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine, static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine,
HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime, DWORD flags,
PCERT_SIMPLE_CHAIN *ppChain) PCERT_SIMPLE_CHAIN *ppChain)
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
...@@ -2226,7 +2226,7 @@ static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine, ...@@ -2226,7 +2226,7 @@ static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine,
ret = CRYPT_AddCertToSimpleChain(engine, chain, cert, 0); ret = CRYPT_AddCertToSimpleChain(engine, chain, cert, 0);
if (ret) if (ret)
{ {
ret = CRYPT_BuildSimpleChain(engine, world, chain); ret = CRYPT_BuildSimpleChain(engine, world, flags, chain);
if (ret) if (ret)
CRYPT_CheckSimpleChain(engine, chain, pTime); CRYPT_CheckSimpleChain(engine, chain, pTime);
} }
...@@ -2241,7 +2241,7 @@ static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine, ...@@ -2241,7 +2241,7 @@ static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine,
} }
static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine, static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine,
PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags,
CertificateChain **ppChain) CertificateChain **ppChain)
{ {
PCERT_SIMPLE_CHAIN simpleChain = NULL; PCERT_SIMPLE_CHAIN simpleChain = NULL;
...@@ -2256,7 +2256,7 @@ static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine, ...@@ -2256,7 +2256,7 @@ static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine,
/* FIXME: only simple chains are supported for now, as CTLs aren't /* FIXME: only simple chains are supported for now, as CTLs aren't
* supported yet. * supported yet.
*/ */
if ((ret = CRYPT_GetSimpleChainForCert(engine, world, cert, pTime, &simpleChain))) if ((ret = CRYPT_GetSimpleChainForCert(engine, world, cert, pTime, flags, &simpleChain)))
{ {
CertificateChain *chain = CryptMemAlloc(sizeof(CertificateChain)); CertificateChain *chain = CryptMemAlloc(sizeof(CertificateChain));
...@@ -2430,7 +2430,7 @@ static CertificateChain *CRYPT_CopyChainToElement(CertificateChain *chain, ...@@ -2430,7 +2430,7 @@ static CertificateChain *CRYPT_CopyChainToElement(CertificateChain *chain,
static CertificateChain *CRYPT_BuildAlternateContextFromChain( static CertificateChain *CRYPT_BuildAlternateContextFromChain(
CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore, CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
CertificateChain *chain) DWORD flags, CertificateChain *chain)
{ {
CertificateChain *alternate; CertificateChain *alternate;
...@@ -2462,7 +2462,7 @@ static CertificateChain *CRYPT_BuildAlternateContextFromChain( ...@@ -2462,7 +2462,7 @@ static CertificateChain *CRYPT_BuildAlternateContextFromChain(
chain->context.rgpChain[i]->rgpElement[j + 1]->pCertContext); chain->context.rgpChain[i]->rgpElement[j + 1]->pCertContext);
alternateIssuer = CRYPT_GetIssuer(engine, prevIssuer->hCertStore, alternateIssuer = CRYPT_GetIssuer(engine, prevIssuer->hCertStore,
subject, prevIssuer, &infoStatus); subject, prevIssuer, flags, &infoStatus);
} }
if (alternateIssuer) if (alternateIssuer)
{ {
...@@ -2481,7 +2481,7 @@ static CertificateChain *CRYPT_BuildAlternateContextFromChain( ...@@ -2481,7 +2481,7 @@ static CertificateChain *CRYPT_BuildAlternateContextFromChain(
if (ret) if (ret)
{ {
ret = CRYPT_BuildSimpleChain(engine, alternate->world, ret = CRYPT_BuildSimpleChain(engine, alternate->world,
alternate->context.rgpChain[i]); flags, alternate->context.rgpChain[i]);
if (ret) if (ret)
CRYPT_CheckSimpleChain(engine, CRYPT_CheckSimpleChain(engine,
alternate->context.rgpChain[i], pTime); alternate->context.rgpChain[i], pTime);
...@@ -2892,7 +2892,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, ...@@ -2892,7 +2892,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
dump_chain_para(pChainPara); dump_chain_para(pChainPara);
/* FIXME: what about HCCE_LOCAL_MACHINE? */ /* FIXME: what about HCCE_LOCAL_MACHINE? */
ret = CRYPT_BuildCandidateChainFromCert(engine, pCertContext, pTime, ret = CRYPT_BuildCandidateChainFromCert(engine, pCertContext, pTime,
hAdditionalStore, &chain); hAdditionalStore, dwFlags, &chain);
if (ret) if (ret)
{ {
CertificateChain *alternate = NULL; CertificateChain *alternate = NULL;
...@@ -2900,7 +2900,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, ...@@ -2900,7 +2900,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
do { do {
alternate = CRYPT_BuildAlternateContextFromChain(engine, alternate = CRYPT_BuildAlternateContextFromChain(engine,
pTime, hAdditionalStore, chain); pTime, hAdditionalStore, dwFlags, chain);
/* Alternate contexts are added as "lower quality" contexts of /* Alternate contexts are added as "lower quality" contexts of
* chain, to avoid loops in alternate chain creation. * chain, to avoid loops in alternate chain creation.
......
...@@ -3998,7 +3998,7 @@ static void testGetCertChain(void) ...@@ -3998,7 +3998,7 @@ static void testGetCertChain(void)
ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError()); ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError());
if(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_PARTIAL_CHAIN) { /* win2k */ if(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_PARTIAL_CHAIN) { /* win2k */
todo_wine win_skip("winehq cert reported as partial chain, skipping its tests\n"); win_skip("winehq cert reported as partial chain, skipping its tests\n");
pCertFreeCertificateChain(chain); pCertFreeCertificateChain(chain);
CertCloseStore(store, 0); CertCloseStore(store, 0);
return; return;
......
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