/*
 * Copyright(C) 2005-2011
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто-Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто-Про.
 *
 * This is proprietary information of
 * Crypto-Pro company.
 *
 * Any part of this file can not be copied, 
 * corrected, translated into other languages,
 * localized or modified by any means,
 * compiled, transferred over a network from or to
 * any computer system without preliminary
 * agreement with Crypto-Pro company
 */

#include <cstdio>
#include <cstring>
#include "UnixRequest.h"
#include "UnixEnroll.h"
#include "WinCryptEx.h"

// Начало примера (не следует удалять данный комментарий, он используется 
// для автоматической сборки документации)
//----------------------------------------------------------------------
// Пример отправки запроса майкрософтскому УЦ на получение сертификата
// До этого необходимо вызвать /opt/cprocsp/src/samples/CSP/UnixEnroll
// для создания запроса, который будет передан в качестве аргумента.
//----------------------------------------------------------------------

static void HandleCode(HRESULT err, const char *s)
{
    ::printf("Error number     : 0x%x\n", err);
    ::printf("Error description: %s\n", s);
    if(!err)
	err = 1;
    ::exit(err);
}


int main(int argc, char* argv[])
{	
    UnixRequest * pRequest = 0;
    pRequest = UnixRequest::URFactory("MSCAstd");
    HRESULT res=-1;
    LONG Flags = CR_IN_PKCS10;
    LONG pRequestId = 0;
    LONG pDisposition = 0;
    FILE* requestFile = NULL,*IdFile = NULL,*certificateFile = NULL;
    std::string str = "";
    BSTR bstrAttributes = 0;
    BSTR strConfig=SysAllocString(L"http://vm-test-ca/certsrv");
    BSTR bstrCertificate = 0;
    BSTR strRequest = 0;
    char * charCertificate = 0;
    int c = 0;
	
    if (pRequest == 0)
	return NTE_FAIL;
    if (argc == 4){
        requestFile = fopen(argv[1], "rb");
        IdFile = fopen(argv[2], "wb");
        certificateFile = fopen(argv[3], "wb");
    }
    else {
        printf("error. 3 files must be defined\n\n");
        goto er;
    }
	
    while ( (c = fgetc(requestFile)) != EOF ){
	str = str + (char)c;
    }
	
    strRequest = ConvertStringToBSTR(str.c_str());
	
    //--------------------------------------------------------------------
    // submit отправляет запрос на сертификат и сохраняет результат подачи 
    // в pDisposition  
    res = pRequest->Submit(Flags, strRequest, bstrAttributes, strConfig, &pDisposition);
	
    if (res != S_OK) {
	    HandleCode(res, "Error submit.");
	    goto er;
    } else {
        printf("Successful submitting. \n");
	    switch (pDisposition) {
		case CR_DISP_DENIED:
			printf("request was denied. \n");
			break;
				
		case CR_DISP_ERROR:
			printf("error request. \n");
			break;
				
		case CR_DISP_INCOMPLETE:
			printf("request was incompleted\n");
			break;
				
		case CR_DISP_ISSUED:
			printf("certificate was issued. \n");
			break;
				
		case CR_DISP_ISSUED_OUT_OF_BAND:
	//Сертификат выдан (будет выдан) непосредственно на УЦ, а не по сети
			printf("certificate was issued out of band. \n");
			break;
				
		case CR_DISP_UNDER_SUBMISSION:
			printf("certificate is under submission. \n");
			break;	
		default:
			break;
	}
		
    }

    //--------------------------------------------------------------------
    // GetRequestId получает идентификатор текущего запроса 
    if ( pDisposition != CR_DISP_ERROR ){
        res = pRequest->GetRequestId(&pRequestId);
        if (res == S_OK) {
            printf("RequestId = %d \n", pRequestId);
            fwrite(&pRequestId, sizeof(LONG), 1, IdFile);
        } 
    }

    res = pRequest->GetCertificate(CR_OUT_BASE64HEADER, &bstrCertificate);
    if (res != S_OK){
        printf("Error Get Certificate. \n\n");
    } else {
        charCertificate = ConvertBSTRToString(bstrCertificate);
        fputs(charCertificate, certificateFile);
    }
    
er : 
    SysFreeString(strConfig);
    if ( strRequest )
        SysFreeString(strRequest);
    if ( bstrCertificate )
        SysFreeString(bstrCertificate);
    free(charCertificate);
    fclose(IdFile);
    fclose(requestFile);
    fclose(certificateFile);
    if (res == S_OK)
	return 0;
    else
	return 1;
     
}//end of main

//END-OF-FILE


