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 "cryptuiapi.h"
38 #include "wintrust_priv.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(wintrust
);
44 /* Utility functions */
45 void * WINAPI
WINTRUST_Alloc(DWORD cb
)
47 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cb
);
50 static void* WINTRUST_ReAlloc(void *ptr
, DWORD cb
) __WINE_ALLOC_SIZE(2);
51 static void* WINTRUST_ReAlloc(void *ptr
, DWORD cb
)
53 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ptr
, cb
);
56 void WINAPI
WINTRUST_Free(void *p
)
58 HeapFree(GetProcessHeap(), 0, p
);
61 /***********************************************************************
62 * DllMain (WINTRUST.@)
64 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
68 case DLL_PROCESS_ATTACH
:
69 DisableThreadLibraryCalls( inst
);
75 /***********************************************************************
76 * TrustIsCertificateSelfSigned (WINTRUST.@)
78 BOOL WINAPI
TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert
)
83 ret
= CertCompareCertificateName(cert
->dwCertEncodingType
,
84 &cert
->pCertInfo
->Subject
, &cert
->pCertInfo
->Issuer
);
88 typedef HRESULT (WINAPI
*wintrust_step_func
)(CRYPT_PROVIDER_DATA
*data
);
92 wintrust_step_func func
;
96 static DWORD
WINTRUST_ExecuteSteps(const struct wintrust_step
*steps
,
97 DWORD numSteps
, CRYPT_PROVIDER_DATA
*provData
)
99 DWORD i
, err
= ERROR_SUCCESS
;
101 for (i
= 0; !err
&& i
< numSteps
; i
++)
103 err
= steps
[i
].func(provData
);
105 err
= provData
->padwTrustStepErrors
[steps
[i
].error_index
];
110 static CRYPT_PROVIDER_DATA
*WINTRUST_AllocateProviderData(void)
112 CRYPT_PROVIDER_DATA
*provData
;
114 provData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA
));
117 provData
->cbStruct
= sizeof(CRYPT_PROVIDER_DATA
);
119 provData
->padwTrustStepErrors
=
120 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
121 if (!provData
->padwTrustStepErrors
)
123 provData
->cdwTrustStepErrors
= TRUSTERROR_MAX_STEPS
;
125 provData
->u
.pPDSip
= WINTRUST_Alloc(sizeof(PROVDATA_SIP
));
126 if (!provData
->u
.pPDSip
)
128 provData
->u
.pPDSip
->cbStruct
= sizeof(PROVDATA_SIP
);
130 provData
->psPfns
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS
));
131 if (!provData
->psPfns
)
133 provData
->psPfns
->cbStruct
= sizeof(CRYPT_PROVIDER_FUNCTIONS
);
139 WINTRUST_Free(provData
->padwTrustStepErrors
);
140 WINTRUST_Free(provData
->u
.pPDSip
);
141 WINTRUST_Free(provData
->psPfns
);
142 WINTRUST_Free(provData
);
147 /* Adds trust steps for each function in psPfns. Assumes steps has at least
148 * 5 entries. Returns the number of steps added.
150 static DWORD
WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step
*steps
,
151 const CRYPT_PROVIDER_FUNCTIONS
*psPfns
)
155 if (psPfns
->pfnInitialize
)
157 steps
[numSteps
].func
= psPfns
->pfnInitialize
;
158 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_WVTINIT
;
160 if (psPfns
->pfnObjectTrust
)
162 steps
[numSteps
].func
= psPfns
->pfnObjectTrust
;
163 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_OBJPROV
;
165 if (psPfns
->pfnSignatureTrust
)
167 steps
[numSteps
].func
= psPfns
->pfnSignatureTrust
;
168 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_SIGPROV
;
170 if (psPfns
->pfnCertificateTrust
)
172 steps
[numSteps
].func
= psPfns
->pfnCertificateTrust
;
173 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_CERTPROV
;
175 if (psPfns
->pfnFinalPolicy
)
177 steps
[numSteps
].func
= psPfns
->pfnFinalPolicy
;
178 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_POLICYPROV
;
183 static LONG
WINTRUST_DefaultVerify(HWND hwnd
, GUID
*actionID
,
186 DWORD err
= ERROR_SUCCESS
, numSteps
= 0;
187 CRYPT_PROVIDER_DATA
*provData
;
189 struct wintrust_step verifySteps
[5];
191 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
193 provData
= WINTRUST_AllocateProviderData();
195 return ERROR_OUTOFMEMORY
;
197 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
200 err
= GetLastError();
204 data
->hWVTStateData
= provData
;
205 provData
->pWintrustData
= data
;
206 if (hwnd
== INVALID_HANDLE_VALUE
)
207 provData
->hWndParent
= GetDesktopWindow();
209 provData
->hWndParent
= hwnd
;
210 provData
->pgActionID
= actionID
;
211 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
213 numSteps
= WINTRUST_AddTrustStepsFromFunctions(verifySteps
,
215 err
= WINTRUST_ExecuteSteps(verifySteps
, numSteps
, provData
);
221 WINTRUST_Free(provData
->padwTrustStepErrors
);
222 WINTRUST_Free(provData
->u
.pPDSip
);
223 WINTRUST_Free(provData
->psPfns
);
224 WINTRUST_Free(provData
);
227 TRACE("returning %08x\n", err
);
231 static LONG
WINTRUST_DefaultClose(HWND hwnd
, GUID
*actionID
,
234 DWORD err
= ERROR_SUCCESS
;
235 CRYPT_PROVIDER_DATA
*provData
= data
->hWVTStateData
;
237 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
241 if (provData
->psPfns
->pfnCleanupPolicy
)
242 err
= provData
->psPfns
->pfnCleanupPolicy(provData
);
244 WINTRUST_Free(provData
->padwTrustStepErrors
);
245 WINTRUST_Free(provData
->u
.pPDSip
);
246 WINTRUST_Free(provData
->psPfns
);
247 WINTRUST_Free(provData
);
248 data
->hWVTStateData
= NULL
;
250 TRACE("returning %08x\n", err
);
254 static LONG
WINTRUST_DefaultVerifyAndClose(HWND hwnd
, GUID
*actionID
,
259 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
261 err
= WINTRUST_DefaultVerify(hwnd
, actionID
, data
);
262 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
263 TRACE("returning %08x\n", err
);
267 static LONG
WINTRUST_PublishedSoftware(HWND hwnd
, GUID
*actionID
,
270 WINTRUST_DATA wintrust_data
= { sizeof(wintrust_data
), 0 };
271 /* Undocumented: the published software action is passed a path,
272 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
274 LPWIN_TRUST_SUBJECT_FILE subjectFile
= data
->pSIPClientData
;
275 WINTRUST_FILE_INFO fileInfo
= { sizeof(fileInfo
), 0 };
277 TRACE("subjectFile->hFile: %p\n", subjectFile
->hFile
);
278 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile
->lpPath
));
279 fileInfo
.pcwszFilePath
= subjectFile
->lpPath
;
280 fileInfo
.hFile
= subjectFile
->hFile
;
281 wintrust_data
.u
.pFile
= &fileInfo
;
282 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
283 wintrust_data
.dwUIChoice
= WTD_UI_NONE
;
285 return WINTRUST_DefaultVerifyAndClose(hwnd
, actionID
, &wintrust_data
);
288 /* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
289 * action is not stored in the registry and is located in wintrust, not in
290 * cryptdlg along with the rest of the implementation (verified by running the
291 * action with a native wintrust.dll.)
293 static HRESULT WINAPI
WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA
*data
)
297 TRACE("(%p)\n", data
);
299 if (!data
->padwTrustStepErrors
)
302 switch (data
->pWintrustData
->dwUnionChoice
)
304 case WTD_CHOICE_BLOB
:
305 if (data
->pWintrustData
->u
.pBlob
&&
306 data
->pWintrustData
->u
.pBlob
->cbStruct
== sizeof(WINTRUST_BLOB_INFO
) &&
307 data
->pWintrustData
->u
.pBlob
->cbMemObject
==
308 sizeof(CERT_VERIFY_CERTIFICATE_TRUST
) &&
309 data
->pWintrustData
->u
.pBlob
->pbMemObject
)
311 CERT_VERIFY_CERTIFICATE_TRUST
*pCert
=
312 (CERT_VERIFY_CERTIFICATE_TRUST
*)
313 data
->pWintrustData
->u
.pBlob
->pbMemObject
;
315 if (pCert
->cbSize
== sizeof(CERT_VERIFY_CERTIFICATE_TRUST
) &&
318 CRYPT_PROVIDER_SGNR signer
= { sizeof(signer
), { 0 } };
322 /* Add a signer with nothing but the time to verify, so we can
325 GetSystemTime(&sysTime
);
326 SystemTimeToFileTime(&sysTime
, &signer
.sftVerifyAsOf
);
327 ret
= data
->psPfns
->pfnAddSgnr2Chain(data
, FALSE
, 0, &signer
);
330 ret
= data
->psPfns
->pfnAddCert2Chain(data
, 0, FALSE
, 0,
334 for (i
= 0; ret
&& i
< pCert
->cRootStores
; i
++)
335 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
336 pCert
->rghstoreRoots
[i
]);
337 for (i
= 0; ret
&& i
< pCert
->cStores
; i
++)
338 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
339 pCert
->rghstoreCAs
[i
]);
340 for (i
= 0; ret
&& i
< pCert
->cTrustStores
; i
++)
341 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
342 pCert
->rghstoreTrust
[i
]);
346 SetLastError(ERROR_INVALID_PARAMETER
);
352 SetLastError(ERROR_INVALID_PARAMETER
);
357 FIXME("unimplemented for %d\n", data
->pWintrustData
->dwUnionChoice
);
358 SetLastError(ERROR_INVALID_PARAMETER
);
364 data
->padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] =
366 TRACE("returning %d (%08x)\n", ret
? S_OK
: S_FALSE
,
367 data
->padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
368 return ret
? S_OK
: S_FALSE
;
371 static LONG
WINTRUST_CertVerify(HWND hwnd
, GUID
*actionID
,
374 DWORD err
= ERROR_SUCCESS
, numSteps
= 0;
375 CRYPT_PROVIDER_DATA
*provData
;
377 struct wintrust_step verifySteps
[5];
379 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
381 provData
= WINTRUST_AllocateProviderData();
383 return ERROR_OUTOFMEMORY
;
385 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
388 err
= GetLastError();
391 if (!provData
->psPfns
->pfnObjectTrust
)
392 provData
->psPfns
->pfnObjectTrust
= WINTRUST_CertVerifyObjTrust
;
393 /* Not sure why, but native skips the policy check */
394 provData
->psPfns
->pfnCertCheckPolicy
= NULL
;
396 data
->hWVTStateData
= provData
;
397 provData
->pWintrustData
= data
;
398 if (hwnd
== INVALID_HANDLE_VALUE
)
399 provData
->hWndParent
= GetDesktopWindow();
401 provData
->hWndParent
= hwnd
;
402 provData
->pgActionID
= actionID
;
403 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
405 numSteps
= WINTRUST_AddTrustStepsFromFunctions(verifySteps
,
407 err
= WINTRUST_ExecuteSteps(verifySteps
, numSteps
, provData
);
413 WINTRUST_Free(provData
->padwTrustStepErrors
);
414 WINTRUST_Free(provData
->u
.pPDSip
);
415 WINTRUST_Free(provData
->psPfns
);
416 WINTRUST_Free(provData
);
419 TRACE("returning %08x\n", err
);
423 static LONG
WINTRUST_CertVerifyAndClose(HWND hwnd
, GUID
*actionID
,
428 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
430 err
= WINTRUST_CertVerify(hwnd
, actionID
, data
);
431 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
432 TRACE("returning %08x\n", err
);
436 static LONG
WINTRUST_CertActionVerify(HWND hwnd
, GUID
*actionID
,
440 LONG err
= ERROR_SUCCESS
;
442 if (WVT_ISINSTRUCT(WINTRUST_DATA
, data
->cbStruct
, dwStateAction
))
443 stateAction
= data
->dwStateAction
;
446 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
447 stateAction
= WTD_STATEACTION_IGNORE
;
451 case WTD_STATEACTION_IGNORE
:
452 err
= WINTRUST_CertVerifyAndClose(hwnd
, actionID
, data
);
454 case WTD_STATEACTION_VERIFY
:
455 err
= WINTRUST_CertVerify(hwnd
, actionID
, data
);
457 case WTD_STATEACTION_CLOSE
:
458 err
= WINTRUST_DefaultClose(hwnd
, actionID
, data
);
461 FIXME("unimplemented for %d\n", data
->dwStateAction
);
466 static void dump_file_info(WINTRUST_FILE_INFO
*pFile
)
468 TRACE("%p\n", pFile
);
471 TRACE("cbStruct: %d\n", pFile
->cbStruct
);
472 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile
->pcwszFilePath
));
473 TRACE("hFile: %p\n", pFile
->hFile
);
474 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile
->pgKnownSubject
));
478 static void dump_catalog_info(WINTRUST_CATALOG_INFO
*catalog
)
480 TRACE("%p\n", catalog
);
483 TRACE("cbStruct: %d\n", catalog
->cbStruct
);
484 TRACE("dwCatalogVersion: %d\n", catalog
->dwCatalogVersion
);
485 TRACE("pcwszCatalogFilePath: %s\n",
486 debugstr_w(catalog
->pcwszCatalogFilePath
));
487 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog
->pcwszMemberTag
));
488 TRACE("pcwszMemberFilePath: %s\n",
489 debugstr_w(catalog
->pcwszMemberFilePath
));
490 TRACE("hMemberFile: %p\n", catalog
->hMemberFile
);
491 TRACE("pbCalculatedFileHash: %p\n", catalog
->pbCalculatedFileHash
);
492 TRACE("cbCalculatedFileHash: %d\n", catalog
->cbCalculatedFileHash
);
493 TRACE("pcCatalogContext: %p\n", catalog
->pcCatalogContext
);
497 static void dump_blob_info(WINTRUST_BLOB_INFO
*blob
)
502 TRACE("cbStruct: %d\n", blob
->cbStruct
);
503 TRACE("gSubject: %s\n", debugstr_guid(&blob
->gSubject
));
504 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob
->pcwszDisplayName
));
505 TRACE("cbMemObject: %d\n", blob
->cbMemObject
);
506 TRACE("pbMemObject: %p\n", blob
->pbMemObject
);
507 TRACE("cbMemSignedMsg: %d\n", blob
->cbMemSignedMsg
);
508 TRACE("pbMemSignedMsg: %p\n", blob
->pbMemSignedMsg
);
512 static void dump_sgnr_info(WINTRUST_SGNR_INFO
*sgnr
)
517 TRACE("cbStruct: %d\n", sgnr
->cbStruct
);
518 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr
->pcwszDisplayName
));
519 TRACE("psSignerInfo: %p\n", sgnr
->psSignerInfo
);
520 TRACE("chStores: %d\n", sgnr
->chStores
);
524 static void dump_cert_info(WINTRUST_CERT_INFO
*cert
)
529 TRACE("cbStruct: %d\n", cert
->cbStruct
);
530 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert
->pcwszDisplayName
));
531 TRACE("psCertContext: %p\n", cert
->psCertContext
);
532 TRACE("chStores: %d\n", cert
->chStores
);
533 TRACE("dwFlags: %08x\n", cert
->dwFlags
);
534 TRACE("psftVerifyAsOf: %p\n", cert
->psftVerifyAsOf
);
538 static void dump_wintrust_data(WINTRUST_DATA
*data
)
543 TRACE("cbStruct: %d\n", data
->cbStruct
);
544 TRACE("pPolicyCallbackData: %p\n", data
->pPolicyCallbackData
);
545 TRACE("pSIPClientData: %p\n", data
->pSIPClientData
);
546 TRACE("dwUIChoice: %d\n", data
->dwUIChoice
);
547 TRACE("fdwRevocationChecks: %08x\n", data
->fdwRevocationChecks
);
548 TRACE("dwUnionChoice: %d\n", data
->dwUnionChoice
);
549 switch (data
->dwUnionChoice
)
551 case WTD_CHOICE_FILE
:
552 dump_file_info(data
->u
.pFile
);
554 case WTD_CHOICE_CATALOG
:
555 dump_catalog_info(data
->u
.pCatalog
);
557 case WTD_CHOICE_BLOB
:
558 dump_blob_info(data
->u
.pBlob
);
560 case WTD_CHOICE_SIGNER
:
561 dump_sgnr_info(data
->u
.pSgnr
);
563 case WTD_CHOICE_CERT
:
564 dump_cert_info(data
->u
.pCert
);
567 TRACE("dwStateAction: %d\n", data
->dwStateAction
);
568 TRACE("hWVTStateData: %p\n", data
->hWVTStateData
);
569 TRACE("pwszURLReference: %s\n", debugstr_w(data
->pwszURLReference
));
570 TRACE("dwProvFlags: %08x\n", data
->dwProvFlags
);
571 TRACE("dwUIContext: %d\n", data
->dwUIContext
);
575 /***********************************************************************
576 * WinVerifyTrust (WINTRUST.@)
578 * Verifies an object by calling the specified trust provider.
581 * hwnd [I] Handle to a caller window.
582 * ActionID [I] Pointer to a GUID that identifies the action to perform.
583 * ActionData [I] Information used by the trust provider to verify the object.
587 * Failure: A TRUST_E_* error code.
590 * Trust providers can be found at:
591 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
593 LONG WINAPI
WinVerifyTrust( HWND hwnd
, GUID
*ActionID
, LPVOID ActionData
)
595 static const GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
596 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
597 static const GUID published_software
= WIN_SPUB_ACTION_PUBLISHED_SOFTWARE
;
598 static const GUID generic_verify_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
599 static const GUID generic_cert_verify
= WINTRUST_ACTION_GENERIC_CERT_VERIFY
;
600 static const GUID generic_chain_verify
= WINTRUST_ACTION_GENERIC_CHAIN_VERIFY
;
601 static const GUID cert_action_verify
= CERT_CERTIFICATE_ACTION_VERIFY
;
602 LONG err
= ERROR_SUCCESS
;
603 WINTRUST_DATA
*actionData
= ActionData
;
605 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(ActionID
), ActionData
);
606 dump_wintrust_data(ActionData
);
608 /* Support for known old-style callers: */
609 if (IsEqualGUID(ActionID
, &published_software
))
610 err
= WINTRUST_PublishedSoftware(hwnd
, ActionID
, ActionData
);
611 else if (IsEqualGUID(ActionID
, &cert_action_verify
))
612 err
= WINTRUST_CertActionVerify(hwnd
, ActionID
, ActionData
);
617 /* Check known actions to warn of possible problems */
618 if (!IsEqualGUID(ActionID
, &unknown
) &&
619 !IsEqualGUID(ActionID
, &generic_verify_v2
) &&
620 !IsEqualGUID(ActionID
, &generic_cert_verify
) &&
621 !IsEqualGUID(ActionID
, &generic_chain_verify
))
622 WARN("unknown action %s, default behavior may not be right\n",
623 debugstr_guid(ActionID
));
624 if (WVT_ISINSTRUCT(WINTRUST_DATA
, actionData
->cbStruct
, dwStateAction
))
625 stateAction
= actionData
->dwStateAction
;
628 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
629 stateAction
= WTD_STATEACTION_IGNORE
;
633 case WTD_STATEACTION_IGNORE
:
634 err
= WINTRUST_DefaultVerifyAndClose(hwnd
, ActionID
, ActionData
);
636 case WTD_STATEACTION_VERIFY
:
637 err
= WINTRUST_DefaultVerify(hwnd
, ActionID
, ActionData
);
639 case WTD_STATEACTION_CLOSE
:
640 err
= WINTRUST_DefaultClose(hwnd
, ActionID
, ActionData
);
643 FIXME("unimplemented for %d\n", actionData
->dwStateAction
);
647 TRACE("returning %08x\n", err
);
651 /***********************************************************************
652 * WinVerifyTrustEx (WINTRUST.@)
654 HRESULT WINAPI
WinVerifyTrustEx( HWND hwnd
, GUID
*ActionID
,
655 WINTRUST_DATA
* ActionData
)
657 return WinVerifyTrust(hwnd
, ActionID
, ActionData
);
660 /***********************************************************************
661 * WTHelperGetProvSignerFromChain (WINTRUST.@)
663 CRYPT_PROVIDER_SGNR
* WINAPI
WTHelperGetProvSignerFromChain(
664 CRYPT_PROVIDER_DATA
*pProvData
, DWORD idxSigner
, BOOL fCounterSigner
,
665 DWORD idxCounterSigner
)
667 CRYPT_PROVIDER_SGNR
*sgnr
;
669 TRACE("(%p %d %d %d)\n", pProvData
, idxSigner
, fCounterSigner
,
672 if (idxSigner
>= pProvData
->csSigners
|| !pProvData
->pasSigners
)
674 sgnr
= &pProvData
->pasSigners
[idxSigner
];
677 if (idxCounterSigner
>= sgnr
->csCounterSigners
||
678 !sgnr
->pasCounterSigners
)
680 sgnr
= &sgnr
->pasCounterSigners
[idxCounterSigner
];
682 TRACE("returning %p\n", sgnr
);
686 /***********************************************************************
687 * WTHelperGetProvCertFromChain (WINTRUST.@)
689 CRYPT_PROVIDER_CERT
* WINAPI
WTHelperGetProvCertFromChain(
690 CRYPT_PROVIDER_SGNR
*pSgnr
, DWORD idxCert
)
692 CRYPT_PROVIDER_CERT
*cert
;
694 TRACE("(%p %d)\n", pSgnr
, idxCert
);
696 if (idxCert
>= pSgnr
->csCertChain
|| !pSgnr
->pasCertChain
)
698 cert
= &pSgnr
->pasCertChain
[idxCert
];
699 TRACE("returning %p\n", cert
);
703 CRYPT_PROVIDER_PRIVDATA
*WINAPI
WTHelperGetProvPrivateDataFromChain(
704 CRYPT_PROVIDER_DATA
* pProvData
,
707 CRYPT_PROVIDER_PRIVDATA
*privdata
= NULL
;
710 TRACE("(%p, %s)\n", pProvData
, debugstr_guid(pgProviderID
));
712 for (i
= 0; i
< pProvData
->csProvPrivData
; i
++)
713 if (IsEqualGUID(pgProviderID
, &pProvData
->pasProvPrivData
[i
].gProviderID
))
715 privdata
= &pProvData
->pasProvPrivData
[i
];
722 /***********************************************************************
723 * WTHelperProvDataFromStateData (WINTRUST.@)
725 CRYPT_PROVIDER_DATA
* WINAPI
WTHelperProvDataFromStateData(HANDLE hStateData
)
727 TRACE("%p\n", hStateData
);
731 /***********************************************************************
732 * WTHelperGetFileName(WINTRUST.@)
734 LPCWSTR WINAPI
WTHelperGetFileName(WINTRUST_DATA
*data
)
737 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
738 return data
->u
.pFile
->pcwszFilePath
;
743 /***********************************************************************
744 * WTHelperGetFileHandle(WINTRUST.@)
746 HANDLE WINAPI
WTHelperGetFileHandle(WINTRUST_DATA
*data
)
749 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
750 return data
->u
.pFile
->hFile
;
752 return INVALID_HANDLE_VALUE
;
755 static BOOL WINAPI
WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo
, void *pvArg
)
757 PCCRYPT_OID_INFO
**usages
= pvArg
;
764 *usages
= WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO
));
768 PCCRYPT_OID_INFO
*ptr
;
770 /* Count the existing usages.
771 * FIXME: make sure the new usage doesn't duplicate any in the list?
773 for (cUsages
= 0, ptr
= *usages
; *ptr
; ptr
++, cUsages
++)
775 *usages
= WINTRUST_ReAlloc(*usages
,
776 (cUsages
+ 2) * sizeof(PCCRYPT_OID_INFO
));
780 (*usages
)[cUsages
] = pInfo
;
781 (*usages
)[cUsages
+ 1] = NULL
;
786 SetLastError(ERROR_OUTOFMEMORY
);
792 /***********************************************************************
793 * WTHelperGetKnownUsages(WINTRUST.@)
795 * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs.
798 * action [In] 1 => allocate and return known usages, 2 => free previously
800 * usages [In/Out] If action == 1, *usages is set to an array of
801 * PCCRYPT_OID_INFO *. The array is terminated with a NULL
803 * If action == 2, *usages is freed.
806 * TRUE on success, FALSE on failure.
808 BOOL WINAPI
WTHelperGetKnownUsages(DWORD action
, PCCRYPT_OID_INFO
**usages
)
812 TRACE("(%d, %p)\n", action
, usages
);
816 SetLastError(ERROR_INVALID_PARAMETER
);
823 ret
= CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID
, 0, usages
,
824 WINTRUST_enumUsages
);
826 else if (action
== 2)
828 WINTRUST_Free(*usages
);
834 WARN("unknown action %d\n", action
);
835 SetLastError(ERROR_INVALID_PARAMETER
);
841 static const WCHAR Software_Publishing
[] = {
842 'S','o','f','t','w','a','r','e','\\',
843 'M','i','c','r','o','s','o','f','t','\\',
844 'W','i','n','d','o','w','s','\\',
845 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
846 'W','i','n','t','r','u','s','t','\\',
847 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
848 'S','o','f','t','w','a','r','e',' ',
849 'P','u','b','l','i','s','h','i','n','g',0 };
850 static const WCHAR State
[] = { 'S','t','a','t','e',0 };
852 /***********************************************************************
853 * WintrustGetRegPolicyFlags (WINTRUST.@)
855 void WINAPI
WintrustGetRegPolicyFlags( DWORD
* pdwPolicyFlags
)
860 TRACE("%p\n", pdwPolicyFlags
);
863 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0, NULL
, 0,
864 KEY_READ
, NULL
, &key
, NULL
);
867 DWORD size
= sizeof(DWORD
);
869 r
= RegQueryValueExW(key
, State
, NULL
, NULL
, (LPBYTE
)pdwPolicyFlags
,
874 /* Failed to query, create and return default value */
875 *pdwPolicyFlags
= WTPF_IGNOREREVOCATIONONTS
|
876 WTPF_OFFLINEOKNBU_COM
|
877 WTPF_OFFLINEOKNBU_IND
|
880 WintrustSetRegPolicyFlags(*pdwPolicyFlags
);
885 /***********************************************************************
886 * WintrustSetRegPolicyFlags (WINTRUST.@)
888 BOOL WINAPI
WintrustSetRegPolicyFlags( DWORD dwPolicyFlags
)
893 TRACE("%x\n", dwPolicyFlags
);
895 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0,
896 NULL
, 0, KEY_WRITE
, NULL
, &key
, NULL
);
899 r
= RegSetValueExW(key
, State
, 0, REG_DWORD
, (LPBYTE
)&dwPolicyFlags
,
903 if (r
) SetLastError(r
);
904 return r
== ERROR_SUCCESS
;
907 /* Utility functions */
909 BOOL WINAPI
WINTRUST_AddStore(CRYPT_PROVIDER_DATA
*data
, HCERTSTORE store
)
913 TRACE("(%p, %p)\n", data
, store
);
916 data
->pahStores
= WINTRUST_ReAlloc(data
->pahStores
,
917 (data
->chStores
+ 1) * sizeof(HCERTSTORE
));
920 data
->pahStores
= WINTRUST_Alloc(sizeof(HCERTSTORE
));
925 data
->pahStores
[data
->chStores
++] = CertDuplicateStore(store
);
929 SetLastError(ERROR_OUTOFMEMORY
);
933 BOOL WINAPI
WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA
*data
,
934 BOOL fCounterSigner
, DWORD idxSigner
, CRYPT_PROVIDER_SGNR
*sgnr
)
938 TRACE("(%p, %d, %d, %p)\n", data
, fCounterSigner
, idxSigner
, sgnr
);
940 if (sgnr
->cbStruct
> sizeof(CRYPT_PROVIDER_SGNR
))
942 SetLastError(ERROR_INVALID_PARAMETER
);
947 FIXME("unimplemented for counter signers\n");
948 SetLastError(ERROR_INVALID_PARAMETER
);
952 data
->pasSigners
= WINTRUST_ReAlloc(data
->pasSigners
,
953 (data
->csSigners
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
956 data
->pasSigners
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
959 if (data
->pasSigners
)
961 if (idxSigner
< data
->csSigners
)
962 memmove(&data
->pasSigners
[idxSigner
],
963 &data
->pasSigners
[idxSigner
+ 1],
964 (data
->csSigners
- idxSigner
) * sizeof(CRYPT_PROVIDER_SGNR
));
966 if (sgnr
->cbStruct
== sizeof(CRYPT_PROVIDER_SGNR
))
968 /* The PSDK says psSigner should be allocated using pfnAlloc, but
969 * it doesn't say anything about ownership. Since callers are
970 * internal, assume ownership is passed, and just store the
973 memcpy(&data
->pasSigners
[idxSigner
], sgnr
,
974 sizeof(CRYPT_PROVIDER_SGNR
));
977 memset(&data
->pasSigners
[idxSigner
], 0,
978 sizeof(CRYPT_PROVIDER_SGNR
));
982 SetLastError(ERROR_OUTOFMEMORY
);
986 BOOL WINAPI
WINTRUST_AddCert(CRYPT_PROVIDER_DATA
*data
, DWORD idxSigner
,
987 BOOL fCounterSigner
, DWORD idxCounterSigner
, PCCERT_CONTEXT pCert2Add
)
991 TRACE("(%p, %d, %d, %d, %p)\n", data
, idxSigner
, fCounterSigner
,
992 idxSigner
, pCert2Add
);
996 FIXME("unimplemented for counter signers\n");
997 SetLastError(ERROR_INVALID_PARAMETER
);
1000 if (data
->pasSigners
[idxSigner
].csCertChain
)
1001 data
->pasSigners
[idxSigner
].pasCertChain
=
1002 WINTRUST_ReAlloc(data
->pasSigners
[idxSigner
].pasCertChain
,
1003 (data
->pasSigners
[idxSigner
].csCertChain
+ 1) *
1004 sizeof(CRYPT_PROVIDER_CERT
));
1007 data
->pasSigners
[idxSigner
].pasCertChain
=
1008 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT
));
1009 data
->pasSigners
[idxSigner
].csCertChain
= 0;
1011 if (data
->pasSigners
[idxSigner
].pasCertChain
)
1013 CRYPT_PROVIDER_CERT
*cert
= &data
->pasSigners
[idxSigner
].pasCertChain
[
1014 data
->pasSigners
[idxSigner
].csCertChain
];
1016 cert
->cbStruct
= sizeof(CRYPT_PROVIDER_CERT
);
1017 cert
->pCert
= CertDuplicateCertificateContext(pCert2Add
);
1018 data
->pasSigners
[idxSigner
].csCertChain
++;
1022 SetLastError(ERROR_OUTOFMEMORY
);
1026 BOOL WINAPI
WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA
*data
,
1027 CRYPT_PROVIDER_PRIVDATA
*pPrivData2Add
)
1031 TRACE("(%p, %p)\n", data
, pPrivData2Add
);
1033 if (pPrivData2Add
->cbStruct
> sizeof(CRYPT_PROVIDER_PRIVDATA
))
1035 SetLastError(ERROR_INVALID_PARAMETER
);
1036 WARN("invalid struct size\n");
1039 if (data
->csProvPrivData
)
1040 data
->pasProvPrivData
= WINTRUST_ReAlloc(data
->pasProvPrivData
,
1041 (data
->csProvPrivData
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
1044 data
->pasProvPrivData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
1045 data
->csProvPrivData
= 0;
1047 if (data
->pasProvPrivData
)
1051 for (i
= 0; i
< data
->csProvPrivData
; i
++)
1052 if (IsEqualGUID(&pPrivData2Add
->gProviderID
, &data
->pasProvPrivData
[i
]))
1055 data
->pasProvPrivData
[i
] = *pPrivData2Add
;
1056 if (i
== data
->csProvPrivData
)
1057 data
->csProvPrivData
++;
1060 SetLastError(ERROR_OUTOFMEMORY
);
1064 /***********************************************************************
1065 * OpenPersonalTrustDBDialog (WINTRUST.@)
1067 * Opens the certificate manager dialog, showing only the stores that
1068 * contain trusted software publishers.
1071 * hwnd [I] handle of parent window
1074 * TRUE if the dialog could be opened, FALSE if not.
1076 BOOL WINAPI
OpenPersonalTrustDBDialog(HWND hwnd
)
1078 CRYPTUI_CERT_MGR_STRUCT uiCertMgr
;
1080 uiCertMgr
.dwSize
= sizeof(uiCertMgr
);
1081 uiCertMgr
.hwndParent
= hwnd
;
1082 uiCertMgr
.dwFlags
= CRYPTUI_CERT_MGR_PUBLISHER_TAB
;
1083 uiCertMgr
.pwszTitle
= NULL
;
1084 uiCertMgr
.pszInitUsageOID
= NULL
;
1085 return CryptUIDlgCertMgr(&uiCertMgr
);