/*
 * An example of enumerating Smart Card Logon certificates present on the MY certificate store
 *
 * Copyright (c) 2009 Mounir IDRASSI <mounir.idrassi@idrix.fr>. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 */


#ifndef _WIN32_WINNT		// Allow use of features specific to Windows 2000 or later.                   
#define _WIN32_WINNT 0x0500	// Change this to the appropriate value to target other versions of Windows.
#endif						

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#pragma comment(lib, "Crypt32")


int _tmain(int argc, _TCHAR* argv[])
{
	HCERTSTORE      hStoreHandle = NULL;
	PCCERT_CONTEXT  pCertContext = NULL;   
	CERT_ENHKEY_USAGE keyUsage;
	DWORD dwLogonCertsCount = 0;
	LPCTSTR pszStoreName = _T("MY");
	char szSCLogonOID[64];
	TCHAR szDisplayName[1024];

	// Open the "MY" certificate store
	hStoreHandle = CertOpenSystemStore(NULL, pszStoreName);
	if (hStoreHandle)
	{
		// populate the key usage structure with the Smart Card Logon OID
		strcpy(szSCLogonOID, szOID_KP_SMARTCARD_LOGON);
		keyUsage.cUsageIdentifier = 1;
		keyUsage.rgpszUsageIdentifier = (LPSTR*) LocalAlloc(0, sizeof(LPSTR));
		keyUsage.rgpszUsageIdentifier[0] = &szSCLogonOID[0];

		do
		{
			// Find certificates that contain the Smart Card Logon Enhanced Key Usage
			pCertContext = CertFindCertificateInStore(hStoreHandle,
								X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
								CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
								CERT_FIND_ENHKEY_USAGE,
								&keyUsage,
								pCertContext);
			
			if (pCertContext)
			{
				// Found
				dwLogonCertsCount++;
				// Print its subject
				if (CertNameToStr(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
						&pCertContext->pCertInfo->Subject,
						CERT_X500_NAME_STR,
						szDisplayName,
						1024))
				{
					_tprintf(_T("%d) Subject = %s\n"), dwLogonCertsCount, szDisplayName);
				}
			}
		} while (pCertContext);

		LocalFree(keyUsage.rgpszUsageIdentifier);
		CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);

		_tprintf(_T("Number of logon certificates found = %d\n"), dwLogonCertsCount);
	}
	else
	{
		_tprintf(_T("CertOpenSystemStore failed with error 0x%.8X\n"), GetLastError);
	}
			
	return 0;
}
