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.
 
 
 
 
 
 

678 lines
25 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: tstore5.cpp
//
// Contents: Test certificate store collection and context link functions
//
// See Usage() for a list of test options.
//
//
// Functions: main
//
// History: 06-Sep-97 philh created
//--------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "certtest.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
static void Usage(void)
{
printf("Usage: tstore5 [options] <StoreName1> <StoreName2>\n");
printf("Options are:\n");
printf(" -h - This message\n");
printf(" -C - Collection tests (default)\n");
printf(" -L - Context Link tests\n");
printf(" -C -L - Context Links enumerated in Collection\n");
printf(" -R - Replace contexts that exist\n");
printf(" -A - Always add a new context\n");
printf(" -P - Set property\n");
printf(" -v - Verbose\n");
printf(" -b - Brief\n");
printf(" -f<number> - Open System Store Flags\n");
printf("\n");
printf("If <StoreName> has embedded \".\", File. Otherwise System Store\n");
}
int _cdecl main(int argc, char * argv[])
{
int status;
DWORD i;
DWORD dwDisplayFlags = 0;
DWORD dwOpenFlags = 0;
DWORD dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
BOOL fVerbose = FALSE;
BOOL fProperty = FALSE;
#define COLLECTION_TEST_FLAG 0x1
#define LINK_TEST_FLAG 0x2
DWORD dwTestFlags = 0;
#define MAX_STORE_CNT 32
DWORD dwStoreCnt = 0;
LPCSTR rgpszStore[MAX_STORE_CNT];
HCERTSTORE rghStore[MAX_STORE_CNT];
memset(rghStore, 0, sizeof(rghStore));
HCERTSTORE hCollectionStore = NULL;
HCERTSTORE hLinkStore = NULL;
PCCERT_CONTEXT pSiblingCert = NULL;
PCCRL_CONTEXT pSiblingCrl = NULL;
PCCTL_CONTEXT pSiblingCtl = NULL;
PCCERT_CONTEXT pLinkCert = NULL;
PCCRL_CONTEXT pLinkCrl = NULL;
PCCTL_CONTEXT pLinkCtl = NULL;
DWORD dwCertAddCnt = 0;
DWORD dwCrlAddCnt = 0;
DWORD dwCtlAddCnt = 0;
while (--argc>0) {
if (**++argv == '-')
{
switch(argv[0][1])
{
case 'C':
dwTestFlags |= COLLECTION_TEST_FLAG;
break;
case 'L':
dwTestFlags |= LINK_TEST_FLAG;
break;
case 'v':
fVerbose = TRUE;
dwDisplayFlags = DISPLAY_VERBOSE_FLAG;
break;
case 'b':
dwDisplayFlags = DISPLAY_BRIEF_FLAG;
break;
case 'f':
dwOpenFlags = strtoul(argv[0]+2, NULL, 0);
break;
case 'R':
dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING;
break;
case 'A':
dwAddDisposition = CERT_STORE_ADD_ALWAYS;
break;
case 'P':
fProperty = TRUE;
break;
case 'h':
default:
goto BadUsage;
}
} else {
if (MAX_STORE_CNT <= dwStoreCnt) {
printf("Too many store names starting with:: %s\n", argv[0]);
goto BadUsage;
}
rgpszStore[dwStoreCnt++] = argv[0];
}
}
printf("command line: %s\n", GetCommandLine());
if (0 == dwStoreCnt) {
printf("Missing store names\n");
goto BadUsage;
}
// Attempt to open the store names
for (i = 0; i < dwStoreCnt; i++) {
DWORD dwFlags;
BOOL fSystemStore;
LPCSTR psz;
char ch;
// Check if store name has an embedded ".".
fSystemStore = TRUE;
psz = rgpszStore[i];
while (ch = *psz++) {
if ('.' == ch) {
fSystemStore = FALSE;
break;
}
}
if (fSystemStore &&
0 == (dwOpenFlags & CERT_SYSTEM_STORE_LOCATION_MASK))
dwFlags = dwOpenFlags | CERT_SYSTEM_STORE_CURRENT_USER;
else
dwFlags = dwOpenFlags;
rghStore[i] = OpenSystemStoreOrFile(fSystemStore, rgpszStore[i],
dwOpenFlags);
}
if (0 == dwTestFlags)
dwTestFlags = COLLECTION_TEST_FLAG;
if (dwTestFlags & COLLECTION_TEST_FLAG) {
// Open collection store
hCollectionStore = CertOpenStore(
CERT_STORE_PROV_COLLECTION,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
);
if (NULL == hCollectionStore) {
PrintLastError("CertOpenStore(COLLECTION)");
goto ErrorReturn;
}
}
if (dwTestFlags & LINK_TEST_FLAG) {
HCERTSTORE hParentStore;
// Open memory store to hold the context links
hLinkStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
);
if (NULL == hLinkStore) {
PrintLastError("CertOpenStore(MEMORY)");
goto ErrorReturn;
}
if (dwTestFlags & COLLECTION_TEST_FLAG) {
if (!CertAddStoreToCollection(
hCollectionStore,
hLinkStore,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
0 // dwPriority
)) {
PrintLastError("CertAddStoreToCollection");
goto ErrorReturn;
}
hParentStore = hCollectionStore;
} else
hParentStore = hLinkStore;
// Loop through stores and add the certificate, CRL and CTL contexts
// as links
for (i = 0; i < dwStoreCnt; i++) {
HCERTSTORE hStore;
PCCERT_CONTEXT pCert;
PCCRL_CONTEXT pCrl;
PCCTL_CONTEXT pCtl;
DWORD dwCrlFlags;
if (NULL == (hStore = rghStore[i]))
continue;
pCert = NULL;
while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
if (!CertAddCertificateLinkToStore(
hLinkStore,
pCert,
dwAddDisposition,
(0 == dwCertAddCnt) ? &pLinkCert : NULL
)) {
PrintLastError("CertAddCertificateLinkToStore");
goto ErrorReturn;
}
if (0 == dwCertAddCnt) {
if (NULL == pLinkCert) {
printf("failed => didn't return cert link\n");
goto ErrorReturn;
}
pSiblingCert = CertDuplicateCertificateContext(pCert);
}
dwCertAddCnt++;
if (CertAddCertificateLinkToStore(
hLinkStore,
pCert,
CERT_STORE_ADD_NEW,
NULL // ppStoreCert
))
printf("failed => expected CertAddCertificateLinkToStore(ADD_NEW) to fail\n");
else if (CRYPT_E_EXISTS != GetLastError()) {
PrintLastError("CertAddCertificateLinkToStore(ADD_NEW)");
printf("failed => expected CRYPT_E_EXISTS\n");
}
}
dwCrlFlags = 0;
pCrl = NULL;
while (pCrl = CertGetCRLFromStore(hStore, NULL, pCrl,
&dwCrlFlags)) {
if (!CertAddCRLLinkToStore(
hLinkStore,
pCrl,
dwAddDisposition,
(0 == dwCrlAddCnt) ? &pLinkCrl : NULL
)) {
PrintLastError("CertAddCRLLinkToStore");
goto ErrorReturn;
}
if (0 == dwCrlAddCnt) {
if (NULL == pLinkCrl) {
printf("failed => didn't return crl link\n");
goto ErrorReturn;
}
pSiblingCrl = CertDuplicateCRLContext(pCrl);
}
dwCrlAddCnt++;
if (CertAddCRLLinkToStore(
hLinkStore,
pCrl,
CERT_STORE_ADD_NEW,
NULL // ppStoreCrl
))
printf("failed => expected CertAddCRLLinkToStore(ADD_NEW) to fail\n");
else if (CRYPT_E_EXISTS != GetLastError()) {
PrintLastError("CertAddCRLLinkToStore(ADD_NEW)");
printf("failed => expected CRYPT_E_EXISTS\n");
}
}
pCtl = NULL;
while (pCtl = CertEnumCTLsInStore(hStore, pCtl)) {
if (!CertAddCTLLinkToStore(
hLinkStore,
pCtl,
dwAddDisposition,
(0 == dwCtlAddCnt) ? &pLinkCtl : NULL
)) {
PrintLastError("CertAddCTLLinkToStore");
goto ErrorReturn;
}
if (0 == dwCtlAddCnt) {
if (NULL == pLinkCtl) {
printf("failed => didn't return crl link\n");
goto ErrorReturn;
}
pSiblingCtl = CertDuplicateCTLContext(pCtl);
}
dwCtlAddCnt++;
if (CertAddCTLLinkToStore(
hLinkStore,
pCtl,
CERT_STORE_ADD_NEW,
NULL // ppStoreCtl
))
printf("failed => expected CertAddCTLLinkToStore(ADD_NEW) to fail\n");
else if (CRYPT_E_EXISTS != GetLastError()) {
PrintLastError("CertAddCTLLinkToStore(ADD_NEW)");
printf("failed => expected CRYPT_E_EXISTS\n");
}
}
}
printf("Added %d Certificates\n", dwCertAddCnt);
printf("Added %d CRLs\n", dwCrlAddCnt);
printf("Added %d CTLs\n", dwCtlAddCnt);
printf("\n");
printf("$$$$$ Certificate Context Links $$$$$\n");
DisplayStore(hParentStore, dwDisplayFlags);
if (fProperty) {
CRYPT_DATA_BLOB LinkSetData;
BYTE rgbLinkSet[4] = {0xDE, 0xAD, 0xBE, 0xEF};
LinkSetData.pbData = rgbLinkSet;
LinkSetData.cbData = sizeof(rgbLinkSet);
CRYPT_DATA_BLOB SiblingSetData;
BYTE rgbSiblingSet[4] = {0xDE, 0xAF, 0xCA, 0xFE};
SiblingSetData.pbData = rgbSiblingSet;
SiblingSetData.cbData = sizeof(rgbSiblingSet);
BYTE rgbGet[4];
DWORD cbData;
if (pLinkCert) {
printf("Setting Certificate Context Link Property\n");
// First make sure the property is deleted
CertSetCertificateContextProperty(
pLinkCert,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
NULL
);
cbData = sizeof(rgbGet);
if (CertGetCertificateContextProperty(
pLinkCert,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected link property to be deleted\n");
PrintLastError("CertGetCertificateContextProperty(LINK)");
}
cbData = sizeof(rgbGet);
if (CertGetCertificateContextProperty(
pSiblingCert,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected sibling property to be deleted\n");
PrintLastError("CertGetCertificateContextProperty(SIBLING)");
}
// Set property in link. It should also be visible in sibling
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCertificateContextProperty(
pLinkCert,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&LinkSetData
))
PrintLastError("CertSetCertificateContextProperty(LINK)");
else if (!CertGetCertificateContextProperty(
pSiblingCert,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCertificateContextProperty(SIBLING)");
else if (cbData != sizeof(rgbLinkSet) ||
0 != memcmp(rgbGet, rgbLinkSet, cbData))
printf("failed => cert sibling not updated with link property\n");
// Set property in sibling. It should also be visible in link
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCertificateContextProperty(
pSiblingCert,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&SiblingSetData
))
PrintLastError("CertSetCertificateContextProperty(SIBLING)");
else if (!CertGetCertificateContextProperty(
pLinkCert,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCertificateContextProperty(LINK)");
else if (cbData != sizeof(rgbSiblingSet) ||
0 != memcmp(rgbGet, rgbSiblingSet, cbData))
printf("failed => cert link not updated with sibling property\n");
}
if (pLinkCrl) {
printf("Setting CRL Context Link Property\n");
// First make sure the property is deleted
CertSetCRLContextProperty(
pLinkCrl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
NULL
);
cbData = sizeof(rgbGet);
if (CertGetCRLContextProperty(
pLinkCrl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected link property to be deleted\n");
PrintLastError("CertGetCRLContextProperty(LINK)");
}
cbData = sizeof(rgbGet);
if (CertGetCRLContextProperty(
pSiblingCrl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected sibling property to be deleted\n");
PrintLastError("CertGetCRLContextProperty(SIBLING)");
}
// Set property in link. It should also be visible in sibling
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCRLContextProperty(
pLinkCrl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&LinkSetData
))
PrintLastError("CertSetCRLContextProperty(LINK)");
else if (!CertGetCRLContextProperty(
pSiblingCrl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCRLContextProperty(SIBLING)");
else if (cbData != sizeof(rgbLinkSet) ||
0 != memcmp(rgbGet, rgbLinkSet, cbData))
printf("failed => CRL sibling not updated with link property\n");
// Set property in sibling. It should also be visible in link
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCRLContextProperty(
pSiblingCrl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&SiblingSetData
))
PrintLastError("CertSetCRLContextProperty(SIBLING)");
else if (!CertGetCRLContextProperty(
pLinkCrl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCRLContextProperty(LINK)");
else if (cbData != sizeof(rgbSiblingSet) ||
0 != memcmp(rgbGet, rgbSiblingSet, cbData))
printf("failed => CRL link not updated with sibling property\n");
}
if (pLinkCtl) {
printf("Setting CTL Context Link Property\n");
// First make sure the property is deleted
CertSetCTLContextProperty(
pLinkCtl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
NULL
);
cbData = sizeof(rgbGet);
if (CertGetCTLContextProperty(
pLinkCtl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected link property to be deleted\n");
PrintLastError("CertGetCTLContextProperty(LINK)");
}
cbData = sizeof(rgbGet);
if (CertGetCTLContextProperty(
pSiblingCtl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData) || CRYPT_E_NOT_FOUND != GetLastError()) {
printf("failed => expected sibling property to be deleted\n");
PrintLastError("CertGetCTLContextProperty(SIBLING)");
}
// Set property in link. It should also be visible in sibling
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCTLContextProperty(
pLinkCtl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&LinkSetData
))
PrintLastError("CertSetCTLContextProperty(LINK)");
else if (!CertGetCTLContextProperty(
pSiblingCtl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCTLContextProperty(SIBLING)");
else if (cbData != sizeof(rgbLinkSet) ||
0 != memcmp(rgbGet, rgbLinkSet, cbData))
printf("failed => CTL sibling not updated with link property\n");
// Set property in sibling. It should also be visible in link
cbData = sizeof(rgbGet);
memset(rgbGet, 0, sizeof(rgbGet));
if (!CertSetCTLContextProperty(
pSiblingCtl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&SiblingSetData
))
PrintLastError("CertSetCTLContextProperty(SIBLING)");
else if (!CertGetCTLContextProperty(
pLinkCtl,
CERT_FIRST_USER_PROP_ID,
rgbGet,
&cbData))
PrintLastError("CertGetCTLContextProperty(LINK)");
else if (cbData != sizeof(rgbSiblingSet) ||
0 != memcmp(rgbGet, rgbSiblingSet, cbData))
printf("failed => CTL link not updated with sibling property\n");
}
}
if (pLinkCert) {
CertDeleteCertificateFromStore(pLinkCert);
pLinkCert = NULL;
}
if (pLinkCrl) {
CertDeleteCRLFromStore(pLinkCrl);
pLinkCrl = NULL;
}
if (pLinkCtl) {
CertDeleteCTLFromStore(pLinkCtl);
pLinkCtl = NULL;
}
} else {
PCCERT_CONTEXT pCert;
for (i = 0; i < dwStoreCnt; i++) {
if (NULL == rghStore[i])
continue;
if (!CertAddStoreToCollection(
hCollectionStore,
rghStore[i],
0, // dwUpdateFlags
i // dwPriority
)) {
PrintLastError("CertAddStoreToCollection");
goto ErrorReturn;
}
}
printf("\n");
printf("$$$$$ Collection Stores $$$$$\n");
DisplayStore(hCollectionStore, dwDisplayFlags);
// Get first cert and duplicate. It should be in last store.
// Remove the last store and the second to last store. Continue
// the enumeration.
if (pCert = CertEnumCertificatesInStore(hCollectionStore, NULL)) {
pLinkCert = CertDuplicateCertificateContext(pCert);
if (0 < dwStoreCnt && rghStore[dwStoreCnt - 1]) {
CertRemoveStoreFromCollection(
hCollectionStore,
rghStore[dwStoreCnt - 1]
);
// Also close the last store
CertCloseStore(rghStore[dwStoreCnt - 1], 0);
rghStore[dwStoreCnt - 1] = NULL;
}
if (1 < dwStoreCnt && rghStore[dwStoreCnt - 2])
CertRemoveStoreFromCollection(
hCollectionStore,
rghStore[dwStoreCnt - 2]
);
printf("$$$$$ Collection Certificates after removing last 2 stores $$$$$\n");
i = 0;
while (pCert = CertEnumCertificatesInStore(hCollectionStore,
pCert)) {
printf("===== %d =====\n", i);
DisplayCert(pCert, DISPLAY_BRIEF_FLAG);
i++;
}
}
}
status = 0;
CommonReturn:
if (pSiblingCert)
CertFreeCertificateContext(pSiblingCert);
if (pLinkCert)
CertFreeCertificateContext(pLinkCert);
if (pLinkCrl)
CertFreeCRLContext(pLinkCrl);
if (pSiblingCrl)
CertFreeCRLContext(pSiblingCrl);
if (pLinkCtl)
CertFreeCTLContext(pLinkCtl);
if (pSiblingCtl)
CertFreeCTLContext(pSiblingCtl);
for (i = 1; i < dwStoreCnt; i++) {
if (rghStore[i])
CertCloseStore(rghStore[i], 0);
}
if (hCollectionStore) {
if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore(COLLECTION)");
}
if (hLinkStore) {
if (!CertCloseStore(hLinkStore, CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore(LINK)");
}
if (0 < dwStoreCnt) {
if (rghStore[0]) {
if (!CertCloseStore(rghStore[0], CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore(SIBLING[0])");
}
}
return status;
BadUsage:
Usage();
status = -1;
goto CommonReturn;
ErrorReturn:
status = -1;
goto CommonReturn;
}