source: trunk/src/crypt32/sip.c@ 21311

Last change on this file since 21311 was 21311, checked in by vladest, 16 years ago

Added CRYPT32 and MSCMS APIs support

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