Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencrypt.c
Go to the documentation of this file.
00001 /* 00002 * WinTrust Cryptography functions 00003 * 00004 * Copyright 2006 James Hawkins 00005 * Copyright 2000-2002 Stuart Caie 00006 * Copyright 2002 Patrik Stridvall 00007 * Copyright 2003 Greg Turner 00008 * Copyright 2008 Juan Lang 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00023 */ 00024 00025 #include <stdarg.h> 00026 #include <stdio.h> 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "wintrust.h" 00030 #include "mscat.h" 00031 #include "mssip.h" 00032 #include "imagehlp.h" 00033 #include "winternl.h" 00034 00035 #include "wine/debug.h" 00036 #include "wine/unicode.h" 00037 00038 WINE_DEFAULT_DEBUG_CHANNEL(wintrust); 00039 00040 #define CATADMIN_MAGIC 0x43415441 /* 'CATA' */ 00041 #define CRYPTCAT_MAGIC 0x43415443 /* 'CATC' */ 00042 #define CATINFO_MAGIC 0x43415449 /* 'CATI' */ 00043 00044 struct cryptcat 00045 { 00046 DWORD magic; 00047 HCRYPTMSG msg; 00048 DWORD encoding; 00049 CTL_INFO *inner; 00050 DWORD inner_len; 00051 GUID subject; 00052 DWORD attr_count; 00053 CRYPTCATATTRIBUTE *attr; 00054 }; 00055 00056 struct catadmin 00057 { 00058 DWORD magic; 00059 WCHAR path[MAX_PATH]; 00060 HANDLE find; 00061 }; 00062 00063 struct catinfo 00064 { 00065 DWORD magic; 00066 WCHAR file[MAX_PATH]; 00067 }; 00068 00069 static HCATINFO create_catinfo(const WCHAR *filename) 00070 { 00071 struct catinfo *ci; 00072 00073 if (!(ci = HeapAlloc(GetProcessHeap(), 0, sizeof(*ci)))) 00074 { 00075 SetLastError(ERROR_OUTOFMEMORY); 00076 return INVALID_HANDLE_VALUE; 00077 } 00078 strcpyW(ci->file, filename); 00079 ci->magic = CATINFO_MAGIC; 00080 return ci; 00081 } 00082 00083 /*********************************************************************** 00084 * CryptCATAdminAcquireContext (WINTRUST.@) 00085 * 00086 * Get a catalog administrator context handle. 00087 * 00088 * PARAMS 00089 * catAdmin [O] Pointer to the context handle. 00090 * sys [I] Pointer to a GUID for the needed subsystem. 00091 * dwFlags [I] Reserved. 00092 * 00093 * RETURNS 00094 * Success: TRUE. catAdmin contains the context handle. 00095 * Failure: FALSE. 00096 * 00097 */ 00098 BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin, 00099 const GUID *sys, DWORD dwFlags) 00100 { 00101 static const WCHAR catroot[] = 00102 {'\\','c','a','t','r','o','o','t',0}; 00103 static const WCHAR fmt[] = 00104 {'%','s','\\','{','%','0','8','x','-','%','0','4','x','-','%','0', 00105 '4','x','-','%','0','2','x','%','0','2','x','-','%','0','2','x', 00106 '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', 00107 '%','0','2','x','}',0}; 00108 static const GUID defsys = 00109 {0x127d0a1d,0x4ef2,0x11d1,{0x86,0x08,0x00,0xc0,0x4f,0xc2,0x95,0xee}}; 00110 00111 WCHAR catroot_dir[MAX_PATH]; 00112 struct catadmin *ca; 00113 00114 TRACE("%p %s %x\n", catAdmin, debugstr_guid(sys), dwFlags); 00115 00116 if (!catAdmin) 00117 { 00118 SetLastError(ERROR_INVALID_PARAMETER); 00119 return FALSE; 00120 } 00121 if (!(ca = HeapAlloc(GetProcessHeap(), 0, sizeof(*ca)))) 00122 { 00123 SetLastError(ERROR_OUTOFMEMORY); 00124 return FALSE; 00125 } 00126 00127 GetSystemDirectoryW(catroot_dir, MAX_PATH); 00128 strcatW(catroot_dir, catroot); 00129 00130 /* create the directory if it doesn't exist */ 00131 CreateDirectoryW(catroot_dir, NULL); 00132 00133 if (!sys) sys = &defsys; 00134 sprintfW(ca->path, fmt, catroot_dir, sys->Data1, sys->Data2, 00135 sys->Data3, sys->Data4[0], sys->Data4[1], sys->Data4[2], 00136 sys->Data4[3], sys->Data4[4], sys->Data4[5], sys->Data4[6], 00137 sys->Data4[7]); 00138 00139 /* create the directory if it doesn't exist */ 00140 CreateDirectoryW(ca->path, NULL); 00141 00142 ca->magic = CATADMIN_MAGIC; 00143 ca->find = INVALID_HANDLE_VALUE; 00144 00145 *catAdmin = ca; 00146 return TRUE; 00147 } 00148 00149 /*********************************************************************** 00150 * CryptCATAdminAddCatalog (WINTRUST.@) 00151 */ 00152 HCATINFO WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile, 00153 PWSTR selectBaseName, DWORD flags) 00154 { 00155 static const WCHAR slashW[] = {'\\',0}; 00156 struct catadmin *ca = catAdmin; 00157 struct catinfo *ci; 00158 WCHAR *target; 00159 DWORD len; 00160 00161 TRACE("%p %s %s %d\n", catAdmin, debugstr_w(catalogFile), 00162 debugstr_w(selectBaseName), flags); 00163 00164 if (!selectBaseName) 00165 { 00166 FIXME("NULL basename not handled\n"); 00167 SetLastError(ERROR_INVALID_PARAMETER); 00168 return NULL; 00169 } 00170 if (!ca || ca->magic != CATADMIN_MAGIC || !catalogFile || flags) 00171 { 00172 SetLastError(ERROR_INVALID_PARAMETER); 00173 return NULL; 00174 } 00175 00176 len = strlenW(ca->path) + strlenW(selectBaseName) + 2; 00177 if (!(target = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) 00178 { 00179 SetLastError(ERROR_OUTOFMEMORY); 00180 return NULL; 00181 } 00182 strcpyW(target, ca->path); 00183 strcatW(target, slashW); 00184 strcatW(target, selectBaseName); 00185 00186 if (!CopyFileW(catalogFile, target, FALSE)) 00187 { 00188 HeapFree(GetProcessHeap(), 0, target); 00189 return NULL; 00190 } 00191 SetFileAttributesW(target, FILE_ATTRIBUTE_SYSTEM); 00192 00193 if (!(ci = HeapAlloc(GetProcessHeap(), 0, sizeof(*ci)))) 00194 { 00195 HeapFree(GetProcessHeap(), 0, target); 00196 SetLastError(ERROR_OUTOFMEMORY); 00197 return NULL; 00198 } 00199 ci->magic = CATINFO_MAGIC; 00200 strcpyW(ci->file, target); 00201 00202 HeapFree(GetProcessHeap(), 0, target); 00203 return ci; 00204 } 00205 00206 /*********************************************************************** 00207 * CryptCATAdminCalcHashFromFileHandle (WINTRUST.@) 00208 */ 00209 BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD* pcbHash, 00210 BYTE* pbHash, DWORD dwFlags ) 00211 { 00212 BOOL ret = FALSE; 00213 00214 TRACE("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags); 00215 00216 if (!hFile || !pcbHash || dwFlags) 00217 { 00218 SetLastError(ERROR_INVALID_PARAMETER); 00219 return FALSE; 00220 } 00221 if (*pcbHash < 20) 00222 { 00223 *pcbHash = 20; 00224 SetLastError(ERROR_INSUFFICIENT_BUFFER); 00225 return TRUE; 00226 } 00227 00228 *pcbHash = 20; 00229 if (pbHash) 00230 { 00231 HCRYPTPROV prov; 00232 HCRYPTHASH hash; 00233 DWORD bytes_read; 00234 BYTE *buffer; 00235 00236 if (!(buffer = HeapAlloc(GetProcessHeap(), 0, 4096))) 00237 { 00238 SetLastError(ERROR_OUTOFMEMORY); 00239 return FALSE; 00240 } 00241 ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 00242 if (!ret) 00243 { 00244 HeapFree(GetProcessHeap(), 0, buffer); 00245 return FALSE; 00246 } 00247 ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash); 00248 if (!ret) 00249 { 00250 HeapFree(GetProcessHeap(), 0, buffer); 00251 CryptReleaseContext(prov, 0); 00252 return FALSE; 00253 } 00254 while ((ret = ReadFile(hFile, buffer, 4096, &bytes_read, NULL)) && bytes_read) 00255 { 00256 CryptHashData(hash, buffer, bytes_read, 0); 00257 } 00258 if (ret) ret = CryptGetHashParam(hash, HP_HASHVAL, pbHash, pcbHash, 0); 00259 00260 HeapFree(GetProcessHeap(), 0, buffer); 00261 CryptDestroyHash(hash); 00262 CryptReleaseContext(prov, 0); 00263 } 00264 return ret; 00265 } 00266 00267 /*********************************************************************** 00268 * CryptCATAdminEnumCatalogFromHash (WINTRUST.@) 00269 */ 00270 HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin, BYTE* pbHash, 00271 DWORD cbHash, DWORD dwFlags, 00272 HCATINFO* phPrevCatInfo ) 00273 { 00274 static const WCHAR slashW[] = {'\\',0}; 00275 static const WCHAR globW[] = {'\\','*','.','c','a','t',0}; 00276 00277 struct catadmin *ca = hCatAdmin; 00278 WIN32_FIND_DATAW data; 00279 HCATINFO prev = NULL; 00280 HCRYPTPROV prov; 00281 DWORD size; 00282 BOOL ret; 00283 00284 TRACE("%p %p %d %x %p\n", hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo); 00285 00286 if (!ca || ca->magic != CATADMIN_MAGIC || !pbHash || cbHash != 20 || dwFlags) 00287 { 00288 SetLastError(ERROR_INVALID_PARAMETER); 00289 return NULL; 00290 } 00291 if (phPrevCatInfo) prev = *phPrevCatInfo; 00292 00293 ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 00294 if (!ret) return NULL; 00295 00296 if (!prev) 00297 { 00298 WCHAR *path; 00299 00300 size = strlenW(ca->path) * sizeof(WCHAR) + sizeof(globW); 00301 if (!(path = HeapAlloc(GetProcessHeap(), 0, size))) 00302 { 00303 CryptReleaseContext(prov, 0); 00304 SetLastError(ERROR_OUTOFMEMORY); 00305 return NULL; 00306 } 00307 strcpyW(path, ca->path); 00308 strcatW(path, globW); 00309 00310 FindClose(ca->find); 00311 ca->find = FindFirstFileW(path, &data); 00312 00313 HeapFree(GetProcessHeap(), 0, path); 00314 if (ca->find == INVALID_HANDLE_VALUE) 00315 { 00316 CryptReleaseContext(prov, 0); 00317 return NULL; 00318 } 00319 } 00320 else if (!FindNextFileW(ca->find, &data)) 00321 { 00322 CryptCATAdminReleaseCatalogContext(hCatAdmin, prev, 0); 00323 CryptReleaseContext(prov, 0); 00324 return NULL; 00325 } 00326 00327 while (1) 00328 { 00329 WCHAR *filename; 00330 CRYPTCATMEMBER *member = NULL; 00331 struct catinfo *ci; 00332 HANDLE hcat; 00333 00334 size = (strlenW(ca->path) + strlenW(data.cFileName) + 2) * sizeof(WCHAR); 00335 if (!(filename = HeapAlloc(GetProcessHeap(), 0, size))) 00336 { 00337 SetLastError(ERROR_OUTOFMEMORY); 00338 return NULL; 00339 } 00340 strcpyW(filename, ca->path); 00341 strcatW(filename, slashW); 00342 strcatW(filename, data.cFileName); 00343 00344 hcat = CryptCATOpen(filename, CRYPTCAT_OPEN_EXISTING, prov, 0, 0); 00345 if (hcat == INVALID_HANDLE_VALUE) 00346 { 00347 WARN("couldn't open %s (%u)\n", debugstr_w(filename), GetLastError()); 00348 continue; 00349 } 00350 while ((member = CryptCATEnumerateMember(hcat, member))) 00351 { 00352 if (member->pIndirectData->Digest.cbData != cbHash) 00353 { 00354 WARN("amount of hash bytes differs: %u/%u\n", member->pIndirectData->Digest.cbData, cbHash); 00355 continue; 00356 } 00357 if (!memcmp(member->pIndirectData->Digest.pbData, pbHash, cbHash)) 00358 { 00359 TRACE("file %s matches\n", debugstr_w(data.cFileName)); 00360 00361 CryptCATClose(hcat); 00362 CryptReleaseContext(prov, 0); 00363 if (!phPrevCatInfo) 00364 { 00365 FindClose(ca->find); 00366 ca->find = INVALID_HANDLE_VALUE; 00367 } 00368 ci = create_catinfo(filename); 00369 HeapFree(GetProcessHeap(), 0, filename); 00370 return ci; 00371 } 00372 } 00373 CryptCATClose(hcat); 00374 HeapFree(GetProcessHeap(), 0, filename); 00375 00376 if (!FindNextFileW(ca->find, &data)) 00377 { 00378 FindClose(ca->find); 00379 ca->find = INVALID_HANDLE_VALUE; 00380 CryptReleaseContext(prov, 0); 00381 return NULL; 00382 } 00383 } 00384 return NULL; 00385 } 00386 00387 /*********************************************************************** 00388 * CryptCATAdminReleaseCatalogContext (WINTRUST.@) 00389 * 00390 * Release a catalog context handle. 00391 * 00392 * PARAMS 00393 * hCatAdmin [I] Context handle. 00394 * hCatInfo [I] Catalog handle. 00395 * dwFlags [I] Reserved. 00396 * 00397 * RETURNS 00398 * Success: TRUE. 00399 * Failure: FALSE. 00400 * 00401 */ 00402 BOOL WINAPI CryptCATAdminReleaseCatalogContext(HCATADMIN hCatAdmin, 00403 HCATINFO hCatInfo, 00404 DWORD dwFlags) 00405 { 00406 struct catinfo *ci = hCatInfo; 00407 struct catadmin *ca = hCatAdmin; 00408 00409 TRACE("%p %p %x\n", hCatAdmin, hCatInfo, dwFlags); 00410 00411 if (!ca || ca->magic != CATADMIN_MAGIC || !ci || ci->magic != CATINFO_MAGIC) 00412 { 00413 SetLastError(ERROR_INVALID_PARAMETER); 00414 return FALSE; 00415 } 00416 ci->magic = 0; 00417 return HeapFree(GetProcessHeap(), 0, ci); 00418 } 00419 00420 /*********************************************************************** 00421 * CryptCATAdminReleaseContext (WINTRUST.@) 00422 * 00423 * Release a catalog administrator context handle. 00424 * 00425 * PARAMS 00426 * catAdmin [I] Context handle. 00427 * dwFlags [I] Reserved. 00428 * 00429 * RETURNS 00430 * Success: TRUE. 00431 * Failure: FALSE. 00432 * 00433 */ 00434 BOOL WINAPI CryptCATAdminReleaseContext(HCATADMIN hCatAdmin, DWORD dwFlags ) 00435 { 00436 struct catadmin *ca = hCatAdmin; 00437 00438 TRACE("%p %x\n", hCatAdmin, dwFlags); 00439 00440 if (!ca || ca->magic != CATADMIN_MAGIC) 00441 { 00442 SetLastError(ERROR_INVALID_PARAMETER); 00443 return FALSE; 00444 } 00445 if (ca->find != INVALID_HANDLE_VALUE) FindClose(ca->find); 00446 ca->magic = 0; 00447 return HeapFree(GetProcessHeap(), 0, ca); 00448 } 00449 00450 /*********************************************************************** 00451 * CryptCATAdminRemoveCatalog (WINTRUST.@) 00452 * 00453 * Remove a catalog file. 00454 * 00455 * PARAMS 00456 * catAdmin [I] Context handle. 00457 * pwszCatalogFile [I] Catalog file. 00458 * dwFlags [I] Reserved. 00459 * 00460 * RETURNS 00461 * Success: TRUE. 00462 * Failure: FALSE. 00463 * 00464 */ 00465 BOOL WINAPI CryptCATAdminRemoveCatalog(HCATADMIN hCatAdmin, LPCWSTR pwszCatalogFile, DWORD dwFlags) 00466 { 00467 struct catadmin *ca = hCatAdmin; 00468 00469 TRACE("%p %s %x\n", hCatAdmin, debugstr_w(pwszCatalogFile), dwFlags); 00470 00471 if (!ca || ca->magic != CATADMIN_MAGIC) 00472 { 00473 SetLastError(ERROR_INVALID_PARAMETER); 00474 return FALSE; 00475 } 00476 00477 /* Only delete when there is a filename and no path */ 00478 if (pwszCatalogFile && pwszCatalogFile[0] != 0 && 00479 !strchrW(pwszCatalogFile, '\\') && !strchrW(pwszCatalogFile, '/') && 00480 !strchrW(pwszCatalogFile, ':')) 00481 { 00482 static const WCHAR slashW[] = {'\\',0}; 00483 WCHAR *target; 00484 DWORD len; 00485 00486 len = strlenW(ca->path) + strlenW(pwszCatalogFile) + 2; 00487 if (!(target = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) 00488 { 00489 SetLastError(ERROR_OUTOFMEMORY); 00490 return FALSE; 00491 } 00492 strcpyW(target, ca->path); 00493 strcatW(target, slashW); 00494 strcatW(target, pwszCatalogFile); 00495 00496 DeleteFileW(target); 00497 00498 HeapFree(GetProcessHeap(), 0, target); 00499 } 00500 00501 return TRUE; 00502 } 00503 00504 /*********************************************************************** 00505 * CryptCATAdminResolveCatalogPath (WINTRUST.@) 00506 */ 00507 BOOL WINAPI CryptCATAdminResolveCatalogPath(HCATADMIN hcatadmin, WCHAR *catalog_file, 00508 CATALOG_INFO *info, DWORD flags) 00509 { 00510 static const WCHAR slashW[] = {'\\',0}; 00511 struct catadmin *ca = hcatadmin; 00512 00513 TRACE("%p %s %p %x\n", hcatadmin, debugstr_w(catalog_file), info, flags); 00514 00515 if (!ca || ca->magic != CATADMIN_MAGIC || !info || info->cbStruct != sizeof(*info) || flags) 00516 { 00517 SetLastError(ERROR_INVALID_PARAMETER); 00518 return FALSE; 00519 } 00520 strcpyW(info->wszCatalogFile, ca->path); 00521 strcatW(info->wszCatalogFile, slashW); 00522 strcatW(info->wszCatalogFile, catalog_file); 00523 00524 return TRUE; 00525 } 00526 00527 /*********************************************************************** 00528 * CryptCATClose (WINTRUST.@) 00529 */ 00530 BOOL WINAPI CryptCATClose(HANDLE hCatalog) 00531 { 00532 struct cryptcat *cc = hCatalog; 00533 00534 TRACE("(%p)\n", hCatalog); 00535 00536 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00537 { 00538 SetLastError(ERROR_INVALID_PARAMETER); 00539 return FALSE; 00540 } 00541 HeapFree(GetProcessHeap(), 0, cc->attr); 00542 HeapFree(GetProcessHeap(), 0, cc->inner); 00543 CryptMsgClose(cc->msg); 00544 00545 cc->magic = 0; 00546 HeapFree(GetProcessHeap(), 0, cc); 00547 return TRUE; 00548 } 00549 00550 /*********************************************************************** 00551 * CryptCATGetAttrInfo (WINTRUST.@) 00552 */ 00553 CRYPTCATATTRIBUTE * WINAPI CryptCATGetAttrInfo(HANDLE hCatalog, CRYPTCATMEMBER *member, LPWSTR tag) 00554 { 00555 struct cryptcat *cc = hCatalog; 00556 00557 FIXME("%p, %p, %s\n", hCatalog, member, debugstr_w(tag)); 00558 00559 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00560 { 00561 SetLastError(ERROR_INVALID_PARAMETER); 00562 return NULL; 00563 } 00564 SetLastError(CRYPT_E_NOT_FOUND); 00565 return NULL; 00566 } 00567 00568 /*********************************************************************** 00569 * CryptCATGetCatAttrInfo (WINTRUST.@) 00570 */ 00571 CRYPTCATATTRIBUTE * WINAPI CryptCATGetCatAttrInfo(HANDLE hCatalog, LPWSTR tag) 00572 { 00573 struct cryptcat *cc = hCatalog; 00574 00575 FIXME("%p, %s\n", hCatalog, debugstr_w(tag)); 00576 00577 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00578 { 00579 SetLastError(ERROR_INVALID_PARAMETER); 00580 return NULL; 00581 } 00582 SetLastError(CRYPT_E_NOT_FOUND); 00583 return NULL; 00584 } 00585 00586 CRYPTCATMEMBER * WINAPI CryptCATGetMemberInfo(HANDLE hCatalog, LPWSTR tag) 00587 { 00588 struct cryptcat *cc = hCatalog; 00589 00590 FIXME("%p, %s\n", hCatalog, debugstr_w(tag)); 00591 00592 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00593 { 00594 SetLastError(ERROR_INVALID_PARAMETER); 00595 return NULL; 00596 } 00597 SetLastError(CRYPT_E_NOT_FOUND); 00598 return NULL; 00599 } 00600 00601 /*********************************************************************** 00602 * CryptCATEnumerateAttr (WINTRUST.@) 00603 */ 00604 CRYPTCATATTRIBUTE * WINAPI CryptCATEnumerateAttr(HANDLE hCatalog, CRYPTCATMEMBER *member, CRYPTCATATTRIBUTE *prev) 00605 { 00606 struct cryptcat *cc = hCatalog; 00607 00608 FIXME("%p, %p, %p\n", hCatalog, member, prev); 00609 00610 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00611 { 00612 SetLastError(ERROR_INVALID_PARAMETER); 00613 return NULL; 00614 } 00615 SetLastError(CRYPT_E_NOT_FOUND); 00616 return NULL; 00617 } 00618 00619 /*********************************************************************** 00620 * CryptCATEnumerateCatAttr (WINTRUST.@) 00621 */ 00622 CRYPTCATATTRIBUTE * WINAPI CryptCATEnumerateCatAttr(HANDLE hCatalog, CRYPTCATATTRIBUTE *prev) 00623 { 00624 struct cryptcat *cc = hCatalog; 00625 00626 FIXME("%p, %p\n", hCatalog, prev); 00627 00628 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00629 { 00630 SetLastError(ERROR_INVALID_PARAMETER); 00631 return NULL; 00632 } 00633 SetLastError(CRYPT_E_NOT_FOUND); 00634 return NULL; 00635 } 00636 00637 /*********************************************************************** 00638 * CryptCATEnumerateMember (WINTRUST.@) 00639 */ 00640 CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER *prev) 00641 { 00642 struct cryptcat *cc = hCatalog; 00643 CRYPTCATMEMBER *member = prev; 00644 CTL_ENTRY *entry; 00645 DWORD size, i; 00646 00647 TRACE("%p, %p\n", hCatalog, prev); 00648 00649 if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC) 00650 { 00651 SetLastError(ERROR_INVALID_PARAMETER); 00652 return NULL; 00653 } 00654 00655 /* dumping the contents makes me think that dwReserved is the iteration number */ 00656 if (!member) 00657 { 00658 if (!(member = HeapAlloc(GetProcessHeap(), 0, sizeof(*member)))) 00659 { 00660 SetLastError(ERROR_OUTOFMEMORY); 00661 return NULL; 00662 } 00663 member->cbStruct = sizeof(*member); 00664 member->pwszFileName = member->pwszReferenceTag = NULL; 00665 member->dwReserved = 0; 00666 member->hReserved = NULL; 00667 member->gSubjectType = cc->subject; 00668 member->fdwMemberFlags = 0; 00669 member->pIndirectData = NULL; 00670 member->dwCertVersion = cc->inner->dwVersion; 00671 } 00672 else member->dwReserved++; 00673 00674 if (member->dwReserved >= cc->inner->cCTLEntry) 00675 { 00676 SetLastError(ERROR_INVALID_PARAMETER); 00677 goto error; 00678 } 00679 00680 /* list them backwards, like native */ 00681 entry = &cc->inner->rgCTLEntry[cc->inner->cCTLEntry - member->dwReserved - 1]; 00682 00683 member->sEncodedIndirectData.cbData = member->sEncodedMemberInfo.cbData = 0; 00684 member->sEncodedIndirectData.pbData = member->sEncodedMemberInfo.pbData = NULL; 00685 HeapFree(GetProcessHeap(), 0, member->pIndirectData); 00686 member->pIndirectData = NULL; 00687 00688 for (i = 0; i < entry->cAttribute; i++) 00689 { 00690 CRYPT_ATTRIBUTE *attr = entry->rgAttribute + i; 00691 00692 if (attr->cValue != 1) 00693 { 00694 ERR("Can't handle attr->cValue of %u\n", attr->cValue); 00695 continue; 00696 } 00697 if (!strcmp(attr->pszObjId, CAT_MEMBERINFO_OBJID)) 00698 { 00699 CAT_MEMBERINFO *mi; 00700 BOOL ret; 00701 00702 member->sEncodedMemberInfo.cbData = attr->rgValue->cbData; 00703 member->sEncodedMemberInfo.pbData = attr->rgValue->pbData; 00704 00705 CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size); 00706 00707 if (!(mi = HeapAlloc(GetProcessHeap(), 0, size))) 00708 { 00709 SetLastError(ERROR_OUTOFMEMORY); 00710 goto error; 00711 } 00712 ret = CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, mi, &size); 00713 if (ret) 00714 { 00715 UNICODE_STRING guid; 00716 00717 member->dwCertVersion = mi->dwCertVersion; 00718 RtlInitUnicodeString(&guid, mi->pwszSubjGuid); 00719 if (RtlGUIDFromString(&guid, &member->gSubjectType)) 00720 { 00721 HeapFree(GetProcessHeap(), 0, mi); 00722 goto error; 00723 } 00724 } 00725 HeapFree(GetProcessHeap(), 0, mi); 00726 if (!ret) goto error; 00727 } 00728 else if (!strcmp(attr->pszObjId, SPC_INDIRECT_DATA_OBJID)) 00729 { 00730 /* SPC_INDIRECT_DATA_CONTENT is equal to SIP_INDIRECT_DATA */ 00731 00732 member->sEncodedIndirectData.cbData = attr->rgValue->cbData; 00733 member->sEncodedIndirectData.pbData = attr->rgValue->pbData; 00734 00735 CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size); 00736 00737 if (!(member->pIndirectData = HeapAlloc(GetProcessHeap(), 0, size))) 00738 { 00739 SetLastError(ERROR_OUTOFMEMORY); 00740 goto error; 00741 } 00742 CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, member->pIndirectData, &size); 00743 } 00744 else 00745 /* this object id should probably be handled in CryptCATEnumerateAttr */ 00746 FIXME("unhandled object id \"%s\"\n", attr->pszObjId); 00747 } 00748 00749 if (!member->sEncodedMemberInfo.cbData || !member->sEncodedIndirectData.cbData) 00750 { 00751 ERR("Corrupted catalog entry?\n"); 00752 SetLastError(CRYPT_E_ATTRIBUTES_MISSING); 00753 goto error; 00754 } 00755 size = (2 * member->pIndirectData->Digest.cbData + 1) * sizeof(WCHAR); 00756 if (member->pwszReferenceTag) 00757 member->pwszReferenceTag = HeapReAlloc(GetProcessHeap(), 0, member->pwszReferenceTag, size); 00758 else 00759 member->pwszReferenceTag = HeapAlloc(GetProcessHeap(), 0, size); 00760 00761 if (!member->pwszReferenceTag) 00762 { 00763 SetLastError(ERROR_OUTOFMEMORY); 00764 goto error; 00765 } 00766 /* FIXME: reference tag is usually the file hash but doesn't have to be */ 00767 for (i = 0; i < member->pIndirectData->Digest.cbData; i++) 00768 { 00769 DWORD sub; 00770 00771 sub = member->pIndirectData->Digest.pbData[i] >> 4; 00772 member->pwszReferenceTag[i * 2] = (sub < 10 ? '0' + sub : 'A' + sub - 10); 00773 sub = member->pIndirectData->Digest.pbData[i] & 0xf; 00774 member->pwszReferenceTag[i * 2 + 1] = (sub < 10 ? '0' + sub : 'A' + sub - 10); 00775 } 00776 member->pwszReferenceTag[i * 2] = 0; 00777 return member; 00778 00779 error: 00780 HeapFree(GetProcessHeap(), 0, member->pIndirectData); 00781 HeapFree(GetProcessHeap(), 0, member->pwszReferenceTag); 00782 HeapFree(GetProcessHeap(), 0, member); 00783 return NULL; 00784 } 00785 00786 static CTL_INFO *decode_inner_content(HANDLE hmsg, DWORD encoding, DWORD *len) 00787 { 00788 DWORD size; 00789 LPSTR oid = NULL; 00790 BYTE *buffer = NULL; 00791 CTL_INFO *inner = NULL; 00792 00793 if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size)) return NULL; 00794 if (!(oid = HeapAlloc(GetProcessHeap(), 0, size))) 00795 { 00796 SetLastError(ERROR_OUTOFMEMORY); 00797 return NULL; 00798 } 00799 if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid, &size)) goto out; 00800 if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, NULL, &size)) goto out; 00801 if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size))) 00802 { 00803 SetLastError(ERROR_OUTOFMEMORY); 00804 goto out; 00805 } 00806 if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, buffer, &size)) goto out; 00807 if (!CryptDecodeObject(encoding, oid, buffer, size, 0, NULL, &size)) goto out; 00808 if (!(inner = HeapAlloc(GetProcessHeap(), 0, size))) 00809 { 00810 SetLastError(ERROR_OUTOFMEMORY); 00811 goto out; 00812 } 00813 if (!CryptDecodeObject(encoding, oid, buffer, size, 0, inner, &size)) goto out; 00814 *len = size; 00815 00816 out: 00817 HeapFree(GetProcessHeap(), 0, oid); 00818 HeapFree(GetProcessHeap(), 0, buffer); 00819 return inner; 00820 } 00821 00822 /*********************************************************************** 00823 * CryptCATCatalogInfoFromContext (WINTRUST.@) 00824 */ 00825 BOOL WINAPI CryptCATCatalogInfoFromContext(HCATINFO hcatinfo, CATALOG_INFO *info, DWORD flags) 00826 { 00827 struct catinfo *ci = hcatinfo; 00828 00829 TRACE("%p, %p, %x\n", hcatinfo, info, flags); 00830 00831 if (!hcatinfo || hcatinfo == INVALID_HANDLE_VALUE || ci->magic != CATINFO_MAGIC || 00832 flags || !info || info->cbStruct != sizeof(*info)) 00833 { 00834 SetLastError(ERROR_INVALID_PARAMETER); 00835 return FALSE; 00836 } 00837 strcpyW(info->wszCatalogFile, ci->file); 00838 return TRUE; 00839 } 00840 00841 /*********************************************************************** 00842 * CryptCATOpen (WINTRUST.@) 00843 */ 00844 HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV hProv, 00845 DWORD dwPublicVersion, DWORD dwEncodingType) 00846 { 00847 HANDLE file, hmsg; 00848 BYTE *buffer = NULL; 00849 DWORD size, flags = OPEN_EXISTING; 00850 struct cryptcat *cc; 00851 00852 TRACE("%s, %x, %lx, %x, %x\n", debugstr_w(pwszFileName), fdwOpenFlags, 00853 hProv, dwPublicVersion, dwEncodingType); 00854 00855 if (!pwszFileName) 00856 { 00857 SetLastError(ERROR_INVALID_PARAMETER); 00858 return INVALID_HANDLE_VALUE; 00859 } 00860 00861 if (!dwPublicVersion) dwPublicVersion = 0x00000100; 00862 if (!dwEncodingType) dwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 00863 00864 if (fdwOpenFlags & CRYPTCAT_OPEN_ALWAYS) flags |= OPEN_ALWAYS; 00865 if (fdwOpenFlags & CRYPTCAT_OPEN_CREATENEW) flags |= CREATE_NEW; 00866 00867 file = CreateFileW(pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, flags, 0, NULL); 00868 if (file == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE; 00869 00870 size = GetFileSize(file, NULL); 00871 if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size))) 00872 { 00873 CloseHandle(file); 00874 SetLastError(ERROR_OUTOFMEMORY); 00875 return INVALID_HANDLE_VALUE; 00876 } 00877 if (!(hmsg = CryptMsgOpenToDecode(dwEncodingType, 0, 0, hProv, NULL, NULL))) 00878 { 00879 CloseHandle(file); 00880 HeapFree(GetProcessHeap(), 0, buffer); 00881 return INVALID_HANDLE_VALUE; 00882 } 00883 if (!ReadFile(file, buffer, size, &size, NULL) || !CryptMsgUpdate(hmsg, buffer, size, TRUE)) 00884 { 00885 CloseHandle(file); 00886 HeapFree(GetProcessHeap(), 0, buffer); 00887 CryptMsgClose(hmsg); 00888 return INVALID_HANDLE_VALUE; 00889 } 00890 HeapFree(GetProcessHeap(), 0, buffer); 00891 CloseHandle(file); 00892 00893 size = sizeof(DWORD); 00894 if (!(cc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cc)))) 00895 { 00896 CryptMsgClose(hmsg); 00897 SetLastError(ERROR_OUTOFMEMORY); 00898 return INVALID_HANDLE_VALUE; 00899 } 00900 00901 cc->msg = hmsg; 00902 cc->encoding = dwEncodingType; 00903 if (CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_COUNT_PARAM, 0, &cc->attr_count, &size)) 00904 { 00905 DWORD i, sum = 0; 00906 BYTE *p; 00907 00908 for (i = 0; i < cc->attr_count; i++) 00909 { 00910 if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size)) 00911 { 00912 CryptMsgClose(hmsg); 00913 return INVALID_HANDLE_VALUE; 00914 } 00915 sum += size; 00916 } 00917 if (!(cc->attr = HeapAlloc(GetProcessHeap(), 0, sizeof(*cc->attr) * cc->attr_count + sum))) 00918 { 00919 CryptMsgClose(hmsg); 00920 SetLastError(ERROR_OUTOFMEMORY); 00921 return INVALID_HANDLE_VALUE; 00922 } 00923 p = (BYTE *)(cc->attr + cc->attr_count); 00924 for (i = 0; i < cc->attr_count; i++) 00925 { 00926 if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size)) 00927 { 00928 CryptMsgClose(hmsg); 00929 HeapFree(GetProcessHeap(), 0, cc->attr); 00930 return INVALID_HANDLE_VALUE; 00931 } 00932 if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, p, &size)) 00933 { 00934 CryptMsgClose(hmsg); 00935 HeapFree(GetProcessHeap(), 0, cc->attr); 00936 return INVALID_HANDLE_VALUE; 00937 } 00938 p += size; 00939 } 00940 cc->inner = decode_inner_content(hmsg, dwEncodingType, &cc->inner_len); 00941 if (!cc->inner || !CryptSIPRetrieveSubjectGuid(pwszFileName, NULL, &cc->subject)) 00942 { 00943 CryptMsgClose(hmsg); 00944 HeapFree(GetProcessHeap(), 0, cc->attr); 00945 HeapFree(GetProcessHeap(), 0, cc->inner); 00946 HeapFree(GetProcessHeap(), 0, cc); 00947 return INVALID_HANDLE_VALUE; 00948 } 00949 cc->magic = CRYPTCAT_MAGIC; 00950 return cc; 00951 } 00952 return INVALID_HANDLE_VALUE; 00953 } 00954 00955 /*********************************************************************** 00956 * CryptSIPCreateIndirectData (WINTRUST.@) 00957 */ 00958 BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData, 00959 SIP_INDIRECT_DATA* pIndirectData) 00960 { 00961 FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData); 00962 00963 return FALSE; 00964 } 00965 00966 00967 /*********************************************************************** 00968 * CryptCATCDFClose (WINTRUST.@) 00969 */ 00970 BOOL WINAPI CryptCATCDFClose(CRYPTCATCDF *pCDF) 00971 { 00972 FIXME("(%p) stub\n", pCDF); 00973 00974 return FALSE; 00975 } 00976 00977 /*********************************************************************** 00978 * CryptCATCDFEnumCatAttributes (WINTRUST.@) 00979 */ 00980 CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumCatAttributes(CRYPTCATCDF *pCDF, 00981 CRYPTCATATTRIBUTE *pPrevAttr, 00982 PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError) 00983 { 00984 FIXME("(%p %p %p) stub\n", pCDF, pPrevAttr, pfnParseError); 00985 00986 return NULL; 00987 } 00988 00989 /*********************************************************************** 00990 * CryptCATCDFEnumMembersByCDFTagEx (WINTRUST.@) 00991 */ 00992 LPWSTR WINAPI CryptCATCDFEnumMembersByCDFTagEx(CRYPTCATCDF *pCDF, LPWSTR pwszPrevCDFTag, 00993 PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError, 00994 CRYPTCATMEMBER **ppMember, BOOL fContinueOnError, 00995 LPVOID pvReserved) 00996 { 00997 FIXME("(%p %s %p %p %d %p) stub\n", pCDF, debugstr_w(pwszPrevCDFTag), pfnParseError, 00998 ppMember, fContinueOnError, pvReserved); 00999 01000 return NULL; 01001 } 01002 01003 /*********************************************************************** 01004 * CryptCATCDFOpen (WINTRUST.@) 01005 */ 01006 CRYPTCATCDF * WINAPI CryptCATCDFOpen(LPWSTR pwszFilePath, 01007 PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError) 01008 { 01009 FIXME("(%s %p) stub\n", debugstr_w(pwszFilePath), pfnParseError); 01010 01011 return NULL; 01012 } 01013 01014 static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo, 01015 DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, 01016 BYTE *pbSignedDataMsg) 01017 { 01018 BOOL ret; 01019 WIN_CERTIFICATE *pCert = NULL; 01020 01021 TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, 01022 pcbSignedDataMsg, pbSignedDataMsg); 01023 01024 if (!pbSignedDataMsg) 01025 { 01026 WIN_CERTIFICATE cert; 01027 01028 /* app hasn't passed buffer, just get the length */ 01029 ret = ImageGetCertificateHeader(pSubjectInfo->hFile, dwIndex, &cert); 01030 if (ret) 01031 { 01032 switch (cert.wCertificateType) 01033 { 01034 case WIN_CERT_TYPE_X509: 01035 case WIN_CERT_TYPE_PKCS_SIGNED_DATA: 01036 *pcbSignedDataMsg = cert.dwLength; 01037 break; 01038 default: 01039 WARN("unknown certificate type %d\n", cert.wCertificateType); 01040 ret = FALSE; 01041 } 01042 } 01043 } 01044 else 01045 { 01046 DWORD len = 0; 01047 01048 ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, NULL, &len); 01049 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 01050 goto error; 01051 pCert = HeapAlloc(GetProcessHeap(), 0, len); 01052 if (!pCert) 01053 { 01054 ret = FALSE; 01055 goto error; 01056 } 01057 ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, pCert, 01058 &len); 01059 if (!ret) 01060 goto error; 01061 if (*pcbSignedDataMsg < pCert->dwLength) 01062 { 01063 *pcbSignedDataMsg = pCert->dwLength; 01064 SetLastError(ERROR_INSUFFICIENT_BUFFER); 01065 ret = FALSE; 01066 } 01067 else 01068 { 01069 memcpy(pbSignedDataMsg, pCert->bCertificate, pCert->dwLength); 01070 switch (pCert->wCertificateType) 01071 { 01072 case WIN_CERT_TYPE_X509: 01073 *pdwEncodingType = X509_ASN_ENCODING; 01074 break; 01075 case WIN_CERT_TYPE_PKCS_SIGNED_DATA: 01076 *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 01077 break; 01078 default: 01079 WARN("don't know what to do for encoding type %d\n", 01080 pCert->wCertificateType); 01081 *pdwEncodingType = 0; 01082 ret = FALSE; 01083 } 01084 } 01085 } 01086 error: 01087 HeapFree(GetProcessHeap(), 0, pCert); 01088 return ret; 01089 } 01090 01091 /* structure offsets */ 01092 #define cfhead_Signature (0x00) 01093 #define cfhead_CabinetSize (0x08) 01094 #define cfhead_MinorVersion (0x18) 01095 #define cfhead_MajorVersion (0x19) 01096 #define cfhead_Flags (0x1E) 01097 #define cfhead_SIZEOF (0x24) 01098 #define cfheadext_HeaderReserved (0x00) 01099 #define cfheadext_SIZEOF (0x04) 01100 #define cfsigninfo_CertOffset (0x04) 01101 #define cfsigninfo_CertSize (0x08) 01102 #define cfsigninfo_SIZEOF (0x0C) 01103 01104 /* flags */ 01105 #define cfheadRESERVE_PRESENT (0x0004) 01106 01107 /* endian-neutral reading of little-endian data */ 01108 #define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0])) 01109 #define EndGetI16(a) ((((a)[1])<<8)|((a)[0])) 01110 01111 /* For documentation purposes only: this is the structure in the reserved 01112 * area of a signed cabinet file. The cert offset indicates where in the 01113 * cabinet file the signature resides, and the count indicates its size. 01114 */ 01115 typedef struct _CAB_SIGNINFO 01116 { 01117 WORD unk0; /* always 0? */ 01118 WORD unk1; /* always 0x0010? */ 01119 DWORD dwCertOffset; 01120 DWORD cbCertBlock; 01121 } CAB_SIGNINFO, *PCAB_SIGNINFO; 01122 01123 static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo, 01124 DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, 01125 BYTE *pbSignedDataMsg) 01126 { 01127 int header_resv; 01128 LONG base_offset, cabsize; 01129 USHORT flags; 01130 BYTE buf[64]; 01131 DWORD cert_offset, cert_size, dwRead; 01132 01133 TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, 01134 pcbSignedDataMsg, pbSignedDataMsg); 01135 01136 /* get basic offset & size info */ 01137 base_offset = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR); 01138 01139 if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == INVALID_SET_FILE_POINTER) 01140 { 01141 TRACE("seek error\n"); 01142 return FALSE; 01143 } 01144 01145 cabsize = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR); 01146 if ((cabsize == -1) || (base_offset == -1) || 01147 (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER)) 01148 { 01149 TRACE("seek error\n"); 01150 return FALSE; 01151 } 01152 01153 /* read in the CFHEADER */ 01154 if (!ReadFile(pSubjectInfo->hFile, buf, cfhead_SIZEOF, &dwRead, NULL) || 01155 dwRead != cfhead_SIZEOF) 01156 { 01157 TRACE("reading header failed\n"); 01158 return FALSE; 01159 } 01160 01161 /* check basic MSCF signature */ 01162 if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) 01163 { 01164 WARN("cabinet signature not present\n"); 01165 return FALSE; 01166 } 01167 01168 /* Ignore the number of folders and files and the set and cabinet IDs */ 01169 01170 /* check the header revision */ 01171 if ((buf[cfhead_MajorVersion] > 1) || 01172 (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3)) 01173 { 01174 WARN("cabinet format version > 1.3\n"); 01175 return FALSE; 01176 } 01177 01178 /* pull the flags out */ 01179 flags = EndGetI16(buf+cfhead_Flags); 01180 01181 if (!(flags & cfheadRESERVE_PRESENT)) 01182 { 01183 TRACE("no header present, not signed\n"); 01184 return FALSE; 01185 } 01186 01187 if (!ReadFile(pSubjectInfo->hFile, buf, cfheadext_SIZEOF, &dwRead, NULL) || 01188 dwRead != cfheadext_SIZEOF) 01189 { 01190 ERR("bunk reserve-sizes?\n"); 01191 return FALSE; 01192 } 01193 01194 header_resv = EndGetI16(buf+cfheadext_HeaderReserved); 01195 if (!header_resv) 01196 { 01197 TRACE("no header_resv, not signed\n"); 01198 return FALSE; 01199 } 01200 else if (header_resv < cfsigninfo_SIZEOF) 01201 { 01202 TRACE("header_resv too small, not signed\n"); 01203 return FALSE; 01204 } 01205 01206 if (header_resv > 60000) 01207 { 01208 WARN("WARNING; header reserved space > 60000\n"); 01209 } 01210 01211 if (!ReadFile(pSubjectInfo->hFile, buf, cfsigninfo_SIZEOF, &dwRead, NULL) || 01212 dwRead != cfsigninfo_SIZEOF) 01213 { 01214 ERR("couldn't read reserve\n"); 01215 return FALSE; 01216 } 01217 01218 cert_offset = EndGetI32(buf+cfsigninfo_CertOffset); 01219 TRACE("cert_offset: %d\n", cert_offset); 01220 cert_size = EndGetI32(buf+cfsigninfo_CertSize); 01221 TRACE("cert_size: %d\n", cert_size); 01222 01223 /* The redundant checks are to avoid wraparound */ 01224 if (cert_offset > cabsize || cert_size > cabsize || 01225 cert_offset + cert_size > cabsize) 01226 { 01227 WARN("offset beyond file, not attempting to read\n"); 01228 return FALSE; 01229 } 01230 01231 SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET); 01232 if (!pbSignedDataMsg) 01233 { 01234 *pcbSignedDataMsg = cert_size; 01235 return TRUE; 01236 } 01237 if (*pcbSignedDataMsg < cert_size) 01238 { 01239 *pcbSignedDataMsg = cert_size; 01240 SetLastError(ERROR_INSUFFICIENT_BUFFER); 01241 return FALSE; 01242 } 01243 if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER) 01244 { 01245 ERR("couldn't seek to cert location\n"); 01246 return FALSE; 01247 } 01248 if (!ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, cert_size, &dwRead, 01249 NULL) || dwRead != cert_size) 01250 { 01251 ERR("couldn't read cert\n"); 01252 SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET); 01253 return FALSE; 01254 } 01255 /* The encoding of the files I've seen appears to be in ASN.1 01256 * format, and there isn't a field indicating the type, so assume it 01257 * always is. 01258 */ 01259 *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 01260 /* Restore base offset */ 01261 SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET); 01262 return TRUE; 01263 } 01264 01265 static BOOL WINTRUST_GetSignedMsgFromCatFile(SIP_SUBJECTINFO *pSubjectInfo, 01266 DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, 01267 BYTE *pbSignedDataMsg) 01268 { 01269 BOOL ret; 01270 01271 TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, 01272 pcbSignedDataMsg, pbSignedDataMsg); 01273 01274 if (!pbSignedDataMsg) 01275 { 01276 *pcbSignedDataMsg = GetFileSize(pSubjectInfo->hFile, NULL); 01277 ret = TRUE; 01278 } 01279 else 01280 { 01281 DWORD len = GetFileSize(pSubjectInfo->hFile, NULL); 01282 01283 if (*pcbSignedDataMsg < len) 01284 { 01285 *pcbSignedDataMsg = len; 01286 SetLastError(ERROR_INSUFFICIENT_BUFFER); 01287 ret = FALSE; 01288 } 01289 else 01290 { 01291 ret = ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, len, 01292 pcbSignedDataMsg, NULL); 01293 if (ret) 01294 *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 01295 } 01296 } 01297 return ret; 01298 } 01299 01300 /*********************************************************************** 01301 * CryptSIPGetSignedDataMsg (WINTRUST.@) 01302 */ 01303 BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType, 01304 DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg) 01305 { 01306 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47, 01307 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; 01308 static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47, 01309 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; 01310 static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47, 01311 0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; 01312 BOOL ret; 01313 01314 TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, 01315 pcbSignedDataMsg, pbSignedDataMsg); 01316 01317 if (!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown))) 01318 ret = WINTRUST_GetSignedMsgFromPEFile(pSubjectInfo, pdwEncodingType, 01319 dwIndex, pcbSignedDataMsg, pbSignedDataMsg); 01320 else if (!memcmp(pSubjectInfo->pgSubjectType, &cabGUID, sizeof(cabGUID))) 01321 ret = WINTRUST_GetSignedMsgFromCabFile(pSubjectInfo, pdwEncodingType, 01322 dwIndex, pcbSignedDataMsg, pbSignedDataMsg); 01323 else if (!memcmp(pSubjectInfo->pgSubjectType, &catGUID, sizeof(catGUID))) 01324 ret = WINTRUST_GetSignedMsgFromCatFile(pSubjectInfo, pdwEncodingType, 01325 dwIndex, pcbSignedDataMsg, pbSignedDataMsg); 01326 else 01327 { 01328 FIXME("unimplemented for subject type %s\n", 01329 debugstr_guid(pSubjectInfo->pgSubjectType)); 01330 ret = FALSE; 01331 } 01332 01333 TRACE("returning %d\n", ret); 01334 return ret; 01335 } 01336 01337 /*********************************************************************** 01338 * CryptSIPPutSignedDataMsg (WINTRUST.@) 01339 */ 01340 BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType, 01341 DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg) 01342 { 01343 FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex, 01344 cbSignedDataMsg, pbSignedDataMsg); 01345 01346 return FALSE; 01347 } 01348 01349 /*********************************************************************** 01350 * CryptSIPRemoveSignedDataMsg (WINTRUST.@) 01351 */ 01352 BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, 01353 DWORD dwIndex) 01354 { 01355 FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex); 01356 01357 return FALSE; 01358 } 01359 01360 /*********************************************************************** 01361 * CryptSIPVerifyIndirectData (WINTRUST.@) 01362 */ 01363 BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo, 01364 SIP_INDIRECT_DATA* pIndirectData) 01365 { 01366 FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData); 01367 01368 return FALSE; 01369 } Generated on Sun May 27 2012 04:22:38 for ReactOS by
1.7.6.1
|