| 1 | /*
 | 
|---|
| 2 |  * Copyright 2002 Mike McCormack for CodeWeavers
 | 
|---|
| 3 |  * Copyright 2005-2008 Juan Lang
 | 
|---|
| 4 |  * Copyright 2006 Paul Vriens
 | 
|---|
| 5 |  *
 | 
|---|
| 6 |  * This library is free software; you can redistribute it and/or
 | 
|---|
| 7 |  * modify it under the terms of the GNU Lesser General Public
 | 
|---|
| 8 |  * License as published by the Free Software Foundation; either
 | 
|---|
| 9 |  * version 2.1 of the License, or (at your option) any later version.
 | 
|---|
| 10 |  *
 | 
|---|
| 11 |  * This library is distributed in the hope that it will be useful,
 | 
|---|
| 12 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 13 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
|---|
| 14 |  * Lesser General Public License for more details.
 | 
|---|
| 15 |  *
 | 
|---|
| 16 |  * You should have received a copy of the GNU Lesser General Public
 | 
|---|
| 17 |  * License along with this library; if not, write to the Free Software
 | 
|---|
| 18 |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 | 
|---|
| 19 |  */
 | 
|---|
| 20 | 
 | 
|---|
| 21 | #include <stdarg.h>
 | 
|---|
| 22 | #include <stdio.h>
 | 
|---|
| 23 | #include <string.h>
 | 
|---|
| 24 | 
 | 
|---|
| 25 | #define WINE_LARGE_INTEGER /* for QuadPart in LARGE_INTEGER */
 | 
|---|
| 26 | 
 | 
|---|
| 27 | #include "windef.h"
 | 
|---|
| 28 | #include "winbase.h"
 | 
|---|
| 29 | #include "winerror.h"
 | 
|---|
| 30 | #include "wincrypt.h"
 | 
|---|
| 31 | #include "winreg.h"
 | 
|---|
| 32 | #include "winnls.h"
 | 
|---|
| 33 | #include "mssip.h"
 | 
|---|
| 34 | #include "winuser.h"
 | 
|---|
| 35 | 
 | 
|---|
| 36 | #include "wine/debug.h"
 | 
|---|
| 37 | #include "wine/list.h"
 | 
|---|
| 38 | #include "win32type.h"
 | 
|---|
| 39 | 
 | 
|---|
| 40 | WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 | 
|---|
| 41 | 
 | 
|---|
| 42 | static const WCHAR szOID[] = {
 | 
|---|
| 43 |     'S','o','f','t','w','a','r','e','\\',
 | 
|---|
| 44 |     'M','i','c','r','o','s','o','f','t','\\',
 | 
|---|
| 45 |     'C','r','y','p','t','o','g','r','a','p','h','y','\\',
 | 
|---|
| 46 |     'O','I','D','\\',
 | 
|---|
| 47 |     'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\',
 | 
|---|
| 48 |     'C','r','y','p','t','S','I','P','D','l','l', 0 };
 | 
|---|
| 49 | 
 | 
