|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: gettrst.cpp
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
#include "wintrustp.h"
#include "crypthlp.h"
extern HINSTANCE HinstDll; extern HMODULE HmodRichEdit;
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static BOOL IsUntrustedRootProblem(WINTRUST_DATA *pWTD) { CRYPT_PROVIDER_DATA *pProvData = NULL; CRYPT_PROVIDER_SGNR *pProvSigner = NULL; CRYPT_PROVIDER_CERT *pCryptProviderCert; DWORD i; pProvData = WTHelperProvDataFromStateData(pWTD->hWVTStateData); pProvSigner = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0); if (pProvSigner) { // get all certs in the chain
for (i=0; i<pProvSigner->csCertChain; i++) { pCryptProviderCert = WTHelperGetProvCertFromChain(pProvSigner, i); if (pCryptProviderCert != NULL) { if (pCryptProviderCert->dwError != ERROR_SUCCESS) { return FALSE; } } else { return FALSE; } } } else { return FALSE; }
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static DWORD GetFinalErrorFromChain(PCERT_VIEW_HELPER pviewhelp) { int i; DWORD dwErr = 0;
for (i=((int)pviewhelp->cpCryptProviderCerts)-1; i>= 0; i--) { dwErr = pviewhelp->rgpCryptProviderCerts[i]->dwError; if (((dwErr == CERT_E_UNTRUSTEDROOT) || (dwErr == CERT_E_UNTRUSTEDTESTROOT)) && (pviewhelp->fIgnoreUntrustedRoot)) { dwErr = 0; } else if (dwErr != 0) { break; } }
return dwErr; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void GetCertChainErrorString(PCERT_VIEW_HELPER pviewhelp) { WCHAR szErrorString[CRYPTUI_MAX_STRING_SIZE]; DWORD i; DWORD dwChainError; //
// free the error string if one already exists
//
if (pviewhelp->pwszErrorString != NULL) { free(pviewhelp->pwszErrorString); pviewhelp->pwszErrorString = NULL; }
// If they ask to be warned about local/remote differences,
// always display this warning
if (pviewhelp->fWarnRemoteTrust) { LoadStringU(HinstDll, IDS_WARNREMOTETRUST_ERROR, szErrorString, ARRAYSIZE(szErrorString)); goto StringLoaded; } //
// if there was no over all chain error, then the only problem,
// is if there are no usages
//
if (pviewhelp->dwChainError == 0) { if (pviewhelp->cUsages == NULL) { LoadStringU(HinstDll, IDS_NOVALIDUSAGES_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else { return; } }
if ((pviewhelp->dwChainError == CERT_E_UNTRUSTEDROOT) || (pviewhelp->dwChainError == CERT_E_UNTRUSTEDTESTROOT)) { //
// if we are ignoring untrusted roots, then just return
//
if (pviewhelp->fIgnoreUntrustedRoot) { return; }
//
// if we are just warning the user about untrusted root AND the root
// cert is in the remote root store then load that string
//
if (pviewhelp->fWarnUntrustedRoot && pviewhelp->fRootInRemoteStore) { //
// if this is a root cert then show the error for a root
//
if (pviewhelp->cpCryptProviderCerts == 1 && (pviewhelp->rgpCryptProviderCerts[0])->fSelfSigned) { LoadStringU(HinstDll, IDS_WARNUNTRUSTEDROOT_ERROR_ROOTCERT, szErrorString, ARRAYSIZE(szErrorString)); } else { LoadStringU(HinstDll, IDS_WARNUNTRUSTEDROOT_ERROR, szErrorString, ARRAYSIZE(szErrorString)); } } else { //
// if this is a root cert then show the error for a root
//
if (pviewhelp->cpCryptProviderCerts == 1 && (pviewhelp->rgpCryptProviderCerts[0])->fSelfSigned) { LoadStringU(HinstDll, IDS_UNTRUSTEDROOT_ROOTCERT_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else { LoadStringU(HinstDll, IDS_UNTRUSTEDROOT_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } } } else if (pviewhelp->dwChainError == CERT_E_REVOKED) { LoadStringU(HinstDll, IDS_CERTREVOKED_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == TRUST_E_CERT_SIGNATURE) { LoadStringU(HinstDll, IDS_CERTBADSIGNATURE_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_EXPIRED) { LoadStringU(HinstDll, IDS_CERTEXPIRED_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_VALIDITYPERIODNESTING) { LoadStringU(HinstDll, IDS_TIMENESTING_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_WRONG_USAGE) { LoadStringU(HinstDll, IDS_WRONG_USAGE_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == TRUST_E_BASIC_CONSTRAINTS) { LoadStringU(HinstDll, IDS_BASIC_CONSTRAINTS_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_PURPOSE) { LoadStringU(HinstDll, IDS_PURPOSE_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_REVOCATION_FAILURE) { LoadStringU(HinstDll, IDS_REVOCATION_FAILURE_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == CERT_E_CHAINING) { LoadStringU(HinstDll, IDS_CANTBUILDCHAIN_ERROR_TREE, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError == TRUST_E_EXPLICIT_DISTRUST) { LoadStringU(HinstDll, IDS_EXPLICITDISTRUST_ERROR, szErrorString, ARRAYSIZE(szErrorString)); } else if (pviewhelp->dwChainError != 0) { //
// this is not an error we know about, so call the general
// error string function
//
GetUnknownErrorString(&(pviewhelp->pwszErrorString), pviewhelp->dwChainError); }
StringLoaded: if (pviewhelp->pwszErrorString == NULL) { pviewhelp->pwszErrorString = AllocAndCopyWStr(szErrorString); } }
// Returned string must be freed via LocalFree()
LPWSTR FormatRevocationStatus( IN PCERT_CHAIN_ELEMENT pElement ) { LPWSTR pwszRevStatus = NULL; UINT ids = IDS_REV_STATUS_UNKNOWN_ERROR; static const WCHAR wszNoTime[] = L"..."; LPWSTR pwszArg1 = (LPWSTR) wszNoTime; LPWSTR pwszArg2 = (LPWSTR) wszNoTime; LPWSTR pwszTime1 = NULL; LPWSTR pwszTime2 = NULL; LPWSTR pwszErrStr = NULL; DWORD dwRevResult; PCERT_REVOCATION_INFO pRevInfo; PCERT_REVOCATION_CRL_INFO pCrlInfo;
pRevInfo = pElement->pRevocationInfo; if (NULL == pRevInfo) return NULL;
dwRevResult = pRevInfo->dwRevocationResult; pCrlInfo = pRevInfo->pCrlInfo;
switch (dwRevResult) { case ERROR_SUCCESS: ids = IDS_REV_STATUS_OK; // Fall through
case CRYPT_E_REVOCATION_OFFLINE: if (pCrlInfo) { PCCRL_CONTEXT pCrl;
pCrl = pCrlInfo->pDeltaCrlContext; if (NULL == pCrl) pCrl = pCrlInfo->pBaseCrlContext; if (pCrl) { BOOL fFormatDate;
fFormatDate = FormatDateString( &pwszTime1, pCrl->pCrlInfo->ThisUpdate, TRUE, // fIncludeTime
TRUE, // fLongFormat
NULL // hwnd
); if (fFormatDate) { pwszArg1 = pwszTime1;
if (I_CryptIsZeroFileTime(&pCrl->pCrlInfo->NextUpdate)) pwszArg2 = (LPWSTR) wszNoTime; else { fFormatDate = FormatDateString( &pwszTime2, pCrl->pCrlInfo->NextUpdate, TRUE, // fIncludeTime
TRUE, // fLongFormat
NULL // hwnd
); if (fFormatDate) pwszArg2 = pwszTime2; } }
if (fFormatDate) { switch (dwRevResult) { case ERROR_SUCCESS: ids = IDS_REV_STATUS_OK_WITH_CRL; break; case CRYPT_E_REVOCATION_OFFLINE: ids = IDS_REV_STATUS_OFFLINE_WITH_CRL; break; } } } } break;
case CRYPT_E_REVOKED: if (pCrlInfo && pCrlInfo->pCrlEntry) { if (FormatDateString( &pwszTime1, pCrlInfo->pCrlEntry->RevocationDate, TRUE, // fIncludeTime
TRUE, // fLongFormat
NULL // hwnd
)) { ids = IDS_REV_STATUS_REVOKED_ON; pwszArg1 = pwszTime1; } } break;
default: break; }
if (IDS_REV_STATUS_UNKNOWN_ERROR == ids) { GetUnknownErrorString(&pwszErrStr, dwRevResult); if (NULL == pwszErrStr) goto CommonReturn; pwszArg1 = pwszErrStr; }
pwszRevStatus = FormatMessageUnicodeIds(ids, pwszArg1, pwszArg2); CommonReturn: if (pwszTime1) free(pwszTime1); if (pwszTime2) free(pwszTime2); if (pwszErrStr) free(pwszErrStr);
return pwszRevStatus; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL BuildChain( PCERT_VIEW_HELPER pviewhelp, LPSTR pszUsage) { CRYPT_PROVIDER_DATA const * pProvData = NULL; CRYPT_PROVIDER_SGNR * pProvSigner = NULL; DWORD i; GUID defaultProviderGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY; HRESULT hr = ERROR_SUCCESS; BOOL fInternalError = FALSE; DWORD dwStartIndex; BOOL fRet = TRUE; PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pcvp = pviewhelp->pcvp; WCHAR szErrorString[CRYPTUI_MAX_STRING_SIZE];
//
// if there was previous chain state then free that before building
// the new chain
//
if (pviewhelp->fFreeWTD) { pviewhelp->sWTD.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrustEx(NULL, &defaultProviderGUID, &(pviewhelp->sWTD)); }
pviewhelp->cpCryptProviderCerts = 0; pviewhelp->fFreeWTD = FALSE;
//
// initialize structs that are used with WinVerifyTrust()
//
memset(&(pviewhelp->sWTD), 0x00, sizeof(WINTRUST_DATA)); pviewhelp->sWTD.cbStruct = sizeof(WINTRUST_DATA); pviewhelp->sWTD.dwUIChoice = WTD_UI_NONE; pviewhelp->sWTD.dwUnionChoice = WTD_CHOICE_CERT; pviewhelp->sWTD.pCert = &(pviewhelp->sWTCI); pviewhelp->sWTD.dwProvFlags = (pszUsage == NULL) ? WTD_NO_POLICY_USAGE_FLAG : 0; if (pcvp->dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT) { pviewhelp->sWTD.dwProvFlags |= WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; } else if (pcvp->dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_END_CERT) { pviewhelp->sWTD.dwProvFlags |= WTD_REVOCATION_CHECK_END_CERT; } else if (pcvp->dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN) { pviewhelp->sWTD.dwProvFlags |= WTD_REVOCATION_CHECK_CHAIN; } else { pviewhelp->sWTD.dwProvFlags |= WTD_REVOCATION_CHECK_NONE; }
memset(&(pviewhelp->sWTCI), 0x00, sizeof(WINTRUST_CERT_INFO)); pviewhelp->sWTCI.cbStruct = sizeof(WINTRUST_CERT_INFO); pviewhelp->sWTCI.pcwszDisplayName = L"CryptUI"; pviewhelp->sWTCI.psCertContext = (CERT_CONTEXT *)pcvp->pCertContext; pviewhelp->sWTCI.chStores = pcvp->cStores; pviewhelp->sWTCI.pahStores = pcvp->rghStores; pviewhelp->sWTCI.dwFlags |= (pcvp->dwFlags & CRYPTUI_DONT_OPEN_STORES) ? WTCI_DONT_OPEN_STORES : 0; pviewhelp->sWTCI.dwFlags |= (pcvp->dwFlags & CRYPTUI_ONLY_OPEN_ROOT_STORE) ? WTCI_OPEN_ONLY_ROOT : 0;
//
// if a provider was passed in, then use it to build the chain,
// otherwise use the default provider to build the chain
//
if (pcvp->pCryptProviderData != NULL) { pProvData = pcvp->pCryptProviderData; } else { pviewhelp->sWTD.dwStateAction = WTD_STATEACTION_VERIFY; //
// the default default provider requires the policycallback data to point
// to the usage oid you are validating for, so set it to the usage passed in
//
pviewhelp->sWTD.pPolicyCallbackData = pszUsage; pviewhelp->sWTD.pSIPClientData = NULL; hr = WinVerifyTrustEx(NULL, &defaultProviderGUID, &(pviewhelp->sWTD));
pProvData = WTHelperProvDataFromStateData(pviewhelp->sWTD.hWVTStateData); if (WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA) pProvData, 0, FALSE, 0) != NULL) { pviewhelp->fFreeWTD = TRUE; fInternalError = FALSE; } else { pviewhelp->fFreeWTD = FALSE; pviewhelp->sWTD.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrustEx(NULL, &defaultProviderGUID, &(pviewhelp->sWTD)); fInternalError = TRUE; } }
if (pProvData && !fInternalError) { //
// set the chain error in the helper struct
//
pviewhelp->dwChainError = pProvData->dwFinalError; //
// This is to catch internal WinVerifyTrust errors
//
if ((pviewhelp->dwChainError == 0) && (FAILED(hr))) { pviewhelp->dwChainError = (DWORD) hr; }
//
// if the WinTrust state was passed into the certUI then use that for
// the chain, else, get it from the state that was just built
//
if (pcvp->pCryptProviderData != NULL) { pProvSigner = WTHelperGetProvSignerFromChain( (PCRYPT_PROVIDER_DATA) pProvData, pcvp->idxSigner, pcvp->fCounterSigner, pcvp->idxCounterSigner); dwStartIndex = pcvp->idxCert; } else { pProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA) pProvData, 0, FALSE, 0); dwStartIndex = 0; } if (pProvSigner) { //
// get all certs in the chain
//
for (i=dwStartIndex; i<pProvSigner->csCertChain && (i<dwStartIndex+MAX_CERT_CHAIN_LENGTH); i++) { pviewhelp->rgpCryptProviderCerts[pviewhelp->cpCryptProviderCerts] = WTHelperGetProvCertFromChain(pProvSigner, i); if (pviewhelp->rgpCryptProviderCerts[pviewhelp->cpCryptProviderCerts] != NULL) { // Note, only modify this property when creating the
// chain for the original end cert. Subsequent CA
// chains won't have the ExtendedErrorInfo.
if ((pcvp->dwFlags & CRYPTUI_TREEVIEW_PAGE_FLAG) == 0) { // Either delete or set the
// CERT_EXTENDED_ERROR_INFO_PROP_ID
// This is used in cvdetail.cpp when displaying
// property details
PCRYPT_PROVIDER_CERT pProvCert = pviewhelp->rgpCryptProviderCerts[ pviewhelp->cpCryptProviderCerts];
LPWSTR pwszExtErrorInfo = NULL; // not allocated
LPWSTR pwszRevStatus = NULL; // LocalAlloc()'ed
if (pProvCert->cbStruct > offsetof(CRYPT_PROVIDER_CERT, pChainElement) && NULL != pProvCert->pChainElement) { pwszExtErrorInfo = (LPWSTR) pProvCert->pChainElement->pwszExtendedErrorInfo; pwszRevStatus = FormatRevocationStatus( pProvCert->pChainElement);
if (NULL == pwszExtErrorInfo) { pwszExtErrorInfo = pwszRevStatus; } else if (pwszRevStatus) { LPWSTR pwszReAlloc; DWORD cchRevStatus; DWORD cchExtErrorInfo;
cchRevStatus = wcslen(pwszRevStatus); cchExtErrorInfo = wcslen(pwszExtErrorInfo); pwszReAlloc = (LPWSTR) LocalReAlloc( pwszRevStatus, (cchRevStatus + cchExtErrorInfo + 1) * sizeof(WCHAR), LMEM_MOVEABLE); if (pwszReAlloc) { memcpy(&pwszReAlloc[cchRevStatus], pwszExtErrorInfo, (cchExtErrorInfo + 1) * sizeof(WCHAR)); pwszExtErrorInfo = pwszRevStatus = pwszReAlloc; } } } if (pwszExtErrorInfo) { CRYPT_DATA_BLOB ExtErrorInfoBlob;
ExtErrorInfoBlob.pbData = (BYTE *) pwszExtErrorInfo; ExtErrorInfoBlob.cbData = (wcslen(pwszExtErrorInfo) + 1) * sizeof(WCHAR);
CertSetCertificateContextProperty( pProvCert->pCert, CERT_EXTENDED_ERROR_INFO_PROP_ID, CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, &ExtErrorInfoBlob ); } else { CertSetCertificateContextProperty( pProvCert->pCert, CERT_EXTENDED_ERROR_INFO_PROP_ID, CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, NULL // pvData, NULL implies delete
); }
if (pwszRevStatus) LocalFree(pwszRevStatus); }
pviewhelp->cpCryptProviderCerts++; } } } } CalculateUsages(pviewhelp);
//
// if the cert we are looking at is not the leaf cert, then we can't just take the
// dwFinalError as the overall chain error, so find the over all chain error by
// walking the chain and looking at the errors
//
if ((pcvp->pCryptProviderData != NULL) && (pcvp->idxCert != 0)) { pviewhelp->dwChainError = GetFinalErrorFromChain(pviewhelp); }
//
// if we are in the fWarnUntrustedRoot then check to see if the root cert is in the
// remote machine's root store
//
if (pviewhelp->fWarnUntrustedRoot) { PCCERT_CONTEXT pCertContext = NULL; CRYPT_HASH_BLOB cryptHashBlob; BYTE hash[20]; DWORD cb = 20;
pviewhelp->fRootInRemoteStore = FALSE;
cryptHashBlob.cbData = 20; cryptHashBlob.pbData = &(hash[0]);
if (CertGetCertificateContextProperty( pviewhelp->rgpCryptProviderCerts[pviewhelp->cpCryptProviderCerts-1]->pCert, CERT_SHA1_HASH_PROP_ID, &(hash[0]), &cb)) {
pCertContext = CertFindCertificateInStore( pviewhelp->pcvp->rghStores[0], X509_ASN_ENCODING || PKCS_7_ASN_ENCODING, 0, CERT_FIND_SHA1_HASH, &cryptHashBlob, NULL);
if (pCertContext != NULL) { CertFreeCertificateContext(pCertContext); pviewhelp->fRootInRemoteStore = TRUE; } } }
//
// get the error string for the whole cert chain
//
if (!fInternalError) { GetCertChainErrorString(pviewhelp); } else { LoadStringU(HinstDll, IDS_INTERNAL_ERROR, szErrorString, ARRAYSIZE(szErrorString)); pviewhelp->pwszErrorString = AllocAndCopyWStr(szErrorString); }
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL CalculateUsages(PCERT_VIEW_HELPER pviewhelp) { DWORD cLocalArrayOfUsages = 0; LPSTR * localArrayOfUsages = NULL; BOOL fLocalUsagesAllocated = FALSE; DWORD i; HRESULT hr; BOOL fRet = TRUE; PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pcvp = pviewhelp->pcvp; void *pTemp;
//
// if there are already usages, then clean them up before recalculating them,
// or just return if state was passed into CertUI
//
if (pviewhelp->cUsages != 0) { //
// state was passed into the CertUI, so just return
//
if (pcvp->pCryptProviderData != NULL) { return TRUE; }
//
// cleanup usages that were generated prior to this call
//
for (i=0; i<pviewhelp->cUsages; i++) { free(pviewhelp->rgUsages[i]); }
free(pviewhelp->rgUsages); }
//
// initialize usage variables
//
pviewhelp->cUsages = 0; pviewhelp->rgUsages = NULL; //
// if a provider was passed in, then we just look at it for the usage and structure
// passed in for the trust of that usage,
// otherwise we need to look at each usage and validate trust for all of them
//
if (pcvp->pCryptProviderData != NULL) { //
// allocate an array of 1 LPSTR
//
if (NULL == (pviewhelp->rgUsages = (LPSTR *) malloc(sizeof(LPSTR)))) { SetLastError(E_OUTOFMEMORY); return FALSE; }
//
// copy either the 1 purpose that was passed in, or the purpose out of WinTrust state
//
if (pcvp->cPurposes == 1) { if (NULL == (pviewhelp->rgUsages[0] = (LPSTR) malloc(strlen(pcvp->rgszPurposes[0])+1))) { SetLastError(E_OUTOFMEMORY); return FALSE; } strcpy(pviewhelp->rgUsages[0], pcvp->rgszPurposes[0]); } else { if (NULL == (pviewhelp->rgUsages[0] = (LPSTR) malloc(strlen(pcvp->pCryptProviderData->pszUsageOID)+1))) { SetLastError(E_OUTOFMEMORY); return FALSE; } strcpy(pviewhelp->rgUsages[0], pcvp->pCryptProviderData->pszUsageOID); }
pviewhelp->cUsages = 1; } else { //
// check to see if usages where passed in, if so, then intersect those with
// available usages in the cert, otherwise, get the available usages in the cert
// and use them as is
//
if (pcvp->cPurposes != 0) { //
// get the array of possible usages for the cert chain
//
// DSIE: Switch over to using pChainElement from philh's new chain building code.
AllocAndReturnKeyUsageList(pviewhelp->rgpCryptProviderCerts[0], &localArrayOfUsages, &cLocalArrayOfUsages);
if (cLocalArrayOfUsages != 0) fLocalUsagesAllocated = TRUE;
//
// for each usage that was passed in check to see if it is in the list of possible usages
//
for (i=0; i<pcvp->cPurposes; i++) { if (OIDinArray(pcvp->rgszPurposes[i], localArrayOfUsages, cLocalArrayOfUsages)) { //
// if an array hasn't yet been allocated, then allocate space for an array of
// 1 LPSTR, otherwise use realloc to add one more element
//
if (pviewhelp->rgUsages == NULL) { pviewhelp->rgUsages = (LPSTR *) malloc(sizeof(LPSTR)); } else { pTemp = realloc(pviewhelp->rgUsages, sizeof(LPSTR) * (pviewhelp->cUsages+1)); if (pTemp == NULL) { free(pviewhelp->rgUsages); pviewhelp->rgUsages = NULL; } else { pviewhelp->rgUsages = (LPSTR *) pTemp; } }
if (pviewhelp->rgUsages == NULL) { goto ErrorCleanUp; }
//
// allocate space for the usage string, then copy it, and increment number of usages
//
if (NULL == (pviewhelp->rgUsages[pviewhelp->cUsages] = (LPSTR) malloc(strlen(pcvp->rgszPurposes[i])+1))) { SetLastError(E_OUTOFMEMORY); goto ErrorCleanUp; } strcpy(pviewhelp->rgUsages[pviewhelp->cUsages], pcvp->rgszPurposes[i]); pviewhelp->cUsages++; } } } else { AllocAndReturnKeyUsageList(pviewhelp->rgpCryptProviderCerts[0], &(pviewhelp->rgUsages), &(pviewhelp->cUsages)); } }
CleanUp:
if (fLocalUsagesAllocated) { i = 0; while ((i < cLocalArrayOfUsages) && (localArrayOfUsages[i] != NULL)) { free(localArrayOfUsages[i]); i++; }
free(localArrayOfUsages); }
return fRet;
ErrorCleanUp:
if (pviewhelp->rgUsages != NULL) { i = 0; while ((i < pviewhelp->cUsages) && (pviewhelp->rgUsages[i] != NULL)) { free(pviewhelp->rgUsages[i]); i++; }
free(pviewhelp->rgUsages); }
fRet = FALSE; goto CleanUp; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL BuildWinVTrustState( LPCWSTR szFileName, CMSG_SIGNER_INFO const *pSignerInfo, DWORD cStores, HCERTSTORE *rghStores, LPCSTR pszOID, PCERT_VIEWSIGNERINFO_PRIVATE pcvsiPrivate, CRYPT_PROVIDER_DEFUSAGE *pCryptProviderDefUsage, WINTRUST_DATA *pWTD) { WINTRUST_FILE_INFO WTFI; WINTRUST_SGNR_INFO WTSI; HRESULT hr; GUID defaultProviderGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
//
// initialize structs that are used locally with WinVerifyTrust()
//
memset(pWTD, 0x00, sizeof(WINTRUST_DATA)); pWTD->cbStruct = sizeof(WINTRUST_DATA); pWTD->dwUIChoice = WTD_UI_NONE;
//
// if the szFileName parameter is non NULL then this for a file,
// otherwise it is for a signer info
//
if (szFileName != NULL) { pWTD->dwUnionChoice = WTD_CHOICE_FILE; pWTD->pFile = &WTFI; pWTD->pPolicyCallbackData = (void *) pszOID;
memset(&WTFI, 0x00, sizeof(WINTRUST_FILE_INFO)); WTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); WTFI.pcwszFilePath = szFileName; } else { pWTD->dwUnionChoice = WTD_CHOICE_SIGNER; pWTD->pSgnr = &WTSI; pWTD->pPolicyCallbackData = (void *) pszOID; memset(&WTSI, 0x00, sizeof(WINTRUST_SGNR_INFO)); WTSI.cbStruct = sizeof(WINTRUST_SGNR_INFO); WTSI.pcwszDisplayName = L"CryptUI"; WTSI.psSignerInfo = (CMSG_SIGNER_INFO *) pSignerInfo; WTSI.chStores = cStores; WTSI.pahStores = rghStores; //WTSI.pszOID = pszOID;
} pWTD->pSIPClientData = NULL; pWTD->dwStateAction = WTD_STATEACTION_VERIFY; hr = WinVerifyTrustEx(NULL, &defaultProviderGUID, pWTD); if (hr == ERROR_SUCCESS) { pcvsiPrivate->fpCryptProviderDataTrustedUsage = TRUE; } else { pcvsiPrivate->fpCryptProviderDataTrustedUsage = FALSE; } pcvsiPrivate->pCryptProviderData = WTHelperProvDataFromStateData(pWTD->hWVTStateData);
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL FreeWinVTrustState( LPCWSTR szFileName, CMSG_SIGNER_INFO const *pSignerInfo, DWORD cStores, HCERTSTORE *rghStores, LPCSTR pszOID, CRYPT_PROVIDER_DEFUSAGE *pCryptProviderDefUsage, WINTRUST_DATA *pWTD)//,
//BOOL *pfUseDefaultProvider)
{ WINTRUST_FILE_INFO WTFI; WINTRUST_SGNR_INFO WTSI; HRESULT hr; GUID defaultProviderGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
// initialize structs that are used locally with WinVerifyTrust()
memset(pWTD, 0x00, sizeof(WINTRUST_DATA)); pWTD->cbStruct = sizeof(WINTRUST_DATA); pWTD->dwUIChoice = WTD_UI_NONE; //
// if the szFileName parameter is non NULL then this for a file,
// otherwise it is for a signer info
//
if (szFileName != NULL) { pWTD->dwUnionChoice = WTD_CHOICE_FILE; pWTD->pFile = &WTFI;
memset(&WTFI, 0x00, sizeof(WINTRUST_FILE_INFO)); WTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); WTFI.pcwszFilePath = szFileName; } else { pWTD->dwUnionChoice = WTD_CHOICE_SIGNER; pWTD->pSgnr = &WTSI;
memset(&WTSI, 0x00, sizeof(WINTRUST_SGNR_INFO)); WTSI.cbStruct = sizeof(WINTRUST_SGNR_INFO); WTSI.psSignerInfo = (CMSG_SIGNER_INFO *) pSignerInfo; WTSI.chStores = cStores; WTSI.pahStores = rghStores; }
/*if (*pfUseDefaultProvider)
{ pWTD->dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrustEx(NULL, &defaultProviderGUID, pWTD); } else {*/ pWTD->dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrustEx(NULL, &(pCryptProviderDefUsage->gActionID), pWTD); WintrustGetDefaultForUsage(DWACTION_FREE, pszOID, pCryptProviderDefUsage); //}
return TRUE; }
|