store.c
来自「一个类似windows」· C语言 代码 · 共 1,949 行 · 第 1/5 页
C
1,949 行
static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
BOOL ret = TRUE;
TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
if (store->provControl)
ret = store->provControl(store->hStoreProv, dwFlags, dwCtrlType,
pvCtrlPara);
return ret;
}
static PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, PWINECRYPT_CERTSTORE memStore, PCERT_STORE_PROV_INFO pProvInfo)
{
PWINE_PROVIDERSTORE ret = (PWINE_PROVIDERSTORE)CryptMemAlloc(
sizeof(WINE_PROVIDERSTORE));
if (ret)
{
CRYPT_InitStore(&ret->hdr, hCryptProv, dwFlags,
StoreTypeProvider);
ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
{
CertCloseStore(memStore, 0);
ret->memStore = NULL;
}
else
ret->memStore = memStore;
ret->hStoreProv = pProvInfo->hStoreProv;
ret->hdr.closeStore = CRYPT_ProvCloseStore;
ret->hdr.addCert = CRYPT_ProvAddCert;
ret->hdr.enumCert = CRYPT_ProvEnumCert;
ret->hdr.deleteCert = CRYPT_ProvDeleteCert;
ret->hdr.control = CRYPT_ProvControl;
if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
ret->provCloseStore =
pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
else
ret->provCloseStore = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_WRITE_CERT_FUNC)
ret->provWriteCert = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_WRITE_CERT_FUNC];
else
ret->provWriteCert = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_DELETE_CERT_FUNC)
ret->provDeleteCert = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_DELETE_CERT_FUNC];
else
ret->provDeleteCert = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_CONTROL_FUNC)
ret->provControl = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_CONTROL_FUNC];
else
ret->provControl = NULL;
}
return (PWINECRYPT_CERTSTORE)ret;
}
static PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
{
static HCRYPTOIDFUNCSET set = NULL;
PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
HCRYPTOIDFUNCADDR hFunc;
PWINECRYPT_CERTSTORE ret = NULL;
if (!set)
set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
CryptGetOIDFunctionAddress(set, dwEncodingType, lpszStoreProvider, 0,
(void **)&provOpenFunc, &hFunc);
if (provOpenFunc)
{
CERT_STORE_PROV_INFO provInfo = { 0 };
provInfo.cbSize = sizeof(provInfo);
if (dwFlags & CERT_STORE_DELETE_FLAG)
provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
dwFlags, pvPara, NULL, &provInfo);
else
{
PWINECRYPT_CERTSTORE memStore;
memStore = CRYPT_MemOpenStore(hCryptProv, dwFlags, NULL);
if (memStore)
{
if (provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
dwFlags, pvPara, memStore, &provInfo))
ret = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore,
&provInfo);
else
CertCloseStore(memStore, 0);
}
}
CryptFreeOIDFunctionAddress(hFunc, 0);
}
else
SetLastError(ERROR_FILE_NOT_FOUND);
return ret;
}
static void CRYPT_HashToStr(LPBYTE hash, LPWSTR asciiHash)
{
static const WCHAR fmt[] = { '%','0','2','X',0 };
DWORD i;
assert(hash);
assert(asciiHash);
for (i = 0; i < 20; i++)
wsprintfW(asciiHash + i * 2, fmt, hash[i]);
}
static const WCHAR CertsW[] = { 'C','e','r','t','i','f','i','c','a','t','e','s',
0 };
static const WCHAR CRLsW[] = { 'C','R','L','s',0 };
static const WCHAR CTLsW[] = { 'C','T','L','s',0 };
static const WCHAR BlobW[] = { 'B','l','o','b',0 };
static void CRYPT_RegReadSerializedFromReg(PWINE_REGSTOREINFO store, HKEY key,
DWORD contextType)
{
LONG rc;
DWORD index = 0;
WCHAR subKeyName[MAX_PATH];
do {
DWORD size = sizeof(subKeyName) / sizeof(WCHAR);
rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL,
NULL);
if (!rc)
{
HKEY subKey;
rc = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
if (!rc)
{
LPBYTE buf = NULL;
size = 0;
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, NULL, &size);
if (!rc)
buf = CryptMemAlloc(size);
if (buf)
{
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, buf,
&size);
if (!rc)
{
const void *context;
DWORD addedType;
TRACE("Adding cert with hash %s\n",
debugstr_w(subKeyName));
context = CRYPT_ReadSerializedElement(buf, size,
contextType, &addedType);
if (context)
{
const WINE_CONTEXT_INTERFACE *contextInterface;
BYTE hash[20];
switch (addedType)
{
case CERT_STORE_CERTIFICATE_CONTEXT:
contextInterface = &gCertInterface;
break;
case CERT_STORE_CRL_CONTEXT:
contextInterface = &gCRLInterface;
break;
case CERT_STORE_CTL_CONTEXT:
contextInterface = &gCTLInterface;
break;
default:
contextInterface = NULL;
}
if (contextInterface)
{
size = sizeof(hash);
if (contextInterface->getProp(context,
CERT_HASH_PROP_ID, hash, &size))
{
WCHAR asciiHash[20 * 2 + 1];
CRYPT_HashToStr(hash, asciiHash);
TRACE("comparing %s\n",
debugstr_w(asciiHash));
TRACE("with %s\n", debugstr_w(subKeyName));
if (!lstrcmpW(asciiHash, subKeyName))
{
TRACE("hash matches, adding\n");
contextInterface->addContextToStore(
store->memStore, context,
CERT_STORE_ADD_REPLACE_EXISTING, NULL);
}
else
TRACE("hash doesn't match, ignoring\n");
}
contextInterface->free(context);
}
}
}
CryptMemFree(buf);
}
RegCloseKey(subKey);
}
/* Ignore intermediate errors, continue enumerating */
rc = ERROR_SUCCESS;
}
} while (!rc);
}
static void CRYPT_RegReadFromReg(PWINE_REGSTOREINFO store)
{
static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW };
static const DWORD contextFlags[] = { CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG };
DWORD i;
for (i = 0; i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
{
HKEY key;
LONG rc;
rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0, KEY_READ, NULL,
&key, NULL);
if (!rc)
{
CRYPT_RegReadSerializedFromReg(store, key, contextFlags[i]);
RegCloseKey(key);
}
}
}
/* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */
static BOOL CRYPT_WriteSerializedToReg(HKEY key, LPBYTE hash, LPBYTE buf,
DWORD len)
{
WCHAR asciiHash[20 * 2 + 1];
LONG rc;
HKEY subKey;
BOOL ret;
CRYPT_HashToStr(hash, asciiHash);
rc = RegCreateKeyExW(key, asciiHash, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
&subKey, NULL);
if (!rc)
{
rc = RegSetValueExW(subKey, BlobW, 0, REG_BINARY, buf, len);
RegCloseKey(subKey);
}
if (!rc)
ret = TRUE;
else
{
SetLastError(rc);
ret = FALSE;
}
return ret;
}
static BOOL CRYPT_SerializeContextsToReg(HKEY key,
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE memStore)
{
const void *context = NULL;
BOOL ret;
do {
context = contextInterface->enumContextsInStore(memStore, context);
if (context)
{
BYTE hash[20];
DWORD hashSize = sizeof(hash);
ret = contextInterface->getProp(context, CERT_HASH_PROP_ID, hash,
&hashSize);
if (ret)
{
DWORD size = 0;
LPBYTE buf = NULL;
ret = contextInterface->serialize(context, 0, NULL, &size);
if (size)
buf = CryptMemAlloc(size);
if (buf)
{
ret = contextInterface->serialize(context, 0, buf, &size);
if (ret)
ret = CRYPT_WriteSerializedToReg(key, hash, buf, size);
}
CryptMemFree(buf);
}
}
else
ret = TRUE;
} while (ret && context != NULL);
if (context)
contextInterface->free(context);
return ret;
}
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
{
static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW };
static const WINE_CONTEXT_INTERFACE *interfaces[] = { &gCertInterface,
&gCRLInterface, &gCTLInterface };
struct list *listToDelete[] = { &store->certsToDelete, NULL, NULL };
BOOL ret = TRUE;
DWORD i;
for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
{
HKEY key;
LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0,
KEY_ALL_ACCESS, NULL, &key, NULL);
if (!rc)
{
if (listToDelete[i])
{
PWINE_HASH_TO_DELETE toDelete, next;
WCHAR asciiHash[20 * 2 + 1];
EnterCriticalSection(&store->cs);
LIST_FOR_EACH_ENTRY_SAFE(toDelete, next, listToDelete[i],
WINE_HASH_TO_DELETE, entry)
{
LONG rc;
CRYPT_HashToStr(toDelete->hash, asciiHash);
TRACE("Removing %s\n", debugstr_w(asciiHash));
rc = RegDeleteKeyW(key, asciiHash);
if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
{
SetLastError(rc);
ret = FALSE;
}
list_remove(&toDelete->entry);
CryptMemFree(toDelete);
}
LeaveCriticalSection(&store->cs);
}
ret = CRYPT_SerializeContextsToReg(key, interfaces[i],
store->memStore);
RegCloseKey(key);
}
else
{
SetLastError(rc);
ret = FALSE;
}
}
return ret;
}
/* If force is true or the registry store is dirty, writes the contents of the
* store to the registry.
*/
static BOOL CRYPT_RegFlushStore(PWINE_REGSTOREINFO store, BOOL force)
{
BOOL ret;
TRACE("(%p, %d)\n", store, force);
if (store->dirty || force)
ret = CRYPT_RegWriteToReg(store);
else
ret = TRUE;
return ret;
}
static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %08lx)\n", store, dwFlags);
if (dwFlags)
FIXME("Unimplemented flags: %08lx\n", dwFlags);
CRYPT_RegFlushStore(store, FALSE);
RegCloseKey(store->key);
DeleteCriticalSection(&store->cs);
CryptMemFree(store);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?