From 71dffcee843fc26f98ed36ed8e38ae2aba2cb1f6 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Thu, 16 Aug 2007 10:54:52 -0700 Subject: [PATCH] crypt32: Move file store to a separate file. --- dlls/crypt32/Makefile.in | 1 + dlls/crypt32/crypt32_private.h | 6 + dlls/crypt32/filestore.c | 270 +++++++++++++++++++++++++++++++++ dlls/crypt32/store.c | 244 ----------------------------- 4 files changed, 277 insertions(+), 244 deletions(-) create mode 100644 dlls/crypt32/filestore.c diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in index f7b62f818a0..84f21dc324d 100644 --- a/dlls/crypt32/Makefile.in +++ b/dlls/crypt32/Makefile.in @@ -16,6 +16,7 @@ C_SRCS = \ crl.c \ decode.c \ encode.c \ + filestore.c \ main.c \ msg.c \ oid.c \ diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index 57846c7b8a4..d2a70a73156 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -246,6 +246,12 @@ PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider, const void *pvPara); PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara); +PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, + const void *pvPara); +PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, + DWORD dwFlags, const void *pvPara); +PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, + DWORD dwFlags, const void *pvPara); /* Helper function for store reading functions and * CertAddSerializedElementToStore. Returns a context of the appropriate type diff --git a/dlls/crypt32/filestore.c b/dlls/crypt32/filestore.c new file mode 100644 index 00000000000..07ab6f11ad3 --- /dev/null +++ b/dlls/crypt32/filestore.c @@ -0,0 +1,270 @@ +/* + * Copyright 2004-2007 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winnls.h" +#include "wine/debug.h" +#include "crypt32_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +typedef struct _WINE_FILESTOREINFO +{ + DWORD dwOpenFlags; + HCRYPTPROV cryptProv; + HCERTSTORE memStore; + HANDLE file; + BOOL dirty; +} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO; + +static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %08x)\n", store, dwFlags); + if (store->dirty) + CRYPT_WriteSerializedFile(store->file, store->memStore); + CertCloseStore(store->memStore, dwFlags); + CloseHandle(store->file); + CryptMemFree(store); +} + +static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore, + PCCERT_CONTEXT cert, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore, + PCCERT_CONTEXT pCertContext, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore, + PCCRL_CONTEXT crl, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore, + PCCRL_CONTEXT pCrlContext, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, + DWORD dwCtrlType, void const *pvCtrlPara) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + BOOL ret; + + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + pvCtrlPara); + + switch (dwCtrlType) + { + case CERT_STORE_CTRL_RESYNC: + CRYPT_EmptyStore(store->memStore); + CRYPT_ReadSerializedFile(store->file, store); + ret = TRUE; + break; + case CERT_STORE_CTRL_COMMIT: + if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + ret = FALSE; + } + else if (store->dirty) + ret = CRYPT_WriteSerializedFile(store->file, store->memStore); + else + ret = TRUE; + break; + default: + FIXME("%d: stub\n", dwCtrlType); + ret = FALSE; + } + return ret; +} + +static void *fileProvFuncs[] = { + CRYPT_FileCloseStore, + NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */ + CRYPT_FileWriteCert, + CRYPT_FileDeleteCert, + NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */ + NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */ + CRYPT_FileWriteCRL, + CRYPT_FileDeleteCRL, + NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */ + NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */ + CRYPT_FileControl, +}; + +PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, + const void *pvPara) +{ + PWINECRYPT_CERTSTORE store = NULL; + HANDLE file = (HANDLE)pvPara; + + TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + + if (!pvPara) + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + if (dwFlags & CERT_STORE_DELETE_FLAG) + { + SetLastError(E_INVALIDARG); + return NULL; + } + if ((dwFlags & CERT_STORE_READONLY_FLAG) && + (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) + { + SetLastError(E_INVALIDARG); + return NULL; + } + + if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara, + GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ? + GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0)) + { + PWINECRYPT_CERTSTORE memStore; + + memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, hCryptProv, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (memStore) + { + if (CRYPT_ReadSerializedFile(file, memStore)) + { + PWINE_FILESTOREINFO info = CryptMemAlloc( + sizeof(WINE_FILESTOREINFO)); + + if (info) + { + CERT_STORE_PROV_INFO provInfo = { 0 }; + + info->dwOpenFlags = dwFlags; + info->cryptProv = hCryptProv; + info->memStore = memStore; + info->file = file; + info->dirty = FALSE; + provInfo.cbSize = sizeof(provInfo); + provInfo.cStoreProvFunc = sizeof(fileProvFuncs) / + sizeof(fileProvFuncs[0]); + provInfo.rgpvStoreProvFunc = fileProvFuncs; + provInfo.hStoreProv = info; + store = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore, + &provInfo); + } + } + } + } + TRACE("returning %p\n", store); + return store; +} + +PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, + DWORD dwFlags, const void *pvPara) +{ + HCERTSTORE store = 0; + LPCWSTR fileName = (LPCWSTR)pvPara; + DWORD access, create; + HANDLE file; + + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); + + if (!fileName) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return NULL; + } + + access = GENERIC_READ; + if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG) + access |= GENERIC_WRITE; + if (dwFlags & CERT_STORE_CREATE_NEW_FLAG) + create = CREATE_NEW; + else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) + create = OPEN_EXISTING; + else + create = OPEN_ALWAYS; + file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, + FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) + { + /* FIXME: need to check whether it's a serialized store; if not, fall + * back to a PKCS#7 signed message, then to a single serialized cert. + */ + store = CertOpenStore(CERT_STORE_PROV_FILE, 0, hCryptProv, dwFlags, + file); + CloseHandle(file); + } + return (PWINECRYPT_CERTSTORE)store; +} + +PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, + DWORD dwFlags, const void *pvPara) +{ + int len; + PWINECRYPT_CERTSTORE ret = NULL; + + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + debugstr_a((LPCSTR)pvPara)); + + if (!pvPara) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return NULL; + } + len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0); + if (len) + { + LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR)); + + if (storeName) + { + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len); + ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName); + CryptMemFree(storeName); + } + } + return ret; +} diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index c2ba2da4073..43e724fb3b3 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -93,15 +93,6 @@ typedef struct _WINE_MEMSTORE struct ContextList *crls; } WINE_MEMSTORE, *PWINE_MEMSTORE; -typedef struct _WINE_FILESTOREINFO -{ - DWORD dwOpenFlags; - HCRYPTPROV cryptProv; - HCERTSTORE memStore; - HANDLE file; - BOOL dirty; -} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO; - typedef struct _WINE_MSGSTOREINFO { DWORD dwOpenFlags; @@ -518,241 +509,6 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, return ret; } -static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - - TRACE("(%p, %08x)\n", store, dwFlags); - if (store->dirty) - CRYPT_WriteSerializedFile(store->file, store->memStore); - CertCloseStore(store->memStore, dwFlags); - CloseHandle(store->file); - CryptMemFree(store); -} - -static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT cert, DWORD dwFlags) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - - TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); - store->dirty = TRUE; - return TRUE; -} - -static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwFlags) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - - TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags); - store->dirty = TRUE; - return TRUE; -} - -static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT crl, DWORD dwFlags) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - - TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); - store->dirty = TRUE; - return TRUE; -} - -static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT pCrlContext, DWORD dwFlags) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - - TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags); - store->dirty = TRUE; - return TRUE; -} - -static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, - DWORD dwCtrlType, void const *pvCtrlPara) -{ - PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; - BOOL ret; - - TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, - pvCtrlPara); - - switch (dwCtrlType) - { - case CERT_STORE_CTRL_RESYNC: - CRYPT_EmptyStore(store->memStore); - CRYPT_ReadSerializedFile(store->file, store); - ret = TRUE; - break; - case CERT_STORE_CTRL_COMMIT: - if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) - { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - ret = FALSE; - } - else if (store->dirty) - ret = CRYPT_WriteSerializedFile(store->file, store->memStore); - else - ret = TRUE; - break; - default: - FIXME("%d: stub\n", dwCtrlType); - ret = FALSE; - } - return ret; -} - -static void *fileProvFuncs[] = { - CRYPT_FileCloseStore, - NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */ - CRYPT_FileWriteCert, - CRYPT_FileDeleteCert, - NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */ - CRYPT_FileWriteCRL, - CRYPT_FileDeleteCRL, - NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */ - CRYPT_FileControl, -}; - -static PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) -{ - PWINECRYPT_CERTSTORE store = NULL; - HANDLE file = (HANDLE)pvPara; - - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); - - if (!pvPara) - { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - if (dwFlags & CERT_STORE_DELETE_FLAG) - { - SetLastError(E_INVALIDARG); - return NULL; - } - if ((dwFlags & CERT_STORE_READONLY_FLAG) && - (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) - { - SetLastError(E_INVALIDARG); - return NULL; - } - - if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara, - GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ? - GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0)) - { - PWINECRYPT_CERTSTORE memStore; - - memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, hCryptProv, - CERT_STORE_CREATE_NEW_FLAG, NULL); - if (memStore) - { - if (CRYPT_ReadSerializedFile(file, memStore)) - { - PWINE_FILESTOREINFO info = CryptMemAlloc( - sizeof(WINE_FILESTOREINFO)); - - if (info) - { - CERT_STORE_PROV_INFO provInfo = { 0 }; - - info->dwOpenFlags = dwFlags; - info->cryptProv = hCryptProv; - info->memStore = memStore; - info->file = file; - info->dirty = FALSE; - provInfo.cbSize = sizeof(provInfo); - provInfo.cStoreProvFunc = sizeof(fileProvFuncs) / - sizeof(fileProvFuncs[0]); - provInfo.rgpvStoreProvFunc = fileProvFuncs; - provInfo.hStoreProv = info; - store = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore, - &provInfo); - } - } - } - } - TRACE("returning %p\n", store); - return store; -} - -static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) -{ - HCERTSTORE store = 0; - LPCWSTR fileName = (LPCWSTR)pvPara; - DWORD access, create; - HANDLE file; - - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); - - if (!fileName) - { - SetLastError(ERROR_PATH_NOT_FOUND); - return NULL; - } - - access = GENERIC_READ; - if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG) - access |= GENERIC_WRITE; - if (dwFlags & CERT_STORE_CREATE_NEW_FLAG) - create = CREATE_NEW; - else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) - create = OPEN_EXISTING; - else - create = OPEN_ALWAYS; - file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, - FILE_ATTRIBUTE_NORMAL, NULL); - if (file != INVALID_HANDLE_VALUE) - { - /* FIXME: need to check whether it's a serialized store; if not, fall - * back to a PKCS#7 signed message, then to a single serialized cert. - */ - store = CertOpenStore(CERT_STORE_PROV_FILE, 0, hCryptProv, dwFlags, - file); - CloseHandle(file); - } - return (PWINECRYPT_CERTSTORE)store; -} - -static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) -{ - int len; - PWINECRYPT_CERTSTORE ret = NULL; - - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, - debugstr_a((LPCSTR)pvPara)); - - if (!pvPara) - { - SetLastError(ERROR_FILE_NOT_FOUND); - return NULL; - } - len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0); - if (len) - { - LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR)); - - if (storeName) - { - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len); - ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName); - CryptMemFree(storeName); - } - } - return ret; -} - static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { PWINE_MSGSTOREINFO store = (PWINE_MSGSTOREINFO)hCertStore;