Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfilestore.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
1.7.6.1
|