#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#ifdef _WIN32
  #include <windows.h>
  #define strlib "lib\\strlib.dll"
#else
  #define GetProcAddress dlsym
  #define FreeLibrary dlclose
  #include <string>
  #include  <unistd.h>
  #include  <dlfcn.h>
  #define strlib "lib/libstr.1.0.0.sl"
  #define _cdecl
  #define TRUE 1
  #define FALSE 0
#endif
#define CRYPT_VERIFYCONTEXT     0xF0000000
#ifndef _WIN32
  typedef unsigned long DWORD;
  typedef unsigned char BYTE;
  typedef void *HINSTANCE;
  typedef char CHAR;
#endif
typedef unsigned long hCERTSTORE;
typedef unsigned long hCERTCONTEXT;
typedef unsigned long hCERTCOLLECTION;
typedef unsigned long hCRYPTMSG;
typedef unsigned long HCRYPTPROV;
// Константы для хранилища :
#define STORE_HOST "127.0.0.1"
#define STORE_PORT "62222"
//Сертификат УЦ
#define CCERTIFICATE "MIICxTCCAm6gAwIBAgIgzTwle8CkqUG6HiBJktl0cfgg51ewTnL0DJYvhaplVlIwDgYKKwYBBAG1EQECAgUAMDM\
                      xEDAOBgNVBAMUB0FETUlOQ0ExEjAQBgNVBAoTCUdBTU1BVEVDSDELMAkGA1UEBhMCS1owIhgPMjAwODAxMDEwMT\
                      AxMDFaGA8yMDE4MDEwMTAxMDEwMVowMzEQMA4GA1UEAxQHQURNSU5DQTESMBAGA1UEChMJR0FNTUFURUNIMQswC\
                      QYDVQQGEwJLWjBjMA4GCisGAQQBtREBAgIFAANRAAYCAAA6qgAAAEVDMQACAADw2qYY1mq4OVlDu7PpgXZc8zZs\
                      hw6tM0INZDijLHnLOkSe+SaJGDBqd4gbOy2nGvRY3/fu4sLIJi8mUQVsPFjbo4IBQDCCATwwVQYDVR0jBE4wTIA\
                      gzTwle8CkqUG6HiBJktl0cfgg51ewTnL0DJYvhaplVlKhBocEfwAAAYIgzTwle8CkqUG6HiBJktl0cfgg51ewTn\
                      L0DJYvhaplVlIwKQYDVR0OBCIEIM08JXvApKlBuh4gSZLZdHH4IOdXsE5y9AyWL4WqZVZSMA4GA1UdDwEBAQQEA\
                      wIBBjASBgNVHRMBAQEECDAGAQEBAgECMIGTBgNVHSAEgYswgYgwgYUGCCsGAQQBtREDMHkwHwYIKwYBBQUHAgEW\
                      E2h0dHA6Ly93d3cuZ2FtbWEua3owVgYIKwYBBQUHAgIwSjAcFhXNyMsgw+Ds7OAg0uX17e7r7uPo/y4wAwIBARo\
                      qz/Do7OXwIO/u6+jy6OroIOjx7+7r/Ofu4uDt6P8g8eXw8uj06Org8uAuMA4GCisGAQQBtREBAgIFAANBAPzmGi\
                      BKNMZtSDuuPLgGIqzR+pP9a8SWdn+Z6pzrLbGiY5MRymCwl8TZxjOkIvJZzsv7ggxHqkkCS44SuEDSUDI="
//Список отозванных сертификатов
#define CRL          "MIIBKTCB0wIBATAOBgorBgEEAbURAQICBQAwMzEQMA4GA1UEAxQHQURNSU5DQTESMBAGA1UEChMJR0FNTUFURUN\
                      IMQswCQYDVQQGEwJLWhgPMjAwODAxMDEwMTAxMDFaGA8yMDA5MDEwMTAxMDEwMVowAKBlMGMwCgYDVR0UBAMCAQ\
                      EwVQYDVR0jBE4wTIAgzTwle8CkqUG6HiBJktl0cfgg51ewTnL0DJYvhaplVlKhBocEfwAAAYIgzTwle8CkqUG6H\
                      iBJktl0cfgg51ewTnL0DJYvhaplVlIwDgYKKwYBBAG1EQECAgUAA0EAOupS/vGyJ0RbFil5JI64Bi4P4A0ktGTh\
                      rO26G5BqgQAIsESh0WNqXnO7xeHGvSDe9xA4D4OfIjauNSdZ3YQrZg=="

typedef int (_cdecl *cspopencontext)
							(HCRYPTPROV *phProv,
							CHAR *pszContainer,
							DWORD dwProvType,
							DWORD dwProvParam,
							DWORD dwFlags,
							BYTE * pbSignature,
							DWORD dwSigLen,
							BYTE * pbContainer,
							DWORD * dwContLen,
							HINSTANCE *phLib);
typedef int (_cdecl *crtopenstore)
							(DWORD StoreProvider,
							HCRYPTPROV hProv,
							unsigned long dwFlags,
							bool  bFlag,
							const void *pvParam,
							hCERTSTORE *phStore);
