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
24 #define NONAMELESSUNION
37 #include "wintrust_priv.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
43 /***********************************************************************
44 * DllMain (WINTRUST.@)
46 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
50 case DLL_PROCESS_ATTACH:
51 DisableThreadLibraryCalls( inst );
57 /***********************************************************************
58 * TrustIsCertificateSelfSigned (WINTRUST.@)
60 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
65 ret = CertCompareCertificateName(cert->dwCertEncodingType,
66 &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
70 typedef HRESULT (WINAPI *wintrust_step_func)(CRYPT_PROVIDER_DATA *data);
74 wintrust_step_func func;
78 static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps,
79 DWORD numSteps, CRYPT_PROVIDER_DATA *provData)
81 DWORD i, err = ERROR_SUCCESS;
83 for (i = 0; !err && i < numSteps; i++)
85 err = steps[i].func(provData);
87 err = provData->padwTrustStepErrors[steps[i].error_index];
92 static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void)
94 CRYPT_PROVIDER_DATA *provData;
96 provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
99 provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
101 provData->padwTrustStepErrors =
102 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
103 if (!provData->padwTrustStepErrors)
105 provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
107 provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
108 if (!provData->u.pPDSip)
110 provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP);
112 provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
113 if (!provData->psPfns)
115 provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
121 WINTRUST_Free(provData->padwTrustStepErrors);
122 WINTRUST_Free(provData->u.pPDSip);
123 WINTRUST_Free(provData->psPfns);
124 WINTRUST_Free(provData);
129 /* Adds trust steps for each function in psPfns. Assumes steps has at least
130 * 5 entries. Returns the number of steps added.
132 static DWORD WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step *steps,
133 const CRYPT_PROVIDER_FUNCTIONS *psPfns)
137 if (psPfns->pfnInitialize)
139 steps[numSteps].func = psPfns->pfnInitialize;
140 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
142 if (psPfns->pfnObjectTrust)
144 steps[numSteps].func = psPfns->pfnObjectTrust;
145 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
147 if (psPfns->pfnSignatureTrust)
149 steps[numSteps].func = psPfns->pfnSignatureTrust;
150 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
152 if (psPfns->pfnCertificateTrust)
154 steps[numSteps].func = psPfns->pfnCertificateTrust;
155 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
157 if (psPfns->pfnFinalPolicy)
159 steps[numSteps].func = psPfns->pfnFinalPolicy;
160 steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
165 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
168 DWORD err = ERROR_SUCCESS, numSteps = 0;
169 CRYPT_PROVIDER_DATA *provData;
171 struct wintrust_step verifySteps[5];
173 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
175 provData = WINTRUST_AllocateProviderData();
177 return ERROR_OUTOFMEMORY;
179 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
182 err = GetLastError();
186 data->hWVTStateData = (HANDLE)provData;
187 provData->pWintrustData = data;
188 if (hwnd == INVALID_HANDLE_VALUE)
189 provData->hWndParent = GetDesktopWindow();
191 provData->hWndParent = hwnd;
192 provData->pgActionID = actionID;
193 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
195 numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
197 err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
203 WINTRUST_Free(provData->padwTrustStepErrors);
204 WINTRUST_Free(provData->u.pPDSip);
205 WINTRUST_Free(provData->psPfns);
206 WINTRUST_Free(provData);
209 TRACE("returning %08x\n", err);
213 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
216 DWORD err = ERROR_SUCCESS;
217 CRYPT_PROVIDER_DATA *provData = (CRYPT_PROVIDER_DATA *)data->hWVTStateData;
219 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
223 if (provData->psPfns->pfnCleanupPolicy)
224 err = provData->psPfns->pfnCleanupPolicy(provData);
226 WINTRUST_Free(provData->padwTrustStepErrors);
227 WINTRUST_Free(provData->u.pPDSip);
228 WINTRUST_Free(provData->psPfns);
229 WINTRUST_Free(provData);
230 data->hWVTStateData = NULL;
232 TRACE("returning %08x\n", err);
236 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
241 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
243 err = WINTRUST_DefaultVerify(hwnd, actionID, data);
244 WINTRUST_DefaultClose(hwnd, actionID, data);
245 TRACE("returning %08x\n", err);
249 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
252 WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
253 /* Undocumented: the published software action is passed a path,
254 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
256 LPWIN_TRUST_SUBJECT_FILE subjectFile =
257 (LPWIN_TRUST_SUBJECT_FILE)data->pSIPClientData;
258 WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
260 TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
261 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
262 fileInfo.pcwszFilePath = subjectFile->lpPath;
263 fileInfo.hFile = subjectFile->hFile;
264 wintrust_data.u.pFile = &fileInfo;
265 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
266 wintrust_data.dwUIChoice = WTD_UI_NONE;
268 return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
271 /* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
272 * action is not stored in the registry and is located in wintrust, not in
273 * cryptdlg along with the rest of the implementation (verified by running the
274 * action with a native wintrust.dll.)
276 static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data)
280 TRACE("(%p)\n", data);
282 if (!data->padwTrustStepErrors)
285 switch (data->pWintrustData->dwUnionChoice)
287 case WTD_CHOICE_BLOB:
288 if (data->pWintrustData->u.pBlob &&
289 data->pWintrustData->u.pBlob->cbStruct == sizeof(WINTRUST_BLOB_INFO) &&
290 data->pWintrustData->u.pBlob->cbMemObject ==
291 sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
292 data->pWintrustData->u.pBlob->pbMemObject)
294 CERT_VERIFY_CERTIFICATE_TRUST *pCert =
295 (CERT_VERIFY_CERTIFICATE_TRUST *)
296 data->pWintrustData->u.pBlob->pbMemObject;
298 if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
301 CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
305 /* Add a signer with nothing but the time to verify, so we can
308 GetSystemTime(&sysTime);
309 SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
310 ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
313 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
317 for (i = 0; ret && i < pCert->cRootStores; i++)
318 ret = data->psPfns->pfnAddStore2Chain(data,
319 pCert->rghstoreRoots[i]);
320 for (i = 0; ret && i < pCert->cStores; i++)
321 ret = data->psPfns->pfnAddStore2Chain(data,
322 pCert->rghstoreCAs[i]);
323 for (i = 0; ret && i < pCert->cTrustStores; i++)
324 ret = data->psPfns->pfnAddStore2Chain(data,
325 pCert->rghstoreTrust[i]);
329 SetLastError(ERROR_INVALID_PARAMETER);
335 SetLastError(ERROR_INVALID_PARAMETER);
340 FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
341 SetLastError(ERROR_INVALID_PARAMETER);
347 data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
349 TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
350 data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
351 return ret ? S_OK : S_FALSE;
354 static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID,
357 DWORD err = ERROR_SUCCESS, numSteps = 0;
358 CRYPT_PROVIDER_DATA *provData;
360 struct wintrust_step verifySteps[5];
362 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
364 provData = WINTRUST_AllocateProviderData();
366 return ERROR_OUTOFMEMORY;
368 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
371 err = GetLastError();
374 if (!provData->psPfns->pfnObjectTrust)
375 provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust;
376 /* Not sure why, but native skips the policy check */
377 provData->psPfns->pfnCertCheckPolicy = NULL;
379 data->hWVTStateData = (HANDLE)provData;
380 provData->pWintrustData = data;
381 if (hwnd == INVALID_HANDLE_VALUE)
382 provData->hWndParent = GetDesktopWindow();
384 provData->hWndParent = hwnd;
385 provData->pgActionID = actionID;
386 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
388 numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
390 err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
396 WINTRUST_Free(provData->padwTrustStepErrors);
397 WINTRUST_Free(provData->u.pPDSip);
398 WINTRUST_Free(provData->psPfns);
399 WINTRUST_Free(provData);
402 TRACE("returning %08x\n", err);
406 static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID,
411 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
413 err = WINTRUST_CertVerify(hwnd, actionID, data);
414 WINTRUST_DefaultClose(hwnd, actionID, data);
415 TRACE("returning %08x\n", err);
419 static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID,
423 LONG err = ERROR_SUCCESS;
425 if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction))
426 stateAction = data->dwStateAction;
429 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
430 stateAction = WTD_STATEACTION_IGNORE;
434 case WTD_STATEACTION_IGNORE:
435 err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data);
437 case WTD_STATEACTION_VERIFY:
438 err = WINTRUST_CertVerify(hwnd, actionID, data);
440 case WTD_STATEACTION_CLOSE:
441 err = WINTRUST_DefaultClose(hwnd, actionID, data);
444 FIXME("unimplemented for %d\n", data->dwStateAction);
449 static void dump_file_info(WINTRUST_FILE_INFO *pFile)
451 TRACE("%p\n", pFile);
454 TRACE("cbStruct: %d\n", pFile->cbStruct);
455 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath));
456 TRACE("hFile: %p\n", pFile->hFile);
457 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject));
461 static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog)
463 TRACE("%p\n", catalog);
466 TRACE("cbStruct: %d\n", catalog->cbStruct);
467 TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion);
468 TRACE("pcwszCatalogFilePath: %s\n",
469 debugstr_w(catalog->pcwszCatalogFilePath));
470 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag));
471 TRACE("pcwszMemberFilePath: %s\n",
472 debugstr_w(catalog->pcwszMemberFilePath));
473 TRACE("hMemberFile: %p\n", catalog->hMemberFile);
474 TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash);
475 TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash);
476 TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext);
480 static void dump_blob_info(WINTRUST_BLOB_INFO *blob)
485 TRACE("cbStruct: %d\n", blob->cbStruct);
486 TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject));
487 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName));
488 TRACE("cbMemObject: %d\n", blob->cbMemObject);
489 TRACE("pbMemObject: %p\n", blob->pbMemObject);
490 TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg);
491 TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg);
495 static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr)
500 TRACE("cbStruct: %d\n", sgnr->cbStruct);
501 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName));
502 TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo);
503 TRACE("chStores: %d\n", sgnr->chStores);
507 static void dump_cert_info(WINTRUST_CERT_INFO *cert)
512 TRACE("cbStruct: %d\n", cert->cbStruct);
513 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName));
514 TRACE("psCertContext: %p\n", cert->psCertContext);
515 TRACE("chStores: %d\n", cert->chStores);
516 TRACE("dwFlags: %08x\n", cert->dwFlags);
517 TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf);
521 static void dump_wintrust_data(WINTRUST_DATA *data)
526 TRACE("cbStruct: %d\n", data->cbStruct);
527 TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData);
528 TRACE("pSIPClientData: %p\n", data->pSIPClientData);
529 TRACE("dwUIChoice: %d\n", data->dwUIChoice);
530 TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks);
531 TRACE("dwUnionChoice: %d\n", data->dwUnionChoice);
532 switch (data->dwUnionChoice)
534 case WTD_CHOICE_FILE:
535 dump_file_info(data->u.pFile);
537 case WTD_CHOICE_CATALOG:
538 dump_catalog_info(data->u.pCatalog);
540 case WTD_CHOICE_BLOB:
541 dump_blob_info(data->u.pBlob);
543 case WTD_CHOICE_SIGNER:
544 dump_sgnr_info(data->u.pSgnr);
546 case WTD_CHOICE_CERT:
547 dump_cert_info(data->u.pCert);
550 TRACE("dwStateAction: %d\n", data->dwStateAction);
551 TRACE("hWVTStateData: %p\n", data->hWVTStateData);
552 TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference));
553 TRACE("dwProvFlags: %08x\n", data->dwProvFlags);
554 TRACE("dwUIContext: %d\n", data->dwUIContext);
558 /***********************************************************************
559 * WinVerifyTrust (WINTRUST.@)
561 * Verifies an object by calling the specified trust provider.
564 * hwnd [I] Handle to a caller window.
565 * ActionID [I] Pointer to a GUID that identifies the action to perform.
566 * ActionData [I] Information used by the trust provider to verify the object.
570 * Failure: A TRUST_E_* error code.
573 * Trust providers can be found at:
574 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
576 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
578 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
579 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
580 static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
581 static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
582 static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
583 static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
584 static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY;
585 LONG err = ERROR_SUCCESS;
586 WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
588 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
589 dump_wintrust_data(ActionData);
591 /* Support for known old-style callers: */
592 if (IsEqualGUID(ActionID, &published_software))
593 err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
594 else if (IsEqualGUID(ActionID, &cert_action_verify))
595 err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData);
600 /* Check known actions to warn of possible problems */
601 if (!IsEqualGUID(ActionID, &unknown) &&
602 !IsEqualGUID(ActionID, &generic_verify_v2) &&
603 !IsEqualGUID(ActionID, &generic_cert_verify) &&
604 !IsEqualGUID(ActionID, &generic_chain_verify))
605 WARN("unknown action %s, default behavior may not be right\n",
606 debugstr_guid(ActionID));
607 if (WVT_ISINSTRUCT(WINTRUST_DATA, actionData->cbStruct, dwStateAction))
608 stateAction = actionData->dwStateAction;
611 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
612 stateAction = WTD_STATEACTION_IGNORE;
616 case WTD_STATEACTION_IGNORE:
617 err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
619 case WTD_STATEACTION_VERIFY:
620 err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
622 case WTD_STATEACTION_CLOSE:
623 err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
626 FIXME("unimplemented for %d\n", actionData->dwStateAction);
630 TRACE("returning %08x\n", err);
634 /***********************************************************************
635 * WinVerifyTrustEx (WINTRUST.@)
637 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
638 WINTRUST_DATA* ActionData )
640 return WinVerifyTrust(hwnd, ActionID, ActionData);
643 /***********************************************************************
644 * WTHelperGetProvSignerFromChain (WINTRUST.@)
646 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
647 CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
648 DWORD idxCounterSigner)
650 CRYPT_PROVIDER_SGNR *sgnr;
652 TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
655 if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
657 sgnr = &pProvData->pasSigners[idxSigner];
660 if (idxCounterSigner >= sgnr->csCounterSigners ||
661 !sgnr->pasCounterSigners)
663 sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
665 TRACE("returning %p\n", sgnr);
669 /***********************************************************************
670 * WTHelperGetProvCertFromChain (WINTRUST.@)
672 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
673 CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
675 CRYPT_PROVIDER_CERT *cert;
677 TRACE("(%p %d)\n", pSgnr, idxCert);
679 if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
681 cert = &pSgnr->pasCertChain[idxCert];
682 TRACE("returning %p\n", cert);
686 CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain(
687 CRYPT_PROVIDER_DATA* pProvData,
690 CRYPT_PROVIDER_PRIVDATA *privdata = NULL;
693 TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID));
695 for (i = 0; i < pProvData->csProvPrivData; i++)
696 if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID))
698 privdata = &pProvData->pasProvPrivData[i];
705 /***********************************************************************
706 * WTHelperProvDataFromStateData (WINTRUST.@)
708 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
710 TRACE("%p\n", hStateData);
711 return (CRYPT_PROVIDER_DATA *)hStateData;
714 /***********************************************************************
715 * WTHelperGetFileName(WINTRUST.@)
717 LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data)
720 if (data->dwUnionChoice == WTD_CHOICE_FILE)
721 return data->u.pFile->pcwszFilePath;
726 /***********************************************************************
727 * WTHelperGetFileHandle(WINTRUST.@)
729 HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
732 if (data->dwUnionChoice == WTD_CHOICE_FILE)
733 return data->u.pFile->hFile;
735 return INVALID_HANDLE_VALUE;
738 static BOOL WINAPI WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo, void *pvArg)
740 PCCRYPT_OID_INFO **usages = (PCCRYPT_OID_INFO **)pvArg;
747 *usages = WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO));
751 PCCRYPT_OID_INFO *ptr;
753 /* Count the existing usages.
754 * FIXME: make sure the new usage doesn't duplicate any in the list?
756 for (cUsages = 0, ptr = *usages; *ptr; ptr++, cUsages++)
758 *usages = WINTRUST_ReAlloc((CRYPT_OID_INFO *)*usages,
759 (cUsages + 1) * sizeof(PCCRYPT_OID_INFO));
763 (*usages)[cUsages] = pInfo;
764 (*usages)[cUsages + 1] = NULL;
769 SetLastError(ERROR_OUTOFMEMORY);
775 /***********************************************************************
776 * WTHelperGetKnownUsages(WINTRUST.@)
778 * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs.
781 * action [In] 1 => allocate and return known usages, 2 => free previously
783 * usages [In/Out] If action == 1, *usages is set to an array of
784 * PCCRYPT_OID_INFO *. The array is terminated with a NULL
786 * If action == 2, *usages is freed.
789 * TRUE on success, FALSE on failure.
791 BOOL WINAPI WTHelperGetKnownUsages(DWORD action, PCCRYPT_OID_INFO **usages)
795 TRACE("(%d, %p)\n", action, usages);
799 SetLastError(ERROR_INVALID_PARAMETER);
806 ret = CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID, 0, usages,
807 WINTRUST_enumUsages);
809 else if (action == 2)
811 WINTRUST_Free((CRYPT_OID_INFO *)*usages);
817 WARN("unknown action %d\n", action);
818 SetLastError(ERROR_INVALID_PARAMETER);
824 static const WCHAR Software_Publishing[] = {
825 'S','o','f','t','w','a','r','e','\\',
826 'M','i','c','r','o','s','o','f','t','\\',
827 'W','i','n','d','o','w','s','\\',
828 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
829 'W','i','n','t','r','u','s','t','\\',
830 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
831 'S','o','f','t','w','a','r','e',' ',
832 'P','u','b','l','i','s','h','i','n','g',0 };
833 static const WCHAR State[] = { 'S','t','a','t','e',0 };
835 /***********************************************************************
836 * WintrustGetRegPolicyFlags (WINTRUST.@)
838 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
843 TRACE("%p\n", pdwPolicyFlags);
846 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
847 KEY_READ, NULL, &key, NULL);
850 DWORD size = sizeof(DWORD);
852 r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
857 /* Failed to query, create and return default value */
858 *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
859 WTPF_OFFLINEOKNBU_COM |
860 WTPF_OFFLINEOKNBU_IND |
863 WintrustSetRegPolicyFlags(*pdwPolicyFlags);
868 /***********************************************************************
869 * WintrustSetRegPolicyFlags (WINTRUST.@)
871 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
876 TRACE("%x\n", dwPolicyFlags);
878 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
879 NULL, 0, KEY_WRITE, NULL, &key, NULL);
882 r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
886 if (r) SetLastError(r);
887 return r == ERROR_SUCCESS;
890 /* Utility functions */
891 void * WINAPI WINTRUST_Alloc(DWORD cb)
893 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
896 void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
898 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
901 void WINAPI WINTRUST_Free(void *p)
903 HeapFree(GetProcessHeap(), 0, p);
906 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
910 TRACE("(%p, %p)\n", data, store);
913 data->pahStores = WINTRUST_ReAlloc(data->pahStores,
914 (data->chStores + 1) * sizeof(HCERTSTORE));
917 data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
922 data->pahStores[data->chStores++] = CertDuplicateStore(store);
926 SetLastError(ERROR_OUTOFMEMORY);
930 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
931 BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
935 TRACE("(%p, %d, %d, %p)\n", data, fCounterSigner, idxSigner, sgnr);
937 if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
939 SetLastError(ERROR_INVALID_PARAMETER);
944 FIXME("unimplemented for counter signers\n");
945 SetLastError(ERROR_INVALID_PARAMETER);
949 data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
950 (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
953 data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
956 if (data->pasSigners)
958 if (idxSigner < data->csSigners)
959 memmove(&data->pasSigners[idxSigner],
960 &data->pasSigners[idxSigner + 1],
961 (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
963 if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
965 /* The PSDK says psSigner should be allocated using pfnAlloc, but
966 * it doesn't say anything about ownership. Since callers are
967 * internal, assume ownership is passed, and just store the
970 memcpy(&data->pasSigners[idxSigner], sgnr,
971 sizeof(CRYPT_PROVIDER_SGNR));
974 memset(&data->pasSigners[idxSigner], 0,
975 sizeof(CRYPT_PROVIDER_SGNR));
979 SetLastError(ERROR_OUTOFMEMORY);
983 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
984 BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
988 TRACE("(%p, %d, %d, %d, %p)\n", data, idxSigner, fCounterSigner,
989 idxSigner, pCert2Add);
993 FIXME("unimplemented for counter signers\n");
994 SetLastError(ERROR_INVALID_PARAMETER);
997 if (data->pasSigners[idxSigner].csCertChain)
998 data->pasSigners[idxSigner].pasCertChain =
999 WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
1000 (data->pasSigners[idxSigner].csCertChain + 1) *
1001 sizeof(CRYPT_PROVIDER_CERT));
1004 data->pasSigners[idxSigner].pasCertChain =
1005 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
1006 data->pasSigners[idxSigner].csCertChain = 0;
1008 if (data->pasSigners[idxSigner].pasCertChain)
1010 CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
1011 data->pasSigners[idxSigner].csCertChain];
1013 cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
1014 cert->pCert = CertDuplicateCertificateContext(pCert2Add);
1015 data->pasSigners[idxSigner].csCertChain++;
1019 SetLastError(ERROR_OUTOFMEMORY);
1023 BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
1024 CRYPT_PROVIDER_PRIVDATA *pPrivData2Add)
1028 TRACE("(%p, %p)\n", data, pPrivData2Add);
1030 if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA))
1032 SetLastError(ERROR_INVALID_PARAMETER);
1033 WARN("invalid struct size\n");
1036 if (data->csProvPrivData)
1037 data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData,
1038 (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR));
1041 data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
1042 data->csProvPrivData = 0;
1044 if (data->pasProvPrivData)
1048 for (i = 0; i < data->csProvPrivData; i++)
1049 if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i]))
1052 data->pasProvPrivData[i] = *pPrivData2Add;
1053 if (i == data->csProvPrivData)
1054 data->csProvPrivData++;
1057 SetLastError(ERROR_OUTOFMEMORY);