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

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

#ifndef PKIXCMP_CLIENT_H
#define PKIXCMP_CLIENT_H

#include "PKIXCMP_Base.h"

class PKIXCMP_Client : public PKIXCMP_Base {
public:
    PKIXCMP_Client( const char * szProvider=NULL, DWORD dwProvType = PROV_GOST_2012_256 );
    // Конструктор для имеющегося ключа по настройкам.
    PKIXCMP_Client( WndProv &wnd_prov, const char *ini_path, 
	const char * szProvider=0, DWORD dwProvType = PROV_GOST_2012_256 );

    PKIXCMP_Client(WndProv &wnd_prov, const CACMPT_BLOB& cert,
		   bool isRequest = false,
		   const char *szProvider=0,
		   DWORD dwProvType = PROV_GOST_2012_256);

    ~PKIXCMP_Client();

    // на входе заполненная RequestInfo (все поля, кроме SubjectPublicKey)
    // создается ключевая пара
    // и прописывается информация о ней и о привязке к ключевому контейнеру
    // szContainer [in/out] : имя ключевого контейнера.
    // Для создания случайного имени "\\\\.\\HDIMAGE\\"
    static PKIXCMP_Client *GenerateKeyPair(WndProv &wnd_prov,
	const char *ini_path, const char *provider, int dwProvType,
        const char *szContainer, unsigned long keySpec/* = AT_SIGNATURE*/,
        bool keyExportable/* = false*/);

    // old
    static PKIXCMP_Client *GenerateKeyPair( const char *ini_path, const char * szProvider,
	int dwProvType, const char *szContainer, unsigned long keySpec = 2, 
	const char *pin = NULL);

    static PKIXCMP_Client *OpenRequest ( WndProv &wnd_prov,
	const CACMPT_BLOB &cert );

    // old
    static PKIXCMP_Client *OpenRequest(const CACMPT_BLOB &cert, const char *pin);

    bool ChangePin( WndProv &wnd_prov );

    void PKIXCMP_Sign (CACMPT_BLOB &in_msg,
	CACMPT_BLOB &out_msg, const PKIXCMP_Message *msg );

    void CertReqMessage_EncodeAndSign(RequestInfo *info,
				      CACMPT_BLOB &cr_msg, bool ToSign=true);

    // Проверка содержимого и подписи возвращенного сообщения
    // Проверка соответствия запроса и ответа
    unsigned CertRepMessage_Verify(const CACMPT_BLOB &cr_msg, const CACMPT_BLOB &cp_msg);

    //  Установка сертификата в store и в контейнер.
    void CertRepMessage_Install(const CACMPT_BLOB &cert, const char * ini_path = "", bool fToStore = true);

    // Декодирование уведомления о отзыва сертификата.
    unsigned RevAnnContent_DecodeAndVerify(const CACMPT_BLOB &ra_msg, RevAnnContentInfo *info);

    // Создать запрос на новый ключ:
    void UpdateKey(WndProv &wnd_prov, RequestInfo *info, const char *new_ini_path,
	const char *provider, int dwProvType, const char *szContainer,
	unsigned long keySpec /* = AT_SIGNATURE */, bool keyExportable /* = false */);

    unsigned long GetCSP() const { return hProv; }
    unsigned long GetKeySpec() const { return dwKeySpec; }

    unsigned ErrorMsgInfo_Verify(const CACMPT_BLOB &em_msg);

    void CertAnnContent_DecodeAndVerify(const CACMPT_BLOB &ann_msg, CACMPT_BLOB &cert);

    // Построение цепочки от сертификата клиента до Root
    void BuildChain(encoded_certificate_list &list);

public:
    // @devnote This fields are used by PkiClient
    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; }

protected:
    std::string IniPath;

    CACMPT_BLOB m_msgNonce;	// dim: похоже, что только читается
    CACMPT_BLOB m_transactionID;

    void init (WndProv &wnd_prov, const CACMPT_BLOB& cert, bool isRequest);
    void init( const char * szProvider, DWORD dwProvType );
    PKIXCMP_Client *new_client;
 private:
    void UpdateKeyInfo( RequestInfo *info, const CACMPT_BLOB &old );
};
#endif // PKIXCMP_CLIENT_H
