//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1995 - 1997 // // File: ttrust.cpp // // Contents: WinVerifyTrust Chain Tests // // See Usage() for a list of test options. // // // Functions: main // // History: 06-Feb-98 philh created //-------------------------------------------------------------------------- #define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS 1 #include #include #include "wincrypt.h" #include "wintrust.h" #include "wintrustp.h" #include "softpub.h" #include "certtest.h" #include "crypthlp.h" #include "unicode.h" #include "wininet.h" #ifndef SECURITY_FLAG_IGNORE_REVOCATION # define SECURITY_FLAG_IGNORE_REVOCATION 0x00000080 # define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100 #endif #ifndef SECURITY_FLAG_IGNORE_WRONG_USAGE # define SECURITY_FLAG_IGNORE_WRONG_USAGE 0x00000200 #endif #include #include #include #include #include #include BOOL fFlushCrl = FALSE; extern BOOL WINAPI ChainWlxLogoffEvent (PWLX_NOTIFICATION_INFO pNotificationInfo); static void PrintStatus( IN LPCSTR pszMsg, IN LONG lStatus ) { printf("%s", pszMsg); switch (lStatus) { case CRYPT_E_MSG_ERROR: printf("CRYPT_E_MSG_ERROR"); break; case CRYPT_E_UNKNOWN_ALGO: printf("CRYPT_E_UNKNOWN_ALGO"); break; case CRYPT_E_OID_FORMAT: printf("CRYPT_E_OID_FORMAT"); break; case CRYPT_E_INVALID_MSG_TYPE: printf("CRYPT_E_INVALID_MSG_TYPE"); break; case CRYPT_E_UNEXPECTED_ENCODING: printf("CRYPT_E_UNEXPECTED_ENCODING"); break; case CRYPT_E_AUTH_ATTR_MISSING: printf("CRYPT_E_AUTH_ATTR_MISSING"); break; case CRYPT_E_HASH_VALUE: printf("CRYPT_E_HASH_VALUE"); break; case CRYPT_E_INVALID_INDEX: printf("CRYPT_E_INVALID_INDEX"); break; case CRYPT_E_ALREADY_DECRYPTED: printf("CRYPT_E_ALREADY_DECRYPTED"); break; case CRYPT_E_NOT_DECRYPTED: printf("CRYPT_E_NOT_DECRYPTED"); break; case CRYPT_E_RECIPIENT_NOT_FOUND: printf("CRYPT_E_RECIPIENT_NOT_FOUND"); break; case CRYPT_E_CONTROL_TYPE: printf("CRYPT_E_CONTROL_TYPE"); break; case CRYPT_E_ISSUER_SERIALNUMBER: printf("CRYPT_E_ISSUER_SERIALNUMBER"); break; case CRYPT_E_SIGNER_NOT_FOUND: printf("CRYPT_E_SIGNER_NOT_FOUND"); break; case CRYPT_E_ATTRIBUTES_MISSING: printf("CRYPT_E_ATTRIBUTES_MISSING"); break; case CRYPT_E_STREAM_MSG_NOT_READY: printf("CRYPT_E_STREAM_MSG_NOT_READY"); break; case CRYPT_E_STREAM_INSUFFICIENT_DATA: printf("CRYPT_E_STREAM_INSUFFICIENT_DATA"); break; case CRYPT_E_BAD_LEN: printf("CRYPT_E_BAD_LEN"); break; case CRYPT_E_BAD_ENCODE: printf("CRYPT_E_BAD_ENCODE"); break; case CRYPT_E_FILE_ERROR: printf("CRYPT_E_FILE_ERROR"); break; case CRYPT_E_NOT_FOUND: printf("CRYPT_E_NOT_FOUND"); break; case CRYPT_E_EXISTS: printf("CRYPT_E_EXISTS"); break; case CRYPT_E_NO_PROVIDER: printf("CRYPT_E_NO_PROVIDER"); break; case CRYPT_E_SELF_SIGNED: printf("CRYPT_E_SELF_SIGNED"); break; case CRYPT_E_DELETED_PREV: printf("CRYPT_E_DELETED_PREV"); break; case CRYPT_E_NO_MATCH: printf("CRYPT_E_NO_MATCH"); break; case CRYPT_E_UNEXPECTED_MSG_TYPE: printf("CRYPT_E_UNEXPECTED_MSG_TYPE"); break; case CRYPT_E_NO_KEY_PROPERTY: printf("CRYPT_E_NO_KEY_PROPERTY"); break; case CRYPT_E_NO_DECRYPT_CERT: printf("CRYPT_E_NO_DECRYPT_CERT"); break; case CRYPT_E_BAD_MSG: printf("CRYPT_E_BAD_MSG"); break; case CRYPT_E_NO_SIGNER: printf("CRYPT_E_NO_SIGNER"); break; case CRYPT_E_PENDING_CLOSE: printf("CRYPT_E_PENDING_CLOSE"); break; case CRYPT_E_REVOKED: printf("CRYPT_E_REVOKED"); break; case CRYPT_E_NO_REVOCATION_DLL: printf("CRYPT_E_NO_REVOCATION_DLL"); break; case CRYPT_E_NO_REVOCATION_CHECK: printf("CRYPT_E_NO_REVOCATION_CHECK"); break; case CRYPT_E_REVOCATION_OFFLINE: printf("CRYPT_E_REVOCATION_OFFLINE"); break; case CRYPT_E_NOT_IN_REVOCATION_DATABASE: printf("CRYPT_E_NOT_IN_REVOCATION_DATABASE"); break; case CRYPT_E_INVALID_NUMERIC_STRING: printf("CRYPT_E_INVALID_NUMERIC_STRING"); break; case CRYPT_E_INVALID_PRINTABLE_STRING: printf("CRYPT_E_INVALID_PRINTABLE_STRING"); break; case CRYPT_E_INVALID_IA5_STRING: printf("CRYPT_E_INVALID_IA5_STRING"); break; case CRYPT_E_INVALID_X500_STRING: printf("CRYPT_E_INVALID_X500_STRING"); break; case CRYPT_E_NOT_CHAR_STRING: printf("CRYPT_E_NOT_CHAR_STRING"); break; case CRYPT_E_FILERESIZED: printf("CRYPT_E_FILERESIZED"); break; case CRYPT_E_SECURITY_SETTINGS: printf("CRYPT_E_SECURITY_SETTINGS"); break; case CRYPT_E_NO_VERIFY_USAGE_DLL: printf("CRYPT_E_NO_VERIFY_USAGE_DLL"); break; case CRYPT_E_NO_VERIFY_USAGE_CHECK: printf("CRYPT_E_NO_VERIFY_USAGE_CHECK"); break; case CRYPT_E_VERIFY_USAGE_OFFLINE: printf("CRYPT_E_VERIFY_USAGE_OFFLINE"); break; case CRYPT_E_NOT_IN_CTL: printf("CRYPT_E_NOT_IN_CTL"); break; case CRYPT_E_NO_TRUSTED_SIGNER: printf("CRYPT_E_NO_TRUSTED_SIGNER"); break; case CERTSRV_E_BAD_REQUESTSUBJECT: printf("CERTSRV_E_BAD_REQUESTSUBJECT"); break; case CERTSRV_E_NO_REQUEST: printf("CERTSRV_E_NO_REQUEST"); break; case CERTSRV_E_BAD_REQUESTSTATUS: printf("CERTSRV_E_BAD_REQUESTSTATUS"); break; case CERTSRV_E_PROPERTY_EMPTY: printf("CERTSRV_E_PROPERTY_EMPTY"); break; case TRUST_E_SYSTEM_ERROR: printf("TRUST_E_SYSTEM_ERROR"); break; case TRUST_E_NO_SIGNER_CERT: printf("TRUST_E_NO_SIGNER_CERT"); break; case TRUST_E_COUNTER_SIGNER: printf("TRUST_E_COUNTER_SIGNER"); break; case TRUST_E_CERT_SIGNATURE: printf("TRUST_E_CERT_SIGNATURE"); break; case TRUST_E_TIME_STAMP: printf("TRUST_E_TIME_STAMP"); break; case TRUST_E_BAD_DIGEST: printf("TRUST_E_BAD_DIGEST"); break; case TRUST_E_BASIC_CONSTRAINTS: printf("TRUST_E_BASIC_CONSTRAINTS"); break; case TRUST_E_FINANCIAL_CRITERIA: printf("TRUST_E_FINANCIAL_CRITERIA"); break; case TRUST_E_PROVIDER_UNKNOWN: printf("TRUST_E_PROVIDER_UNKNOWN"); break; case TRUST_E_ACTION_UNKNOWN: printf("TRUST_E_ACTION_UNKNOWN"); break; case TRUST_E_SUBJECT_FORM_UNKNOWN: printf("TRUST_E_SUBJECT_FORM_UNKNOWN"); break; case TRUST_E_SUBJECT_NOT_TRUSTED: printf("TRUST_E_SUBJECT_NOT_TRUSTED"); break; case TRUST_E_EXPLICIT_DISTRUST: printf("TRUST_E_EXPLICIT_DISTRUST"); break; case DIGSIG_E_ENCODE: printf("DIGSIG_E_ENCODE"); break; case DIGSIG_E_DECODE: printf("DIGSIG_E_DECODE"); break; case DIGSIG_E_EXTENSIBILITY: printf("DIGSIG_E_EXTENSIBILITY"); break; case DIGSIG_E_CRYPTO: printf("DIGSIG_E_CRYPTO"); break; case PERSIST_E_SIZEDEFINITE: printf("PERSIST_E_SIZEDEFINITE"); break; case PERSIST_E_SIZEINDEFINITE: printf("PERSIST_E_SIZEINDEFINITE"); break; case PERSIST_E_NOTSELFSIZING: printf("PERSIST_E_NOTSELFSIZING"); break; case TRUST_E_NOSIGNATURE: printf("TRUST_E_NOSIGNATURE"); break; case CERT_E_EXPIRED: printf("CERT_E_EXPIRED"); break; case CERT_E_VALIDITYPERIODNESTING: printf("CERT_E_VALIDITYPERIODNESTING"); break; case CERT_E_ROLE: printf("CERT_E_ROLE"); break; case CERT_E_PATHLENCONST: printf("CERT_E_PATHLENCONST"); break; case CERT_E_CRITICAL: printf("CERT_E_CRITICAL"); break; case CERT_E_PURPOSE: printf("CERT_E_PURPOSE"); break; case CERT_E_ISSUERCHAINING: printf("CERT_E_ISSUERCHAINING"); break; case CERT_E_MALFORMED: printf("CERT_E_MALFORMED"); break; case CERT_E_UNTRUSTEDROOT: printf("CERT_E_UNTRUSTEDROOT"); break; case CERT_E_UNTRUSTEDCA: printf("CERT_E_UNTRUSTEDCA"); break; case CERT_E_CHAINING: printf("CERT_E_CHAINING"); break; case TRUST_E_FAIL: printf("TRUST_E_FAIL"); break; case CERT_E_REVOKED: printf("CERT_E_REVOKED"); break; case CERT_E_UNTRUSTEDTESTROOT: printf("CERT_E_UNTRUSTEDTESTROOT"); break; case CERT_E_REVOCATION_FAILURE: printf("CERT_E_REVOCATION_FAILURE"); break; case CERT_E_CN_NO_MATCH: printf("CERT_E_CN_NO_MATCH"); break; case CERT_E_WRONG_USAGE: printf("CERT_E_WRONG_USAGE"); break; default: break; } printf (" 0x%x (%d)\n", lStatus, lStatus); } static void PrintError( IN LPCSTR pszMsg, IN DWORD dwErr ) { PrintStatus(pszMsg, (LONG) dwErr); } static void Usage(void) { printf("Usage: ttrust [options] \n"); printf("Options are:\n"); printf(" -Cert - Default\n"); printf(" -File\n"); printf(" -Driver\n"); printf(" -Https\n"); printf(" -Chain\n"); printf(" -ChainCallback\n"); printf(" -NTAuth\n"); printf(" -NTAuthNameConstraint\n"); printf(" -Safer\n"); printf("\n"); printf(" -UseIE4Trust\n"); printf(" -NoIE4Chain\n"); printf(" -NoUsage\n"); printf(" -OrUsage\n"); printf(" -OrPolicy\n"); printf(" -LifetimeSigning\n"); printf(" -MicrosoftRoot\n"); printf(" -MicrosoftTestRoot\n"); printf(" -NotMicrosoftRoot\n"); printf(" -FlushCrl\n"); printf(" -DeferClosing\n"); printf("\n"); printf(" -DisplayKnownUsages\n"); printf(" -LogoffNotification\n"); printf("\n"); printf(" -UINone - Default\n"); printf(" -UIAll\n"); printf(" -UINoBad\n"); printf(" -UINoGood\n"); printf("\n"); printf(" -RevokeNone - Default\n"); printf(" -RevokeChain\n"); printf("\n"); printf(" -DontOpenStores\n"); printf(" -OpenOnlyRoot\n"); printf("\n"); printf(" -HttpsIgnoreRevocation\n"); printf(" -HttpsIgnoreUnknownCa\n"); printf(" -HttpsIgnoreWrongUsage\n"); printf(" -HttpsIgnoreCertDateInvalid\n"); printf(" -HttpsIgnoreCertCNInvalid\n"); printf("\n"); printf(" -Client - Default\n"); printf(" -Server\n"); printf("\n"); printf(" -InstallThreadDefaultContext\n"); printf(" -InstallProcessDefaultContext\n"); printf(" -AutoReleaseDefaultContext\n"); printf(" -NULLDefaultContext\n"); printf(" -MultiDefaultContext\n"); printf("\n"); printf(" -AuthenticodeFlags \n"); printf(" -DeleteSaferRegKey\n"); printf(" -EnableRootAutoUpdate\n"); printf(" -DisableRootAutoUpdate\n"); printf(" -EnableUntrustedRootLogging\n"); printf(" -DisableUntrustedRootLogging\n"); printf(" -EnablePartialChainLogging\n"); printf(" -DisablePartialChainLogging\n"); printf(" -EnableNTAuthRequired\n"); printf(" -DisableNTAuthRequired\n"); printf(" -EnableNotDefinedNameConstraint\n"); printf(" -DisableNotDefinedNameConstraint\n"); printf(" -EnableAuthRoot\n"); printf(" -DisableAuthRoot\n"); printf(" -RegistryOnlyExit\n"); printf("\n"); printf("Cert Chain Config Registry Values (0xFFFFFFFF deletes):\n"); printf(" -DisableMandatoryBasicConstraints \n"); printf(" -DisableAIAUrlRetrieval \n"); printf(" -MaxAIAUrlCountInCert \n"); printf(" -MaxAIAUrlRetrievalCountPerChain \n"); printf(" -MaxAIAUrlRetrievalByteCount \n"); printf(" -MaxAIAUrlRetrievalCertCount \n"); printf("\n"); printf(" -h - This message\n"); printf(" -b - Brief\n"); printf(" -v - Verbose\n"); printf(" -q[] - Quiet, expected error\n"); printf(" -e - Expected trust error status\n"); printf(" -i - Expected trust info status\n"); printf(" -u - Usage OID string -u1.3.6.1.5.5.7.3.3\n"); printf(" -p - Policy OID string -u1.3.6.1.5.5.7.3.3\n"); printf(" -s - Additional System Store\n"); printf(" -S - Additional File System Store\n"); printf(" -n - Https ServerName\n"); printf(" -f - Flags\n"); printf(" -t - Url timeout (milliseconds)\n"); printf(" -r - Revocation freshness (seconds)\n"); printf("\n"); } static PCCERT_CONTEXT ReadCert( IN LPSTR pszCert ) { BOOL fResult; BYTE *pbEncoded; DWORD cbEncoded; PCCERT_CONTEXT pCert; if (!ReadDERFromFile(pszCert, &pbEncoded, &cbEncoded)) { PrintLastError("ReadCert"); return NULL; } pCert = CertCreateCertificateContext( dwCertEncodingType, pbEncoded, cbEncoded ); if (pCert == NULL) PrintLastError("CertCreateCertificateContext"); TestFree(pbEncoded); return pCert; } static void DisplayPeterSigner( IN CRYPT_PROVIDER_SGNR *pProvSign, IN DWORD dwDisplayFlags ) { DWORD idxCert; printf("Verify Time: %s\n", FileTimeText(&pProvSign->sftVerifyAsOf)); if (pProvSign->dwSignerType) { printf("Signer Type: 0x%x", pProvSign->dwSignerType); if (pProvSign->dwSignerType == SGNR_TYPE_TIMESTAMP) printf(" TIMESTAMP"); printf("\n"); } if (pProvSign->dwError) PrintError("Error: ", pProvSign->dwError); if (0 == pProvSign->csCertChain) { printf("No Certificates\n"); return; } for (idxCert = 0; idxCert < pProvSign->csCertChain; idxCert++) { CRYPT_PROVIDER_CERT *pProvCert; printf("----- Cert [%d] -----\n", idxCert); pProvCert = WTHelperGetProvCertFromChain(pProvSign, idxCert); if (pProvCert) { if (pProvCert->dwError) PrintError("Error: ", pProvCert->dwError); if (pProvCert->dwRevokedReason) PrintError("RevokedReason: ", pProvCert->dwRevokedReason); printf("Confidence:: 0x%x ", pProvCert->dwConfidence); if ((pProvCert->dwConfidence & CERT_CONFIDENCE_HIGHEST) == CERT_CONFIDENCE_HIGHEST) printf("Highest "); else { if (pProvCert->dwConfidence & CERT_CONFIDENCE_SIG) printf("Signature "); if (pProvCert->dwConfidence & CERT_CONFIDENCE_TIME) printf("Time "); if (pProvCert->dwConfidence & CERT_CONFIDENCE_TIMENEST) printf("TimeNest "); if (pProvCert->dwConfidence & CERT_CONFIDENCE_AUTHIDEXT) printf("AuthorityID "); if (pProvCert->dwConfidence & CERT_CONFIDENCE_HYGIENE) printf("Hygiene "); } printf("\n"); if (pProvCert->fTrustListSignerCert) printf("TrustListSignerCert "); if (pProvCert->fCommercial) printf("Commercial "); if (pProvCert->fTrustedRoot) printf("TrustedRoot "); if (pProvCert->fSelfSigned) printf("SelfSigned "); if (pProvCert->fTestCert) printf("TestCert "); printf("\n"); DisplayCert(pProvCert->pCert, dwDisplayFlags); if (pProvCert->pTrustListContext) { printf("----- Outlook CTL -----\n"); DisplayCtl( (PCCTL_CONTEXT) pProvCert->pTrustListContext, dwDisplayFlags ); } if (pProvCert->dwCtlError) PrintError("Ctl Error: ", pProvCert->dwCtlError); if (pProvCert->pCtlContext) { printf("----- CTL -----\n"); DisplayCtl(pProvCert->pCtlContext, dwDisplayFlags); } } } } //+--------------------------------------------------------------------------- // // Synopsis: Chain Display Functions // //---------------------------------------------------------------------------- LPSTR rgszErrorStatus[] = { "CERT_TRUST_IS_NOT_TIME_VALID", // 0x00000001 "CERT_TRUST_IS_NOT_TIME_NESTED", // 0x00000002 "CERT_TRUST_IS_REVOKED", // 0x00000004 "CERT_TRUST_IS_NOT_SIGNATURE_VALID", // 0x00000008 "CERT_TRUST_IS_NOT_VALID_FOR_USAGE", // 0x00000010 "CERT_TRUST_IS_UNTRUSTED_ROOT", // 0x00000020 "CERT_TRUST_REVOCATION_STATUS_UNKNOWN", // 0x00000040 "CERT_TRUST_IS_CYCLIC", // 0x00000080 "CERT_TRUST_INVALID_EXTENSION", // 0x00000100 "CERT_TRUST_INVALID_POLICY_CONSTRAINTS", // 0x00000200 "CERT_TRUST_INVALID_BASIC_CONSTRAINTS", // 0x00000400 "CERT_TRUST_INVALID_NAME_CONSTRAINTS", // 0x00000800 "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", // 0x00001000 "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT",// 0x00002000 "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", // 0x00004000 "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", // 0x00008000 "CERT_TRUST_IS_PARTIAL_CHAIN", // 0x00010000 "CERT_TRUST_CTL_IS_NOT_TIME_VALID", // 0x00020000 "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID", // 0x00040000 "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE", // 0x00080000 "Unknown Error Status", // 0x00100000 "Unknown Error Status", // 0x00200000 "Unknown Error Status", // 0x00400000 "Unknown Error Status", // 0x00800000 "CERT_TRUST_IS_OFFLINE_REVOCATION", // 0x01000000 "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", // 0x02000000 "Unknown Error Status", // 0x04000000 "Unknown Error Status", // 0x08000000 "Unknown Error Status", // 0x10000000 "Unknown Error Status", // 0x20000000 "Unknown Error Status", // 0x40000000 "Unknown Error Status" // 0x80000000 }; LPSTR rgszInfoStatus[] = { "CERT_TRUST_HAS_EXACT_MATCH_ISSUER",// 0x00000001 "CERT_TRUST_HAS_KEY_MATCH_ISSUER", // 0x00000002 "CERT_TRUST_HAS_NAME_MATCH_ISSUER", // 0x00000004 "CERT_TRUST_IS_SELF_SIGNED", // 0x00000008 "Unknown Info Status", // 0x00000010 "Unknown Info Status", // 0x00000020 "Unknown Info Status", // 0x00000040 "Unknown Info Status", // 0x00000080 "CERT_TRUST_HAS_PREFERRED_ISSUER", // 0x00000100 "CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY", // 0x00000200 "CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS", // 0x00000400 "Unknown Info Status", // 0x00000800 "Unknown Info Status", // 0x00001000 "Unknown Info Status", // 0x00002000 "Unknown Info Status", // 0x00004000 "Unknown Info Status", // 0x00008000 "CERT_TRUST_IS_COMPLEX_CHAIN", // 0x00010000 "Unknown Info Status", // 0x00020000 "Unknown Info Status", // 0x00040000 "Unknown Info Status", // 0x00080000 "Unknown Info Status", // 0x00100000 "Unknown Info Status", // 0x00200000 "Unknown Info Status", // 0x00400000 "Unknown Info Status", // 0x00800000 "Unknown Info Status", // 0x01000000 "Unknown Info Status", // 0x02000000 "Unknown Info Status", // 0x04000000 "Unknown Info Status", // 0x08000000 "Unknown Info Status", // 0x10000000 "Unknown Info Status", // 0x20000000 "Unknown Info Status", // 0x40000000 "Unknown Info Status" // 0x80000000 }; void DisplayTrustStatus( IN PCERT_TRUST_STATUS pStatus ) { DWORD dwMask; DWORD cCount; printf( "Trust Status (E=0x%lx,I=0x%lx)\n\n", pStatus->dwErrorStatus, pStatus->dwInfoStatus ); dwMask = 1; for ( cCount = 0; cCount < 32; cCount++ ) { if ( pStatus->dwErrorStatus & dwMask ) { if ( strcmp( rgszErrorStatus[ cCount ], "Unknown Error Status" ) != 0 ) { printf("%s\n", rgszErrorStatus[ cCount ]); } } dwMask = dwMask << 1; } dwMask = 1; for ( cCount = 0; cCount < 32; cCount++ ) { if ( pStatus->dwInfoStatus & dwMask ) { if ( strcmp( rgszInfoStatus[ cCount ], "Unknown Info Status" ) != 0 ) { printf("%s\n", rgszInfoStatus[ cCount ]); } } dwMask = dwMask << 1; } printf("\n"); } void DisplayRevocationFreshnessTime( IN DWORD dwTime // seconds ) { DWORD dwRemain; DWORD dwSec; DWORD dwMin; DWORD dwHour; DWORD dwDay; dwRemain = dwTime; dwSec = dwRemain % 60; dwRemain /= 60; // total minutes dwMin = dwRemain % 60; dwRemain /= 60; // total hours dwHour = dwRemain % 24; dwDay = dwRemain / 24; printf("Revocation Freshness Time : %d (%d day %d hour %d min %d sec)\n", dwTime, dwDay, dwHour, dwMin, dwSec); } void DisplayChainElement( IN PCERT_CHAIN_ELEMENT pElement, IN DWORD dwDisplayFlags ) { DisplayCert( pElement->pCertContext, dwDisplayFlags ); printf("\n"); if (pElement->pRevocationInfo) { PCERT_REVOCATION_INFO pRevocationInfo = pElement->pRevocationInfo; PrintError("RevocationResult: ", pRevocationInfo->dwRevocationResult); if (pRevocationInfo->pszRevocationOid) printf("RevocationOid: %s\n", pRevocationInfo->pszRevocationOid); if (pRevocationInfo->fHasFreshnessTime) DisplayRevocationFreshnessTime( pRevocationInfo->dwFreshnessTime); if (pRevocationInfo->pCrlInfo) { PCERT_REVOCATION_CRL_INFO pCrlInfo = pRevocationInfo->pCrlInfo; if (pCrlInfo->pBaseCrlContext) { printf("Base CRL\n"); DisplayCrl(pCrlInfo->pBaseCrlContext, dwDisplayFlags ); } if (pCrlInfo->pDeltaCrlContext) { printf("Delta CRL\n"); DisplayCrl(pCrlInfo->pDeltaCrlContext, dwDisplayFlags ); } if (pCrlInfo->pCrlEntry) { if (pCrlInfo->fDeltaCrlEntry) printf("Delta "); else printf("Base "); printf("CRL entry\n"); PrintCrlEntries(1, pCrlInfo->pCrlEntry, dwDisplayFlags); } } printf("\n"); } if (NULL == pElement->pIssuanceUsage) printf("Any Issuance Usages\n"); else if (0 == pElement->pIssuanceUsage->cUsageIdentifier) printf("No Issuance Usages\n"); else { printf("Issuance Usages\n"); LPSTR *ppszId = pElement->pIssuanceUsage->rgpszUsageIdentifier; DWORD cId = pElement->pIssuanceUsage->cUsageIdentifier; DWORD i; for (i = 0; i < cId; i++, ppszId++) printf(" [%d] %s\n", i, *ppszId); } if (NULL == pElement->pApplicationUsage) printf("Any Application Usages\n"); else if (0 == pElement->pApplicationUsage->cUsageIdentifier) printf("No Application Usages\n"); else { printf("Application Usages\n"); LPSTR *ppszId = pElement->pApplicationUsage->rgpszUsageIdentifier; DWORD cId = pElement->pApplicationUsage->cUsageIdentifier; DWORD i; for (i = 0; i < cId; i++, ppszId++) printf(" [%d] %s\n", i, *ppszId); } printf("\n"); if (pElement->pwszExtendedErrorInfo) { printf("Extended Error Information::\n%S\n", pElement->pwszExtendedErrorInfo); } DisplayTrustStatus( &pElement->TrustStatus ); } void DisplaySimpleChain( IN PCERT_SIMPLE_CHAIN pChain, IN DWORD dwDisplayFlags = 0 ) { DWORD cElement; if (pChain->fHasRevocationFreshnessTime) DisplayRevocationFreshnessTime( pChain->dwRevocationFreshnessTime); DisplayTrustStatus( &pChain->TrustStatus ); if (fFlushCrl && pChain->cElement >= 2) { if (CryptFlushTimeValidObject( TIME_VALID_OID_FLUSH_CRL_FROM_CERT, (LPVOID) pChain->rgpElement[0]->pCertContext, // pvPara pChain->rgpElement[1]->pCertContext, // pIssuer 0, // dwFlags NULL // pvReserved )) printf("Successful FlushCrl\n"); else PrintLastError("FlushCrl"); } printf("Chain Element Count = %d\n", pChain->cElement); for ( cElement = 0; cElement < pChain->cElement; cElement++ ) { printf("Chain Element [%d]\n", cElement); DisplayChainElement( pChain->rgpElement[ cElement ], dwDisplayFlags ); } } void DisplayKirtChain( IN PCCERT_CHAIN_CONTEXT pChainContext, IN DWORD dwDisplayFlags ) { DWORD cChain; if (NULL == pChainContext) return; printf("Chain Context\n\n"); if (pChainContext->fHasRevocationFreshnessTime) DisplayRevocationFreshnessTime( pChainContext->dwRevocationFreshnessTime); DisplayTrustStatus( (PCERT_TRUST_STATUS)&pChainContext->TrustStatus ); printf("Simple Chain Count = %d\n\n", pChainContext->cChain ); for ( cChain = 0; cChain < pChainContext->cChain; cChain++ ) { printf("Simple Chain [%d]\n", cChain); DisplaySimpleChain( pChainContext->rgpChain[ cChain ], dwDisplayFlags ); } if (pChainContext->cLowerQualityChainContext) { DWORD i; printf("Lower Quality Chain Count = %d\n\n", pChainContext->cLowerQualityChainContext); for (i = 0; i < pChainContext->cLowerQualityChainContext; i++) { printf("Lower Quality Chain [%d]\n", i); DisplayKirtChain(pChainContext->rgpLowerQualityChainContext[i], dwDisplayFlags); } } } void DisplayChainPolicyCallbackSigner( IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSigner ) { if (pSigner->dwSignerType) { printf("Signer Type: 0x%x", pSigner->dwSignerType); if (pSigner->dwSignerType == SGNR_TYPE_TIMESTAMP) printf(" TIMESTAMP"); printf("\n"); } if (pSigner->dwError) PrintError("Error: ", pSigner->dwError); if (pSigner->pMsgSignerInfo) printf("pMsgSignerInfo: 0x%p\n", pSigner->pMsgSignerInfo); DisplayKirtChain(pSigner->pChainContext, DISPLAY_BRIEF_FLAG); } #define CHAIN_POLICY_ARG (DWORD_PTR)0x8765beef HRESULT WINAPI ChainPolicyCallback( IN PCRYPT_PROVIDER_DATA pProvData, IN DWORD dwStepError, IN DWORD dwRegPolicySettings, IN DWORD cSigner, IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *rgpSigner, IN void *pvPolicyArg ) { printf(">>>>> ChainPolicyCallback <<<<<\n"); if (pvPolicyArg != (void *) CHAIN_POLICY_ARG) printf("failed => wrong pvPolicyArg\n"); if (dwStepError) PrintError("StepError: ", dwStepError); if (dwRegPolicySettings) printf("RegPolicySettings: 0x%p\n"); if (0 == cSigner) printf("No Signers\n"); else { DWORD idxSigner; for (idxSigner = 0; idxSigner < cSigner; idxSigner++) { DWORD idxCounterSigner; PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSigner = rgpSigner[idxSigner]; printf("====== Signer [%d] ======\n", idxSigner); DisplayChainPolicyCallbackSigner(pSigner); for (idxCounterSigner = 0; idxCounterSigner < pSigner->cCounterSigner; idxCounterSigner++) { PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pCounterSigner = pSigner->rgpCounterSigner[idxCounterSigner]; printf("\n"); printf("====== CounterSigner [%d,%d] ======\n", idxSigner, idxCounterSigner); DisplayChainPolicyCallbackSigner(pCounterSigner); } } } return TRUST_E_FAIL; } static BOOL fInstallDefaultContext = FALSE; static DWORD dwDefaultContextFlags = 0; static BOOL fNULLDefaultContext = FALSE; static BOOL fMultiDefaultContext = FALSE; static LPSTR rgpszDefaultContextOID[] = { // 0 szOID_OIWSEC_sha1RSASign, // 1 szOID_OIWSEC_shaRSA, // 2 szOID_RSA_MD5RSA, // 3 szOID_OIWSEC_md5RSA, // 4 szOID_RSA_MD2RSA, // 5 szOID_RSA_MD4RSA, // 6 szOID_OIWSEC_md4RSA, // 7 szOID_OIWSEC_md4RSA2, // 8 szOID_OIWDIR_md2RSA, // 9 szOID_RSA_SHA1RSA, }; static CRYPT_DEFAULT_CONTEXT_MULTI_OID_PARA rgMultiOIDPara[] = { 1, &rgpszDefaultContextOID[3], 2, &rgpszDefaultContextOID[2], 10, &rgpszDefaultContextOID[0], 4, &rgpszDefaultContextOID[6], 1, &rgpszDefaultContextOID[8], }; #define NUM_MULTI_OID_PARA (sizeof(rgMultiOIDPara) / sizeof(rgMultiOIDPara[0])) static HCRYPTDEFAULTCONTEXT rghDefaultContext[NUM_MULTI_OID_PARA]; static DWORD cDefaultContext = 0; static HCRYPTPROV hDefaultContextProv = 0; static void InstallDefaultContext() { if (!CryptAcquireContext( &hDefaultContextProv, NULL, // pszContainer NULL, // pszProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT // dwFlags )) { PrintLastError( "CryptAcquireContext(PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)"); hDefaultContextProv = 0; return; } if (fMultiDefaultContext) { DWORD dwFlags = dwDefaultContextFlags; for (cDefaultContext = 0; cDefaultContext < NUM_MULTI_OID_PARA; cDefaultContext++) { if (!CryptInstallDefaultContext( hDefaultContextProv, CRYPT_DEFAULT_CONTEXT_MULTI_CERT_SIGN_OID, (const void *) &rgMultiOIDPara[cDefaultContext], dwFlags, NULL, // pvReserved &rghDefaultContext[cDefaultContext] )) { PrintLastError("CryptInstallDefaultContext"); break; } dwFlags &= ~CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG; } } else { LPSTR pszOID; if (fNULLDefaultContext) pszOID = NULL; else pszOID = szOID_RSA_MD5RSA; if (!CryptInstallDefaultContext( hDefaultContextProv, CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID, (const void *) pszOID, dwDefaultContextFlags, NULL, // pvReserved &rghDefaultContext[0] )) PrintLastError("CryptInstallDefaultContext"); else cDefaultContext = 1; } if (0 == cDefaultContext) { CryptReleaseContext(hDefaultContextProv, 0); hDefaultContextProv = 0; } } static void FreeDefaultContext() { if (dwDefaultContextFlags & CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG) return; if (0 < cDefaultContext) { if (!CryptUninstallDefaultContext( rghDefaultContext[0], 0, // dwFlags NULL // pvReserved )) PrintLastError("CryptUninstallDefaultContext"); rghDefaultContext[0] = NULL; while (cDefaultContext-- > 0){ if (!CryptUninstallDefaultContext( rghDefaultContext[cDefaultContext], 0, // dwFlags NULL // pvReserved )) PrintLastError("CryptUninstallDefaultContext"); } } if (hDefaultContextProv) CryptReleaseContext(hDefaultContextProv, 0); } BOOL NTAuthVerify( IN PCCERT_CHAIN_CONTEXT pChainContext, IN DWORD dwExpectedErr ) { BOOL fResult = TRUE; DWORD dwErr; HCERTSTORE hNTAuthStore = NULL; PCERT_SIMPLE_CHAIN pChain; PCCERT_CONTEXT pCACert; // don't free PCCERT_CONTEXT pAddCert = NULL; CERT_CHAIN_POLICY_PARA PolicyPara; memset(&PolicyPara, 0, sizeof(PolicyPara)); PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG | CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; CERT_CHAIN_POLICY_STATUS PolicyStatus; memset(&PolicyStatus, 0, sizeof(PolicyStatus)); PolicyStatus.cbSize = sizeof(PolicyStatus); if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_NT_AUTH, pChainContext, &PolicyPara, &PolicyStatus )) { PrintLastError( "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)"); goto ErrorReturn; } dwErr = PolicyStatus.dwError; if ((CRYPT_E_NO_REVOCATION_CHECK == dwExpectedErr || CRYPT_E_REVOCATION_OFFLINE == dwExpectedErr)) { if (CERT_E_UNTRUSTEDCA != dwErr) { PrintStatus("NTAuth failed without CERT_E_UNTRUSTEDCA when revocation checking => ", (LONG) dwErr); fResult = FALSE; } } else if (dwExpectedErr != dwErr) { PrintStatus("Expected => ", (LONG) dwExpectedErr); PrintStatus("NTAuth failed => ", (LONG) dwErr); fResult = FALSE; } if (CERT_E_UNTRUSTEDCA != dwErr) goto CommonReturn; pChain = pChainContext->rgpChain[0]; if (2 > pChain->cElement) { printf("NTAuth:: failed => missing CA cert\n"); goto ErrorReturn; } pCACert = pChain->rgpElement[1]->pCertContext; hNTAuthStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, // dwEncodingType 0, // hCryptProv CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, L"NTAuth" ); if (NULL == hNTAuthStore) { PrintLastError("CertOpenStore(NTAuth)"); goto ErrorReturn; } if (!CertAddCertificateContextToStore( hNTAuthStore, pCACert, CERT_STORE_ADD_NEW, &pAddCert )) { PrintLastError("CertAddCertificateContextToStore(NTAuth CA)"); goto ErrorReturn; } // Need to sleep to allow the registry notification to occur. Sleep(200); // With the CA cert added, the verify policy should succeed if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_NT_AUTH, pChainContext, &PolicyPara, &PolicyStatus )) { PrintLastError( "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)"); fResult = FALSE; } else if (0 != PolicyStatus.dwError) { if ((CRYPT_E_NO_REVOCATION_CHECK == dwExpectedErr || CRYPT_E_REVOCATION_OFFLINE == dwExpectedErr) && dwExpectedErr == PolicyStatus.dwError) { PrintStatus("NTAuth got expected error adding NTAuth CA = ", (LONG) dwExpectedErr); } else { PrintStatus("NTAuth failed after adding NTAuth CA with dwError = ", (LONG) PolicyStatus.dwError); fResult = FALSE; } } CertDeleteCertificateFromStore(pAddCert); pAddCert = NULL; // Need to sleep to allow the registry notification to occur. Sleep(200); // With the CA cert deleted, the verify policy should fail if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_NT_AUTH, pChainContext, &PolicyPara, &PolicyStatus )) { PrintLastError( "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)"); fResult = FALSE; } else if (CERT_E_UNTRUSTEDCA != PolicyStatus.dwError) { PrintStatus("NTAuth failed without CERT_E_UNTRUSTEDCA after deleting NTAuth CA with dwError = ", (LONG) PolicyStatus.dwError); fResult = FALSE; } CommonReturn: if (hNTAuthStore) CertCloseStore(hNTAuthStore, 0); return fResult; ErrorReturn: if (pAddCert) CertDeleteCertificateFromStore(pAddCert); fResult = FALSE; goto CommonReturn; } BOOL NTAuthNameConstraintVerify( IN PCCERT_CHAIN_CONTEXT pChainContext, IN DWORD dwExpectedErr ) { BOOL fResult = FALSE; DWORD dwErr; CERT_CHAIN_POLICY_PARA PolicyPara; memset(&PolicyPara, 0, sizeof(PolicyPara)); PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG; CERT_CHAIN_POLICY_STATUS PolicyStatus; memset(&PolicyStatus, 0, sizeof(PolicyStatus)); PolicyStatus.cbSize = sizeof(PolicyStatus); if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_NT_AUTH, pChainContext, &PolicyPara, &PolicyStatus )) { PrintLastError( "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)"); goto CommonReturn; } dwErr = PolicyStatus.dwError; if (dwExpectedErr == dwErr) { PrintStatus("NTAuthNameConstraint returned expected => ", (LONG) dwExpectedErr); fResult = TRUE; } else { PrintStatus("Expected => ", (LONG) dwExpectedErr); PrintStatus("NTAuthNameConstraint failed => ", (LONG) dwErr); } CommonReturn: return fResult; } void DeleteSaferRegKey() { HKEY hKey = NULL; LONG err; if (ERROR_SUCCESS != (err = RegOpenKeyExU( HKEY_LOCAL_MACHINE, CERT_TRUST_PUB_SAFER_LOCAL_MACHINE_REGPATH, 0, // dwReserved KEY_ALL_ACCESS, &hKey ))) { if (ERROR_FILE_NOT_FOUND != err) PrintError("RegOpenKey(SAFER) failed", (DWORD) err); goto CommonReturn; } RegDeleteValueU(hKey, CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME); CommonReturn: if (hKey) RegCloseKey(hKey); } void SetSaferRegKeyValue( IN LPCWSTR pwszValueName, IN DWORD dwValue ) { LONG err; DWORD dwDisposition; HKEY hKey = NULL; if (ERROR_SUCCESS != (err = RegCreateKeyExU( HKEY_LOCAL_MACHINE, CERT_TRUST_PUB_SAFER_LOCAL_MACHINE_REGPATH, 0, // dwReserved NULL, // lpClass REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, // lpSecurityAttributes &hKey, &dwDisposition))) { PrintError("RegCreateKey(SAFER) failed", (DWORD) err); goto CommonReturn; } if (ERROR_SUCCESS != (err = RegSetValueExU( hKey, pwszValueName, 0, // dwReserved REG_DWORD, (BYTE *) &dwValue, sizeof(DWORD)))) { PrintError("RegSetValue(SAFER) failed", (DWORD) err); goto CommonReturn; } CommonReturn: if (hKey) RegCloseKey(hKey); } void SetRootAutoUpdateValue( IN DWORD dwValue ) { LONG err; DWORD dwDisposition; HKEY hKey = NULL; if (ERROR_SUCCESS != (err = RegCreateKeyExU( HKEY_LOCAL_MACHINE, CERT_OCM_SUBCOMPONENTS_LOCAL_MACHINE_REGPATH, 0, // dwReserved NULL, // lpClass REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, // lpSecurityAttributes &hKey, &dwDisposition))) { PrintError("RegCreateKey(OCM Subcomponents) failed", (DWORD) err); goto CommonReturn; } if (ERROR_SUCCESS != (err = RegSetValueExU( hKey, CERT_OCM_SUBCOMPONENTS_ROOT_AUTO_UPDATE_VALUE_NAME, 0, // dwReserved REG_DWORD, (BYTE *) &dwValue, sizeof(DWORD)))) { PrintError("RegSetValue(RootAutoUpdate) failed", (DWORD) err); goto CommonReturn; } CommonReturn: if (hKey) RegCloseKey(hKey); } void SetAuthRootAutoUpdateFlags( IN DWORD dwSetValue, IN BOOL fEnable ) { LONG err; DWORD dwDisposition; HKEY hKey = NULL; DWORD dwValue = 0; DWORD cbValue = sizeof(dwValue); DWORD dwType = 0; if (ERROR_SUCCESS != (err = RegCreateKeyExU( HKEY_LOCAL_MACHINE, CERT_AUTH_ROOT_AUTO_UPDATE_LOCAL_MACHINE_REGPATH, 0, // dwReserved NULL, // lpClass REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, // lpSecurityAttributes &hKey, &dwDisposition))) { PrintError("RegCreateKey(AuthRootAutoUpdate) failed", (DWORD) err); goto CommonReturn; } RegQueryValueExU( hKey, CERT_AUTH_ROOT_AUTO_UPDATE_FLAGS_VALUE_NAME, NULL, // pdwReserved &dwType, (BYTE *) &dwValue, &cbValue ); if (fEnable) dwValue |= dwSetValue; else dwValue &= ~dwSetValue; if (ERROR_SUCCESS != (err = RegSetValueExU( hKey, CERT_AUTH_ROOT_AUTO_UPDATE_FLAGS_VALUE_NAME, 0, // dwReserved REG_DWORD, (BYTE *) &dwValue, sizeof(DWORD)))) { PrintError("RegSetValue(AuthRootAutoUpdate) failed", (DWORD) err); goto CommonReturn; } CommonReturn: if (hKey) RegCloseKey(hKey); } void SetProtectedRootsFlags( IN DWORD dwSetValue, IN BOOL fEnable ) { LONG err; DWORD dwDisposition; HKEY hKey = NULL; DWORD dwValue = 0; DWORD cbValue = sizeof(dwValue); DWORD dwType = 0; if (ERROR_SUCCESS != (err = RegCreateKeyExU( HKEY_LOCAL_MACHINE, CERT_PROT_ROOT_FLAGS_REGPATH, 0, // dwReserved NULL, // lpClass REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, // lpSecurityAttributes &hKey, &dwDisposition))) { PrintError("RegCreateKey(ProtectedRoots) failed", (DWORD) err); goto CommonReturn; } RegQueryValueExU( hKey, CERT_PROT_ROOT_FLAGS_VALUE_NAME, NULL, // pdwReserved &dwType, (BYTE *) &dwValue, &cbValue ); if (fEnable) dwValue |= dwSetValue; else dwValue &= ~dwSetValue; if (ERROR_SUCCESS != (err = RegSetValueExU( hKey, CERT_PROT_ROOT_FLAGS_VALUE_NAME, 0, // dwReserved REG_DWORD, (BYTE *) &dwValue, sizeof(DWORD)))) { PrintError("RegSetValue(ProtectedRootsFlags) failed", (DWORD) err); goto CommonReturn; } CommonReturn: if (hKey) RegCloseKey(hKey); } void SetCertChainConfigRegKeyValue( IN LPCSTR pszValueName, IN DWORD dwValue ) { LONG err; DWORD dwDisposition; HKEY hKey = NULL; if (ERROR_SUCCESS != (err = RegCreateKeyExU( HKEY_LOCAL_MACHINE, CERT_CHAIN_CONFIG_REGPATH, 0, // dwReserved NULL, // lpClass REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, // lpSecurityAttributes &hKey, &dwDisposition))) { PrintError("RegCreateKey(CERT_CHAIN_CONFIG) failed", (DWORD) err); goto CommonReturn; } if (0xFFFFFFFF == dwValue) { err = RegDeleteValueA(hKey, pszValueName); if (ERROR_FILE_NOT_FOUND == err) ; else if (ERROR_SUCCESS != err) { printf("RegDeleteValue(%s) failed => 0x%x (%d)\n", pszValueName, (DWORD) err, (DWORD) err); goto CommonReturn; } } else { if (ERROR_SUCCESS != (err = RegSetValueExA( hKey, pszValueName, 0, // dwReserved REG_DWORD, (BYTE *) &dwValue, sizeof(DWORD)))) { printf("RegSetValue(%s) failed => 0x%x (%d)\n", pszValueName, (DWORD) err, (DWORD) err); goto CommonReturn; goto CommonReturn; } } CommonReturn: if (hKey) RegCloseKey(hKey); } int _cdecl main(int argc, char * argv[]) { BOOL fResult; int status; LONG lStatus; DWORD dwDisplayFlags = 0; DWORD i; #define TRUST_TYPE_CERT 1 #define TRUST_TYPE_FILE 2 #define TRUST_TYPE_HTTPS 3 #define TRUST_TYPE_DRIVER 4 DWORD dwTrustType = TRUST_TYPE_CERT; BOOL fChain = FALSE; BOOL fChainCallback = FALSE; DWORD dwFlags = 0; BOOL fQuiet = FALSE; LONG lWVTExpected = 0; LPSTR pszCertOrFile = NULL; // not allocated LPSTR pszUsageOID = NULL; // not allocated LPSTR pszSignerUsage = szOID_KP_CTL_USAGE_SIGNING; GUID wvtFileActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2; GUID wvtCertActionID = WINTRUST_ACTION_GENERIC_CERT_VERIFY; GUID wvtHttpsActionID = HTTPSPROV_ACTION; GUID wvtDriverActionID = DRIVER_ACTION_VERIFY; GUID wvtChainActionID = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY; GUID *pwvtActionID; CRYPT_PROVIDER_DATA *pProvData; // not allocated WINTRUST_FILE_INFO wvtFileInfo; memset(&wvtFileInfo, 0, sizeof(wvtFileInfo)); wvtFileInfo.cbStruct = sizeof(wvtFileInfo); wvtFileInfo.pcwszFilePath = NULL; #define MAX_CERT_STORE 10 HCERTSTORE rghStore[MAX_CERT_STORE]; WINTRUST_CERT_INFO wvtCertInfo; memset(&wvtCertInfo, 0, sizeof(wvtCertInfo)); wvtCertInfo.cbStruct = sizeof(wvtCertInfo); wvtCertInfo.psCertContext = NULL; wvtCertInfo.chStores = 0; wvtCertInfo.pahStores = rghStore; wvtCertInfo.dwFlags = 0; wvtCertInfo.pcwszDisplayName = L"Cert Display Name"; HTTPSPolicyCallbackData httpsPolicyCallbackData; memset(&httpsPolicyCallbackData, 0, sizeof(httpsPolicyCallbackData)); httpsPolicyCallbackData.cbStruct = sizeof(httpsPolicyCallbackData); httpsPolicyCallbackData.dwAuthType = AUTHTYPE_CLIENT; httpsPolicyCallbackData.fdwChecks = 0; DRIVER_VER_INFO DriverVerInfo; memset(&DriverVerInfo, 0, sizeof(DriverVerInfo)); DriverVerInfo.cbStruct = sizeof(DriverVerInfo); CERT_CHAIN_PARA ChainPara; memset(&ChainPara, 0, sizeof(ChainPara)); ChainPara.cbSize = sizeof(ChainPara); #define MAX_USAGE_CNT 16 LPSTR rgpszUsageOID[MAX_USAGE_CNT]; DWORD cUsageOID = 0; DWORD dwUsageType = USAGE_MATCH_TYPE_AND; #define MAX_POLICY_CNT 16 LPSTR rgpszPolicyOID[MAX_POLICY_CNT]; DWORD cPolicyOID = 0; DWORD dwPolicyUsageType = USAGE_MATCH_TYPE_AND; WTD_GENERIC_CHAIN_POLICY_CREATE_INFO ChainInfo; memset(&ChainInfo, 0, sizeof(ChainInfo)); ChainInfo.cbSize = sizeof(ChainInfo); ChainInfo.pChainPara = &ChainPara; WTD_GENERIC_CHAIN_POLICY_DATA wtdChainPolicyData; memset(&wtdChainPolicyData, 0, sizeof(wtdChainPolicyData)); wtdChainPolicyData.cbSize = sizeof(wtdChainPolicyData); wtdChainPolicyData.pvPolicyArg = (void *) CHAIN_POLICY_ARG; WINTRUST_DATA wvtData; memset(&wvtData, 0, sizeof(wvtData)); wvtData.cbStruct = sizeof(wvtData); wvtData.pPolicyCallbackData = NULL; wvtData.dwUIChoice = WTD_UI_NONE; wvtData.fdwRevocationChecks = WTD_REVOKE_NONE; wvtData.dwUnionChoice = WTD_CHOICE_CERT; wvtData.pCert = &wvtCertInfo; wvtData.dwStateAction = WTD_STATEACTION_IGNORE; wvtData.hWVTStateData = NULL; wvtData.dwProvFlags = 0; BOOL fDisplayKnownUsages = FALSE; BOOL fNTAuth = FALSE; BOOL fNTAuthNameConstraint = FALSE; BOOL fLogoffNotification = FALSE; BOOL fDeferClosing = FALSE; BOOL fExpectedTrustErrorStatus = FALSE; DWORD dwExpectedTrustErrorStatus = 0; BOOL fExpectedTrustInfoStatus = FALSE; DWORD dwExpectedTrustInfoStatus = 0; DWORD dwUrlRetrievalTimeout = 0; BOOL fCheckRevocationFreshnessTime = FALSE; DWORD dwRevocationFreshnessTime; BOOL fSafer = FALSE; BOOL fMicrosoftRoot = FALSE; BOOL fMicrosoftTestRoot = FALSE; BOOL fNotMicrosoftRoot = FALSE; while (--argc>0) { if (**++argv == '-') { if (0 == _stricmp(argv[0]+1, "Cert")) { wvtData.dwUnionChoice = WTD_CHOICE_CERT; dwTrustType = TRUST_TYPE_CERT; } else if (0 == _stricmp(argv[0]+1, "File")) { wvtData.dwUnionChoice = WTD_CHOICE_FILE; dwTrustType = TRUST_TYPE_FILE; } else if (0 == _stricmp(argv[0]+1, "Driver")) { wvtData.dwUnionChoice = WTD_CHOICE_FILE; dwTrustType = TRUST_TYPE_DRIVER; } else if (0 == _stricmp(argv[0]+1, "Https")) { wvtData.dwUnionChoice = WTD_CHOICE_CERT; dwTrustType = TRUST_TYPE_HTTPS; } else if (0 == _stricmp(argv[0]+1, "Chain")) { fChain = TRUE; } else if (0 == _stricmp(argv[0]+1, "ChainCallback")) { fChain = TRUE; fChainCallback = TRUE; } else if (0 == _stricmp(argv[0]+1, "NTAuth")) { fNTAuth = TRUE; } else if (0 == _stricmp(argv[0]+1, "NTAuthNameConstraint")) { fNTAuth = TRUE; fNTAuthNameConstraint = TRUE; } else if (0 == _stricmp(argv[0]+1, "Safer")) { wvtData.dwUnionChoice = WTD_CHOICE_FILE; dwTrustType = TRUST_TYPE_FILE; fSafer = TRUE; } else if (0 == _stricmp(argv[0]+1, "Client")) { httpsPolicyCallbackData.dwAuthType = AUTHTYPE_CLIENT; } else if (0 == _stricmp(argv[0]+1, "Server")) { httpsPolicyCallbackData.dwAuthType = AUTHTYPE_SERVER; } else if (0 == _stricmp(argv[0]+1, "UIAll")) { wvtData.dwUIChoice = WTD_UI_ALL; } else if (0 == _stricmp(argv[0]+1, "UINone")) { wvtData.dwUIChoice = WTD_UI_NONE; } else if (0 == _stricmp(argv[0]+1, "UINoBad")) { wvtData.dwUIChoice = WTD_UI_NOBAD; } else if (0 == _stricmp(argv[0]+1, "UINoGood")) { wvtData.dwUIChoice = WTD_UI_NOGOOD; } else if (0 == _stricmp(argv[0]+1, "RevokeNone")) { wvtData.fdwRevocationChecks = WTD_REVOKE_NONE; } else if (0 == _stricmp(argv[0]+1, "RevokeChain")) { wvtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; } else if (0 == _stricmp(argv[0]+1, "UseIE4Trust")) { wvtData.dwProvFlags |= WTD_USE_IE4_TRUST_FLAG; } else if (0 == _stricmp(argv[0]+1, "NoIE4Chain")) { wvtData.dwProvFlags |= WTD_NO_IE4_CHAIN_FLAG; } else if (0 == _stricmp(argv[0]+1, "NoUsage")) { wvtData.dwProvFlags |= WTD_NO_POLICY_USAGE_FLAG; } else if (0 == _stricmp(argv[0]+1, "OrUsage")) { dwUsageType = USAGE_MATCH_TYPE_OR; } else if (0 == _stricmp(argv[0]+1, "OrPolicy")) { dwPolicyUsageType = USAGE_MATCH_TYPE_OR; } else if (0 == _stricmp(argv[0]+1, "LifetimeSigning")) { wvtData.dwProvFlags |= WTD_LIFETIME_SIGNING_FLAG; } else if (0 == _stricmp(argv[0]+1, "MicrosoftRoot")) { fMicrosoftRoot = TRUE; } else if (0 == _stricmp(argv[0]+1, "MicrosoftTestRoot")) { fMicrosoftTestRoot = TRUE; fMicrosoftRoot = TRUE; } else if (0 == _stricmp(argv[0]+1, "NotMicrosoftRoot")) { fNotMicrosoftRoot = TRUE; } else if (0 == _stricmp(argv[0]+1, "FlushCrl")) { fFlushCrl = TRUE; } else if (0 == _stricmp(argv[0]+1, "DeferClosing")) { fDeferClosing = TRUE; } else if (0 == _stricmp(argv[0]+1, "DisplayKnownUsages")) { fDisplayKnownUsages = TRUE; } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreRevocation")) { httpsPolicyCallbackData.fdwChecks |= SECURITY_FLAG_IGNORE_REVOCATION; } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreUnknownCA")) { httpsPolicyCallbackData.fdwChecks |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreWrongUsage")) { httpsPolicyCallbackData.fdwChecks |= SECURITY_FLAG_IGNORE_WRONG_USAGE; } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreCertDateInvalid")) { httpsPolicyCallbackData.fdwChecks |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreCertCNInvalid")) { httpsPolicyCallbackData.fdwChecks |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; } else if (0 == _stricmp(argv[0]+1, "DontOpenStores")) { wvtCertInfo.dwFlags = WTCI_DONT_OPEN_STORES; } else if (0 == _stricmp(argv[0]+1, "OpenOnlyRoot")) { wvtCertInfo.dwFlags = WTCI_OPEN_ONLY_ROOT; } else if (0 == _stricmp(argv[0]+1, "InstallThreadDefaultContext")) { fInstallDefaultContext = TRUE; dwDefaultContextFlags &= ~CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG; } else if (0 == _stricmp(argv[0]+1, "InstallProcessDefaultContext")) { fInstallDefaultContext = TRUE; dwDefaultContextFlags |= CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG; } else if (0 == _stricmp(argv[0]+1, "AutoReleaseDefaultContext")) { dwDefaultContextFlags |= CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG; } else if (0 == _stricmp(argv[0]+1, "NULLDefaultContext")) { fNULLDefaultContext = TRUE; } else if (0 == _stricmp(argv[0]+1, "MultiDefaultContext")) { fMultiDefaultContext = TRUE; } else if (0 == _stricmp(argv[0]+1, "LogoffNotification")) { fLogoffNotification = TRUE; } else if (0 == _stricmp(argv[0]+1, "AuthenticodeFlags")) { DWORD dwFlags; if (argc < 2 || argv[1][0] == '-') { printf("Option (-AuthenticodeFlags) : missing number argument\n"); goto BadUsage; } dwFlags = strtoul(argv[1], NULL, 0); argc -= 1; argv += 1; SetSaferRegKeyValue( CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME, dwFlags); } else if (0 == _stricmp(argv[0]+1, "DisableMandatoryBasicConstraints") || 0 == _stricmp(argv[0]+1, "DisableAIAUrlRetrieval") || 0 == _stricmp(argv[0]+1, "MaxAIAUrlCountInCert") || 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalCountPerChain") || 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalByteCount") || 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalCertCount")) { LPCSTR pszOption = argv[0]+1; DWORD dwValue; if (argc < 2 || argv[1][0] == '-') { printf("Option (-%s) : missing number argument\n", pszOption); goto BadUsage; } dwValue = strtoul(argv[1], NULL, 0); argc -= 1; argv += 1; SetCertChainConfigRegKeyValue(pszOption, dwValue); } else if (0 == _stricmp(argv[0]+1, "DeleteSaferRegKey")) { DeleteSaferRegKey(); } else if (0 == _stricmp(argv[0]+1, "EnableRootAutoUpdate")) { SetRootAutoUpdateValue(0x1); } else if (0 == _stricmp(argv[0]+1, "DisableRootAutoUpdate")) { SetRootAutoUpdateValue(0x0); } else if (0 == _stricmp(argv[0]+1, "EnableUntrustedRootLogging")) { SetAuthRootAutoUpdateFlags( CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_UNTRUSTED_ROOT_LOGGING_FLAG, FALSE); } else if (0 == _stricmp(argv[0]+1, "DisableUntrustedRootLogging")) { SetAuthRootAutoUpdateFlags( CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_UNTRUSTED_ROOT_LOGGING_FLAG, TRUE); } else if (0 == _stricmp(argv[0]+1, "EnablePartialChainLogging")) { SetAuthRootAutoUpdateFlags( CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_PARTIAL_CHAIN_LOGGING_FLAG, FALSE); } else if (0 == _stricmp(argv[0]+1, "DisablePartialChainLogging")) { SetAuthRootAutoUpdateFlags( CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_PARTIAL_CHAIN_LOGGING_FLAG, TRUE); } else if (0 == _stricmp(argv[0]+1, "EnableNTAuthRequired")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_NT_AUTH_REQUIRED_FLAG, FALSE); } else if (0 == _stricmp(argv[0]+1, "DisableNTAuthRequired")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_NT_AUTH_REQUIRED_FLAG, TRUE); } else if (0 == _stricmp(argv[0]+1, "EnableNotDefinedNameConstraint")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_NOT_DEFINED_NAME_CONSTRAINT_FLAG, FALSE); } else if (0 == _stricmp(argv[0]+1, "DisableNotDefinedNameConstraint")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_NOT_DEFINED_NAME_CONSTRAINT_FLAG, TRUE); } else if (0 == _stricmp(argv[0]+1, "EnableAuthRoot")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_LM_AUTH_FLAG, FALSE); } else if (0 == _stricmp(argv[0]+1, "DisableAuthRoot")) { SetProtectedRootsFlags( CERT_PROT_ROOT_DISABLE_LM_AUTH_FLAG, TRUE); } else if (0 == _stricmp(argv[0]+1, "RegistryOnlyExit")) { goto RegistryOnlyExit; } else { switch(argv[0][1]) { case 's': case 'S': if (wvtCertInfo.chStores >= MAX_CERT_STORE) { printf("Exceed maximum number of stores %d\n", MAX_CERT_STORE); goto BadUsage; } if (NULL == (rghStore[wvtCertInfo.chStores] = OpenSystemStoreOrFile( argv[0][1] == 's', // fSystemStore argv[0]+2, 0 // dwFlags ))) goto BadUsage; wvtCertInfo.chStores++; break; case 'b': dwDisplayFlags |= DISPLAY_BRIEF_FLAG; break; case 'v': dwDisplayFlags |= DISPLAY_VERBOSE_FLAG; break; case 'u': if (MAX_USAGE_CNT <= cUsageOID) { printf("Too many usages\n"); goto BadUsage; } if (0 == cUsageOID) pszUsageOID = argv[0]+2; rgpszUsageOID[cUsageOID++] = argv[0]+2; break; case 'p': if (MAX_POLICY_CNT <= cPolicyOID) { printf("Too many policies\n"); goto BadUsage; } rgpszPolicyOID[cPolicyOID++] = argv[0]+2; break; case 'n': httpsPolicyCallbackData.pwszServerName = AllocAndSzToWsz(argv[0]+2); break; case 'f': dwFlags = (DWORD) strtoul(argv[0]+2, NULL, 0); break; case 'e': fExpectedTrustErrorStatus = TRUE; dwExpectedTrustErrorStatus = (DWORD) strtoul(argv[0]+2, NULL, 0); break; case 'i': fExpectedTrustInfoStatus = TRUE; dwExpectedTrustInfoStatus = (DWORD) strtoul(argv[0]+2, NULL, 0); break; case 't': dwUrlRetrievalTimeout = (DWORD) strtoul(argv[0]+2, NULL, 0); break; case 'r': fCheckRevocationFreshnessTime = TRUE; dwRevocationFreshnessTime = (DWORD) strtoul(argv[0]+2, NULL, 0); break; case 'q': fQuiet = TRUE; if (argv[0][2]) lWVTExpected = (LONG) strtoul(argv[0]+2, NULL, 0); break; case 'h': default: goto BadUsage; } } } else { if (pszCertOrFile) { printf("Multiple certs or filenames not supported\n"); goto BadUsage; } pszCertOrFile = argv[0]; } } if (NULL == pszCertOrFile) { printf("Missing cert or filename\n"); goto BadUsage; } printf("command line: %s\n", GetCommandLine()); if (fDisplayKnownUsages) { PCCRYPT_OID_INFO *ppOidInfo = NULL; if (WTHelperGetKnownUsages(WTH_ALLOC, &ppOidInfo)) { for (DWORD i = 0; ppOidInfo[i]; i++) printf("Usage[%d]:: OID: %s Name: %S\n", i, ppOidInfo[i]->pszOID, ppOidInfo[i]->pwszName); WTHelperGetKnownUsages(WTH_FREE, &ppOidInfo); } } switch (wvtData.dwUnionChoice) { case WTD_CHOICE_FILE: if (TRUST_TYPE_DRIVER == dwTrustType) { pwvtActionID = &wvtDriverActionID; wvtData.pPolicyCallbackData = (void *) &DriverVerInfo; } else { pwvtActionID = &wvtFileActionID; } wvtData.pFile = &wvtFileInfo; wvtFileInfo.pcwszFilePath = AllocAndSzToWsz(pszCertOrFile); break; case WTD_CHOICE_CERT: if (TRUST_TYPE_HTTPS == dwTrustType) { pwvtActionID = &wvtHttpsActionID; wvtData.pPolicyCallbackData = (void *) &httpsPolicyCallbackData; } else { pwvtActionID = &wvtCertActionID; wvtData.pPolicyCallbackData = (void *) pszUsageOID; } wvtData.pCert = &wvtCertInfo; if (NULL == (wvtCertInfo.psCertContext = (CERT_CONTEXT *) ReadCert(pszCertOrFile))) goto ErrorReturn; if (fDeferClosing && 1 == wvtCertInfo.chStores) { HCERTSTORE hDeferStore = NULL; PCCERT_CONTEXT pDeferCert = NULL; PCCERT_CONTEXT pAddCert = NULL; PCCERT_CHAIN_CONTEXT pDeferChain = NULL; CERT_CHAIN_PARA DeferChainPara; if (NULL == (hDeferStore = CertOpenStore( CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL))) { PrintLastError("CertOpenStore(DeferClosing)"); goto ErrorReturn; } while (pAddCert = CertEnumCertificatesInStore( wvtCertInfo.pahStores[0], pAddCert)) CertAddCertificateContextToStore( hDeferStore, pAddCert, CERT_STORE_ADD_USE_EXISTING, NULL ); if (!CertAddCertificateContextToStore( hDeferStore, wvtCertInfo.psCertContext, CERT_STORE_ADD_USE_EXISTING, &pDeferCert )) { PrintLastError("CertAddCertificateContextToStore(DeferClosing)"); CertCloseStore(hDeferStore, 0); goto ErrorReturn; } CertCloseStore(hDeferStore, 0); memset(&DeferChainPara, 0, sizeof(DeferChainPara)); DeferChainPara.cbSize = sizeof(DeferChainPara); CertGetCertificateChain( NULL, // hChainEngine pDeferCert, NULL, // pTime hDeferStore, &DeferChainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, // pvReserved &pDeferChain ); CertFreeCertificateContext(pDeferCert); if (pDeferChain) CertFreeCertificateChain(pDeferChain); } break; default: goto BadUsage; } if (fChain) { pwvtActionID = &wvtChainActionID; if (fChainCallback || dwFlags || cUsageOID || cPolicyOID || 0 != dwUrlRetrievalTimeout || fCheckRevocationFreshnessTime) { wvtData.pPolicyCallbackData = (void *) &wtdChainPolicyData; if (fChainCallback) wtdChainPolicyData.pfnPolicyCallback = ChainPolicyCallback; if (dwFlags || cUsageOID || cPolicyOID || 0 != dwUrlRetrievalTimeout || fCheckRevocationFreshnessTime) { ChainInfo.dwFlags = dwFlags; wtdChainPolicyData.pSignerChainInfo = &ChainInfo; wtdChainPolicyData.pCounterSignerChainInfo = &ChainInfo; ChainPara.RequestedUsage.dwType = dwUsageType; ChainPara.RequestedUsage.Usage.cUsageIdentifier = cUsageOID; ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgpszUsageOID; ChainPara.RequestedIssuancePolicy.dwType = dwPolicyUsageType; ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = cPolicyOID; ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = rgpszPolicyOID; ChainPara.dwUrlRetrievalTimeout = dwUrlRetrievalTimeout; ChainPara.fCheckRevocationFreshnessTime = fCheckRevocationFreshnessTime; ChainPara.dwRevocationFreshnessTime = dwRevocationFreshnessTime; } } if (0 != (dwFlags & CERT_CHAIN_CACHE_END_CERT) && WTD_CHOICE_CERT == wvtData.dwUnionChoice) { // Do an extra verify to ensure the cache is loaded on the // next call wvtData.dwStateAction = WTD_STATEACTION_IGNORE; WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); CertFreeCertificateContext(wvtCertInfo.psCertContext); if (NULL == (wvtCertInfo.psCertContext = (CERT_CONTEXT *) ReadCert(pszCertOrFile))) goto ErrorReturn; } } if (fExpectedTrustErrorStatus || fExpectedTrustInfoStatus) wvtData.dwStateAction = WTD_STATEACTION_VERIFY; else if (fQuiet && !fNTAuth) wvtData.dwStateAction = WTD_STATEACTION_IGNORE; else wvtData.dwStateAction = WTD_STATEACTION_VERIFY; if (fInstallDefaultContext) InstallDefaultContext(); if (fSafer) { DWORD dwFlags; BOOL fHasValue; DWORD dwLastError; wvtData.dwProvFlags |= WTD_SAFER_FLAG; lStatus = WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); dwLastError = GetLastError(); fHasValue = I_CryptReadTrustedPublisherDWORDValueFromRegistry( CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME, &dwFlags ); printf("AuthenticodeFlags: "); if (fHasValue) printf("0x%x\n", dwFlags); else printf("NONE\n"); dwFlags = 0; WintrustGetRegPolicyFlags(&dwFlags); printf("WintrustFlags: 0x%x\n", dwFlags); PrintStatus("LastError: ", (LONG) dwLastError); if (wvtFileInfo.pcwszFilePath) { BYTE rgbFileHash[20]; DWORD cbFileHash = 20; ALG_ID HashAlgid = 0; LONG lHashStatus; PCCRYPT_OID_INFO pOIDInfo; lHashStatus = WTHelperGetFileHash( wvtFileInfo.pcwszFilePath, 0, // dwFlags NULL, // pvReserved rgbFileHash, &cbFileHash, &HashAlgid ); PrintStatus("HashStatus: ", lHashStatus); printf("HashAlgid: 0x%x", HashAlgid); pOIDInfo = CryptFindOIDInfo( CRYPT_OID_INFO_ALGID_KEY, &HashAlgid, CRYPT_HASH_ALG_OID_GROUP_ID ); if (pOIDInfo) printf(" %S", pOIDInfo->pwszName); printf("\n"); if (cbFileHash) { PrintBytes("File Hash:: ", rgbFileHash, cbFileHash); } } } else lStatus = WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); if (fExpectedTrustErrorStatus || fExpectedTrustInfoStatus) { if (NULL == (pProvData = WTHelperProvDataFromStateData( wvtData.hWVTStateData))) { printf("TrustStatus:: failed => no WVTStateData\n"); goto ErrorReturn; } fResult = FALSE; if (0 == pProvData->csSigners) printf("TrustStatus:: failed => No Signers\n"); else { CRYPT_PROVIDER_SGNR *pProvSign; pProvSign = WTHelperGetProvSignerFromChain( pProvData, 0, // idxSigner FALSE, // fCounterSigner 0 // idxCounterSigner ); if (pProvSign && pProvSign->pChainContext) { const CERT_TRUST_STATUS *pTrustStatus = &pProvSign->pChainContext->TrustStatus; fResult = TRUE; if (fExpectedTrustErrorStatus) { if (dwExpectedTrustErrorStatus == pTrustStatus->dwErrorStatus) { if (0 != dwExpectedTrustErrorStatus) printf("ChainContext has Expected TrustErrorStatus => 0x%x\n", dwExpectedTrustErrorStatus); } else { fResult = FALSE; printf("Expected => 0x%x ChainContext TrustErrorStatus failed => 0x%x\n", dwExpectedTrustErrorStatus, pTrustStatus->dwErrorStatus ); } } if (fExpectedTrustInfoStatus) { if (dwExpectedTrustInfoStatus == pTrustStatus->dwInfoStatus) { if (0 != dwExpectedTrustInfoStatus) printf("ChainContext has Expected TrustInfoStatus => 0x%x\n", dwExpectedTrustInfoStatus); } else { fResult = FALSE; printf("Expected => 0x%x ChainContext TrustInfoStatus failed => 0x%x\n", dwExpectedTrustInfoStatus, pTrustStatus->dwInfoStatus ); } } if (fMicrosoftRoot || fNotMicrosoftRoot) { // Check if the top level certificate contains the public // key for the Microsoft root. CERT_CHAIN_POLICY_PARA MicrosoftRootPolicyPara; CERT_CHAIN_POLICY_STATUS MicrosoftRootPolicyStatus; memset(&MicrosoftRootPolicyPara, 0, sizeof(MicrosoftRootPolicyPara)); MicrosoftRootPolicyPara.cbSize = sizeof(MicrosoftRootPolicyPara); memset(&MicrosoftRootPolicyStatus, 0, sizeof(MicrosoftRootPolicyStatus)); MicrosoftRootPolicyStatus.cbSize = sizeof(MicrosoftRootPolicyStatus); if (fMicrosoftTestRoot) MicrosoftRootPolicyPara.dwFlags |= MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG; if (!CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_MICROSOFT_ROOT, pProvSign->pChainContext, &MicrosoftRootPolicyPara, &MicrosoftRootPolicyStatus )) { PrintLastError("CERT_CHAIN_POLICY_MICROSOFT_ROOT"); } else { if (fMicrosoftRoot) { if (0 == MicrosoftRootPolicyStatus.dwError) printf("ChainContext has Expected Microsoft Root\n"); else printf("failed => not a Microsoft Root\n"); } if (fNotMicrosoftRoot) { if (0 != MicrosoftRootPolicyStatus.dwError) printf("ChainContext has Expected Not a Microsoft Root\n"); else printf("failed => has a Microsoft Root\n"); } } } } else printf("TrustStatus:: failed => no first signer\n"); } wvtData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); if (fResult) goto SuccessReturn; else goto ErrorReturn; } else if (fQuiet) { if (TRUST_TYPE_DRIVER == dwTrustType) { if (DriverVerInfo.pcSignerCertContext) { CertFreeCertificateContext(DriverVerInfo.pcSignerCertContext); } } if (fNTAuth) { if (NULL == (pProvData = WTHelperProvDataFromStateData( wvtData.hWVTStateData))) { printf("NTAuth:: failed => no WVTStateData\n"); goto ErrorReturn; } fResult = FALSE; if (0 == pProvData->csSigners) printf("NTAuth:: failed => No Signers\n"); else { CRYPT_PROVIDER_SGNR *pProvSign; pProvSign = WTHelperGetProvSignerFromChain( pProvData, 0, // idxSigner FALSE, // fCounterSigner 0 // idxCounterSigner ); if (pProvSign && pProvSign->pChainContext) { if (fNTAuthNameConstraint) fResult = NTAuthNameConstraintVerify( pProvSign->pChainContext, (DWORD) lWVTExpected); else fResult = NTAuthVerify(pProvSign->pChainContext, (DWORD) lWVTExpected); } else printf("NTAuth:: failed => no first signer\n"); } wvtData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); if (fResult) goto SuccessReturn; else goto ErrorReturn; } else if (lStatus == lWVTExpected) { if (ERROR_SUCCESS != lStatus) PrintStatus("WinVerifyTrust returned expected => ", lStatus); goto SuccessReturn; } else { PrintStatus("Expected => ", lWVTExpected); PrintStatus("WinVerifyTrust(Verify) failed => ", lStatus); goto ErrorReturn; } } if (ERROR_SUCCESS != lStatus) { if (fFlushCrl && CERT_E_EXPIRED == lStatus) ; else PrintStatus("WinVerifyTrust(Verify) failed => ", lStatus); } if (NULL == (pProvData = WTHelperProvDataFromStateData( wvtData.hWVTStateData))) { printf("failed => no WVTStateData\n"); goto ErrorReturn; } if (pProvData->dwError) PrintError("Low Level system error: ", pProvData->dwError); for (i = 0; i < pProvData->cdwTrustStepErrors; i++) { if (pProvData->padwTrustStepErrors[i]) { printf(">>>>> Step Error [%d] : ", i); PrintError("", pProvData->padwTrustStepErrors[i]); } } if (TRUST_TYPE_DRIVER == dwTrustType) { if (DriverVerInfo.pcSignerCertContext) { CertFreeCertificateContext(DriverVerInfo.pcSignerCertContext); } printf("Driver version: %S signedBy: %S\n", DriverVerInfo.wszVersion, DriverVerInfo.wszSignedBy); } if (0 == pProvData->csSigners) printf("No Signers\n"); else { DWORD idxSigner; for (idxSigner = 0; idxSigner < pProvData->csSigners; idxSigner++) { CRYPT_PROVIDER_SGNR *pProvSign; printf("====== Signer [%d] ======\n", idxSigner); pProvSign = WTHelperGetProvSignerFromChain( pProvData, idxSigner, FALSE, // fCounterSigner 0 // idxCounterSigner ); if (pProvSign) { DWORD idxCounterSigner; DisplayPeterSigner(pProvSign, dwDisplayFlags); DisplayKirtChain(pProvSign->pChainContext, dwDisplayFlags); if (fNTAuth && !fNTAuthNameConstraint && pProvSign->pChainContext) NTAuthVerify(pProvSign->pChainContext, CERT_E_UNTRUSTEDCA); for (idxCounterSigner = 0; idxCounterSigner < pProvSign->csCounterSigners; idxCounterSigner++) { CRYPT_PROVIDER_SGNR *pProvCounterSign; printf("\n"); printf("====== CounterSigner [%d,%d] ======\n", idxSigner, idxCounterSigner); pProvCounterSign = WTHelperGetProvSignerFromChain( pProvData, idxSigner, TRUE, // fCounterSigner idxCounterSigner ); DisplayPeterSigner(pProvCounterSign, dwDisplayFlags); DisplayKirtChain(pProvCounterSign->pChainContext, dwDisplayFlags); } } } } wvtData.dwStateAction = WTD_STATEACTION_CLOSE; lStatus = WinVerifyTrust( NULL, // hwnd pwvtActionID, &wvtData ); if (ERROR_SUCCESS != lStatus) { PrintStatus("WinVerifyTrust(Close) failed => ", lStatus); goto ErrorReturn; } SuccessReturn: printf("Passed\n"); RegistryOnlyExit: status = 0; CommonReturn: if (fLogoffNotification) { int c; fputs("Waiting to call ChainWlxLogoffEvent ->", stdout); fflush(stdin); fflush(stdout); c = getchar(); ChainWlxLogoffEvent(NULL); fputs("Finished call ->", stdout); fflush(stdin); fflush(stdout); c = getchar(); } if (fInstallDefaultContext) FreeDefaultContext(); while(wvtCertInfo.chStores--) { if (!CertCloseStore(wvtCertInfo.pahStores[wvtCertInfo.chStores], CERT_CLOSE_STORE_CHECK_FLAG)) PrintLastError("CertCloseStore"); } CertFreeCertificateContext(wvtCertInfo.psCertContext); TestFree((LPWSTR) wvtFileInfo.pcwszFilePath); TestFree(httpsPolicyCallbackData.pwszServerName); return status; ErrorReturn: status = -1; printf("Failed\n"); goto CommonReturn; BadUsage: Usage(); goto ErrorReturn; }