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.
 
 
 
 
 
 

736 lines
25 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: tfindcer.cpp
//
// Contents: Cert Store Find API Tests
//
// See Usage() for list of test options.
//
//
// Functions: main
//
// History: 11-Apr-96 philh created
// 07-Jun-96 HelleS Added printing the command line
// and Failed or Passed at the end.
// 20-Aug-96 jeffspel name changes
//--------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "certtest.h"
#include "cryptuiapi.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <memory.h>
#include <time.h>
#include <stddef.h>
static CRYPT_ENCODE_PARA TestEncodePara = {
offsetof(CRYPT_ENCODE_PARA, pfnFree) + sizeof(TestEncodePara.pfnFree),
TestAlloc,
TestFree
};
static BOOL AllocAndEncodeObject(
IN LPCSTR lpszStructType,
IN const void *pvStructInfo,
OUT BYTE **ppbEncoded,
OUT DWORD *pcbEncoded
)
{
BOOL fResult;
fResult = CryptEncodeObjectEx(
dwCertEncodingType,
lpszStructType,
pvStructInfo,
CRYPT_ENCODE_ALLOC_FLAG,
&TestEncodePara,
(void *) ppbEncoded,
pcbEncoded
);
if (!fResult) {
if ((DWORD_PTR) lpszStructType <= 0xFFFF)
printf("CryptEncodeObject(StructType: %d)",
(DWORD)(DWORD_PTR) lpszStructType);
else
printf("CryptEncodeObject(StructType: %s)",
lpszStructType);
PrintLastError("");
}
return fResult;
}
static void Usage(void)
{
printf("Usage: tfindcer [options] <StoreName> [<Name String>]\n");
printf("Options are:\n");
printf(" -h - This message\n");
printf(" -D<digest> - Find cert matching Digest (Hash)\n");
printf(" -S - Find cert matching Subject\n");
printf(" -I - Find cert matching Issuer\n");
printf(" -U<ObjectID> - Find cert matching Usage Identifiers\n");
printf(" -F<number> - Find Flags\n");
printf(" -f<filename> - Get matching Name from cert file\n");
printf(" -o<ObjectID> - Object Identifier (1.2.3.4)\n");
printf(" -t<ValueType> - Attribute value type (printableString - %d)\n", CERT_RDN_PRINTABLE_STRING);
printf(" -a[<attributeString>] - Attribute value match\n");
printf(" -A[<attributeString>] - Attribute value match (test unicode)\n");
printf(" -C - Case Insensitive Attribute value match\n");
printf(" -e<number> - Cert encoding type\n");
printf(" -s - Open the \"StoreName\" System store\n");
printf(" -p<filename> - Put encoded cert to file\n");
printf(" -d - Delete cert\n");
printf(" -7[<SaveFilename>] - PKCS# 7 formated save for delete\n");
printf(" -b - Brief\n");
printf(" -v - Verbose\n");
printf(" -u - UI Dialog Viewer//Selection\n");
printf(" -c - Verify checks enabled\n");
printf(" -q - Quiet. Don't display certs\n");
printf(" -xDelete - Delete CrossCertDistPoint property\n");
printf(" -x<number> - CrossCertDistPoint sync delta seconds\n");
printf(" -x<Url> - CrossCertDistPoint Url\n");
printf(" -X<Url> - CrossCertDistPoint Alternate Url\n");
printf("\n");
printf("Default: find all certs in the store\n");
}
static BOOL AllocAndGetEncodedName(
LPSTR pszCertFilename,
DWORD dwFindInfo,
BYTE **ppbEncodedName,
DWORD *pcbEncodedName)
{
BOOL fResult;
BYTE *pbEncodedCert = NULL;
DWORD cbEncodedCert;
PCCERT_CONTEXT pCert = NULL;
BYTE *pbAllocEncodedName = NULL;
BYTE *pbEncodedName;
DWORD cbEncodedName;
if (!ReadDERFromFile(pszCertFilename, &pbEncodedCert, &cbEncodedCert)) {
PrintLastError("AllocAndGetEncodedName::ReadDERFromFile");
goto ErrorReturn;
}
if (NULL == (pCert = CertCreateCertificateContext(
dwCertEncodingType,
pbEncodedCert,
cbEncodedCert
))) {
PrintLastError("AllocAndGetEncodedName::CertCreateCertificateContext");
goto ErrorReturn;
}
if (dwFindInfo == CERT_INFO_SUBJECT_FLAG) {
cbEncodedName = pCert->pCertInfo->Subject.cbData;
pbEncodedName = pCert->pCertInfo->Subject.pbData;
} else {
cbEncodedName = pCert->pCertInfo->Issuer.cbData;
pbEncodedName = pCert->pCertInfo->Issuer.pbData;
}
pbAllocEncodedName = (BYTE *) TestAlloc(cbEncodedName);
if (pbAllocEncodedName == NULL) goto ErrorReturn;
memcpy(pbAllocEncodedName, pbEncodedName, cbEncodedName);
fResult = TRUE;
goto CommonReturn;
ErrorReturn:
if (pbAllocEncodedName) {
TestFree(pbAllocEncodedName);
pbAllocEncodedName = NULL;
}
cbEncodedName = 0;
fResult = FALSE;
CommonReturn:
if (pbEncodedCert)
TestFree(pbEncodedCert);
if (pCert)
CertFreeCertificateContext(pCert);
*ppbEncodedName = pbAllocEncodedName;
*pcbEncodedName = cbEncodedName;
return fResult;
}
static void DisplayFindAttr(DWORD cRDNAttr, CERT_RDN_ATTR rgRDNAttr[])
{
DWORD i;
for (i = 0; i < cRDNAttr; i++) {
LPSTR pszObjId = rgRDNAttr[i].pszObjId;
LPSTR pszValue = (LPSTR) rgRDNAttr[i].Value.pbData;
printf(" [%d] ", i);
if (pszObjId)
printf("%s ", pszObjId);
if (rgRDNAttr[i].dwValueType)
printf("ValueType: %d ", rgRDNAttr[i].dwValueType);
if (pszValue == NULL)
pszValue = "<NONE>";
else {
if (rgRDNAttr[i].Value.cbData)
printf("Value: %s\n", pszValue);
else
// For UNICODE, cbData is 0.
printf("Value: %S\n", (LPCSTR) pszValue);
}
}
}
typedef PCCERT_CONTEXT (WINAPI *PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE)(
IN HCERTSTORE hCertStore,
IN OPTIONAL HWND hwnd, // Defaults to the desktop window
IN OPTIONAL LPCWSTR pwszTitle,
IN OPTIONAL LPCWSTR pwszDisplaystring,
IN DWORD dwDontUseColumn,
IN DWORD dwFlags,
IN void *pvReserved
);
void SelectCertficateFromStoreUI(
IN HCERTSTORE hStore,
IN DWORD dwDisplayFlags
)
{
HMODULE hDll = NULL;
PCCERT_CONTEXT pCert = NULL;
PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE
pfnCryptUIDlgSelectCertificateFromStore;
if (NULL == (hDll = LoadLibraryA("cryptui.dll"))) {
PrintLastError("LoadLibraryA(cryptui.dll)");
goto CommonReturn;
}
if (NULL == (pfnCryptUIDlgSelectCertificateFromStore =
(PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE)
GetProcAddress(hDll, "CryptUIDlgSelectCertificateFromStore"))) {
PrintLastError("GetProcAddress(CryptUIDlgSelectCertificateFromStore)");
goto CommonReturn;
}
pCert = pfnCryptUIDlgSelectCertificateFromStore(
hStore,
NULL, // hwnd
NULL, // pwszTitle
NULL, // pwszDisplaystring
CRYPTUI_SELECT_INTENDEDUSE_COLUMN |
CRYPTUI_SELECT_FRIENDLYNAME_COLUMN |
CRYPTUI_SELECT_LOCATION_COLUMN,
0, // dwFlags
NULL // pvReserved
);
if (NULL == pCert)
PrintLastError("CryptUIDlgSelectCertificateFromStore");
else {
printf("===== Selected Certificate =====\n");
DisplayCert(pCert, dwDisplayFlags & ~DISPLAY_UI_FLAG);
}
CommonReturn:
if (pCert)
CertFreeCertificateContext(pCert);
if (hDll)
FreeLibrary(hDll);
}
int _cdecl main(int argc, char * argv[])
{
int ReturnStatus;
DWORD dwFindCmp = CERT_COMPARE_ANY;
DWORD dwFindInfo = 0;
LPSTR pszFindInfo = NULL;
DWORD dwFindType;
DWORD dwFindFlags = 0;
void *pvFindPara = NULL;
DWORD cbHash = 0;
BYTE rgbHash[MAX_HASH_LEN];
CRYPT_HASH_BLOB HashBlob;
CERT_NAME_BLOB NameBlob;
BYTE *pbEncodedName = NULL;
DWORD cbEncodedName;
#define MAX_RDN_ATTR 20
DWORD cRDNAttr = 0;
CERT_RDN_ATTR rgRDNAttr[MAX_RDN_ATTR + 1];
memset (rgRDNAttr, 0, sizeof(rgRDNAttr));
CERT_RDN NameRDN;
#define MAX_USAGE_ID 20
LPSTR rgpszUsageId[MAX_USAGE_ID];
CTL_USAGE CtlUsage = {0, rgpszUsageId};
BOOL fSystemStore = FALSE;
BOOL fDelete = FALSE;
LPSTR pszCertFilename = NULL;
LPSTR pszStoreFilename = NULL;
LPSTR pszPutFilename = NULL;
LPSTR pszFindStr = NULL;
DWORD dwDisplayFlags = 0;
BOOL fQuiet = FALSE;
BOOL fPKCS7Save = FALSE;
LPSTR pszSaveFilename = NULL;
#define MAX_DIST_POINT 10
#define MAX_DIST_POINT_ALT_NAME_ENTRY 20
CERT_ALT_NAME_INFO rgDistPoint[MAX_DIST_POINT];
CERT_ALT_NAME_ENTRY rgDistPointAltNameEntry[MAX_DIST_POINT_ALT_NAME_ENTRY];
CROSS_CERT_DIST_POINTS_INFO XCertInfo = {0, 0, rgDistPoint};
DWORD cDistPointAltNameEntry = 0;
BOOL fAddXCertProp = FALSE;
BOOL fDeleteXCertProp = FALSE;
BYTE *pbEncodedXCert = NULL;
DWORD cbEncodedXCert;
HANDLE hStore;
while (--argc>0)
{
if (**++argv == '-')
{
switch(argv[0][1])
{
case 'D':
{
char *pszHash = argv[0]+2;
int cchHash = strlen(pszHash);
char rgch[3];
if (!(cchHash == 32 || cchHash == 40)) {
printf("Need 32 digits (MD5) or 40 digits (SHA) ");
printf("for hash , not %d digits\n", cchHash);
goto BadUsage;
}
if (32 == cchHash)
dwFindCmp = CERT_COMPARE_MD5_HASH;
else
dwFindCmp = CERT_COMPARE_SHA1_HASH;
cbHash = 0;
while (cchHash > 0) {
rgch[0] = *pszHash++;
rgch[1] = *pszHash++;
rgch[2] = '\0';
rgbHash[cbHash++] = (BYTE) strtoul(rgch, NULL, 16);
cchHash -= 2;
}
}
break;
case 'S':
dwFindInfo = CERT_INFO_SUBJECT_FLAG;
pszFindInfo = "subject";
break;
case 'I':
dwFindInfo = CERT_INFO_ISSUER_FLAG;
pszFindInfo = "issuer";
break;
case 'f':
pszCertFilename = argv[0]+2;
if (*pszCertFilename == '\0') {
printf("Need to specify filename\n");
goto BadUsage;
}
dwFindCmp = CERT_COMPARE_NAME;
break;
case 'o':
rgRDNAttr[cRDNAttr].pszObjId = argv[0] + 2;
break;
case 't':
rgRDNAttr[cRDNAttr].dwValueType =
(DWORD) strtoul(argv[0]+2, NULL, 0);
break;
case 'a':
if (cRDNAttr >= MAX_RDN_ATTR) {
printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR);
goto BadUsage;
}
rgRDNAttr[cRDNAttr].Value.cbData = strlen(argv[0] + 2);
if (rgRDNAttr[cRDNAttr].Value.cbData == 0)
rgRDNAttr[cRDNAttr].Value.pbData = NULL;
else
rgRDNAttr[cRDNAttr].Value.pbData = (BYTE *) (argv[0] + 2);
cRDNAttr++;
dwFindCmp = CERT_COMPARE_ATTR;
break;
case 'A':
if (cRDNAttr >= MAX_RDN_ATTR) {
printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR);
goto BadUsage;
}
rgRDNAttr[cRDNAttr].Value.pbData =
(BYTE *) AllocAndSzToWsz(argv[0]+2);
rgRDNAttr[cRDNAttr].Value.cbData = 0;
cRDNAttr++;
dwFindFlags |= CERT_UNICODE_IS_RDN_ATTRS_FLAG;
dwFindCmp = CERT_COMPARE_ATTR;
break;
case 'C':
dwFindFlags |= CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG;
break;
case 'U':
if (CtlUsage.cUsageIdentifier >= MAX_USAGE_ID) {
printf("Maximum number of Usage Identifiers: %d\n",
MAX_USAGE_ID);
goto BadUsage;
}
if (0 < strlen(argv[0] + 2))
rgpszUsageId[CtlUsage.cUsageIdentifier++] = argv[0] + 2;
dwFindCmp = CERT_COMPARE_CTL_USAGE;
break;
case 'F':
dwFindFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
break;
case 'p':
pszPutFilename = argv[0]+2;
if (*pszPutFilename == '\0') {
printf("Need to specify filename\n");
goto BadUsage;
}
break;
case 'd':
fDelete = TRUE;
break;
case '7':
fPKCS7Save = TRUE;
if (argv[0][2])
pszSaveFilename = argv[0]+2;
break;
case 'b':
dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
break;
case 'v':
dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
break;
case 'u':
dwDisplayFlags |= DISPLAY_UI_FLAG;
break;
case 'c':
dwDisplayFlags |= DISPLAY_CHECK_FLAG;
break;
case 'q':
fQuiet = TRUE;
break;
case 's':
fSystemStore = TRUE;
break;
case 'e':
dwCertEncodingType = (DWORD) strtoul(argv[0]+2, NULL, 0);
break;
case 'x':
case 'X':
fAddXCertProp = TRUE;
if (argv[0][2] == 0)
;
else if (0 == _stricmp(argv[0]+2, "Delete"))
fDeleteXCertProp = TRUE;
else if (isdigit(argv[0][2]))
XCertInfo.dwSyncDeltaTime =
(DWORD) strtoul(argv[0]+2, NULL, 0);
else {
if (cDistPointAltNameEntry >=
MAX_DIST_POINT_ALT_NAME_ENTRY) {
printf("Exceeded DistPointAltNameEntry MaxCount(%d)\n",
MAX_DIST_POINT_ALT_NAME_ENTRY);
goto BadUsage;
}
if (XCertInfo.cDistPoint == 0 ||
argv[0][1] == 'x') {
if (XCertInfo.cDistPoint >= MAX_DIST_POINT) {
printf("Exceeded DistPoint MaxCount(%d)\n",
MAX_DIST_POINT);
goto BadUsage;
}
XCertInfo.rgDistPoint[XCertInfo.cDistPoint].cAltEntry =
0;
XCertInfo.rgDistPoint[XCertInfo.cDistPoint].rgAltEntry =
&rgDistPointAltNameEntry[cDistPointAltNameEntry];
XCertInfo.cDistPoint++;
}
rgDistPointAltNameEntry[cDistPointAltNameEntry].dwAltNameChoice =
CERT_ALT_NAME_URL;
rgDistPointAltNameEntry[cDistPointAltNameEntry].pwszURL =
AllocAndSzToWsz(argv[0]+2);
cDistPointAltNameEntry++;
XCertInfo.rgDistPoint[XCertInfo.cDistPoint - 1].cAltEntry++;
}
break;
case 'h':
default:
goto BadUsage;
}
} else {
if (pszStoreFilename == NULL)
pszStoreFilename = argv[0];
else if (pszFindStr == NULL) {
if (dwFindCmp != CERT_COMPARE_ANY) {
printf("Invalid options for <Name String>\n");
goto BadUsage;
}
dwFindCmp = CERT_COMPARE_NAME_STR_A;
if (dwFindInfo == 0) {
dwFindInfo = CERT_INFO_SUBJECT_FLAG;
pszFindInfo = "subject";
}
pszFindStr = argv[0];
} else {
printf("Too many arguments\n");
goto BadUsage;
}
}
}
printf("command line: %s\n", GetCommandLine());
if (dwDisplayFlags & DISPLAY_VERBOSE_FLAG)
dwDisplayFlags &= ~DISPLAY_BRIEF_FLAG;
if (pszStoreFilename == NULL) {
printf("missing store filename\n");
goto BadUsage;
}
if (pszSaveFilename == NULL) {
if (!fSystemStore)
pszSaveFilename = pszStoreFilename;
}
dwFindType = dwFindCmp << CERT_COMPARE_SHIFT | dwFindInfo;
switch (dwFindType) {
case CERT_FIND_ANY:
if (dwDisplayFlags & DISPLAY_UI_FLAG)
printf("UI certificate selection\n");
else
printf("Finding all certificates\n");
break;
case CERT_FIND_MD5_HASH:
case CERT_FIND_SHA1_HASH:
{
if (CERT_FIND_MD5_HASH == dwFindType)
printf("Finding MD5 hash:: ");
else
printf("Finding SHA1 hash:: ");
DWORD cb = cbHash;
BYTE *pb = rgbHash;
for (; cb > 0; cb--, pb++)
printf("%02X", *pb);
printf("\n");
}
HashBlob.pbData = rgbHash;
HashBlob.cbData = cbHash;
pvFindPara = &HashBlob;
break;
case CERT_FIND_SUBJECT_NAME:
case CERT_FIND_ISSUER_NAME:
printf("Finding %s name using CertFile %s\n",
pszFindInfo, pszCertFilename);
if (!AllocAndGetEncodedName(pszCertFilename, dwFindInfo,
&pbEncodedName, &cbEncodedName))
goto ErrorReturn;
NameBlob.pbData = pbEncodedName;
NameBlob.cbData = cbEncodedName;
pvFindPara = &NameBlob;
break;
case CERT_FIND_SUBJECT_ATTR:
case CERT_FIND_ISSUER_ATTR:
printf("Finding %s name using attributes::\n", pszFindInfo);
DisplayFindAttr(cRDNAttr, rgRDNAttr);
NameRDN.cRDNAttr = cRDNAttr;
NameRDN.rgRDNAttr = rgRDNAttr;
pvFindPara = &NameRDN;
break;
case CERT_FIND_SUBJECT_STR_A:
case CERT_FIND_ISSUER_STR_A:
printf("Finding %s name matching:: %s\n", pszFindInfo, pszFindStr);
pvFindPara = pszFindStr;
break;
case CERT_FIND_CTL_USAGE:
if (dwFindFlags & CERT_FIND_OPTIONAL_CTL_USAGE_FLAG)
printf("Enabled:: CERT_FIND_OPTIONAL_CTL_USAGE_FLAG\n");
if (dwFindFlags & CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG)
printf("Enabled:: CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG\n");
if (dwFindFlags & CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG)
printf("Enabled:: CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG\n");
if (dwFindFlags & CERT_FIND_NO_CTL_USAGE_FLAG)
printf("Enabled:: CERT_FIND_NO_CTL_USAGE_FLAG\n");
if (0 == CtlUsage.cUsageIdentifier) {
printf("No Usage Identifiers\n");
pvFindPara = NULL;
} else {
LPSTR *ppszId = CtlUsage.rgpszUsageIdentifier;
DWORD i;
printf("Usage Identifiers::\n");
for (i = 0; i < CtlUsage.cUsageIdentifier; i++, ppszId++)
printf(" [%d] %s\n", i, *ppszId);
pvFindPara = &CtlUsage;
}
break;
default:
printf("Bad dwFindType: %x\n", dwFindType);
goto BadUsage;
}
if (fAddXCertProp && !fDeleteXCertProp) {
printf("Encoding Cross Certificate Property\n");
if (!AllocAndEncodeObject(
X509_CROSS_CERT_DIST_POINTS,
&XCertInfo,
&pbEncodedXCert,
&cbEncodedXCert))
goto ErrorReturn;
}
// Attempt to open the store
hStore = OpenStore(fSystemStore, pszStoreFilename);
if (hStore == NULL)
return -1;
if (CERT_FIND_ANY == dwFindType && (dwDisplayFlags & DISPLAY_UI_FLAG)) {
SelectCertficateFromStoreUI(hStore, dwDisplayFlags);
} else {
int i;
PCCERT_CONTEXT pCert = NULL;
PCCERT_CONTEXT pDeleteCert = NULL;
for (i = 0;; i++) {
pCert = CertFindCertificateInStore(
hStore,
dwCertEncodingType,
dwFindFlags,
dwFindType,
pvFindPara,
pCert
);
if (pCert == NULL) {
if (i == 0) {
if (GetLastError() == CRYPT_E_NOT_FOUND)
printf(
"CertFindCertificateInStore warning => cert not found\n");
else
PrintLastError("CertFindCertificateInStore");
}
break;
}
if (fDeleteXCertProp) {
printf("Deleting Cross Certificate Property from following =>\n");
if (!CertSetCertificateContextProperty(
pCert,
CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
0, // dwFlags
NULL
))
PrintLastError("CertSetCertificateContextProperty(Delete)");
} else if (fAddXCertProp) {
CRYPT_DATA_BLOB Data;
printf("Adding Cross Certificate Property to following =>\n");
Data.pbData = pbEncodedXCert;
Data.cbData = cbEncodedXCert;
if (!CertSetCertificateContextProperty(
pCert,
CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
0, // dwFlags
&Data
))
PrintLastError("CertSetCertificateContextProperty");
}
if (!fQuiet) {
printf("===== %d =====\n", i);
DisplayCert(pCert, dwDisplayFlags);
}
if (pszPutFilename) {
printf("Putting\n");
if (!WriteDERToFile(
pszPutFilename,
pCert->pbCertEncoded,
pCert->cbCertEncoded
))
PrintLastError("Put Cert::WriteDERToFile");
}
if (fDelete) {
printf("Deleting\n");
if (pDeleteCert) {
if (!CertDeleteCertificateFromStore(pDeleteCert))
PrintLastError("CertDeleteCertificateFromStore");
}
pDeleteCert = CertDuplicateCertificateContext(pCert);
}
}
if (pDeleteCert) {
if (!CertDeleteCertificateFromStore(pDeleteCert))
PrintLastError("CertDeleteCertificateFromStore");
if (!fSystemStore)
SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
} else if (fAddXCertProp || fDeleteXCertProp) {
if (!fSystemStore)
SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
}
}
if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore");
if (pbEncodedName)
TestFree(pbEncodedName);
ReturnStatus = 0;
goto CommonReturn;
BadUsage:
Usage();
ErrorReturn:
ReturnStatus = -1;
CommonReturn:
while (cRDNAttr--) {
if (0 == rgRDNAttr[cRDNAttr].Value.cbData &&
rgRDNAttr[cRDNAttr].Value.pbData)
// Allocated for unicode
TestFree(rgRDNAttr[cRDNAttr].Value.pbData);
}
while (cDistPointAltNameEntry--)
TestFree(rgDistPointAltNameEntry[cDistPointAltNameEntry].pwszURL);
TestFree(pbEncodedXCert);
if (!ReturnStatus)
printf("Passed\n");
else
printf("Failed\n");
return ReturnStatus;
}