|---|
| 50 | static const WCHAR szPutSigned[] = {
 | 
|---|
| 51 |     'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
 | 
|---|
| 52 | static const WCHAR szGetSigned[] = {
 | 
|---|
| 53 |     'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
 | 
|---|
| 54 | static const WCHAR szRemoveSigned[] = {
 | 
|---|
| 55 |     'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
 | 
|---|
| 56 | static const WCHAR szCreate[] = {
 | 
|---|
| 57 |     'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
 | 
|---|
| 58 | static const WCHAR szVerify[] = {
 | 
|---|
| 59 |     'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
 | 
|---|
| 60 | static const WCHAR szIsMyFile[] = {
 | 
|---|
| 61 |     'I','s','M','y','F','i','l','e','T','y','p','e','\\',0};
 | 
|---|
| 62 | static const WCHAR szIsMyFile2[] = {
 | 
|---|
| 63 |     'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0};
 | 
|---|
| 64 | 
 | 
|---|
| 65 | static const WCHAR szDllName[] = { 'D','l','l',0 };
 | 
|---|
| 66 | static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 };
 | 
|---|
| 67 | 
 | 
|---|
| 68 | /* convert a guid to a wide character string */
 | 
|---|
| 69 | static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr )
 | 
|---|
| 70 | {
 | 
|---|
| 71 |     char str[40];
 | 
|---|
| 72 | 
 | 
|---|
| 73 |     sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
 | 
|---|
| 74 |            guid->Data1, guid->Data2, guid->Data3,
 | 
|---|
| 75 |            guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
 | 
|---|
| 76 |            guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
 | 
|---|
| 77 |     MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
 | 
|---|
| 78 | }
 | 
|---|
| 79 | 
 | 
|---|
| 80 | /***********************************************************************
 | 
|---|
| 81 |  *              CRYPT_SIPDeleteFunction
 | 
|---|
| 82 |  *
 | 
|---|
| 83 |  * Helper function for CryptSIPRemoveProvider
 | 
|---|
| 84 |  */
 | 
|---|
| 85 | static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey )
 | 
|---|
| 86 | {
 | 
|---|
| 87 |     WCHAR szFullKey[ 0x100 ];
 | 
|---|
| 88 |     LONG r = ERROR_SUCCESS;
 | 
|---|
| 89 | 
 | 
|---|
| 90 |     /* max length of szFullKey depends on our code only, so we won't overrun */
 | 
|---|
| 91 |     lstrcpyW( szFullKey, szOID );
 | 
|---|
| 92 |     lstrcatW( szFullKey, szKey );
 | 
|---|
| 93 |     CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );
 | 
|---|
| 94 | 
 | 
|---|
| 95 |     r = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szFullKey);
 | 
|---|
| 96 | 
 | 
|---|
| 97 |     return r;
 | 
|---|
| 98 | }
 | 
|---|
| 99 | 
 | 
|---|
| 100 | /***********************************************************************
 | 
|---|
| 101 |  *             CryptSIPRemoveProvider (CRYPT32.@)
 | 
|---|
| 102 |  *
 | 
|---|
| 103 |  * Remove a SIP provider and its functions from the registry.
 | 
|---|
| 104 |  *
 | 
|---|
| 105 |  * PARAMS
 | 
|---|
| 106 |  *  pgProv     [I] Pointer to a GUID for this SIP provider
 | 
|---|
| 107 |  *
 | 
|---|
| 108 |  * RETURNS
 | 
|---|
| 109 |  *  Success: TRUE.
 | 
|---|
| 110 |  *  Failure: FALSE. (Look at GetLastError()).
 | 
|---|
| 111 |  *
 | 
|---|
| 112 |  * NOTES
 | 
|---|
| 113 |  *  Registry errors are always reported via SetLastError(). Every registry
 | 
|---|
| 114 |  *  deletion will be tried.
 | 
|---|
| 115 |  */
 | 
|---|
| 116 | BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
 | 
|---|
| 117 | {
 | 
|---|
| 118 |     LONG r = ERROR_SUCCESS;
 | 
|---|
| 119 |     LONG remove_error = ERROR_SUCCESS;
 | 
|---|
| 120 | 
 | 
|---|
| 121 |     TRACE("%s\n", debugstr_guid(pgProv));
 | 
|---|
| 122 | 
 | 
|---|
| 123 |     if (!pgProv)
 | 
|---|
| 124 |     {
 | 
|---|
| 125 |         SetLastError(ERROR_INVALID_PARAMETER);
 | 
|---|
| 126 |         return FALSE;
 | 
|---|
| 127 |     }
 | 
|---|
| 128 | 
 | 
|---|
| 129 | 
 | 
|---|
| 130 | #define CRYPT_SIPREMOVEPROV( key ) \
 | 
|---|
| 131 |     r = CRYPT_SIPDeleteFunction( pgProv, key); \
 | 
|---|
| 132 |     if (r != ERROR_SUCCESS) remove_error = r
 | 
|---|
| 133 | 
 | 
|---|
| 134 |     CRYPT_SIPREMOVEPROV( szPutSigned);
 | 
|---|
| 135 |     CRYPT_SIPREMOVEPROV( szGetSigned);
 | 
|---|
| 136 |     CRYPT_SIPREMOVEPROV( szRemoveSigned);
 | 
|---|
| 137 |     CRYPT_SIPREMOVEPROV( szCreate);
 | 
|---|
| 138 |     CRYPT_SIPREMOVEPROV( szVerify);
 | 
|---|
| 139 |     CRYPT_SIPREMOVEPROV( szIsMyFile);
 | 
|---|
| 140 |     CRYPT_SIPREMOVEPROV( szIsMyFile2);
 | 
|---|
| 141 | 
 | 
|---|
| 142 | #undef CRYPT_SIPREMOVEPROV
 | 
|---|
| 143 | 
 | 
|---|
| 144 |     if (remove_error != ERROR_SUCCESS)
 | 
|---|
| 145 |     {
 | 
|---|
| 146 |         SetLastError(remove_error);
 | 
|---|
| 147 |         return FALSE;
 | 
|---|
| 148 |     }
 | 
|---|
| 149 | 
 | 
|---|
| 150 |     return TRUE;
 | 
|---|
| 151 | }
 | 
|---|
| 152 | 
 | 
|---|
| 153 | /*
 | 
|---|
| 154 |  * Helper for CryptSIPAddProvider
 | 
|---|
| 155 |  *
 | 
|---|
| 156 |  * Add a registry key containing a dll name and function under
 | 
|---|
| 157 |  *  "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\<func>\\<guid>"
 | 
|---|
| 158 |  */
 | 
|---|
| 159 | static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey,
 | 
|---|
| 160 |               LPCWSTR szDll, LPCWSTR szFunction )
 | 
|---|
| 161 | {
 | 
|---|
| 162 |     WCHAR szFullKey[ 0x100 ];
 | 
|---|
| 163 |     LONG r = ERROR_SUCCESS;
 | 
|---|
| 164 |     HKEY hKey;
 | 
|---|
| 165 | 
 | 
|---|
| 166 |     if( !szFunction )
 | 
|---|
| 167 |          return ERROR_SUCCESS;
 | 
|---|
| 168 | 
 | 
|---|
| 169 |     /* max length of szFullKey depends on our code only, so we won't overrun */
 | 
|---|
| 170 |     lstrcpyW( szFullKey, szOID );
 | 
|---|
| 171 |     lstrcatW( szFullKey, szKey );
 | 
|---|
| 172 |     CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );
 | 
|---|
| 173 | 
 | 
|---|
| 174 |     TRACE("key is %s\n", debugstr_w( szFullKey ) );
 | 
|---|
| 175 | 
 | 
|---|
| 176 |     r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey );
 | 
|---|
| 177 |     if( r != ERROR_SUCCESS ) goto error_close_key;
 | 
|---|
| 178 | 
 | 
|---|
| 179 |     /* write the values */
 | 
|---|
| 180 |     r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (BYTE*) szFunction,
 | 
|---|
| 181 |                         ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) );
 | 
|---|
| 182 |     if( r != ERROR_SUCCESS ) goto error_close_key;
 | 
|---|
| 183 |     r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (BYTE*) szDll,
 | 
|---|
| 184 |                         ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) );
 | 
|---|
| 185 | 
 | 
|---|
| 186 | error_close_key:
 | 
|---|
| 187 | 
 | 
|---|
| 188 |     RegCloseKey( hKey );
 | 
|---|
| 189 | 
 | 
|---|
| 190 |     return r;
 | 
|---|
| 191 | }
 | 
|---|
| 192 | 
 | 
|---|
| 193 | /***********************************************************************
 | 
|---|
| 194 |  *             CryptSIPAddProvider (CRYPT32.@)
 | 
|---|
| 195 |  *
 | 
|---|
| 196 |  * Add a SIP provider and its functions to the registry.
 | 
|---|
| 197 |  *
 | 
|---|
| 198 |  * PARAMS
 | 
|---|
| 199 |  *  psNewProv       [I] Pointer to a structure with information about
 | 
|---|
| 200 |  *                      the functions this SIP provider can perform.
 | 
|---|
| 201 |  *
 | 
|---|
| 202 |  * RETURNS
 | 
|---|
| 203 |  *  Success: TRUE.
 | 
|---|
| 204 |  *  Failure: FALSE. (Look at GetLastError()).
 | 
|---|
| 205 |  *
 | 
|---|
| 206 |  * NOTES
 | 
|---|
| 207 |  *  Registry errors are always reported via SetLastError(). If a
 | 
|---|
| 208 |  *  registry error occurs the rest of the registry write operations
 | 
|---|
| 209 |  *  will be skipped.
 | 
|---|
| 210 |  */
 | 
