Juan Lang : wintrust: Support the CERT_CERTIFICATE_ACTION_VERIFY action.
Alexandre Julliard
julliard at winehq.org
Tue Sep 23 09:28:24 CDT 2008
Module: wine
Branch: master
Commit: d99b23819d34b9627745ec4474b5edbf93d86b00
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d99b23819d34b9627745ec4474b5edbf93d86b00
Author: Juan Lang <juan.lang at gmail.com>
Date: Mon Sep 22 13:20:35 2008 -0700
wintrust: Support the CERT_CERTIFICATE_ACTION_VERIFY action.
---
dlls/wintrust/wintrust_main.c | 182 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 182 insertions(+), 0 deletions(-)
diff --git a/dlls/wintrust/wintrust_main.c b/dlls/wintrust/wintrust_main.c
index a1893d3..2218ca0 100644
--- a/dlls/wintrust/wintrust_main.c
+++ b/dlls/wintrust/wintrust_main.c
@@ -33,6 +33,7 @@
#include "mscat.h"
#include "objbase.h"
#include "winuser.h"
+#include "cryptdlg.h"
#include "wintrust_priv.h"
#include "wine/debug.h"
@@ -267,6 +268,184 @@ static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
}
+/* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY
+ * action is not stored in the registry and is located in wintrust, not in
+ * cryptdlg along with the rest of the implementation (verified by running the
+ * action with a native wintrust.dll.)
+ */
+static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data)
+{
+ BOOL ret;
+
+ TRACE("(%p)\n", data);
+
+ if (!data->padwTrustStepErrors)
+ return S_FALSE;
+
+ switch (data->pWintrustData->dwUnionChoice)
+ {
+ case WTD_CHOICE_BLOB:
+ if (data->pWintrustData->u.pBlob &&
+ data->pWintrustData->u.pBlob->cbStruct == sizeof(WINTRUST_BLOB_INFO) &&
+ data->pWintrustData->u.pBlob->cbMemObject ==
+ sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
+ data->pWintrustData->u.pBlob->pbMemObject)
+ {
+ CERT_VERIFY_CERTIFICATE_TRUST *pCert =
+ (CERT_VERIFY_CERTIFICATE_TRUST *)
+ data->pWintrustData->u.pBlob->pbMemObject;
+
+ if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
+ pCert->pccert)
+ {
+ CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
+ DWORD i;
+ SYSTEMTIME sysTime;
+
+ /* Add a signer with nothing but the time to verify, so we can
+ * add a cert to it
+ */
+ GetSystemTime(&sysTime);
+ SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
+ ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
+ if (!ret)
+ goto error;
+ ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
+ pCert->pccert);
+ if (!ret)
+ goto error;
+ for (i = 0; ret && i < pCert->cRootStores; i++)
+ ret = data->psPfns->pfnAddStore2Chain(data,
+ pCert->rghstoreRoots[i]);
+ for (i = 0; ret && i < pCert->cStores; i++)
+ ret = data->psPfns->pfnAddStore2Chain(data,
+ pCert->rghstoreCAs[i]);
+ for (i = 0; ret && i < pCert->cTrustStores; i++)
+ ret = data->psPfns->pfnAddStore2Chain(data,
+ pCert->rghstoreTrust[i]);
+ }
+ else
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ }
+ }
+ else
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ }
+ break;
+ default:
+ FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ }
+
+error:
+ if (!ret)
+ data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
+ GetLastError();
+ TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
+ data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
+ return ret ? S_OK : S_FALSE;
+}
+
+static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+ DWORD err = ERROR_SUCCESS, numSteps = 0;
+ CRYPT_PROVIDER_DATA *provData;
+ BOOL ret;
+ struct wintrust_step verifySteps[5];
+
+ TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
+
+ provData = WINTRUST_AllocateProviderData();
+ if (!provData)
+ return ERROR_OUTOFMEMORY;
+
+ ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
+ if (!ret)
+ {
+ err = GetLastError();
+ goto error;
+ }
+ if (!provData->psPfns->pfnObjectTrust)
+ provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust;
+ /* Not sure why, but native skips the policy check */
+ provData->psPfns->pfnCertCheckPolicy = NULL;
+
+ data->hWVTStateData = (HANDLE)provData;
+ provData->pWintrustData = data;
+ if (hwnd == INVALID_HANDLE_VALUE)
+ provData->hWndParent = GetDesktopWindow();
+ else
+ provData->hWndParent = hwnd;
+ provData->pgActionID = actionID;
+ WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
+
+ numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps,
+ provData->psPfns);
+ err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
+ goto done;
+
+error:
+ if (provData)
+ {
+ WINTRUST_Free(provData->padwTrustStepErrors);
+ WINTRUST_Free(provData->u.pPDSip);
+ WINTRUST_Free(provData->psPfns);
+ WINTRUST_Free(provData);
+ }
+done:
+ TRACE("returning %08x\n", err);
+ return err;
+}
+
+static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+ LONG err;
+
+ TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
+
+ err = WINTRUST_CertVerify(hwnd, actionID, data);
+ WINTRUST_DefaultClose(hwnd, actionID, data);
+ TRACE("returning %08x\n", err);
+ return err;
+}
+
+static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID,
+ WINTRUST_DATA *data)
+{
+ DWORD stateAction;
+ LONG err = ERROR_SUCCESS;
+
+ if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction))
+ stateAction = data->dwStateAction;
+ else
+ {
+ TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n");
+ stateAction = WTD_STATEACTION_IGNORE;
+ }
+ switch (stateAction)
+ {
+ case WTD_STATEACTION_IGNORE:
+ err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data);
+ break;
+ case WTD_STATEACTION_VERIFY:
+ err = WINTRUST_CertVerify(hwnd, actionID, data);
+ break;
+ case WTD_STATEACTION_CLOSE:
+ err = WINTRUST_DefaultClose(hwnd, actionID, data);
+ break;
+ default:
+ FIXME("unimplemented for %d\n", data->dwStateAction);
+ }
+ return err;
+}
+
static void dump_file_info(WINTRUST_FILE_INFO *pFile)
{
TRACE("%p\n", pFile);
@@ -402,6 +581,7 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
+ static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY;
LONG err = ERROR_SUCCESS;
WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
@@ -411,6 +591,8 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
/* Support for known old-style callers: */
if (IsEqualGUID(ActionID, &published_software))
err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
+ else if (IsEqualGUID(ActionID, &cert_action_verify))
+ err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData);
else
{
DWORD stateAction;
More information about the wine-cvs
mailing list