/*
 * Copyright(C) 2003 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/*!
 * \file $RCSfile: PKIXCMP_Server.h,v $
 * \version $Revision: 1.70.2.1 $
 * \date $Date: 2007/05/10 10:53:42 $
 * \author $Author: alexl $
 *
 * \brief PKIXCMP_Server class
 */

#ifndef PKIXCMP_SERVER_H
#define PKIXCMP_SERVER_H

#include <utility>

#define CPCSP_C_SOURCE 30
#include "PKIXCMP_Base.h"
#include "WinCryptEx.h"

class PKIXCMP_Server : public PKIXCMP_Base {
public:
    PKIXCMP_Server( const char *ini_path, WndProv *wnd_prov );
    PKIXCMP_Server( const char *szProvider=0, DWORD dwProvType = PROV_GOST_2012_256 );
    ~PKIXCMP_Server();

    // Создание сертификата корневого ЦС
    // dn [in] : RDN центра сертификации
    // szContainer [in/out] : имя ключевого контейнера
    // Для создания случайного имени "\\\\.\\HDIMAGE\\"
    static PKIXCMP_Server *GenerateRoot( const char *ini_path,
	const wchar_t *dn,
	const CACMPT_Extensions& Extensions,
	const wchar_t *caname,
        bool keyExportable,
	const char *szProvider,
	int dwProvType,
	const char *szContainer,
	const CACMPT_Period &cert_period,
	const CACMPT_Date &notbefore,
	const char *cdp,
	const CACMPT_Period &crl_period,
	WndProv *wnd_prov);

    void ImportRoot (
	const char *szProvider,
	int dwProvType,
	const char *szContainer,
        bool keyExportable,
        CACMPT_BLOB & mykey,
        CACMPT_BLOB & mycert,
        CACMPT_BLOB & Seed,
	WndProv *wnd_prov );



    // Создание нового сертификата корневого ЦС
    // ann_msg [out] : уведомление о смене ключа ЦС
    // ann_size [in/out] : длина ann_msg
    // szContainer [in/out] : имя нового ключевого контейнера.
    // Для создания случайного имени "\\\\.\\HDIMAGE\\"
    // используется только в CSP/samples/PKIXCMPtst/
    void UpdateRoot(const char *ini_path,
	int dwProvType,
        const char *szContainer, bool keyExportable, CACMPT_BLOB &ann_msg,
	PKIXCMP_Message *info, WndProv *wnd_prov = 0,
	CACMPT_BLOB *new_cert = NULL);

    // Создание сертификата корневого ЦС
    // dn [in] : RDN центра сертификации
    // szContainer [in/out] : имя ключевого контейнера
    // Для создания случайного имени "\\\\.\\HDIMAGE\\"
    static PKIXCMP_Server *GenerateRootCDPS( const char *ini_path,
	const wchar_t *dn, 
	const CACMPT_Extensions& Extensions,
	const wchar_t *caname,
	const char *szProvider,
	int dwProvType,
	const char *szContainer,
	const CACMPT_Period &cert_period,
	const std::vector<std::string> & cdps,
	const CACMPT_Period &crl_period,
	WndProv *wnd_prov);

    // Создание нового сертификата корневого ЦС
    // ann_msg [out] : уведомление о смене ключа ЦС
    // ann_size [in/out] : длина ann_msg
    // szContainer [in/out] : имя нового ключевого контейнера.
    // Для создания случайного имени "\\\\.\\HDIMAGE\\"
    // используется только в Standart_CC
    // [потребует переделки под новый мир по образу и подобию UpdateRoot()]
    void UpdateRootCDPS(const char *ini_path,
	const char * szProvider, int dwProvType,
        const char *szContainer, CACMPT_BLOB &ann_msg,
	PKIXCMP_Message *info, WndProv *wnd_prov = 0,bool ToSign=true,
	const CACMPT_Period *new_date_period = NULL, CACMPT_BLOB *new_cert = NULL,
	const CACMPT_Extensions* extensions = NULL,
	const std::vector<std::string> & cdps = std::vector<std::string>(),
	bool replace_extensions = false);

    int ChangePassword( WndProv *wnd_prov );

    // Выпуск СОС
    void GenerateCRL(CACMPT_BLOB &crl_msg, const CrlInfo *info,
		     PKIXCMP_Message *crlAnninfo = NULL);

    // Заполнение полей структуры сертификата значениями из 
    // Request и по умолчанию.
    void CertReqMessage_PreProcess(const CACMPT_BLOB &cr_msg, CertificateInfo *info);

