//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: gettrst.cpp // //-------------------------------------------------------------------------- #include "global.hxx" #include #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; icsCertChain; 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; icsCertChain && (irgpCryptProviderCerts[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; icUsages; 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; icPurposes; 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; }