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.
 
 
 
 
 
 

1169 lines
26 KiB

/*++
Copyright (C) Microsoft Corporation, 1996 - 1999
Module Name:
CheckSC
Abstract:
This application is used to provide a snapshot of the Calais (Smart Card
Resource Manager) service's status, and to display certificates on smart
cards via the common WinNT UI.
CheckSC -- describes the RM status and displays each available sc cert(s)
-r Readername -- for just one reader
-sig -- display signature key certs only
-ex -- display exchange key certs only
-nocert -- don't look for certs to display
-key -- verify keyset public key matches cert public key
Author:
Amanda Matlosz (AMatlosz) 07/14/1998
Environment:
Win32 Console App
Notes:
For use in NT5 public key rollout testing
--*/
/*++
need to include the following libs:
calaislb.lib (unicode build: calaislbw.lib)
winscard.lib
--*/
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
// #include <string.h>
// #include <stdarg.h>
#include <winscard.h>
#include <SCardLib.h>
#include <winsvc.h>
#include <scEvents.h>
#include <cryptui.h>
#ifndef SCARD_PROVIDER_CSP
#define SCARD_PROVIDER_CSP 2
#endif
#define KERB_PKINIT_CLIENT_CERT_TYPE szOID_PKIX_KP_CLIENT_AUTH
//
// Globals
//
int g_nKeys;
DWORD g_rgKeySet[2]; // { AT_KEYEXCHANGE , AT_SIGNATURE };
SCARDCONTEXT g_hSCardCtx;
LPTSTR g_szReaderName;
DWORD g_dwNumReaders;
BOOL g_fReaderNameAllocd;
BOOL g_fChain = FALSE;
BOOL g_fPublicKeyCheck = FALSE;
SCARD_READERSTATE* g_pReaderStatusArray;
const char* g_szEx = TEXT("exchange");
const char* g_szSig = TEXT("signature");
//
// Functions
//
///////////////////////////////////////////////////////////////////////////////
// DisplayUsage does easy UI
void DisplayUsage()
{
cout << "\n"
<< "CheckSC [-sig|-ex|-nocert|-chain|-key] [-r \"Readername\"]\n"
<< " -sig Displays only signature key certificates.\n"
<< " -ex Displays only signature key certificates.\n"
<< " -nocert Does not display smart card certificates.\n"
<< " -chain Check trust status.\n"
<< " -key Verify keyset public key matches certificate public key.\n"
<< endl;
}
///////////////////////////////////////////////////////////////////////////////
// ProcessCommandLine does the dirty work, sets behavior globals
bool ProcessCommandLine(DWORD cArgs, LPCTSTR rgszArgs[])
{
// set everything to default
g_szReaderName = NULL; // no reader
g_rgKeySet[0] = AT_KEYEXCHANGE; // certs for both kinds of keys
g_rgKeySet[1] = AT_SIGNATURE;
g_nKeys = 2;
if (cArgs == 1)
{
return true;
}
// For each arg, verify that it's a real arg and deal with it
bool fLookForReader = false;
bool fCertOptionSpecified = false;
bool fBogus = FALSE;
for (DWORD n=1; n<cArgs; n++)
{
if ('/' == *rgszArgs[n] || '-' == *rgszArgs[n])
{
if (0 == _stricmp("r", rgszArgs[n]+1*sizeof(TCHAR))) // reader
{
fLookForReader = true;
}
else if (0 == _stricmp("sig",rgszArgs[n]+1*sizeof(TCHAR))) // signature cert only
{
if (true == fCertOptionSpecified)
{
// bogus!
fBogus = true;
break;
}
g_rgKeySet[0] = AT_SIGNATURE;
g_nKeys = 1;
}
else if (0 == _stricmp("ex",rgszArgs[n]+1*sizeof(TCHAR))) // exchange cert only
{
if (true == fCertOptionSpecified)
{
// bogus!
fBogus = true;
break;
}
g_rgKeySet[0] = AT_KEYEXCHANGE;
g_nKeys = 1;
}
else if (0 == _stricmp("nocert",rgszArgs[n]+1*sizeof(TCHAR))) // no certs
{
if (true == fCertOptionSpecified)
{
// bogus!
fBogus = true;
break;
}
g_nKeys = 0;
}
else if (0 == _stricmp("chain",rgszArgs[n]+1*sizeof(TCHAR))) // verify chain
{
g_fChain = TRUE;
}
else if (0 == _stricmp("key",rgszArgs[n]+1*sizeof(TCHAR))) // verify cert & keyset
{
g_fPublicKeyCheck = TRUE;
}
else
{
// bogus!!
fBogus = true;
break;
}
}
else if (fLookForReader)
{
fLookForReader = false;
g_szReaderName = (LPTSTR)rgszArgs[n];
}
else
{
// Bogus!
fBogus = true;
break;
}
}
if (!fLookForReader && !fBogus)
{
// All's well, we're set to go
return true;
}
//
// educate user when args incorrect
//
DisplayUsage();
return false;
}
///////////////////////////////////////////////////////////////////////////////
bool IsCalaisRunning()
{
bool fCalaisUp = false;
HANDLE hCalaisStarted = NULL;
HMODULE hDll = GetModuleHandle( TEXT("WINSCARD.DLL") );
typedef HANDLE (WINAPI *PFN_SCARDACCESSSTARTEDEVENT)(VOID);
PFN_SCARDACCESSSTARTEDEVENT pSCardAccessStartedEvent;
pSCardAccessStartedEvent = (PFN_SCARDACCESSSTARTEDEVENT) GetProcAddress(hDll, "SCardAccessStartedEvent");
if (pSCardAccessStartedEvent)
{
hCalaisStarted = pSCardAccessStartedEvent();
}
if (hCalaisStarted)
{
if (WAIT_OBJECT_0 == WaitForSingleObject(hCalaisStarted, 1000))
{
fCalaisUp = true;
}
}
//
// Display status
//
if (fCalaisUp)
{
cout << "\n"
<< "The Microsoft Smart Card Resource Manager is running.\n"
<< endl;
}
else
{
cout << "\n"
<< "The Microsoft Smart Card Resource Manager is not running.\n"
<< endl;
}
//
// Clean up
//
return fCalaisUp;
}
///////////////////////////////////////////////////////////////////////////////
// DisplayReaderList tries to set g_hSCardCtx, get a list of currently available
// smart card readers, and display their status
void DisplayReaderList()
{
long lReturn = SCARD_S_SUCCESS;
cout << "Current reader/card status:\n" << endl;
// Acquire global SCARDCONTEXT from resource manager if possible
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
NULL,
NULL,
&g_hSCardCtx);
if (SCARD_S_SUCCESS != lReturn)
{
cout << "SCardEstablishContext failed for user scope.\n"
<< "A list of smart card readers cannot be determined.\n"
<< endl;
return;
}
// Build a readerstatus array from either a list of readers; or use the one the user specified
g_dwNumReaders = 0;
if (NULL == g_szReaderName)
{
DWORD dwAutoAllocate = SCARD_AUTOALLOCATE;
g_fReaderNameAllocd = true;
lReturn = SCardListReaders(g_hSCardCtx,
SCARD_DEFAULT_READERS,
(LPTSTR)&g_szReaderName,
&dwAutoAllocate);
if (SCARD_S_SUCCESS != lReturn)
{
TCHAR szMsg[128]; // %Xx
sprintf(szMsg,
"SCardListReaders failed for SCARD_ALL_READERS with: 0x%X.\n",
lReturn);
cout << szMsg;
if (SCARD_E_NO_READERS_AVAILABLE == lReturn)
{
cout << "No smart card readers are currently available.\n";
}
else
{
cout << "A list of smart card readers could not be determined.\n";
}
cout << endl;
return;
}
// Build a readerstatus array...
LPCTSTR szReaderName = g_szReaderName;
g_dwNumReaders = MStringCount(szReaderName);
g_pReaderStatusArray = new SCARD_READERSTATE[g_dwNumReaders];
::ZeroMemory((LPVOID)g_pReaderStatusArray, sizeof(g_pReaderStatusArray));
szReaderName = FirstString(szReaderName);
for (DWORD dwRdr = 0; NULL != szReaderName && dwRdr < g_dwNumReaders; szReaderName = NextString(szReaderName), dwRdr++)
{
g_pReaderStatusArray[dwRdr].szReader = (LPCTSTR)szReaderName;
g_pReaderStatusArray[dwRdr].dwCurrentState = SCARD_STATE_UNAWARE;
}
}
else
{
g_dwNumReaders = 1;
g_pReaderStatusArray = new SCARD_READERSTATE;
g_pReaderStatusArray->szReader = (LPCTSTR)g_szReaderName;
g_pReaderStatusArray->dwCurrentState = SCARD_STATE_UNAWARE;
}
// ...And get the reader status from the resource manager
lReturn = SCardGetStatusChange(g_hSCardCtx,
INFINITE, // hardly
g_pReaderStatusArray,
g_dwNumReaders);
if (SCARD_S_SUCCESS != lReturn)
{
TCHAR szMsg[128]; // %Xx
sprintf(szMsg,
"SCardGetStatusChange failed with: 0x%X.\n",
lReturn);
cout << szMsg << endl;
sprintf(szMsg,
"MStringCount returned %d readers.\n",
g_dwNumReaders);
cout << szMsg << endl;
return;
}
// Finally, display all reader information
DWORD dwState = 0;
for (DWORD dwRdrSt = 0; dwRdrSt < g_dwNumReaders; dwRdrSt++)
{
//--- reader: readerName\n
cout << TEXT("--- reader: ")
<< g_pReaderStatusArray[dwRdrSt].szReader
<< TEXT("\n");
//--- status: /bits/\n
bool fOr = false;
cout << TEXT("--- status: ");
dwState = g_pReaderStatusArray[dwRdrSt].dwEventState;
if (0 != (dwState & SCARD_STATE_UNKNOWN))
{
cout << TEXT("SCARD_STATE_UNKNOWN ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_UNAVAILABLE))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_UNAVAILABLE ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_EMPTY))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_EMPTY ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_PRESENT))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_PRESENT ";)
fOr = true;
}
if (0 != (dwState & SCARD_STATE_EXCLUSIVE))
{
if (fOr)
{
cout << TEXT("| ";)
}
cout << TEXT("SCARD_STATE_EXCLUSIVE ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_INUSE))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_INUSE ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_MUTE))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_MUTE ");
fOr = true;
}
if (0 != (dwState & SCARD_STATE_UNPOWERED))
{
if (fOr)
{
cout << TEXT("| ");
}
cout << TEXT("SCARD_STATE_UNPOWERED");
fOr = true;
}
cout << TEXT("\n");
//--- status: what scstatus would say\n
cout << TEXT("--- status: ");
// NO CARD
if(dwState & SCARD_STATE_EMPTY)
{
cout << TEXT("No card.");// SC_STATUS_NO_CARD;
}
// CARD in reader: SHARED, EXCLUSIVE, FREE, UNKNOWN ?
else if(dwState & SCARD_STATE_PRESENT)
{
if (dwState & SCARD_STATE_MUTE)
{
cout << TEXT("The card is unrecognized or not responding.");// SC_STATUS_UNKNOWN;
}
else if (dwState & SCARD_STATE_INUSE)
{
if(dwState & SCARD_STATE_EXCLUSIVE)
{
cout << TEXT("Card is in use exclusively by another process.");// SC_STATUS_EXCLUSIVE;
}
else
{
cout << TEXT("The card is being shared by a process.");// SC_STATUS_SHARED;
}
}
else
{
cout << TEXT("The card is available for use.");// SC_SATATUS_AVAILABLE;
}
}
// READER ERROR: at this point, something's gone wrong
else // dwState & SCARD_STATE_UNAVAILABLE
{
cout << TEXT("Card/Reader not responding.");// SC_STATUS_ERROR;
}
cout << TEXT("\n");
//- card name(s):\n\n
cout << TEXT("--- card: ");
if (0 < g_pReaderStatusArray[dwRdrSt].cbAtr)
{
//
// Get the name of the card
//
LPTSTR szCardName = NULL;
DWORD dwAutoAllocate = SCARD_AUTOALLOCATE;
lReturn = SCardListCards(g_hSCardCtx,
g_pReaderStatusArray[dwRdrSt].rgbAtr,
NULL,
0,
(LPTSTR)&szCardName,
&dwAutoAllocate);
if (SCARD_S_SUCCESS != lReturn || NULL == szCardName)
{
cout << TEXT("Unknown Card.");
}
else
{
LPCTSTR szName = szCardName;
bool fNotFirst = false;
for (szName = FirstString(szName); NULL != szName; szName = NextString(szName))
{
if (fNotFirst) cout << TEXT(", ");
cout << szName;
fNotFirst = true;
}
}
if (NULL != szCardName)
{
SCardFreeMemory(g_hSCardCtx, (PVOID)szCardName);
}
}
cout << TEXT("\n") << endl;
}
}
///////////////////////////////////////////////////////////////////////////////
// GetCertContext -- called by DisplayCerts
PCCERT_CONTEXT GetCertContext(HCRYPTPROV* phProv, HCRYPTKEY* phKey, DWORD dwKeySpec)
{
PCCERT_CONTEXT pCertCtx = NULL;
LONG lResult = SCARD_S_SUCCESS;
BOOL fSts = FALSE;
PCERT_PUBLIC_KEY_INFO pInfo = NULL;
CRYPT_KEY_PROV_INFO KeyProvInfo;
LPSTR szContainerName = NULL;
LPSTR szProvName = NULL;
LPWSTR wszContainerName = NULL;
LPWSTR wszProvName = NULL;
DWORD cbContainerName, cbProvName;
LPBYTE pbCert = NULL;
DWORD cbCertLen;
int nLen = 0;
//
// Get the cert from this key
//
fSts = CryptGetKeyParam(
*phKey,
KP_CERTIFICATE,
NULL,
&cbCertLen,
0);
if (!fSts)
{
lResult = GetLastError();
if (ERROR_MORE_DATA != lResult)
{
return NULL;
}
}
lResult = SCARD_S_SUCCESS;
pbCert = (LPBYTE)LocalAlloc(LPTR, cbCertLen);
if (NULL == pbCert)
{
return NULL;
}
fSts = CryptGetKeyParam(
*phKey,
KP_CERTIFICATE,
pbCert,
&cbCertLen,
0);
if (!fSts)
{
return NULL;
}
//
// Convert the certificate into a Cert Context.
//
pCertCtx = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pbCert,
cbCertLen);
if (NULL == pCertCtx)
{
lResult = GetLastError();
goto ErrorExit;
}
//
// Perform public key check
//
if (g_fPublicKeyCheck) // -key
{
cout << "\nPerforming public key matching test...\n";
DWORD dwPCBsize = 0;
fSts = CryptExportPublicKeyInfo(
*phProv, // in
dwKeySpec, // in
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // in
NULL,
&dwPCBsize // in, out
);
if (!fSts)
{
lResult = GetLastError();
TCHAR sz[256];
sprintf(sz,"CryptExportPublicKeyInfo failed: 0x%x\n ", lResult);
cout << sz;
goto ErrorExit;
}
if (dwPCBsize == 0)
{
lResult = SCARD_E_UNEXPECTED; // huh?
cout << "CryptExportPublicKeyInfo succeeded but returned size==0\n";
goto ErrorExit;
}
pInfo = (PCERT_PUBLIC_KEY_INFO)LocalAlloc(LPTR, dwPCBsize);
if (NULL == pInfo)
{
lResult = E_OUTOFMEMORY;
cout << "Could not complete key test; out of memory.\n";
goto ErrorExit;
}
fSts = CryptExportPublicKeyInfo(
*phProv,
dwKeySpec,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pInfo,
&dwPCBsize
);
if (!fSts)
{
lResult = GetLastError();
TCHAR sz[256];
sprintf(sz,"CryptExportPublicKeyInfo failed: 0x%x\n ", lResult);
cout << sz;
goto ErrorExit;
}
fSts = CertComparePublicKeyInfo(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pInfo, // from the private keyset
&(pCertCtx->pCertInfo->SubjectPublicKeyInfo) // public key from cert
);
if (!fSts)
{
lResult = GetLastError();
goto ErrorExit;
}
cout << "Public key matching test succeeded.\n";
}
//
// Associate cryptprovider w/ the private key property of this cert
//
// ... need the container name
fSts = CryptGetProvParam(
*phProv,
PP_CONTAINER,
NULL, // out
&cbContainerName, // in/out
0);
if (!fSts)
{
lResult = GetLastError();
goto ErrorExit;
}
szContainerName = (LPSTR)LocalAlloc(LPTR, cbContainerName);
fSts = CryptGetProvParam(
*phProv,
PP_CONTAINER,
(PBYTE)szContainerName,
&cbContainerName,
0);
if (!fSts)
{
lResult = GetLastError();
goto ErrorExit;
}
nLen = MultiByteToWideChar(
GetACP(),
MB_PRECOMPOSED,
szContainerName,
-1,
NULL,
0);
if (0 < nLen)
{
wszContainerName = (LPWSTR)LocalAlloc(LPTR, nLen*sizeof(WCHAR));
nLen = MultiByteToWideChar(
GetACP(),
MB_PRECOMPOSED,
szContainerName,
-1,
wszContainerName,
nLen);
if (0 == nLen)
{
lResult = GetLastError();
goto ErrorExit;
}
}
// ... need the provider name
fSts = CryptGetProvParam(
*phProv,
PP_NAME,
NULL, // out
&cbProvName, // in/out
0);
if (!fSts)
{
lResult = GetLastError();
goto ErrorExit;
}
szProvName = (LPSTR)LocalAlloc(LPTR, cbProvName);
fSts = CryptGetProvParam(
*phProv,
PP_NAME,
(PBYTE)szProvName, // out
&cbProvName, // in/out
0);
if (!fSts)
{
lResult = GetLastError();
goto ErrorExit;
}
nLen = MultiByteToWideChar(
GetACP(),
MB_PRECOMPOSED,
szProvName,
-1,
NULL,
0);
if (0 < nLen)
{
wszProvName = (LPWSTR)LocalAlloc(LPTR, nLen*sizeof(WCHAR));
nLen = MultiByteToWideChar(
GetACP(),
MB_PRECOMPOSED,
szProvName,
-1,
wszProvName,
nLen);
if (0 == nLen)
{
lResult = GetLastError();
goto ErrorExit;
}
}
//
// Set the cert context properties to reflect the prov info
//
KeyProvInfo.pwszContainerName = wszContainerName;
KeyProvInfo.pwszProvName = wszProvName;
KeyProvInfo.dwProvType = PROV_RSA_FULL;
KeyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
KeyProvInfo.cProvParam = 0;
KeyProvInfo.rgProvParam = NULL;
KeyProvInfo.dwKeySpec = dwKeySpec;
fSts = CertSetCertificateContextProperty(
pCertCtx,
CERT_KEY_PROV_INFO_PROP_ID,
0,
(void *)&KeyProvInfo);
if (!fSts)
{
lResult = GetLastError();
// the cert's been incorrectly created -- scrap it.
CertFreeCertificateContext(pCertCtx);
pCertCtx = NULL;
goto ErrorExit;
}
ErrorExit:
if (NULL != pInfo)
{
LocalFree(pInfo);
}
if(NULL != szContainerName)
{
LocalFree(szContainerName);
}
if(NULL != szProvName)
{
LocalFree(szProvName);
}
if(NULL != wszContainerName)
{
LocalFree(wszContainerName);
}
if(NULL != wszProvName)
{
LocalFree(wszProvName);
}
return pCertCtx;
}
/*++
DisplayChainInfo:
This code verifies that the SC cert is valid.
Uses identical code to KDC cert chaining engine.
Author:
Todds
--*/
DWORD
DisplayChainInfo(PCCERT_CONTEXT pCert)
{
BOOL fRet = FALSE;
DWORD dwErr = 0;
TCHAR sz[256];
CERT_CHAIN_PARA ChainParameters = {0};
LPSTR ClientAuthUsage = KERB_PKINIT_CLIENT_CERT_TYPE;
PCCERT_CHAIN_CONTEXT ChainContext = NULL;
ChainParameters.cbSize = sizeof(CERT_CHAIN_PARA);
ChainParameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
ChainParameters.RequestedUsage.Usage.cUsageIdentifier = 1;
ChainParameters.RequestedUsage.Usage.rgpszUsageIdentifier = &ClientAuthUsage;
if (!CertGetCertificateChain(
HCCE_LOCAL_MACHINE,
pCert,
NULL, // evaluate at current time
NULL, // no additional stores
&ChainParameters,
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
NULL, // reserved
&ChainContext
))
{
dwErr = GetLastError();
sprintf(sz,"CertGetCertificateChain failed: 0x%x\n ", dwErr);
cout << sz;
}
else
{
if (ChainContext->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR)
{
dwErr = ChainContext->TrustStatus.dwErrorStatus;
sprintf(sz,"CertGetCertificateChain TrustStatus failed, see wincrypt.h: 0x%x\n ", dwErr);
cout << sz;
}
}
if (ChainContext != NULL)
{
CertFreeCertificateChain(ChainContext);
}
return dwErr;
}
///////////////////////////////////////////////////////////////////////////////
// DisplayCerts
void DisplayCerts()
{
_ASSERTE(0 < g_nKeys);
// For each reader that has a card, load the CSP and display the cert
for (DWORD dw = 0; dw < g_dwNumReaders; dw++)
{
LPTSTR szCardName = NULL;
LPTSTR szCSPName = NULL;
if(0 >= g_pReaderStatusArray[dw].cbAtr)
{
// no point to do anymore work in this iteration
continue;
}
//
// Inform user of current test
//
cout << TEXT("\n=======================================================\n")
<< TEXT("Analyzing card in reader: ")
<< g_pReaderStatusArray[dw].szReader
<< TEXT("\n");
// Get the name of the card
DWORD dwAutoAllocate = SCARD_AUTOALLOCATE;
LONG lReturn = SCardListCards(g_hSCardCtx,
g_pReaderStatusArray[dw].rgbAtr,
NULL,
0,
(LPTSTR)&szCardName,
&dwAutoAllocate);
if (SCARD_S_SUCCESS == lReturn)
{
dwAutoAllocate = SCARD_AUTOALLOCATE;
lReturn = SCardGetCardTypeProviderName(
g_hSCardCtx,
szCardName,
SCARD_PROVIDER_CSP,
(LPTSTR)&szCSPName,
&dwAutoAllocate);
if (SCARD_S_SUCCESS != lReturn)
{
TCHAR szErr[16];
sprintf(szErr, "0x%X", lReturn);
cout << TEXT("Error on SCardGetCardTypeProviderName for ")
<< szCardName
<< TEXT(": ")
<< szErr
<< TEXT("\n");
}
}
// Prepare FullyQualifiedContainerName for CryptAcCntx call
TCHAR szFQCN[256];
sprintf(szFQCN, "\\\\.\\%s\\", g_pReaderStatusArray[dw].szReader);
HCRYPTPROV hProv = NULL;
if (SCARD_S_SUCCESS == lReturn)
{
BOOL fSts = CryptAcquireContext(
&hProv,
szFQCN, // default container via reader
szCSPName,
PROV_RSA_FULL,
CRYPT_SILENT);
// Enumerate the keys user specified and display the certs...
if (fSts)
{
for (int n=0; n<g_nKeys; n++)
{
// Which keyset is this?
LPCTSTR szKeyset = AT_KEYEXCHANGE==g_rgKeySet[n]?g_szEx:g_szSig;
HCRYPTKEY hKey = NULL;
// Get the key
fSts = CryptGetUserKey(
hProv,
g_rgKeySet[n],
&hKey);
if (!fSts)
{
lReturn = GetLastError();
if (NTE_NO_KEY == lReturn)
{
cout << TEXT("No ")
<< szKeyset
<< TEXT(" cert for reader: ")
<< g_pReaderStatusArray[dw].szReader
<< TEXT("\n");
}
else
{
TCHAR sz[256];
sprintf(sz,"An error (0x%X) occurred opening the ", lReturn);
cout << sz
<< szKeyset
<< TEXT(" key for reader: ")
<< g_pReaderStatusArray[dw].szReader
<< TEXT("\n");
}
// No point to work on this keyset anymore
continue;
}
// Get the cert for this key
PCCERT_CONTEXT pCertCtx = NULL;
pCertCtx = GetCertContext(&hProv, &hKey, g_rgKeySet[n]);
if (NULL != pCertCtx)
{
//
// If desired, attempt to build a certificate chain
//
if (g_fChain)
{
cout << TEXT("\nPerforming cert chain verification...\n");
if (S_OK != DisplayChainInfo(pCertCtx)) {
cout << TEXT("Cert did not chain!\n") << endl;
} else {
cout << TEXT("--- chain: Chain verifies.\n") << endl;
}
}
// call common UI to display m_pCertContext
// ( from cryptui.h ( cryptui.dll ) )
TCHAR szTitle[300];
sprintf(szTitle,
"%s : %s",
g_pReaderStatusArray[dw].szReader,
szKeyset);
CRYPTUI_VIEWCERTIFICATE_STRUCT CertViewInfo;
memset( &CertViewInfo, 0, sizeof( CertViewInfo ) );
CertViewInfo.dwSize = (sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
CertViewInfo.hwndParent = NULL;
CertViewInfo.szTitle = szTitle;
CertViewInfo.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES |
CRYPTUI_DISABLE_ADDTOSTORE;
CertViewInfo.pCertContext = pCertCtx;
BOOL fThrowAway = FALSE;
fSts = CryptUIDlgViewCertificate(&CertViewInfo, &fThrowAway);
// clean up certcontext
CertFreeCertificateContext(pCertCtx);
cout << TEXT("Displayed ")
<< szKeyset
<< TEXT(" cert for reader: ")
<< g_pReaderStatusArray[dw].szReader
<< TEXT("\n");
}
else
{
cout << TEXT("No cert retrieved for reader: ")
<< g_pReaderStatusArray[dw].szReader
<< TEXT("\n");
}
// clean up stuff
if (NULL != hKey)
{
CryptDestroyKey(hKey);
hKey = NULL;
}
}
}
else
{
TCHAR szErr[16];
sprintf(szErr, "0x%X", GetLastError());
cout << TEXT("Error on CryptAcquireContext for ")
<< szCSPName
<< TEXT(": ")
<< szErr
<< TEXT("\n");
}
}
// Clean up
if (NULL != szCSPName)
{
SCardFreeMemory(g_hSCardCtx, (PVOID)szCSPName);
szCSPName = NULL;
}
if (NULL != szCardName)
{
SCardFreeMemory(g_hSCardCtx, (PVOID)szCardName);
szCardName = NULL;
}
if (NULL != hProv)
{
CryptReleaseContext(hProv, 0);
hProv = NULL;
}
} // end for
}
/*++
main:
This is the main entry point for the test program.
It runs the test. Nice and simple, borrowed from DBarlow
Author:
Doug Barlow (dbarlow) 11/10/1997
Revisions:
AMatlosz 2/26/98
--*/
void __cdecl
main(DWORD cArgs,LPCTSTR rgszArgs[])
{
//init globals & locals
g_nKeys = 0;
g_rgKeySet[0] = g_rgKeySet[1] = 0;
g_hSCardCtx = NULL;
g_szReaderName = NULL;
g_fReaderNameAllocd = false;
g_dwNumReaders = 0;
g_pReaderStatusArray = NULL;
if (!ProcessCommandLine(cArgs, rgszArgs))
{
return;
}
if (IsCalaisRunning())
{
DisplayReaderList();
if (0 < g_nKeys)
{
DisplayCerts();
}
}
cout << TEXT("\ndone.") << endl;
// clean up globals
if (g_fReaderNameAllocd && NULL != g_szReaderName)
{
SCardFreeMemory(g_hSCardCtx, (PVOID)g_szReaderName);
}
if (NULL != g_hSCardCtx)
{
SCardReleaseContext(g_hSCardCtx);
}
}