    // Заполнение полей структуры сертификата значениями из 
    // сертификата и по умолчанию. Для выпуска Self-Issued
    // сертификатов
    void CertReqCert_PreProcess(const CACMPT_BLOB &cert, CertificateInfo *info);

    // обработка запроса
    void CertReqMessage_Process(CertificateInfo *info, CACMPT_BLOB &cp_msg, int nCertId = -1, bool ToSign = true);

    void CertReqMessage_Reject(RequestInfo &request, CACMPT_BLOB &cp_msg, bool toSign);

    const CACMPT_BLOB& GetCert () const { return MYCert; }

    // Создание уведомления отзыва сертификата.
    void RevAnnContent_Process(CACMPT_BLOB &ra_msg,
        const RevAnnContentInfo *info, bool ToSign = true);

    unsigned long GetCSP() const { return hProv; }

    CACMPT_BLOB GetCrl();

    // Создать запрос на cross сертификат.
    void CrossReqMessage_EncodeAndSign(const CertificateInfo *info, CACMPT_BLOB &cr_msg);

    void ErrorMsgInfo_EncodeAndSign(const ErrorMsgInfo *em_info,
				    CACMPT_BLOB &em_msg, bool ToSign=true)
    {
	PKIXCMP_Base::ErrorMsgInfo_EncodeAndSign(em_info, em_msg,
						 hProv, AT_SIGNATURE, MYCert, ToSign);
    }

    void CertAnnContent_EncodeAndSign(CertificateInfo *info,
				      CACMPT_BLOB &ann_msg, bool ToSign=true);

    // Построение цепочки от сертификата центра до Root
    void BuildChain( encoded_certificate_list &path )
    {
	CertChain_VerifyCertificate(GetCert(), path, NULL, ADD_STORE, ADD_STORE_LEN);
    }

    // Общее сообщение пока с пустым Body
    void GenMsgContent_EncodeAndSign(PKIXCMP_Message *info, CACMPT_BLOB &msg);

    // Общее сообщение пока с пустым Body, без подписи
    int GenMsgContent_Encode(
	PKIXCMP_Message *info, CACMPT_BLOB &msg );

protected:
    void CertReqMessage_Process(CertificateInfo *info,
	CACMPT_BLOB &cp_msg, CACMPT_SERIAL szSerial /* in/out */,
	int nCertId = -1, bool ToSign = true );
    void GenerateRoot (const wchar_t *dn, 
	const CACMPT_Extensions& Extensions,
	const char * szProvider,
	int dwProvType,
	const char *szContainer,
        bool keyExportable,
	const CACMPT_Period &period,
	const CACMPT_Date &notbefore,
	const std::vector<std::string> &cdps,
	WndProv *wnd_prov);
    void CertReqMessage_PreProcess(const CACMPT_BLOB &cr_msg,
	CertificateInfo *info, int dummy );
    void CertReqCert_PreProcess(const CACMPT_BLOB &cert, CertificateInfo *info, int dummy);
    void GenerateCRL(CACMPT_BLOB &crl_msg, const CrlInfo *info,
		     const CACMPT_Period &period, PKIXCMP_Message *crlAnnInfo = NULL);

    void *hProvParts;
    void init (const CACMPT_BLOB& cert, WndProv *wnd_prov );
    void release ();
    void init ( const char * szProvider, DWORD dwProvType );

    std::string ini_path;
    static HCRYPTPROV create_container_root( WndProv *wnd_prov, 
	const char *container, const char *provider, DWORD provtype,
        bool keyExportable, void* &parts, HCRYPTPROV hProvVer);
    static HCRYPTPROV import_container_root( WndProv *wnd_prov,
	const char *container, const char *provider, DWORD provtype,
	bool keyExportable, void* &parts, BYTE* pbBlob, DWORD dwBlobLen, BYTE* pbSeed, DWORD dwSeedLen, HCRYPTPROV hProvVer);

    static void read_container_root( HCRYPTPROV hProvCA,
	WndProv *wnd_prov, void *&parts );
    static void close_container_root( HCRYPTPROV hProvCA, void *&parts );

public:
    static const CertificateStore *ADD_STORE;
    static const int ADD_STORE_LEN;

    virtual const CertificateStore *Get_ADD_STORE () const { return ADD_STORE; }
    virtual int Get_ADD_STORE_LEN () const { return ADD_STORE_LEN; }
};
#endif // PKIXCMP_SERVER_H
