BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data, BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr) { BOOL ret = FALSE; TRACE("(%p, %d, %d, %p)\n", data, fCounterSigner, idxSigner, sgnr); if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (fCounterSigner) { FIXME("unimplemented for counter signers\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (data->csSigners) data->pasSigners = WINTRUST_ReAlloc(data->pasSigners, (data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR)); else { data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR)); data->csSigners = 0; } if (data->pasSigners) { if (idxSigner < data->csSigners) memmove(&data->pasSigners[idxSigner], &data->pasSigners[idxSigner + 1], (data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR)); ret = TRUE; if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR)) { /* The PSDK says psSigner should be allocated using pfnAlloc, but * it doesn't say anything about ownership. Since callers are * internal, assume ownership is passed, and just store the * pointer. */ memcpy(&data->pasSigners[idxSigner], sgnr, sizeof(CRYPT_PROVIDER_SGNR)); } else memset(&data->pasSigners[idxSigner], 0, sizeof(CRYPT_PROVIDER_SGNR)); data->csSigners++; } else SetLastError(ERROR_OUTOFMEMORY); return ret; }
/*********************************************************************** * 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; }
BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner, BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add) { BOOL ret = FALSE; TRACE("(%p, %d, %d, %d, %p)\n", data, idxSigner, fCounterSigner, idxSigner, pCert2Add); if (fCounterSigner) { FIXME("unimplemented for counter signers\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (data->pasSigners[idxSigner].csCertChain) data->pasSigners[idxSigner].pasCertChain = WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain, (data->pasSigners[idxSigner].csCertChain + 1) * sizeof(CRYPT_PROVIDER_CERT)); else { data->pasSigners[idxSigner].pasCertChain = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT)); data->pasSigners[idxSigner].csCertChain = 0; } if (data->pasSigners[idxSigner].pasCertChain) { CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[ data->pasSigners[idxSigner].csCertChain]; cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT); cert->pCert = CertDuplicateCertificateContext(pCert2Add); data->pasSigners[idxSigner].csCertChain++; ret = TRUE; } else SetLastError(ERROR_OUTOFMEMORY); return ret; }
/*********************************************************************** * 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; }
BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store) { BOOL ret = FALSE; TRACE("(%p, %p)\n", data, store); if (data->chStores) data->pahStores = WINTRUST_ReAlloc(data->pahStores, (data->chStores + 1) * sizeof(HCERTSTORE)); else { data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE)); data->chStores = 0; } if (data->pahStores) { data->pahStores[data->chStores++] = CertDuplicateStore(store); ret = TRUE; } else SetLastError(ERROR_OUTOFMEMORY); return ret; }
BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data, CRYPT_PROVIDER_PRIVDATA *pPrivData2Add) { BOOL ret = FALSE; TRACE("(%p, %p)\n", data, pPrivData2Add); if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA)) { SetLastError(ERROR_INVALID_PARAMETER); WARN("invalid struct size\n"); return FALSE; } if (data->csProvPrivData) data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData, (data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR)); else { data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR)); data->csProvPrivData = 0; } if (data->pasProvPrivData) { DWORD i; for (i = 0; i < data->csProvPrivData; i++) if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i])) break; data->pasProvPrivData[i] = *pPrivData2Add; if (i == data->csProvPrivData) data->csProvPrivData++; } else SetLastError(ERROR_OUTOFMEMORY); return ret; }
static BOOL WINAPI WINTRUST_enumUsages(PCCRYPT_OID_INFO pInfo, void *pvArg) { PCCRYPT_OID_INFO **usages = pvArg; DWORD cUsages; BOOL ret; if (!*usages) { cUsages = 0; *usages = WINTRUST_Alloc(2 * sizeof(PCCRYPT_OID_INFO)); } else { PCCRYPT_OID_INFO *ptr; /* Count the existing usages. * FIXME: make sure the new usage doesn't duplicate any in the list? */ for (cUsages = 0, ptr = *usages; *ptr; ptr++, cUsages++) ; *usages = WINTRUST_ReAlloc(*usages, (cUsages + 2) * sizeof(PCCRYPT_OID_INFO)); } if (*usages) { (*usages)[cUsages] = pInfo; (*usages)[cUsages + 1] = NULL; ret = TRUE; } else { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; } 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; }