Revert "winex11.drv: Optimise getting the bits of a DIB after calling SetDIBits."
[wine] / dlls / wintrust / wintrust_main.c
1 /*
2  * Copyright 2001 Rein Klazes
3  * Copyright 2007 Juan Lang
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "config.h"
21
22 #include <stdarg.h>
23
24 #define NONAMELESSUNION
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "winreg.h"
30 #include "guiddef.h"
31 #include "wintrust.h"
32 #include "softpub.h"
33 #include "mscat.h"
34 #include "objbase.h"
35 #include "winuser.h"
36 #include "wintrust_priv.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
40
41
42 /***********************************************************************
43  *              DllMain  (WINTRUST.@)
44  */
45 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
46 {
47     switch(reason)
48     {
49     case DLL_PROCESS_ATTACH:
50         DisableThreadLibraryCalls( inst );
51         break;
52     }
53     return TRUE;
54 }
55
56 /***********************************************************************
57  *              TrustIsCertificateSelfSigned (WINTRUST.@)
58  */
59 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
60 {
61     BOOL ret;
62
63     TRACE("%p\n", cert);
64     ret = CertCompareCertificateName(cert->dwCertEncodingType,
65      &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
66     return ret;
67 }
68
69 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
70  WINTRUST_DATA *data)
71 {
72     DWORD err = ERROR_SUCCESS;
73     CRYPT_PROVIDER_DATA *provData;
74     BOOL ret;
75
76     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
77
78     provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
79     if (!provData)
80         goto oom;
81     provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
82
83     provData->padwTrustStepErrors =
84      WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
85     if (!provData->padwTrustStepErrors)
86         goto oom;
87     provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
88
89     provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
90     if (!provData->u.pPDSip)
91         goto oom;
92     provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP);
93
94     provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
95     if (!provData->psPfns)
96         goto oom;
97     provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
98     ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
99     if (!ret)
100     {
101         err = GetLastError();
102         goto error;
103     }
104
105     data->hWVTStateData = (HANDLE)provData;
106     provData->pWintrustData = data;
107     if (hwnd == INVALID_HANDLE_VALUE)
108         provData->hWndParent = GetDesktopWindow();
109     else
110         provData->hWndParent = hwnd;
111     provData->pgActionID = actionID;
112     WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
113
114     if (provData->psPfns->pfnInitialize)
115     {
116         err = provData->psPfns->pfnInitialize(provData);
117         if (err)
118             goto done;
119     }
120     if (provData->psPfns->pfnObjectTrust)
121     {
122         err = provData->psPfns->pfnObjectTrust(provData);
123         if (err)
124             goto done;
125     }
126     if (provData->psPfns->pfnSignatureTrust)
127     {
128         err = provData->psPfns->pfnSignatureTrust(provData);
129         if (err)
130             goto done;
131     }
132     if (provData->psPfns->pfnCertificateTrust)
133     {
134         err = provData->psPfns->pfnCertificateTrust(provData);
135         if (err)
136             goto done;
137     }
138     if (provData->psPfns->pfnFinalPolicy)
139         err = provData->psPfns->pfnFinalPolicy(provData);
140     goto done;
141
142 oom:
143     err = ERROR_OUTOFMEMORY;
144 error:
145     if (provData)
146     {
147         WINTRUST_Free(provData->padwTrustStepErrors);
148         WINTRUST_Free(provData->u.pPDSip);
149         WINTRUST_Free(provData->psPfns);
150         WINTRUST_Free(provData);
151     }
152 done:
153     TRACE("returning %08x\n", err);
154     return err;
155 }
156
157 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
158  WINTRUST_DATA *data)
159 {
160     DWORD err = ERROR_SUCCESS;
161     CRYPT_PROVIDER_DATA *provData = (CRYPT_PROVIDER_DATA *)data->hWVTStateData;
162
163     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
164
165     if (provData)
166     {
167         if (provData->psPfns->pfnCleanupPolicy)
168             err = provData->psPfns->pfnCleanupPolicy(provData);
169
170         WINTRUST_Free(provData->padwTrustStepErrors);
171         WINTRUST_Free(provData->u.pPDSip);
172         WINTRUST_Free(provData->psPfns);
173         WINTRUST_Free(provData);
174         data->hWVTStateData = NULL;
175     }
176     TRACE("returning %08x\n", err);
177     return err;
178 }
179
180 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
181  WINTRUST_DATA *data)
182 {
183     LONG err;
184
185     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
186
187     err = WINTRUST_DefaultVerify(hwnd, actionID, data);
188     WINTRUST_DefaultClose(hwnd, actionID, data);
189     TRACE("returning %08x\n", err);
190     return err;
191 }
192
193 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
194  WINTRUST_DATA *data)
195 {
196     WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
197     /* Undocumented: the published software action is passed a path,
198      * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
199      */
200     LPWIN_TRUST_SUBJECT_FILE subjectFile =
201      (LPWIN_TRUST_SUBJECT_FILE)data->pSIPClientData;
202     WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
203
204     TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
205     TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
206     fileInfo.pcwszFilePath = subjectFile->lpPath;
207     fileInfo.hFile = subjectFile->hFile;
208     wintrust_data.u.pFile = &fileInfo;
209     wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
210     wintrust_data.dwUIChoice = WTD_UI_NONE;
211
212     return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
213 }
214
215 static void dump_file_info(WINTRUST_FILE_INFO *pFile)
216 {
217     TRACE("%p\n", pFile);
218     if (pFile)
219     {
220         TRACE("cbStruct: %d\n", pFile->cbStruct);
221         TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath));
222         TRACE("hFile: %p\n", pFile->hFile);
223         TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject));
224     }
225 }
226
227 static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog)
228 {
229     TRACE("%p\n", catalog);
230     if (catalog)
231     {
232         TRACE("cbStruct: %d\n", catalog->cbStruct);
233         TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion);
234         TRACE("pcwszCatalogFilePath: %s\n",
235          debugstr_w(catalog->pcwszCatalogFilePath));
236         TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag));
237         TRACE("pcwszMemberFilePath: %s\n",
238          debugstr_w(catalog->pcwszMemberFilePath));
239         TRACE("hMemberFile: %p\n", catalog->hMemberFile);
240         TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash);
241         TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash);
242         TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext);
243     }
244 }
245
246 static void dump_blob_info(WINTRUST_BLOB_INFO *blob)
247 {
248     TRACE("%p\n", blob);
249     if (blob)
250     {
251         TRACE("cbStruct: %d\n", blob->cbStruct);
252         TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject));
253         TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName));
254         TRACE("cbMemObject: %d\n", blob->cbMemObject);
255         TRACE("pbMemObject: %p\n", blob->pbMemObject);
256         TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg);
257         TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg);
258     }
259 }
260
261 static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr)
262 {
263     TRACE("%p\n", sgnr);
264     if (sgnr)
265     {
266         TRACE("cbStruct: %d\n", sgnr->cbStruct);
267         TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName));
268         TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo);
269         TRACE("chStores: %d\n", sgnr->chStores);
270     }
271 }
272
273 static void dump_cert_info(WINTRUST_CERT_INFO *cert)
274 {
275     TRACE("%p\n", cert);
276     if (cert)
277     {
278         TRACE("cbStruct: %d\n", cert->cbStruct);
279         TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName));
280         TRACE("psCertContext: %p\n", cert->psCertContext);
281         TRACE("chStores: %d\n", cert->chStores);
282         TRACE("dwFlags: %08x\n", cert->dwFlags);
283         TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf);
284     }
285 }
286
287 static void dump_wintrust_data(WINTRUST_DATA *data)
288 {
289     TRACE("%p\n", data);
290     if (data)
291     {
292         TRACE("cbStruct: %d\n", data->cbStruct);
293         TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData);
294         TRACE("pSIPClientData: %p\n", data->pSIPClientData);
295         TRACE("dwUIChoice: %d\n", data->dwUIChoice);
296         TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks);
297         TRACE("dwUnionChoice: %d\n", data->dwUnionChoice);
298         switch (data->dwUnionChoice)
299         {
300         case WTD_CHOICE_FILE:
301             dump_file_info(data->u.pFile);
302             break;
303         case WTD_CHOICE_CATALOG:
304             dump_catalog_info(data->u.pCatalog);
305             break;
306         case WTD_CHOICE_BLOB:
307             dump_blob_info(data->u.pBlob);
308             break;
309         case WTD_CHOICE_SIGNER:
310             dump_sgnr_info(data->u.pSgnr);
311             break;
312         case WTD_CHOICE_CERT:
313             dump_cert_info(data->u.pCert);
314             break;
315         }
316         TRACE("dwStateAction: %d\n", data->dwStateAction);
317         TRACE("hWVTStateData: %p\n", data->hWVTStateData);
318         TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference));
319         TRACE("dwProvFlags: %08x\n", data->dwProvFlags);
320         TRACE("dwUIContext: %d\n", data->dwUIContext);
321     }
322 }
323
324 /***********************************************************************
325  *              WinVerifyTrust (WINTRUST.@)
326  *
327  * Verifies an object by calling the specified trust provider.
328  *
329  * PARAMS
330  *   hwnd       [I] Handle to a caller window.
331  *   ActionID   [I] Pointer to a GUID that identifies the action to perform.
332  *   ActionData [I] Information used by the trust provider to verify the object.
333  *
334  * RETURNS
335  *   Success: Zero.
336  *   Failure: A TRUST_E_* error code.
337  *
338  * NOTES
339  *   Trust providers can be found at:
340  *   HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
341  */
342 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
343 {
344     static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
345      0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
346     static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
347     static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
348     static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
349     static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
350     LONG err = ERROR_SUCCESS;
351     WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
352
353     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
354     dump_wintrust_data(ActionData);
355
356     /* Support for known old-style callers: */
357     if (IsEqualGUID(ActionID, &published_software))
358         err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
359     else
360     {
361         /* Check known actions to warn of possible problems */
362         if (!IsEqualGUID(ActionID, &unknown) &&
363          !IsEqualGUID(ActionID, &generic_verify_v2) &&
364          !IsEqualGUID(ActionID, &generic_cert_verify) &&
365          !IsEqualGUID(ActionID, &generic_chain_verify))
366             WARN("unknown action %s, default behavior may not be right\n",
367              debugstr_guid(ActionID));
368         switch (actionData->dwStateAction)
369         {
370         case WTD_STATEACTION_IGNORE:
371             err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
372             break;
373         case WTD_STATEACTION_VERIFY:
374             err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
375             break;
376         case WTD_STATEACTION_CLOSE:
377             err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
378             break;
379         default:
380             FIXME("unimplemented for %d\n", actionData->dwStateAction);
381         }
382     }
383
384     TRACE("returning %08x\n", err);
385     return err;
386 }
387
388 /***********************************************************************
389  *              WinVerifyTrustEx (WINTRUST.@)
390  */
391 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
392  WINTRUST_DATA* ActionData )
393 {
394     return WinVerifyTrust(hwnd, ActionID, ActionData);
395 }
396
397 /***********************************************************************
398  *              WTHelperGetProvSignerFromChain (WINTRUST.@)
399  */
400 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
401  CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
402  DWORD idxCounterSigner)
403 {
404     CRYPT_PROVIDER_SGNR *sgnr;
405
406     TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
407      idxCounterSigner);
408
409     if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
410         return NULL;
411     sgnr = &pProvData->pasSigners[idxSigner];
412     if (fCounterSigner)
413     {
414         if (idxCounterSigner >= sgnr->csCounterSigners ||
415          !sgnr->pasCounterSigners)
416             return NULL;
417         sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
418     }
419     TRACE("returning %p\n", sgnr);
420     return sgnr;
421 }
422
423 /***********************************************************************
424  *              WTHelperGetProvCertFromChain (WINTRUST.@)
425  */
426 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
427  CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
428 {
429     CRYPT_PROVIDER_CERT *cert;
430
431     TRACE("(%p %d)\n", pSgnr, idxCert);
432
433     if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
434         return NULL;
435     cert = &pSgnr->pasCertChain[idxCert];
436     TRACE("returning %p\n", cert);
437     return cert;
438 }
439
440 CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain(
441  CRYPT_PROVIDER_DATA* pProvData,
442  GUID* pgProviderID)
443 {
444     CRYPT_PROVIDER_PRIVDATA *privdata = NULL;
445     DWORD i;
446
447     TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID));
448
449     for (i = 0; i < pProvData->csProvPrivData; i++)
450         if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID))
451         {
452             privdata = &pProvData->pasProvPrivData[i];
453             break;
454         }
455
456     return privdata;
457 }
458
459 /***********************************************************************
460  *              WTHelperProvDataFromStateData (WINTRUST.@)
461  */
462 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
463 {
464     TRACE("%p\n", hStateData);
465     return (CRYPT_PROVIDER_DATA *)hStateData;
466 }
467
468 /***********************************************************************
469  *              WTHelperGetFileName(WINTRUST.@)
470  */
471 LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data)
472 {
473     TRACE("%p\n",data);
474     if (data->dwUnionChoice == WTD_CHOICE_FILE)
475         return data->u.pFile->pcwszFilePath;
476     else
477         return NULL;
478 }
479
480 /***********************************************************************
481  *              WTHelperGetFileHandle(WINTRUST.@)
482  */
483 HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
484 {
485     TRACE("%p\n",data);
486     if (data->dwUnionChoice == WTD_CHOICE_FILE)
487         return data->u.pFile->hFile;
488     else
489         return INVALID_HANDLE_VALUE;
490 }
491
492 static const WCHAR Software_Publishing[] = {
493  'S','o','f','t','w','a','r','e','\\',
494  'M','i','c','r','o','s','o','f','t','\\',
495  'W','i','n','d','o','w','s','\\',
496  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
497  'W','i','n','t','r','u','s','t','\\',
498  'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
499  'S','o','f','t','w','a','r','e',' ',
500  'P','u','b','l','i','s','h','i','n','g',0 };
501 static const WCHAR State[] = { 'S','t','a','t','e',0 };
502
503 /***********************************************************************
504  *              WintrustGetRegPolicyFlags (WINTRUST.@)
505  */
506 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
507 {
508     HKEY key;
509     LONG r;
510
511     TRACE("%p\n", pdwPolicyFlags);
512
513     *pdwPolicyFlags = 0;
514     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
515      KEY_READ, NULL, &key, NULL);
516     if (!r)
517     {
518         DWORD size = sizeof(DWORD);
519
520         r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
521          &size);
522         RegCloseKey(key);
523         if (r)
524         {
525             /* Failed to query, create and return default value */
526             *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
527              WTPF_OFFLINEOKNBU_COM |
528              WTPF_OFFLINEOKNBU_IND |
529              WTPF_OFFLINEOK_COM |
530              WTPF_OFFLINEOK_IND;
531             WintrustSetRegPolicyFlags(*pdwPolicyFlags);
532         }
533     }
534 }
535
536 /***********************************************************************
537  *              WintrustSetRegPolicyFlags (WINTRUST.@)
538  */
539 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
540 {
541     HKEY key;
542     LONG r;
543
544     TRACE("%x\n", dwPolicyFlags);
545
546     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
547      NULL, 0, KEY_WRITE, NULL, &key, NULL);
548     if (!r)
549     {
550         r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
551          sizeof(DWORD));
552         RegCloseKey(key);
553     }
554     if (r) SetLastError(r);
555     return r == ERROR_SUCCESS;
556 }
557
558 /* Utility functions */
559 void * WINAPI WINTRUST_Alloc(DWORD cb)
560 {
561     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
562 }
563
564 void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
565 {
566     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
567 }
568
569 void WINAPI WINTRUST_Free(void *p)
570 {
571     HeapFree(GetProcessHeap(), 0, p);
572 }
573
574 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
575 {
576     BOOL ret = FALSE;
577
578     if (data->chStores)
579         data->pahStores = WINTRUST_ReAlloc(data->pahStores,
580          (data->chStores + 1) * sizeof(HCERTSTORE));
581     else
582     {
583         data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
584         data->chStores = 0;
585     }
586     if (data->pahStores)
587     {
588         data->pahStores[data->chStores++] = CertDuplicateStore(store);
589         ret = TRUE;
590     }
591     else
592         SetLastError(ERROR_OUTOFMEMORY);
593     return ret;
594 }
595
596 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
597  BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
598 {
599     BOOL ret = FALSE;
600
601     if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
602     {
603         SetLastError(ERROR_INVALID_PARAMETER);
604         return FALSE;
605     }
606     if (fCounterSigner)
607     {
608         FIXME("unimplemented for counter signers\n");
609         SetLastError(ERROR_INVALID_PARAMETER);
610         return FALSE;
611     }
612     if (data->csSigners)
613         data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
614          (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
615     else
616     {
617         data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
618         data->csSigners = 0;
619     }
620     if (data->pasSigners)
621     {
622         if (idxSigner < data->csSigners)
623             memmove(&data->pasSigners[idxSigner],
624              &data->pasSigners[idxSigner + 1],
625              (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
626         ret = TRUE;
627         if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
628         {
629             /* The PSDK says psSigner should be allocated using pfnAlloc, but
630              * it doesn't say anything about ownership.  Since callers are
631              * internal, assume ownership is passed, and just store the
632              * pointer.
633              */
634             memcpy(&data->pasSigners[idxSigner], sgnr,
635              sizeof(CRYPT_PROVIDER_SGNR));
636         }
637         else
638             memset(&data->pasSigners[idxSigner], 0,
639              sizeof(CRYPT_PROVIDER_SGNR));
640         data->csSigners++;
641     }
642     else
643         SetLastError(ERROR_OUTOFMEMORY);
644     return ret;
645 }
646
647 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
648  BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
649 {
650     BOOL ret = FALSE;
651
652     if (fCounterSigner)
653     {
654         FIXME("unimplemented for counter signers\n");
655         SetLastError(ERROR_INVALID_PARAMETER);
656         return FALSE;
657     }
658     if (data->pasSigners[idxSigner].csCertChain)
659         data->pasSigners[idxSigner].pasCertChain =
660          WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
661          (data->pasSigners[idxSigner].csCertChain + 1) *
662          sizeof(CRYPT_PROVIDER_CERT));
663     else
664     {
665         data->pasSigners[idxSigner].pasCertChain =
666          WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
667         data->pasSigners[idxSigner].csCertChain = 0;
668     }
669     if (data->pasSigners[idxSigner].pasCertChain)
670     {
671         CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
672          data->pasSigners[idxSigner].csCertChain];
673
674         cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
675         cert->pCert = CertDuplicateCertificateContext(pCert2Add);
676         data->pasSigners[idxSigner].csCertChain++;
677         ret = TRUE;
678     }
679     else
680         SetLastError(ERROR_OUTOFMEMORY);
681     return ret;
682 }
683
684 BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
685  CRYPT_PROVIDER_PRIVDATA *pPrivData2Add)
686 {
687     BOOL ret = FALSE;
688
689     TRACE("(%p, %p)\n", data, pPrivData2Add);
690
691     if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA))
692     {
693         SetLastError(ERROR_INVALID_PARAMETER);
694         WARN("invalid struct size\n");
695         return FALSE;
696     }
697     if (data->csProvPrivData)
698         data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData,
699          (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR));
700     else
701     {
702         data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
703         data->csProvPrivData = 0;
704     }
705     if (data->pasProvPrivData)
706     {
707         DWORD i;
708
709         for (i = 0; i < data->csProvPrivData; i++)
710             if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i]))
711                 break;
712
713         data->pasProvPrivData[i] = *pPrivData2Add;
714         if (i == data->csProvPrivData)
715             data->csProvPrivData++;
716     }
717     else
718         SetLastError(ERROR_OUTOFMEMORY);
719     return ret;
720 }