Juan Lang : cryptnet: Partially implement CryptGetObjectUrl.
Alexandre Julliard
julliard at winehq.org
Fri Oct 19 08:35:45 CDT 2007
Module: wine
Branch: master
Commit: 43bdf4e52d929d65aee05c9c23f6ea896902d07a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=43bdf4e52d929d65aee05c9c23f6ea896902d07a
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Oct 18 10:29:34 2007 -0700
cryptnet: Partially implement CryptGetObjectUrl.
---
dlls/cryptnet/cryptnet_main.c | 204 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 202 insertions(+), 2 deletions(-)
diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c
index 67a1ebb..206ba24 100644
--- a/dlls/cryptnet/cryptnet_main.c
+++ b/dlls/cryptnet/cryptnet_main.c
@@ -18,10 +18,13 @@
*/
#include "config.h"
+#include "wine/port.h"
+#include <stdio.h>
#include "windef.h"
#include "wine/debug.h"
#include "winbase.h"
#include "winnt.h"
+#define NONAMELESSUNION
#include "wincrypt.h"
WINE_DEFAULT_DEBUG_CHANNEL(cryptnet);
@@ -78,6 +81,169 @@ HRESULT WINAPI DllUnregisterServer(void)
return S_OK;
}
+static const char *url_oid_to_str(LPCSTR oid)
+{
+ if (HIWORD(oid))
+ return oid;
+ else
+ {
+ static char buf[10];
+
+ switch (LOWORD(oid))
+ {
+#define _x(oid) case LOWORD(oid): return #oid
+ _x(URL_OID_CERTIFICATE_ISSUER);
+ _x(URL_OID_CERTIFICATE_CRL_DIST_POINT);
+ _x(URL_OID_CTL_ISSUER);
+ _x(URL_OID_CTL_NEXT_UPDATE);
+ _x(URL_OID_CRL_ISSUER);
+ _x(URL_OID_CERTIFICATE_FRESHEST_CRL);
+ _x(URL_OID_CRL_FRESHEST_CRL);
+ _x(URL_OID_CROSS_CERT_DIST_POINT);
+#undef _x
+ default:
+ snprintf(buf, sizeof(buf), "%d", LOWORD(oid));
+ return buf;
+ }
+ }
+}
+
+typedef BOOL (WINAPI *UrlDllGetObjectUrlFunc)(LPCSTR, LPVOID, DWORD,
+ PCRYPT_URL_ARRAY, DWORD *, PCRYPT_URL_INFO, DWORD *, LPVOID);
+
+static BOOL WINAPI CRYPT_GetUrlFromCertificateIssuer(LPCSTR pszUrlOid,
+ 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 = (PCCERT_CONTEXT)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)))
+ {
+ CRL_DIST_POINTS_INFO *info;
+ DWORD size;
+
+ ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CRL_DIST_POINTS,
+ ext->Value.pbData, ext->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.FullName;
+
+ for (j = 0; j < name->cAltEntry; j++)
+ if (name->rgAltEntry[j].dwAltNameChoice ==
+ CERT_ALT_NAME_URL)
+ {
+ if (name->rgAltEntry[j].pwszURL)
+ {
+ cUrl++;
+ bytesNeeded += sizeof(LPWSTR) +
+ (lstrlenW(name->rgAltEntry[j].pwszURL) + 1)
+ * sizeof(WCHAR);
+ }
+ }
+ }
+ if (!pcbUrlArray)
+ SetLastError(E_INVALIDARG);
+ 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.FullName;
+
+ for (j = 0; j < name->cAltEntry; j++)
+ if (name->rgAltEntry[j].dwAltNameChoice ==
+ CERT_ALT_NAME_URL)
+ {
+ if (name->rgAltEntry[j].pwszURL)
+ {
+ lstrcpyW(nextUrl,
+ name->rgAltEntry[j].pwszURL);
+ pUrlArray->rgwszUrl[pUrlArray->cUrl++] =
+ nextUrl;
+ nextUrl +=
+ (lstrlenW(name->rgAltEntry[j].pwszURL) + 1)
+ * sizeof(WCHAR);
+ }
+ }
+ }
+ }
+ 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);
+ }
+ }
+ else
+ SetLastError(CRYPT_E_NOT_FOUND);
+ return ret;
+}
+
/***********************************************************************
* CryptGetObjectUrl (CRYPTNET.@)
*/
@@ -85,9 +251,43 @@ BOOL WINAPI CryptGetObjectUrl(LPCSTR pszUrlOid, LPVOID pvPara, DWORD dwFlags,
PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo,
DWORD *pcbUrlInfo, LPVOID pvReserved)
{
- FIXME("(%s, %p, %08x, %p, %p, %p, %p, %p): stub\n", debugstr_a(pszUrlOid),
+ UrlDllGetObjectUrlFunc func = NULL;
+ HCRYPTOIDFUNCADDR hFunc = NULL;
+ BOOL ret = FALSE;
+
+ TRACE("(%s, %p, %08x, %p, %p, %p, %p, %p)\n", debugstr_a(pszUrlOid),
pvPara, dwFlags, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved);
- return FALSE;
+
+ if (!HIWORD(pszUrlOid))
+ {
+ switch (LOWORD(pszUrlOid))
+ {
+ case LOWORD(URL_OID_CERTIFICATE_ISSUER):
+ func = CRYPT_GetUrlFromCertificateIssuer;
+ break;
+ case LOWORD(URL_OID_CERTIFICATE_CRL_DIST_POINT):
+ func = CRYPT_GetUrlFromCertificateCRLDistPoint;
+ break;
+ default:
+ FIXME("unimplemented for %s\n", url_oid_to_str(pszUrlOid));
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ }
+ }
+ else
+ {
+ static HCRYPTOIDFUNCSET set = NULL;
+
+ if (!set)
+ set = CryptInitOIDFunctionSet(URL_OID_GET_OBJECT_URL_FUNC, 0);
+ CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, pszUrlOid, 0,
+ (void **)&func, &hFunc);
+ }
+ if (func)
+ ret = func(pszUrlOid, pvPara, dwFlags, pUrlArray, pcbUrlArray,
+ pUrlInfo, pcbUrlInfo, pvReserved);
+ if (hFunc)
+ CryptFreeOIDFunctionAddress(hFunc, 0);
+ return ret;
}
/***********************************************************************
More information about the wine-cvs
mailing list