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.
 
 
 
 
 
 

2900 lines
63 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: misc.cpp
//
//--------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <setupapi.h>
#include <ocmanage.h>
#include "certsrvd.h"
#include "cscsp.h"
#include "initcert.h"
#include "csprop.h"
#define __dwFILE__ __dwFILE_CERTUTIL_MISC_CPP__
DWORD
cuFileSize(
IN WCHAR const *pwszfn)
{
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesEx(pwszfn, GetFileExInfoStandard, &fad))
{
fad.nFileSizeLow = 0;
}
return(fad.nFileSizeLow);
}
HRESULT
verbHexTranslate(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszfnIn,
IN WCHAR const *pwszfnOut,
IN OPTIONAL IN WCHAR const *pwszType,
IN WCHAR const *pwszArg4)
{
BYTE *pbIn = NULL;
DWORD cbIn;
HRESULT hr;
BOOL fEncode = g_wszEncodeHex == pwszOption;
DWORD dwEncodeFlags;
// Read in and decode the file.
hr = DecodeFileW(
pwszfnIn,
&pbIn,
&cbIn,
fEncode? CRYPT_STRING_BINARY : CRYPT_STRING_HEX_ANY);
if (S_OK != hr)
{
cuPrintError(IDS_ERR_FORMAT_DECODEFILE, hr);
goto error;
}
CSASSERT(NULL != pbIn && 0 != cbIn);
wprintf(
myLoadResourceString(IDS_FORMAT_INPUT_LENGTH), // "Input Length = %d"
cuFileSize(pwszfnIn));
wprintf(wszNewLine);
// Write encoded certificate to file
dwEncodeFlags = CRYPT_STRING_BINARY;
if (fEncode)
{
dwEncodeFlags = CRYPT_STRING_HEXASCIIADDR;
if (NULL != pwszType)
{
BOOL fValid;
dwEncodeFlags = myWtoI(pwszType, &fValid);
if (!fValid)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "bad encoding type");
}
}
dwEncodeFlags |= g_CryptEncodeFlags;
}
hr = EncodeToFileW(pwszfnOut, pbIn, cbIn, dwEncodeFlags | g_EncodeFlags);
if (S_OK != hr)
{
cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
goto error;
}
wprintf(
myLoadResourceString(IDS_FORMAT_OUTPUT_LENGTH), // "Output Length = %d"
cuFileSize(pwszfnOut));
wprintf(wszNewLine);
error:
if (NULL != pbIn)
{
LocalFree(pbIn);
}
return(hr);
}
// If a CRL, return CRYPT_STRING_BASE64X509CRLHEADER.
// If a cert or an empty PKCS7 with at least one cert, return
// CRYPT_STRING_BASE64HEADER.
// Otherwise, return CRYPT_STRING_BASE64REQUESTHEADER
HRESULT
GetBase64EncodeFlags(
IN BYTE const *pbIn,
IN DWORD cbIn,
OUT DWORD *pdwEncodeFlags)
{
HRESULT hr;
*pdwEncodeFlags = CRYPT_STRING_BASE64HEADER;
// Try as a Cert:
{
CERT_CONTEXT const *pCertContext;
pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING,
pbIn,
cbIn);
if (NULL != pCertContext)
{
CertFreeCertificateContext(pCertContext);
goto error;
}
}
// Try as a CRL:
{
CRL_CONTEXT const *pCRLContext;
pCRLContext = CertCreateCRLContext(X509_ASN_ENCODING, pbIn, cbIn);
if (NULL != pCRLContext)
{
CertFreeCRLContext(pCRLContext);
*pdwEncodeFlags = CRYPT_STRING_BASE64X509CRLHEADER;
goto error;
}
}
// Try as a PKCS10, KeyGen or CMC request
{
BYTE *pbDecoded;
DWORD cbDecoded;
DWORD i;
char const *rgpszStructType[] = {
X509_CERT_REQUEST_TO_BE_SIGNED,
X509_KEYGEN_REQUEST_TO_BE_SIGNED,
CMC_DATA,
};
for (i = 0; i < ARRAYSIZE(rgpszStructType); i++)
{
if (myDecodeObject(
X509_ASN_ENCODING,
rgpszStructType[i],
pbIn,
cbIn,
CERTLIB_USE_LOCALALLOC,
(VOID **) &pbDecoded,
&cbDecoded))
{
LocalFree(pbDecoded);
*pdwEncodeFlags = CRYPT_STRING_BASE64REQUESTHEADER;
goto error;
}
}
}
// Recurse on the PKCS7 to examine the innermost content
{
BYTE *pbContents;
DWORD cbContents;
DWORD dwMsgType;
DWORD cRecipient;
hr = myDecodePKCS7(
pbIn,
cbIn,
&pbContents,
&cbContents,
&dwMsgType,
NULL,
NULL,
&cRecipient,
NULL,
NULL);
if (S_OK == hr)
{
if (CMSG_SIGNED == dwMsgType &&
NULL != pbContents &&
0 != cbContents &&
0 == cRecipient)
{
DWORD dwEncodeFlags;
hr = GetBase64EncodeFlags(
pbContents,
cbContents,
pdwEncodeFlags);
_JumpIfError(hr, error, "GetBase64EncodeFlags");
}
}
}
error:
hr = S_OK;
return(hr);
}
HRESULT
verbBase64Translate(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszfnIn,
IN WCHAR const *pwszfnOut,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
BYTE *pbIn = NULL;
DWORD cbIn;
HRESULT hr;
BOOL fEncode = g_wszEncode == pwszOption;
DWORD dwEncodeFlags;
// Read in and decode the file.
hr = DecodeFileW(
pwszfnIn,
&pbIn,
&cbIn,
fEncode? CRYPT_STRING_BINARY : CRYPT_STRING_BASE64_ANY);
if (S_OK != hr)
{
cuPrintError(IDS_ERR_FORMAT_DECODEFILE, hr);
goto error;
}
CSASSERT(NULL != pbIn && 0 != cbIn);
dwEncodeFlags = CRYPT_STRING_BINARY;
if (fEncode)
{
hr = GetBase64EncodeFlags(pbIn, cbIn, &dwEncodeFlags);
_JumpIfError(hr, error, "GetBase64EncodeFlags");
dwEncodeFlags |= g_CryptEncodeFlags;
}
wprintf(
myLoadResourceString(IDS_FORMAT_INPUT_LENGTH), // "Input Length = %d"
cuFileSize(pwszfnIn));
wprintf(wszNewLine);
// Write encoded certificate to file
hr = EncodeToFileW(
pwszfnOut,
pbIn,
cbIn,
dwEncodeFlags | g_EncodeFlags);
if (S_OK != hr)
{
cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
goto error;
}
wprintf(
myLoadResourceString(IDS_FORMAT_OUTPUT_LENGTH), // "Output Length = %d"
cuFileSize(pwszfnOut));
wprintf(wszNewLine);
error:
if (NULL != pbIn)
{
LocalFree(pbIn);
}
return(hr);
}
HRESULT
TestCSP(
IN WCHAR const *pwszProvName,
IN DWORD const dwProvType,
OPTIONAL WCHAR const *pwszKeyContainer)
{
HRESULT hr;
HCRYPTPROV hProv = NULL;
DWORD dwFlags = 0;
if (NULL == pwszKeyContainer)
{
dwFlags |= CRYPT_VERIFYCONTEXT;
}
if (g_fCryptSilent)
{
dwFlags |= CRYPT_SILENT;
}
wprintf(
L"CryptAcquireContext(%ws, %ws, %d, 0x%x)\n",
NULL == pwszKeyContainer? L"Verify" : pwszKeyContainer,
pwszProvName,
dwProvType,
dwFlags);
if (!myCertSrvCryptAcquireContext(
&hProv,
pwszKeyContainer,
pwszProvName,
dwProvType,
dwFlags,
!g_fUserRegistry)) // fMachineKeyset
{
hr = myHLastError();
cuPrintError(0, hr);
_JumpErrorStr(hr, error, "myCertSrvCryptAcquireContext", pwszProvName);
}
wprintf(L"%ws\n", myLoadResourceString(IDS_PASS)); // "Pass"
hr = S_OK;
error:
if (NULL != hProv)
{
CryptReleaseContext(hProv, 0);
}
return hr;
}
HRESULT
EnumAndTestCSP(
IN BOOL const fTest)
{
HRESULT hr;
DWORD i;
DWORD dwProvType;
WCHAR *pwszProvName = NULL;
BOOL fFirst = TRUE;
for (i = 0; ; i++)
{
hr = myEnumProviders(i, NULL, 0, &dwProvType, &pwszProvName);
if (S_OK != hr)
{
if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ||
NTE_FAIL == hr)
{
// no more providers under type, terminate loop
break;
}
// invalid csp entry, skip it
wprintf(myLoadResourceString(IDS_FORMAT_SKIP_CSP_ENUM), i);
wprintf(wszNewLine);
}
else
{
if (!fFirst)
{
wprintf(wszNewLine);
}
fFirst = FALSE;
wprintf(myLoadResourceString(IDS_PROVIDER_NAME_COLON));
wprintf(L" %ws\n", pwszProvName);
wprintf(myLoadResourceString(IDS_PROVIDER_TYPE_COLON));
wprintf(L" %d\n", dwProvType);
if (fTest)
{
hr = TestCSP(pwszProvName, dwProvType, NULL);
}
LocalFree(pwszProvName);
pwszProvName = NULL;
}
}
hr = S_OK;
//error:
if (NULL != pwszProvName)
{
LocalFree(pwszProvName);
}
return(hr);
}
HRESULT
verbCSPList(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszArg1,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
return EnumAndTestCSP(FALSE);
}
HRESULT
verbCSPTest(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszKeyContainer,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
DWORD dwProvType;
if (NULL != g_pwszCSP)
{
// get prov type
hr = csiGetProviderTypeFromProviderName(g_pwszCSP, &dwProvType);
_JumpIfError(hr, error, "GetProviderTypeFromProviderName");
hr = TestCSP(g_pwszCSP, dwProvType, pwszKeyContainer);
_JumpIfError(hr, error, "TestCSP");
}
else
{
hr = EnumAndTestCSP(TRUE);
_JumpIfError(hr, error, "EnumAndTestCSP");
}
error:
return(hr);
}
UINT enumCATypeRscMap[] =
{
IDS_ENTERPRISE_ROOT, // ENUM_ENTERPRISE_ROOT = 0
IDS_ENTERPRISE_SUB, // ENUM_ENTERPRISE_SUBCA = 1
IDS_CATYPE_UNKNOWN, // ENUM_UNUSED2 = 2
IDS_STANDALONE_ROOT, // ENUM_STANDALONE_ROOTCA = 3
IDS_STANDALONE_SUB, // ENUM_STANDALONE_SUBCA = 4
// ENUM_UNKNOWN_CA = 5
};
typedef struct _CAINFOTABLE
{
WCHAR const *pwszCmdLineName;
LONG lPropId;
LONG lPropType;
UINT ids;
DWORD dwGetCert;
DWORD Flags;
WCHAR const *pwszRegName;
} CAINFOTABLE;
#define CAITF_FLAGSARG 0x00000001
#define CAITF_INDEXARGMAXDWORD 0x00000002 // default index is MAXDWORD
#define CAITF_INDEXARGZERO 0x00000004 // default index is 0
#define CAITF_INDEXARGREQUIRED 0x00000008 // index required
#define CAITF_SIGCERTCOUNT 0x00000010 // cCASigCert elements
#define CAITF_XCHGCERTCOUNT 0x00000020 // cCAXchgCert elements
#define CAITF_KRACERTCOUNT 0x00000040 // cCAXchgCert elements
#define CAITF_EXITCOUNT 0x00000080 // exit mod count elements
#define CAITF_ASN 0x00000100 // contains dumpable ASN object
#define CAITF_DEFAULT 0x00000200 // default (unnamed) set
#define CAITF_SKIPINVALIDARG 0x00000400 // skip if multiple & E_INVALIDARG
#define CAITF_SKIP 0x00000800 // skip when enumerating all
#define CAITF_OPTIONAL 0x00001000 // not always available
#define CAITF_CRLSTATE 0x00002000 // depends on CRL state
#define CAITF_FORWARDCROSSCERTSTATE 0x00004000 // depends on fwd cross state
#define CAITF_BACKWARDCROSSCERTSTATE 0x00008000 // depends on rev cross state
#define CAITF_INDEXARG (CAITF_INDEXARGMAXDWORD | \
CAITF_INDEXARGZERO | \
CAITF_INDEXARGREQUIRED)
WCHAR const g_wszCAInfoCRL[] = L"crl";
WCHAR const g_wszCAInfoCert[] = L"cert";
WCHAR const g_wszCAInfoCertChain[] = L"certchain";
WCHAR const g_wszCAInfoName[] = L"name";
WCHAR const g_wszCAInfoSanitizedName[] = L"sanitizedname";
WCHAR const g_wszCAInfoDSName[] = L"dsname";
#define GETCERT_UNSUPPORTED MAXDWORD // not supported by old ICertRequest
CAINFOTABLE g_aCAInfoTable[] =
{
{
L"file",
CR_PROP_FILEVERSION,
PROPTYPE_STRING,
IDS_PROP_FILEVERSION,
GETCERT_FILEVERSION,
0,
NULL,
},
{
L"product",
CR_PROP_PRODUCTVERSION,
PROPTYPE_STRING,
IDS_PROP_PRODUCTVERSION,
GETCERT_PRODUCTVERSION,
0,
NULL,
},
{
L"exitcount",
CR_PROP_EXITCOUNT,
PROPTYPE_LONG,
IDS_PROP_EXITCOUNT,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT,
NULL,
},
{
L"exit",
CR_PROP_EXITDESCRIPTION,
PROPTYPE_STRING,
IDS_PROP_EXITDESCRIPTION,
GETCERT_EXITVERSIONBYINDEX,
CAITF_INDEXARGZERO | CAITF_EXITCOUNT,
NULL,
},
{
L"policy",
CR_PROP_POLICYDESCRIPTION,
PROPTYPE_STRING,
IDS_PROP_POLICYDESCRIPTION,
GETCERT_POLICYVERSION,
0,
NULL,
},
{
g_wszCAInfoName,
CR_PROP_CANAME,
PROPTYPE_STRING,
IDS_PROP_CANAME,
GETCERT_CANAME,
CAITF_DEFAULT,
NULL,
},
{
g_wszCAInfoSanitizedName,
CR_PROP_SANITIZEDCANAME,
PROPTYPE_STRING,
IDS_PROP_SANITIZEDCANAME,
GETCERT_SANITIZEDCANAME,
0,
NULL,
},
{
g_wszCAInfoDSName,
CR_PROP_SANITIZEDCASHORTNAME,
PROPTYPE_STRING,
IDS_PROP_SANITIZEDCASHORTNAME,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT | CAITF_OPTIONAL,
NULL,
},
{
L"sharedfolder",
CR_PROP_SHAREDFOLDER,
PROPTYPE_STRING,
IDS_PROP_SHAREDFOLDER,
GETCERT_SHAREDFOLDER,
CAITF_OPTIONAL,
NULL,
},
{
L"error1",
CR_PROP_NONE, // separate method call in ICertRequest2
PROPTYPE_STRING,
IDS_PROP_ERROR1,
GETCERT_ERRORTEXT1,
CAITF_FLAGSARG | CAITF_SKIP,
NULL,
},
{
L"error2",
CR_PROP_NONE, // separate method call in ICertRequest2
PROPTYPE_STRING,
IDS_PROP_ERROR2,
GETCERT_ERRORTEXT2,
CAITF_FLAGSARG | CAITF_SKIP,
NULL,
},
{
L"type",
CR_PROP_CATYPE,
PROPTYPE_LONG,
IDS_PROP_CATYPE,
GETCERT_CATYPE,
CAITF_DEFAULT,
wszPROPCATYPE,
},
{
L"info",
CR_PROP_NONE, // not supported by ICertRequest2
PROPTYPE_BINARY,
IDS_PROP_CAINFO,
GETCERT_CAINFO,
0,
NULL,
},
{
L"parent",
CR_PROP_PARENTCA,
PROPTYPE_STRING,
IDS_PROP_PARENTCA,
GETCERT_PARENTCONFIG,
CAITF_OPTIONAL,
NULL,
},
{
L"certcount",
CR_PROP_CASIGCERTCOUNT,
PROPTYPE_LONG,
IDS_PROP_CASIGCERTCOUNT,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT,
NULL,
},
{
L"xchgcount",
CR_PROP_CAXCHGCERTCOUNT,
PROPTYPE_LONG,
IDS_PROP_CAXCHGCERTCOUNT,
GETCERT_UNSUPPORTED,
0,
NULL,
},
{
L"kracount",
CR_PROP_KRACERTCOUNT,
PROPTYPE_LONG,
IDS_PROP_KRACERTCOUNT,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT,
NULL,
},
{
L"kraused",
CR_PROP_KRACERTUSEDCOUNT,
PROPTYPE_LONG,
IDS_PROP_KRACERTUSEDCOUNT,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT,
NULL,
},
{
L"propidmax",
CR_PROP_CAPROPIDMAX,
PROPTYPE_LONG,
IDS_PROP_CAPROPIDMAX,
GETCERT_UNSUPPORTED,
0,
NULL,
},
// Cert and CRL state:
{
L"certstate",
CR_PROP_CACERTSTATE,
PROPTYPE_LONG,
IDS_PROP_CACERTSTATE,
GETCERT_CACERTSTATEBYINDEX,
CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
NULL,
},
{
L"certversion",
CR_PROP_CACERTVERSION,
PROPTYPE_LONG,
IDS_PROP_CACERTVERSION,
GETCERT_UNSUPPORTED,
CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
NULL,
},
{
L"certstatuscode",
CR_PROP_CACERTSTATUSCODE,
PROPTYPE_LONG,
IDS_PROP_CACERSTATUSCODE,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
NULL,
},
{
L"crlstate",
CR_PROP_CRLSTATE,
PROPTYPE_LONG,
IDS_PROP_CRLSTATE,
GETCERT_CRLSTATEBYINDEX,
CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
NULL,
},
{
L"krastate",
CR_PROP_KRACERTSTATE,
PROPTYPE_LONG,
IDS_PROP_KRACERTSTATE,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGZERO | CAITF_KRACERTCOUNT | CAITF_DEFAULT,
NULL,
},
{
L"crossstate+",
CR_PROP_CAFORWARDCROSSCERTSTATE,
PROPTYPE_LONG,
IDS_PROP_CAFORWARDCROSSCERTSTATE,
GETCERT_UNSUPPORTED,
CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT,
NULL,
},
{
L"crossstate-",
CR_PROP_CABACKWARDCROSSCERTSTATE,
PROPTYPE_LONG,
IDS_PROP_CABACKWARDCROSSCERTSTATE,
GETCERT_UNSUPPORTED,
CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT,
NULL,
},
// Signature certs:
{
g_wszCAInfoCert, // L"cert"
CR_PROP_CASIGCERT,
PROPTYPE_BINARY,
IDS_PROP_CASIGCERT,
GETCERT_CACERTBYINDEX, // GETCERT_CASIGCERT handled by code hack
CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
{
g_wszCAInfoCertChain, // L"certchain"
CR_PROP_CASIGCERTCHAIN,
PROPTYPE_BINARY,
IDS_PROP_CASIGCERTCHAIN,
GETCERT_CACERTBYINDEX | GETCERT_CHAIN, // GETCERT_CASIGCERT | GETCERT_CHAIN handled by code hack
CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"certcrlchain",
CR_PROP_CASIGCERTCRLCHAIN,
PROPTYPE_BINARY,
IDS_PROP_CASIGCERTCRLCHAIN,
GETCERT_CACERTBYINDEX | GETCERT_CHAIN | GETCERT_CRLS,
CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
// Exchange certs:
{
L"xchg",
CR_PROP_CAXCHGCERT,
PROPTYPE_BINARY,
IDS_PROP_CAXCHGCERT,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"xchgchain",
CR_PROP_CAXCHGCERTCHAIN,
PROPTYPE_BINARY,
IDS_PROP_CAXCHGCERTCHAIN,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"xchgcrlchain",
CR_PROP_CAXCHGCERTCRLCHAIN,
PROPTYPE_BINARY,
IDS_PROP_CAXCHGCERTCRLCHAIN,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
NULL,
},
// KRA certs:
{
L"kra",
CR_PROP_KRACERT,
PROPTYPE_BINARY,
IDS_PROP_KRACERT,
GETCERT_UNSUPPORTED,
CAITF_INDEXARGMAXDWORD | CAITF_KRACERTCOUNT | CAITF_ASN,
NULL,
},
// Cross certs:
{
L"cross+",
CR_PROP_CAFORWARDCROSSCERT,
PROPTYPE_BINARY,
IDS_PROP_CAFORWARDCROSSCERT,
GETCERT_UNSUPPORTED,
CAITF_FORWARDCROSSCERTSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"cross-",
CR_PROP_CABACKWARDCROSSCERT,
PROPTYPE_BINARY,
IDS_PROP_CABACKWARDCROSSCERT,
GETCERT_UNSUPPORTED,
CAITF_BACKWARDCROSSCERTSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
// CRLs:
{
g_wszCAInfoCRL, // L"CRL"
CR_PROP_BASECRL,
PROPTYPE_BINARY,
IDS_PROP_BASECRL,
GETCERT_CRLBYINDEX, // GETCERT_CURRENTCRL handled by code hack
CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"deltacrl",
CR_PROP_DELTACRL,
PROPTYPE_BINARY,
IDS_PROP_DELTACRL,
GETCERT_UNSUPPORTED,
CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
NULL,
},
{
L"crlstatus",
CR_PROP_BASECRLPUBLISHSTATUS,
PROPTYPE_LONG,
IDS_PROP_BASECRLPUBLISHSTATUS,
GETCERT_UNSUPPORTED,
CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT | CAITF_OPTIONAL,
wszPROPCRLPUBLISHFLAGS,
},
{
L"deltacrlstatus",
CR_PROP_DELTACRLPUBLISHSTATUS,
PROPTYPE_LONG,
IDS_PROP_DELTACRLPUBLISHSTATUS,
GETCERT_UNSUPPORTED,
CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT | CAITF_OPTIONAL,
wszPROPCRLPUBLISHFLAGS,
},
{
L"dns",
CR_PROP_DNSNAME,
PROPTYPE_STRING,
IDS_PROP_DNSNAME,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT | CAITF_OPTIONAL,
NULL,
},
{
L"role",
CR_PROP_ROLESEPARATIONENABLED,
PROPTYPE_LONG,
IDS_PROP_ROLESEPARATIONENABLED,
GETCERT_UNSUPPORTED,
CAITF_OPTIONAL | CAITF_SKIP,
NULL,
},
{
L"ads",
CR_PROP_ADVANCEDSERVER,
PROPTYPE_LONG,
IDS_PROP_ADVANCEDSERVER,
GETCERT_UNSUPPORTED,
CAITF_DEFAULT | CAITF_OPTIONAL,
NULL,
},
{
L"templates",
CR_PROP_TEMPLATES,
PROPTYPE_STRING,
IDS_PROP_TEMPLATES,
GETCERT_UNSUPPORTED,
CAITF_SKIPINVALIDARG | CAITF_OPTIONAL,
NULL,
},
{
NULL,
},
};
typedef HRESULT (FNPROP_INIT)(
IN DWORD Flags,
IN OUT DISPATCHINTERFACE *pdiProp);
typedef VOID (FNPROP_RELEASE)(
IN OUT DISPATCHINTERFACE *pdiProp);
typedef HRESULT (FNPROP2_GETCAPROPERTY)(
IN DISPATCHINTERFACE *pdiRequest,
IN WCHAR const *pwszConfig,
IN LONG PropId,
IN LONG PropIndex,
IN LONG PropType,
IN LONG Flags,
OUT VOID *pPropertyValue);
typedef HRESULT (FNPROP2_GETCAPROPERTYFLAGS)(
IN DISPATCHINTERFACE *pdiProp,
IN WCHAR const *pwszConfig,
IN LONG PropId,
OUT LONG *pPropFlags);
typedef HRESULT (FNPROP2_GETCAPROPERTYDISPLAYNAME)(
IN DISPATCHINTERFACE *pdiProp,
IN WCHAR const *pwszConfig,
IN LONG PropId,
OUT BSTR *pstrDisplayName);
FNPROP_INIT *g_pfnProp_Init;
FNPROP_RELEASE *g_pfnProp_Release;
FNPROP2_GETCAPROPERTY *g_pfnProp2_GetCAProperty;
FNPROP2_GETCAPROPERTYFLAGS *g_pfnProp2_GetCAPropertyFlags;
FNPROP2_GETCAPROPERTYDISPLAYNAME *g_pfnProp2_GetCAPropertyDisplayName;
VOID
InitPropFunctionPointers(VOID)
{
if (g_fAdminInterface)
{
g_pfnProp_Init = Admin_Init;
g_pfnProp_Release = Admin_Release;
g_pfnProp2_GetCAProperty = Admin2_GetCAProperty;
g_pfnProp2_GetCAPropertyFlags = Admin2_GetCAPropertyFlags;
g_pfnProp2_GetCAPropertyDisplayName = Admin2_GetCAPropertyDisplayName;
}
else
{
g_pfnProp_Init = Request_Init;
g_pfnProp_Release = Request_Release;
g_pfnProp2_GetCAProperty = Request2_GetCAProperty;
g_pfnProp2_GetCAPropertyFlags = Request2_GetCAPropertyFlags;
g_pfnProp2_GetCAPropertyDisplayName = Request2_GetCAPropertyDisplayName;
}
}
VOID
cuCAInfoUsage(VOID)
{
CAINFOTABLE const *pcait;
UINT id;
wprintf(wszNewLine);
wprintf(L" %ws\n", myLoadResourceString(IDS_CAINFO_USAGEHEADERCOLON)); // "InfoName argument values:"
for (pcait = g_aCAInfoTable; NULL != pcait->pwszCmdLineName; pcait++)
{
id = 0;
wprintf(L"\t%ws", pcait->pwszCmdLineName);
if (CAITF_FLAGSARG & pcait->Flags)
{
id = IDS_CAINFO_USAGEERROR;
}
if (CAITF_INDEXARG & pcait->Flags)
{
id = IDS_CAINFO_USAGEINDEX;
}
if (0 != id)
{
wprintf(L" %ws", myLoadResourceString(id));
}
wprintf(L" -- %ws", myLoadResourceString(pcait->ids));
wprintf(wszNewLine);
}
}
BOOL
cuParseDecimal(
IN OUT WCHAR const **ppwc,
IN OUT DWORD *pcwc,
OUT DWORD *pdw)
{
BOOL fFound = FALSE;
WCHAR const *pwc = *ppwc;
DWORD cwc = *pcwc;
DWORD dw = 0;
while (0 != cwc && iswdigit(*pwc))
{
dw = (10 * dw) + *pwc++ - L'0';
cwc--;
fFound = TRUE;
}
if (fFound && 0 != cwc && L',' == *pwc)
{
pwc++;
cwc--;
}
*ppwc = pwc;
*pcwc = cwc;
*pdw = dw;
return(fFound);
}
UINT enumDispositionResourceMap[] =
{
IDS_CADISP_INCOMPLETE, // CA_DISP_INCOMPLETE = 0
IDS_CADISP_ERROR, // CA_DISP_ERROR = 1
//IDS_CADISP_ERROR_CRL, // CA_DISP_ERROR = 1
IDS_CADISP_REVOKED, // CA_DISP_REVOKED = 2
IDS_CADISP_VALID, // CA_DISP_VALID = 3
IDS_CADISP_EXPIRED, // CA_DISP_INVALID = 4
IDS_CADISP_UNDERSUBMISSION, // CA_DISP_UNDER_SUBMISSION = 5
//IDS_CADISP_UNKNOWN, // ???
};
VOID
DisplayCAState(
IN LONG lPropId,
IN DWORD State)
{
UINT id;
CSASSERT(
CR_PROP_CACERTSTATE == lPropId ||
CR_PROP_CRLSTATE == lPropId ||
CR_PROP_CAFORWARDCROSSCERTSTATE == lPropId ||
CR_PROP_CABACKWARDCROSSCERTSTATE == lPropId);
id = IDS_CADISP_UNKNOWN;
if (ARRAYSIZE(enumDispositionResourceMap) > State)
{
id = enumDispositionResourceMap[State];
if (IDS_CADISP_ERROR == id && CR_PROP_CRLSTATE == lPropId)
{
id = IDS_CADISP_ERROR_CRL; // "Error: No CRL for this Cert"
}
}
wprintf(L" -- %ws", myLoadResourceString(id)); // "Valid", etc.
wprintf(wszNewLine);
}
VOID
DisplayCAVersion(
IN LONG longValue)
{
wprintf(
L" -- V%u.%u\n",
CANAMEIDTOICERT(longValue),
CANAMEIDTOIKEY(longValue));
}
UINT enumKRADispositionResourceMap[] =
{
IDS_CADISP_EXPIRED, // KRA_DISP_EXPIRED = 0
IDS_KRADISP_NOTFOUND, // KRA_DISP_NOTFOUND = 1
IDS_CADISP_REVOKED, // KRA_DISP_REVOKED = 2
IDS_CADISP_VALID, // KRA_DISP_VALID = 3
IDS_KRADISP_INVALID, // KRA_DISP_INVALID = 4
IDS_KRADISP_UNTRUSTED, // KRA_DISP_UNTRUSTED = 5
IDS_KRADISP_NOTLOADED, // KRA_DISP_NOTLOADED = 6
//IDS_CADISP_UNKNOWN, // ???
};
VOID
DisplayKRAState(
IN DWORD State)
{
UINT id;
id = IDS_CADISP_UNKNOWN;
if (ARRAYSIZE(enumKRADispositionResourceMap) > State)
{
id = enumKRADispositionResourceMap[State];
}
wprintf(L" -- %ws", myLoadResourceString(id)); // "Valid", etc.
wprintf(wszNewLine);
}
VOID
cuDisplayCAType(
IN LONG CAType)
{
UINT uid;
if (CAType >= ARRAYSIZE(enumCATypeRscMap))
{
uid = IDS_CATYPE_UNKNOWN;
}
else
{
uid = enumCATypeRscMap[CAType];
}
wprintf(myLoadResourceString(uid), CAType);
wprintf(wszNewLine);
}
//+-------------------------------------------------------------------------
// cuGetCAInfoPropertyByIndex -- display one CA Property for one index value.
//
//--------------------------------------------------------------------------
HRESULT
cuGetCAInfoPropertyByIndex(
OPTIONAL IN WCHAR const *pwszOption,
OPTIONAL IN WCHAR const *pwszfnOut,
OPTIONAL IN WCHAR const *pwszInfoName,
OPTIONAL IN LONG const *pPropIndex,
IN CAINFOTABLE const *pcait,
IN OUT DISPATCHINTERFACE *pdiProp,
IN BOOL fV1,
IN BOOL fDisplayResult,
OPTIONAL OUT DWORD *pdwValue)
{
HRESULT hr;
BYTE *pbBinary = NULL;
DWORD cbBinary;
DWORD dwGetCertType;
DWORD Format;
DWORD Index = 0;
DWORD IndexV1 = 0;
LONG longValue;
BSTR strValue = NULL;
BOOL fVerbose = FALSE;
BOOL fVerboseOld = g_fVerbose;
BOOL fDisplayed = FALSE;
if (NULL != pdwValue)
{
*pdwValue = MAXDWORD;
}
if (g_fVerbose)
{
g_fVerbose--;
fVerbose = TRUE;
}
dwGetCertType = pcait->dwGetCert;
if ((CAITF_INDEXARG | CAITF_FLAGSARG) & pcait->Flags)
{
if (NULL == pPropIndex)
{
if ((CAITF_INDEXARGREQUIRED | CAITF_FLAGSARG) & pcait->Flags)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "missing numeric arg");
}
if (CAITF_INDEXARGMAXDWORD & pcait->Flags)
{
Index = MAXDWORD;
}
switch (pcait->lPropId)
{
case CR_PROP_BASECRL:
dwGetCertType = GETCERT_CURRENTCRL;
break;
case CR_PROP_CASIGCERT:
dwGetCertType = GETCERT_CASIGCERT;
break;
case CR_PROP_CASIGCERTCHAIN:
dwGetCertType = GETCERT_CASIGCERT | GETCERT_CHAIN;
break;
}
}
else
{
Index = *pPropIndex;
IndexV1 = Index;
}
if (0 == (CAITF_FLAGSARG & pcait->Flags))
{
if (GETCERT_INDEXVALUEMASK < IndexV1)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "index too large");
}
CSASSERT(
0 == IndexV1 ||
GETCERT_UNSUPPORTED == dwGetCertType ||
0 == (GETCERT_INDEXVALUEMASK & dwGetCertType));
}
}
else
{
if (NULL != pPropIndex)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "too many args");
}
}
if (!fV1)
{
if (CR_PROP_NONE != pcait->lPropId)
{
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
pcait->lPropId,
Index,
pcait->lPropType,
PROPTYPE_BINARY == pcait->lPropType?
CV_OUT_BASE64HEADER : CV_OUT_BINARY,
PROPTYPE_LONG == pcait->lPropType?
(VOID *) &longValue : (VOID *) &strValue);
if (E_NOTIMPL != hr && RPC_E_VERSION_MISMATCH != hr)
{
_JumpIfError2(hr, error, "g_pfnProp2_GetCAProperty", hr);
}
else
{
fV1 = TRUE;
}
}
else
{
fV1 = TRUE;
}
}
if (fV1)
{
DWORD FlagsV1;
if (g_fAdminInterface || GETCERT_UNSUPPORTED == dwGetCertType)
{
hr = E_NOTIMPL;
_JumpIfError(hr, error, "ICertRequest2 required");
}
if (CAITF_FLAGSARG & pcait->Flags)
{
FlagsV1 = IndexV1;
IndexV1 = 0;
}
else
{
FlagsV1 = (CAITF_ASN & pcait->Flags)?
CR_OUT_BASE64HEADER : CR_OUT_BINARY;
if (g_wszCAChain == pwszOption)
{
FlagsV1 |= CR_OUT_CHAIN;
}
}
hr = Request_GetCACertificate(
pdiProp,
dwGetCertType | IndexV1, // fExchangeCertificate
g_pwszConfig,
FlagsV1,
&strValue);
_JumpIfError2(
hr,
error,
"Request_GetCACertificate",
(CAITF_OPTIONAL & pcait->Flags)?
HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) : S_OK);
// Build up a nice debug print:
if (fVerbose)
{
WCHAR wszArg[5 + cwcDWORDSPRINTF];
switch (dwGetCertType)
{
case GETCERT_CASIGCERT:
wcscpy(wszArg, L"SignatureCert");
break;
case GETCERT_CAXCHGCERT:
wcscpy(wszArg, L"ExchangeCert");
break;
case GETCERT_CACERTBYINDEX:
case GETCERT_CRLBYINDEX:
case GETCERT_CACERTSTATEBYINDEX:
case GETCERT_CRLSTATEBYINDEX:
case GETCERT_EXITVERSIONBYINDEX:
swprintf(
wszArg,
L"\"%c%c.%d\"",
((char *) &dwGetCertType)[3],
((char *) &dwGetCertType)[2],
Index);
break;
default:
swprintf(
wszArg,
L"\"%c%c%c%c\"",
((char *) &dwGetCertType)[3],
((char *) &dwGetCertType)[2],
((char *) &dwGetCertType)[1],
((char *) &dwGetCertType)[0]);
break;
}
wprintf(L"GetCACertificate(%ws):\n%ws\n", wszArg, strValue);
}
if (PROPTYPE_LONG == pcait->lPropType)
{
DWORD cwc = wcslen(strValue);
WCHAR const *pwc = strValue;
if (!cuParseDecimal(&pwc, &cwc, (DWORD *) &longValue))
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
_JumpErrorStr(hr, error, "bad decimal number", strValue);
}
}
}
// At this point:
// if PROPTYPE_LONG, the value is in longValue,
// if PROPTYPE_STRING, the value is in strValue
// if PROPTYPE_BINARY, the base64-encoded string is in strValue
if (PROPTYPE_LONG == pcait->lPropType && NULL != pdwValue)
{
*pdwValue = longValue;
}
if ((CAITF_ASN & pcait->Flags))
{
hr = myCryptStringToBinary(
strValue,
0,
CRYPT_STRING_BASE64HEADER,
&pbBinary,
&cbBinary,
NULL,
NULL);
_JumpIfError(hr, error, "myCryptStringToBinary");
if (fVerbose)
{
hr = cuDumpAsnBinary(pbBinary, cbBinary, MAXDWORD);
_JumpIfError(hr, error, "cuDumpAsnBinary");
}
}
switch (pcait->lPropId)
{
case CR_PROP_NONE:
{
switch (dwGetCertType)
{
case GETCERT_ERRORTEXT1:
case GETCERT_ERRORTEXT2:
wprintf(
myLoadResourceString(IDS_FORMAT_MESSAGE_TEXT), // "Error message text: %ws"
L"");
wprintf(L"%ws\n", strValue);
fDisplayed = TRUE;
break;
// prettyprint CA Type/CA Info
case GETCERT_CAINFO:
{
DWORD cwc = wcslen(strValue);
WCHAR const *pwc = strValue;
CAINFO CAInfo;
if (cuParseDecimal(&pwc, &cwc, (DWORD *) &CAInfo.CAType))
{
if (NULL != pwszInfoName &&
0 != lstrcmp(L"*", pwszInfoName))
{
cuDisplayCAType(CAInfo.CAType);
}
if (cuParseDecimal(&pwc, &cwc, &CAInfo.cCASignatureCerts))
{
wprintf(
myLoadResourceString(IDS_FORMAT_CCACERTS),
CAInfo.cCASignatureCerts);
wprintf(wszNewLine);
}
}
fDisplayed = TRUE;
break;
}
}
break;
}
}
if (!fDisplayed && fDisplayResult)
{
wprintf(L"%ws", myLoadResourceString(pcait->ids));
if (NULL != pPropIndex)
{
wprintf(L"[%d]", *pPropIndex);
}
if (PROPTYPE_LONG == pcait->lPropType)
{
if (0 > longValue || 9 < longValue)
{
wprintf(L": 0x%x (%d)", longValue, longValue);
}
else
{
wprintf(L": %x", longValue);
}
switch (pcait->lPropId)
{
// prettyprint Cert/CRL State
case CR_PROP_CACERTSTATE:
case CR_PROP_CRLSTATE:
case CR_PROP_CAFORWARDCROSSCERTSTATE:
case CR_PROP_CABACKWARDCROSSCERTSTATE:
DisplayCAState(pcait->lPropId, longValue);
break;
case CR_PROP_CACERTVERSION:
DisplayCAVersion(longValue);
break;
case CR_PROP_KRACERTSTATE:
DisplayKRAState(longValue);
break;
case CR_PROP_CATYPE:
wprintf(L" -- ");
cuDisplayCAType(longValue);
break;
default:
wprintf(wszNewLine);
break;
}
if (NULL != pcait->pwszRegName)
{
cuRegPrintDwordValue(
FALSE,
pcait->pwszRegName,
pcait->pwszRegName,
longValue);
}
}
else
{
wprintf(L":%ws", (CAITF_ASN & pcait->Flags)? L"\n" : L" ");
cuPrintCRLFString(NULL, strValue);
wprintf(wszNewLine);
}
}
if (NULL != pwszfnOut && NULL != pbBinary)
{
hr = EncodeToFileW(
pwszfnOut,
pbBinary,
cbBinary,
CRYPT_STRING_BINARY | g_EncodeFlags);
if (S_OK != hr)
{
_PrintError(hr, "EncodeToFileW");
cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
goto error;
}
}
error:
g_fVerbose = fVerboseOld;
if (NULL != pbBinary)
{
LocalFree(pbBinary);
}
if (NULL != strValue)
{
SysFreeString(strValue);
}
return(hr);
}
HRESULT
GetCACounts(
IN OUT DISPATCHINTERFACE *pdiProp,
IN OUT BOOL *pfV1,
OUT LONG *pcCASigCerts,
OUT LONG *pcCAXchgCerts,
OUT LONG *pcKRACerts,
OUT LONG *pcExitMods,
OUT LONG *plPropIdMax)
{
HRESULT hr;
BSTR strValue = NULL;
if (!*pfV1)
{
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
CR_PROP_CASIGCERTCOUNT,
0,
PROPTYPE_LONG,
CV_OUT_BINARY,
pcCASigCerts);
if (RPC_E_VERSION_MISMATCH != hr)
{
_JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
CR_PROP_CAXCHGCERTCOUNT,
0,
PROPTYPE_LONG,
CV_OUT_BINARY,
pcCAXchgCerts);
_JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
CR_PROP_KRACERTCOUNT,
0,
PROPTYPE_LONG,
CV_OUT_BINARY,
pcKRACerts);
_JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
CR_PROP_EXITCOUNT,
0,
PROPTYPE_LONG,
CV_OUT_BINARY,
pcExitMods);
_JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
hr = (*g_pfnProp2_GetCAProperty)(
pdiProp,
g_pwszConfig,
CR_PROP_CAPROPIDMAX,
0,
PROPTYPE_LONG,
CV_OUT_BINARY,
plPropIdMax);
_JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
}
else
{
*pfV1 = TRUE;
}
}
if (*pfV1)
{
WCHAR const *pwc;
DWORD cwc;
if (g_fAdminInterface)
{
hr = E_NOTIMPL;
_JumpIfError(hr, error, "ICertRequest required");
}
hr = Request_GetCACertificate(
pdiProp,
GETCERT_CAINFO, // fExchangeCertificate
g_pwszConfig,
CR_OUT_BINARY,
&strValue);
_JumpIfError(hr, error, "Request_GetCACertificate");
pwc = wcschr(strValue, L',');
if (NULL == pwc)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
_JumpErrorStr(hr, error, "bad CAInfo string", strValue);
}
pwc++;
cwc = wcslen(pwc);
if (!cuParseDecimal(&pwc, &cwc, (DWORD *) pcCASigCerts))
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
_JumpErrorStr(hr, error, "bad CAInfo cert count", strValue);
}
*pcCAXchgCerts = 0;
*pcExitMods = 1;
*plPropIdMax = 0;
}
if (1 < g_fVerbose)
{
wprintf(
L"GetCACounts(): cCASigCerts = %d, cCAXchgCerts = %d, cKRACerts = %d\n",
*pcCASigCerts,
*pcCAXchgCerts,
*pcKRACerts);
}
error:
if (NULL != strValue)
{
SysFreeString(strValue);
}
return(hr);
}
//+-------------------------------------------------------------------------
// cuGetCAInfoProperty -- display one CA Property.
//
// If an index is specifed, display the property only for that index.
// Otherwse, display the property for all valid indexes.
//
//--------------------------------------------------------------------------
HRESULT
cuGetCAInfoProperty(
IN WCHAR const *pwszOption,
OPTIONAL IN WCHAR const *pwszfnOut,
OPTIONAL IN WCHAR const *pwszInfoName,
OPTIONAL IN WCHAR const *pwszNumber,
IN BOOL fMultiple,
IN CAINFOTABLE const *pcait,
IN LONG cCASigCerts,
IN LONG cCAXchgCerts,
IN LONG cKRACerts,
IN LONG cExitMods,
IN OUT DISPATCHINTERFACE *pdiProp,
IN BOOL fV1)
{
HRESULT hr;
HRESULT hr2 = S_OK;
LONG CmdLineIndex;
LONG PropIndex;
LONG *pPropIndex = NULL;
LONG Count = 1;
// Determine indexed property Count.
// Non-indexed property Count is always 1.
switch (
(CAITF_EXITCOUNT | CAITF_SIGCERTCOUNT | CAITF_XCHGCERTCOUNT | CAITF_KRACERTCOUNT) &
pcait->Flags)
{
case CAITF_EXITCOUNT:
Count = cExitMods;
pPropIndex = &PropIndex;
break;
case CAITF_SIGCERTCOUNT:
Count = cCASigCerts;
pPropIndex = &PropIndex;
break;
case CAITF_XCHGCERTCOUNT:
Count = cCAXchgCerts;
pPropIndex = &PropIndex;
break;
case CAITF_KRACERTCOUNT:
Count = cKRACerts;
pPropIndex = &PropIndex;
break;
}
if (NULL != pwszNumber)
{
hr = myGetSignedLong(pwszNumber, &CmdLineIndex);
_JumpIfErrorStr(hr, error, "Value not a number", pwszNumber);
if (MAXDWORD == CmdLineIndex)
{
CmdLineIndex = Count - 1;
}
Count = 1;
pPropIndex = &CmdLineIndex;
}
for (PropIndex = 0; PropIndex < Count; PropIndex++)
{
DWORD lPropIdState = MAXDWORD;
BOOL fSkip;
switch (
(CAITF_CRLSTATE | CAITF_FORWARDCROSSCERTSTATE | CAITF_BACKWARDCROSSCERTSTATE) &
pcait->Flags)
{
case CAITF_CRLSTATE:
lPropIdState = CR_PROP_CRLSTATE;
break;
case CAITF_FORWARDCROSSCERTSTATE:
lPropIdState = CR_PROP_CAFORWARDCROSSCERTSTATE;
break;
case CAITF_BACKWARDCROSSCERTSTATE:
lPropIdState = CR_PROP_CABACKWARDCROSSCERTSTATE;
break;
}
if (MAXDWORD != lPropIdState)
{
CAINFOTABLE const *pcaitT;
fSkip = FALSE;
for (pcaitT = g_aCAInfoTable; NULL != pcaitT->pwszCmdLineName; pcaitT++)
{
if (lPropIdState == pcaitT->lPropId)
{
LONG PropIndexState = *pPropIndex;
DWORD dwState;
hr = cuGetCAInfoPropertyByIndex(
NULL, // pwszOption
NULL, // pwszfnOut
NULL, // pwszInfoName
&PropIndexState,
pcaitT,
pdiProp,
fV1,
(CAITF_ASN & pcait->Flags)?
TRUE : FALSE, // fDisplayResult
&dwState); // pdwValue
_PrintIfError2(hr, "cuGetCAInfoPropertyByIndex", hr);
if (S_OK == hr && CA_DISP_ERROR == dwState)
{
fSkip = TRUE;
}
break;
}
}
if (fSkip)
{
continue;
}
}
if (1 < g_fVerbose)
{
wprintf(
NULL == pPropIndex?
L"cuGetCAInfoProperty(%ws): %ws:\n" :
L"cuGetCAInfoProperty(%ws): %ws[%u]:\n",
pcait->pwszCmdLineName,
pcait->pwszCmdLineName,
NULL == pPropIndex? -1 : *pPropIndex);
}
hr = cuGetCAInfoPropertyByIndex(
pwszOption,
pwszfnOut,
pwszInfoName,
pPropIndex,
pcait,
pdiProp,
fV1,
TRUE, // fDisplayResult
NULL); // pdwValue
if (E_INVALIDARG == hr &&
(fMultiple || 1 < Count) &&
(CAITF_SKIPINVALIDARG & pcait->Flags))
{
_PrintIfError2(hr, "cuGetCAInfoPropertyByIndex", hr);
hr = S_OK;
}
_PrintIfErrorStr3(
hr,
"cuGetCAInfoPropertyByIndex",
pcait->pwszCmdLineName,
HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
E_INVALIDARG);
if (S_OK == hr2)
{
hr2 = hr; // Save first error
}
}
hr = hr2;
error:
return(hr);
}
//+-------------------------------------------------------------------------
// cuGetCAInfo -- display one or more CA Properties.
//
// If indexed property counts will be needed, fetch them first, so we know
// how many of each indexed property to fetch.
//
// If pwszInfoName is NULL, display the default set of properties.
// If pwszInfoName is L"*", display all properties.
// Otherwise, display only the specified property.
//
//--------------------------------------------------------------------------
HRESULT
cuGetCAInfo(
IN WCHAR const *pwszOption,
OPTIONAL IN WCHAR const *pwszfnOut,
OPTIONAL IN WCHAR const *pwszInfoName,
OPTIONAL IN WCHAR const *pwszNumber)
{
HRESULT hr;
HRESULT hr2 = S_OK;
DISPATCHINTERFACE diProp;
BOOL fV1 = g_fV1Interface;
BOOL fMustRelease = FALSE;
BOOL fMultiple = FALSE;
LONG cCASigCerts = 0;
LONG cCAXchgCerts = 0;
LONG cKRACerts = 0;
LONG cExitMods = 0;
LONG lPropIdMax;
CAINFOTABLE const *pcait;
InitPropFunctionPointers();
hr = (*g_pfnProp_Init)(g_DispatchFlags, &diProp);
_JumpIfError(hr, error, "g_pfnProp_Init");
fMustRelease = TRUE;
if (NULL == pwszInfoName ||
(0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoName) &&
0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoSanitizedName) &&
0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoDSName)))
{
hr = GetCACounts(
&diProp,
&fV1,
&cCASigCerts,
&cCAXchgCerts,
&cKRACerts,
&cExitMods,
&lPropIdMax);
_JumpIfError(hr, error, "GetCACounts");
}
if (NULL == pwszInfoName || 0 == lstrcmp(L"*", pwszInfoName))
{
CSASSERT(NULL == pwszfnOut);
if (NULL != pwszNumber)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "too many args");
}
fMultiple = TRUE; // loop displaying default or all entries
}
for (pcait = g_aCAInfoTable; ; pcait++)
{
if (NULL == pcait->pwszCmdLineName)
{
if (!fMultiple)
{
hr = E_INVALIDARG;
_JumpErrorStr(hr, error, "bad command line name", pwszInfoName);
}
break;
}
if (fMultiple)
{
if (NULL == pwszInfoName)
{
if (0 == (CAITF_DEFAULT & pcait->Flags))
{
continue;
}
}
else
{
if (CAITF_SKIP & pcait->Flags)
{
continue;
}
}
if (fV1)
{
if (GETCERT_UNSUPPORTED == pcait->dwGetCert)
{
continue;
}
}
else
{
if (CR_PROP_NONE == pcait->lPropId)
{
continue;
}
}
}
else
{
if (0 != mylstrcmpiS(pwszInfoName, pcait->pwszCmdLineName))
{
continue;
}
}
hr = cuGetCAInfoProperty(
pwszOption,
pwszfnOut,
pwszInfoName,
pwszNumber,
fMultiple,
pcait,
cCASigCerts,
cCAXchgCerts,
cKRACerts,
cExitMods,
&diProp,
fV1);
if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ||
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) == hr ||
E_INVALIDARG == hr) &&
(CAITF_OPTIONAL & pcait->Flags) &&
fMultiple)
{
_PrintError2(hr, "cuGetCAInfoProperty", hr);
hr = S_OK;
}
_PrintIfError2(hr, "cuGetCAInfoProperty", E_INVALIDARG);
if (S_OK == hr2)
{
hr2 = hr; // Save first error
}
if (!fMultiple)
{
break;
}
}
hr = hr2;
error:
if (fMustRelease)
{
(*g_pfnProp_Release)(&diProp);
}
return(hr);
}
HRESULT
verbGetCACertificate(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszfnCert,
OPTIONAL IN WCHAR const *pwszIndex,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
if (NULL == pwszIndex)
{
pwszIndex = L"-1";
}
hr = cuGetCAInfo(
pwszOption,
pwszfnCert,
g_wszCACert == pwszOption?
g_wszCAInfoCert : g_wszCAInfoCertChain,
pwszIndex);
_JumpIfError(hr, error, "cuGetCAInfo");
error:
return(hr);
}
HRESULT
verbGetCAInfo(
IN WCHAR const *pwszOption,
OPTIONAL IN WCHAR const *pwszInfoName,
OPTIONAL IN WCHAR const *pwszNumber,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
hr = cuGetCAInfo(pwszOption, NULL, pwszInfoName, pwszNumber);
_JumpIfError(hr, error, "cuGetCAInfo");
error:
return(hr);
}
HRESULT
verbGetCAPropInfo(
IN WCHAR const *pwszOption,
OPTIONAL IN WCHAR const *pwszInfoName,
OPTIONAL IN WCHAR const *pwszNumber,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
HRESULT hr2 = S_OK;
DISPATCHINTERFACE diProp;
BOOL fV1 = g_fV1Interface;
BOOL fMustRelease = FALSE;
LONG cCASigCerts;
LONG cCAXchgCerts;
LONG cKRACerts;
LONG cExitMods;
LONG lPropIdMax;
LONG lPropId;
BSTR strDisplayName = NULL;
InitPropFunctionPointers();
hr = (*g_pfnProp_Init)(g_DispatchFlags, &diProp);
_JumpIfError(hr, error, "g_pfnProp_Init");
fMustRelease = TRUE;
hr = GetCACounts(
&diProp,
&fV1,
&cCASigCerts,
&cCAXchgCerts,
&cKRACerts,
&cExitMods,
&lPropIdMax);
_JumpIfError(hr, error, "GetCACounts");
for (lPropId = 1; lPropId <= lPropIdMax; lPropId++)
{
LONG lPropFlags;
// don't use the display name twice!
if (NULL != strDisplayName)
{
SysFreeString(strDisplayName);
strDisplayName = NULL;
}
hr = (*g_pfnProp2_GetCAPropertyFlags)(
&diProp,
g_pwszConfig,
lPropId,
&lPropFlags);
_PrintIfError(hr, "g_pfnProp2_GetCAPropertyFlags");
if (S_OK == hr)
{
hr = (*g_pfnProp2_GetCAPropertyDisplayName)(
&diProp,
g_pwszConfig,
lPropId,
&strDisplayName);
_PrintIfError(hr, "g_pfnProp2_GetCAPropertyDisplayName");
wprintf(L"%3d: ", lPropId);
cuPrintSchemaEntry(
NULL, // pwszName
NULL != strDisplayName? strDisplayName : g_wszEmpty,
lPropFlags,
0); // cbMax
}
}
error:
if (fMustRelease)
{
(*g_pfnProp_Release)(&diProp);
}
if (NULL != strDisplayName)
{
SysFreeString(strDisplayName);
}
return(hr);
}
HRESULT
verbGetConfig(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszArg1,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
wprintf(
myLoadResourceString(IDS_FORMAT_CONFIG_STRING), // "Config String: ""%ws"""
g_pwszConfig);
wprintf(wszNewLine);
return(S_OK);
}
HRESULT
verbGetConfig2(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszFlags,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
ICertGetConfig *pConfig = NULL;
BSTR strConfig = NULL;
LONG Flags;
hr = CoCreateInstance(
CLSID_CCertGetConfig,
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
IID_ICertGetConfig,
(VOID **) &pConfig);
_JumpIfError(hr, error, "CoCreateInstance");
Flags = CC_LOCALCONFIG;
if (NULL != pwszFlags)
{
hr = myGetLong(pwszFlags, &Flags);
_JumpIfError(hr, error, "Flags must be a number");
}
hr = pConfig->GetConfig(Flags, &strConfig);
_JumpIfError(hr, error, "GetConfig");
wprintf(
myLoadResourceString(IDS_FORMAT_ICERTCONFIG_CONFIG_STRING), // "ICertGetConfig Config String: ""%ws"""
strConfig);
wprintf(wszNewLine);
error:
if (NULL != strConfig)
{
SysFreeString(strConfig);
}
if (NULL != pConfig)
{
pConfig->Release();
}
return(hr);
}
HRESULT
verbGetConfig3(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszFlags,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
LONG count;
DISPATCHINTERFACE diConfig;
BOOL fRelease = FALSE;
BSTR strConfig = NULL;
LONG Flags;
hr = Config_Init(g_DispatchFlags, &diConfig);
_JumpIfError(hr, error, "Config_Init");
fRelease = TRUE;
hr = Config_Reset(&diConfig, 0, &count);
_JumpIfError(hr, error, "Config_Reset");
Flags = CC_UIPICKCONFIG;
if (NULL != pwszFlags)
{
hr = myGetLong(pwszFlags, &Flags);
_JumpIfError(hr, error, "Flags must be a number");
}
hr = Config_GetConfig(&diConfig, Flags, &strConfig);
_JumpIfError(hr, error, "Config_GetConfig");
hr = ConfigDumpEntry(&diConfig, NULL, -1, NULL);
_JumpIfError(hr, error, "ConfigDumpEntry");
error:
if (NULL != strConfig)
{
SysFreeString(strConfig);
}
if (fRelease)
{
Config_Release(&diConfig);
}
return(hr);
}
HRESULT
verbErrorDump(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszErrorCode,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
HRESULT hrDump;
WCHAR awchr[cwcHRESULTSTRING];
WCHAR const *pwszError = NULL;
hr = myGetSignedLong(pwszErrorCode, &hrDump);
_JumpIfError(hr, error, "bad numeric operand");
wprintf(
L"%ws -- %u (%d)\n",
myHResultToString(awchr, hrDump),
hrDump,
hrDump);
pwszError = myGetErrorMessageText(hrDump, g_fVerbose);
wprintf(
myLoadResourceString(IDS_FORMAT_MESSAGE_TEXT), // "Error message text: %ws"
pwszError);
wprintf(wszNewLine);
hr = S_OK;
error:
if (NULL != pwszError)
{
LocalFree(const_cast<WCHAR *>(pwszError));
}
return(hr);
}
HRESULT
RequestCACertificateAndComplete(
IN DWORD Flags,
OPTIONAL IN WCHAR const *pwszParentMachine,
OPTIONAL IN WCHAR const *pwszParentCA,
OPTIONAL IN WCHAR const *pwszfnCACert,
OPTIONAL OUT WCHAR **ppwszRequestFile)
{
HRESULT hr;
WCHAR *pwszCAName = NULL;
WCHAR *pwszFinalCAName;
pwszFinalCAName = wcschr(g_pwszConfig, L'\\');
if (NULL != pwszFinalCAName)
{
pwszFinalCAName++;
}
else
{
hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGACTIVE, &pwszCAName);
_JumpIfErrorStr(hr, error, "myGetCertRegStrValue", wszREGACTIVE);
pwszFinalCAName = pwszCAName;
}
if (g_fForce)
{
Flags |= CSRF_OVERWRITE;
}
if (g_fCryptSilent)
{
Flags |= CSRF_UNATTENDED;
}
hr = CertServerRequestCACertificateAndComplete(
g_hInstance, // hInstance
NULL, // hwnd
Flags, // Flags
pwszFinalCAName, // pwszCAName
pwszParentMachine, // pwszParentMachine
pwszParentCA, // pwszParentCA
pwszfnCACert, // pwszCAChainFile
ppwszRequestFile); // ppwszRequestFile
_JumpIfError(hr, error, "CertServerRequestCACertificateAndComplete");
error:
if (NULL != pwszCAName)
{
LocalFree(pwszCAName);
}
return(hr);
}
HRESULT
verbInstallCACert(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszfnCACert,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
hr = RequestCACertificateAndComplete(
CSRF_INSTALLCACERT,
NULL, // pwszParentMachine
NULL, // pwszParentCA
pwszfnCACert, // pwszfnCACert
NULL); // ppwszRequestFile
_JumpIfError(hr, error, "RequestCACertificateAndComplete");
error:
return(hr);
}
HRESULT
verbRenewCACert(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszReuseKeys,
IN WCHAR const *pwszParentConfig,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
DWORD Flags = CSRF_RENEWCACERT | CSRF_NEWKEYS;
WCHAR *pwszParentMachine = NULL;
WCHAR *pwszParentCA = NULL;
WCHAR *pwszRequestFile = NULL;
if (NULL != pwszReuseKeys)
{
if (0 == LSTRCMPIS(pwszReuseKeys, L"ReuseKeys"))
{
Flags &= ~CSRF_NEWKEYS;
}
else if (NULL == pwszParentConfig)
{
pwszParentConfig = pwszReuseKeys;
}
if (NULL != pwszParentConfig)
{
hr = mySplitConfigString(
pwszParentConfig,
&pwszParentMachine,
&pwszParentCA);
_JumpIfErrorStr(hr, error, "mySplitConfigString", pwszParentConfig);
}
}
hr = RequestCACertificateAndComplete(
Flags, // Flags
pwszParentMachine, // pwszParentMachine
pwszParentCA, // pwszParentCA
NULL, // pwszfnCACert
&pwszRequestFile); // ppwszRequestFile
_JumpIfError(hr, error, "RequestCACertificateAndComplete");
if (NULL != pwszRequestFile)
{
wprintf(
L"%ws %ws\n",
myLoadResourceString(IDS_REQUEST_FILE_COLON),
pwszRequestFile);
}
error:
if (NULL != pwszRequestFile)
{
LocalFree(pwszRequestFile);
}
if (NULL != pwszParentMachine)
{
LocalFree(pwszParentMachine);
}
if (NULL != pwszParentCA)
{
LocalFree(pwszParentCA);
}
return(hr);
}
VOID
cuPrintVRootDisposition(
IN DWORD idmsg,
IN DWORD Disposition)
{
DWORD idDisp = 0;
switch (0x0000ffff & Disposition)
{
case VFD_CREATED: idDisp = IDS_VROOTDISP_CREATED; break;
case VFD_DELETED: idDisp = IDS_VROOTDISP_DELETED; break;
case VFD_EXISTS: idDisp = IDS_VROOTDISP_EXISTS; break;
case VFD_NOTFOUND: idDisp = IDS_VROOTDISP_NOTFOUND; break;
case VFD_CREATEERROR: idDisp = IDS_VROOTDISP_CREATEERROR; break;
case VFD_DELETEERROR: idDisp = IDS_VROOTDISP_DELETERROR; break;
case VFD_NOTSUPPORTED: idDisp = IDS_VROOTDISP_NOTSUPPORTED; break;
}
if (0 != idDisp)
{
wprintf(myLoadResourceString(idmsg), myLoadResourceString(idDisp));
wprintf(wszNewLine);
}
idDisp = 0;
switch (Disposition >> 16) // display ASP disposition
{
case VFD_CREATED: idDisp = IDS_VROOTDISP_ENABLEDASP; break;
case VFD_EXISTS: idDisp = IDS_VROOTDISP_ASPALREADYENABLED; break;
case VFD_CREATEERROR: idDisp = IDS_VROOTDISP_ENABLEASPERROR; break;
}
if (0 != idDisp)
{
wprintf(L"%ws\n", myLoadResourceString(idDisp));
}
}
HRESULT
verbCreateVRoots(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszDelete,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
DWORD VRootDisposition = 0;
DWORD ShareDisposition = 0;
DWORD Flags;
WCHAR* pwszPath = NULL;
ENUM_CATYPES CAType = ENUM_UNKNOWN_CA;
DWORD cb = sizeof(ENUM_CATYPES);
DWORD dwType;
HKEY hkey = NULL;
hr = myRegOpenRelativeKey(
NULL,
L"ca",
RORKF_CREATESUBKEYS,
&pwszPath,
NULL, // ppwszName
&hkey);
if (S_OK == hr)
{
cb = sizeof(CAType);
hr = RegQueryValueEx(
hkey,
wszREGCATYPE,
0,
&dwType,
(BYTE *) &CAType,
&cb);
_JumpIfErrorStr(hr, error, "RegQueryValueEx", wszREGCATYPE);
}
else
{
hr = myRegOpenRelativeKey(
NULL,
L"",
RORKF_CREATESUBKEYS,
&pwszPath,
NULL, // ppwszName
&hkey);
_JumpIfError(hr, error, "myRegOpenRelativeKey");
cb = sizeof(CAType);
hr = RegQueryValueEx(
hkey,
wszREGWEBCLIENTCATYPE,
0,
&dwType,
(BYTE *) &CAType,
&cb);
_JumpIfErrorStr(hr, error, "RegQueryValueEx", wszREGWEBCLIENTCATYPE);
}
if (0 != LSTRCMPIS(pwszDelete, L"delete"))
{
Flags = VFF_CREATEVROOTS |
VFF_CREATEFILESHARES |
VFF_CLEARREGFLAGIFOK |
VFF_ENABLEASP;
}
else
{
Flags = VFF_DELETEVROOTS | VFF_DELETEFILESHARES;
}
hr = myModifyVirtualRootsAndFileShares(
Flags,
CAType,
FALSE, // synchronous -- blocking call
INFINITE, // will block for good
&VRootDisposition,
&ShareDisposition);
cuPrintVRootDisposition(IDS_FORMAT_VROOT, VRootDisposition);
cuPrintVRootDisposition(IDS_FORMAT_FILESHARE, ShareDisposition);
_JumpIfError(hr, error, "myModifyVirtualRootsAndFileShares");
error:
if (pwszPath)
LocalFree(pwszPath);
if (hkey)
RegCloseKey(hkey);
return(hr);
}
HRESULT
cuPingCertSrv(
IN WCHAR const *pwszConfig,
OPTIONAL OUT CAINFO **ppCAInfo)
{
HRESULT hr;
WCHAR *pwszzCANames = NULL;
DWORD dwServerVersion;
WCHAR wszVersion[12];
if (NULL != ppCAInfo)
{
*ppCAInfo = NULL;
}
wprintf(
myLoadResourceString(IDS_FORMAT_CONNECTING), // "Connecting to %ws"
pwszConfig);
hr = myPingCertSrv(
pwszConfig,
NULL,
&pwszzCANames,
NULL,
ppCAInfo,
&dwServerVersion,
NULL);
wprintf(wszNewLine);
if (S_OK != hr)
{
cuPrintErrorAndString(
NULL,
IDS_FORMAT_SERVER_DEAD, // "Server could not be reached: %ws"
hr,
NULL);
}
_JumpIfError(hr, error, "Ping");
if (1 == dwServerVersion)
{
wszVersion[0] = L'\0';
}
else
{
swprintf(wszVersion, L"%u", dwServerVersion);
}
wprintf(
myLoadResourceString(IDS_FORMAT_SERVER_ALIVE), // "Server ""%ws"" ICertRequest%ws interface is alive"
pwszzCANames, // Assume only one CA Name for now
wszVersion);
error:
wprintf(wszNewLine);
if (NULL != pwszzCANames)
{
LocalFree(pwszzCANames);
}
return(hr);
}
HRESULT
verbPing(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszArg1,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
hr = cuPingCertSrv(g_pwszConfig, NULL);
_JumpIfError(hr, error, "cuPingCertSrv");
error:
return(hr);
}
HRESULT
OpenAdminServer(
OPTIONAL OUT WCHAR const **ppwszAuthority,
OUT DWORD *pdwServerVersion,
OUT ICertAdminD2 **ppICertAdminD)
{
HRESULT hr;
*pdwServerVersion = 0;
hr = myOpenAdminDComConnection(
g_pwszConfig,
ppwszAuthority,
NULL,
pdwServerVersion,
ppICertAdminD);
_JumpIfError(hr, error, "myOpenDComConnection");
CSASSERT(0 != *pdwServerVersion);
error:
return(hr);
}
VOID
CloseAdminServer(
IN OUT ICertAdminD2 **ppICertAdminD)
{
myCloseDComConnection((IUnknown **) ppICertAdminD, NULL);
}
HRESULT
verbPingAdmin(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszArg1,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
ICertAdminD2 *pICertAdminD = NULL;
WCHAR const *pwszAuthority;
WCHAR wszVersion[12];
DWORD dwServerVersion = 0;
wprintf(
myLoadResourceString(IDS_FORMAT_CONNECTING), // "Connecting to %ws"
g_pwszConfig);
hr = OpenAdminServer(&pwszAuthority, &dwServerVersion, &pICertAdminD);
_JumpIfError(hr, error, "OpenAdminServer");
CSASSERT(0 != dwServerVersion);
if (1 == dwServerVersion)
{
wszVersion[0] = L'\0';
}
else
{
swprintf(wszVersion, L"%u", dwServerVersion);
}
if (2 <= dwServerVersion)
{
hr = pICertAdminD->Ping2(pwszAuthority);
_JumpIfError(hr, error, "Ping2");
}
else
{
hr = pICertAdminD->Ping(pwszAuthority);
_JumpIfError(hr, error, "Ping");
}
wprintf(wszNewLine);
wprintf(
myLoadResourceString(IDS_ADMIN_INTERFACE_ALIVE), // "Server ICertAdmin%ws interface is alive"
wszVersion);
error:
wprintf(wszNewLine);
if (NULL != pICertAdminD)
{
CloseAdminServer(&pICertAdminD);
}
return(hr);
}
HRESULT
verbGetMapiInfo(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszArg1,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
WCHAR *pwszProfileName = NULL; // obsolete
WCHAR *pwszLogonName = NULL;
WCHAR *pwszPassword = NULL;
DWORD cwc;
hr = myGetMapiInfo(NULL, &pwszProfileName, &pwszLogonName, &pwszPassword);
_JumpIfError2(
hr,
error,
"myGetMapiInfo",
HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
wprintf(L"\"%ws\" \"", pwszLogonName);
for (cwc = wcslen(pwszPassword); cwc != 0; cwc--)
{
wprintf(L"*");
}
wprintf(L"\"\n");
hr = S_OK;
error:
if (NULL != pwszProfileName)
{
LocalFree(pwszProfileName);
}
if (NULL != pwszLogonName)
{
LocalFree(pwszLogonName);
}
if (NULL != pwszPassword)
{
myZeroDataString(pwszPassword); // password data
LocalFree(pwszPassword);
}
return(hr);
}
HRESULT
verbSetMapiInfo(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszLogonName,
IN WCHAR const *pwszArg2,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
WCHAR wszPassword[MAX_PATH];
WCHAR const *pwszPassword;
WCHAR const *pwszProfileName = L"";
verbGetMapiInfo(pwszOption, NULL, NULL, NULL, NULL);
hr = cuGetPassword(
0, // idsPrompt
NULL, // pwszfn
g_pwszPassword,
TRUE, // fVerify
wszPassword,
ARRAYSIZE(wszPassword),
&pwszPassword);
_JumpIfError(hr, error, "cuGetPassword");
hr = mySaveMapiInfo(NULL, pwszProfileName, pwszLogonName, pwszPassword);
_JumpIfError(hr, error, "mySaveMapiInfo");
hr = verbGetMapiInfo(pwszOption, NULL, NULL, NULL, NULL);
_JumpIfError(hr, error, "verbGetMapiInfo");
error:
SecureZeroMemory(wszPassword, sizeof(wszPassword)); // password data
return(hr);
}
HRESULT
verbGetCertFromUI(
IN WCHAR const *pwszOption,
IN WCHAR const *pwszObjId,
IN WCHAR const *pwszCNArg,
IN WCHAR const *pwszArg3,
IN WCHAR const *pwszArg4)
{
HRESULT hr;
char *pszObjId = NULL;
WCHAR const *pwszCommonName = NULL;
CERT_CONTEXT const *pCert = NULL;
BOOL fKRA = FALSE;
BOOL fERA = FALSE;
DWORD i;
if (NULL != pwszObjId)
{
hr = S_FALSE;
if (iswdigit(*pwszObjId))
{
hr = myVerifyObjId(pwszObjId);
if (S_OK == hr)
{
if (!myConvertWszToSz(&pszObjId, pwszObjId, -1))
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "myConvertWszToSz");
}
cuDumpOIDAndDescriptionA(pszObjId);
wprintf(wszNewLine);
}
}
if (S_OK != hr)
{
if (0 == LSTRCMPIS(pwszObjId, L"KRA"))
{
fKRA = TRUE;
}
else if (0 == LSTRCMPIS(pwszObjId, L"ERA"))
{
fERA = TRUE;
}
else
{
pwszCommonName = pwszObjId;
}
}
}
if (NULL != pwszCNArg)
{
if (NULL != pwszCommonName)
{
hr = E_INVALIDARG;
_JumpError(hr, error, "bad arg");
}
pwszCommonName = pwszCNArg;
}
if (fKRA)
{
hr = myGetKRACertificateFromPicker(
g_hInstance,
NULL, // hwndParent
IDS_GETCERT_TITLE,
IDS_GETCERT_SUBTITLE_KRA,
pwszCommonName,
TRUE, // is DS available?
g_fCryptSilent,
&pCert);
_JumpIfError(hr, error, "myGetKRACertificateFromPicker");
}
else if (fERA)
{
hr = myGetERACertificateFromPicker(
g_hInstance,
NULL, // hwndParent
IDS_GETCERT_TITLE,
IDS_GETCERT_SUBTITLE_ERA,
pwszCommonName,
g_fCryptSilent,
&pCert);
_JumpIfError(hr, error, "myGetERACertificateFromPicker");
}
else
{
hr = myGetCertificateFromPicker(
g_hInstance,
NULL, // hwndParent
IDS_GETCERT_TITLE,
NULL != pszObjId?
IDS_GETCERT_SUBTITLE_OBJID :
IDS_GETCERT_SUBTITLE,
// dwFlags: HKLM+HKCU My store
CUCS_MYSTORE |
CUCS_CASTORE |
CUCS_KRASTORE |
CUCS_ROOTSTORE |
CUCS_MACHINESTORE |
CUCS_USERSTORE |
CUCS_DSSTORE |
(g_fCryptSilent? CUCS_SILENT : 0),
pwszCommonName,
0,
NULL,
NULL != pszObjId? 1 : 0, // cpszObjId
NULL != pszObjId? &pszObjId : NULL,
&pCert);
_JumpIfError(hr, error, "myGetCertificateFromPicker");
}
if (NULL != pCert)
{
hr = cuDumpAsnBinary(
pCert->pbCertEncoded,
pCert->cbCertEncoded,
MAXDWORD);
_JumpIfError(hr, error, "cuDumpAsnBinary(cert)");
}
error:
if (NULL != pCert)
{
CertFreeCertificateContext(pCert);
}
if (NULL != pszObjId)
{
LocalFree(pszObjId);
}
return(hr);
}