//------------------------------------------------------------------------------
// Tumar CSP
// Copyright (c) 2011 Scientific Lab. Gamma Technologies. All rights reserved.
// SDK
// Create TSP Request
//------------------------------------------------------------------------------
#include "ex_util.h"
//------------------------------------------------------------------------------
#define TSP_REQ_FILE "tsp_req_ex.bin"
#define TSP_POLICY   "1.2.3"
#define CMP_RA_CERT "cmp_ra.cer"
//------------------------------------------------------------------------------
char *Data_for_sign=(char*)"1234567890ABCD";
//------------------------------------------------------------------------------
// Пользователь формирует ЭЦП и есть необходимсь добавления метки времени
// Задача:
// 1. Создать TSP запрос на получение метки времени
//------------------------------------------------------------------------------
unsigned char WBuf[4096];
unsigned char Cert[4096];
//------------------------------------------------------------------------------
int main(void)
{
 int code;
 HCRYPTPROV hProv=0;
 HCRYPTHASH hHash;
 DWORD dw,len;

 // Загружаем криптопровайдер
 code=LoadTumarCSP((char*)CSP_LIB); if (code) {printf("Load CSP error: %d\n",code); return 1;}
 //
 // Загружаем сертификат
 if (getFileLen(CMP_RA_CERT,    &dw)) {printf("getFileLen error\r\n"); return 1;}
 if (readFile  (CMP_RA_CERT,Cert,dw)) {printf("readFile error\r\n");   return 1;}
 // Создаем контекст CSP
 if (!CPAcquireContext(&hProv,(char*)CSP_PROF,0,NULL)) {
   printf("CPAcquireContext Error: %0X\n",GetLastErrorCSP(0));
   return 1;
 }
 // Создеем хэш-объект
 if (!CPCreateHash(hProv,CALG_TGR3411,0,0,&hHash)) {
   printf("CPCreateHash Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Хэшируем данные
 if (!CPHashData(hProv,hHash,(BYTE*)Data_for_sign,strlen(Data_for_sign),0)) {
   printf("CPHashData Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Устанавливаем политику использования TSP
 if (!CPSetHashParam(hProv,hHash,HP_TIME_STAMP_OID,(BYTE*)TSP_POLICY,0)) {
   printf("CPSetHashParam HP_TIME_STAMP_OID Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Если требуется чтобы TSP-сервер вложил свой сертификат:
 dw=1;
 if (!CPSetHashParam(hProv,hHash,HP_TIME_STAMP_CRT,(BYTE*)&dw,0)) {
   printf("CPSetHashParam HP_TIME_STAMP_CRT Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Формируем запрос
 len=sizeof(WBuf);
 if (!CPGetHashParam(hProv,hHash,HP_TIME_STAMP_REQ,WBuf,&len,0)) {
   printf("CPGetHashParam HP_TIME_STAMP_REQ Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 CPDestroyHash(hProv,hHash);
 // Создеем хэш-объект
 if (!CPCreateHash(hProv,CALG_TGR3411,0,0,&hHash)) {
   printf("CPCreateHash Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Хэшируем данные
 if (!CPHashData(hProv,hHash,WBuf,len,0)) {
   printf("CPHashData Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Добавляем данные
 if (!CPSetHashParam(hProv,hHash,HP_PKCS7_DATA_SIZE,(BYTE*)&len,0)) {
   printf("CPSetHashParam Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 if (!CPSetHashParam(hProv,hHash,HP_PKCS7_DATA,WBuf,0)) {
   printf("CPSetHashParam Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Добавляем сертификат
 if (!CPSetHashParam(hProv,hHash,HP_PKCS7_CERTIFICATE,Cert,0)) {
   printf("CPSetHashParam Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Формируем PKCS7
 len=sizeof(WBuf);
 if (!CPSignHash(hProv,hHash,AT_SIGNATURE,NULL,CRYPT_SIGN_PKCS7,WBuf,&len)) {
   printf("CPSignHash Error: %0X\n",GetLastErrorCSP(hProv));
   return 1;
 }
 // Сохраняем запрос
 writeFile(TSP_REQ_FILE,WBuf,len);
 //
 CPDestroyHash(hProv,hHash);
 // Закрываем контекст CSP
 CPReleaseContext(hProv,0);
 printf("OK\n");
 return 0;
}
//------------------------------------------------------------------------------
