Author: cwittich Date: Wed Mar 3 21:55:41 2010 New Revision: 45804
URL: http://svn.reactos.org/svn/reactos?rev=45804&view=rev Log: [CRYPTNET] sync cryptnet to wine 1.1.39
Modified: trunk/reactos/dll/win32/cryptnet/cryptnet_main.c
Modified: trunk/reactos/dll/win32/cryptnet/cryptnet_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptnet/cryptnet... ============================================================================== --- trunk/reactos/dll/win32/cryptnet/cryptnet_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/cryptnet/cryptnet_main.c [iso-8859-1] Wed Mar 3 21:55:41 2010 @@ -40,6 +40,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(cryptnet);
+#define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0) + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); @@ -92,9 +94,7 @@
static const char *url_oid_to_str(LPCSTR oid) { - if (HIWORD(oid)) - return oid; - else + if (IS_INTOID(oid)) { static char buf[10];
@@ -115,6 +115,8 @@ return buf; } } + else + return oid; }
typedef BOOL (WINAPI *UrlDllGetObjectUrlFunc)(LPCSTR, LPVOID, DWORD, @@ -124,18 +126,6 @@ LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved) { - /* FIXME: This depends on the AIA (authority info access) extension being - * supported in crypt32. - */ - FIXME("\n"); - SetLastError(CRYPT_E_NOT_FOUND); - return FALSE; -} - -static BOOL WINAPI CRYPT_GetUrlFromCertificateCRLDistPoint(LPCSTR pszUrlOid, - LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, - PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved) -{ PCCERT_CONTEXT cert = pvPara; PCERT_EXTENSION ext; BOOL ret = FALSE; @@ -146,39 +136,37 @@ SetLastError(CRYPT_E_NOT_FOUND); return FALSE; } - if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS, + if ((ext = CertFindExtension(szOID_AUTHORITY_INFO_ACCESS, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) { - CRL_DIST_POINTS_INFO *info; + CERT_AUTHORITY_INFO_ACCESS *aia; DWORD size;
- ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CRL_DIST_POINTS, + ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_AUTHORITY_INFO_ACCESS, ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, - &info, &size); + &aia, &size); if (ret) { DWORD i, cUrl, bytesNeeded = sizeof(CRYPT_URL_ARRAY);
- for (i = 0, cUrl = 0; i < info->cDistPoint; i++) - if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice - == CRL_DIST_POINT_FULL_NAME) - { - DWORD j; - CERT_ALT_NAME_INFO *name = - &info->rgDistPoint[i].DistPointName.u.FullName; - - for (j = 0; j < name->cAltEntry; j++) - if (name->rgAltEntry[j].dwAltNameChoice == - CERT_ALT_NAME_URL) + for (i = 0, cUrl = 0; i < aia->cAccDescr; i++) + if (!strcmp(aia->rgAccDescr[i].pszAccessMethod, + szOID_PKIX_CA_ISSUERS)) + { + if (aia->rgAccDescr[i].AccessLocation.dwAltNameChoice == + CERT_ALT_NAME_URL) + { + if (aia->rgAccDescr[i].AccessLocation.u.pwszURL) { - if (name->rgAltEntry[j].u.pwszURL) - { - cUrl++; - bytesNeeded += sizeof(LPWSTR) + - (lstrlenW(name->rgAltEntry[j].u.pwszURL) + 1) - * sizeof(WCHAR); - } + cUrl++; + bytesNeeded += sizeof(LPWSTR) + + (lstrlenW(aia->rgAccDescr[i].AccessLocation.u. + pwszURL) + 1) * sizeof(WCHAR); } + } + else + FIXME("unsupported alt name type %d\n", + aia->rgAccDescr[i].AccessLocation.dwAltNameChoice); } if (!pcbUrlArray) { @@ -203,28 +191,22 @@ (LPWSTR *)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY)); nextUrl = (LPWSTR)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY) + cUrl * sizeof(LPWSTR)); - for (i = 0; i < info->cDistPoint; i++) - if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice - == CRL_DIST_POINT_FULL_NAME) + for (i = 0; i < aia->cAccDescr; i++) + if (!strcmp(aia->rgAccDescr[i].pszAccessMethod, + szOID_PKIX_CA_ISSUERS)) { - DWORD j; - CERT_ALT_NAME_INFO *name = - &info->rgDistPoint[i].DistPointName.u.FullName; - - for (j = 0; j < name->cAltEntry; j++) - if (name->rgAltEntry[j].dwAltNameChoice == - CERT_ALT_NAME_URL) + if (aia->rgAccDescr[i].AccessLocation.dwAltNameChoice + == CERT_ALT_NAME_URL) + { + if (aia->rgAccDescr[i].AccessLocation.u.pwszURL) { - if (name->rgAltEntry[j].u.pwszURL) - { - lstrcpyW(nextUrl, - name->rgAltEntry[j].u.pwszURL); - pUrlArray->rgwszUrl[pUrlArray->cUrl++] = - nextUrl; - nextUrl += - (lstrlenW(name->rgAltEntry[j].u.pwszURL) + 1); - } + lstrcpyW(nextUrl, + aia->rgAccDescr[i].AccessLocation.u.pwszURL); + pUrlArray->rgwszUrl[pUrlArray->cUrl++] = + nextUrl; + nextUrl += (lstrlenW(nextUrl) + 1); } + } } } if (ret) @@ -247,9 +229,139 @@ } } } - LocalFree(info); - } - } + LocalFree(aia); + } + } + else + SetLastError(CRYPT_E_NOT_FOUND); + return ret; +} + +static BOOL CRYPT_GetUrlFromCRLDistPointsExt(const CRYPT_DATA_BLOB *value, + PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo, + DWORD *pcbUrlInfo) +{ + BOOL ret; + CRL_DIST_POINTS_INFO *info; + DWORD size; + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CRL_DIST_POINTS, + value->pbData, value->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + if (ret) + { + DWORD i, cUrl, bytesNeeded = sizeof(CRYPT_URL_ARRAY); + + for (i = 0, cUrl = 0; i < info->cDistPoint; i++) + if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice + == CRL_DIST_POINT_FULL_NAME) + { + DWORD j; + CERT_ALT_NAME_INFO *name = + &info->rgDistPoint[i].DistPointName.u.FullName; + + for (j = 0; j < name->cAltEntry; j++) + if (name->rgAltEntry[j].dwAltNameChoice == + CERT_ALT_NAME_URL) + { + if (name->rgAltEntry[j].u.pwszURL) + { + cUrl++; + bytesNeeded += sizeof(LPWSTR) + + (lstrlenW(name->rgAltEntry[j].u.pwszURL) + 1) + * sizeof(WCHAR); + } + } + } + if (!pcbUrlArray) + { + SetLastError(E_INVALIDARG); + ret = FALSE; + } + else if (!pUrlArray) + *pcbUrlArray = bytesNeeded; + else if (*pcbUrlArray < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + *pcbUrlArray = bytesNeeded; + ret = FALSE; + } + else + { + LPWSTR nextUrl; + + *pcbUrlArray = bytesNeeded; + pUrlArray->cUrl = 0; + pUrlArray->rgwszUrl = + (LPWSTR *)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY)); + nextUrl = (LPWSTR)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY) + + cUrl * sizeof(LPWSTR)); + for (i = 0; i < info->cDistPoint; i++) + if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice + == CRL_DIST_POINT_FULL_NAME) + { + DWORD j; + CERT_ALT_NAME_INFO *name = + &info->rgDistPoint[i].DistPointName.u.FullName; + + for (j = 0; j < name->cAltEntry; j++) + if (name->rgAltEntry[j].dwAltNameChoice == + CERT_ALT_NAME_URL) + { + if (name->rgAltEntry[j].u.pwszURL) + { + lstrcpyW(nextUrl, + name->rgAltEntry[j].u.pwszURL); + pUrlArray->rgwszUrl[pUrlArray->cUrl++] = + nextUrl; + nextUrl += + (lstrlenW(name->rgAltEntry[j].u.pwszURL) + 1); + } + } + } + } + if (ret) + { + if (pcbUrlInfo) + { + FIXME("url info: stub\n"); + if (!pUrlInfo) + *pcbUrlInfo = sizeof(CRYPT_URL_INFO); + else if (*pcbUrlInfo < sizeof(CRYPT_URL_INFO)) + { + *pcbUrlInfo = sizeof(CRYPT_URL_INFO); + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + *pcbUrlInfo = sizeof(CRYPT_URL_INFO); + memset(pUrlInfo, 0, sizeof(CRYPT_URL_INFO)); + } + } + } + LocalFree(info); + } + return ret; +} + +static BOOL WINAPI CRYPT_GetUrlFromCertificateCRLDistPoint(LPCSTR pszUrlOid, + LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, + PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved) +{ + PCCERT_CONTEXT cert = pvPara; + PCERT_EXTENSION ext; + BOOL ret = FALSE; + + /* The only applicable flag is CRYPT_GET_URL_FROM_EXTENSION */ + if (dwFlags && !(dwFlags & CRYPT_GET_URL_FROM_EXTENSION)) + { + SetLastError(CRYPT_E_NOT_FOUND); + return FALSE; + } + if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) + ret = CRYPT_GetUrlFromCRLDistPointsExt(&ext->Value, pUrlArray, + pcbUrlArray, pUrlInfo, pcbUrlInfo); else SetLastError(CRYPT_E_NOT_FOUND); return ret; @@ -269,7 +381,7 @@ TRACE("(%s, %p, %08x, %p, %p, %p, %p, %p)\n", debugstr_a(pszUrlOid), pvPara, dwFlags, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved);
- if (!HIWORD(pszUrlOid)) + if (IS_INTOID(pszUrlOid)) { switch (LOWORD(pszUrlOid)) { @@ -566,7 +678,7 @@ } } if (ret) - object.cbData += bytesAvailable; + object.cbData += buffer.dwBufferLength; } else { @@ -1246,20 +1358,24 @@ if (!CertAddCertificateContextToStore(store, context, CERT_STORE_ADD_ALWAYS, NULL)) ret = FALSE; + CertFreeCertificateContext(context); break; case CERT_QUERY_CONTENT_CRL: if (!CertAddCRLContextToStore(store, context, CERT_STORE_ADD_ALWAYS, NULL)) ret = FALSE; + CertFreeCRLContext(context); break; case CERT_QUERY_CONTENT_CTL: if (!CertAddCTLContextToStore(store, context, CERT_STORE_ADD_ALWAYS, NULL)) ret = FALSE; + CertFreeCTLContext(context); break; default: CertAddStoreToCollection(store, contextStore, 0, 0); } + CertCloseStore(contextStore, 0); } else ret = FALSE; @@ -1284,7 +1400,7 @@
*pFunc = NULL; *phFunc = 0; - if (!HIWORD(pszObjectOid)) + if (IS_INTOID(pszObjectOid)) { switch (LOWORD(pszObjectOid)) { @@ -1354,7 +1470,7 @@ { BOOL ret;
- if (!HIWORD(pszObjectOid)) + if (IS_INTOID(pszObjectOid)) { switch (LOWORD(pszObjectOid)) { @@ -1437,6 +1553,238 @@ return ret; }
+static DWORD verify_cert_revocation_with_crl(PCCERT_CONTEXT cert, + PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime, + PCERT_REVOCATION_STATUS pRevStatus) +{ + DWORD error; + + if (CertVerifyCRLTimeValidity(pTime, crl->pCrlInfo)) + { + /* The CRL isn't time valid */ + error = CRYPT_E_NO_REVOCATION_CHECK; + } + else + { + PCRL_ENTRY entry = NULL; + + CertFindCertificateInCRL(cert, crl, 0, NULL, &entry); + if (entry) + { + error = CRYPT_E_REVOKED; + pRevStatus->dwIndex = index; + } + else + error = ERROR_SUCCESS; + } + return error; +} + +static DWORD verify_cert_revocation_from_dist_points_ext( + const CRYPT_DATA_BLOB *value, PCCERT_CONTEXT cert, DWORD index, + FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, + PCERT_REVOCATION_STATUS pRevStatus) +{ + DWORD error = ERROR_SUCCESS, cbUrlArray; + + if (CRYPT_GetUrlFromCRLDistPointsExt(value, NULL, &cbUrlArray, NULL, NULL)) + { + CRYPT_URL_ARRAY *urlArray = CryptMemAlloc(cbUrlArray); + + if (urlArray) + { + DWORD j, retrievalFlags = 0, startTime, endTime, timeout; + BOOL ret; + + ret = CRYPT_GetUrlFromCRLDistPointsExt(value, urlArray, + &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)) + { + startTime = GetTickCount(); + endTime = startTime + pRevPara->dwUrlRetrievalTimeout; + timeout = pRevPara->dwUrlRetrievalTimeout; + } + else + endTime = timeout = 0; + if (!ret) + error = GetLastError(); + for (j = 0; !error && j < urlArray->cUrl; j++) + { + PCCRL_CONTEXT crl; + + ret = CryptRetrieveObjectByUrlW(urlArray->rgwszUrl[j], + CONTEXT_OID_CRL, retrievalFlags, timeout, (void **)&crl, + NULL, NULL, NULL, NULL); + if (ret) + { + error = verify_cert_revocation_with_crl(cert, crl, index, + pTime, pRevStatus); + if (!error && timeout) + { + DWORD time = GetTickCount(); + + if ((int)(endTime - time) <= 0) + { + error = ERROR_TIMEOUT; + pRevStatus->dwIndex = index; + } + else + timeout = endTime - time; + } + CertFreeCRLContext(crl); + } + else + error = CRYPT_E_REVOCATION_OFFLINE; + } + 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) +{ + BOOL ret; + DWORD error, size; + CERT_AUTHORITY_INFO_ACCESS *aia; + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_AUTHORITY_INFO_ACCESS, + value->pbData, value->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &aia, &size); + if (ret) + { + DWORD i; + + for (i = 0; i < aia->cAccDescr; i++) + if (!strcmp(aia->rgAccDescr[i].pszAccessMethod, + szOID_PKIX_OCSP)) + { + if (aia->rgAccDescr[i].AccessLocation.dwAltNameChoice == + CERT_ALT_NAME_URL) + FIXME("OCSP URL = %s\n", + debugstr_w(aia->rgAccDescr[i].AccessLocation.u.pwszURL)); + else + FIXME("unsupported AccessLocation type %d\n", + aia->rgAccDescr[i].AccessLocation.dwAltNameChoice); + } + LocalFree(aia); + /* FIXME: lie and pretend OCSP validated the cert */ + error = ERROR_SUCCESS; + } + else + error = GetLastError(); + return error; +} + +static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, + FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, + PCERT_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); + 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); + else + { + if (pRevPara && pRevPara->hCrlStore && pRevPara->pIssuerCert) + { + PCCRL_CONTEXT crl = NULL; + BOOL canSignCRLs; + + /* If the caller told us about the issuer, make sure the issuer + * can sign CRLs before looking for one. + */ + if ((ext = CertFindExtension(szOID_KEY_USAGE, + pRevPara->pIssuerCert->pCertInfo->cExtension, + pRevPara->pIssuerCert->pCertInfo->rgExtension))) + { + CRYPT_BIT_BLOB usage; + DWORD size = sizeof(usage); + + if (!CryptDecodeObjectEx(cert->dwCertEncodingType, X509_BITS, + ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size)) + canSignCRLs = FALSE; + else if (usage.cbData > 2) + { + /* The key usage extension only defines 9 bits => no more + * than 2 bytes are needed to encode all known usages. + */ + canSignCRLs = FALSE; + } + else + { + BYTE usageBits = usage.pbData[usage.cbData - 1]; + + canSignCRLs = usageBits & CERT_CRL_SIGN_KEY_USAGE; + } + } + else + canSignCRLs = TRUE; + if (canSignCRLs) + { + /* If the caller was helpful enough to tell us where to find a + * CRL for the cert, look for one and check it. + */ + crl = CertFindCRLInStore(pRevPara->hCrlStore, + cert->dwCertEncodingType, + CRL_FIND_ISSUED_BY_SIGNATURE_FLAG | + CRL_FIND_ISSUED_BY_AKI_FLAG, + CRL_FIND_ISSUED_BY, pRevPara->pIssuerCert, NULL); + } + if (crl) + { + error = verify_cert_revocation_with_crl(cert, crl, index, + pTime, pRevStatus); + CertFreeCRLContext(crl); + } + else + { + error = CRYPT_E_NO_REVOCATION_CHECK; + pRevStatus->dwIndex = index; + } + } + else + { + error = CRYPT_E_NO_REVOCATION_CHECK; + pRevStatus->dwIndex = index; + } + } + return error; +} + +typedef struct _CERT_REVOCATION_PARA_NO_EXTRA_FIELDS { + DWORD cbSize; + PCCERT_CONTEXT pIssuerCert; + DWORD cCertStore; + HCERTSTORE *rgCertStore; + HCERTSTORE hCrlStore; + LPFILETIME pftTimeToUse; +} CERT_REVOCATION_PARA_NO_EXTRA_FIELDS, *PCERT_REVOCATION_PARA_NO_EXTRA_FIELDS; + typedef struct _OLD_CERT_REVOCATION_STATUS { DWORD cbSize; DWORD dwIndex; @@ -1452,7 +1800,8 @@ PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus) { DWORD error = 0, i; - BOOL ret; + FILETIME now; + LPFILETIME pTime = NULL;
TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType, cContext, rgpvContext, dwFlags, pRevPara, pRevStatus); @@ -1463,106 +1812,33 @@ SetLastError(E_INVALIDARG); return FALSE; } + if (!cContext) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + if (pRevPara && pRevPara->cbSize >= + sizeof(CERT_REVOCATION_PARA_NO_EXTRA_FIELDS)) + pTime = pRevPara->pftTimeToUse; + if (!pTime) + { + GetSystemTimeAsFileTime(&now); + pTime = &now; + } memset(&pRevStatus->dwIndex, 0, pRevStatus->cbSize - sizeof(DWORD)); if (dwRevType != CERT_CONTEXT_REVOCATION_TYPE) - { error = CRYPT_E_NO_REVOCATION_CHECK; - ret = FALSE; - } else { - ret = TRUE; - for (i = 0; ret && i < cContext; i++) - { - DWORD cbUrlArray; - - ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, - rgpvContext[i], 0, NULL, &cbUrlArray, NULL, NULL, NULL); - if (!ret && GetLastError() == CRYPT_E_NOT_FOUND) - { - error = CRYPT_E_NO_REVOCATION_CHECK; - pRevStatus->dwIndex = i; - } - else if (ret) - { - CRYPT_URL_ARRAY *urlArray = CryptMemAlloc(cbUrlArray); - - if (urlArray) - { - DWORD j, retrievalFlags = 0, startTime, endTime, timeout; - - ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, - rgpvContext[i], 0, urlArray, &cbUrlArray, NULL, NULL, - NULL); - if (dwFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION) - retrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL; - if (dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG && - pRevPara->cbSize >= offsetof(CERT_REVOCATION_PARA, - dwUrlRetrievalTimeout) + sizeof(DWORD)) - { - startTime = GetTickCount(); - endTime = startTime + pRevPara->dwUrlRetrievalTimeout; - timeout = pRevPara->dwUrlRetrievalTimeout; - } - else - endTime = timeout = 0; - for (j = 0; ret && j < urlArray->cUrl; j++) - { - PCCRL_CONTEXT crl; - - ret = CryptRetrieveObjectByUrlW(urlArray->rgwszUrl[j], - CONTEXT_OID_CRL, retrievalFlags, timeout, - (void **)&crl, NULL, NULL, NULL, NULL); - if (ret) - { - PCRL_ENTRY entry = NULL; - - CertFindCertificateInCRL( - rgpvContext[i], crl, 0, NULL, - &entry); - if (entry) - { - error = CRYPT_E_REVOKED; - pRevStatus->dwIndex = i; - ret = FALSE; - } - else if (timeout) - { - DWORD time = GetTickCount(); - - if ((int)(endTime - time) <= 0) - { - error = ERROR_TIMEOUT; - pRevStatus->dwIndex = i; - ret = FALSE; - } - else - timeout = endTime - time; - } - CertFreeCRLContext(crl); - } - else - error = CRYPT_E_REVOCATION_OFFLINE; - } - CryptMemFree(urlArray); - } - else - { - error = ERROR_OUTOFMEMORY; - pRevStatus->dwIndex = i; - ret = FALSE; - } - } - else - pRevStatus->dwIndex = i; - } - } - - if (!ret) + for (i = 0; !error && i < cContext; i++) + error = verify_cert_revocation(rgpvContext[i], i, pTime, dwFlags, + pRevPara, pRevStatus); + } + if (error) { SetLastError(error); pRevStatus->dwError = error; } - TRACE("returning %d (%08x)\n", ret, error); - return ret; -} + TRACE("returning %d (%08x)\n", !error, error); + return !error; +}