Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstore.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2002 Mike McCormack for CodeWeavers 00003 * Copyright 2004-2006 Juan Lang 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 * 00019 * FIXME: 00020 * - The concept of physical stores and locations isn't implemented. (This 00021 * doesn't mean registry stores et al aren't implemented. See the PSDK for 00022 * registering and enumerating physical stores and locations.) 00023 * - Many flags, options and whatnot are unimplemented. 00024 */ 00025 00026 #include "config.h" 00027 #include "wine/port.h" 00028 00029 #include <assert.h> 00030 #include <stdarg.h> 00031 #include "windef.h" 00032 #include "winbase.h" 00033 #include "winnls.h" 00034 #include "winreg.h" 00035 #include "winuser.h" 00036 #include "wincrypt.h" 00037 #include "wine/debug.h" 00038 #include "wine/list.h" 00039 #include "wine/exception.h" 00040 #include "crypt32_private.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 00043 00044 static const WINE_CONTEXT_INTERFACE gCertInterface = { 00045 (CreateContextFunc)CertCreateCertificateContext, 00046 (AddContextToStoreFunc)CertAddCertificateContextToStore, 00047 (AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore, 00048 (DuplicateContextFunc)CertDuplicateCertificateContext, 00049 (EnumContextsInStoreFunc)CertEnumCertificatesInStore, 00050 (EnumPropertiesFunc)CertEnumCertificateContextProperties, 00051 (GetContextPropertyFunc)CertGetCertificateContextProperty, 00052 (SetContextPropertyFunc)CertSetCertificateContextProperty, 00053 (SerializeElementFunc)CertSerializeCertificateStoreElement, 00054 (FreeContextFunc)CertFreeCertificateContext, 00055 (DeleteContextFunc)CertDeleteCertificateFromStore, 00056 }; 00057 PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface; 00058 00059 static const WINE_CONTEXT_INTERFACE gCRLInterface = { 00060 (CreateContextFunc)CertCreateCRLContext, 00061 (AddContextToStoreFunc)CertAddCRLContextToStore, 00062 (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore, 00063 (DuplicateContextFunc)CertDuplicateCRLContext, 00064 (EnumContextsInStoreFunc)CertEnumCRLsInStore, 00065 (EnumPropertiesFunc)CertEnumCRLContextProperties, 00066 (GetContextPropertyFunc)CertGetCRLContextProperty, 00067 (SetContextPropertyFunc)CertSetCRLContextProperty, 00068 (SerializeElementFunc)CertSerializeCRLStoreElement, 00069 (FreeContextFunc)CertFreeCRLContext, 00070 (DeleteContextFunc)CertDeleteCRLFromStore, 00071 }; 00072 PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface; 00073 00074 static const WINE_CONTEXT_INTERFACE gCTLInterface = { 00075 (CreateContextFunc)CertCreateCTLContext, 00076 (AddContextToStoreFunc)CertAddCTLContextToStore, 00077 (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore, 00078 (DuplicateContextFunc)CertDuplicateCTLContext, 00079 (EnumContextsInStoreFunc)CertEnumCTLsInStore, 00080 (EnumPropertiesFunc)CertEnumCTLContextProperties, 00081 (GetContextPropertyFunc)CertGetCTLContextProperty, 00082 (SetContextPropertyFunc)CertSetCTLContextProperty, 00083 (SerializeElementFunc)CertSerializeCTLStoreElement, 00084 (FreeContextFunc)CertFreeCTLContext, 00085 (DeleteContextFunc)CertDeleteCTLFromStore, 00086 }; 00087 PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface; 00088 00089 typedef struct _WINE_MEMSTORE 00090 { 00091 WINECRYPT_CERTSTORE hdr; 00092 struct ContextList *certs; 00093 struct ContextList *crls; 00094 struct ContextList *ctls; 00095 } WINE_MEMSTORE, *PWINE_MEMSTORE; 00096 00097 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, 00098 CertStoreType type) 00099 { 00100 store->ref = 1; 00101 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC; 00102 store->type = type; 00103 store->dwOpenFlags = dwFlags; 00104 store->properties = NULL; 00105 } 00106 00107 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store) 00108 { 00109 if (store->properties) 00110 ContextPropertyList_Free(store->properties); 00111 CryptMemFree(store); 00112 } 00113 00114 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, 00115 DWORD unk1) 00116 { 00117 static BOOL warned = FALSE; 00118 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface, 00119 pCRLInterface, pCTLInterface }; 00120 DWORD i; 00121 00122 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1); 00123 if (!warned) 00124 { 00125 FIXME("semi-stub\n"); 00126 warned = TRUE; 00127 } 00128 00129 /* Poor-man's resync: empty first store, then add everything from second 00130 * store to it. 00131 */ 00132 for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++) 00133 { 00134 const void *context; 00135 00136 do { 00137 context = interfaces[i]->enumContextsInStore(store1, NULL); 00138 if (context) 00139 interfaces[i]->deleteFromStore(context); 00140 } while (context); 00141 do { 00142 context = interfaces[i]->enumContextsInStore(store2, context); 00143 if (context) 00144 interfaces[i]->addContextToStore(store1, context, 00145 CERT_STORE_ADD_ALWAYS, NULL); 00146 } while (context); 00147 } 00148 return TRUE; 00149 } 00150 00151 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert, 00152 void *toReplace, const void **ppStoreContext) 00153 { 00154 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00155 PCERT_CONTEXT context; 00156 00157 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext); 00158 00159 context = ContextList_Add(ms->certs, cert, toReplace); 00160 if (context) 00161 { 00162 context->hCertStore = store; 00163 if (ppStoreContext) 00164 *ppStoreContext = CertDuplicateCertificateContext(context); 00165 } 00166 return context ? TRUE : FALSE; 00167 } 00168 00169 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev) 00170 { 00171 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00172 void *ret; 00173 00174 TRACE("(%p, %p)\n", store, pPrev); 00175 00176 ret = ContextList_Enum(ms->certs, pPrev); 00177 if (!ret) 00178 SetLastError(CRYPT_E_NOT_FOUND); 00179 00180 TRACE("returning %p\n", ret); 00181 return ret; 00182 } 00183 00184 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext) 00185 { 00186 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00187 BOOL ret; 00188 00189 if (ContextList_Remove(ms->certs, pCertContext)) 00190 ret = CertFreeCertificateContext(pCertContext); 00191 else 00192 ret = TRUE; 00193 return ret; 00194 } 00195 00196 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl, 00197 void *toReplace, const void **ppStoreContext) 00198 { 00199 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00200 PCRL_CONTEXT context; 00201 00202 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext); 00203 00204 context = ContextList_Add(ms->crls, crl, toReplace); 00205 if (context) 00206 { 00207 context->hCertStore = store; 00208 if (ppStoreContext) 00209 *ppStoreContext = CertDuplicateCRLContext(context); 00210 } 00211 return context ? TRUE : FALSE; 00212 } 00213 00214 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev) 00215 { 00216 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00217 void *ret; 00218 00219 TRACE("(%p, %p)\n", store, pPrev); 00220 00221 ret = ContextList_Enum(ms->crls, pPrev); 00222 if (!ret) 00223 SetLastError(CRYPT_E_NOT_FOUND); 00224 00225 TRACE("returning %p\n", ret); 00226 return ret; 00227 } 00228 00229 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext) 00230 { 00231 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00232 BOOL ret; 00233 00234 if (ContextList_Remove(ms->crls, pCrlContext)) 00235 ret = CertFreeCRLContext(pCrlContext); 00236 else 00237 ret = TRUE; 00238 return ret; 00239 } 00240 00241 static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl, 00242 void *toReplace, const void **ppStoreContext) 00243 { 00244 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00245 PCTL_CONTEXT context; 00246 00247 TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext); 00248 00249 context = ContextList_Add(ms->ctls, ctl, toReplace); 00250 if (context) 00251 { 00252 context->hCertStore = store; 00253 if (ppStoreContext) 00254 *ppStoreContext = CertDuplicateCTLContext(context); 00255 } 00256 return context ? TRUE : FALSE; 00257 } 00258 00259 static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev) 00260 { 00261 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00262 void *ret; 00263 00264 TRACE("(%p, %p)\n", store, pPrev); 00265 00266 ret = ContextList_Enum(ms->ctls, pPrev); 00267 if (!ret) 00268 SetLastError(CRYPT_E_NOT_FOUND); 00269 00270 TRACE("returning %p\n", ret); 00271 return ret; 00272 } 00273 00274 static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext) 00275 { 00276 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; 00277 BOOL ret; 00278 00279 if (ContextList_Remove(ms->ctls, pCtlContext)) 00280 ret = CertFreeCTLContext(pCtlContext); 00281 else 00282 ret = TRUE; 00283 return ret; 00284 } 00285 00286 static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags, 00287 DWORD dwCtrlType, void const *pvCtrlPara) 00288 { 00289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00290 return FALSE; 00291 } 00292 00293 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) 00294 { 00295 WINE_MEMSTORE *store = hCertStore; 00296 00297 TRACE("(%p, %08x)\n", store, dwFlags); 00298 if (dwFlags) 00299 FIXME("Unimplemented flags: %08x\n", dwFlags); 00300 00301 ContextList_Free(store->certs); 00302 ContextList_Free(store->crls); 00303 ContextList_Free(store->ctls); 00304 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store); 00305 } 00306 00307 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, 00308 DWORD dwFlags, const void *pvPara) 00309 { 00310 PWINE_MEMSTORE store; 00311 00312 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); 00313 00314 if (dwFlags & CERT_STORE_DELETE_FLAG) 00315 { 00316 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00317 store = NULL; 00318 } 00319 else 00320 { 00321 store = CryptMemAlloc(sizeof(WINE_MEMSTORE)); 00322 if (store) 00323 { 00324 memset(store, 0, sizeof(WINE_MEMSTORE)); 00325 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem); 00326 store->hdr.closeStore = CRYPT_MemCloseStore; 00327 store->hdr.certs.addContext = CRYPT_MemAddCert; 00328 store->hdr.certs.enumContext = CRYPT_MemEnumCert; 00329 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert; 00330 store->hdr.crls.addContext = CRYPT_MemAddCrl; 00331 store->hdr.crls.enumContext = CRYPT_MemEnumCrl; 00332 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl; 00333 store->hdr.ctls.addContext = CRYPT_MemAddCtl; 00334 store->hdr.ctls.enumContext = CRYPT_MemEnumCtl; 00335 store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl; 00336 store->hdr.control = CRYPT_MemControl; 00337 store->certs = ContextList_Create(pCertInterface, 00338 sizeof(CERT_CONTEXT)); 00339 store->crls = ContextList_Create(pCRLInterface, 00340 sizeof(CRL_CONTEXT)); 00341 store->ctls = ContextList_Create(pCTLInterface, 00342 sizeof(CTL_CONTEXT)); 00343 /* Mem store doesn't need crypto provider, so close it */ 00344 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) 00345 CryptReleaseContext(hCryptProv, 0); 00346 } 00347 } 00348 return (PWINECRYPT_CERTSTORE)store; 00349 } 00350 00351 static const WCHAR rootW[] = { 'R','o','o','t',0 }; 00352 00353 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, 00354 DWORD dwFlags, const void *pvPara) 00355 { 00356 static const WCHAR fmt[] = { '%','s','\\','%','s',0 }; 00357 LPCWSTR storeName = pvPara; 00358 LPWSTR storePath; 00359 PWINECRYPT_CERTSTORE store = NULL; 00360 HKEY root; 00361 LPCWSTR base; 00362 00363 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, 00364 debugstr_w(pvPara)); 00365 00366 if (!pvPara) 00367 { 00368 SetLastError(E_INVALIDARG); 00369 return NULL; 00370 } 00371 /* FIXME: In Windows, the root store (even the current user location) is 00372 * protected: adding to it or removing from it present a user interface, 00373 * and the keys are owned by the system process, not the current user. 00374 * Wine's registry doesn't implement access controls, so a similar 00375 * mechanism isn't possible yet. 00376 */ 00377 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == 00378 CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW)) 00379 return CRYPT_RootOpenStore(hCryptProv, dwFlags); 00380 00381 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) 00382 { 00383 case CERT_SYSTEM_STORE_LOCAL_MACHINE: 00384 root = HKEY_LOCAL_MACHINE; 00385 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; 00386 break; 00387 case CERT_SYSTEM_STORE_CURRENT_USER: 00388 root = HKEY_CURRENT_USER; 00389 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; 00390 break; 00391 case CERT_SYSTEM_STORE_CURRENT_SERVICE: 00392 /* hklm\Software\Microsoft\Cryptography\Services\servicename\ 00393 * SystemCertificates 00394 */ 00395 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n", 00396 debugstr_w(storeName)); 00397 return NULL; 00398 case CERT_SYSTEM_STORE_SERVICES: 00399 /* hklm\Software\Microsoft\Cryptography\Services\servicename\ 00400 * SystemCertificates 00401 */ 00402 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n", 00403 debugstr_w(storeName)); 00404 return NULL; 00405 case CERT_SYSTEM_STORE_USERS: 00406 /* hku\user sid\Software\Microsoft\SystemCertificates */ 00407 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n", 00408 debugstr_w(storeName)); 00409 return NULL; 00410 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY: 00411 root = HKEY_CURRENT_USER; 00412 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; 00413 break; 00414 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY: 00415 root = HKEY_LOCAL_MACHINE; 00416 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; 00417 break; 00418 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE: 00419 /* hklm\Software\Microsoft\EnterpriseCertificates */ 00420 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n", 00421 debugstr_w(storeName)); 00422 return NULL; 00423 default: 00424 SetLastError(E_INVALIDARG); 00425 return NULL; 00426 } 00427 00428 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) * 00429 sizeof(WCHAR)); 00430 if (storePath) 00431 { 00432 LONG rc; 00433 HKEY key; 00434 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : 00435 KEY_ALL_ACCESS; 00436 00437 wsprintfW(storePath, fmt, base, storeName); 00438 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) 00439 rc = RegOpenKeyExW(root, storePath, 0, sam, &key); 00440 else 00441 { 00442 DWORD disp; 00443 00444 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL, 00445 &key, &disp); 00446 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG && 00447 disp == REG_OPENED_EXISTING_KEY) 00448 { 00449 RegCloseKey(key); 00450 rc = ERROR_FILE_EXISTS; 00451 } 00452 } 00453 if (!rc) 00454 { 00455 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key); 00456 RegCloseKey(key); 00457 } 00458 else 00459 SetLastError(rc); 00460 CryptMemFree(storePath); 00461 } 00462 return store; 00463 } 00464 00465 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv, 00466 DWORD dwFlags, const void *pvPara) 00467 { 00468 int len; 00469 PWINECRYPT_CERTSTORE ret = NULL; 00470 00471 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, 00472 debugstr_a(pvPara)); 00473 00474 if (!pvPara) 00475 { 00476 SetLastError(ERROR_FILE_NOT_FOUND); 00477 return NULL; 00478 } 00479 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0); 00480 if (len) 00481 { 00482 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR)); 00483 00484 if (storeName) 00485 { 00486 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len); 00487 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName); 00488 CryptMemFree(storeName); 00489 } 00490 } 00491 return ret; 00492 } 00493 00494 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv, 00495 DWORD dwFlags, const void *pvPara) 00496 { 00497 HCERTSTORE store = 0; 00498 BOOL ret; 00499 00500 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, 00501 debugstr_w(pvPara)); 00502 00503 if (!pvPara) 00504 { 00505 SetLastError(ERROR_FILE_NOT_FOUND); 00506 return NULL; 00507 } 00508 /* This returns a different error than system registry stores if the 00509 * location is invalid. 00510 */ 00511 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) 00512 { 00513 case CERT_SYSTEM_STORE_LOCAL_MACHINE: 00514 case CERT_SYSTEM_STORE_CURRENT_USER: 00515 case CERT_SYSTEM_STORE_CURRENT_SERVICE: 00516 case CERT_SYSTEM_STORE_SERVICES: 00517 case CERT_SYSTEM_STORE_USERS: 00518 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY: 00519 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY: 00520 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE: 00521 ret = TRUE; 00522 break; 00523 default: 00524 SetLastError(ERROR_FILE_NOT_FOUND); 00525 ret = FALSE; 00526 } 00527 if (ret) 00528 { 00529 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 00530 0, 0, dwFlags, pvPara); 00531 00532 if (regStore) 00533 { 00534 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 00535 CERT_STORE_CREATE_NEW_FLAG, NULL); 00536 CertAddStoreToCollection(store, regStore, 00537 dwFlags & CERT_STORE_READONLY_FLAG ? 0 : 00538 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 00539 CertCloseStore(regStore, 0); 00540 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM 00541 * stores. 00542 */ 00543 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == 00544 CERT_SYSTEM_STORE_CURRENT_USER) 00545 { 00546 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER; 00547 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; 00548 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 00549 0, dwFlags, pvPara); 00550 if (regStore) 00551 { 00552 CertAddStoreToCollection(store, regStore, 00553 dwFlags & CERT_STORE_READONLY_FLAG ? 0 : 00554 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); 00555 CertCloseStore(regStore, 0); 00556 } 00557 } 00558 /* System store doesn't need crypto provider, so close it */ 00559 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) 00560 CryptReleaseContext(hCryptProv, 0); 00561 } 00562 } 00563 return store; 00564 } 00565 00566 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, 00567 DWORD dwFlags, const void *pvPara) 00568 { 00569 int len; 00570 PWINECRYPT_CERTSTORE ret = NULL; 00571 00572 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, 00573 debugstr_a(pvPara)); 00574 00575 if (!pvPara) 00576 { 00577 SetLastError(ERROR_FILE_NOT_FOUND); 00578 return NULL; 00579 } 00580 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0); 00581 if (len) 00582 { 00583 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR)); 00584 00585 if (storeName) 00586 { 00587 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len); 00588 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName); 00589 CryptMemFree(storeName); 00590 } 00591 } 00592 return ret; 00593 } 00594 00595 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) 00596 { 00597 HCRYPTMSG msg = hCertStore; 00598 00599 TRACE("(%p, %08x)\n", msg, dwFlags); 00600 CryptMsgClose(msg); 00601 } 00602 00603 static void *msgProvFuncs[] = { 00604 CRYPT_MsgCloseStore, 00605 }; 00606 00607 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv, 00608 DWORD dwFlags, const void *pvPara) 00609 { 00610 PWINECRYPT_CERTSTORE store = NULL; 00611 HCRYPTMSG msg = (HCRYPTMSG)pvPara; 00612 PWINECRYPT_CERTSTORE memStore; 00613 00614 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); 00615 00616 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 00617 CERT_STORE_CREATE_NEW_FLAG, NULL); 00618 if (memStore) 00619 { 00620 BOOL ret; 00621 DWORD size, count, i; 00622 00623 size = sizeof(count); 00624 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size); 00625 for (i = 0; ret && i < count; i++) 00626 { 00627 size = 0; 00628 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size); 00629 if (ret) 00630 { 00631 LPBYTE buf = CryptMemAlloc(size); 00632 00633 if (buf) 00634 { 00635 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size); 00636 if (ret) 00637 ret = CertAddEncodedCertificateToStore(memStore, 00638 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, 00639 NULL); 00640 CryptMemFree(buf); 00641 } 00642 } 00643 } 00644 size = sizeof(count); 00645 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size); 00646 for (i = 0; ret && i < count; i++) 00647 { 00648 size = 0; 00649 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size); 00650 if (ret) 00651 { 00652 LPBYTE buf = CryptMemAlloc(size); 00653 00654 if (buf) 00655 { 00656 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size); 00657 if (ret) 00658 ret = CertAddEncodedCRLToStore(memStore, 00659 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, 00660 NULL); 00661 CryptMemFree(buf); 00662 } 00663 } 00664 } 00665 if (ret) 00666 { 00667 CERT_STORE_PROV_INFO provInfo = { 0 }; 00668 00669 provInfo.cbSize = sizeof(provInfo); 00670 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) / 00671 sizeof(msgProvFuncs[0]); 00672 provInfo.rgpvStoreProvFunc = msgProvFuncs; 00673 provInfo.hStoreProv = CryptMsgDuplicate(msg); 00674 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo); 00675 /* Msg store doesn't need crypto provider, so close it */ 00676 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) 00677 CryptReleaseContext(hCryptProv, 0); 00678 } 00679 else 00680 CertCloseStore(memStore, 0); 00681 } 00682 TRACE("returning %p\n", store); 00683 return store; 00684 } 00685 00686 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv, 00687 DWORD dwFlags, const void *pvPara) 00688 { 00689 HCRYPTMSG msg; 00690 PWINECRYPT_CERTSTORE store = NULL; 00691 const CRYPT_DATA_BLOB *data = pvPara; 00692 BOOL ret; 00693 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 : 00694 CMSG_CRYPT_RELEASE_CONTEXT_FLAG; 00695 00696 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); 00697 00698 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED, 00699 hCryptProv, NULL, NULL); 00700 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE); 00701 if (!ret) 00702 { 00703 CryptMsgClose(msg); 00704 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0, 00705 hCryptProv, NULL, NULL); 00706 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE); 00707 if (ret) 00708 { 00709 DWORD type, size = sizeof(type); 00710 00711 /* Only signed messages are allowed, check type */ 00712 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size); 00713 if (ret && type != CMSG_SIGNED) 00714 { 00715 SetLastError(CRYPT_E_INVALID_MSG_TYPE); 00716 ret = FALSE; 00717 } 00718 } 00719 } 00720 if (ret) 00721 store = CRYPT_MsgOpenStore(0, dwFlags, msg); 00722 CryptMsgClose(msg); 00723 TRACE("returning %p\n", store); 00724 return store; 00725 } 00726 00727 static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv, 00728 DWORD dwFlags, const void *pvPara) 00729 { 00730 HCERTSTORE store; 00731 const CRYPT_DATA_BLOB *data = pvPara; 00732 00733 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); 00734 00735 if (dwFlags & CERT_STORE_DELETE_FLAG) 00736 { 00737 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00738 return NULL; 00739 } 00740 00741 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 00742 CERT_STORE_CREATE_NEW_FLAG, NULL); 00743 if (store) 00744 { 00745 if (!CRYPT_ReadSerializedStoreFromBlob(data, store)) 00746 { 00747 CertCloseStore(store, 0); 00748 store = NULL; 00749 } 00750 } 00751 TRACE("returning %p\n", store); 00752 return (PWINECRYPT_CERTSTORE)store; 00753 } 00754 00755 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv, 00756 DWORD dwFlags, const void *pvPara) 00757 { 00758 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) 00759 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara); 00760 else 00761 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags, 00762 debugstr_w(pvPara)); 00763 return NULL; 00764 } 00765 00766 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, 00767 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, 00768 const void* pvPara) 00769 { 00770 WINECRYPT_CERTSTORE *hcs; 00771 StoreOpenFunc openFunc = NULL; 00772 00773 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider), 00774 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara); 00775 00776 if (IS_INTOID(lpszStoreProvider)) 00777 { 00778 switch (LOWORD(lpszStoreProvider)) 00779 { 00780 case LOWORD(CERT_STORE_PROV_MSG): 00781 openFunc = CRYPT_MsgOpenStore; 00782 break; 00783 case LOWORD(CERT_STORE_PROV_MEMORY): 00784 openFunc = CRYPT_MemOpenStore; 00785 break; 00786 case LOWORD(CERT_STORE_PROV_FILE): 00787 openFunc = CRYPT_FileOpenStore; 00788 break; 00789 case LOWORD(CERT_STORE_PROV_PKCS7): 00790 openFunc = CRYPT_PKCSOpenStore; 00791 break; 00792 case LOWORD(CERT_STORE_PROV_SERIALIZED): 00793 openFunc = CRYPT_SerializedOpenStore; 00794 break; 00795 case LOWORD(CERT_STORE_PROV_REG): 00796 openFunc = CRYPT_RegOpenStore; 00797 break; 00798 case LOWORD(CERT_STORE_PROV_FILENAME_A): 00799 openFunc = CRYPT_FileNameOpenStoreA; 00800 break; 00801 case LOWORD(CERT_STORE_PROV_FILENAME_W): 00802 openFunc = CRYPT_FileNameOpenStoreW; 00803 break; 00804 case LOWORD(CERT_STORE_PROV_COLLECTION): 00805 openFunc = CRYPT_CollectionOpenStore; 00806 break; 00807 case LOWORD(CERT_STORE_PROV_SYSTEM_A): 00808 openFunc = CRYPT_SysOpenStoreA; 00809 break; 00810 case LOWORD(CERT_STORE_PROV_SYSTEM_W): 00811 openFunc = CRYPT_SysOpenStoreW; 00812 break; 00813 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A): 00814 openFunc = CRYPT_SysRegOpenStoreA; 00815 break; 00816 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W): 00817 openFunc = CRYPT_SysRegOpenStoreW; 00818 break; 00819 case LOWORD(CERT_STORE_PROV_PHYSICAL_W): 00820 openFunc = CRYPT_PhysOpenStoreW; 00821 break; 00822 default: 00823 if (LOWORD(lpszStoreProvider)) 00824 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider)); 00825 } 00826 } 00827 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY)) 00828 openFunc = CRYPT_MemOpenStore; 00829 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W)) 00830 openFunc = CRYPT_FileOpenStore; 00831 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM)) 00832 openFunc = CRYPT_SysOpenStoreW; 00833 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7)) 00834 openFunc = CRYPT_PKCSOpenStore; 00835 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED)) 00836 openFunc = CRYPT_SerializedOpenStore; 00837 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION)) 00838 openFunc = CRYPT_CollectionOpenStore; 00839 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY)) 00840 openFunc = CRYPT_SysRegOpenStoreW; 00841 else 00842 { 00843 FIXME("unimplemented type %s\n", lpszStoreProvider); 00844 openFunc = NULL; 00845 } 00846 00847 if (!openFunc) 00848 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType, 00849 hCryptProv, dwFlags, pvPara); 00850 else 00851 hcs = openFunc(hCryptProv, dwFlags, pvPara); 00852 return hcs; 00853 } 00854 00855 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, 00856 LPCSTR szSubSystemProtocol) 00857 { 00858 if (!szSubSystemProtocol) 00859 { 00860 SetLastError(E_INVALIDARG); 00861 return 0; 00862 } 00863 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv, 00864 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol); 00865 } 00866 00867 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, 00868 LPCWSTR szSubSystemProtocol) 00869 { 00870 if (!szSubSystemProtocol) 00871 { 00872 SetLastError(E_INVALIDARG); 00873 return 0; 00874 } 00875 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv, 00876 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol); 00877 } 00878 00879 #define CertContext_CopyProperties(to, from) \ 00880 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT)) 00881 00882 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, 00883 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, 00884 PCCERT_CONTEXT *ppStoreContext) 00885 { 00886 PWINECRYPT_CERTSTORE store = hCertStore; 00887 BOOL ret = TRUE; 00888 PCCERT_CONTEXT toAdd = NULL, existing = NULL; 00889 00890 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, 00891 dwAddDisposition, ppStoreContext); 00892 00893 switch (dwAddDisposition) 00894 { 00895 case CERT_STORE_ADD_ALWAYS: 00896 break; 00897 case CERT_STORE_ADD_NEW: 00898 case CERT_STORE_ADD_REPLACE_EXISTING: 00899 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: 00900 case CERT_STORE_ADD_USE_EXISTING: 00901 case CERT_STORE_ADD_NEWER: 00902 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: 00903 { 00904 BYTE hashToAdd[20]; 00905 DWORD size = sizeof(hashToAdd); 00906 00907 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, 00908 hashToAdd, &size); 00909 if (ret) 00910 { 00911 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd }; 00912 00913 existing = CertFindCertificateInStore(hCertStore, 00914 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, 00915 NULL); 00916 } 00917 break; 00918 } 00919 default: 00920 FIXME("Unimplemented add disposition %d\n", dwAddDisposition); 00921 SetLastError(E_INVALIDARG); 00922 ret = FALSE; 00923 } 00924 00925 switch (dwAddDisposition) 00926 { 00927 case CERT_STORE_ADD_ALWAYS: 00928 toAdd = CertDuplicateCertificateContext(pCertContext); 00929 break; 00930 case CERT_STORE_ADD_NEW: 00931 if (existing) 00932 { 00933 TRACE("found matching certificate, not adding\n"); 00934 SetLastError(CRYPT_E_EXISTS); 00935 ret = FALSE; 00936 } 00937 else 00938 toAdd = CertDuplicateCertificateContext(pCertContext); 00939 break; 00940 case CERT_STORE_ADD_REPLACE_EXISTING: 00941 toAdd = CertDuplicateCertificateContext(pCertContext); 00942 break; 00943 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: 00944 toAdd = CertDuplicateCertificateContext(pCertContext); 00945 if (existing) 00946 CertContext_CopyProperties(toAdd, existing); 00947 break; 00948 case CERT_STORE_ADD_USE_EXISTING: 00949 if (existing) 00950 { 00951 CertContext_CopyProperties(existing, pCertContext); 00952 if (ppStoreContext) 00953 *ppStoreContext = CertDuplicateCertificateContext(existing); 00954 } 00955 else 00956 toAdd = CertDuplicateCertificateContext(pCertContext); 00957 break; 00958 case CERT_STORE_ADD_NEWER: 00959 if (existing) 00960 { 00961 if (CompareFileTime(&existing->pCertInfo->NotBefore, 00962 &pCertContext->pCertInfo->NotBefore) >= 0) 00963 { 00964 TRACE("existing certificate is newer, not adding\n"); 00965 SetLastError(CRYPT_E_EXISTS); 00966 ret = FALSE; 00967 } 00968 else 00969 toAdd = CertDuplicateCertificateContext(pCertContext); 00970 } 00971 else 00972 toAdd = CertDuplicateCertificateContext(pCertContext); 00973 break; 00974 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: 00975 if (existing) 00976 { 00977 if (CompareFileTime(&existing->pCertInfo->NotBefore, 00978 &pCertContext->pCertInfo->NotBefore) >= 0) 00979 { 00980 TRACE("existing certificate is newer, not adding\n"); 00981 SetLastError(CRYPT_E_EXISTS); 00982 ret = FALSE; 00983 } 00984 else 00985 { 00986 toAdd = CertDuplicateCertificateContext(pCertContext); 00987 CertContext_CopyProperties(toAdd, existing); 00988 } 00989 } 00990 else 00991 toAdd = CertDuplicateCertificateContext(pCertContext); 00992 break; 00993 } 00994 00995 if (toAdd) 00996 { 00997 if (store) 00998 ret = store->certs.addContext(store, (void *)toAdd, 00999 (void *)existing, (const void **)ppStoreContext); 01000 else if (ppStoreContext) 01001 *ppStoreContext = CertDuplicateCertificateContext(toAdd); 01002 CertFreeCertificateContext(toAdd); 01003 } 01004 CertFreeCertificateContext(existing); 01005 01006 TRACE("returning %d\n", ret); 01007 return ret; 01008 } 01009 01010 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, 01011 PCCERT_CONTEXT pPrev) 01012 { 01013 WINECRYPT_CERTSTORE *hcs = hCertStore; 01014 PCCERT_CONTEXT ret; 01015 01016 TRACE("(%p, %p)\n", hCertStore, pPrev); 01017 if (!hCertStore) 01018 ret = NULL; 01019 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) 01020 ret = NULL; 01021 else 01022 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev); 01023 return ret; 01024 } 01025 01026 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext) 01027 { 01028 BOOL ret; 01029 01030 TRACE("(%p)\n", pCertContext); 01031 01032 if (!pCertContext) 01033 ret = TRUE; 01034 else if (!pCertContext->hCertStore) 01035 ret = CertFreeCertificateContext(pCertContext); 01036 else 01037 { 01038 PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore; 01039 01040 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) 01041 ret = FALSE; 01042 else 01043 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext); 01044 if (ret) 01045 ret = CertFreeCertificateContext(pCertContext); 01046 } 01047 return ret; 01048 } 01049 01050 #define CrlContext_CopyProperties(to, from) \ 01051 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT)) 01052 01053 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, 01054 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition, 01055 PCCRL_CONTEXT* ppStoreContext) 01056 { 01057 PWINECRYPT_CERTSTORE store = hCertStore; 01058 BOOL ret = TRUE; 01059 PCCRL_CONTEXT toAdd = NULL, existing = NULL; 01060 01061 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext, 01062 dwAddDisposition, ppStoreContext); 01063 01064 /* Weird case to pass a test */ 01065 if (dwAddDisposition == 0) 01066 { 01067 SetLastError(STATUS_ACCESS_VIOLATION); 01068 return FALSE; 01069 } 01070 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) 01071 { 01072 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING, 01073 pCrlContext, NULL); 01074 } 01075 01076 switch (dwAddDisposition) 01077 { 01078 case CERT_STORE_ADD_ALWAYS: 01079 toAdd = CertDuplicateCRLContext(pCrlContext); 01080 break; 01081 case CERT_STORE_ADD_NEW: 01082 if (existing) 01083 { 01084 TRACE("found matching CRL, not adding\n"); 01085 SetLastError(CRYPT_E_EXISTS); 01086 ret = FALSE; 01087 } 01088 else 01089 toAdd = CertDuplicateCRLContext(pCrlContext); 01090 break; 01091 case CERT_STORE_ADD_NEWER: 01092 if (existing) 01093 { 01094 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate, 01095 &pCrlContext->pCrlInfo->ThisUpdate); 01096 01097 if (newer < 0) 01098 toAdd = CertDuplicateCRLContext(pCrlContext); 01099 else 01100 { 01101 TRACE("existing CRL is newer, not adding\n"); 01102 SetLastError(CRYPT_E_EXISTS); 01103 ret = FALSE; 01104 } 01105 } 01106 else 01107 toAdd = CertDuplicateCRLContext(pCrlContext); 01108 break; 01109 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: 01110 if (existing) 01111 { 01112 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate, 01113 &pCrlContext->pCrlInfo->ThisUpdate); 01114 01115 if (newer < 0) 01116 { 01117 toAdd = CertDuplicateCRLContext(pCrlContext); 01118 CrlContext_CopyProperties(toAdd, existing); 01119 } 01120 else 01121 { 01122 TRACE("existing CRL is newer, not adding\n"); 01123 SetLastError(CRYPT_E_EXISTS); 01124 ret = FALSE; 01125 } 01126 } 01127 else 01128 toAdd = CertDuplicateCRLContext(pCrlContext); 01129 break; 01130 case CERT_STORE_ADD_REPLACE_EXISTING: 01131 toAdd = CertDuplicateCRLContext(pCrlContext); 01132 break; 01133 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: 01134 toAdd = CertDuplicateCRLContext(pCrlContext); 01135 if (existing) 01136 CrlContext_CopyProperties(toAdd, existing); 01137 break; 01138 case CERT_STORE_ADD_USE_EXISTING: 01139 if (existing) 01140 { 01141 CrlContext_CopyProperties(existing, pCrlContext); 01142 if (ppStoreContext) 01143 *ppStoreContext = CertDuplicateCRLContext(existing); 01144 } 01145 else 01146 toAdd = CertDuplicateCRLContext(pCrlContext); 01147 break; 01148 default: 01149 FIXME("Unimplemented add disposition %d\n", dwAddDisposition); 01150 ret = FALSE; 01151 } 01152 01153 if (toAdd) 01154 { 01155 if (store) 01156 ret = store->crls.addContext(store, (void *)toAdd, 01157 (void *)existing, (const void **)ppStoreContext); 01158 else if (ppStoreContext) 01159 *ppStoreContext = CertDuplicateCRLContext(toAdd); 01160 CertFreeCRLContext(toAdd); 01161 } 01162 CertFreeCRLContext(existing); 01163 01164 TRACE("returning %d\n", ret); 01165 return ret; 01166 } 01167 01168 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext) 01169 { 01170 BOOL ret; 01171 01172 TRACE("(%p)\n", pCrlContext); 01173 01174 if (!pCrlContext) 01175 ret = TRUE; 01176 else if (!pCrlContext->hCertStore) 01177 ret = CertFreeCRLContext(pCrlContext); 01178 else 01179 { 01180 PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore; 01181 01182 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) 01183 ret = FALSE; 01184 else 01185 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext); 01186 if (ret) 01187 ret = CertFreeCRLContext(pCrlContext); 01188 } 01189 return ret; 01190 } 01191 01192 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, 01193 PCCRL_CONTEXT pPrev) 01194 { 01195 WINECRYPT_CERTSTORE *hcs = hCertStore; 01196 PCCRL_CONTEXT ret; 01197 01198 TRACE("(%p, %p)\n", hCertStore, pPrev); 01199 if (!hCertStore) 01200 ret = NULL; 01201 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) 01202 ret = NULL; 01203 else 01204 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev); 01205 return ret; 01206 } 01207 01208 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore) 01209 { 01210 WINECRYPT_CERTSTORE *hcs = hCertStore; 01211 01212 TRACE("(%p)\n", hCertStore); 01213 01214 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC) 01215 InterlockedIncrement(&hcs->ref); 01216 return hCertStore; 01217 } 01218 01219 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) 01220 { 01221 WINECRYPT_CERTSTORE *hcs = hCertStore; 01222 01223 TRACE("(%p, %08x)\n", hCertStore, dwFlags); 01224 01225 if( ! hCertStore ) 01226 return TRUE; 01227 01228 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC ) 01229 return FALSE; 01230 01231 if (hcs->ref <= 0) 01232 ERR("%p's ref count is %d\n", hcs, hcs->ref); 01233 if (InterlockedDecrement(&hcs->ref) == 0) 01234 { 01235 TRACE("%p's ref count is 0, freeing\n", hcs); 01236 hcs->dwMagic = 0; 01237 hcs->closeStore(hcs, dwFlags); 01238 } 01239 else 01240 TRACE("%p's ref count is %d\n", hcs, hcs->ref); 01241 return TRUE; 01242 } 01243 01244 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, 01245 DWORD dwCtrlType, void const *pvCtrlPara) 01246 { 01247 WINECRYPT_CERTSTORE *hcs = hCertStore; 01248 BOOL ret; 01249 01250 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, 01251 pvCtrlPara); 01252 01253 if (!hcs) 01254 ret = FALSE; 01255 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) 01256 ret = FALSE; 01257 else 01258 { 01259 if (hcs->control) 01260 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara); 01261 else 01262 ret = TRUE; 01263 } 01264 return ret; 01265 } 01266 01267 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, 01268 void *pvData, DWORD *pcbData) 01269 { 01270 PWINECRYPT_CERTSTORE store = hCertStore; 01271 BOOL ret = FALSE; 01272 01273 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData); 01274 01275 switch (dwPropId) 01276 { 01277 case CERT_ACCESS_STATE_PROP_ID: 01278 if (!pvData) 01279 { 01280 *pcbData = sizeof(DWORD); 01281 ret = TRUE; 01282 } 01283 else if (*pcbData < sizeof(DWORD)) 01284 { 01285 SetLastError(ERROR_MORE_DATA); 01286 *pcbData = sizeof(DWORD); 01287 } 01288 else 01289 { 01290 DWORD state = 0; 01291 01292 if (store->type != StoreTypeMem && 01293 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG)) 01294 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG; 01295 *(DWORD *)pvData = state; 01296 ret = TRUE; 01297 } 01298 break; 01299 default: 01300 if (store->properties) 01301 { 01302 CRYPT_DATA_BLOB blob; 01303 01304 ret = ContextPropertyList_FindProperty(store->properties, dwPropId, 01305 &blob); 01306 if (ret) 01307 { 01308 if (!pvData) 01309 *pcbData = blob.cbData; 01310 else if (*pcbData < blob.cbData) 01311 { 01312 SetLastError(ERROR_MORE_DATA); 01313 *pcbData = blob.cbData; 01314 ret = FALSE; 01315 } 01316 else 01317 { 01318 memcpy(pvData, blob.pbData, blob.cbData); 01319 *pcbData = blob.cbData; 01320 } 01321 } 01322 else 01323 SetLastError(CRYPT_E_NOT_FOUND); 01324 } 01325 else 01326 SetLastError(CRYPT_E_NOT_FOUND); 01327 } 01328 return ret; 01329 } 01330 01331 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, 01332 DWORD dwFlags, const void *pvData) 01333 { 01334 PWINECRYPT_CERTSTORE store = hCertStore; 01335 BOOL ret = FALSE; 01336 01337 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData); 01338 01339 if (!store->properties) 01340 store->properties = ContextPropertyList_Create(); 01341 switch (dwPropId) 01342 { 01343 case CERT_ACCESS_STATE_PROP_ID: 01344 SetLastError(E_INVALIDARG); 01345 break; 01346 default: 01347 if (pvData) 01348 { 01349 const CRYPT_DATA_BLOB *blob = pvData; 01350 01351 ret = ContextPropertyList_SetProperty(store->properties, dwPropId, 01352 blob->pbData, blob->cbData); 01353 } 01354 else 01355 { 01356 ContextPropertyList_RemoveProperty(store->properties, dwPropId); 01357 ret = TRUE; 01358 } 01359 } 01360 return ret; 01361 } 01362 01363 static LONG CRYPT_OpenParentStore(DWORD dwFlags, 01364 void *pvSystemStoreLocationPara, HKEY *key) 01365 { 01366 HKEY root; 01367 LPCWSTR base; 01368 01369 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara); 01370 01371 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) 01372 { 01373 case CERT_SYSTEM_STORE_LOCAL_MACHINE: 01374 root = HKEY_LOCAL_MACHINE; 01375 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; 01376 break; 01377 case CERT_SYSTEM_STORE_CURRENT_USER: 01378 root = HKEY_CURRENT_USER; 01379 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; 01380 break; 01381 case CERT_SYSTEM_STORE_CURRENT_SERVICE: 01382 /* hklm\Software\Microsoft\Cryptography\Services\servicename\ 01383 * SystemCertificates 01384 */ 01385 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n"); 01386 return ERROR_FILE_NOT_FOUND; 01387 case CERT_SYSTEM_STORE_SERVICES: 01388 /* hklm\Software\Microsoft\Cryptography\Services\servicename\ 01389 * SystemCertificates 01390 */ 01391 FIXME("CERT_SYSTEM_STORE_SERVICES\n"); 01392 return ERROR_FILE_NOT_FOUND; 01393 case CERT_SYSTEM_STORE_USERS: 01394 /* hku\user sid\Software\Microsoft\SystemCertificates */ 01395 FIXME("CERT_SYSTEM_STORE_USERS\n"); 01396 return ERROR_FILE_NOT_FOUND; 01397 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY: 01398 root = HKEY_CURRENT_USER; 01399 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; 01400 break; 01401 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY: 01402 root = HKEY_LOCAL_MACHINE; 01403 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; 01404 break; 01405 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE: 01406 /* hklm\Software\Microsoft\EnterpriseCertificates */ 01407 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n"); 01408 return ERROR_FILE_NOT_FOUND; 01409 default: 01410 return ERROR_FILE_NOT_FOUND; 01411 } 01412 01413 return RegOpenKeyExW(root, base, 0, KEY_READ, key); 01414 } 01415 01416 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, 01417 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum) 01418 { 01419 BOOL ret = FALSE; 01420 LONG rc; 01421 HKEY key; 01422 CERT_SYSTEM_STORE_INFO info = { sizeof(info) }; 01423 01424 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg, 01425 pfnEnum); 01426 01427 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key); 01428 if (!rc) 01429 { 01430 DWORD index = 0; 01431 01432 ret = TRUE; 01433 do { 01434 WCHAR name[MAX_PATH]; 01435 DWORD size = sizeof(name) / sizeof(name[0]); 01436 01437 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL, 01438 NULL); 01439 if (!rc) 01440 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg); 01441 } while (ret && !rc); 01442 if (ret && rc != ERROR_NO_MORE_ITEMS) 01443 SetLastError(rc); 01444 } 01445 else 01446 SetLastError(rc); 01447 /* Include root store for the local machine location (it isn't in the 01448 * registry) 01449 */ 01450 if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == 01451 CERT_SYSTEM_STORE_LOCAL_MACHINE) 01452 ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg); 01453 return ret; 01454 } 01455 01456 BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags, 01457 void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum) 01458 { 01459 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) 01460 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg, 01461 pfnEnum); 01462 else 01463 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore), 01464 dwFlags, pvArg, 01465 pfnEnum); 01466 return FALSE; 01467 } 01468 01469 BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, 01470 LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved) 01471 { 01472 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) 01473 FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags, 01474 debugstr_w(pwszStoreName), pStoreInfo, pvReserved); 01475 else 01476 FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore), 01477 dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved); 01478 return FALSE; 01479 } Generated on Sun May 27 2012 04:23:19 for ReactOS by
1.7.6.1
|