ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

filestore.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2004-2007 Juan Lang
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 #include <stdarg.h>
00019 #include "windef.h"
00020 #include "winbase.h"
00021 #include "wincrypt.h"
00022 #include "winnls.h"
00023 #include "wine/debug.h"
00024 #include "wine/unicode.h"
00025 #include "crypt32_private.h"
00026 
00027 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
00028 
00029 typedef struct _WINE_FILESTOREINFO
00030 {
00031     DWORD      dwOpenFlags;
00032     HCERTSTORE memStore;
00033     HANDLE     file;
00034     DWORD      type;
00035     BOOL       dirty;
00036 } WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
00037 
00038 static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
00039 {
00040     PWINE_FILESTOREINFO store = hCertStore;
00041 
00042     TRACE("(%p, %08x)\n", store, dwFlags);
00043     if (store->dirty)
00044         CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
00045          store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
00046     CloseHandle(store->file);
00047     CryptMemFree(store);
00048 }
00049 
00050 static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
00051  PCCERT_CONTEXT cert, DWORD dwFlags)
00052 {
00053     PWINE_FILESTOREINFO store = hCertStore;
00054 
00055     TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
00056     store->dirty = TRUE;
00057     return TRUE;
00058 }
00059 
00060 static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
00061  PCCERT_CONTEXT pCertContext, DWORD dwFlags)
00062 {
00063     PWINE_FILESTOREINFO store = hCertStore;
00064 
00065     TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
00066     store->dirty = TRUE;
00067     return TRUE;
00068 }
00069 
00070 static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
00071  PCCRL_CONTEXT crl, DWORD dwFlags)
00072 {
00073     PWINE_FILESTOREINFO store = hCertStore;
00074 
00075     TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
00076     store->dirty = TRUE;
00077     return TRUE;
00078 }
00079 
00080 static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
00081  PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
00082 {
00083     PWINE_FILESTOREINFO store = hCertStore;
00084 
00085     TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
00086     store->dirty = TRUE;
00087     return TRUE;
00088 }
00089 
00090 static BOOL WINAPI CRYPT_FileWriteCTL(HCERTSTORE hCertStore,
00091  PCCTL_CONTEXT ctl, DWORD dwFlags)
00092 {
00093     PWINE_FILESTOREINFO store = hCertStore;
00094 
00095     TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags);
00096     store->dirty = TRUE;
00097     return TRUE;
00098 }
00099 
00100 static BOOL WINAPI CRYPT_FileDeleteCTL(HCERTSTORE hCertStore,
00101  PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
00102 {
00103     PWINE_FILESTOREINFO store = hCertStore;
00104 
00105     TRACE("(%p, %p, %08x)\n", hCertStore, pCtlContext, dwFlags);
00106     store->dirty = TRUE;
00107     return TRUE;
00108 }
00109 
00110 static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
00111 {
00112     BOOL ret = TRUE;
00113 
00114     blob->cbData = GetFileSize(file, NULL);
00115     if (blob->cbData)
00116     {
00117         blob->pbData = CryptMemAlloc(blob->cbData);
00118         if (blob->pbData)
00119         {
00120             DWORD read;
00121 
00122             ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
00123         }
00124     }
00125     return ret;
00126 }
00127 
00128 static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
00129  DWORD dwCtrlType, void const *pvCtrlPara)
00130 {
00131     PWINE_FILESTOREINFO store = hCertStore;
00132     BOOL ret;
00133 
00134     TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
00135      pvCtrlPara);
00136 
00137     switch (dwCtrlType)
00138     {
00139     case CERT_STORE_CTRL_RESYNC:
00140         store->dirty = FALSE;
00141         if (store->type == CERT_STORE_SAVE_AS_STORE)
00142         {
00143             HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
00144              CERT_STORE_CREATE_NEW_FLAG, NULL);
00145 
00146             /* FIXME: if I could translate a handle to a path, I could use
00147              * CryptQueryObject instead, but there's no API to do so yet.
00148              */
00149             ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore);
00150             if (ret)
00151                 I_CertUpdateStore(store->memStore, memStore, 0, 0);
00152             CertCloseStore(memStore, 0);
00153         }
00154         else if (store->type == CERT_STORE_SAVE_AS_PKCS7)
00155         {
00156             CERT_BLOB blob = { 0, NULL };
00157 
00158             ret = CRYPT_ReadBlobFromFile(store->file, &blob);
00159             if (ret)
00160             {
00161                 HCERTSTORE messageStore;
00162 
00163                 ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
00164                  CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
00165                  CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
00166                  &messageStore, NULL, NULL);
00167                 I_CertUpdateStore(store->memStore, messageStore, 0, 0);
00168                 CertCloseStore(messageStore, 0);
00169                 CryptMemFree(blob.pbData);
00170             }
00171         }
00172         else
00173         {
00174             WARN("unknown type %d\n", store->type);
00175             ret = FALSE;
00176         }
00177         break;
00178     case CERT_STORE_CTRL_COMMIT:
00179         if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
00180         {
00181             SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00182             ret = FALSE;
00183         }
00184         else if (store->dirty)
00185             ret = CertSaveStore(store->memStore,
00186              X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
00187              store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
00188         else
00189             ret = TRUE;
00190         break;
00191     default:
00192         FIXME("%d: stub\n", dwCtrlType);
00193         ret = FALSE;
00194     }
00195     return ret;
00196 }
00197 
00198 static void *fileProvFuncs[] = {
00199     CRYPT_FileCloseStore,
00200     NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
00201     CRYPT_FileWriteCert,
00202     CRYPT_FileDeleteCert,
00203     NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
00204     NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
00205     CRYPT_FileWriteCRL,
00206     CRYPT_FileDeleteCRL,
00207     NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
00208     NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
00209     CRYPT_FileWriteCTL,
00210     CRYPT_FileDeleteCTL,
00211     NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
00212     CRYPT_FileControl,
00213 };
00214 
00215 static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
00216  HCERTSTORE memStore, HANDLE file, DWORD type)
00217 {
00218     PWINECRYPT_CERTSTORE store = NULL;
00219     PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
00220 
00221     if (info)
00222     {
00223         CERT_STORE_PROV_INFO provInfo = { 0 };
00224 
00225         info->dwOpenFlags = dwFlags;
00226         info->memStore = memStore;
00227         info->file = file;
00228         info->type = type;
00229         info->dirty = FALSE;
00230         provInfo.cbSize = sizeof(provInfo);
00231         provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
00232          sizeof(fileProvFuncs[0]);
00233         provInfo.rgpvStoreProvFunc = fileProvFuncs;
00234         provInfo.hStoreProv = info;
00235         store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
00236     }
00237     return store;
00238 }
00239 
00240 PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
00241  const void *pvPara)
00242 {
00243     PWINECRYPT_CERTSTORE store = NULL;
00244     HANDLE file = (HANDLE)pvPara;
00245 
00246     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
00247 
00248     if (!pvPara)
00249     {
00250         SetLastError(ERROR_INVALID_HANDLE);
00251         return NULL;
00252     }
00253     if (dwFlags & CERT_STORE_DELETE_FLAG)
00254     {
00255         SetLastError(E_INVALIDARG);
00256         return NULL;
00257     }
00258     if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
00259      (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
00260     {
00261         SetLastError(E_INVALIDARG);
00262         return NULL;
00263     }
00264 
00265     if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
00266      GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
00267      GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
00268     {
00269         HCERTSTORE memStore;
00270 
00271         memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
00272          CERT_STORE_CREATE_NEW_FLAG, NULL);
00273         if (memStore)
00274         {
00275             if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
00276             {
00277                 store = CRYPT_CreateFileStore(dwFlags, memStore, file,
00278                  CERT_STORE_SAVE_AS_STORE);
00279                 /* File store doesn't need crypto provider, so close it */
00280                 if (hCryptProv &&
00281                  !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
00282                     CryptReleaseContext(hCryptProv, 0);
00283             }
00284         }
00285     }
00286     TRACE("returning %p\n", store);
00287     return store;
00288 }
00289 
00290 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
00291  DWORD dwFlags, const void *pvPara)
00292 {
00293     HCERTSTORE store = 0;
00294     LPCWSTR fileName = pvPara;
00295     DWORD access, create;
00296     HANDLE file;
00297 
00298     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
00299 
00300     if (!fileName)
00301     {
00302         SetLastError(ERROR_PATH_NOT_FOUND);
00303         return NULL;
00304     }
00305     if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
00306      (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
00307     {
00308         SetLastError(E_INVALIDARG);
00309         return NULL;
00310     }
00311 
00312     access = GENERIC_READ;
00313     if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
00314         access |= GENERIC_WRITE;
00315     if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
00316         create = CREATE_NEW;
00317     else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
00318         create = OPEN_EXISTING;
00319     else
00320         create = OPEN_ALWAYS;
00321     file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
00322      FILE_ATTRIBUTE_NORMAL, NULL);
00323     if (file != INVALID_HANDLE_VALUE)
00324     {
00325         HCERTSTORE memStore = NULL;
00326         DWORD size = GetFileSize(file, NULL), type = 0;
00327 
00328         /* If the file isn't empty, try to get the type from the file itself */
00329         if (size)
00330         {
00331             DWORD contentType;
00332             BOOL ret;
00333 
00334             /* Close the file so CryptQueryObject can succeed.. */
00335             CloseHandle(file);
00336             ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
00337              CERT_QUERY_CONTENT_FLAG_CERT |
00338              CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
00339              CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
00340              CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &contentType, NULL,
00341              &memStore, NULL, NULL);
00342             if (ret)
00343             {
00344                 if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
00345                     type = CERT_STORE_SAVE_AS_PKCS7;
00346                 else
00347                     type = CERT_STORE_SAVE_AS_STORE;
00348                 /* and reopen the file. */
00349                 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
00350                  create, FILE_ATTRIBUTE_NORMAL, NULL);
00351             }
00352         }
00353         else
00354         {
00355             static const WCHAR spc[] = { 's','p','c',0 };
00356             static const WCHAR p7c[] = { 'p','7','c',0 };
00357             LPCWSTR ext = strrchrW(fileName, '.');
00358 
00359             if (ext)
00360             {
00361                 ext++;
00362                 if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
00363                     type = CERT_STORE_SAVE_AS_PKCS7;
00364             }
00365             if (!type)
00366                 type = CERT_STORE_SAVE_AS_STORE;
00367             memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
00368              CERT_STORE_CREATE_NEW_FLAG, NULL);
00369         }
00370         if (memStore)
00371         {
00372             store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
00373             /* File store doesn't need crypto provider, so close it */
00374             if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
00375                 CryptReleaseContext(hCryptProv, 0);
00376         }
00377     }
00378     return store;
00379 }
00380 
00381 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
00382  DWORD dwFlags, const void *pvPara)
00383 {
00384     int len;
00385     PWINECRYPT_CERTSTORE ret = NULL;
00386 
00387     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
00388      debugstr_a(pvPara));
00389 
00390     if (!pvPara)
00391     {
00392         SetLastError(ERROR_FILE_NOT_FOUND);
00393         return NULL;
00394     }
00395     len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
00396     if (len)
00397     {
00398         LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
00399 
00400         if (storeName)
00401         {
00402             MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
00403             ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
00404             CryptMemFree(storeName);
00405         }
00406     }
00407     return ret;
00408 }

Generated on Sun May 27 2012 04:23:14 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.