//------------------------------------------------------------------------------
// Tumar CSP
// Copyright (c) 2011 Scientific Lab. Gamma Technologies. All rights reserved.
// SDK
// Encrypt and create Enveloped PKCS-7 message
//------------------------------------------------------------------------------
#include "ex_util.h"
//------------------------------------------------------------------------------
#define CMP_RA_CERT "cmp_ra.cer"
#define PKCS7E_FILE "pkcs7_enc.bin"
//------------------------------------------------------------------------------
unsigned char WBuf[8196];
unsigned char Cert[8196];
//------------------------------------------------------------------------------
// Пользователь имеет сертификат получателя
// Задача:
// 1. Зашифровать данные
// 2. Создать Enveloped PKCS-7 message
//------------------------------------------------------------------------------
char *Data_for_enc=(char*)"1234567890ABCD";
//------------------------------------------------------------------------------
int main(void)
{
 int code;
 HCRYPTPROV hProv=0;
 HCRYPTKEY hKey,hExpKey;
 DWORD len,len2,sz;
 unsigned char *res;

 // Загружаем криптопровайдер
 code=LoadTumarCSP((char*)CSP_LIB); if (code) {printf("Load CSP error: %d\n",code); return 1;}
 //
 // Загружаем сертификат получателя
 if (getFileLen(CMP_RA_CERT,    &sz)) {printf("getFileLen error\r\n"); return 1;}
 if (readFile  (CMP_RA_CERT,Cert,sz)) {printf("readFile error\r\n");   return 1;}
 //
 // Создаем контекст CSP
 if (!CPAcquireContext(&hProv,NULL,CRYPT_VERIFYCONTEXT,NULL)) {
   printf("CPAcquireContext Error: %0X\n",GetLastErrorCSP(0));
   return 1;
 }
 // Устанавливаем ключ получателя
 if (!CPImportKey(hProv,Cert,sz,0,0,&hExpKey)) {
   printf("CPImportKey Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Создаем сессионный ключ
// if (!CPGenKey(hProv,CALG_GOST,CRYPT_EXPORTABLE,&hKey)) {
 if (!CPGenKey(hProv,CALG_T3DES,CRYPT_EXPORTABLE,&hKey)) {
   printf("CPGenKey CALG_GOST Error: %0X\r\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Шифруем данные
 len =strlen(Data_for_enc);
 len2=sizeof(WBuf);
 memcpy(WBuf,Data_for_enc,len);
 if (!CPEncrypt(hProv,hKey,0,TRUE,0,WBuf,&len,len2)) {
   printf("CPEncrypt Error: %0X\r\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Если требуется вложить данные:
 // Устанавливаем размер данных для экспорта PKCS7
 if (!CPSetKeyParam(hProv,hKey,KP_PKCS7_DATA_SIZE,(BYTE*)&len,0)) {
   printf("CPSetKeyParam KP_PKCS7_DATA_SIZE Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Устанавливаем данные для экспорта PKCS7
 if (!CPSetKeyParam(hProv,hKey,KP_PKCS7_DATA,(BYTE*)WBuf,0)) {
   printf("CPSetKeyParam KP_PKCS7_DATA Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Формируем PKCS7
 if (!CPExportKey(hProv,hKey,hExpKey,SIMPLEBLOB_P7,CRYPT_DEFAULT_MODE,NULL,&len)) {
   printf("CPExportKey SIMPLEBLOB_P7 3 Error: %0X\r\n",GetLastErrorCSP(hProv));
   return 1;
 }
 res=(unsigned char*)calloc(len,sizeof(unsigned char));
 // Формируем результат
 if (!CPExportKey(hProv,hKey,0,SIMPLEBLOB_P7,0,res,&len)) {
   printf("CPExportKey SIMPLEBLOB_P7 4 Error: %0X\r\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Сохраняем запрос
 writeFile(PKCS7E_FILE,res,len);
 CPDestroyKey(hProv,hKey);
 CPDestroyKey(hProv,hExpKey);
 free(res);
 // Закрываем контекст CSP
 CPReleaseContext(hProv,0);
 printf("OK\n");
 return 0;
}
//------------------------------------------------------------------------------
