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

/*!
 * \file $RCSfile: CA_CMP_Certificate.h,v $
 * \version $Revision: 1.15 $
 * \date $Date: 2005/01/24 12:36:43 $
 * \author $Author: cav $
 *
 * \brief CertificateInfo class
 */

#ifndef CA_CMP_CERIFICATE_H
#define CA_CMP_CERIFICATE_H

#include "CA_CMP_Types.h"
#include "CA_CMP_Msg.h"

/**************************************************************/
/*                                                            */
/*  Internal structure                                        */
/*                                                            */
/**************************************************************/

class CertificateTemplate;

class CertificateInfo : public PKIXCMP_Message
{
public:
    friend class PKIXCMP_Server;
    friend class PKIXCMP_Client;

    // Init by zero
    CertificateInfo();
    ~CertificateInfo();

    CertificateInfo( const CertificateInfo& c ) : PKIXCMP_Message()
    {
	preprocessed = NULL;
	*this = c;
    }
    CertificateInfo& operator=( const CertificateInfo& c );
    void clear();

    // Индекс запроса
    int RequestID;
    
    int Status;

    // !!!!! тип сертификата, что здесь может быть ????? Предлагается убрать
    int CertificateType;

    // Далее идут поля, полученные из Subject (разобранные из ASN1T_Name.ASN1T_RDNSequence)
    // ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Name subject
    CACMPT_PARSED_RDN subjectRDN;

    // Далее идут поля, полученные из Issuer (разобранные из ASN1T_Name.ASN1T_RDNSequence)
    // ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Name issuer
    CACMPT_PARSED_RDN issuerRDN;
    
    // Двоичный -	ASN1T_Certificate
    CACMPT_BLOB RawCertificate;
    
    // Строка - 	ASN1T_Certificate.ASN1TDynBitStr signature;
    CACMPT_BLOB CertificateSignature;
    
    // Строка -		ASN1T_Certificate.ASN1T_AlgorithmIdentifier signatureAlgorithm;
    char CertificateSignatureAlgorithm[ 254 ];
    
    // Строка - 	ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_CertificateSerialNumber serialNumber
    CACMPT_SERIAL SerialNumber;
    
    // Date -		ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Validity.ASN1T_Time notBefore
    CACMPT_Date NotBefore;
    	
    // Date -		ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Validity.ASN1T_Time notAfter
    CACMPT_Date NotAfter;

    // Date -		ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Validity.ASN1T_Time SuspendedBefore
    CACMPT_Date SuspendedBefore;

    // Date -		ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Validity.ASN1T_Time ArchiveDate
    CACMPT_Date ArchiveDate;
    
    // ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_SubjectPublicKeyInfo
    CACMPT_PublicKeyInfo	SubjectPublicKey;
    
    // ID -			ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_UniqueIdentifier issuerUniqueID
    int IssuerUniqueID;
    
    // ID -			ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_UniqueIdentifier issuerUniqueID
    int SubjectUniqueID;
    
    // ASN1T_Certificate.ASN1T_TBSCertificate.ASN1T_Extensions extensions
    CACMPT_Extensions Extensions;
    
    // Идентификатор ключа субъекта
    CACMPT_BLOB SubjectKeyIdentifier;

    // Идентификатор ключа издателя
    CACMPT_BLOB AuthorityKeyIdentifier;

    // Строка
    char DeviceSerialNumber[ 256 ];
    
    // Двоичный
    char RawSMIMECapabilities[ 8192 ];

    bool subject_changed;
    bool validity_changed;
protected:
    // Внутренние структуры
    CertificateTemplate *preprocessed;
};

// кучка из capilte/StoreUtil.h
/* Поиск сертификата в Store по его блобу
 * используется только в библиотеке
 */

template<class Right> class StoreFindParam
{
public:
    const DWORD dwFindType;
    const void *pvFindPara;
    StoreFindParam( DWORD FindType, const void *FindPara ) : 
      dwFindType( FindType ), pvFindPara( FindPara ) {}
    virtual ~StoreFindParam( ) {} 
    virtual bool operator ==( const Right &right ) const 
    { (void)right; return true; }
    inline bool operator !=( const Right &right ) const
    { return !( *this == right ); }
};
typedef StoreFindParam<CERT_CONTEXT> CertStoreFindParam;

PCCERT_CONTEXT CertStore_FindExisting(const CACMPT_BLOB &cert,
				      HANDLE& hRetCertStore,
				      const wchar_t * store_name = L"My",
				      bool SystemStore = false, bool ReadOnly = true);

void CertStore_Find(encoded_certificate_list &dest,
		    HANDLE hCertStore,
		    const CertStoreFindParam &param,
		    bool first);

class CertFindBySubjectAndSerial : public CertStoreFindParam
{
public:
    CertFindBySubjectAndSerial( const CACMPT_BLOB &Subject,
	const CACMPT_BLOB &Serial );
    virtual bool operator==( const CERT_CONTEXT &right ) const;
protected:
    CERT_NAME_BLOB name_blob;
    CACMPT_BLOB serial;
};

class CertFindByPublicKey: public CertStoreFindParam
{
public:
    CertFindByPublicKey ( const CACMPT_BLOB &Cert );
    CertFindByPublicKey ( const CACMPT_PublicKeyInfo &PKInfo );
    virtual bool operator ==( const CERT_CONTEXT &right ) const;
protected:
    CACMPT_BLOB pkey;
};


#if !defined _WIN32
class CryptSetPinCallback
{
  public:
    CryptSetPinCallback ();
    virtual ~CryptSetPinCallback ();
    virtual std::string get_pin () = 0;
    bool Get (char *pin_buf, size_t pin_len);
  protected:
    CRYPT_PIN_CALLBACK m_old_func;
    void * m_old_arg;
};

/* Объект этого класса надо завести на стеке перед вызовом 
 * AcquireCredentialsHandle или CryptAcquireCertificatePrivateKey,
 * чтобы они имели доступ к пину. Не следует создавать глобальных
 * объектов этого класса - он должен существовать только на время
 * вызова одной из этих функций. */
class CryptSetPinCallbackFixed: public CryptSetPinCallback
{
  public:
    CryptSetPinCallbackFixed (std::string pin) : m_pin (pin) {}
    virtual ~CryptSetPinCallbackFixed () {}
    virtual std::string get_pin ();
  protected:
    std::string m_pin;
};
#endif	/* !_WIN32 */

#endif // CA_CMP_CERIFICATE_H