|---|
| 211 | BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv)
 | 
|---|
| 212 | {
 | 
|---|
| 213 |     LONG r = ERROR_SUCCESS;
 | 
|---|
| 214 | 
 | 
|---|
| 215 |     TRACE("%p\n", psNewProv);
 | 
|---|
| 216 | 
 | 
|---|
| 217 |     if (!psNewProv ||
 | 
|---|
| 218 |         psNewProv->cbStruct != sizeof(SIP_ADD_NEWPROVIDER) ||
 | 
|---|
| 219 |         !psNewProv->pwszGetFuncName ||
 | 
|---|
| 220 |         !psNewProv->pwszPutFuncName ||
 | 
|---|
| 221 |         !psNewProv->pwszCreateFuncName ||
 | 
|---|
| 222 |         !psNewProv->pwszVerifyFuncName ||
 | 
|---|
| 223 |         !psNewProv->pwszRemoveFuncName)
 | 
|---|
| 224 |     {
 | 
|---|
| 225 |         SetLastError(ERROR_INVALID_PARAMETER);
 | 
|---|
| 226 |         return FALSE;
 | 
|---|
| 227 |     }
 | 
|---|
| 228 | 
 | 
|---|
| 229 |     TRACE("%s %s %s %s %s\n",
 | 
|---|
| 230 |           debugstr_guid( psNewProv->pgSubject ),
 | 
|---|
| 231 |           debugstr_w( psNewProv->pwszDLLFileName ),
 | 
|---|
| 232 |           debugstr_w( psNewProv->pwszMagicNumber ),
 | 
|---|
| 233 |           debugstr_w( psNewProv->pwszIsFunctionName ),
 | 
|---|
| 234 |           debugstr_w( psNewProv->pwszIsFunctionNameFmt2 ) );
 | 
|---|
| 235 | 
 | 
|---|
| 236 | #define CRYPT_SIPADDPROV( key, field ) \
 | 
|---|
| 237 |     r = CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \
 | 
|---|
| 238 |            psNewProv->pwszDLLFileName, psNewProv->field); \
 | 
|---|
| 239 |     if (r != ERROR_SUCCESS) goto end_function
 | 
|---|
| 240 | 
 | 
|---|
| 241 |     CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName );
 | 
|---|
| 242 |     CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName );
 | 
|---|
| 243 |     CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName );
 | 
|---|
| 244 |     CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName );
 | 
|---|
| 245 |     CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName );
 | 
|---|
| 246 |     CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName );
 | 
|---|
| 247 |     CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 );
 | 
|---|
| 248 | 
 | 
|---|
| 249 | #undef CRYPT_SIPADDPROV
 | 
|---|
| 250 | 
 | 
|---|
| 251 | end_function:
 | 
|---|
| 252 | 
 | 
|---|
| 253 |     if (r != ERROR_SUCCESS)
 | 
|---|
| 254 |     {
 | 
|---|
| 255 |         SetLastError(r);
 | 
|---|
| 256 |         return FALSE;
 | 
|---|
| 257 |     }
 | 
|---|
| 258 | 
 | 
|---|
| 259 |     return TRUE;
 | 
|---|
| 260 | }
 | 
|---|
| 261 | 
 | 
|---|
| 262 | static void *CRYPT_LoadSIPFuncFromKey(HKEY key, HMODULE *pLib)
 | 
|---|
| 263 | {
 | 
|---|
| 264 |     LONG r;
 | 
|---|
| 265 |     DWORD size;
 | 
|---|
| 266 |     WCHAR dllName[MAX_PATH];
 | 
|---|
| 267 |     char functionName[MAX_PATH];
 | 
|---|
| 268 |     HMODULE lib;
 | 
|---|
| 269 |     void *func = NULL;
 | 
|---|
| 270 | 
 | 
|---|
| 271 |     /* Read the DLL entry */
 | 
|---|
| 272 |     size = sizeof(dllName);
 | 
|---|
| 273 |     r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
 | 
|---|
| 274 |     if (r) goto end;
 | 
|---|
| 275 | 
 | 
|---|
| 276 |     /* Read the Function entry */
 | 
|---|
| 277 |     size = sizeof(functionName);
 | 
|---|
| 278 |     r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
 | 
|---|
| 279 |      &size);
 | 
|---|
| 280 |     if (r) goto end;
 | 
|---|
| 281 | 
 | 
|---|
| 282 |     lib = LoadLibraryW(dllName);
 | 
|---|
| 283 |     if (!lib)
 | 
|---|
| 284 |         goto end;
 | 
|---|
| 285 |     func = (void*)GetProcAddress(lib, functionName);
 | 
|---|
| 286 |     if (func)
 | 
|---|
| 287 |         *pLib = lib;
 | 
|---|
| 288 |     else
 | 
|---|
| 289 |         FreeLibrary(lib);
 | 
|---|
| 290 | 
 | 
|---|
| 291 | end:
 | 
|---|
| 292 |     return func;
 | 
|---|
| 293 | }
 | 
|---|
| 294 | 
 | 
|---|
| 295 | /***********************************************************************
 | 
|---|
| 296 |  *             CryptSIPRetrieveSubjectGuid (CRYPT32.@)
 | 
|---|
| 297 |  *
 | 
|---|
| 298 |  * Determine the right SIP GUID for the given file.
 | 
|---|
| 299 |  *
 | 
|---|
| 300 |  * PARAMS
 | 
|---|
| 301 |  *  FileName   [I] Filename.
 | 
|---|
| 302 |  *  hFileIn    [I] Optional handle to the file.
 | 
|---|
| 303 |  *  pgSubject  [O] The SIP's GUID.
 | 
|---|
| 304 |  *
 | 
|---|
| 305 |  * RETURNS
 | 
|---|
| 306 |  *  Success: TRUE. pgSubject contains the SIP GUID.
 | 
|---|
| 307 |  *  Failure: FALSE. (Look at GetLastError()).
 | 
|---|
| 308 |  *
 | 
|---|
| 309 |  * NOTES
 | 
|---|
| 310 |  *  On failure pgSubject will contain a NULL GUID.
 | 
|---|
| 311 |  *  The handle is always preferred above the filename.
 | 
|---|
| 312 |  */
 | 
|---|
| 313 | BOOL WINAPI CryptSIPRetrieveSubjectGuid
 | 
