"cloned" is very ambiguous and can be interpreted as the destination rather than the source.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/crypt32/crl.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index 31bf35bd041..4dc77c2a246 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -40,40 +40,38 @@ static const context_vtbl_t crl_vtbl;
static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { - crl_t *crl; + crl_t *dst;
if(use_link) { - crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store); - if(!crl) + if (!(dst = (crl_t *)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store))) return NULL; }else { - const crl_t *cloned = (const crl_t*)context; + const crl_t *src = (const crl_t*)context; DWORD size = 0; BOOL res;
- crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store); - if(!crl) + if (!(dst = (crl_t *)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store))) return NULL;
- Context_CopyProperties(&crl->ctx, &cloned->ctx); + Context_CopyProperties(&dst->ctx, &src->ctx);
- crl->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType; - crl->ctx.pbCrlEncoded = CryptMemAlloc(cloned->ctx.cbCrlEncoded); - memcpy(crl->ctx.pbCrlEncoded, cloned->ctx.pbCrlEncoded, cloned->ctx.cbCrlEncoded); - crl->ctx.cbCrlEncoded = cloned->ctx.cbCrlEncoded; + dst->ctx.dwCertEncodingType = src->ctx.dwCertEncodingType; + dst->ctx.pbCrlEncoded = CryptMemAlloc(src->ctx.cbCrlEncoded); + memcpy(dst->ctx.pbCrlEncoded, src->ctx.pbCrlEncoded, src->ctx.cbCrlEncoded); + dst->ctx.cbCrlEncoded = src->ctx.cbCrlEncoded;
- /* FIXME: We don't need to decode the object here, we could just clone crl info. */ - res = CryptDecodeObjectEx(crl->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, - crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, - &crl->ctx.pCrlInfo, &size); + /* FIXME: We don't need to decode the object here, we could just clone dst info. */ + res = CryptDecodeObjectEx(dst->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, + dst->ctx.pbCrlEncoded, dst->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, + &dst->ctx.pCrlInfo, &size); if(!res) { - CertFreeCRLContext(&crl->ctx); + CertFreeCRLContext(&dst->ctx); return NULL; } }
- crl->ctx.hCertStore = store; - return &crl->base; + dst->ctx.hCertStore = store; + return &dst->base; }
static const context_vtbl_t crl_vtbl = {
Steam calls CertGetCertificateChain() on a certificate with a 20 MB CRL, which can take over 400 ms to parse each time. Avoid parsing it more often than we need to.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/crypt32/crl.c | 111 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 7 deletions(-)
diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index 4dc77c2a246..657810e0c6b 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -38,6 +38,108 @@ static void CRL_free(context_t *context)
static const context_vtbl_t crl_vtbl;
+static char *copy_string(char *p, char **dst, const char *src) +{ + size_t size = strlen(src) + 1; + + *dst = memcpy(p, src, size); + return p + size; +} + +static char *copy_blob(char *p, DATA_BLOB *dst, const DATA_BLOB *src) +{ + size_t size = src->cbData; + + dst->cbData = size; + dst->pbData = memcpy(p, src->pbData, size); + return p + size; +} + +static char *copy_extension(char *p, CERT_EXTENSION *dst, const CERT_EXTENSION *src) +{ + p = copy_string(p, &dst->pszObjId, src->pszObjId); + dst->fCritical = src->fCritical; + return copy_blob(p, &dst->Value, &src->Value); +} + +static CRL_INFO *clone_crl_info(const CRL_INFO *src) +{ + size_t size = sizeof(CRL_INFO); + CRL_INFO *dst; + DWORD i, j; + char *p; + + if (src->SignatureAlgorithm.pszObjId) + size += strlen(src->SignatureAlgorithm.pszObjId) + 1; + size += src->SignatureAlgorithm.Parameters.cbData; + size += src->Issuer.cbData; + for (i = 0; i < src->cCRLEntry; ++i) + { + const CRL_ENTRY *entry = &src->rgCRLEntry[i]; + + size += sizeof(CRL_ENTRY); + size += entry->SerialNumber.cbData; + for (j = 0; j < entry->cExtension; ++j) + { + const CERT_EXTENSION *ext = &entry->rgExtension[j]; + + size += sizeof(CERT_EXTENSION); + size += strlen(ext->pszObjId) + 1; + size += ext->Value.cbData; + } + } + + for (j = 0; j < src->cExtension; ++j) + { + const CERT_EXTENSION *ext = &src->rgExtension[j]; + + size += sizeof(CERT_EXTENSION); + size += strlen(ext->pszObjId) + 1; + size += ext->Value.cbData; + } + + if (!(dst = LocalAlloc(LPTR, size))) + return NULL; + p = (char *)(dst + 1); + + dst->dwVersion = src->dwVersion; + if (src->SignatureAlgorithm.pszObjId) + p = copy_string(p, &dst->SignatureAlgorithm.pszObjId, src->SignatureAlgorithm.pszObjId); + p = copy_blob(p, &dst->SignatureAlgorithm.Parameters, &src->SignatureAlgorithm.Parameters); + p = copy_blob(p, &dst->Issuer, &src->Issuer); + dst->ThisUpdate = src->ThisUpdate; + dst->NextUpdate = src->NextUpdate; + + dst->cCRLEntry = src->cCRLEntry; + dst->rgCRLEntry = (CRL_ENTRY *)p; + p += src->cCRLEntry * sizeof(CRL_ENTRY); + + dst->cExtension = src->cExtension; + dst->rgExtension = (CERT_EXTENSION *)p; + p += src->cExtension * sizeof(CERT_EXTENSION); + + for (i = 0; i < src->cCRLEntry; ++i) + { + const CRL_ENTRY *src_entry = &src->rgCRLEntry[i]; + CRL_ENTRY *dst_entry = &dst->rgCRLEntry[i]; + + p = copy_blob(p, &dst_entry->SerialNumber, &src_entry->SerialNumber); + dst_entry->RevocationDate = src_entry->RevocationDate; + dst_entry->cExtension = src_entry->cExtension; + dst_entry->rgExtension = (CERT_EXTENSION *)p; + p += src_entry->cExtension * sizeof(CERT_EXTENSION); + + for (j = 0; j < src_entry->cExtension; ++j) + p = copy_extension(p, &dst_entry->rgExtension[j], &src_entry->rgExtension[j]); + } + + for (j = 0; j < src->cExtension; ++j) + p = copy_extension(p, &dst->rgExtension[j], &src->rgExtension[j]); + + assert(p - (char *)dst == size); + return dst; +} + static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { crl_t *dst; @@ -47,8 +149,6 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL return NULL; }else { const crl_t *src = (const crl_t*)context; - DWORD size = 0; - BOOL res;
if (!(dst = (crl_t *)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store))) return NULL; @@ -60,11 +160,8 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL memcpy(dst->ctx.pbCrlEncoded, src->ctx.pbCrlEncoded, src->ctx.cbCrlEncoded); dst->ctx.cbCrlEncoded = src->ctx.cbCrlEncoded;
- /* FIXME: We don't need to decode the object here, we could just clone dst info. */ - res = CryptDecodeObjectEx(dst->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, - dst->ctx.pbCrlEncoded, dst->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, - &dst->ctx.pCrlInfo, &size); - if(!res) { + if (!(dst->ctx.pCrlInfo = clone_crl_info(src->ctx.pCrlInfo))) + { CertFreeCRLContext(&dst->ctx); return NULL; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/cryptnet/cryptnet_main.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c index efcb3dc9ba2..f667c655e46 100644 --- a/dlls/cryptnet/cryptnet_main.c +++ b/dlls/cryptnet/cryptnet_main.c @@ -521,13 +521,13 @@ static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject, { if ((ret = CRYPT_GetObjectFromFile(hFile, pObject))) { - if (pAuxInfo && pAuxInfo->cbSize >= - offsetof(CRYPT_RETRIEVE_AUX_INFO, - pLastSyncTime) + sizeof(PFILETIME) && - pAuxInfo->pLastSyncTime) + if (pAuxInfo && pAuxInfo->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CRYPT_RETRIEVE_AUX_INFO, pLastSyncTime) + && pAuxInfo->pLastSyncTime) + { memcpy(pAuxInfo->pLastSyncTime, &pCacheInfo->LastSyncTime, sizeof(FILETIME)); + } } CloseHandle(hFile); } @@ -1028,12 +1028,12 @@ static BOOL WINAPI File_RetrieveEncodedObjectW(LPCWSTR pszURL, { if ((ret = CRYPT_GetObjectFromFile(hFile, pObject))) { - if (pAuxInfo && pAuxInfo->cbSize >= - offsetof(CRYPT_RETRIEVE_AUX_INFO, - pLastSyncTime) + sizeof(PFILETIME) && - pAuxInfo->pLastSyncTime) + if (pAuxInfo && pAuxInfo->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CRYPT_RETRIEVE_AUX_INFO, pLastSyncTime) + && pAuxInfo->pLastSyncTime) + { GetFileTime(hFile, NULL, NULL, pAuxInfo->pLastSyncTime); + } } CloseHandle(hFile); } @@ -1557,9 +1557,8 @@ static DWORD verify_cert_revocation_from_dist_points_ext( &cbUrlArray, NULL, NULL); if (dwFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION) retrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL; - if (dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG && - pRevPara && pRevPara->cbSize >= offsetof(CERT_REVOCATION_PARA, - dwUrlRetrievalTimeout) + sizeof(DWORD)) + if ((dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) && pRevPara + && pRevPara->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CERT_REVOCATION_PARA, dwUrlRetrievalTimeout)) { startTime = GetTickCount(); endTime = startTime + pRevPara->dwUrlRetrievalTimeout;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/cryptnet/tests/cryptnet.c | 360 +++++++++++++++++++-------------- 1 file changed, 210 insertions(+), 150 deletions(-)
diff --git a/dlls/cryptnet/tests/cryptnet.c b/dlls/cryptnet/tests/cryptnet.c index 3eca9e43f2e..b37a5e698f3 100644 --- a/dlls/cryptnet/tests/cryptnet.c +++ b/dlls/cryptnet/tests/cryptnet.c @@ -593,200 +593,260 @@ static SYSTEMTIME may2007 = { 2007, 5, 2, 1, 0, 0, 0, 0 };
static void test_verifyRevocation(void) { - HMODULE hCryptNet = GetModuleHandleA("cryptnet.dll"); - BOOL ret; - CERT_REVOCATION_STATUS status = { sizeof(status), 0 }; - PCCERT_CONTEXT certs[2]; - CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 }; + CERT_REVOCATION_STATUS status = {sizeof(status)}; + CERT_REVOCATION_PARA params = {sizeof(params)}; + const CERT_CONTEXT *certs[2]; FILETIME time; + BOOL ret; + + pCertVerifyRevocation = (void *)GetProcAddress(GetModuleHandleA("cryptnet.dll"), "CertDllVerifyRevocation");
- pCertVerifyRevocation = (void *)GetProcAddress(hCryptNet, - "CertDllVerifyRevocation"); - if (!pCertVerifyRevocation) - { - win_skip("no CertDllVerifyRevocation\n"); - return; - } if (0) { /* Crash */ pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL); } + SetLastError(0xdeadbeef); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); ret = pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); - ok(!ret && GetLastError() == E_INVALIDARG, - "expected E_INVALIDARG, got %08x\n", GetLastError()); + ok(!ret, "expected failure\n"); + ok(GetLastError() == E_INVALIDARG, "got error %#x\n", GetLastError()); + todo_wine ok(!status.dwIndex, "got index %u\n", status.dwIndex); + todo_wine ok(status.dwError == E_INVALIDARG, "got error %#x\n", status.dwError); + todo_wine ok(!status.dwReason, "got reason %u\n", status.dwReason); + SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0, 0, NULL, 0, NULL, - &status); - ok(!ret && GetLastError() == E_INVALIDARG, - "expected E_INVALIDARG, got %08x\n", GetLastError()); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0, 0, NULL, 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == E_INVALIDARG, "got error %#x\n", GetLastError()); + todo_wine ok(!status.dwIndex, "got index %u\n", status.dwIndex); + todo_wine ok(status.dwError == E_INVALIDARG, "got error %#x\n", status.dwError); + todo_wine ok(!status.dwReason, "got reason %u\n", status.dwReason); + SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 0, NULL, 0, - NULL, &status); - ok(!ret && GetLastError() == E_INVALIDARG, - "expected E_INVALIDARG, got %08x\n", GetLastError()); - certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, - sizeof(bigCert)); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 0, NULL, 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == E_INVALIDARG, "got error %#x\n", GetLastError()); + todo_wine ok(!status.dwIndex, "got index %u\n", status.dwIndex); + todo_wine ok(status.dwError == E_INVALIDARG, "got error %#x\n", status.dwError); + todo_wine ok(!status.dwReason, "got reason %u\n", status.dwReason); + + certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)certs, 0, NULL, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)certs, 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + CertFreeCertificateContext(certs[0]); - certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, - rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign)); - certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, - revokedCert, sizeof(revokedCert)); + + certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign)); + certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, revokedCert, sizeof(revokedCert)); + /* The root cert itself can't be checked for revocation */ SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)certs, 0, NULL, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[0], 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + /* Neither can the end cert */ SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, NULL, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + /* Both certs together can't, either (they're not CRLs) */ SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 2, (void **)certs, 0, NULL, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); - /* Now add a CRL to the hCrlStore */ - revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, - CERT_STORE_CREATE_NEW_FLAG, NULL); - CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING, - rootSignedCRLWithBadAKI, sizeof(rootSignedCRLWithBadAKI), - CERT_STORE_ADD_ALWAYS, NULL); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 2, (void **)certs, 0, NULL, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + /* Test with an invalid CRL */ + + params.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + ret = CertAddEncodedCRLToStore(params.hCrlStore, X509_ASN_ENCODING, rootSignedCRLWithBadAKI, + sizeof(rootSignedCRLWithBadAKI), CERT_STORE_ADD_ALWAYS, NULL); + ok(ret, "failed to add CRL, error %u\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 2, (void **)certs, 0, &revPara, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 2, (void **)certs, 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + /* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */ SetLastError(0xdeadbeef); - ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, - 2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status); - ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + /* Again, specifying the issuer cert: no change */ - revPara.pIssuerCert = certs[0]; + params.pIssuerCert = certs[0]; SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - /* Win2k thinks the cert is revoked, and it is, except the CRL contains a - * bad authority key ID extension and can't be matched with the issuer - * cert, hence the revocation status should be unknown. - */ - if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) - { - win_skip("CERT_CONTEXT_REVOCATION_TYPE unsupported, skipping\n"); - return; - } - ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || - broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)), - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || - broken(status.dwError == CRYPT_E_REVOKED /* Win2k */), - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + /* Specifying the time to check: still no change */ SystemTimeToFileTime(&oct2007, &time); - revPara.pftTimeToUse = &time; + params.pftTimeToUse = &time; + + SetLastError(0xdeadbeef); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret, "Expected failure\n"); - ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || - broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */ - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); - ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || - broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */ - "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); - ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); - CertCloseStore(revPara.hCrlStore, 0); + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + CertCloseStore(params.hCrlStore, 0); + /* Test again with a valid CRL. This time, the cert should be revoked when * the time is after the validity period of the CRL, or considered * "revocation offline" when the checked time precedes the validity * period of the CRL. */ - revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, - CERT_STORE_CREATE_NEW_FLAG, NULL); - ret = CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING, - rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL); - ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); - revPara.pftTimeToUse = NULL; + params.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + ret = CertAddEncodedCRLToStore(params.hCrlStore, X509_ASN_ENCODING, + rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL); + ok(ret, "failed to add CRL, error %u\n", GetLastError()); + + params.pftTimeToUse = NULL; + SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOKED || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOKED, got %08x\n", GetLastError()); - revPara.pftTimeToUse = &time; + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOKED, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOKED, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + SystemTimeToFileTime(&oct2007, &time); + params.pftTimeToUse = &time; SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOKED || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOKED, got %08x\n", GetLastError()); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOKED, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOKED, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + SystemTimeToFileTime(&may2007, &time); SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + CertFreeCertificateContext(certs[1]); + /* Test again with a valid CRL and an un-revoked cert. No matter the * time checked, it's reported as revocation offline. */ - certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, - unRevokedCert, sizeof(unRevokedCert)); - ok(certs[1] != NULL, "CertCreateCertificateContext failed: %08x\n", - GetLastError()); - revPara.pftTimeToUse = NULL; + certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, unRevokedCert, sizeof(unRevokedCert)); + + params.pftTimeToUse = NULL; SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); - revPara.pftTimeToUse = &time; + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + SystemTimeToFileTime(&oct2007, &time); + params.pftTimeToUse = &time; SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + SystemTimeToFileTime(&may2007, &time); SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, - 1, (void **)&certs[1], 0, &revPara, &status); - ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || - broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), - "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); - CertCloseStore(revPara.hCrlStore, 0); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_REVOCATION_OFFLINE, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + params.pftTimeToUse = NULL; + + /* Test with the wrong encoding type. */ + SetLastError(0xdeadbeef); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + todo_wine ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + /* Test with the wrong context type. */ + SetLastError(0xdeadbeef); + memset(&status.dwIndex, 0xcc, sizeof(status) - offsetof(CERT_REVOCATION_STATUS, dwIndex)); + ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0xdeadbeef, + 1, (void **)&certs[1], 0, ¶ms, &status); + ok(!ret, "expected failure\n"); + ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", GetLastError()); + ok(!status.dwIndex, "got index %u\n", status.dwIndex); + ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "got error %#x\n", status.dwError); + ok(!status.dwReason, "got reason %u\n", status.dwReason); + + CertCloseStore(params.hCrlStore, 0); CertFreeCertificateContext(certs[1]); CertFreeCertificateContext(certs[0]); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/cryptnet/cryptnet_main.c | 114 +++++++++++++--------------------- 1 file changed, 42 insertions(+), 72 deletions(-)
diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c index f667c655e46..06c468bd655 100644 --- a/dlls/cryptnet/cryptnet_main.c +++ b/dlls/cryptnet/cryptnet_main.c @@ -1514,33 +1514,22 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, return ret; }
-static DWORD verify_cert_revocation_with_crl_online(PCCERT_CONTEXT cert, - PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime, - PCERT_REVOCATION_STATUS pRevStatus) +static DWORD verify_cert_revocation_with_crl_online(const CERT_CONTEXT *cert, + const CRL_CONTEXT *crl, FILETIME *pTime, CERT_REVOCATION_STATUS *pRevStatus) { - DWORD error; PCRL_ENTRY entry = NULL;
CertFindCertificateInCRL(cert, crl, 0, NULL, &entry); if (entry) - { - error = CRYPT_E_REVOKED; - pRevStatus->dwIndex = index; - } - else - { - /* Since the CRL was retrieved for the cert being checked, then it's - * guaranteed to be fresh, and the cert is not revoked. - */ - error = ERROR_SUCCESS; - } - return error; + return CRYPT_E_REVOKED; + + /* Since the CRL was retrieved for the cert being checked, then it's + * guaranteed to be fresh, and the cert is not revoked. */ + return ERROR_SUCCESS; }
-static DWORD verify_cert_revocation_from_dist_points_ext( - const CRYPT_DATA_BLOB *value, PCCERT_CONTEXT cert, DWORD index, - FILETIME *pTime, DWORD dwFlags, const CERT_REVOCATION_PARA *pRevPara, - PCERT_REVOCATION_STATUS pRevStatus) +static DWORD verify_cert_revocation_from_dist_points_ext(const CRYPT_DATA_BLOB *value, const CERT_CONTEXT *cert, + FILETIME *pTime, DWORD dwFlags, const CERT_REVOCATION_PARA *pRevPara, CERT_REVOCATION_STATUS *pRevStatus) { DWORD error = ERROR_SUCCESS, cbUrlArray;
@@ -1578,17 +1567,13 @@ static DWORD verify_cert_revocation_from_dist_points_ext( NULL, NULL, NULL, NULL); if (ret) { - error = verify_cert_revocation_with_crl_online(cert, crl, - index, pTime, pRevStatus); + error = verify_cert_revocation_with_crl_online(cert, crl, pTime, pRevStatus); if (!error && timeout) { DWORD time = GetTickCount();
if ((int)(endTime - time) <= 0) - { error = ERROR_TIMEOUT; - pRevStatus->dwIndex = index; - } else timeout = endTime - time; } @@ -1600,23 +1585,15 @@ static DWORD verify_cert_revocation_from_dist_points_ext( CryptMemFree(urlArray); } else - { error = ERROR_OUTOFMEMORY; - pRevStatus->dwIndex = index; - } } else - { error = GetLastError(); - pRevStatus->dwIndex = index; - } return error; }
-static DWORD verify_cert_revocation_from_aia_ext( - const CRYPT_DATA_BLOB *value, PCCERT_CONTEXT cert, DWORD index, - FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, - PCERT_REVOCATION_STATUS pRevStatus) +static DWORD verify_cert_revocation_from_aia_ext(const CRYPT_DATA_BLOB *value, const CERT_CONTEXT *cert, + FILETIME *pTime, DWORD dwFlags, CERT_REVOCATION_PARA *pRevPara, CERT_REVOCATION_STATUS *pRevStatus) { BOOL ret; DWORD error, size; @@ -1650,10 +1627,9 @@ static DWORD verify_cert_revocation_from_aia_ext( }
static DWORD verify_cert_revocation_with_crl_offline(PCCERT_CONTEXT cert, - PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime, - PCERT_REVOCATION_STATUS pRevStatus) + const CRL_CONTEXT *crl, FILETIME *pTime, CERT_REVOCATION_STATUS *pRevStatus) { - DWORD error; + PCRL_ENTRY entry = NULL; LONG valid;
valid = CompareFileTime(pTime, &crl->pCrlInfo->ThisUpdate); @@ -1663,46 +1639,38 @@ static DWORD verify_cert_revocation_with_crl_offline(PCCERT_CONTEXT cert, * way to know whether the certificate was revoked. */ TRACE("CRL not old enough\n"); - error = CRYPT_E_REVOCATION_OFFLINE; + return CRYPT_E_REVOCATION_OFFLINE; } - else - { - PCRL_ENTRY entry = NULL;
- CertFindCertificateInCRL(cert, crl, 0, NULL, &entry); - if (entry) - { - error = CRYPT_E_REVOKED; - pRevStatus->dwIndex = index; - } - else - { - /* Since the CRL was not retrieved for the cert being checked, - * there's no guarantee it's fresh, so the cert *might* be okay, - * but it's safer not to guess. - */ - TRACE("certificate not found\n"); - error = CRYPT_E_REVOCATION_OFFLINE; - } - } - return error; + CertFindCertificateInCRL(cert, crl, 0, NULL, &entry); + if (entry) + return CRYPT_E_REVOKED; + + /* Since the CRL was not retrieved for the cert being checked, there's no + * guarantee it's fresh, so the cert *might* be okay, but it's safer not to + * guess. */ + TRACE("certificate not found\n"); + return CRYPT_E_REVOCATION_OFFLINE; }
-static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, - FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, - PCERT_REVOCATION_STATUS pRevStatus) +static DWORD verify_cert_revocation(const CERT_CONTEXT *cert, FILETIME *pTime, + DWORD dwFlags, CERT_REVOCATION_PARA *pRevPara, CERT_REVOCATION_STATUS *pRevStatus) { DWORD error = ERROR_SUCCESS; PCERT_EXTENSION ext;
if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) + { error = verify_cert_revocation_from_dist_points_ext(&ext->Value, cert, - index, pTime, dwFlags, pRevPara, pRevStatus); + pTime, dwFlags, pRevPara, pRevStatus); + } else if ((ext = CertFindExtension(szOID_AUTHORITY_INFO_ACCESS, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) - error = verify_cert_revocation_from_aia_ext(&ext->Value, cert, - index, pTime, dwFlags, pRevPara, pRevStatus); + { + error = verify_cert_revocation_from_aia_ext(&ext->Value, cert, pTime, + dwFlags, pRevPara, pRevStatus); + } else { if (pRevPara && pRevPara->hCrlStore && pRevPara->pIssuerCert) @@ -1753,15 +1721,13 @@ static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, } if (crl) { - error = verify_cert_revocation_with_crl_offline(cert, crl, - index, pTime, pRevStatus); + error = verify_cert_revocation_with_crl_offline(cert, crl, pTime, pRevStatus); CertFreeCRLContext(crl); } else { TRACE("no CRL found\n"); error = CRYPT_E_NO_REVOCATION_CHECK; - pRevStatus->dwIndex = index; } } else @@ -1773,7 +1739,6 @@ static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, else if (!pRevPara->pIssuerCert) WARN("no dist points/aia extension and no issuer\n"); error = CRYPT_E_NO_REVOCATION_CHECK; - pRevStatus->dwIndex = index; } } return error; @@ -1833,9 +1798,14 @@ BOOL WINAPI CertDllVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, error = CRYPT_E_NO_REVOCATION_CHECK; else { - for (i = 0; !error && i < cContext; i++) - error = verify_cert_revocation(rgpvContext[i], i, pTime, dwFlags, - pRevPara, pRevStatus); + for (i = 0; i < cContext; i++) + { + if ((error = verify_cert_revocation(rgpvContext[i], pTime, dwFlags, pRevPara, pRevStatus))) + { + pRevStatus->dwIndex = i; + break; + } + } } if (error) {