typedef int (_cdecl *crtclosestore)                     (hCERTSTORE *phStore);
typedef int (_cdecl *cspclosecontext)                   (HCRYPTPROV *phProv);
typedef char* (_cdecl *errorstring)                     (const int err);
typedef int (_cdecl *basetobin)
							(unsigned char *inBuf,
							long inSize,
							unsigned char *ouBuf,
							long *outSize);
typedef int (_cdecl *crptverifycrlsignature)
							(const hCERTSTORE hStore,
							const unsigned char *crlBody,
							const unsigned long crlSize,
							const unsigned char *CABody,
							const unsigned long caSize);							
							
cspopencontext					CSPOpenContext;
crtopenstore					CrtOpenStore;
crtclosestore					CrtCloseStore;
cspclosecontext					CSPCloseContext;
errorstring						ErrorString;	
basetobin						BaseToBin;								
crptverifycrlsignature			CrptVerifyCRLSignature;
HINSTANCE load_lib(char *lib)
{
   #ifdef _WIN32
	  return LoadLibraryA(lib);
   #else
	  return dlopen(lib,RTLD_LAZY);
   #endif
}
void lib_free( HINSTANCE Instance )
{
#ifdef _WIN32
  FreeLibrary(Instance);
#else
  dlclose(Instance);
#endif
}
int get_func(HINSTANCE lib)
{
   CSPOpenContext = (cspopencontext) GetProcAddress(lib,"CSPOpenContext");
   if(!CSPOpenContext)
   {
       printf("error load function - %s", "CSPOpenContext");
       return 1;
   }
   CrtOpenStore = (crtopenstore) GetProcAddress(lib,"CrtOpenStore");
   if(!CrtOpenStore)
   {
       printf("error load function - %s", "CrtOpenStore");
       return 1;
   }
   CSPCloseContext= (cspclosecontext) GetProcAddress(lib,"CSPCloseContext");
   if(!CSPCloseContext)
   {
       printf("error load function - %s", "CSPCloseContext");
       return 1;
   }
   CrtCloseStore= (crtclosestore) GetProcAddress(lib,"CrtCloseStore");
   if(!CrtCloseStore)
   {
       printf("error load function - %s", "CrtCloseStore");
       return 1;
   }
   ErrorString = (errorstring) GetProcAddress(lib,"ErrorString");
   if(!ErrorString)
   {
       printf("error load function - %s", "ErrorString");
       return 1;
   }   
   BaseToBin = (basetobin) GetProcAddress(lib,"BaseToBin");
   if(!BaseToBin)
   {
       printf("error load function - %s", "BaseToBin");
       return 1;
   }  
   CrptVerifyCRLSignature = (crptverifycrlsignature) GetProcAddress (lib, "CrptVerifyCRLSignature");
   if (!CrptVerifyCRLSignature)
   {
        printf ("error load function - %s", "CrptVerifyCRLSignature");
        return 1;
   }
   return 0;
}
//------------------------------------------------------------------------------
int main(void)
{
int ret					= 0;
int code				= 0;
hCERTSTORE hStore		= 0;
HINSTANCE lib			= NULL;
HCRYPTPROV hP			= 0;
unsigned char *binCert	=NULL;
unsigned char *binCRL	=NULL;
long CRLSize;
long binSize;
try
{
  lib = load_lib(strlib);
  if( get_func(lib) )
  {
    printf("error load func.\n");
	exit(1);
  }    
  //получить контекст криптопровайдера
  code = CSPOpenContext(&hP,NULL, 25, 0, CRYPT_VERIFYCONTEXT, NULL, 0, NULL, 0, NULL);
  if( code )
  {
    printf("%s [CSPOpenContext: error = %d]\n",ErrorString(code), code);
    throw code;
  }
  //открыть хранилище сертификатов
  code = CrtOpenStore(0, hP, 0, false, NULL, &hStore);
  if( code )
  {
    printf("%s [CrtOpenStore: error = %d]\n",ErrorString(code), code);
    throw code;
  }
  binCert = (unsigned char*) calloc (sizeof(CCERTIFICATE),sizeof(unsigned char));
  code = BaseToBin ((unsigned char*)CCERTIFICATE, sizeof(CCERTIFICATE), binCert, &binSize);
  if (code) 
  {
    printf("%s [BaseToBin: error = %d]\n",ErrorString(code), code);
    throw code;
  }
  binCRL = (unsigned char*) calloc (sizeof(CRL),sizeof(unsigned char));
  code = BaseToBin ((unsigned char*)CRL, sizeof(CRL), binCRL, &CRLSize);
  if (code) 
  {
    printf("%s [BaseToBin: error = %d]\n",ErrorString(code), code);
    throw code;
  }
  //проверить подпись СОС
  code = CrptVerifyCRLSignature (hStore, binCRL, CRLSize, binCert, binSize);
  if (code)
  {
    printf("%s [CrptVerifyCRLSignature: error = %d]\n",ErrorString(code), code);
    throw code;
  }
  printf("VerifyCRLSignature = OK\n");
}
catch(int er){ret=er;}
if (binCert) free (binCert);
if (binCRL) free (binCRL);
//закрыть хранилище сертификатов
if( hStore ) 
{
  CrtCloseStore(&hStore); 
  hStore = (hCERTSTORE) NULL;
}
//удалить контекст криптопровайдера
if( hP )
{
  CSPCloseContext(&hP); 
  hP = (HCRYPTPROV) NULL;
}
if (lib) lib_free( lib );
return ret;
}
