2 * Copyright 2001 Rein Klazes
3 * Copyright 2007 Juan Lang
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
37 #include "wintrust_priv.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(wintrust
);
43 /***********************************************************************
44 * DllMain (WINTRUST.@)
46 BOOL WINAPI
DllMain( HINSTANCE inst
, DWORD reason
, LPVOID reserved
)
50 case DLL_PROCESS_ATTACH
:
51 DisableThreadLibraryCalls( inst
);
57 /***********************************************************************
58 * TrustIsCertificateSelfSigned (WINTRUST.@)
60 BOOL WINAPI
TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert
)
65 ret
= CertCompareCertificateName(cert
->dwCertEncodingType
,
66 &cert
->pCertInfo
->Subject
, &cert
->pCertInfo
->Issuer
);
70 typedef HRESULT (WINAPI
*wintrust_step_func
)(CRYPT_PROVIDER_DATA
*data
);
74 wintrust_step_func func
;
78 static DWORD
WINTRUST_ExecuteSteps(const struct wintrust_step
*steps
,
79 DWORD numSteps
, CRYPT_PROVIDER_DATA
*provData
)
81 DWORD i
, err
= ERROR_SUCCESS
;
83 for (i
= 0; !err
&& i
< numSteps
; i
++)
85 err
= steps
[i
].func(provData
);
87 err
= provData
->padwTrustStepErrors
[steps
[i
].error_index
];
92 static CRYPT_PROVIDER_DATA
*WINTRUST_AllocateProviderData(void)
94 CRYPT_PROVIDER_DATA
*provData
;
96 provData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA
));
99 provData
->cbStruct
= sizeof(CRYPT_PROVIDER_DATA
);
101 provData
->padwTrustStepErrors
=
102 WINTRUST_Alloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
103 if (!provData
->padwTrustStepErrors
)
105 provData
->cdwTrustStepErrors
= TRUSTERROR_MAX_STEPS
;
107 provData
->u
.pPDSip
= WINTRUST_Alloc(sizeof(PROVDATA_SIP
));
108 if (!provData
->u
.pPDSip
)
110 provData
->u
.pPDSip
->cbStruct
= sizeof(PROVDATA_SIP
);
112 provData
->psPfns
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS
));
113 if (!provData
->psPfns
)
115 provData
->psPfns
->cbStruct
= sizeof(CRYPT_PROVIDER_FUNCTIONS
);
121 WINTRUST_Free(provData
->padwTrustStepErrors
);
122 WINTRUST_Free(provData
->u
.pPDSip
);
123 WINTRUST_Free(provData
->psPfns
);
124 WINTRUST_Free(provData
);
129 /* Adds trust steps for each function in psPfns. Assumes steps has at least
130 * 5 entries. Returns the number of steps added.
132 static DWORD
WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step
*steps
,
133 const CRYPT_PROVIDER_FUNCTIONS
*psPfns
)
137 if (psPfns
->pfnInitialize
)
139 steps
[numSteps
].func
= psPfns
->pfnInitialize
;
140 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_WVTINIT
;
142 if (psPfns
->pfnObjectTrust
)
144 steps
[numSteps
].func
= psPfns
->pfnObjectTrust
;
145 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_OBJPROV
;
147 if (psPfns
->pfnSignatureTrust
)
149 steps
[numSteps
].func
= psPfns
->pfnSignatureTrust
;
150 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_SIGPROV
;
152 if (psPfns
->pfnCertificateTrust
)
154 steps
[numSteps
].func
= psPfns
->pfnCertificateTrust
;
155 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_CERTPROV
;
157 if (psPfns
->pfnFinalPolicy
)
159 steps
[numSteps
].func
= psPfns
->pfnFinalPolicy
;
160 steps
[numSteps
++].error_index
= TRUSTERROR_STEP_FINAL_POLICYPROV
;
165 static LONG
WINTRUST_DefaultVerify(HWND hwnd
, GUID
*actionID
,
168 DWORD err
= ERROR_SUCCESS
, numSteps
= 0;
169 CRYPT_PROVIDER_DATA
*provData
;
171 struct wintrust_step verifySteps
[5];
173 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
175 provData
= WINTRUST_AllocateProviderData();
177 return ERROR_OUTOFMEMORY
;
179 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
182 err
= GetLastError();
186 data
->hWVTStateData
= (HANDLE
)provData
;
187 provData
->pWintrustData
= data
;
188 if (hwnd
== INVALID_HANDLE_VALUE
)
189 provData
->hWndParent
= GetDesktopWindow();
191 provData
->hWndParent
= hwnd
;
192 provData
->pgActionID
= actionID
;
193 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
195 numSteps
= WINTRUST_AddTrustStepsFromFunctions(verifySteps
,
197 err
= WINTRUST_ExecuteSteps(verifySteps
, numSteps
, provData
);
203 WINTRUST_Free(provData
->padwTrustStepErrors
);
204 WINTRUST_Free(provData
->u
.pPDSip
);
205 WINTRUST_Free(provData
->psPfns
);
206 WINTRUST_Free(provData
);
209 TRACE("returning %08x\n", err
);
213 static LONG
WINTRUST_DefaultClose(HWND hwnd
, GUID
*actionID
,
216 DWORD err
= ERROR_SUCCESS
;
217 CRYPT_PROVIDER_DATA
*provData
= (CRYPT_PROVIDER_DATA
*)data
->hWVTStateData
;
219 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
223 if (provData
->psPfns
->pfnCleanupPolicy
)
224 err
= provData
->psPfns
->pfnCleanupPolicy(provData
);
226 WINTRUST_Free(provData
->padwTrustStepErrors
);
227 WINTRUST_Free(provData
->u
.pPDSip
);
228 WINTRUST_Free(provData
->psPfns
);
229 WINTRUST_Free(provData
);
230 data
->hWVTStateData
= NULL
;
232 TRACE("returning %08x\n", err
);
236 static LONG
WINTRUST_DefaultVerifyAndClose(HWND hwnd
, GUID
*actionID
,
241 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
243 err
= WINTRUST_DefaultVerify(hwnd
, actionID
, data
);
244 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
245 TRACE("returning %08x\n", err
);
249 static LONG
WINTRUST_PublishedSoftware(HWND hwnd
, GUID
*actionID
,
252 WINTRUST_DATA wintrust_data
= { sizeof(wintrust_data
), 0 };
253 /* Undocumented: the published software action is passed a path,
254 * and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
256 LPWIN_TRUST_SUBJECT_FILE subjectFile
=
257 (LPWIN_TRUST_SUBJECT_FILE
)data
->pSIPClientData
;
258 WINTRUST_FILE_INFO fileInfo
= { sizeof(fileInfo
), 0 };
260 TRACE("subjectFile->hFile: %p\n", subjectFile
->hFile
);
261 TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile
->lpPath
));
262 fileInfo
.pcwszFilePath
= subjectFile
->lpPath
;
263 fileInfo
.hFile
= subjectFile
->hFile
;
264 wintrust_data
.u
.pFile
= &fileInfo
;
265 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
266 wintrust_data
.dwUIChoice
= WTD_UI_NONE
;
268 return WINTRUST_DefaultVerifyAndClose(hwnd
, actionID
, &wintrust_data
);
271 /* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
272 * action is not stored in the registry and is located in wintrust, not in
273 * cryptdlg along with the rest of the implementation (verified by running the
274 * action with a native wintrust.dll.)
276 static HRESULT WINAPI
WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA
*data
)
280 TRACE("(%p)\n", data
);
282 if (!data
->padwTrustStepErrors
)
285 switch (data
->pWintrustData
->dwUnionChoice
)
287 case WTD_CHOICE_BLOB
:
288 if (data
->pWintrustData
->u
.pBlob
&&
289 data
->pWintrustData
->u
.pBlob
->cbStruct
== sizeof(WINTRUST_BLOB_INFO
) &&
290 data
->pWintrustData
->u
.pBlob
->cbMemObject
==
291 sizeof(CERT_VERIFY_CERTIFICATE_TRUST
) &&
292 data
->pWintrustData
->u
.pBlob
->pbMemObject
)
294 CERT_VERIFY_CERTIFICATE_TRUST
*pCert
=
295 (CERT_VERIFY_CERTIFICATE_TRUST
*)
296 data
->pWintrustData
->u
.pBlob
->pbMemObject
;
298 if (pCert
->cbSize
== sizeof(CERT_VERIFY_CERTIFICATE_TRUST
) &&
301 CRYPT_PROVIDER_SGNR signer
= { sizeof(signer
), { 0 } };
305 /* Add a signer with nothing but the time to verify, so we can
308 GetSystemTime(&sysTime
);
309 SystemTimeToFileTime(&sysTime
, &signer
.sftVerifyAsOf
);
310 ret
= data
->psPfns
->pfnAddSgnr2Chain(data
, FALSE
, 0, &signer
);
313 ret
= data
->psPfns
->pfnAddCert2Chain(data
, 0, FALSE
, 0,
317 for (i
= 0; ret
&& i
< pCert
->cRootStores
; i
++)
318 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
319 pCert
->rghstoreRoots
[i
]);
320 for (i
= 0; ret
&& i
< pCert
->cStores
; i
++)
321 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
322 pCert
->rghstoreCAs
[i
]);
323 for (i
= 0; ret
&& i
< pCert
->cTrustStores
; i
++)
324 ret
= data
->psPfns
->pfnAddStore2Chain(data
,
325 pCert
->rghstoreTrust
[i
]);
329 SetLastError(ERROR_INVALID_PARAMETER
);
335 SetLastError(ERROR_INVALID_PARAMETER
);
340 FIXME("unimplemented for %d\n", data
->pWintrustData
->dwUnionChoice
);
341 SetLastError(ERROR_INVALID_PARAMETER
);
347 data
->padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] =
349 TRACE("returning %d (%08x)\n", ret
? S_OK
: S_FALSE
,
350 data
->padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
351 return ret
? S_OK
: S_FALSE
;
354 static LONG
WINTRUST_CertVerify(HWND hwnd
, GUID
*actionID
,
357 DWORD err
= ERROR_SUCCESS
, numSteps
= 0;
358 CRYPT_PROVIDER_DATA
*provData
;
360 struct wintrust_step verifySteps
[5];
362 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
364 provData
= WINTRUST_AllocateProviderData();
366 return ERROR_OUTOFMEMORY
;
368 ret
= WintrustLoadFunctionPointers(actionID
, provData
->psPfns
);
371 err
= GetLastError();
374 if (!provData
->psPfns
->pfnObjectTrust
)
375 provData
->psPfns
->pfnObjectTrust
= WINTRUST_CertVerifyObjTrust
;
376 /* Not sure why, but native skips the policy check */
377 provData
->psPfns
->pfnCertCheckPolicy
= NULL
;
379 data
->hWVTStateData
= (HANDLE
)provData
;
380 provData
->pWintrustData
= data
;
381 if (hwnd
== INVALID_HANDLE_VALUE
)
382 provData
->hWndParent
= GetDesktopWindow();
384 provData
->hWndParent
= hwnd
;
385 provData
->pgActionID
= actionID
;
386 WintrustGetRegPolicyFlags(&provData
->dwRegPolicySettings
);
388 numSteps
= WINTRUST_AddTrustStepsFromFunctions(verifySteps
,
390 err
= WINTRUST_ExecuteSteps(verifySteps
, numSteps
, provData
);
396 WINTRUST_Free(provData
->padwTrustStepErrors
);
397 WINTRUST_Free(provData
->u
.pPDSip
);
398 WINTRUST_Free(provData
->psPfns
);
399 WINTRUST_Free(provData
);
402 TRACE("returning %08x\n", err
);
406 static LONG
WINTRUST_CertVerifyAndClose(HWND hwnd
, GUID
*actionID
,
411 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(actionID
), data
);
413 err
= WINTRUST_CertVerify(hwnd
, actionID
, data
);
414 WINTRUST_DefaultClose(hwnd
, actionID
, data
);
415 TRACE("returning %08x\n", err
);
419 static LONG
WINTRUST_CertActionVerify(HWND hwnd
, GUID
*actionID
,
423 LONG err
= ERROR_SUCCESS
;
425 if (WVT_ISINSTRUCT(WINTRUST_DATA
, data
->cbStruct
, dwStateAction
))
426 stateAction
= data
->dwStateAction
;
429 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
430 stateAction
= WTD_STATEACTION_IGNORE
;
434 case WTD_STATEACTION_IGNORE
:
435 err
= WINTRUST_CertVerifyAndClose(hwnd
, actionID
, data
);
437 case WTD_STATEACTION_VERIFY
:
438 err
= WINTRUST_CertVerify(hwnd
, actionID
, data
);
440 case WTD_STATEACTION_CLOSE
:
441 err
= WINTRUST_DefaultClose(hwnd
, actionID
, data
);
444 FIXME("unimplemented for %d\n", data
->dwStateAction
);
449 static void dump_file_info(WINTRUST_FILE_INFO
*pFile
)
451 TRACE("%p\n", pFile
);
454 TRACE("cbStruct: %d\n", pFile
->cbStruct
);
455 TRACE("pcwszFilePath: %s\n", debugstr_w(pFile
->pcwszFilePath
));
456 TRACE("hFile: %p\n", pFile
->hFile
);
457 TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile
->pgKnownSubject
));
461 static void dump_catalog_info(WINTRUST_CATALOG_INFO
*catalog
)
463 TRACE("%p\n", catalog
);
466 TRACE("cbStruct: %d\n", catalog
->cbStruct
);
467 TRACE("dwCatalogVersion: %d\n", catalog
->dwCatalogVersion
);
468 TRACE("pcwszCatalogFilePath: %s\n",
469 debugstr_w(catalog
->pcwszCatalogFilePath
));
470 TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog
->pcwszMemberTag
));
471 TRACE("pcwszMemberFilePath: %s\n",
472 debugstr_w(catalog
->pcwszMemberFilePath
));
473 TRACE("hMemberFile: %p\n", catalog
->hMemberFile
);
474 TRACE("pbCalculatedFileHash: %p\n", catalog
->pbCalculatedFileHash
);
475 TRACE("cbCalculatedFileHash: %d\n", catalog
->cbCalculatedFileHash
);
476 TRACE("pcCatalogContext: %p\n", catalog
->pcCatalogContext
);
480 static void dump_blob_info(WINTRUST_BLOB_INFO
*blob
)
485 TRACE("cbStruct: %d\n", blob
->cbStruct
);
486 TRACE("gSubject: %s\n", debugstr_guid(&blob
->gSubject
));
487 TRACE("pcwszDisplayName: %s\n", debugstr_w(blob
->pcwszDisplayName
));
488 TRACE("cbMemObject: %d\n", blob
->cbMemObject
);
489 TRACE("pbMemObject: %p\n", blob
->pbMemObject
);
490 TRACE("cbMemSignedMsg: %d\n", blob
->cbMemSignedMsg
);
491 TRACE("pbMemSignedMsg: %p\n", blob
->pbMemSignedMsg
);
495 static void dump_sgnr_info(WINTRUST_SGNR_INFO
*sgnr
)
500 TRACE("cbStruct: %d\n", sgnr
->cbStruct
);
501 TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr
->pcwszDisplayName
));
502 TRACE("psSignerInfo: %p\n", sgnr
->psSignerInfo
);
503 TRACE("chStores: %d\n", sgnr
->chStores
);
507 static void dump_cert_info(WINTRUST_CERT_INFO
*cert
)
512 TRACE("cbStruct: %d\n", cert
->cbStruct
);
513 TRACE("pcwszDisplayName: %s\n", debugstr_w(cert
->pcwszDisplayName
));
514 TRACE("psCertContext: %p\n", cert
->psCertContext
);
515 TRACE("chStores: %d\n", cert
->chStores
);
516 TRACE("dwFlags: %08x\n", cert
->dwFlags
);
517 TRACE("psftVerifyAsOf: %p\n", cert
->psftVerifyAsOf
);
521 static void dump_wintrust_data(WINTRUST_DATA
*data
)
526 TRACE("cbStruct: %d\n", data
->cbStruct
);
527 TRACE("pPolicyCallbackData: %p\n", data
->pPolicyCallbackData
);
528 TRACE("pSIPClientData: %p\n", data
->pSIPClientData
);
529 TRACE("dwUIChoice: %d\n", data
->dwUIChoice
);
530 TRACE("fdwRevocationChecks: %08x\n", data
->fdwRevocationChecks
);
531 TRACE("dwUnionChoice: %d\n", data
->dwUnionChoice
);
532 switch (data
->dwUnionChoice
)
534 case WTD_CHOICE_FILE
:
535 dump_file_info(data
->u
.pFile
);
537 case WTD_CHOICE_CATALOG
:
538 dump_catalog_info(data
->u
.pCatalog
);
540 case WTD_CHOICE_BLOB
:
541 dump_blob_info(data
->u
.pBlob
);
543 case WTD_CHOICE_SIGNER
:
544 dump_sgnr_info(data
->u
.pSgnr
);
546 case WTD_CHOICE_CERT
:
547 dump_cert_info(data
->u
.pCert
);
550 TRACE("dwStateAction: %d\n", data
->dwStateAction
);
551 TRACE("hWVTStateData: %p\n", data
->hWVTStateData
);
552 TRACE("pwszURLReference: %s\n", debugstr_w(data
->pwszURLReference
));
553 TRACE("dwProvFlags: %08x\n", data
->dwProvFlags
);
554 TRACE("dwUIContext: %d\n", data
->dwUIContext
);
558 /***********************************************************************
559 * WinVerifyTrust (WINTRUST.@)
561 * Verifies an object by calling the specified trust provider.
564 * hwnd [I] Handle to a caller window.
565 * ActionID [I] Pointer to a GUID that identifies the action to perform.
566 * ActionData [I] Information used by the trust provider to verify the object.
570 * Failure: A TRUST_E_* error code.
573 * Trust providers can be found at:
574 * HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\
576 LONG WINAPI
WinVerifyTrust( HWND hwnd
, GUID
*ActionID
, LPVOID ActionData
)
578 static const GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
579 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
580 static const GUID published_software
= WIN_SPUB_ACTION_PUBLISHED_SOFTWARE
;
581 static const GUID generic_verify_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
582 static const GUID generic_cert_verify
= WINTRUST_ACTION_GENERIC_CERT_VERIFY
;
583 static const GUID generic_chain_verify
= WINTRUST_ACTION_GENERIC_CHAIN_VERIFY
;
584 static const GUID cert_action_verify
= CERT_CERTIFICATE_ACTION_VERIFY
;
585 LONG err
= ERROR_SUCCESS
;
586 WINTRUST_DATA
*actionData
= (WINTRUST_DATA
*)ActionData
;
588 TRACE("(%p, %s, %p)\n", hwnd
, debugstr_guid(ActionID
), ActionData
);
589 dump_wintrust_data(ActionData
);
591 /* Support for known old-style callers: */
592 if (IsEqualGUID(ActionID
, &published_software
))
593 err
= WINTRUST_PublishedSoftware(hwnd
, ActionID
, ActionData
);
594 else if (IsEqualGUID(ActionID
, &cert_action_verify
))
595 err
= WINTRUST_CertActionVerify(hwnd
, ActionID
, ActionData
);
600 /* Check known actions to warn of possible problems */
601 if (!IsEqualGUID(ActionID
, &unknown
) &&
602 !IsEqualGUID(ActionID
, &generic_verify_v2
) &&
603 !IsEqualGUID(ActionID
, &generic_cert_verify
) &&
604 !IsEqualGUID(ActionID
, &generic_chain_verify
))
605 WARN("unknown action %s, default behavior may not be right\n",
606 debugstr_guid(ActionID
));
607 if (WVT_ISINSTRUCT(WINTRUST_DATA
, actionData
->cbStruct
, dwStateAction
))
608 stateAction
= actionData
->dwStateAction
;
611 TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
612 stateAction
= WTD_STATEACTION_IGNORE
;
616 case WTD_STATEACTION_IGNORE
:
617 err
= WINTRUST_DefaultVerifyAndClose(hwnd
, ActionID
, ActionData
);
619 case WTD_STATEACTION_VERIFY
:
620 err
= WINTRUST_DefaultVerify(hwnd
, ActionID
, ActionData
);
622 case WTD_STATEACTION_CLOSE
:
623 err
= WINTRUST_DefaultClose(hwnd
, ActionID
, ActionData
);
626 FIXME("unimplemented for %d\n", actionData
->dwStateAction
);
630 TRACE("returning %08x\n", err
);
634 /***********************************************************************
635 * WinVerifyTrustEx (WINTRUST.@)
637 HRESULT WINAPI
WinVerifyTrustEx( HWND hwnd
, GUID
*ActionID
,
638 WINTRUST_DATA
* ActionData
)
640 return WinVerifyTrust(hwnd
, ActionID
, ActionData
);
643 /***********************************************************************
644 * WTHelperGetProvSignerFromChain (WINTRUST.@)
646 CRYPT_PROVIDER_SGNR
* WINAPI
WTHelperGetProvSignerFromChain(
647 CRYPT_PROVIDER_DATA
*pProvData
, DWORD idxSigner
, BOOL fCounterSigner
,
648 DWORD idxCounterSigner
)
650 CRYPT_PROVIDER_SGNR
*sgnr
;
652 TRACE("(%p %d %d %d)\n", pProvData
, idxSigner
, fCounterSigner
,
655 if (idxSigner
>= pProvData
->csSigners
|| !pProvData
->pasSigners
)
657 sgnr
= &pProvData
->pasSigners
[idxSigner
];
660 if (idxCounterSigner
>= sgnr
->csCounterSigners
||
661 !sgnr
->pasCounterSigners
)
663 sgnr
= &sgnr
->pasCounterSigners
[idxCounterSigner
];
665 TRACE("returning %p\n", sgnr
);
669 /***********************************************************************
670 * WTHelperGetProvCertFromChain (WINTRUST.@)
672 CRYPT_PROVIDER_CERT
* WINAPI
WTHelperGetProvCertFromChain(
673 CRYPT_PROVIDER_SGNR
*pSgnr
, DWORD idxCert
)
675 CRYPT_PROVIDER_CERT
*cert
;
677 TRACE("(%p %d)\n", pSgnr
, idxCert
);
679 if (idxCert
>= pSgnr
->csCertChain
|| !pSgnr
->pasCertChain
)
681 cert
= &pSgnr
->pasCertChain
[idxCert
];
682 TRACE("returning %p\n", cert
);
686 CRYPT_PROVIDER_PRIVDATA
*WINAPI
WTHelperGetProvPrivateDataFromChain(
687 CRYPT_PROVIDER_DATA
* pProvData
,
690 CRYPT_PROVIDER_PRIVDATA
*privdata
= NULL
;
693 TRACE("(%p, %s)\n", pProvData
, debugstr_guid(pgProviderID
));
695 for (i
= 0; i
< pProvData
->csProvPrivData
; i
++)
696 if (IsEqualGUID(pgProviderID
, &pProvData
->pasProvPrivData
[i
].gProviderID
))
698 privdata
= &pProvData
->pasProvPrivData
[i
];
705 /***********************************************************************
706 * WTHelperProvDataFromStateData (WINTRUST.@)
708 CRYPT_PROVIDER_DATA
* WINAPI
WTHelperProvDataFromStateData(HANDLE hStateData
)
710 TRACE("%p\n", hStateData
);
711 return (CRYPT_PROVIDER_DATA
*)hStateData
;
714 /***********************************************************************
715 * WTHelperGetFileName(WINTRUST.@)
717 LPCWSTR WINAPI
WTHelperGetFileName(WINTRUST_DATA
*data
)
720 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
721 return data
->u
.pFile
->pcwszFilePath
;
726 /***********************************************************************
727 * WTHelperGetFileHandle(WINTRUST.@)
729 HANDLE WINAPI
WTHelperGetFileHandle(WINTRUST_DATA
*data
)
732 if (data
->dwUnionChoice
== WTD_CHOICE_FILE
)
733 return data
->u
.pFile
->hFile
;
735 return INVALID_HANDLE_VALUE
;
738 static const WCHAR Software_Publishing
[] = {
739 'S','o','f','t','w','a','r','e','\\',
740 'M','i','c','r','o','s','o','f','t','\\',
741 'W','i','n','d','o','w','s','\\',
742 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
743 'W','i','n','t','r','u','s','t','\\',
744 'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
745 'S','o','f','t','w','a','r','e',' ',
746 'P','u','b','l','i','s','h','i','n','g',0 };
747 static const WCHAR State
[] = { 'S','t','a','t','e',0 };
749 /***********************************************************************
750 * WintrustGetRegPolicyFlags (WINTRUST.@)
752 void WINAPI
WintrustGetRegPolicyFlags( DWORD
* pdwPolicyFlags
)
757 TRACE("%p\n", pdwPolicyFlags
);
760 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0, NULL
, 0,
761 KEY_READ
, NULL
, &key
, NULL
);
764 DWORD size
= sizeof(DWORD
);
766 r
= RegQueryValueExW(key
, State
, NULL
, NULL
, (LPBYTE
)pdwPolicyFlags
,
771 /* Failed to query, create and return default value */
772 *pdwPolicyFlags
= WTPF_IGNOREREVOCATIONONTS
|
773 WTPF_OFFLINEOKNBU_COM
|
774 WTPF_OFFLINEOKNBU_IND
|
777 WintrustSetRegPolicyFlags(*pdwPolicyFlags
);
782 /***********************************************************************
783 * WintrustSetRegPolicyFlags (WINTRUST.@)
785 BOOL WINAPI
WintrustSetRegPolicyFlags( DWORD dwPolicyFlags
)
790 TRACE("%x\n", dwPolicyFlags
);
792 r
= RegCreateKeyExW(HKEY_CURRENT_USER
, Software_Publishing
, 0,
793 NULL
, 0, KEY_WRITE
, NULL
, &key
, NULL
);
796 r
= RegSetValueExW(key
, State
, 0, REG_DWORD
, (LPBYTE
)&dwPolicyFlags
,
800 if (r
) SetLastError(r
);
801 return r
== ERROR_SUCCESS
;
804 /* Utility functions */
805 void * WINAPI
WINTRUST_Alloc(DWORD cb
)
807 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cb
);
810 void * WINAPI
WINTRUST_ReAlloc(void *ptr
, DWORD cb
)
812 return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ptr
, cb
);
815 void WINAPI
WINTRUST_Free(void *p
)
817 HeapFree(GetProcessHeap(), 0, p
);
820 BOOL WINAPI
WINTRUST_AddStore(CRYPT_PROVIDER_DATA
*data
, HCERTSTORE store
)
824 TRACE("(%p, %p)\n", data
, store
);
827 data
->pahStores
= WINTRUST_ReAlloc(data
->pahStores
,
828 (data
->chStores
+ 1) * sizeof(HCERTSTORE
));
831 data
->pahStores
= WINTRUST_Alloc(sizeof(HCERTSTORE
));
836 data
->pahStores
[data
->chStores
++] = CertDuplicateStore(store
);
840 SetLastError(ERROR_OUTOFMEMORY
);
844 BOOL WINAPI
WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA
*data
,
845 BOOL fCounterSigner
, DWORD idxSigner
, CRYPT_PROVIDER_SGNR
*sgnr
)
849 TRACE("(%p, %d, %d, %p)\n", data
, fCounterSigner
, idxSigner
, sgnr
);
851 if (sgnr
->cbStruct
> sizeof(CRYPT_PROVIDER_SGNR
))
853 SetLastError(ERROR_INVALID_PARAMETER
);
858 FIXME("unimplemented for counter signers\n");
859 SetLastError(ERROR_INVALID_PARAMETER
);
863 data
->pasSigners
= WINTRUST_ReAlloc(data
->pasSigners
,
864 (data
->csSigners
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
867 data
->pasSigners
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
870 if (data
->pasSigners
)
872 if (idxSigner
< data
->csSigners
)
873 memmove(&data
->pasSigners
[idxSigner
],
874 &data
->pasSigners
[idxSigner
+ 1],
875 (data
->csSigners
- idxSigner
) * sizeof(CRYPT_PROVIDER_SGNR
));
877 if (sgnr
->cbStruct
== sizeof(CRYPT_PROVIDER_SGNR
))
879 /* The PSDK says psSigner should be allocated using pfnAlloc, but
880 * it doesn't say anything about ownership. Since callers are
881 * internal, assume ownership is passed, and just store the
884 memcpy(&data
->pasSigners
[idxSigner
], sgnr
,
885 sizeof(CRYPT_PROVIDER_SGNR
));
888 memset(&data
->pasSigners
[idxSigner
], 0,
889 sizeof(CRYPT_PROVIDER_SGNR
));
893 SetLastError(ERROR_OUTOFMEMORY
);
897 BOOL WINAPI
WINTRUST_AddCert(CRYPT_PROVIDER_DATA
*data
, DWORD idxSigner
,
898 BOOL fCounterSigner
, DWORD idxCounterSigner
, PCCERT_CONTEXT pCert2Add
)
902 TRACE("(%p, %d, %d, %d, %p)\n", data
, idxSigner
, fCounterSigner
,
903 idxSigner
, pCert2Add
);
907 FIXME("unimplemented for counter signers\n");
908 SetLastError(ERROR_INVALID_PARAMETER
);
911 if (data
->pasSigners
[idxSigner
].csCertChain
)
912 data
->pasSigners
[idxSigner
].pasCertChain
=
913 WINTRUST_ReAlloc(data
->pasSigners
[idxSigner
].pasCertChain
,
914 (data
->pasSigners
[idxSigner
].csCertChain
+ 1) *
915 sizeof(CRYPT_PROVIDER_CERT
));
918 data
->pasSigners
[idxSigner
].pasCertChain
=
919 WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT
));
920 data
->pasSigners
[idxSigner
].csCertChain
= 0;
922 if (data
->pasSigners
[idxSigner
].pasCertChain
)
924 CRYPT_PROVIDER_CERT
*cert
= &data
->pasSigners
[idxSigner
].pasCertChain
[
925 data
->pasSigners
[idxSigner
].csCertChain
];
927 cert
->cbStruct
= sizeof(CRYPT_PROVIDER_CERT
);
928 cert
->pCert
= CertDuplicateCertificateContext(pCert2Add
);
929 data
->pasSigners
[idxSigner
].csCertChain
++;
933 SetLastError(ERROR_OUTOFMEMORY
);
937 BOOL WINAPI
WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA
*data
,
938 CRYPT_PROVIDER_PRIVDATA
*pPrivData2Add
)
942 TRACE("(%p, %p)\n", data
, pPrivData2Add
);
944 if (pPrivData2Add
->cbStruct
> sizeof(CRYPT_PROVIDER_PRIVDATA
))
946 SetLastError(ERROR_INVALID_PARAMETER
);
947 WARN("invalid struct size\n");
950 if (data
->csProvPrivData
)
951 data
->pasProvPrivData
= WINTRUST_ReAlloc(data
->pasProvPrivData
,
952 (data
->csProvPrivData
+ 1) * sizeof(CRYPT_PROVIDER_SGNR
));
955 data
->pasProvPrivData
= WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR
));
956 data
->csProvPrivData
= 0;
958 if (data
->pasProvPrivData
)
962 for (i
= 0; i
< data
->csProvPrivData
; i
++)
963 if (IsEqualGUID(&pPrivData2Add
->gProviderID
, &data
->pasProvPrivData
[i
]))
966 data
->pasProvPrivData
[i
] = *pPrivData2Add
;
967 if (i
== data
->csProvPrivData
)
968 data
->csProvPrivData
++;
971 SetLastError(ERROR_OUTOFMEMORY
);