|---|
| 314 |       (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
 | 
|---|
| 315 | {
 | 
|---|
| 316 |     HANDLE hFile;
 | 
|---|
| 317 |     BOOL   bRet = FALSE;
 | 
|---|
| 318 |     DWORD  count;
 | 
|---|
| 319 |     LARGE_INTEGER zero, oldPos;
 | 
|---|
| 320 |     /* FIXME, find out if there is a name for this GUID */
 | 
|---|
| 321 |     static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
 | 
|---|
| 322 |     static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }};
 | 
|---|
| 323 |     static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
 | 
|---|
| 324 |     static const WORD dosHdr = IMAGE_DOS_SIGNATURE;
 | 
|---|
| 325 |     static const BYTE cabHdr[] = { 'M','S','C','F' };
 | 
|---|
| 326 |     BYTE hdr[SIP_MAX_MAGIC_NUMBER];
 | 
|---|
| 327 |     WCHAR szFullKey[ 0x100 ];
 | 
|---|
| 328 |     LONG r = ERROR_SUCCESS;
 | 
|---|
| 329 |     HKEY key;
 | 
|---|
| 330 | 
 | 
|---|
| 331 |     TRACE("(%s %p %p)\n", FileName, hFileIn, pgSubject);
 | 
|---|
| 332 | 
 | 
|---|
| 333 |     if (!pgSubject || (!FileName && !hFileIn))
 | 
|---|
| 334 |     {
 | 
|---|
| 335 |         SetLastError(ERROR_INVALID_PARAMETER);
 | 
|---|
| 336 |         return FALSE;
 | 
|---|
| 337 |     }
 | 
|---|
| 338 | 
 | 
|---|
| 339 |     /* Set pgSubject to zero's */
 | 
|---|
| 340 |     memset(pgSubject, 0 , sizeof(GUID));
 | 
|---|
| 341 | 
 | 
|---|
| 342 |     if (hFileIn)
 | 
|---|
| 343 |         /* Use the given handle, make sure not to close this one ourselves */
 | 
|---|
| 344 |         hFile = hFileIn;
 | 
|---|
| 345 |     else
 | 
|---|
| 346 |     {
 | 
|---|
| 347 |         hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 | 
|---|
| 348 |         /* Last error is set by CreateFile */
 | 
|---|
| 349 |         if (hFile == INVALID_HANDLE_VALUE) return FALSE;
 | 
|---|
| 350 |     }
 | 
|---|
| 351 | 
 | 
|---|
| 352 |     zero.QuadPart = 0;
 | 
|---|
| 353 |     SetFilePointerEx(hFile, zero, &oldPos, FILE_CURRENT);
 | 
|---|
| 354 |     SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
 | 
|---|
| 355 |     if (!ReadFile(hFile, hdr, sizeof(hdr), &count, NULL))
 | 
|---|
| 356 |         goto cleanup;
 | 
|---|
| 357 | 
 | 
|---|
| 358 |     if (count < SIP_MAX_MAGIC_NUMBER)
 | 
|---|
| 359 |     {
 | 
|---|
| 360 |         SetLastError(ERROR_INVALID_PARAMETER);
 | 
|---|
| 361 |         goto cleanup;
 | 
|---|
| 362 |     }
 | 
|---|
| 363 | 
 | 
|---|
| 364 |     TRACE("file magic = 0x%02x%02x%02x%02x\n", hdr[0], hdr[1], hdr[2], hdr[3]);
 | 
|---|
| 365 |     /* As everything is in place now we start looking at the file header */
 | 
|---|
| 366 |     if (!memcmp(hdr, &dosHdr, sizeof(dosHdr)))
 | 
|---|
| 367 |     {
 | 
|---|
| 368 |         *pgSubject = unknown;
 | 
|---|
| 369 |         SetLastError(S_OK);
 | 
|---|
| 370 |         bRet = TRUE;
 | 
|---|
| 371 |         goto cleanup;
 | 
|---|
| 372 |     }
 | 
|---|
| 373 |     /* Quick-n-dirty check for a cab file. */
 | 
|---|
| 374 |     if (!memcmp(hdr, cabHdr, sizeof(cabHdr)))
 | 
|---|
| 375 |     {
 | 
|---|
| 376 |         *pgSubject = cabGUID;
 | 
|---|
| 377 |         SetLastError(S_OK);
 | 
|---|
| 378 |         bRet = TRUE;
 | 
|---|
| 379 |         goto cleanup;
 | 
|---|
| 380 |     }
 | 
|---|
| 381 |     /* If it's asn.1-encoded, it's probably a .cat file. */
 | 
|---|
| 382 |     if (hdr[0] == 0x30)
 | 
|---|
| 383 |     {
 | 
|---|
| 384 |         DWORD fileLen = GetFileSize(hFile, NULL);
 | 
|---|
| 385 | 
 | 
|---|
| 386 |         TRACE("fileLen = %d\n", fileLen);
 | 
|---|
| 387 |         /* Sanity-check length */
 | 
|---|
| 388 |         if (hdr[1] < 0x80 && fileLen == 2 + hdr[1])
 | 
|---|
| 389 |         {
 | 
|---|
| 390 |             *pgSubject = catGUID;
 | 
|---|
| 391 |             SetLastError(S_OK);
 | 
|---|
| 392 |             bRet = TRUE;
 | 
|---|
| 393 |             goto cleanup;
 | 
|---|
| 394 |         }
 | 
|---|
| 395 |         else if (hdr[1] == 0x80)
 | 
|---|
| 396 |         {
 | 
|---|
| 397 |             /* Indefinite length, can't verify with just the header, assume it
 | 
|---|
| 398 |              * is.
 | 
|---|
| 399 |              */
 | 
|---|
| 400 |             *pgSubject = catGUID;
 | 
|---|
| 401 |             SetLastError(S_OK);
 | 
|---|
| 402 |             bRet = TRUE;
 | 
|---|
| 403 |             goto cleanup;
 | 
|---|
| 404 |         }
 | 
|---|
| 405 |         else
 | 
|---|
| 406 |         {
 | 
|---|
| 407 |             BYTE lenBytes = hdr[1] & 0x7f;
 | 
|---|
| 408 | 
 | 
|---|
| 409 |             if (lenBytes == 1 && fileLen == 2 + lenBytes + hdr[2])
 | 
|---|
| 410 |             {
 | 
|---|
| 411 |                 *pgSubject = catGUID;
 | 
|---|
| 412 |                 SetLastError(S_OK);
 | 
|---|
| 413 |                 bRet = TRUE;
 | 
|---|
| 414 |                 goto cleanup;
 | 
|---|
| 415 |             }
 | 
|---|
| 416 |             else if (lenBytes == 2 && fileLen == 2 + lenBytes +
 | 
|---|
| 417 |              (hdr[2] << 8 | hdr[3]))
 | 
|---|
| 418 |             {
 | 
|---|
| 419 |                 *pgSubject = catGUID;
 | 
|---|
| 420 |                 SetLastError(S_OK);
 | 
|---|
| 421 |                 bRet = TRUE;
 | 
|---|
| 422 |                 goto cleanup;
 | 
|---|
| 423 |             }
 | 
|---|
| 424 |             else if (fileLen > 0xffff)
 | 
|---|
| 425 |             {
 | 
|---|
| 426 |                 /* The file size must be greater than 2 bytes in length, so
 | 
|---|
| 427 |                  * assume it is a .cat file
 | 
|---|
| 428 |                  */
 | 
|---|
| 429 |                 *pgSubject = catGUID;
 | 
|---|
| 430 |                 SetLastError(S_OK);
 | 
|---|
| 431 |                 bRet = TRUE;
 | 
|---|
| 432 |                 goto cleanup;
 | 
|---|
| 433 |             }
 | 
|---|
| 434 |         }
 | 
|---|
| 435 |     }
 | 
