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 = 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; }
/*********************************************************************** * WTHelperGetKnownUsages(WINTRUST.@) * * Enumerates the known enhanced key usages as an array of PCCRYPT_OID_INFOs. * * PARAMS * action [In] 1 => allocate and return known usages, 2 => free previously * allocated usages. * usages [In/Out] If action == 1, *usages is set to an array of * PCCRYPT_OID_INFO *. The array is terminated with a NULL * pointer. * If action == 2, *usages is freed. * * RETURNS * TRUE on success, FALSE on failure. */ BOOL WINAPI WTHelperGetKnownUsages(DWORD action, PCCRYPT_OID_INFO **usages) { BOOL ret; TRACE("(%d, %p)\n", action, usages); if (!usages) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (action == 1) { *usages = NULL; ret = CryptEnumOIDInfo(CRYPT_ENHKEY_USAGE_OID_GROUP_ID, 0, usages, WINTRUST_enumUsages); } else if (action == 2) { WINTRUST_Free(*usages); *usages = NULL; ret = TRUE; } else { WARN("unknown action %d\n", action); SetLastError(ERROR_INVALID_PARAMETER); ret = FALSE; } return ret; }
static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID, WINTRUST_DATA *data) { DWORD err = ERROR_SUCCESS; CRYPT_PROVIDER_DATA *provData = data->hWVTStateData; TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); if (provData) { if (provData->psPfns->pfnCleanupPolicy) err = provData->psPfns->pfnCleanupPolicy(provData); WINTRUST_Free(provData->padwTrustStepErrors); WINTRUST_Free(provData->u.pPDSip); WINTRUST_Free(provData->psPfns); WINTRUST_Free(provData); data->hWVTStateData = NULL; } TRACE("returning %08x\n", err); return err; }
/*********************************************************************** * WINTRUST_WriteSingleUsageEntry * * Helper for WintrustAddDefaultForUsage, writes a single value and its * data to: * * HKLM\Software\Microsoft\Cryptography\Trust\Usages\<OID> */ static LONG WINTRUST_WriteSingleUsageEntry(LPCSTR OID, const WCHAR* Value, WCHAR* Data) { static const WCHAR Usages[] = {'U','s','a','g','e','s','\\', 0}; WCHAR* UsageKey; HKEY Key; LONG Res = ERROR_SUCCESS; WCHAR* OIDW; DWORD Len; /* Turn OID into a wide-character string */ Len = MultiByteToWideChar( CP_ACP, 0, OID, -1, NULL, 0 ); OIDW = WINTRUST_Alloc( Len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, OID, -1, OIDW, Len ); /* Allocate the needed space for UsageKey */ UsageKey = WINTRUST_Alloc((lstrlenW(Trust) + lstrlenW(Usages) + Len) * sizeof(WCHAR)); /* Create the key string */ lstrcpyW(UsageKey, Trust); lstrcatW(UsageKey, Usages); lstrcatW(UsageKey, OIDW); Res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, UsageKey, 0, NULL, 0, KEY_WRITE, NULL, &Key, NULL); if (Res == ERROR_SUCCESS) { /* Create the Value entry */ Res = RegSetValueExW(Key, Value, 0, REG_SZ, (BYTE*)Data, (lstrlenW(Data) + 1)*sizeof(WCHAR)); } RegCloseKey(Key); WINTRUST_Free(OIDW); WINTRUST_Free(UsageKey); return Res; }
static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void) { CRYPT_PROVIDER_DATA *provData; provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA)); if (!provData) goto oom; provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA); provData->padwTrustStepErrors = WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD)); if (!provData->padwTrustStepErrors) goto oom; provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS; provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP)); if (!provData->u.pPDSip) goto oom; provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP); provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS)); if (!provData->psPfns) goto oom; provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS); return provData; oom: if (provData) { WINTRUST_Free(provData->padwTrustStepErrors); WINTRUST_Free(provData->u.pPDSip); WINTRUST_Free(provData->psPfns); WINTRUST_Free(provData); } return NULL; }
/*************************************************************************** * WINTRUST_RegisterHttpsProv * * Register HTTPSPROV_ACTION actions and usages. * * NOTES * HTTPSPROV_ACTION ({573E31F8-AABA-11D0-8CCB-00C04FC295EE}) * is defined in softpub.h */ static BOOL WINTRUST_RegisterHttpsProv(void) { BOOL RegisteredOK = TRUE; static CHAR SoftpubLoadUsage[] = "SoftpubLoadDefUsageCallData"; static CHAR SoftpubFreeUsage[] = "SoftpubFreeDefUsageCallData"; static GUID ProvGUID = HTTPSPROV_ACTION; CRYPT_REGISTER_ACTIONID ProvInfo; CRYPT_PROVIDER_REGDEFUSAGE DefUsage = { sizeof(CRYPT_PROVIDER_REGDEFUSAGE), &ProvGUID, NULL, /* Will be filled later */ SoftpubLoadUsage, SoftpubFreeUsage }; ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID); ProvInfo.sInitProvider = SoftpubInitialization; ProvInfo.sObjectProvider = SoftpubMessage; ProvInfo.sSignatureProvider = SoftpubSignature; ProvInfo.sCertificateProvider = HTTPSCertificateTrust; ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck; ProvInfo.sFinalPolicyProvider = HTTPSFinalProv; ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */ ProvInfo.sCleanupProvider = SoftpubCleanup; DefUsage.pwszDllName = WINTRUST_Alloc(sizeof(SP_POLICY_PROVIDER_DLL_NAME)); lstrcpyW(DefUsage.pwszDllName, SP_POLICY_PROVIDER_DLL_NAME); if (!WintrustAddDefaultForUsage(szOID_PKIX_KP_SERVER_AUTH, &DefUsage)) RegisteredOK = FALSE; if (!WintrustAddDefaultForUsage(szOID_PKIX_KP_CLIENT_AUTH, &DefUsage)) RegisteredOK = FALSE; if (!WintrustAddDefaultForUsage(szOID_SERVER_GATED_CRYPTO, &DefUsage)) RegisteredOK = FALSE; if (!WintrustAddDefaultForUsage(szOID_SGC_NETSCAPE, &DefUsage)) RegisteredOK = FALSE; WINTRUST_Free(DefUsage.pwszDllName); if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo)) RegisteredOK = FALSE; return RegisteredOK; }
/*********************************************************************** * WINTRUST_SIPPAddProvider * * Helper for DllRegisterServer. */ static BOOL WINTRUST_SIPPAddProvider(GUID* Subject, WCHAR* MagicNumber) { static WCHAR CryptSIPGetSignedDataMsg[] = {'C','r','y','p','t','S','I','P','G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g', 0}; static WCHAR CryptSIPPutSignedDataMsg[] = {'C','r','y','p','t','S','I','P','P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g', 0}; static WCHAR CryptSIPCreateIndirectData[] = {'C','r','y','p','t','S','I','P','C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a', 0}; static WCHAR CryptSIPVerifyIndirectData[] = {'C','r','y','p','t','S','I','P','V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a', 0}; static WCHAR CryptSIPRemoveSignedDataMsg[] = {'C','r','y','p','t','S','I','P','R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g', 0}; SIP_ADD_NEWPROVIDER NewProv; BOOL Ret; /* Clear and initialize the structure */ memset(&NewProv, 0, sizeof(SIP_ADD_NEWPROVIDER)); NewProv.cbStruct = sizeof(SIP_ADD_NEWPROVIDER); NewProv.pwszDLLFileName = WINTRUST_Alloc(sizeof(SP_POLICY_PROVIDER_DLL_NAME)); /* Fill the structure */ NewProv.pgSubject = Subject; lstrcpyW(NewProv.pwszDLLFileName, SP_POLICY_PROVIDER_DLL_NAME); NewProv.pwszMagicNumber = MagicNumber; NewProv.pwszIsFunctionName = NULL; NewProv.pwszGetFuncName = CryptSIPGetSignedDataMsg; NewProv.pwszPutFuncName = CryptSIPPutSignedDataMsg; NewProv.pwszCreateFuncName = CryptSIPCreateIndirectData; NewProv.pwszVerifyFuncName = CryptSIPVerifyIndirectData; NewProv.pwszRemoveFuncName = CryptSIPRemoveSignedDataMsg; NewProv.pwszIsFunctionNameFmt2 = NULL; NewProv.pwszGetCapFuncName = NULL; Ret = CryptSIPAddProvider(&NewProv); WINTRUST_Free(NewProv.pwszDLLFileName); return Ret; }
/*********************************************************************** * WintrustAddDefaultForUsage (WINTRUST.@) * * Write OID and callback functions to the registry. * * PARAMS * pszUsageOID [I] Pointer to a GUID. * psDefUsage [I] Pointer to a structure that specifies the callback functions. * * RETURNS * Success: TRUE. * Failure: FALSE. * * NOTES * WintrustAddDefaultForUsage will only return TRUE or FALSE, no last * error is set, not even when the registry cannot be written to. */ BOOL WINAPI WintrustAddDefaultForUsage(const char *pszUsageOID, CRYPT_PROVIDER_REGDEFUSAGE *psDefUsage) { static const WCHAR CBAlloc[] = {'C','a','l','l','b','a','c','k','A','l','l','o','c','F','u','n','c','t','i','o','n', 0}; static const WCHAR CBFree[] = {'C','a','l','l','b','a','c','k','F','r','e','e','F','u','n','c','t','i','o','n', 0}; LONG Res = ERROR_SUCCESS; LONG WriteUsageError = ERROR_SUCCESS; DWORD Len; WCHAR GuidString[39]; TRACE("(%s %p)\n", debugstr_a(pszUsageOID), psDefUsage); /* Some sanity checks. */ if (!pszUsageOID || !psDefUsage || !psDefUsage->pgActionID || (psDefUsage->cbStruct != sizeof(CRYPT_PROVIDER_REGDEFUSAGE))) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (psDefUsage->pwszDllName) { Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, Dll, psDefUsage->pwszDllName); if (Res != ERROR_SUCCESS) WriteUsageError = Res; } if (psDefUsage->pwszLoadCallbackDataFunctionName) { WCHAR* CallbackW; Len = MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszLoadCallbackDataFunctionName, -1, NULL, 0 ); CallbackW = WINTRUST_Alloc( Len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszLoadCallbackDataFunctionName, -1, CallbackW, Len ); Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, CBAlloc, CallbackW); if (Res != ERROR_SUCCESS) WriteUsageError = Res; WINTRUST_Free(CallbackW); } if (psDefUsage->pwszFreeCallbackDataFunctionName) { WCHAR* CallbackW; Len = MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszFreeCallbackDataFunctionName, -1, NULL, 0 ); CallbackW = WINTRUST_Alloc( Len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszFreeCallbackDataFunctionName, -1, CallbackW, Len ); Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, CBFree, CallbackW); if (Res != ERROR_SUCCESS) WriteUsageError = Res; WINTRUST_Free(CallbackW); } WINTRUST_Guid2Wstr(psDefUsage->pgActionID, GuidString); Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, DefaultId, GuidString); if (Res != ERROR_SUCCESS) WriteUsageError = Res; if (WriteUsageError != ERROR_SUCCESS) return FALSE; return TRUE; }