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
36 #include "wintrust_priv.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(wintrust
);
42 /***********************************************************************
43 * DllMain (WINTRUST.@)
45 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
49 case DLL_PROCESS_ATTACH
:
50 DisableThreadLibraryCalls( inst
);
56 /***********************************************************************
57 * TrustIsCertificateSelfSigned (WINTRUST.@)
59 BOOL WINAPI
TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert
)
64 ret
= CertCompareCertificateName(cert
->dwCertEncodingType
,
65 &cert
->pCertInfo
->Subject
, &cert
->pCertInfo
->Issuer
);
69 static LONG
WINTRUST_DefaultVerify(HWND hwnd
, GUID
*actionID
,
72 DWORD err
= ERROR_SUCCESS
;
73 CRYPT_PROVIDER_DATA
*provData
;
76 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
78 provData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA
));
81 provData
->cbStruct
= sizeof(CRYPT_PROVIDER_DATA
);
83 provData
->padwTrustStepErrors
=
84 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
85 if (!provData
->padwTrustStepErrors
)
87 provData
->cdwTrustStepErrors
= TRUSTERROR_MAX_STEPS
;
89 provData
->u
.pPDSip
= WINTRUST_Alloc(sizeof(PROVDATA_SIP
));
90 if (!provData
->u
.pPDSip
)
92 provData
->u
.pPDSip
->cbStruct
= sizeof(PROVDATA_SIP
);
94 provData
->psPfns
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS
));
95 if (!provData
->psPfns
)
97 provData
->psPfns
->cbStruct
= sizeof(CRYPT_PROVIDER_FUNCTIONS
);
98 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
101 err
= GetLastError();
105 data
->hWVTStateData
= (HANDLE
)provData
;
106 provData
->pWintrustData
= data
;
107 if (hwnd
== INVALID_HANDLE_VALUE
)
108 provData
->hWndParent
= GetDesktopWindow();
110 provData
->hWndParent
= hwnd
;
111 provData
->pgActionID
= actionID
;
112 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
114 err
= provData
->psPfns
->pfnInitialize(provData
);
117 err
= provData
->psPfns
->pfnObjectTrust(provData
);
120 err
= provData
->psPfns
->pfnSignatureTrust(provData
);
123 err
= provData
->psPfns
->pfnCertificateTrust(provData
);
126 err
= provData
->psPfns
->pfnFinalPolicy(provData
);
130 err
= ERROR_OUTOFMEMORY
;
134 WINTRUST_Free(provData
->padwTrustStepErrors
);
135 WINTRUST_Free(provData
->u
.pPDSip
);
136 WINTRUST_Free(provData
->psPfns
);
137 WINTRUST_Free(provData
);
140 TRACE("returning %08x\n", err
);
144 static LONG
WINTRUST_DefaultClose(HWND hwnd
, GUID
*actionID
,
147 DWORD err
= ERROR_SUCCESS
;
148 CRYPT_PROVIDER_DATA
*provData
= (CRYPT_PROVIDER_DATA
*)data
->hWVTStateData
;
150 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
154 if (provData
->psPfns
->pfnCleanupPolicy
)
155 err
= provData
->psPfns
->pfnCleanupPolicy(provData
);
157 WINTRUST_Free(provData
->padwTrustStepErrors
);
158 WINTRUST_Free(provData
->u
.pPDSip
);
159 WINTRUST_Free(provData
->psPfns
);
160 WINTRUST_Free(provData
);
161 data
->hWVTStateData
= NULL
;
163 TRACE("returning %08x\n", err
);
167 static LONG
WINTRUST_DefaultVerifyAndClose(HWND hwnd
, GUID
*actionID
,
172 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
174 err
= WINTRUST_DefaultVerify(hwnd
, actionID
, data
);
175 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
176 TRACE("returning %08x\n", err
);
180 static LONG
WINTRUST_PublishedSoftware(HWND hwnd
, GUID
*actionID
,
183 WINTRUST_DATA wintrust_data
= { sizeof(wintrust_data
), 0 };
184 /* Undocumented: the published software action is passed a path,
185 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
187 LPCWSTR path
= (LPCWSTR
)data
->u
.pFile
;
188 LPWIN_TRUST_SUBJECT_FILE subjectFile
=
189 (LPWIN_TRUST_SUBJECT_FILE
)data
->pSIPClientData
;
190 WINTRUST_FILE_INFO fileInfo
= { sizeof(fileInfo
), 0 };
192 TRACE("subjectFile->hFile: %p\n", subjectFile
->hFile
);
193 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile
->lpPath
));
194 fileInfo
.pcwszFilePath
= path
;
195 fileInfo
.hFile
= subjectFile
->hFile
;
196 wintrust_data
.u
.pFile
= &fileInfo
;
197 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
198 wintrust_data
.dwUIChoice
= WTD_UI_NONE
;
200 return WINTRUST_DefaultVerifyAndClose(hwnd
, actionID
, &wintrust_data
);
203 static void dump_file_info(WINTRUST_FILE_INFO
*pFile
)
205 TRACE("%p\n", pFile
);
208 TRACE("cbStruct: %d\n", pFile
->cbStruct
);
209 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile
->pcwszFilePath
));
210 TRACE("hFile: %p\n", pFile
->hFile
);
211 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile
->pgKnownSubject
));
215 static void dump_catalog_info(WINTRUST_CATALOG_INFO
*catalog
)
217 TRACE("%p\n", catalog
);
220 TRACE("cbStruct: %d\n", catalog
->cbStruct
);
221 TRACE("dwCatalogVersion: %d\n", catalog
->dwCatalogVersion
);
222 TRACE("pcwszCatalogFilePath: %s\n",
223 debugstr_w(catalog
->pcwszCatalogFilePath
));
224 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog
->pcwszMemberTag
));
225 TRACE("pcwszMemberFilePath: %s\n",
226 debugstr_w(catalog
->pcwszMemberFilePath
));
227 TRACE("hMemberFile: %p\n", catalog
->hMemberFile
);
228 TRACE("pbCalculatedFileHash: %p\n", catalog
->pbCalculatedFileHash
);
229 TRACE("cbCalculatedFileHash: %d\n", catalog
->cbCalculatedFileHash
);
230 TRACE("pcCatalogContext: %p\n", catalog
->pcCatalogContext
);
234 static void dump_blob_info(WINTRUST_BLOB_INFO
*blob
)
239 TRACE("cbStruct: %d\n", blob
->cbStruct
);
240 TRACE("gSubject: %s\n", debugstr_guid(&blob
->gSubject
));
241 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob
->pcwszDisplayName
));
242 TRACE("cbMemObject: %d\n", blob
->cbMemObject
);
243 TRACE("pbMemObject: %p\n", blob
->pbMemObject
);
244 TRACE("cbMemSignedMsg: %d\n", blob
->cbMemSignedMsg
);
245 TRACE("pbMemSignedMsg: %p\n", blob
->pbMemSignedMsg
);
249 static void dump_sgnr_info(WINTRUST_SGNR_INFO
*sgnr
)
254 TRACE("cbStruct: %d\n", sgnr
->cbStruct
);
255 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr
->pcwszDisplayName
));
256 TRACE("psSignerInfo: %p\n", sgnr
->psSignerInfo
);
257 TRACE("chStores: %d\n", sgnr
->chStores
);
261 static void dump_cert_info(WINTRUST_CERT_INFO
*cert
)
266 TRACE("cbStruct: %d\n", cert
->cbStruct
);
267 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert
->pcwszDisplayName
));
268 TRACE("psCertContext: %p\n", cert
->psCertContext
);
269 TRACE("chStores: %d\n", cert
->chStores
);
270 TRACE("dwFlags: %08x\n", cert
->dwFlags
);
271 TRACE("psftVerifyAsOf: %p\n", cert
->psftVerifyAsOf
);
275 static void dump_wintrust_data(WINTRUST_DATA
*data
)
280 TRACE("cbStruct: %d\n", data
->cbStruct
);
281 TRACE("pPolicyCallbackData: %p\n", data
->pPolicyCallbackData
);
282 TRACE("pSIPClientData: %p\n", data
->pSIPClientData
);
283 TRACE("dwUIChoice: %d\n", data
->dwUIChoice
);
284 TRACE("fdwRevocationChecks: %08x\n", data
->fdwRevocationChecks
);
285 TRACE("dwUnionChoice: %d\n", data
->dwUnionChoice
);
286 switch (data
->dwUnionChoice
)
288 case WTD_CHOICE_FILE
:
289 dump_file_info(data
->u
.pFile
);
291 case WTD_CHOICE_CATALOG
:
292 dump_catalog_info(data
->u
.pCatalog
);
294 case WTD_CHOICE_BLOB
:
295 dump_blob_info(data
->u
.pBlob
);
297 case WTD_CHOICE_SIGNER
:
298 dump_sgnr_info(data
->u
.pSgnr
);
300 case WTD_CHOICE_CERT
:
301 dump_cert_info(data
->u
.pCert
);
304 TRACE("dwStateAction: %d\n", data
->dwStateAction
);
305 TRACE("hWVTStateData: %p\n", data
->hWVTStateData
);
306 TRACE("pwszURLReference: %s\n", debugstr_w(data
->pwszURLReference
));
307 TRACE("dwProvFlags: %08x\n", data
->dwProvFlags
);
308 TRACE("dwUIContext: %d\n", data
->dwUIContext
);
312 /***********************************************************************
313 * WinVerifyTrust (WINTRUST.@)
315 * Verifies an object by calling the specified trust provider.
318 * hwnd [I] Handle to a caller window.
319 * ActionID [I] Pointer to a GUID that identifies the action to perform.
320 * ActionData [I] Information used by the trust provider to verify the object.
324 * Failure: A TRUST_E_* error code.
327 * Trust providers can be found at:
328 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
330 LONG WINAPI
WinVerifyTrust( HWND hwnd
, GUID
*ActionID
, LPVOID ActionData
)
332 static const GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
333 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
334 static const GUID published_software
= WIN_SPUB_ACTION_PUBLISHED_SOFTWARE
;
335 static const GUID generic_verify_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
336 static const GUID generic_cert_verify
= WINTRUST_ACTION_GENERIC_CERT_VERIFY
;
337 static const GUID generic_chain_verify
= WINTRUST_ACTION_GENERIC_CHAIN_VERIFY
;
338 LONG err
= ERROR_SUCCESS
;
339 WINTRUST_DATA
*actionData
= (WINTRUST_DATA
*)ActionData
;
341 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(ActionID
), ActionData
);
342 dump_wintrust_data(ActionData
);
344 /* Support for known old-style callers: */
345 if (IsEqualGUID(ActionID
, &published_software
))
346 err
= WINTRUST_PublishedSoftware(hwnd
, ActionID
, ActionData
);
349 /* Check known actions to warn of possible problems */
350 if (!IsEqualGUID(ActionID
, &unknown
) &&
351 !IsEqualGUID(ActionID
, &generic_verify_v2
) &&
352 !IsEqualGUID(ActionID
, &generic_cert_verify
) &&
353 !IsEqualGUID(ActionID
, &generic_chain_verify
))
354 WARN("unknown action %s, default behavior may not be right\n",
355 debugstr_guid(ActionID
));
356 switch (actionData
->dwStateAction
)
358 case WTD_STATEACTION_IGNORE
:
359 err
= WINTRUST_DefaultVerifyAndClose(hwnd
, ActionID
, ActionData
);
361 case WTD_STATEACTION_VERIFY
:
362 err
= WINTRUST_DefaultVerify(hwnd
, ActionID
, ActionData
);
364 case WTD_STATEACTION_CLOSE
:
365 err
= WINTRUST_DefaultClose(hwnd
, ActionID
, ActionData
);
368 FIXME("unimplemented for %d\n", actionData
->dwStateAction
);
372 TRACE("returning %08x\n", err
);
376 /***********************************************************************
377 * WinVerifyTrustEx (WINTRUST.@)
379 HRESULT WINAPI
WinVerifyTrustEx( HWND hwnd
, GUID
*ActionID
,
380 WINTRUST_DATA
* ActionData
)
382 return WinVerifyTrust(hwnd
, ActionID
, ActionData
);
385 /***********************************************************************
386 * WTHelperGetProvSignerFromChain (WINTRUST.@)
388 CRYPT_PROVIDER_SGNR
* WINAPI
WTHelperGetProvSignerFromChain(
389 CRYPT_PROVIDER_DATA
*pProvData
, DWORD idxSigner
, BOOL fCounterSigner
,
390 DWORD idxCounterSigner
)
392 CRYPT_PROVIDER_SGNR
*sgnr
;
394 TRACE("(%p %d %d %d)\n", pProvData
, idxSigner
, fCounterSigner
,
397 if (idxSigner
>= pProvData
->csSigners
|| !pProvData
->pasSigners
)
399 sgnr
= &pProvData
->pasSigners
[idxSigner
];
402 if (idxCounterSigner
>= sgnr
->csCounterSigners
||
403 !sgnr
->pasCounterSigners
)
405 sgnr
= &sgnr
->pasCounterSigners
[idxCounterSigner
];
407 TRACE("returning %p\n", sgnr
);
411 /***********************************************************************
412 * WTHelperGetProvCertFromChain (WINTRUST.@)
414 CRYPT_PROVIDER_CERT
* WINAPI
WTHelperGetProvCertFromChain(
415 CRYPT_PROVIDER_SGNR
*pSgnr
, DWORD idxCert
)
417 CRYPT_PROVIDER_CERT
*cert
;
419 TRACE("(%p %d)\n", pSgnr
, idxCert
);
421 if (idxCert
>= pSgnr
->csCertChain
|| !pSgnr
->pasCertChain
)
423 cert
= &pSgnr
->pasCertChain
[idxCert
];
424 TRACE("returning %p\n", cert
);
428 /***********************************************************************
429 * WTHelperProvDataFromStateData (WINTRUST.@)
431 CRYPT_PROVIDER_DATA
* WINAPI
WTHelperProvDataFromStateData(HANDLE hStateData
)
433 TRACE("%p\n", hStateData
);
434 return (CRYPT_PROVIDER_DATA
*)hStateData
;
437 /***********************************************************************
438 * WTHelperGetFileName(WINTRUST.@)
440 LPCWSTR WINAPI
WTHelperGetFileName(WINTRUST_DATA
*data
)
443 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
444 return data
->u
.pFile
->pcwszFilePath
;
449 /***********************************************************************
450 * WTHelperGetFileHandle(WINTRUST.@)
452 HANDLE WINAPI
WTHelperGetFileHandle(WINTRUST_DATA
*data
)
455 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
456 return data
->u
.pFile
->hFile
;
458 return INVALID_HANDLE_VALUE
;
461 static const WCHAR Software_Publishing
[] = {
462 'S','o','f','t','w','a','r','e','\\',
463 'M','i','c','r','o','s','o','f','t','\\',
464 'W','i','n','d','o','w','s','\\',
465 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
466 'W','i','n','t','r','u','s','t','\\',
467 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
468 'S','o','f','t','w','a','r','e',' ',
469 'P','u','b','l','i','s','h','i','n','g',0 };
470 static const WCHAR State
[] = { 'S','t','a','t','e',0 };
472 /***********************************************************************
473 * WintrustGetRegPolicyFlags (WINTRUST.@)
475 void WINAPI
WintrustGetRegPolicyFlags( DWORD
* pdwPolicyFlags
)
480 TRACE("%p\n", pdwPolicyFlags
);
483 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0, NULL
, 0,
484 KEY_READ
, NULL
, &key
, NULL
);
487 DWORD size
= sizeof(DWORD
);
489 r
= RegQueryValueExW(key
, State
, NULL
, NULL
, (LPBYTE
)pdwPolicyFlags
,
494 /* Failed to query, create and return default value */
495 *pdwPolicyFlags
= WTPF_IGNOREREVOCATIONONTS
|
496 WTPF_OFFLINEOKNBU_COM
|
497 WTPF_OFFLINEOKNBU_IND
|
500 WintrustSetRegPolicyFlags(*pdwPolicyFlags
);
505 /***********************************************************************
506 * WintrustSetRegPolicyFlags (WINTRUST.@)
508 BOOL WINAPI
WintrustSetRegPolicyFlags( DWORD dwPolicyFlags
)
513 TRACE("%x\n", dwPolicyFlags
);
515 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0,
516 NULL
, 0, KEY_WRITE
, NULL
, &key
, NULL
);
519 r
= RegSetValueExW(key
, State
, 0, REG_DWORD
, (LPBYTE
)&dwPolicyFlags
,
523 if (r
) SetLastError(r
);
524 return r
== ERROR_SUCCESS
;
527 /* Utility functions */
528 void * WINAPI
WINTRUST_Alloc(DWORD cb
)
530 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cb
);
533 void * WINAPI
WINTRUST_ReAlloc(void *ptr
, DWORD cb
)
535 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ptr
, cb
);
538 void WINAPI
WINTRUST_Free(void *p
)
540 HeapFree(GetProcessHeap(), 0, p
);
543 BOOL WINAPI
WINTRUST_AddStore(CRYPT_PROVIDER_DATA
*data
, HCERTSTORE store
)
548 data
->pahStores
= WINTRUST_ReAlloc(data
->pahStores
,
549 (data
->chStores
+ 1) * sizeof(HCERTSTORE
));
552 data
->pahStores
= WINTRUST_Alloc(sizeof(HCERTSTORE
));
557 data
->pahStores
[data
->chStores
++] = CertDuplicateStore(store
);
561 SetLastError(ERROR_OUTOFMEMORY
);
565 BOOL WINAPI
WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA
*data
,
566 BOOL fCounterSigner
, DWORD idxSigner
, CRYPT_PROVIDER_SGNR
*sgnr
)
570 if (sgnr
->cbStruct
> sizeof(CRYPT_PROVIDER_SGNR
))
572 SetLastError(ERROR_INVALID_PARAMETER
);
577 FIXME("unimplemented for counter signers\n");
578 SetLastError(ERROR_INVALID_PARAMETER
);
582 data
->pasSigners
= WINTRUST_ReAlloc(data
->pasSigners
,
583 (data
->csSigners
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
586 data
->pasSigners
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
589 if (data
->pasSigners
)
591 if (idxSigner
< data
->csSigners
)
592 memmove(&data
->pasSigners
[idxSigner
],
593 &data
->pasSigners
[idxSigner
+ 1],
594 (data
->csSigners
- idxSigner
) * sizeof(CRYPT_PROVIDER_SGNR
));
596 if (sgnr
->cbStruct
== sizeof(CRYPT_PROVIDER_SGNR
))
598 /* The PSDK says psSigner should be allocated using pfnAlloc, but
599 * it doesn't say anything about ownership. Since callers are
600 * internal, assume ownership is passed, and just store the
603 memcpy(&data
->pasSigners
[idxSigner
], sgnr
,
604 sizeof(CRYPT_PROVIDER_SGNR
));
607 memset(&data
->pasSigners
[idxSigner
], 0,
608 sizeof(CRYPT_PROVIDER_SGNR
));
612 SetLastError(ERROR_OUTOFMEMORY
);
616 BOOL WINAPI
WINTRUST_AddCert(CRYPT_PROVIDER_DATA
*data
, DWORD idxSigner
,
617 BOOL fCounterSigner
, DWORD idxCounterSigner
, PCCERT_CONTEXT pCert2Add
)
623 FIXME("unimplemented for counter signers\n");
624 SetLastError(ERROR_INVALID_PARAMETER
);
627 if (data
->pasSigners
[idxSigner
].csCertChain
)
628 data
->pasSigners
[idxSigner
].pasCertChain
=
629 WINTRUST_ReAlloc(data
->pasSigners
[idxSigner
].pasCertChain
,
630 (data
->pasSigners
[idxSigner
].csCertChain
+ 1) *
631 sizeof(CRYPT_PROVIDER_CERT
));
634 data
->pasSigners
[idxSigner
].pasCertChain
=
635 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT
));
636 data
->pasSigners
[idxSigner
].csCertChain
= 0;
638 if (data
->pasSigners
[idxSigner
].pasCertChain
)
640 CRYPT_PROVIDER_CERT
*cert
= &data
->pasSigners
[idxSigner
].pasCertChain
[
641 data
->pasSigners
[idxSigner
].csCertChain
];
643 cert
->cbStruct
= sizeof(CRYPT_PROVIDER_CERT
);
644 cert
->pCert
= CertDuplicateCertificateContext(pCert2Add
);
645 data
->pasSigners
[idxSigner
].csCertChain
++;
649 SetLastError(ERROR_OUTOFMEMORY
);