|---|
| 436 | 
 | 
|---|
| 437 |     /* Check for supported functions using CryptSIPDllIsMyFileType */
 | 
|---|
| 438 |     /* max length of szFullKey depends on our code only, so we won't overrun */
 | 
|---|
| 439 |     lstrcpyW(szFullKey, szOID);
 | 
|---|
| 440 |     lstrcatW(szFullKey, szIsMyFile);
 | 
|---|
| 441 |     r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
 | 
|---|
| 442 |     if (r == ERROR_SUCCESS)
 | 
|---|
| 443 |     {
 | 
|---|
| 444 |         DWORD index = 0, size;
 | 
|---|
| 445 |         WCHAR subKeyName[MAX_PATH];
 | 
|---|
| 446 | 
 | 
|---|
| 447 |         do {
 | 
|---|
| 448 |             size = sizeof(subKeyName) / sizeof(subKeyName[0]);
 | 
|---|
| 449 |             r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
 | 
|---|
| 450 |              NULL, NULL);
 | 
|---|
| 451 |             if (r == ERROR_SUCCESS)
 | 
|---|
| 452 |             {
 | 
|---|
| 453 |                 HKEY subKey;
 | 
|---|
| 454 | 
 | 
|---|
| 455 |                 r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
 | 
|---|
| 456 |                 if (r == ERROR_SUCCESS)
 | 
|---|
| 457 |                 {
 | 
|---|
| 458 |                     HMODULE lib;
 | 
|---|
| 459 |                     pfnIsFileSupported isMy =
 | 
|---|
| 460 |                        (pfnIsFileSupported)CRYPT_LoadSIPFuncFromKey(subKey, &lib);
 | 
|---|
| 461 | 
 | 
|---|
| 462 |                     if (isMy)
 | 
|---|
| 463 |                     {
 | 
|---|
| 464 |                         bRet = isMy(hFile, pgSubject);
 | 
|---|
| 465 |                         FreeLibrary(lib);
 | 
|---|
| 466 |                     }
 | 
|---|
| 467 |                     RegCloseKey(subKey);
 | 
|---|
| 468 |                 }
 | 
|---|
| 469 |             }
 | 
|---|
| 470 |         } while (!bRet && r == ERROR_SUCCESS);
 | 
|---|
| 471 |         RegCloseKey(key);
 | 
|---|
| 472 |     }
 | 
|---|
| 473 | 
 | 
|---|
| 474 |     /* Check for supported functions using CryptSIPDllIsMyFileType2 */
 | 
|---|
| 475 |     if (!bRet)
 | 
|---|
| 476 |     {
 | 
|---|
| 477 |         lstrcpyW(szFullKey, szOID);
 | 
|---|
| 478 |         lstrcatW(szFullKey, szIsMyFile2);
 | 
|---|
| 479 |         r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
 | 
|---|
| 480 |         if (r == ERROR_SUCCESS)
 | 
|---|
| 481 |         {
 | 
|---|
| 482 |             DWORD index = 0, size;
 | 
|---|
| 483 |             WCHAR subKeyName[MAX_PATH];
 | 
|---|
| 484 | 
 | 
|---|
| 485 |             do {
 | 
|---|
| 486 |                 size = sizeof(subKeyName) / sizeof(subKeyName[0]);
 | 
|---|
| 487 |                 r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
 | 
|---|
| 488 |                  NULL, NULL);
 | 
|---|
| 489 |                 if (r == ERROR_SUCCESS)
 | 
|---|
| 490 |                 {
 | 
|---|
| 491 |                     HKEY subKey;
 | 
|---|
| 492 | 
 | 
|---|
| 493 |                     r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
 | 
|---|
| 494 |                     if (r == ERROR_SUCCESS)
 | 
|---|
| 495 |                     {
 | 
|---|
| 496 |                         HMODULE lib;
 | 
|---|
| 497 |                         pfnIsFileSupportedName isMy2 = (pfnIsFileSupportedName)
 | 
|---|
| 498 |                          CRYPT_LoadSIPFuncFromKey(subKey, &lib);
 | 
|---|
| 499 | 
 | 
|---|
| 500 |                         if (isMy2)
 | 
|---|
| 501 |                         {
 | 
|---|
| 502 |                             bRet = isMy2((LPWSTR)FileName, pgSubject);
 | 
|---|
| 503 |                             FreeLibrary(lib);
 | 
|---|
| 504 |                         }
 | 
|---|
| 505 |                         RegCloseKey(subKey);
 | 
|---|
| 506 |                     }
 | 
|---|
| 507 |                 }
 | 
|---|
| 508 |             } while (!bRet && r == ERROR_SUCCESS);
 | 
|---|
| 509 |             RegCloseKey(key);
 | 
|---|
| 510 |         }
 | 
|---|
| 511 |     }
 | 
|---|
| 512 | 
 | 
