2 * Copyright (C) 2006 Maarten Lankhorst
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
24 #include "wine/debug.h"
29 #define NONAMELESSUNION
32 WINE_DEFAULT_DEBUG_CHANNEL(cryptnet);
34 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
36 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
39 case DLL_WINE_PREATTACH:
40 return FALSE; /* prefer native version */
41 case DLL_PROCESS_ATTACH:
42 DisableThreadLibraryCalls(hinstDLL);
44 case DLL_PROCESS_DETACH:
45 /* Do uninitialisation here */
52 static const WCHAR cryptNet[] = { 'c','r','y','p','t','n','e','t','.',
54 static const WCHAR ldapProvOpenStore[] = { 'L','d','a','p','P','r','o','v',
55 'O','p','e','S','t','o','r','e',0 };
57 /***********************************************************************
58 * DllRegisterServer (CRYPTNET.@)
60 HRESULT WINAPI DllRegisterServer(void)
63 CryptRegisterDefaultOIDFunction(X509_ASN_ENCODING,
64 CRYPT_OID_VERIFY_REVOCATION_FUNC, 0, cryptNet);
65 CryptRegisterOIDFunction(0, CRYPT_OID_OPEN_STORE_PROV_FUNC, "Ldap",
66 cryptNet, "LdapProvOpenStore");
67 CryptRegisterOIDFunction(0, CRYPT_OID_OPEN_STORE_PROV_FUNC,
68 CERT_STORE_PROV_LDAP_W, cryptNet, "LdapProvOpenStore");
72 /***********************************************************************
73 * DllUnregisterServer (CRYPTNET.@)
75 HRESULT WINAPI DllUnregisterServer(void)
78 CryptUnregisterDefaultOIDFunction(X509_ASN_ENCODING,
79 CRYPT_OID_VERIFY_REVOCATION_FUNC, cryptNet);
80 CryptUnregisterOIDFunction(0, CRYPT_OID_OPEN_STORE_PROV_FUNC, "Ldap");
81 CryptUnregisterOIDFunction(0, CRYPT_OID_OPEN_STORE_PROV_FUNC,
82 CERT_STORE_PROV_LDAP_W);
86 static const char *url_oid_to_str(LPCSTR oid)
96 #define _x(oid) case LOWORD(oid): return #oid
97 _x(URL_OID_CERTIFICATE_ISSUER);
98 _x(URL_OID_CERTIFICATE_CRL_DIST_POINT);
99 _x(URL_OID_CTL_ISSUER);
100 _x(URL_OID_CTL_NEXT_UPDATE);
101 _x(URL_OID_CRL_ISSUER);
102 _x(URL_OID_CERTIFICATE_FRESHEST_CRL);
103 _x(URL_OID_CRL_FRESHEST_CRL);
104 _x(URL_OID_CROSS_CERT_DIST_POINT);
107 snprintf(buf, sizeof(buf), "%d", LOWORD(oid));
113 typedef BOOL (WINAPI *UrlDllGetObjectUrlFunc)(LPCSTR, LPVOID, DWORD,
114 PCRYPT_URL_ARRAY, DWORD *, PCRYPT_URL_INFO, DWORD *, LPVOID);
116 static BOOL WINAPI CRYPT_GetUrlFromCertificateIssuer(LPCSTR pszUrlOid,
117 LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray,
118 PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved)
120 /* FIXME: This depends on the AIA (authority info access) extension being
121 * supported in crypt32.
124 SetLastError(CRYPT_E_NOT_FOUND);
128 static BOOL WINAPI CRYPT_GetUrlFromCertificateCRLDistPoint(LPCSTR pszUrlOid,
129 LPVOID pvPara, DWORD dwFlags, PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray,
130 PCRYPT_URL_INFO pUrlInfo, DWORD *pcbUrlInfo, LPVOID pvReserved)
132 PCCERT_CONTEXT cert = (PCCERT_CONTEXT)pvPara;
136 /* The only applicable flag is CRYPT_GET_URL_FROM_EXTENSION */
137 if (dwFlags && !(dwFlags & CRYPT_GET_URL_FROM_EXTENSION))
139 SetLastError(CRYPT_E_NOT_FOUND);
142 if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS,
143 cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
145 CRL_DIST_POINTS_INFO *info;
148 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CRL_DIST_POINTS,
149 ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
153 DWORD i, cUrl, bytesNeeded = sizeof(CRYPT_URL_ARRAY);
155 for (i = 0, cUrl = 0; i < info->cDistPoint; i++)
156 if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice
157 == CRL_DIST_POINT_FULL_NAME)
160 CERT_ALT_NAME_INFO *name =
161 &info->rgDistPoint[i].DistPointName.FullName;
163 for (j = 0; j < name->cAltEntry; j++)
164 if (name->rgAltEntry[j].dwAltNameChoice ==
167 if (name->rgAltEntry[j].pwszURL)
170 bytesNeeded += sizeof(LPWSTR) +
171 (lstrlenW(name->rgAltEntry[j].pwszURL) + 1)
177 SetLastError(E_INVALIDARG);
179 *pcbUrlArray = bytesNeeded;
180 else if (*pcbUrlArray < bytesNeeded)
182 SetLastError(ERROR_MORE_DATA);
183 *pcbUrlArray = bytesNeeded;
190 *pcbUrlArray = bytesNeeded;
192 pUrlArray->rgwszUrl =
193 (LPWSTR *)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY));
194 nextUrl = (LPWSTR)((BYTE *)pUrlArray + sizeof(CRYPT_URL_ARRAY)
195 + cUrl * sizeof(LPWSTR));
196 for (i = 0; i < info->cDistPoint; i++)
197 if (info->rgDistPoint[i].DistPointName.dwDistPointNameChoice
198 == CRL_DIST_POINT_FULL_NAME)
201 CERT_ALT_NAME_INFO *name =
202 &info->rgDistPoint[i].DistPointName.FullName;
204 for (j = 0; j < name->cAltEntry; j++)
205 if (name->rgAltEntry[j].dwAltNameChoice ==
208 if (name->rgAltEntry[j].pwszURL)
211 name->rgAltEntry[j].pwszURL);
212 pUrlArray->rgwszUrl[pUrlArray->cUrl++] =
215 (lstrlenW(name->rgAltEntry[j].pwszURL) + 1)
225 FIXME("url info: stub\n");
227 *pcbUrlInfo = sizeof(CRYPT_URL_INFO);
228 else if (*pcbUrlInfo < sizeof(CRYPT_URL_INFO))
230 *pcbUrlInfo = sizeof(CRYPT_URL_INFO);
231 SetLastError(ERROR_MORE_DATA);
236 *pcbUrlInfo = sizeof(CRYPT_URL_INFO);
237 memset(pUrlInfo, 0, sizeof(CRYPT_URL_INFO));
245 SetLastError(CRYPT_E_NOT_FOUND);
249 /***********************************************************************
250 * CryptGetObjectUrl (CRYPTNET.@)
252 BOOL WINAPI CryptGetObjectUrl(LPCSTR pszUrlOid, LPVOID pvPara, DWORD dwFlags,
253 PCRYPT_URL_ARRAY pUrlArray, DWORD *pcbUrlArray, PCRYPT_URL_INFO pUrlInfo,
254 DWORD *pcbUrlInfo, LPVOID pvReserved)
256 UrlDllGetObjectUrlFunc func = NULL;
257 HCRYPTOIDFUNCADDR hFunc = NULL;
260 TRACE("(%s, %p, %08x, %p, %p, %p, %p, %p)\n", debugstr_a(pszUrlOid),
261 pvPara, dwFlags, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved);
263 if (!HIWORD(pszUrlOid))
265 switch (LOWORD(pszUrlOid))
267 case LOWORD(URL_OID_CERTIFICATE_ISSUER):
268 func = CRYPT_GetUrlFromCertificateIssuer;
270 case LOWORD(URL_OID_CERTIFICATE_CRL_DIST_POINT):
271 func = CRYPT_GetUrlFromCertificateCRLDistPoint;
274 FIXME("unimplemented for %s\n", url_oid_to_str(pszUrlOid));
275 SetLastError(ERROR_FILE_NOT_FOUND);
280 static HCRYPTOIDFUNCSET set = NULL;
283 set = CryptInitOIDFunctionSet(URL_OID_GET_OBJECT_URL_FUNC, 0);
284 CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, pszUrlOid, 0,
285 (void **)&func, &hFunc);
288 ret = func(pszUrlOid, pvPara, dwFlags, pUrlArray, pcbUrlArray,
289 pUrlInfo, pcbUrlInfo, pvReserved);
291 CryptFreeOIDFunctionAddress(hFunc, 0);
295 /***********************************************************************
296 * CryptRetrieveObjectByUrlA (CRYPTNET.@)
298 BOOL WINAPI CryptRetrieveObjectByUrlA(LPCSTR pszURL, LPCSTR pszObjectOid,
299 DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject,
300 HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify,
301 PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
306 TRACE("(%s, %s, %08x, %d, %p, %p, %p, %p, %p)\n", debugstr_a(pszURL),
307 debugstr_a(pszObjectOid), dwRetrievalFlags, dwTimeout, ppvObject,
308 hAsyncRetrieve, pCredentials, pvVerify, pAuxInfo);
312 SetLastError(ERROR_INVALID_PARAMETER);
315 len = MultiByteToWideChar(CP_ACP, 0, pszURL, -1, NULL, 0);
318 LPWSTR url = CryptMemAlloc(len * sizeof(WCHAR));
322 MultiByteToWideChar(CP_ACP, 0, pszURL, -1, url, len);
323 ret = CryptRetrieveObjectByUrlW(url, pszObjectOid,
324 dwRetrievalFlags, dwTimeout, ppvObject, hAsyncRetrieve,
325 pCredentials, pvVerify, pAuxInfo);
329 SetLastError(ERROR_OUTOFMEMORY);
334 static void WINAPI CRYPT_FreeBlob(LPCSTR pszObjectOid,
335 PCRYPT_BLOB_ARRAY pObject, void *pvFreeContext)
339 for (i = 0; i < pObject->cBlob; i++)
340 CryptMemFree(pObject->rgBlob[i].pbData);
341 CryptMemFree(pObject->rgBlob);
344 static BOOL WINAPI FTP_RetrieveEncodedObjectW(LPCWSTR pszURL,
345 LPCSTR pszObjectOid, DWORD dwRetrievalFlags, DWORD dwTimeout,
346 PCRYPT_BLOB_ARRAY pObject, PFN_FREE_ENCODED_OBJECT_FUNC *ppfnFreeObject,
347 void **ppvFreeContext, HCRYPTASYNC hAsyncRetrieve,
348 PCRYPT_CREDENTIALS pCredentials, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
350 FIXME("(%s, %s, %08x, %d, %p, %p, %p, %p, %p, %p)\n", debugstr_w(pszURL),
351 debugstr_a(pszObjectOid), dwRetrievalFlags, dwTimeout, pObject,
352 ppfnFreeObject, ppvFreeContext, hAsyncRetrieve, pCredentials, pAuxInfo);
355 pObject->rgBlob = NULL;
356 *ppfnFreeObject = CRYPT_FreeBlob;
357 *ppvFreeContext = NULL;
361 static BOOL WINAPI HTTP_RetrieveEncodedObjectW(LPCWSTR pszURL,
362 LPCSTR pszObjectOid, DWORD dwRetrievalFlags, DWORD dwTimeout,
363 PCRYPT_BLOB_ARRAY pObject, PFN_FREE_ENCODED_OBJECT_FUNC *ppfnFreeObject,
364 void **ppvFreeContext, HCRYPTASYNC hAsyncRetrieve,
365 PCRYPT_CREDENTIALS pCredentials, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
367 FIXME("(%s, %s, %08x, %d, %p, %p, %p, %p, %p, %p)\n", debugstr_w(pszURL),
368 debugstr_a(pszObjectOid), dwRetrievalFlags, dwTimeout, pObject,
369 ppfnFreeObject, ppvFreeContext, hAsyncRetrieve, pCredentials, pAuxInfo);
372 pObject->rgBlob = NULL;
373 *ppfnFreeObject = CRYPT_FreeBlob;
374 *ppvFreeContext = NULL;
378 static BOOL WINAPI File_RetrieveEncodedObjectW(LPCWSTR pszURL,
379 LPCSTR pszObjectOid, DWORD dwRetrievalFlags, DWORD dwTimeout,
380 PCRYPT_BLOB_ARRAY pObject, PFN_FREE_ENCODED_OBJECT_FUNC *ppfnFreeObject,
381 void **ppvFreeContext, HCRYPTASYNC hAsyncRetrieve,
382 PCRYPT_CREDENTIALS pCredentials, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
384 URL_COMPONENTSW components = { sizeof(components), 0 };
387 TRACE("(%s, %s, %08x, %d, %p, %p, %p, %p, %p, %p)\n", debugstr_w(pszURL),
388 debugstr_a(pszObjectOid), dwRetrievalFlags, dwTimeout, pObject,
389 ppfnFreeObject, ppvFreeContext, hAsyncRetrieve, pCredentials, pAuxInfo);
392 pObject->rgBlob = NULL;
393 *ppfnFreeObject = CRYPT_FreeBlob;
394 *ppvFreeContext = NULL;
396 components.dwUrlPathLength = 1;
397 ret = InternetCrackUrlW(pszURL, 0, ICU_DECODE, &components);
402 /* 3 == lstrlenW(L"c:") + 1 */
403 path = CryptMemAlloc((components.dwUrlPathLength + 3) * sizeof(WCHAR));
408 /* Try to create the file directly - Wine handles / in pathnames */
409 lstrcpynW(path, components.lpszUrlPath,
410 components.dwUrlPathLength + 1);
411 hFile = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
412 FILE_ATTRIBUTE_NORMAL, NULL);
413 if (hFile == INVALID_HANDLE_VALUE)
415 /* Try again on the current drive */
416 GetCurrentDirectoryW(components.dwUrlPathLength, path);
419 lstrcpynW(path + 2, components.lpszUrlPath,
420 components.dwUrlPathLength + 1);
421 hFile = CreateFileW(path, GENERIC_READ, 0, NULL,
422 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
424 if (hFile == INVALID_HANDLE_VALUE)
426 /* Try again on the Windows drive */
427 GetWindowsDirectoryW(path, components.dwUrlPathLength);
430 lstrcpynW(path + 2, components.lpszUrlPath,
431 components.dwUrlPathLength + 1);
432 hFile = CreateFileW(path, GENERIC_READ, 0, NULL,
433 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
437 if (hFile != INVALID_HANDLE_VALUE)
441 if ((ret = GetFileSizeEx(hFile, &size)))
445 WARN("file too big\n");
446 SetLastError(ERROR_INVALID_DATA);
451 CRYPT_DATA_BLOB blob;
453 blob.pbData = CryptMemAlloc(size.LowPart);
456 blob.cbData = size.LowPart;
457 ret = ReadFile(hFile, blob.pbData, size.LowPart,
462 CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
466 memcpy(pObject->rgBlob, &blob,
467 sizeof(CRYPT_DATA_BLOB));
471 SetLastError(ERROR_OUTOFMEMORY);
476 CryptMemFree(blob.pbData);
479 if (pAuxInfo && pAuxInfo->cbSize >=
480 offsetof(CRYPT_RETRIEVE_AUX_INFO,
481 pLastSyncTime) + sizeof(PFILETIME) &&
482 pAuxInfo->pLastSyncTime)
483 GetFileTime(hFile, NULL, NULL,
484 pAuxInfo->pLastSyncTime);
489 SetLastError(ERROR_OUTOFMEMORY);
504 typedef BOOL (WINAPI *SchemeDllRetrieveEncodedObjectW)(LPCWSTR pwszUrl,
505 LPCSTR pszObjectOid, DWORD dwRetrievalFlags, DWORD dwTimeout,
506 PCRYPT_BLOB_ARRAY pObject, PFN_FREE_ENCODED_OBJECT_FUNC *ppfnFreeObject,
507 void **ppvFreeContext, HCRYPTASYNC hAsyncRetrieve,
508 PCRYPT_CREDENTIALS pCredentials, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo);
510 static BOOL CRYPT_GetRetrieveFunction(LPCWSTR pszURL,
511 SchemeDllRetrieveEncodedObjectW *pFunc, HCRYPTOIDFUNCADDR *phFunc)
513 URL_COMPONENTSW components = { sizeof(components), 0 };
518 components.dwSchemeLength = 1;
519 ret = InternetCrackUrlW(pszURL, 0, ICU_DECODE, &components);
522 /* Microsoft always uses CryptInitOIDFunctionSet/
523 * CryptGetOIDFunctionAddress, but there doesn't seem to be a pressing
524 * reason to do so for builtin schemes.
526 switch (components.nScheme)
528 case INTERNET_SCHEME_FTP:
529 *pFunc = FTP_RetrieveEncodedObjectW;
531 case INTERNET_SCHEME_HTTP:
532 *pFunc = HTTP_RetrieveEncodedObjectW;
534 case INTERNET_SCHEME_FILE:
535 *pFunc = File_RetrieveEncodedObjectW;
539 int len = WideCharToMultiByte(CP_ACP, 0, components.lpszScheme,
540 components.dwSchemeLength, NULL, 0, NULL, NULL);
544 LPSTR scheme = CryptMemAlloc(len);
548 static HCRYPTOIDFUNCSET set = NULL;
551 set = CryptInitOIDFunctionSet(
552 SCHEME_OID_RETRIEVE_ENCODED_OBJECTW_FUNC, 0);
553 WideCharToMultiByte(CP_ACP, 0, components.lpszScheme,
554 components.dwSchemeLength, scheme, len, NULL, NULL);
555 ret = CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING,
556 scheme, 0, (void **)pFunc, phFunc);
557 CryptMemFree(scheme);
561 SetLastError(ERROR_OUTOFMEMORY);
573 static BOOL WINAPI CRYPT_CreateBlob(LPCSTR pszObjectOid,
574 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
577 CRYPT_BLOB_ARRAY *context;
580 size = sizeof(CRYPT_BLOB_ARRAY) + pObject->cBlob * sizeof(CRYPT_DATA_BLOB);
581 for (i = 0; i < pObject->cBlob; i++)
582 size += pObject->rgBlob[i].cbData;
583 context = CryptMemAlloc(size);
590 (CRYPT_DATA_BLOB *)((LPBYTE)context + sizeof(CRYPT_BLOB_ARRAY));
592 (LPBYTE)context->rgBlob + pObject->cBlob * sizeof(CRYPT_DATA_BLOB);
593 for (i = 0; i < pObject->cBlob; i++)
595 memcpy(nextData, pObject->rgBlob[i].pbData,
596 pObject->rgBlob[i].cbData);
597 context->rgBlob[i].pbData = nextData;
598 context->rgBlob[i].cbData = pObject->rgBlob[i].cbData;
599 nextData += pObject->rgBlob[i].cbData;
602 *ppvContext = context;
608 typedef BOOL (WINAPI *AddContextToStore)(HCERTSTORE hCertStore,
609 const void *pContext, DWORD dwAddDisposition, const void **ppStoreContext);
611 static BOOL CRYPT_CreateContext(PCRYPT_BLOB_ARRAY pObject,
612 DWORD dwExpectedContentTypeFlags, AddContextToStore addFunc, void **ppvContext)
618 SetLastError(ERROR_INVALID_DATA);
622 else if (pObject->cBlob == 1)
624 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &pObject->rgBlob[0],
625 dwExpectedContentTypeFlags, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL,
626 NULL, NULL, NULL, NULL, (const void **)ppvContext))
628 SetLastError(CRYPT_E_NO_MATCH);
634 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
635 CERT_STORE_CREATE_NEW_FLAG, NULL);
642 for (i = 0; i < pObject->cBlob; i++)
644 if (CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
645 &pObject->rgBlob[i], dwExpectedContentTypeFlags,
646 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, NULL,
649 if (!addFunc(store, context, CERT_STORE_ADD_ALWAYS, NULL))
654 SetLastError(CRYPT_E_NO_MATCH);
666 static BOOL WINAPI CRYPT_CreateCert(LPCSTR pszObjectOid,
667 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
669 return CRYPT_CreateContext(pObject, CERT_QUERY_CONTENT_FLAG_CERT,
670 (AddContextToStore)CertAddCertificateContextToStore, ppvContext);
673 static BOOL WINAPI CRYPT_CreateCRL(LPCSTR pszObjectOid,
674 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
676 return CRYPT_CreateContext(pObject, CERT_QUERY_CONTENT_FLAG_CRL,
677 (AddContextToStore)CertAddCRLContextToStore, ppvContext);
680 static BOOL WINAPI CRYPT_CreateCTL(LPCSTR pszObjectOid,
681 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
683 return CRYPT_CreateContext(pObject, CERT_QUERY_CONTENT_FLAG_CTL,
684 (AddContextToStore)CertAddCTLContextToStore, ppvContext);
687 static BOOL WINAPI CRYPT_CreatePKCS7(LPCSTR pszObjectOid,
688 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
694 SetLastError(ERROR_INVALID_DATA);
698 else if (pObject->cBlob == 1)
699 ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &pObject->rgBlob[0],
700 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
701 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED, CERT_QUERY_FORMAT_FLAG_BINARY,
702 0, NULL, NULL, NULL, (HCERTSTORE *)ppvContext, NULL, NULL);
705 FIXME("multiple messages unimplemented\n");
711 static BOOL WINAPI CRYPT_CreateAny(LPCSTR pszObjectOid,
712 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext)
718 SetLastError(ERROR_INVALID_DATA);
724 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
725 CERT_STORE_CREATE_NEW_FLAG, NULL);
729 HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
730 CERT_STORE_CREATE_NEW_FLAG, NULL);
734 CertAddStoreToCollection(store, memStore,
735 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
736 CertCloseStore(memStore, 0);
740 CertCloseStore(store, 0);
749 for (i = 0; i < pObject->cBlob; i++)
751 DWORD contentType, expectedContentTypes =
752 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
753 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED |
754 CERT_QUERY_CONTENT_FLAG_CERT |
755 CERT_QUERY_CONTENT_FLAG_CRL |
756 CERT_QUERY_CONTENT_FLAG_CTL;
757 HCERTSTORE contextStore;
760 if (CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
761 &pObject->rgBlob[i], expectedContentTypes,
762 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
763 &contextStore, NULL, &context))
767 case CERT_QUERY_CONTENT_CERT:
768 if (!CertAddCertificateContextToStore(store,
769 (PCCERT_CONTEXT)context, CERT_STORE_ADD_ALWAYS, NULL))
772 case CERT_QUERY_CONTENT_CRL:
773 if (!CertAddCRLContextToStore(store,
774 (PCCRL_CONTEXT)context, CERT_STORE_ADD_ALWAYS, NULL))
777 case CERT_QUERY_CONTENT_CTL:
778 if (!CertAddCTLContextToStore(store,
779 (PCCTL_CONTEXT)context, CERT_STORE_ADD_ALWAYS, NULL))
783 CertAddStoreToCollection(store, contextStore, 0, 0);
797 typedef BOOL (WINAPI *ContextDllCreateObjectContext)(LPCSTR pszObjectOid,
798 DWORD dwRetrievalFlags, PCRYPT_BLOB_ARRAY pObject, void **ppvContext);
800 static BOOL CRYPT_GetCreateFunction(LPCSTR pszObjectOid,
801 ContextDllCreateObjectContext *pFunc, HCRYPTOIDFUNCADDR *phFunc)
807 if (!HIWORD(pszObjectOid))
809 switch (LOWORD(pszObjectOid))
812 *pFunc = CRYPT_CreateBlob;
814 case LOWORD(CONTEXT_OID_CERTIFICATE):
815 *pFunc = CRYPT_CreateCert;
817 case LOWORD(CONTEXT_OID_CRL):
818 *pFunc = CRYPT_CreateCRL;
820 case LOWORD(CONTEXT_OID_CTL):
821 *pFunc = CRYPT_CreateCTL;
823 case LOWORD(CONTEXT_OID_PKCS7):
824 *pFunc = CRYPT_CreatePKCS7;
826 case LOWORD(CONTEXT_OID_CAPI2_ANY):
827 *pFunc = CRYPT_CreateAny;
833 static HCRYPTOIDFUNCSET set = NULL;
836 set = CryptInitOIDFunctionSet(
837 CONTEXT_OID_CREATE_OBJECT_CONTEXT_FUNC, 0);
838 ret = CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, pszObjectOid,
839 0, (void **)pFunc, phFunc);
844 /***********************************************************************
845 * CryptRetrieveObjectByUrlW (CRYPTNET.@)
847 BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
848 DWORD dwRetrievalFlags, DWORD dwTimeout, LPVOID *ppvObject,
849 HCRYPTASYNC hAsyncRetrieve, PCRYPT_CREDENTIALS pCredentials, LPVOID pvVerify,
850 PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
853 SchemeDllRetrieveEncodedObjectW retrieve;
854 ContextDllCreateObjectContext create;
855 HCRYPTOIDFUNCADDR hRetrieve = 0, hCreate = 0;
857 TRACE("(%s, %s, %08x, %d, %p, %p, %p, %p, %p)\n", debugstr_w(pszURL),
858 debugstr_a(pszObjectOid), dwRetrievalFlags, dwTimeout, ppvObject,
859 hAsyncRetrieve, pCredentials, pvVerify, pAuxInfo);
863 SetLastError(ERROR_INVALID_PARAMETER);
866 ret = CRYPT_GetRetrieveFunction(pszURL, &retrieve, &hRetrieve);
868 ret = CRYPT_GetCreateFunction(pszObjectOid, &create, &hCreate);
871 CRYPT_BLOB_ARRAY object = { 0, NULL };
872 PFN_FREE_ENCODED_OBJECT_FUNC freeObject;
875 ret = retrieve(pszURL, pszObjectOid, dwRetrievalFlags, dwTimeout,
876 &object, &freeObject, &freeContext, hAsyncRetrieve, pCredentials,
880 ret = create(pszObjectOid, dwRetrievalFlags, &object, ppvObject);
881 freeObject(pszObjectOid, &object, freeContext);
885 CryptFreeOIDFunctionAddress(hCreate, 0);
887 CryptFreeOIDFunctionAddress(hRetrieve, 0);
891 /***********************************************************************
892 * CertDllVerifyRevocation (CRYPTNET.@)
894 BOOL WINAPI CertDllVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType,
895 DWORD cContext, void *rgpvContext[], DWORD dwFlags,
896 PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
898 FIXME("(%08x, %d, %d, %p, %08x, %p, %p): stub\n", dwEncodingType, dwRevType,
899 cContext, rgpvContext, dwFlags, pRevPara, pRevStatus);