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

crypt.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 doxygen 1.7.6.1

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