|---|
| 513 |     if (!bRet)
 | 
|---|
| 514 |         SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
 | 
|---|
| 515 | 
 | 
|---|
| 516 | cleanup:
 | 
|---|
| 517 |     /* If we didn't open this one we shouldn't close it (hFile is a copy),
 | 
|---|
| 518 |      * but we should reset the file pointer to its original position.
 | 
|---|
| 519 |      */
 | 
|---|
| 520 |     if (!hFileIn)
 | 
|---|
| 521 |         CloseHandle(hFile);
 | 
|---|
| 522 |     else
 | 
|---|
| 523 |         SetFilePointerEx(hFile, oldPos, NULL, FILE_BEGIN);
 | 
|---|
| 524 | 
 | 
|---|
| 525 |     return bRet;
 | 
|---|
| 526 | }
 | 
|---|
| 527 | 
 | 
|---|
| 528 | static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function,
 | 
|---|
| 529 |  HKEY *key)
 | 
|---|
| 530 | {
 | 
|---|
| 531 |     WCHAR szFullKey[ 0x100 ];
 | 
|---|
| 532 | 
 | 
|---|
| 533 |     lstrcpyW(szFullKey, szOID);
 | 
|---|
| 534 |     lstrcatW(szFullKey, function);
 | 
|---|
| 535 |     CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]);
 | 
|---|
| 536 |     return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key);
 | 
|---|
| 537 | }
 | 
|---|
| 538 | 
 | 
|---|
| 539 | /* Loads the function named function for the SIP specified by pgSubject, and
 | 
|---|
| 540 |  * returns it if found.  Returns NULL on error.  If the function is loaded,
 | 
|---|
| 541 |  * *pLib is set to the library in which it is found.
 | 
|---|
| 542 |  */
 | 
|---|
| 543 | static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
 | 
|---|
| 544 |  HMODULE *pLib)
 | 
|---|
| 545 | {
 | 
|---|
| 546 |     LONG r;
 | 
|---|
| 547 |     HKEY key;
 | 
|---|
| 548 |     void *func = NULL;
 | 
|---|
| 549 | 
 | 
|---|
| 550 |     TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));
 | 
|---|
| 551 | 
 | 
|---|
| 552 |     r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
 | 
|---|
| 553 |     if (!r)
 | 
|---|
| 554 |     {
 | 
|---|
| 555 |         func = CRYPT_LoadSIPFuncFromKey(key, pLib);
 | 
|---|
| 556 |         RegCloseKey(key);
 | 
|---|
| 557 |     }
 | 
|---|
| 558 |     TRACE("returning %p\n", func);
 | 
|---|
| 559 |     return func;
 | 
|---|
| 560 | }
 | 
|---|
| 561 | 
 | 
|---|
| 562 | typedef struct _WINE_SIP_PROVIDER {
 | 
|---|
| 563 |     GUID              subject;
 | 
|---|
| 564 |     SIP_DISPATCH_INFO info;
 | 
|---|
| 565 |     struct list       entry;
 | 
|---|
| 566 | } WINE_SIP_PROVIDER;
 | 
|---|
| 567 | 
 | 
|---|
| 568 | static struct list providers = { &providers, &providers };
 | 
|---|
| 569 | static RTL_CRITICAL_SECTION providers_cs;
 | 
|---|
| 570 | static RTL_CRITICAL_SECTION_DEBUG providers_cs_debug =
 | 
|---|
| 571 | {
 | 
|---|
| 572 | #ifndef __WIN32OS2__
 | 
|---|
| 573 |     0, 0, &providers_cs,
 | 
|---|
| 574 |     { &providers_cs_debug.ProcessLocksList,
 | 
|---|
| 575 |     &providers_cs_debug.ProcessLocksList },
 | 
|---|
| 576 |     0, 0, { (DWORD)(DWORD_PTR)(__FILE__ ": providers_cs") }
 | 
|---|
| 577 | #endif
 | 
|---|
| 578 | };
 | 
|---|
| 579 | static RTL_CRITICAL_SECTION providers_cs = { &providers_cs_debug, -1, 0, 0, 0, 0 };
 | 
|---|
| 580 | 
 | 
|---|
| 581 | static void CRYPT_CacheSIP(const GUID *pgSubject, SIP_DISPATCH_INFO *info)
 | 
|---|
| 582 | {
 | 
|---|
| 583 |     WINE_SIP_PROVIDER *prov = CryptMemAlloc(sizeof(WINE_SIP_PROVIDER));
 | 
|---|
| 584 | 
 | 
|---|
| 585 |     if (prov)
 | 
|---|
| 586 |     {
 | 
|---|
| 587 |         prov->subject = *pgSubject;
 | 
|---|
| 588 |         prov->info = *info;
 | 
|---|
| 589 |         EnterCriticalSection((CRITICAL_SECTION*)&providers_cs);
 | 
|---|
| 590 |         list_add_tail(&providers, &prov->entry);
 | 
|---|
| 591 |         LeaveCriticalSection((CRITICAL_SECTION*)&providers_cs);
 | 
|---|
| 592 |     }
 | 
|---|
| 593 | }
 | 
|---|
| 594 | 
 | 
|---|
| 595 | static WINE_SIP_PROVIDER *CRYPT_GetCachedSIP(const GUID *pgSubject)
 | 
|---|
| 596 | {
 | 
|---|
| 597 |     WINE_SIP_PROVIDER *provider = NULL, *ret = NULL;
 | 
|---|
| 598 | 
 | 
|---|
| 599 |     EnterCriticalSection((CRITICAL_SECTION*)&providers_cs);
 | 
|---|
| 600 |     LIST_FOR_EACH_ENTRY(provider, &providers, WINE_SIP_PROVIDER, entry)
 | 
|---|
| 601 |     {
 | 
|---|
| 602 |         if (IsEqualGUID(pgSubject, &provider->subject))
 | 
|---|
| 603 |             break;
 | 
|---|
| 604 |     }
 | 
|---|
| 605 |     if (provider && IsEqualGUID(pgSubject, &provider->subject))
 | 
|---|
| 606 |         ret = provider;
 | 
|---|
| 607 |     LeaveCriticalSection((CRITICAL_SECTION*)&providers_cs);
 | 
|---|
| 608 |     return ret;
 | 
|---|
| 609 | }
 | 
|---|
| 610 | 
 | 
