push 8edcbf8579c1d48dd3fb4c679acf4b3012a9efac
[wine/hacks.git] / dlls / wintrust / wintrust_main.c
blobed6a8ed9af3d3140b96e0151a37611b5e0b971ec
1 /*
2 * Copyright 2001 Rein Klazes
3 * Copyright 2007 Juan Lang
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.
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.
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
20 #include "config.h"
22 #include <stdarg.h>
24 #define NONAMELESSUNION
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"
39 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
42 /***********************************************************************
43 * DllMain (WINTRUST.@)
45 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
47 switch(reason)
49 case DLL_PROCESS_ATTACH:
50 DisableThreadLibraryCalls( inst );
51 break;
53 return TRUE;
56 /***********************************************************************
57 * TrustIsCertificateSelfSigned (WINTRUST.@)
59 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
61 BOOL ret;
63 TRACE("%p\n", cert);
64 ret = CertCompareCertificateName(cert->dwCertEncodingType,
65 &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
66 return ret;
69 typedef HRESULT (WINAPI *wintrust_step_func)(CRYPT_PROVIDER_DATA *data);
71 struct wintrust_step
73 wintrust_step_func func;
74 DWORD error_index;
77 static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps,
78 DWORD numSteps, CRYPT_PROVIDER_DATA *provData)
80 DWORD i, err = ERROR_SUCCESS;
82 for (i = 0; !err && i < numSteps; i++)
84 err = steps[i].func(provData);
85 if (err)
86 err = provData->padwTrustStepErrors[steps[i].error_index];
88 return err;
91 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
92 WINTRUST_DATA *data)
94 DWORD err = ERROR_SUCCESS, numSteps = 0;
95 CRYPT_PROVIDER_DATA *provData;
96 BOOL ret;
97 struct wintrust_step verifySteps[5];
99 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
101 provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
102 if (!provData)
103 goto oom;
104 provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
106 provData->padwTrustStepErrors =
107 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
108 if (!provData->padwTrustStepErrors)
109 goto oom;
110 provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
112 provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
113 if (!provData->u.pPDSip)
114 goto oom;
115 provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP);
117 provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
118 if (!provData->psPfns)
119 goto oom;
120 provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
121 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
122 if (!ret)
124 err = GetLastError();
125 goto error;
128 data->hWVTStateData = (HANDLE)provData;
129 provData->pWintrustData = data;
130 if (hwnd == INVALID_HANDLE_VALUE)
131 provData->hWndParent = GetDesktopWindow();
132 else
133 provData->hWndParent = hwnd;
134 provData->pgActionID = actionID;
135 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
137 if (provData->psPfns->pfnInitialize)
139 verifySteps[numSteps].func = provData->psPfns->pfnInitialize;
140 verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
142 if (provData->psPfns->pfnObjectTrust)
144 verifySteps[numSteps].func = provData->psPfns->pfnObjectTrust;
145 verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
147 if (provData->psPfns->pfnSignatureTrust)
149 verifySteps[numSteps].func = provData->psPfns->pfnSignatureTrust;
150 verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
152 if (provData->psPfns->pfnCertificateTrust)
154 verifySteps[numSteps].func = provData->psPfns->pfnCertificateTrust;
155 verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
157 if (provData->psPfns->pfnFinalPolicy)
159 verifySteps[numSteps].func = provData->psPfns->pfnFinalPolicy;
160 verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
162 err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
163 goto done;
165 oom:
166 err = ERROR_OUTOFMEMORY;
167 error:
168 if (provData)
170 WINTRUST_Free(provData->padwTrustStepErrors);
171 WINTRUST_Free(provData->u.pPDSip);
172 WINTRUST_Free(provData->psPfns);
173 WINTRUST_Free(provData);
175 done:
176 TRACE("returning %08x\n", err);
177 return err;
180 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
181 WINTRUST_DATA *data)
183 DWORD err = ERROR_SUCCESS;
184 CRYPT_PROVIDER_DATA *provData = (CRYPT_PROVIDER_DATA *)data->hWVTStateData;
186 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
188 if (provData)
190 if (provData->psPfns->pfnCleanupPolicy)
191 err = provData->psPfns->pfnCleanupPolicy(provData);
193 WINTRUST_Free(provData->padwTrustStepErrors);
194 WINTRUST_Free(provData->u.pPDSip);
195 WINTRUST_Free(provData->psPfns);
196 WINTRUST_Free(provData);
197 data->hWVTStateData = NULL;
199 TRACE("returning %08x\n", err);
200 return err;
203 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
204 WINTRUST_DATA *data)
206 LONG err;
208 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
210 err = WINTRUST_DefaultVerify(hwnd, actionID, data);
211 WINTRUST_DefaultClose(hwnd, actionID, data);
212 TRACE("returning %08x\n", err);
213 return err;
216 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
217 WINTRUST_DATA *data)
219 WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
220 /* Undocumented: the published software action is passed a path,
221 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
223 LPWIN_TRUST_SUBJECT_FILE subjectFile =
224 (LPWIN_TRUST_SUBJECT_FILE)data->pSIPClientData;
225 WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
227 TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
228 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
229 fileInfo.pcwszFilePath = subjectFile->lpPath;
230 fileInfo.hFile = subjectFile->hFile;
231 wintrust_data.u.pFile = &fileInfo;
232 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
233 wintrust_data.dwUIChoice = WTD_UI_NONE;
235 return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
238 static void dump_file_info(WINTRUST_FILE_INFO *pFile)
240 TRACE("%p\n", pFile);
241 if (pFile)
243 TRACE("cbStruct: %d\n", pFile->cbStruct);
244 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath));
245 TRACE("hFile: %p\n", pFile->hFile);
246 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject));
250 static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog)
252 TRACE("%p\n", catalog);
253 if (catalog)
255 TRACE("cbStruct: %d\n", catalog->cbStruct);
256 TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion);
257 TRACE("pcwszCatalogFilePath: %s\n",
258 debugstr_w(catalog->pcwszCatalogFilePath));
259 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag));
260 TRACE("pcwszMemberFilePath: %s\n",
261 debugstr_w(catalog->pcwszMemberFilePath));
262 TRACE("hMemberFile: %p\n", catalog->hMemberFile);
263 TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash);
264 TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash);
265 TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext);
269 static void dump_blob_info(WINTRUST_BLOB_INFO *blob)
271 TRACE("%p\n", blob);
272 if (blob)
274 TRACE("cbStruct: %d\n", blob->cbStruct);
275 TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject));
276 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName));
277 TRACE("cbMemObject: %d\n", blob->cbMemObject);
278 TRACE("pbMemObject: %p\n", blob->pbMemObject);
279 TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg);
280 TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg);
284 static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr)
286 TRACE("%p\n", sgnr);
287 if (sgnr)
289 TRACE("cbStruct: %d\n", sgnr->cbStruct);
290 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName));
291 TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo);
292 TRACE("chStores: %d\n", sgnr->chStores);
296 static void dump_cert_info(WINTRUST_CERT_INFO *cert)
298 TRACE("%p\n", cert);
299 if (cert)
301 TRACE("cbStruct: %d\n", cert->cbStruct);
302 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName));
303 TRACE("psCertContext: %p\n", cert->psCertContext);
304 TRACE("chStores: %d\n", cert->chStores);
305 TRACE("dwFlags: %08x\n", cert->dwFlags);
306 TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf);
310 static void dump_wintrust_data(WINTRUST_DATA *data)
312 TRACE("%p\n", data);
313 if (data)
315 TRACE("cbStruct: %d\n", data->cbStruct);
316 TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData);
317 TRACE("pSIPClientData: %p\n", data->pSIPClientData);
318 TRACE("dwUIChoice: %d\n", data->dwUIChoice);
319 TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks);
320 TRACE("dwUnionChoice: %d\n", data->dwUnionChoice);
321 switch (data->dwUnionChoice)
323 case WTD_CHOICE_FILE:
324 dump_file_info(data->u.pFile);
325 break;
326 case WTD_CHOICE_CATALOG:
327 dump_catalog_info(data->u.pCatalog);
328 break;
329 case WTD_CHOICE_BLOB:
330 dump_blob_info(data->u.pBlob);
331 break;
332 case WTD_CHOICE_SIGNER:
333 dump_sgnr_info(data->u.pSgnr);
334 break;
335 case WTD_CHOICE_CERT:
336 dump_cert_info(data->u.pCert);
337 break;
339 TRACE("dwStateAction: %d\n", data->dwStateAction);
340 TRACE("hWVTStateData: %p\n", data->hWVTStateData);
341 TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference));
342 TRACE("dwProvFlags: %08x\n", data->dwProvFlags);
343 TRACE("dwUIContext: %d\n", data->dwUIContext);
347 /***********************************************************************
348 * WinVerifyTrust (WINTRUST.@)
350 * Verifies an object by calling the specified trust provider.
352 * PARAMS
353 * hwnd [I] Handle to a caller window.
354 * ActionID [I] Pointer to a GUID that identifies the action to perform.
355 * ActionData [I] Information used by the trust provider to verify the object.
357 * RETURNS
358 * Success: Zero.
359 * Failure: A TRUST_E_* error code.
361 * NOTES
362 * Trust providers can be found at:
363 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
365 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
367 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
368 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
369 static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
370 static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
371 static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
372 static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
373 LONG err = ERROR_SUCCESS;
374 WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
376 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
377 dump_wintrust_data(ActionData);
379 /* Support for known old-style callers: */
380 if (IsEqualGUID(ActionID, &published_software))
381 err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
382 else
384 /* Check known actions to warn of possible problems */
385 if (!IsEqualGUID(ActionID, &unknown) &&
386 !IsEqualGUID(ActionID, &generic_verify_v2) &&
387 !IsEqualGUID(ActionID, &generic_cert_verify) &&
388 !IsEqualGUID(ActionID, &generic_chain_verify))
389 WARN("unknown action %s, default behavior may not be right\n",
390 debugstr_guid(ActionID));
391 switch (actionData->dwStateAction)
393 case WTD_STATEACTION_IGNORE:
394 err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
395 break;
396 case WTD_STATEACTION_VERIFY:
397 err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
398 break;
399 case WTD_STATEACTION_CLOSE:
400 err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
401 break;
402 default:
403 FIXME("unimplemented for %d\n", actionData->dwStateAction);
407 TRACE("returning %08x\n", err);
408 return err;
411 /***********************************************************************
412 * WinVerifyTrustEx (WINTRUST.@)
414 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
415 WINTRUST_DATA* ActionData )
417 return WinVerifyTrust(hwnd, ActionID, ActionData);
420 /***********************************************************************
421 * WTHelperGetProvSignerFromChain (WINTRUST.@)
423 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
424 CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
425 DWORD idxCounterSigner)
427 CRYPT_PROVIDER_SGNR *sgnr;
429 TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
430 idxCounterSigner);
432 if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
433 return NULL;
434 sgnr = &pProvData->pasSigners[idxSigner];
435 if (fCounterSigner)
437 if (idxCounterSigner >= sgnr->csCounterSigners ||
438 !sgnr->pasCounterSigners)
439 return NULL;
440 sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
442 TRACE("returning %p\n", sgnr);
443 return sgnr;
446 /***********************************************************************
447 * WTHelperGetProvCertFromChain (WINTRUST.@)
449 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
450 CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
452 CRYPT_PROVIDER_CERT *cert;
454 TRACE("(%p %d)\n", pSgnr, idxCert);
456 if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
457 return NULL;
458 cert = &pSgnr->pasCertChain[idxCert];
459 TRACE("returning %p\n", cert);
460 return cert;
463 CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain(
464 CRYPT_PROVIDER_DATA* pProvData,
465 GUID* pgProviderID)
467 CRYPT_PROVIDER_PRIVDATA *privdata = NULL;
468 DWORD i;
470 TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID));
472 for (i = 0; i < pProvData->csProvPrivData; i++)
473 if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID))
475 privdata = &pProvData->pasProvPrivData[i];
476 break;
479 return privdata;
482 /***********************************************************************
483 * WTHelperProvDataFromStateData (WINTRUST.@)
485 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
487 TRACE("%p\n", hStateData);
488 return (CRYPT_PROVIDER_DATA *)hStateData;
491 /***********************************************************************
492 * WTHelperGetFileName(WINTRUST.@)
494 LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data)
496 TRACE("%p\n",data);
497 if (data->dwUnionChoice == WTD_CHOICE_FILE)
498 return data->u.pFile->pcwszFilePath;
499 else
500 return NULL;
503 /***********************************************************************
504 * WTHelperGetFileHandle(WINTRUST.@)
506 HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
508 TRACE("%p\n",data);
509 if (data->dwUnionChoice == WTD_CHOICE_FILE)
510 return data->u.pFile->hFile;
511 else
512 return INVALID_HANDLE_VALUE;
515 static const WCHAR Software_Publishing[] = {
516 'S','o','f','t','w','a','r','e','\\',
517 'M','i','c','r','o','s','o','f','t','\\',
518 'W','i','n','d','o','w','s','\\',
519 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
520 'W','i','n','t','r','u','s','t','\\',
521 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
522 'S','o','f','t','w','a','r','e',' ',
523 'P','u','b','l','i','s','h','i','n','g',0 };
524 static const WCHAR State[] = { 'S','t','a','t','e',0 };
526 /***********************************************************************
527 * WintrustGetRegPolicyFlags (WINTRUST.@)
529 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
531 HKEY key;
532 LONG r;
534 TRACE("%p\n", pdwPolicyFlags);
536 *pdwPolicyFlags = 0;
537 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
538 KEY_READ, NULL, &key, NULL);
539 if (!r)
541 DWORD size = sizeof(DWORD);
543 r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
544 &size);
545 RegCloseKey(key);
546 if (r)
548 /* Failed to query, create and return default value */
549 *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
550 WTPF_OFFLINEOKNBU_COM |
551 WTPF_OFFLINEOKNBU_IND |
552 WTPF_OFFLINEOK_COM |
553 WTPF_OFFLINEOK_IND;
554 WintrustSetRegPolicyFlags(*pdwPolicyFlags);
559 /***********************************************************************
560 * WintrustSetRegPolicyFlags (WINTRUST.@)
562 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
564 HKEY key;
565 LONG r;
567 TRACE("%x\n", dwPolicyFlags);
569 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
570 NULL, 0, KEY_WRITE, NULL, &key, NULL);
571 if (!r)
573 r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
574 sizeof(DWORD));
575 RegCloseKey(key);
577 if (r) SetLastError(r);
578 return r == ERROR_SUCCESS;
581 /* Utility functions */
582 void * WINAPI WINTRUST_Alloc(DWORD cb)
584 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
587 void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
589 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
592 void WINAPI WINTRUST_Free(void *p)
594 HeapFree(GetProcessHeap(), 0, p);
597 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
599 BOOL ret = FALSE;
601 if (data->chStores)
602 data->pahStores = WINTRUST_ReAlloc(data->pahStores,
603 (data->chStores + 1) * sizeof(HCERTSTORE));
604 else
606 data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
607 data->chStores = 0;
609 if (data->pahStores)
611 data->pahStores[data->chStores++] = CertDuplicateStore(store);
612 ret = TRUE;
614 else
615 SetLastError(ERROR_OUTOFMEMORY);
616 return ret;
619 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
620 BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
622 BOOL ret = FALSE;
624 if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
626 SetLastError(ERROR_INVALID_PARAMETER);
627 return FALSE;
629 if (fCounterSigner)
631 FIXME("unimplemented for counter signers\n");
632 SetLastError(ERROR_INVALID_PARAMETER);
633 return FALSE;
635 if (data->csSigners)
636 data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
637 (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
638 else
640 data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
641 data->csSigners = 0;
643 if (data->pasSigners)
645 if (idxSigner < data->csSigners)
646 memmove(&data->pasSigners[idxSigner],
647 &data->pasSigners[idxSigner + 1],
648 (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
649 ret = TRUE;
650 if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
652 /* The PSDK says psSigner should be allocated using pfnAlloc, but
653 * it doesn't say anything about ownership. Since callers are
654 * internal, assume ownership is passed, and just store the
655 * pointer.
657 memcpy(&data->pasSigners[idxSigner], sgnr,
658 sizeof(CRYPT_PROVIDER_SGNR));
660 else
661 memset(&data->pasSigners[idxSigner], 0,
662 sizeof(CRYPT_PROVIDER_SGNR));
663 data->csSigners++;
665 else
666 SetLastError(ERROR_OUTOFMEMORY);
667 return ret;
670 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
671 BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
673 BOOL ret = FALSE;
675 if (fCounterSigner)
677 FIXME("unimplemented for counter signers\n");
678 SetLastError(ERROR_INVALID_PARAMETER);
679 return FALSE;
681 if (data->pasSigners[idxSigner].csCertChain)
682 data->pasSigners[idxSigner].pasCertChain =
683 WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
684 (data->pasSigners[idxSigner].csCertChain + 1) *
685 sizeof(CRYPT_PROVIDER_CERT));
686 else
688 data->pasSigners[idxSigner].pasCertChain =
689 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
690 data->pasSigners[idxSigner].csCertChain = 0;
692 if (data->pasSigners[idxSigner].pasCertChain)
694 CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
695 data->pasSigners[idxSigner].csCertChain];
697 cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
698 cert->pCert = CertDuplicateCertificateContext(pCert2Add);
699 data->pasSigners[idxSigner].csCertChain++;
700 ret = TRUE;
702 else
703 SetLastError(ERROR_OUTOFMEMORY);
704 return ret;
707 BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
708 CRYPT_PROVIDER_PRIVDATA *pPrivData2Add)
710 BOOL ret = FALSE;
712 TRACE("(%p, %p)\n", data, pPrivData2Add);
714 if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA))
716 SetLastError(ERROR_INVALID_PARAMETER);
717 WARN("invalid struct size\n");
718 return FALSE;
720 if (data->csProvPrivData)
721 data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData,
722 (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR));
723 else
725 data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
726 data->csProvPrivData = 0;
728 if (data->pasProvPrivData)
730 DWORD i;
732 for (i = 0; i < data->csProvPrivData; i++)
733 if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i]))
734 break;
736 data->pasProvPrivData[i] = *pPrivData2Add;
737 if (i == data->csProvPrivData)
738 data->csProvPrivData++;
740 else
741 SetLastError(ERROR_OUTOFMEMORY);
742 return ret;