//---------------------------------------------------------------------------

#pragma hdrstop
#include <windows.h>
#include <stdio.h>
#include <winldap.h>
#include <wincrypt.h>
//---------------------------------------------------------------------------
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define CERT_LDAP_STORE_OPENED_FLAG 0x40000
#define CERT_LDAP_STORE_UNBIND_FLAG 0x80000
#pragma argsused
typedef struct _CERT_LDAP_STORE_OPENED_PARA
{
   void        *pvLdapSessionHandle;   // The (LDAP *) handle returned by ldap_init
   LPCWSTR     pwszLdapUrl;
} CERT_LDAP_STORE_OPENED_PARA, *PCERT_LDAP_STORE_OPENED_PARA;
int main(int argc, char* argv[])
{
	HCERTSTORE hStore = NULL;
	DWORD dwErr;
	LDAP *hLdap=NULL;
	CERT_LDAP_STORE_OPENED_PARA  LdapPara;
	char  url   [260];
	WCHAR wszUrl[260];
	int code,s_len,version=LDAP_VERSION3;
	PCCERT_CONTEXT pCert=NULL;
	SYSTEMTIME notBefore;
	SYSTEMTIME notAfter;
	char out[256];
	int i=0;
	int month1=0;
	int month2 = 0;
	char month1_str[3];
	char month2_str[3];
	int day1 = 0;
	int day2 = 0;
	char day1_str[3];
	char day2_str[3];
	char date_string1[64];
	char date_string2[64];
try
{
	 // открываем контекст ldap и выполняем необходимые настройки
	 hLdap = ldap_init("127.0.0.1",62222);
	 if (!hLdap) throw GetLastError();
	 ldap_set_option(hLdap,LDAP_OPT_PROTOCOL_VERSION,(void*)&version);
	 code=ldap_bind_s(hLdap,"C=KZ;",NULL,LDAP_AUTH_SIMPLE);
	 if (code!=LDAP_SUCCESS) throw GetLastError();
	 memset(url,0,sizeof(url));
	 sprintf(url,"ldap://%s:%d/%s?userCertificate?base","127.0.0.1",62222,"C=KZ, O=Test, CN=Test");
	 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, url, -1,reinterpret_cast<LPWSTR>(wszUrl),260);
	 LdapPara.pvLdapSessionHandle=hLdap;
	 LdapPara.pwszLdapUrl=wszUrl;
	 // открываем хранилище ldap
	 hStore = CertOpenStore(CERT_STORE_PROV_LDAP,MY_ENCODING_TYPE,0,CERT_LDAP_STORE_OPENED_FLAG |CERT_LDAP_STORE_UNBIND_FLAG|CERT_STORE_READONLY_FLAG,&LdapPara);
	 if (hStore == NULL) throw GetLastError();
	 pCert=NULL;
	 i=0;
	while(1) // сертификатов с указанным dn может быть несколько. Необходимо перебрать все и найти нужный
	{
			pCert = CertFindCertificateInStore(hStore,MY_ENCODING_TYPE,0,CERT_FIND_ANY,NULL,pCert);
			if (pCert==NULL) break;
			if (!FileTimeToSystemTime(&pCert->pCertInfo->NotBefore,&notBefore)) throw 300;
			if (!FileTimeToSystemTime(&pCert->pCertInfo->NotAfter, &notAfter)) throw 300;
			int month1 = notBefore.wMonth;
			int month2 = notAfter.wMonth;

			memset(month1_str,0,3);

			memset(month2_str,0,3);
			if (month1<10) sprintf(month1_str,"0%d",month1); else  sprintf(month1_str,"%d",month1);
			if (month2<10) sprintf(month2_str,"0%d",month2); else  sprintf(month2_str,"%d",month2);
			day1 = notBefore.wDay;
			day2 = notAfter.wDay;

			memset(day1_str,0,3);
			memset(day2_str,0,3);
			if (day1<10) sprintf(day1_str,"0%d",day1); else  sprintf(day1_str,"%d",day1);
			if (day2<10) sprintf(day2_str,"0%d",day2); else  sprintf(day2_str,"%d",day2);

			sprintf(date_string1,"%d.%s.%s %d:%d:%d",notBefore.wYear,month1_str,day1_str,notBefore.wHour,notBefore.wMinute, notBefore.wSecond);
			sprintf(date_string2,"%d.%s.%s %d:%d:%d",notAfter.wYear,month2_str,day2_str,notAfter.wHour,notAfter.wMinute, notAfter.wSecond);

			sprintf(out,"Certificate #%d with NotBefore = %s and NotAfter = %s found\n",i+1,date_string1,date_string2);
			printf(out);
	}
}
catch(DWORD err)
{
   code =err;
}
}
//---------------------------------------------------------------------------