|---|
| 611 | static inline BOOL CRYPT_IsSIPCached(const GUID *pgSubject)
 | 
|---|
| 612 | {
 | 
|---|
| 613 |     return CRYPT_GetCachedSIP(pgSubject) != NULL;
 | 
|---|
| 614 | }
 | 
|---|
| 615 | 
 | 
|---|
| 616 | void crypt_sip_free(void)
 | 
|---|
| 617 | {
 | 
|---|
| 618 |     WINE_SIP_PROVIDER *prov, *next;
 | 
|---|
| 619 | 
 | 
|---|
| 620 |     LIST_FOR_EACH_ENTRY_SAFE(prov, next, &providers, WINE_SIP_PROVIDER, entry)
 | 
|---|
| 621 |     {
 | 
|---|
| 622 |         list_remove(&prov->entry);
 | 
|---|
| 623 |         FreeLibrary(prov->info.hSIP);
 | 
|---|
| 624 |         CryptMemFree(prov);
 | 
|---|
| 625 |     }
 | 
|---|
| 626 | }
 | 
|---|
| 627 | 
 | 
|---|
| 628 | /* Loads the SIP for pgSubject into the global cache.  Returns FALSE if the
 | 
|---|
| 629 |  * SIP isn't registered or is invalid.
 | 
|---|
| 630 |  */
 | 
|---|
| 631 | static BOOL CRYPT_LoadSIP(const GUID *pgSubject)
 | 
|---|
| 632 | {
 | 
|---|
| 633 |     SIP_DISPATCH_INFO sip = { 0 };
 | 
|---|
| 634 |     HMODULE lib = NULL, temp = NULL;
 | 
|---|
| 635 | 
 | 
|---|
| 636 |     sip.pfGet = (pCryptSIPGetSignedDataMsg)CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib);
 | 
|---|
| 637 |     if (!sip.pfGet)
 | 
|---|
| 638 |         goto error;
 | 
|---|
| 639 |     sip.pfPut = (pCryptSIPPutSignedDataMsg)CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp);
 | 
|---|
| 640 |     if (!sip.pfPut || temp != lib)
 | 
|---|
| 641 |         goto error;
 | 
|---|
| 642 |     FreeLibrary(temp);
 | 
|---|
| 643 |     sip.pfCreate = (pCryptSIPCreateIndirectData)CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp);
 | 
|---|
| 644 |     if (!sip.pfCreate || temp != lib)
 | 
|---|
| 645 |         goto error;
 | 
|---|
| 646 |     FreeLibrary(temp);
 | 
|---|
| 647 |     sip.pfVerify = (pCryptSIPVerifyIndirectData)CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp);
 | 
|---|
| 648 |     if (!sip.pfVerify || temp != lib)
 | 
|---|
| 649 |         goto error;
 | 
|---|
| 650 |     FreeLibrary(temp);
 | 
|---|
| 651 |     sip.pfRemove = (pCryptSIPRemoveSignedDataMsg)CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp);
 | 
|---|
| 652 |     if (!sip.pfRemove || temp != lib)
 | 
|---|
| 653 |         goto error;
 | 
|---|
| 654 |     FreeLibrary(temp);
 | 
|---|
| 655 |     sip.hSIP = lib;
 | 
|---|
| 656 |     CRYPT_CacheSIP(pgSubject, &sip);
 | 
|---|
| 657 |     return TRUE;
 | 
|---|
| 658 | 
 | 
|---|
| 659 | error:
 | 
|---|
| 660 |     FreeLibrary(lib);
 | 
|---|
| 661 |     FreeLibrary(temp);
 | 
|---|
| 662 |     SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
 | 
|---|
| 663 |     return FALSE;
 | 
|---|
| 664 | }
 | 
|---|
| 665 | 
 | 
|---|
| 666 | /***********************************************************************
 | 
|---|
| 667 |  *             CryptSIPLoad (CRYPT32.@)
 | 
|---|
| 668 |  *
 | 
|---|
| 669 |  * Load some internal crypt32 functions into a SIP_DISPATCH_INFO structure.
 | 
|---|
| 670 |  *
 | 
|---|
| 671 |  * PARAMS
 | 
|---|
| 672 |  *  pgSubject    [I] The GUID.
 | 
|---|
| 673 |  *  dwFlags      [I] Flags.
 | 
|---|
| 674 |  *  pSipDispatch [I] The loaded functions.
 | 
|---|
| 675 |  *
 | 
|---|
| 676 |  * RETURNS
 | 
|---|
| 677 |  *  Success: TRUE. pSipDispatch contains the functions.
 | 
|---|
| 678 |  *  Failure: FALSE. (Look at GetLastError()).
 | 
|---|
| 679 |  *
 | 
|---|
| 680 |  * NOTES
 | 
|---|
| 681 |  *  CryptSIPLoad uses caching for the list of GUIDs and whether a SIP is
 | 
|---|
| 682 |  *  already loaded.
 | 
|---|
| 683 |  *
 | 
|---|
| 684 |  *  An application calls CryptSipLoad which will return a structure with the
 | 
|---|
| 685 |  *  function addresses of some internal crypt32 functions. The application will
 | 
|---|
| 686 |  *  then call these functions which will be forwarded to the appropriate SIP.
 | 
|---|
| 687 |  *
 | 
|---|
| 688 |  *  CryptSIPLoad will load the needed SIP but doesn't unload this dll. The unloading
 | 
|---|
| 689 |  *  is done when crypt32 is unloaded.
 | 
|---|
| 690 |  */
 | 
|---|
| 691 | BOOL WINAPI CryptSIPLoad
 | 
