Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2450 lines
85 KiB

//+-------------------------------------------------------------------------
//
// 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;
}