~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/wintrust/wintrust_main.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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 "cryptdlg.h"
 37 #include "cryptuiapi.h"
 38 #include "wintrust_priv.h"
 39 #include "wine/debug.h"
 40 
 41 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
 42 
 43 
 44 /* Utility functions */
 45 void * WINAPI WINTRUST_Alloc(DWORD cb)
 46 {
 47     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
 48 }
 49 
 50 static void* WINTRUST_ReAlloc(void *ptr, DWORD cb) __WINE_ALLOC_SIZE(2);
 51 static void* WINTRUST_ReAlloc(void *ptr, DWORD cb)
 52 {
 53     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
 54 }
 55 
 56 void WINAPI WINTRUST_Free(void *p)
 57 {
 58     HeapFree(GetProcessHeap(), 0, p);
 59 }
 60 
 61 /***********************************************************************
 62  *              DllMain  (WINTRUST.@)
 63  */
 64 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
 65 {
 66     switch(reason)
 67     {
 68     case DLL_PROCESS_ATTACH:
 69         DisableThreadLibraryCalls( inst );
 70         break;
 71     }
 72     return TRUE;
 73 }
 74 
 75 /***********************************************************************
 76  *              TrustIsCertificateSelfSigned (WINTRUST.@)
 77  */
 78 BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
 79 {
 80     PCERT_EXTENSION ext;
 81     DWORD size;
 82     BOOL ret;
 83 
 84     TRACE("%p\n", cert);
 85     if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
 86      cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
 87     {
 88         CERT_AUTHORITY_KEY_ID2_INFO *info;
 89 
 90         ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
 91          X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
 92          CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
 93          &info, &size);
 94         if (ret)
 95         {
 96             if (info->AuthorityCertIssuer.cAltEntry &&
 97              info->AuthorityCertSerialNumber.cbData)
 98             {
 99                 PCERT_ALT_NAME_ENTRY directoryName = NULL;
100                 DWORD i;
101 
102                 for (i = 0; !directoryName &&
103                  i < info->AuthorityCertIssuer.cAltEntry; i++)
104                     if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
105                      == CERT_ALT_NAME_DIRECTORY_NAME)
106                         directoryName =
107                          &info->AuthorityCertIssuer.rgAltEntry[i];
108                 if (directoryName)
109                 {
110                     ret = CertCompareCertificateName(cert->dwCertEncodingType,
111                      &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
112                      && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
113                      &cert->pCertInfo->SerialNumber);
114                 }
115                 else
116                 {
117                     FIXME("no supported name type in authority key id2\n");
118                     ret = FALSE;
119                 }
120             }
121             else if (info->KeyId.cbData)
122             {
123                 ret = CertGetCertificateContextProperty(cert,
124                  CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
125                 if (ret && size == info->KeyId.cbData)
126                 {
127                     LPBYTE buf = CryptMemAlloc(size);
128 
129                     if (buf)
130                     {
131                         CertGetCertificateContextProperty(cert,
132                          CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
133                         ret = !memcmp(buf, info->KeyId.pbData, size);
134                         CryptMemFree(buf);
135                     }
136                     else
137                         ret = FALSE;
138                 }
139                 else
140                     ret = FALSE;
141             }
142             LocalFree(info);
143         }
144     }
145     else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
146      cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
147     {
148         CERT_AUTHORITY_KEY_ID_INFO *info;
149 
150         ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
151          X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
152          CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
153          &info, &size);
154         if (ret)
155         {
156             if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
157             {
158                 ret = CertCompareCertificateName(cert->dwCertEncodingType,
159                  &info->CertIssuer, &cert->pCertInfo->Issuer) &&
160                  CertCompareIntegerBlob(&info->CertSerialNumber,
161                  &cert->pCertInfo->SerialNumber);
162             }
163             else if (info->KeyId.cbData)
164             {
165                 ret = CertGetCertificateContextProperty(cert,
166                  CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
167                 if (ret && size == info->KeyId.cbData)
168                 {
169                     LPBYTE buf = CryptMemAlloc(size);
170 
171                     if (buf)
172                     {
173                         CertGetCertificateContextProperty(cert,
174                          CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
175                         ret = !memcmp(buf, info->KeyId.pbData, size);
176                         CryptMemFree(buf);
177                     }
178                     else
179                         ret = FALSE;
180                 }
181                 else
182                     ret = FALSE;
183             }
184             else
185                 ret = FALSE;
186             LocalFree(info);
187         }
188     }
189     else
190         ret = CertCompareCertificateName(cert->dwCertEncodingType,
191          &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
192     return ret;
193 }
194 
195 typedef HRESULT (WINAPI *wintrust_step_func)(CRYPT_PROVIDER_DATA *data);
196 
197 struct wintrust_step
198 {
199     wintrust_step_func func;
200     DWORD              error_index;
201 };
202 
203 static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps,
204  DWORD numSteps, CRYPT_PROVIDER_DATA *provData)
205 {
206     DWORD i, err = ERROR_SUCCESS;
207 
208     for (i = 0; !err && i < numSteps; i++)
209     {
210         err = steps[i].func(provData);
211         if (err)
212             err = provData->padwTrustStepErrors[steps[i].error_index];
213     }
214     return err;
215 }
216 
217 static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void)
218 {
219     CRYPT_PROVIDER_DATA *provData;
220 
221     provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
222     if (!provData)
223         goto oom;
224     provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
225 
226     provData->padwTrustStepErrors =
227      WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
228     if (!provData->padwTrustStepErrors)
229         goto oom;
230     provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
231 
232     provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
233     if (!provData->u.pPDSip)
234         goto oom;
235     provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP);
236 
237     provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
238     if (!provData->psPfns)
239         goto oom;
240     provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
241     return provData;
242 
243 oom:
244     if (provData)
245     {
246         WINTRUST_Free(provData->padwTrustStepErrors);
247         WINTRUST_Free(provData->u.pPDSip);
248         WINTRUST_Free(provData->psPfns);
249         WINTRUST_Free(provData);
250     }
251     return NULL;
252 }
253 
254 /* Adds trust steps for each function in psPfns.  Assumes steps has at least
255  * 5 entries.  Returns the number of steps added.
256  */
257 static DWORD WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step *steps,
258  const CRYPT_PROVIDER_FUNCTIONS *psPfns)
259 {
260     DWORD numSteps = 0;
261 
262     if (psPfns->pfnInitialize)
263     {
264         steps[numSteps].func = psPfns->pfnInitialize;
265         steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
266     }
267     if (psPfns->pfnObjectTrust)
268     {
269         steps[numSteps].func = psPfns->pfnObjectTrust;
270         steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
271     }
272     if (psPfns->pfnSignatureTrust)
273     {
274         steps[numSteps].func = psPfns->pfnSignatureTrust;
275         steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
276     }
277     if (psPfns->pfnCertificateTrust)
278     {
279         steps[numSteps].func = psPfns->pfnCertificateTrust;
280         steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
281     }
282     if (psPfns->pfnFinalPolicy)
283     {
284         steps[numSteps].func = psPfns->pfnFinalPolicy;
285         steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
286     }
287     return numSteps;
288 }
289 
290 static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
291  WINTRUST_DATA *data)
292 {
293     DWORD err = ERROR_SUCCESS, numSteps = 0;
294     CRYPT_PROVIDER_DATA *provData;
295     BOOL ret;
296     struct wintrust_step verifySteps[5];
297 
298     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
299 
300     provData = WINTRUST_AllocateProviderData();
301     if (!provData)
302         return ERROR_OUTOFMEMORY;
303 
304     ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
305     if (!ret)
306     {
307         err = GetLastError();
308         goto error;
309     }
310 
311     data->hWVTStateData = provData;
312     provData->pWintrustData = data;
313     if (hwnd == INVALID_HANDLE_VALUE)
314         provData->hWndParent = GetDesktopWindow();
315     else
316         provData->hWndParent = hwnd;
317     provData->pgActionID = actionID;
318     WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
319 
320     numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
321      provData->psPfns);
322     err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
323     goto done;
324 
325 error:
326     if (provData)
327     {
328         WINTRUST_Free(provData->padwTrustStepErrors);
329         WINTRUST_Free(provData->u.pPDSip);
330         WINTRUST_Free(provData->psPfns);
331         WINTRUST_Free(provData);
332     }
333 done:
334     TRACE("returning %08x\n", err);
335     return err;
336 }
337 
338 static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
339  WINTRUST_DATA *data)
340 {
341     DWORD err = ERROR_SUCCESS;
342     CRYPT_PROVIDER_DATA *provData = data->hWVTStateData;
343 
344     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
345 
346     if (provData)
347     {
348         if (provData->psPfns->pfnCleanupPolicy)
349             err = provData->psPfns->pfnCleanupPolicy(provData);
350 
351         WINTRUST_Free(provData->padwTrustStepErrors);
352         WINTRUST_Free(provData->u.pPDSip);
353         WINTRUST_Free(provData->psPfns);
354         WINTRUST_Free(provData);
355         data->hWVTStateData = NULL;
356     }
357     TRACE("returning %08x\n", err);
358     return err;
359 }
360 
361 static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
362  WINTRUST_DATA *data)
363 {
364     LONG err;
365 
366     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
367 
368     err = WINTRUST_DefaultVerify(hwnd, actionID, data);
369     WINTRUST_DefaultClose(hwnd, actionID, data);
370     TRACE("returning %08x\n", err);
371     return err;
372 }
373 
374 static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
375  WINTRUST_DATA *data)
376 {
377     WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
378     /* Undocumented: the published software action is passed a path,
379      * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
380      */
381     LPWIN_TRUST_SUBJECT_FILE subjectFile = data->pSIPClientData;
382     WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
383 
384     TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
385     TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
386     fileInfo.pcwszFilePath = subjectFile->lpPath;
387     fileInfo.hFile = subjectFile->hFile;
388     wintrust_data.u.pFile = &fileInfo;
389     wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
390     wintrust_data.dwUIChoice = WTD_UI_NONE;
391 
392     return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
393 }
394 
395 /* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
396  * action is not stored in the registry and is located in wintrust, not in
397  * cryptdlg along with the rest of the implementation (verified by running the
398  * action with a native wintrust.dll.)
399  */
400 static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data)
401 {
402     BOOL ret;
403 
404     TRACE("(%p)\n", data);
405 
406     if (!data->padwTrustStepErrors)
407         return S_FALSE;
408 
409     switch (data->pWintrustData->dwUnionChoice)
410     {
411     case WTD_CHOICE_BLOB:
412         if (data->pWintrustData->u.pBlob &&
413          WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(WINTRUST_BLOB_INFO,
414          data->pWintrustData->u.pBlob->cbStruct, pbMemObject) &&
415          data->pWintrustData->u.pBlob->cbMemObject ==
416          sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
417          data->pWintrustData->u.pBlob->pbMemObject)
418         {
419             CERT_VERIFY_CERTIFICATE_TRUST *pCert =
420              (CERT_VERIFY_CERTIFICATE_TRUST *)
421              data->pWintrustData->u.pBlob->pbMemObject;
422 
423             if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
424              pCert->pccert)
425             {
426                 CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
427                 DWORD i;
428                 SYSTEMTIME sysTime;
429 
430                 /* Add a signer with nothing but the time to verify, so we can
431                  * add a cert to it
432                  */
433                 GetSystemTime(&sysTime);
434                 SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
435                 ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
436                 if (!ret)
437                     goto error;
438                 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
439                  pCert->pccert);
440                 if (!ret)
441                     goto error;
442                 for (i = 0; ret && i < pCert->cRootStores; i++)
443                     ret = data->psPfns->pfnAddStore2Chain(data,
444                      pCert->rghstoreRoots[i]);
445                 for (i = 0; ret && i < pCert->cStores; i++)
446                     ret = data->psPfns->pfnAddStore2Chain(data,
447                      pCert->rghstoreCAs[i]);
448                 for (i = 0; ret && i < pCert->cTrustStores; i++)
449                     ret = data->psPfns->pfnAddStore2Chain(data,
450                      pCert->rghstoreTrust[i]);
451             }
452             else
453             {
454                 SetLastError(ERROR_INVALID_PARAMETER);
455                 ret = FALSE;
456             }
457         }
458         else
459         {
460             SetLastError(ERROR_INVALID_PARAMETER);
461             ret = FALSE;
462         }
463         break;
464     default:
465         FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
466         SetLastError(ERROR_INVALID_PARAMETER);
467         ret = FALSE;
468     }
469 
470 error:
471     if (!ret)
472         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
473          GetLastError();
474     TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
475      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
476     return ret ? S_OK : S_FALSE;
477 }
478 
479 static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID,
480  WINTRUST_DATA *data)
481 {
482     DWORD err = ERROR_SUCCESS, numSteps = 0;
483     CRYPT_PROVIDER_DATA *provData;
484     BOOL ret;
485     struct wintrust_step verifySteps[5];
486 
487     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
488 
489     provData = WINTRUST_AllocateProviderData();
490     if (!provData)
491         return ERROR_OUTOFMEMORY;
492 
493     ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
494     if (!ret)
495     {
496         err = GetLastError();
497         goto error;
498     }
499     if (!provData->psPfns->pfnObjectTrust)
500         provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust;
501     /* Not sure why, but native skips the policy check */
502     provData->psPfns->pfnCertCheckPolicy = NULL;
503 
504     data->hWVTStateData = provData;
505     provData->pWintrustData = data;
506     if (hwnd == INVALID_HANDLE_VALUE)
507         provData->hWndParent = GetDesktopWindow();
508     else
509         provData->hWndParent = hwnd;
510     provData->pgActionID = actionID;
511     WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
512 
513     numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
514      provData->psPfns);
515     err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
516     goto done;
517 
518 error:
519     if (provData)
520     {
521         WINTRUST_Free(provData->padwTrustStepErrors);
522         WINTRUST_Free(provData->u.pPDSip);
523         WINTRUST_Free(provData->psPfns);
524         WINTRUST_Free(provData);
525     }
526 done:
527     TRACE("returning %08x\n", err);
528     return err;
529 }
530 
531 static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID,
532  WINTRUST_DATA *data)
533 {
534     LONG err;
535 
536     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
537 
538     err = WINTRUST_CertVerify(hwnd, actionID, data);
539     WINTRUST_DefaultClose(hwnd, actionID, data);
540     TRACE("returning %08x\n", err);
541     return err;
542 }
543 
544 static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID,
545  WINTRUST_DATA *data)
546 {
547     DWORD stateAction;
548     LONG err = ERROR_SUCCESS;
549 
550     if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction))
551         stateAction = data->dwStateAction;
552     else
553     {
554         TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
555         stateAction = WTD_STATEACTION_IGNORE;
556     }
557     switch (stateAction)
558     {
559     case WTD_STATEACTION_IGNORE:
560         err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data);
561         break;
562     case WTD_STATEACTION_VERIFY:
563         err = WINTRUST_CertVerify(hwnd, actionID, data);
564         break;
565     case WTD_STATEACTION_CLOSE:
566         err = WINTRUST_DefaultClose(hwnd, actionID, data);
567         break;
568     default:
569         FIXME("unimplemented for %d\n", data->dwStateAction);
570     }
571     return err;
572 }
573 
574 static void dump_file_info(WINTRUST_FILE_INFO *pFile)
575 {
576     TRACE("%p\n", pFile);
577     if (pFile)
578     {
579         TRACE("cbStruct: %d\n", pFile->cbStruct);
580         TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath));
581         TRACE("hFile: %p\n", pFile->hFile);
582         TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject));
583     }
584 }
585 
586 static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog)
587 {
588     TRACE("%p\n", catalog);
589     if (catalog)
590     {
591         TRACE("cbStruct: %d\n", catalog->cbStruct);
592         TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion);
593         TRACE("pcwszCatalogFilePath: %s\n",
594          debugstr_w(catalog->pcwszCatalogFilePath));
595         TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag));
596         TRACE("pcwszMemberFilePath: %s\n",
597          debugstr_w(catalog->pcwszMemberFilePath));
598         TRACE("hMemberFile: %p\n", catalog->hMemberFile);
599         TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash);
600         TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash);
601         TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext);
602     }
603 }
604 
605 static void dump_blob_info(WINTRUST_BLOB_INFO *blob)
606 {
607     TRACE("%p\n", blob);
608     if (blob)
609     {
610         TRACE("cbStruct: %d\n", blob->cbStruct);
611         TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject));
612         TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName));
613         TRACE("cbMemObject: %d\n", blob->cbMemObject);
614         TRACE("pbMemObject: %p\n", blob->pbMemObject);
615         TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg);
616         TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg);
617     }
618 }
619 
620 static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr)
621 {
622     TRACE("%p\n", sgnr);
623     if (sgnr)
624     {
625         TRACE("cbStruct: %d\n", sgnr->cbStruct);
626         TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName));
627         TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo);
628         TRACE("chStores: %d\n", sgnr->chStores);
629     }
630 }
631 
632 static void dump_cert_info(WINTRUST_CERT_INFO *cert)
633 {
634     TRACE("%p\n", cert);
635     if (cert)
636     {
637         TRACE("cbStruct: %d\n", cert->cbStruct);
638         TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName));
639         TRACE("psCertContext: %p\n", cert->psCertContext);
640         TRACE("chStores: %d\n", cert->chStores);
641         TRACE("dwFlags: %08x\n", cert->dwFlags);
642         TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf);
643     }
644 }
645 
646 static void dump_wintrust_data(WINTRUST_DATA *data)
647 {
648     TRACE("%p\n", data);
649     if (data)
650     {
651         TRACE("cbStruct: %d\n", data->cbStruct);
652         TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData);
653         TRACE("pSIPClientData: %p\n", data->pSIPClientData);
654         TRACE("dwUIChoice: %d\n", data->dwUIChoice);
655         TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks);
656         TRACE("dwUnionChoice: %d\n", data->dwUnionChoice);
657         switch (data->dwUnionChoice)
658         {
659         case WTD_CHOICE_FILE:
660             dump_file_info(data->u.pFile);
661             break;
662         case WTD_CHOICE_CATALOG:
663             dump_catalog_info(data->u.pCatalog);
664             break;
665         case WTD_CHOICE_BLOB:
666             dump_blob_info(data->u.pBlob);
667             break;
668         case WTD_CHOICE_SIGNER:
669             dump_sgnr_info(data->u.pSgnr);
670             break;
671         case WTD_CHOICE_CERT:
672             dump_cert_info(data->u.pCert);
673             break;
674         }
675         TRACE("dwStateAction: %d\n", data->dwStateAction);
676         TRACE("hWVTStateData: %p\n", data->hWVTStateData);
677         TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference));
678         TRACE("dwProvFlags: %08x\n", data->dwProvFlags);
679         TRACE("dwUIContext: %d\n", data->dwUIContext);
680     }
681 }
682 
683 /***********************************************************************
684  *              WinVerifyTrust (WINTRUST.@)
685  *
686  * Verifies an object by calling the specified trust provider.
687  *
688  * PARAMS
689  *   hwnd       [I] Handle to a caller window.
690  *   ActionID   [I] Pointer to a GUID that identifies the action to perform.
691  *   ActionData [I] Information used by the trust provider to verify the object.
692  *
693  * RETURNS
694  *   Success: Zero.
695  *   Failure: A TRUST_E_* error code.
696  *
697  * NOTES
698  *   Trust providers can be found at:
699  *   HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
700  */
701 LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
702 {
703     static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
704      0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
705     static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
706     static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
707     static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
708     static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
709     static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY;
710     LONG err = ERROR_SUCCESS;
711     WINTRUST_DATA *actionData = ActionData;
712 
713     TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
714     dump_wintrust_data(ActionData);
715 
716     /* Support for known old-style callers: */
717     if (IsEqualGUID(ActionID, &published_software))
718         err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
719     else if (IsEqualGUID(ActionID, &cert_action_verify))
720         err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData);
721     else
722     {
723         DWORD stateAction;
724 
725         /* Check known actions to warn of possible problems */
726         if (!IsEqualGUID(ActionID, &unknown) &&
727          !IsEqualGUID(ActionID, &generic_verify_v2) &&
728          !IsEqualGUID(ActionID, &generic_cert_verify) &&
729          !IsEqualGUID(ActionID, &generic_chain_verify))
730             WARN("unknown action %s, default behavior may not be right\n",
731              debugstr_guid(ActionID));
732         if (WVT_ISINSTRUCT(WINTRUST_DATA, actionData->cbStruct, dwStateAction))
733             stateAction = actionData->dwStateAction;
734         else
735         {
736             TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
737             stateAction = WTD_STATEACTION_IGNORE;
738         }
739         switch (stateAction)
740         {
741         case WTD_STATEACTION_IGNORE:
742             err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
743             break;
744         case WTD_STATEACTION_VERIFY:
745             err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
746             break;
747         case WTD_STATEACTION_CLOSE:
748             err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
749             break;
750         default:
751             FIXME("unimplemented for %d\n", actionData->dwStateAction);
752         }
753     }
754 
755     TRACE("returning %08x\n", err);
756     return err;
757 }
758 
759 /***********************************************************************
760  *              WinVerifyTrustEx (WINTRUST.@)
761  */
762 HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
763  WINTRUST_DATA* ActionData )
764 {
765     return WinVerifyTrust(hwnd, ActionID, ActionData);
766 }
767 
768 /***********************************************************************
769  *              WTHelperGetProvSignerFromChain (WINTRUST.@)
770  */
771 CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
772  CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
773  DWORD idxCounterSigner)
774 {
775     CRYPT_PROVIDER_SGNR *sgnr;
776 
777     TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
778      idxCounterSigner);
779 
780     if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
781         return NULL;
782     sgnr = &pProvData->pasSigners[idxSigner];
783     if (fCounterSigner)
784     {
785         if (idxCounterSigner >= sgnr->csCounterSigners ||
786          !sgnr->pasCounterSigners)
787             return NULL;
788         sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
789     }
790     TRACE("returning %p\n", sgnr);
791     return sgnr;
792 }
793 
794 /***********************************************************************
795  *              WTHelperGetProvCertFromChain (WINTRUST.@)
796  */
797 CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
798  CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
799 {
800     CRYPT_PROVIDER_CERT *cert;
801 
802     TRACE("(%p %d)\n", pSgnr, idxCert);
803 
804     if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
805         return NULL;
806     cert = &pSgnr->pasCertChain[idxCert];
807     TRACE("returning %p\n", cert);
808     return cert;
809 }
810 
811 CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain(
812  CRYPT_PROVIDER_DATA* pProvData,
813  GUID* pgProviderID)
814 {
815     CRYPT_PROVIDER_PRIVDATA *privdata = NULL;
816     DWORD i;
817 
818     TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID));
819 
820     for (i = 0; i < pProvData->csProvPrivData; i++)
821         if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID))
822         {
823             privdata = &pProvData->pasProvPrivData[i];
824             break;
825         }
826 
827     return privdata;
828 }
829 
830 /***********************************************************************
831  *              WTHelperProvDataFromStateData (WINTRUST.@)
832  */
833 CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
834 {
835     TRACE("%p\n", hStateData);
836     return hStateData;
837 }
838 
839 /***********************************************************************
840  *              WTHelperGetFileName(WINTRUST.@)
841  */
842 LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data)
843 {
844     TRACE("%p\n",data);
845     if (data->dwUnionChoice == WTD_CHOICE_FILE)
846         return data->u.pFile->pcwszFilePath;
847     else
848         return NULL;
849 }
850 
851 /***********************************************************************
852  *              WTHelperGetFileHandle(WINTRUST.@)
853  */
854 HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
855 {
856     TRACE("%p\n",data);
857     if (data->dwUnionChoice == WTD_CHOICE_FILE)
858         return data->u.pFile->hFile;
859     else
860         return INVALID_HANDLE_VALUE;
861 }
862 
863 static BOOL WINAPI WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo, void *pvArg)
864 {
865     PCCRYPT_OID_INFO **usages = pvArg;
866     DWORD cUsages;
867     BOOL ret;
868 
869     if (!*usages)
870     {
871         cUsages = 0;
872         *usages = WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO));
873     }
874     else
875     {
876         PCCRYPT_OID_INFO *ptr;
877 
878         /* Count the existing usages.
879          * FIXME: make sure the new usage doesn't duplicate any in the list?
880          */
881         for (cUsages = 0, ptr = *usages; *ptr; ptr++, cUsages++)
882             ;
883         *usages = WINTRUST_ReAlloc(*usages,
884          (cUsages + 2) * sizeof(PCCRYPT_OID_INFO));
885     }
886     if (*usages)
887     {
888         (*usages)[cUsages] = pInfo;
889         (*usages)[cUsages + 1] = NULL;
890         ret = TRUE;
891     }
892     else
893     {
894         SetLastError(ERROR_OUTOFMEMORY);
895         ret = FALSE;
896     }
897     return ret;
898 }
899 
900 /***********************************************************************
901  *              WTHelperGetKnownUsages(WINTRUST.@)
902  *
903  * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs.
904  *
905  * PARAMS
906  *  action      [In]     1 => allocate and return known usages, 2 => free previously
907  *                       allocated usages.
908  *  usages      [In/Out] If action == 1, *usages is set to an array of
909  *                       PCCRYPT_OID_INFO *.  The array is terminated with a NULL
910  *                       pointer.
911  *                       If action == 2, *usages is freed.
912  *
913  * RETURNS
914  *  TRUE on success, FALSE on failure.
915  */
916 BOOL WINAPI WTHelperGetKnownUsages(DWORD action, PCCRYPT_OID_INFO **usages)
917 {
918     BOOL ret;
919 
920     TRACE("(%d, %p)\n", action, usages);
921 
922     if (!usages)
923     {
924         SetLastError(ERROR_INVALID_PARAMETER);
925         return FALSE;
926     }
927 
928     if (action == 1)
929     {
930         *usages = NULL;
931         ret = CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID, 0, usages,
932          WINTRUST_enumUsages);
933     }
934     else if (action == 2)
935     {
936         WINTRUST_Free(*usages);
937         *usages = NULL;
938         ret = TRUE;
939     }
940     else
941     {
942         WARN("unknown action %d\n", action);
943         SetLastError(ERROR_INVALID_PARAMETER);
944         ret = FALSE;
945     }
946     return ret;
947 }
948 
949 static const WCHAR Software_Publishing[] = {
950  'S','o','f','t','w','a','r','e','\\',
951  'M','i','c','r','o','s','o','f','t','\\',
952  'W','i','n','d','o','w','s','\\',
953  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
954  'W','i','n','t','r','u','s','t','\\',
955  'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
956  'S','o','f','t','w','a','r','e',' ',
957  'P','u','b','l','i','s','h','i','n','g',0 };
958 static const WCHAR State[] = { 'S','t','a','t','e',0 };
959 
960 /***********************************************************************
961  *              WintrustGetRegPolicyFlags (WINTRUST.@)
962  */
963 void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
964 {
965     HKEY key;
966     LONG r;
967 
968     TRACE("%p\n", pdwPolicyFlags);
969 
970     *pdwPolicyFlags = 0;
971     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
972      KEY_READ, NULL, &key, NULL);
973     if (!r)
974     {
975         DWORD size = sizeof(DWORD);
976 
977         r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
978          &size);
979         RegCloseKey(key);
980         if (r)
981         {
982             /* Failed to query, create and return default value */
983             *pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
984              WTPF_OFFLINEOKNBU_COM |
985              WTPF_OFFLINEOKNBU_IND |
986              WTPF_OFFLINEOK_COM |
987              WTPF_OFFLINEOK_IND;
988             WintrustSetRegPolicyFlags(*pdwPolicyFlags);
989         }
990     }
991 }
992 
993 /***********************************************************************
994  *              WintrustSetRegPolicyFlags (WINTRUST.@)
995  */
996 BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
997 {
998     HKEY key;
999     LONG r;
1000 
1001     TRACE("%x\n", dwPolicyFlags);
1002 
1003     r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
1004      NULL, 0, KEY_WRITE, NULL, &key, NULL);
1005     if (!r)
1006     {
1007         r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
1008          sizeof(DWORD));
1009         RegCloseKey(key);
1010     }
1011     if (r) SetLastError(r);
1012     return r == ERROR_SUCCESS;
1013 }
1014 
1015 /* Utility functions */
1016 
1017 BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
1018 {
1019     BOOL ret = FALSE;
1020 
1021     TRACE("(%p, %p)\n", data, store);
1022 
1023     if (data->chStores)
1024         data->pahStores = WINTRUST_ReAlloc(data->pahStores,
1025          (data->chStores + 1) * sizeof(HCERTSTORE));
1026     else
1027     {
1028         data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
1029         data->chStores = 0;
1030     }
1031     if (data->pahStores)
1032     {
1033         data->pahStores[data->chStores++] = CertDuplicateStore(store);
1034         ret = TRUE;
1035     }
1036     else
1037         SetLastError(ERROR_OUTOFMEMORY);
1038     return ret;
1039 }
1040 
1041 BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
1042  BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
1043 {
1044     BOOL ret = FALSE;
1045 
1046     TRACE("(%p, %d, %d, %p)\n", data, fCounterSigner, idxSigner, sgnr);
1047 
1048     if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
1049     {
1050         SetLastError(ERROR_INVALID_PARAMETER);
1051         return FALSE;
1052     }
1053     if (fCounterSigner)
1054     {
1055         FIXME("unimplemented for counter signers\n");
1056         SetLastError(ERROR_INVALID_PARAMETER);
1057         return FALSE;
1058     }
1059     if (data->csSigners)
1060         data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
1061          (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
1062     else
1063     {
1064         data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
1065         data->csSigners = 0;
1066     }
1067     if (data->pasSigners)
1068     {
1069         if (idxSigner < data->csSigners)
1070             memmove(&data->pasSigners[idxSigner],
1071              &data->pasSigners[idxSigner + 1],
1072              (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
1073         ret = TRUE;
1074         if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
1075         {
1076             /* The PSDK says psSigner should be allocated using pfnAlloc, but
1077              * it doesn't say anything about ownership.  Since callers are
1078              * internal, assume ownership is passed, and just store the
1079              * pointer.
1080              */
1081             memcpy(&data->pasSigners[idxSigner], sgnr,
1082              sizeof(CRYPT_PROVIDER_SGNR));
1083         }
1084         else
1085             memset(&data->pasSigners[idxSigner], 0,
1086              sizeof(CRYPT_PROVIDER_SGNR));
1087         data->csSigners++;
1088     }
1089     else
1090         SetLastError(ERROR_OUTOFMEMORY);
1091     return ret;
1092 }
1093 
1094 BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
1095  BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
1096 {
1097     BOOL ret = FALSE;
1098 
1099     TRACE("(%p, %d, %d, %d, %p)\n", data, idxSigner, fCounterSigner,
1100      idxSigner, pCert2Add);
1101 
1102     if (fCounterSigner)
1103     {
1104         FIXME("unimplemented for counter signers\n");
1105         SetLastError(ERROR_INVALID_PARAMETER);
1106         return FALSE;
1107     }
1108     if (data->pasSigners[idxSigner].csCertChain)
1109         data->pasSigners[idxSigner].pasCertChain =
1110          WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
1111          (data->pasSigners[idxSigner].csCertChain + 1) *
1112          sizeof(CRYPT_PROVIDER_CERT));
1113     else
1114     {
1115         data->pasSigners[idxSigner].pasCertChain =
1116          WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
1117         data->pasSigners[idxSigner].csCertChain = 0;
1118     }
1119     if (data->pasSigners[idxSigner].pasCertChain)
1120     {
1121         CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
1122          data->pasSigners[idxSigner].csCertChain];
1123 
1124         cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
1125         cert->pCert = CertDuplicateCertificateContext(pCert2Add);
1126         data->pasSigners[idxSigner].csCertChain++;
1127         ret = TRUE;
1128     }
1129     else
1130         SetLastError(ERROR_OUTOFMEMORY);
1131     return ret;
1132 }
1133 
1134 BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
1135  CRYPT_PROVIDER_PRIVDATA *pPrivData2Add)
1136 {
1137     BOOL ret = FALSE;
1138 
1139     TRACE("(%p, %p)\n", data, pPrivData2Add);
1140 
1141     if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA))
1142     {
1143         SetLastError(ERROR_INVALID_PARAMETER);
1144         WARN("invalid struct size\n");
1145         return FALSE;
1146     }
1147     if (data->csProvPrivData)
1148         data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData,
1149          (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR));
1150     else
1151     {
1152         data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
1153         data->csProvPrivData = 0;
1154     }
1155     if (data->pasProvPrivData)
1156     {
1157         DWORD i;
1158 
1159         for (i = 0; i < data->csProvPrivData; i++)
1160             if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i]))
1161                 break;
1162 
1163         data->pasProvPrivData[i] = *pPrivData2Add;
1164         if (i == data->csProvPrivData)
1165             data->csProvPrivData++;
1166     }
1167     else
1168         SetLastError(ERROR_OUTOFMEMORY);
1169     return ret;
1170 }
1171 
1172 /***********************************************************************
1173  *              OpenPersonalTrustDBDialog (WINTRUST.@)
1174  *
1175  * Opens the certificate manager dialog, showing only the stores that
1176  * contain trusted software publishers.
1177  *
1178  * PARAMS
1179  *  hwnd [I] handle of parent window
1180  *
1181  * RETURNS
1182  *  TRUE if the dialog could be opened, FALSE if not.
1183  */
1184 BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwnd)
1185 {
1186     CRYPTUI_CERT_MGR_STRUCT uiCertMgr;
1187 
1188     uiCertMgr.dwSize = sizeof(uiCertMgr);
1189     uiCertMgr.hwndParent = hwnd;
1190     uiCertMgr.dwFlags = CRYPTUI_CERT_MGR_PUBLISHER_TAB;
1191     uiCertMgr.pwszTitle = NULL;
1192     uiCertMgr.pszInitUsageOID = NULL;
1193     return CryptUIDlgCertMgr(&uiCertMgr);
1194 }
1195 
1196 /***********************************************************************
1197  *              WTHelperCertCheckValidSignature
1198  */
1199 HRESULT WINAPI WTHelperCertCheckValidSignature(CRYPT_PROVIDER_DATA *pProvData)
1200 {
1201     FIXME("Stub\n");
1202     return S_OK;
1203 }
1204 
1205 /***********************************************************************
1206  *              IsCatalogFile
1207  */
1208 BOOL WINAPI IsCatalogFile(HANDLE hFile, WCHAR *pwszFileName)
1209 {
1210     static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
1211     GUID guid;
1212 
1213     TRACE("(%p, %s)\n", hFile, debugstr_w(pwszFileName));
1214 
1215     if (!CryptSIPRetrieveSubjectGuid(pwszFileName, hFile, &guid))
1216         return FALSE;
1217     return IsEqualGUID(&guid, &catGUID);
1218 }
1219 
1220 /***********************************************************************
1221  *              FindCertsByIssuer
1222  */
1223 HRESULT WINAPI FindCertsByIssuer(PCERT_CHAIN pCertChains, DWORD *pcbCertChains,
1224  DWORD *pcCertChains, BYTE* pbEncodedIssuerName, DWORD cbEncodedIssuerName,
1225  LPCWSTR pwszPurpose, DWORD dwKeySpec)
1226 {
1227     FIXME("(%p, %p, %p, %p, %d, %s, %d): stub\n", pCertChains, pcbCertChains,
1228      pcCertChains, pbEncodedIssuerName, cbEncodedIssuerName,
1229      debugstr_w(pwszPurpose), dwKeySpec);
1230     return E_FAIL;
1231 }
1232 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.