|
|
//+-------------------------------------------------------------------------
//
// 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 <windows.h>
#include <assert.h>
#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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
#include <winwlx.h>
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] <filename>\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 <Number>\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 <Number>\n"); printf(" -DisableAIAUrlRetrieval <Number>\n"); printf(" -MaxAIAUrlCountInCert <Number>\n"); printf(" -MaxAIAUrlRetrievalCountPerChain <Number>\n"); printf(" -MaxAIAUrlRetrievalByteCount <Number>\n"); printf(" -MaxAIAUrlRetrievalCertCount <Number>\n"); printf("\n"); printf(" -h - This message\n"); printf(" -b - Brief\n"); printf(" -v - Verbose\n"); printf(" -q[<Number>] - Quiet, expected error\n"); printf(" -e<Number> - Expected trust error status\n"); printf(" -i<Number> - Expected trust info status\n"); printf(" -u<OID String> - Usage OID string -u1.3.6.1.5.5.7.3.3\n"); printf(" -p<OID String> - Policy OID string -u1.3.6.1.5.5.7.3.3\n"); printf(" -s<SystemStore> - Additional System Store\n"); printf(" -S<FileSystemStore> - Additional File System Store\n"); printf(" -n<ServerName> - Https ServerName\n"); printf(" -f<Number> - Flags\n"); printf(" -t<Number> - Url timeout (milliseconds)\n"); printf(" -r<Number> - 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; }
|