|---|
| 692 |        (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
 | 
|---|
| 693 | {
 | 
|---|
| 694 |     TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
 | 
|---|
| 695 | 
 | 
|---|
| 696 |     if (!pgSubject || dwFlags != 0 || !pSipDispatch)
 | 
|---|
| 697 |     {
 | 
|---|
| 698 |         SetLastError(ERROR_INVALID_PARAMETER);
 | 
|---|
| 699 |         return FALSE;
 | 
|---|
| 700 |     }
 | 
|---|
| 701 |     if (!CRYPT_IsSIPCached(pgSubject) && !CRYPT_LoadSIP(pgSubject))
 | 
|---|
| 702 |         return FALSE;
 | 
|---|
| 703 | 
 | 
|---|
| 704 |     pSipDispatch->hSIP = NULL;
 | 
|---|
| 705 |     pSipDispatch->pfGet = CryptSIPGetSignedDataMsg;
 | 
|---|
| 706 |     pSipDispatch->pfPut = CryptSIPPutSignedDataMsg;
 | 
|---|
| 707 |     pSipDispatch->pfCreate = CryptSIPCreateIndirectData;
 | 
|---|
| 708 |     pSipDispatch->pfVerify = CryptSIPVerifyIndirectData;
 | 
|---|
| 709 |     pSipDispatch->pfRemove = CryptSIPRemoveSignedDataMsg;
 | 
|---|
| 710 | 
 | 
|---|
| 711 |     return TRUE;
 | 
|---|
| 712 | }
 | 
|---|
| 713 | 
 | 
|---|
| 714 | /***********************************************************************
 | 
|---|
| 715 |  *             CryptSIPCreateIndirectData (CRYPT32.@)
 | 
|---|
| 716 |  */
 | 
|---|
| 717 | BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
 | 
|---|
| 718 |                                        SIP_INDIRECT_DATA* pIndirectData)
 | 
|---|
| 719 | {
 | 
|---|
| 720 |     WINE_SIP_PROVIDER *sip;
 | 
|---|
| 721 |     BOOL ret = FALSE;
 | 
|---|
| 722 | 
 | 
|---|
| 723 |     TRACE("(%p %p %p)\n", pSubjectInfo, pcbIndirectData, pIndirectData);
 | 
|---|
| 724 | 
 | 
|---|
| 725 |     if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)) != NULL)
 | 
|---|
| 726 |         ret = sip->info.pfCreate(pSubjectInfo, pcbIndirectData, pIndirectData);
 | 
|---|
| 727 |     TRACE("returning %d\n", ret);
 | 
|---|
| 728 |     return ret;
 | 
|---|
| 729 | }
 | 
|---|
| 730 | 
 | 
|---|
| 731 | /***********************************************************************
 | 
|---|
| 732 |  *             CryptSIPGetSignedDataMsg (CRYPT32.@)
 | 
|---|
| 733 |  */
 | 
|---|
| 734 | BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
 | 
|---|
| 735 |                                        DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
 | 
|---|
| 736 | {
 | 
|---|
| 737 |     WINE_SIP_PROVIDER *sip;
 | 
|---|
| 738 |     BOOL ret = FALSE;
 | 
|---|
| 739 | 
 | 
|---|
| 740 |     TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
 | 
|---|
| 741 |           pcbSignedDataMsg, pbSignedDataMsg);
 | 
|---|
| 742 | 
 | 
|---|
| 743 |     if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)) != NULL)
 | 
|---|
| 744 |         ret = sip->info.pfGet(pSubjectInfo, pdwEncodingType, dwIndex,
 | 
|---|
| 745 |          pcbSignedDataMsg, pbSignedDataMsg);
 | 
|---|
| 746 |     TRACE("returning %d\n", ret);
 | 
|---|
| 747 |     return ret;
 | 
|---|
| 748 | }
 | 
|---|
| 749 | 
 | 
|---|
| 750 | /***********************************************************************
 | 
|---|
| 751 |  *             CryptSIPPutSignedDataMsg (CRYPT32.@)
 | 
|---|
| 752 |  */
 | 
|---|
| 753 | BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
 | 
|---|
| 754 |                                        DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
 | 
|---|
| 755 | {
 | 
|---|
| 756 |     WINE_SIP_PROVIDER *sip;
 | 
|---|
| 757 |     BOOL ret = FALSE;
 | 
|---|
| 758 | 
 | 
|---|
| 759 |     TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
 | 
|---|
| 760 |           cbSignedDataMsg, pbSignedDataMsg);
 | 
|---|
| 761 | 
 | 
|---|
| 762 |     if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)) != NULL)
 | 
|---|
| 763 |         ret = sip->info.pfPut(pSubjectInfo, pdwEncodingType, pdwIndex,
 | 
|---|
| 764 |          cbSignedDataMsg, pbSignedDataMsg);
 | 
|---|
| 765 |     TRACE("returning %d\n", ret);
 | 
|---|
| 766 |     return ret;
 | 
|---|
| 767 | }
 | 
|---|
| 768 | 
 | 
|---|
| 769 | /***********************************************************************
 | 
|---|
| 770 |  *             CryptSIPRemoveSignedDataMsg (CRYPT32.@)
 | 
|---|
| 771 |  */
 | 
|---|
| 772 | BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
 | 
|---|
| 773 |                                        DWORD dwIndex)
 | 
|---|
| 774 | {
 | 
|---|
| 775 |     WINE_SIP_PROVIDER *sip;
 | 
|---|
| 776 |     BOOL ret = FALSE;
 | 
|---|
| 777 | 
 | 
|---|
| 778 |     TRACE("(%p %d)\n", pSubjectInfo, dwIndex);
 | 
|---|
| 779 | 
 | 
|---|
| 780 |     if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)) != NULL)
 | 
|---|
| 781 |         ret = sip->info.pfRemove(pSubjectInfo, dwIndex);
 | 
|---|
| 782 |     TRACE("returning %d\n", ret);
 | 
|---|
| 783 |     return ret;
 | 
|---|
| 784 | }
 | 
|---|
| 785 | 
 | 
|---|
| 786 | /***********************************************************************
 | 
|---|
| 787 |  *             CryptSIPVerifyIndirectData (CRYPT32.@)
 | 
|---|
| 788 |  */
 | 
|---|
| 789 | BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
 | 
|---|
| 790 |                                        SIP_INDIRECT_DATA* pIndirectData)
 | 
|---|
| 791 | {
 | 
|---|
| 792 |     WINE_SIP_PROVIDER *sip;
 | 
|---|
| 793 |     BOOL ret = FALSE;
 | 
|---|
| 794 | 
 | 
|---|
| 795 |     TRACE("(%p %p)\n", pSubjectInfo, pIndirectData);
 | 
|---|
| 796 | 
 | 
|---|
| 797 |     if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)) != NULL)
 | 
|---|
| 798 |         ret = sip->info.pfVerify(pSubjectInfo, pIndirectData);
 | 
|---|
| 799 |     TRACE("returning %d\n", ret);
 | 
|---|
| 800 |     return ret;
 | 
|---|
| 801 | }
 | 
|---|