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
34 #include "wintrust_priv.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
40 /***********************************************************************
41 * DllMain (WINTRUST.@)
43 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
47 case DLL_PROCESS_ATTACH:
48 DisableThreadLibraryCalls( inst );
54 /***********************************************************************
55 * TrustIsCertificateSelfSigned (WINTRUST.@)
57 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
62 ret = CertCompareCertificateName(cert->dwCertEncodingType,
63 &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
67 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
70 DWORD err = ERROR_SUCCESS;
71 CRYPT_PROVIDER_DATA *provData;
74 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
76 provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
79 provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
81 provData->padwTrustStepErrors =
82 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
83 if (!provData->padwTrustStepErrors)
85 provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
87 provData->pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
88 if (!provData->pPDSip)
90 provData->pPDSip->cbStruct = sizeof(PROVDATA_SIP);
92 provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
93 if (!provData->psPfns)
95 provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
96 ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
103 data->hWVTStateData = (HANDLE)provData;
104 provData->pWintrustData = data;
105 if (hwnd == INVALID_HANDLE_VALUE)
106 provData->hWndParent = GetDesktopWindow();
108 provData->hWndParent = hwnd;
109 provData->pgActionID = actionID;
110 WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
112 err = provData->psPfns->pfnInitialize(provData);
115 err = provData->psPfns->pfnObjectTrust(provData);
118 err = provData->psPfns->pfnSignatureTrust(provData);
121 err = provData->psPfns->pfnCertificateTrust(provData);
124 err = provData->psPfns->pfnFinalPolicy(provData);
128 err = ERROR_OUTOFMEMORY;
132 WINTRUST_Free(provData->padwTrustStepErrors);
133 WINTRUST_Free(provData->pPDSip);
134 WINTRUST_Free(provData->psPfns);
135 WINTRUST_Free(provData);
138 TRACE("returning %08x\n", err);
142 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
145 DWORD err = ERROR_SUCCESS;
146 CRYPT_PROVIDER_DATA *provData = (CRYPT_PROVIDER_DATA *)data->hWVTStateData;
148 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
152 err = provData->psPfns->pfnCleanupPolicy(provData);
153 WINTRUST_Free(provData->padwTrustStepErrors);
154 WINTRUST_Free(provData->pPDSip);
155 WINTRUST_Free(provData->psPfns);
156 WINTRUST_Free(provData);
157 data->hWVTStateData = NULL;
159 TRACE("returning %08x\n", err);
163 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
168 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
170 err = WINTRUST_DefaultVerify(hwnd, actionID, data);
171 WINTRUST_DefaultClose(hwnd, actionID, data);
172 TRACE("returning %08x\n", err);
176 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
179 WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
180 /* Undocumented: the published software action is passed a path,
181 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
183 LPCWSTR path = (LPCWSTR)data->pFile;
184 LPWIN_TRUST_SUBJECT_FILE subjectFile =
185 (LPWIN_TRUST_SUBJECT_FILE)data->pSIPClientData;
186 WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
188 TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
189 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
190 fileInfo.pcwszFilePath = path;
191 fileInfo.hFile = subjectFile->hFile;
192 wintrust_data.pFile = &fileInfo;
193 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
194 wintrust_data.dwUIChoice = WTD_UI_NONE;
196 return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
199 /***********************************************************************
200 * WinVerifyTrust (WINTRUST.@)
202 * Verifies an object by calling the specified trust provider.
205 * hwnd [I] Handle to a caller window.
206 * ActionID [I] Pointer to a GUID that identifies the action to perform.
207 * ActionData [I] Information used by the trust provider to verify the object.
211 * Failure: A TRUST_E_* error code.
214 * Trust providers can be found at:
215 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
217 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
219 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
220 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
221 static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
222 static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
223 LONG err = ERROR_SUCCESS;
224 WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
226 TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
228 /* Support for known old-style callers: */
229 if (IsEqualGUID(ActionID, &published_software))
230 err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
233 /* Check known actions to warn of possible problems */
234 if (!IsEqualGUID(ActionID, &unknown) &&
235 !IsEqualGUID(ActionID, &generic_verify_v2))
236 WARN("unknown action %s, default behavior may not be right\n",
237 debugstr_guid(ActionID));
238 switch (actionData->dwStateAction)
240 case WTD_STATEACTION_IGNORE:
241 err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
243 case WTD_STATEACTION_VERIFY:
244 err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
246 case WTD_STATEACTION_CLOSE:
247 err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
250 FIXME("unimplemented for %d\n", actionData->dwStateAction);
254 TRACE("returning %08x\n", err);
258 /***********************************************************************
259 * WinVerifyTrustEx (WINTRUST.@)
261 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
262 WINTRUST_DATA* ActionData )
264 return WinVerifyTrust(hwnd, ActionID, ActionData);
267 /***********************************************************************
268 * WTHelperGetProvSignerFromChain (WINTRUST.@)
270 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
271 CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
272 DWORD idxCounterSigner)
274 CRYPT_PROVIDER_SGNR *sgnr;
276 TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
279 if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
281 sgnr = &pProvData->pasSigners[idxSigner];
284 if (idxCounterSigner >= sgnr->csCounterSigners ||
285 !sgnr->pasCounterSigners)
287 sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
289 TRACE("returning %p\n", sgnr);
293 /***********************************************************************
294 * WTHelperGetProvCertFromChain (WINTRUST.@)
296 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
297 CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
299 CRYPT_PROVIDER_CERT *cert;
301 TRACE("(%p %d)\n", pSgnr, idxCert);
303 if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
305 cert = &pSgnr->pasCertChain[idxCert];
306 TRACE("returning %p\n", cert);
310 /***********************************************************************
311 * WTHelperProvDataFromStateData (WINTRUST.@)
313 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
315 TRACE("%p\n", hStateData);
316 return (CRYPT_PROVIDER_DATA *)hStateData;
319 static const WCHAR Software_Publishing[] = {
320 'S','o','f','t','w','a','r','e','\\',
321 'M','i','c','r','o','s','o','f','t','\\',
322 'W','i','n','d','o','w','s','\\',
323 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
324 'W','i','n','t','r','u','s','t','\\',
325 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
326 'S','o','f','t','w','a','r','e',' ',
327 'P','u','b','l','i','s','h','i','n','g',0 };
328 static const WCHAR State[] = { 'S','t','a','t','e',0 };
330 /***********************************************************************
331 * WintrustGetRegPolicyFlags (WINTRUST.@)
333 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
338 TRACE("%p\n", pdwPolicyFlags);
341 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
342 KEY_READ, NULL, &key, NULL);
345 DWORD size = sizeof(DWORD);
347 r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
352 /* Failed to query, create and return default value */
353 *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
354 WTPF_OFFLINEOKNBU_COM |
355 WTPF_OFFLINEOKNBU_IND |
358 WintrustSetRegPolicyFlags(*pdwPolicyFlags);
363 /***********************************************************************
364 * WintrustSetRegPolicyFlags (WINTRUST.@)
366 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
371 TRACE("%x\n", dwPolicyFlags);
373 r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
374 NULL, 0, KEY_WRITE, NULL, &key, NULL);
377 r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
381 if (r) SetLastError(r);
382 return r == ERROR_SUCCESS;
385 /* Utility functions */
386 void * WINAPI WINTRUST_Alloc(DWORD cb)
388 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
391 void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
393 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
396 void WINAPI WINTRUST_Free(void *p)
398 HeapFree(GetProcessHeap(), 0, p);
401 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
406 data->pahStores = WINTRUST_ReAlloc(data->pahStores,
407 (data->chStores + 1) * sizeof(HCERTSTORE));
410 data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
415 data->pahStores[data->chStores++] = CertDuplicateStore(store);
419 SetLastError(ERROR_OUTOFMEMORY);
423 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
424 BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
428 if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
430 SetLastError(ERROR_INVALID_PARAMETER);
435 FIXME("unimplemented for counter signers\n");
436 SetLastError(ERROR_INVALID_PARAMETER);
440 data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
441 (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
444 data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
447 if (data->pasSigners)
449 if (idxSigner < data->csSigners)
450 memmove(&data->pasSigners[idxSigner],
451 &data->pasSigners[idxSigner + 1],
452 (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
454 if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
456 /* The PSDK says psSigner should be allocated using pfnAlloc, but
457 * it doesn't say anything about ownership. Since callers are
458 * internal, assume ownership is passed, and just store the
461 memcpy(&data->pasSigners[idxSigner], sgnr,
462 sizeof(CRYPT_PROVIDER_SGNR));
465 memset(&data->pasSigners[idxSigner], 0,
466 sizeof(CRYPT_PROVIDER_SGNR));
470 SetLastError(ERROR_OUTOFMEMORY);
474 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
475 BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
481 FIXME("unimplemented for counter signers\n");
482 SetLastError(ERROR_INVALID_PARAMETER);
485 if (data->pasSigners[idxSigner].csCertChain)
486 data->pasSigners[idxSigner].pasCertChain =
487 WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
488 (data->pasSigners[idxSigner].csCertChain + 1) *
489 sizeof(CRYPT_PROVIDER_CERT));
492 data->pasSigners[idxSigner].pasCertChain =
493 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
494 data->pasSigners[idxSigner].csCertChain = 0;
496 if (data->pasSigners[idxSigner].pasCertChain)
498 CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
499 data->pasSigners[idxSigner].csCertChain];
501 cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
502 cert->pCert = CertDuplicateCertificateContext(pCert2Add);
503 data->pasSigners[idxSigner].csCertChain++;
507 SetLastError(ERROR_OUTOFMEMORY);