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/cryptne…
==============================================================================
--- 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;
+}