#if !defined(__alffcertadm_h) // Sentry, use file only if it's not already included.
#define __alffcertadm_h
/*  Project Biblio-Tec

	 SUBSYSTEM:    TECSecurity.dll Library
	 FILE:         alffcertadm.h
	 AUTHOR:       Alcindo Ferreira Filho

	 OVERVIEW:
	 Source file for definition of:
    
       ALFFX509Select (Dialog for X509 Certificates Selection),
       ALFFCertsComparator (Auxiliar Class For comparing certificates),
       ALFFCertAdminDlg,  (Dialog for managing X509 Certificates)
       ALFFImportCertificates (The dialog wizard that imports certificates),
       ALFFCertImportKey (Auxiliary dialog for Private Key importing),
       ALFFExportCertificate (The dialog wizard that exports certificates).

    Based on OpenSSL (www.openssl.org)
    COPYRIGHT:    © 2003,2005
                  Alcindo Ferreira Filho
                  <alcindo@inttec.com.br>

    LICENSE:      Biblio-Tec license (BiblTec.txt)
*/
//General Settings for TEC Libraries
#include "teclibs.h"

// OWL includes
#include <owl\owlall.h>       // OWL TEdit Definitions
#include <owl\notetab.h>
#include <stdio.h>

// ALFFLib Includes
#include "alfflstw.h"   // ALFF List Window Classes
#include "alffdlg.h"       // ALFF Dialog Class
#include "alffmsgs.h"      // ALFF Messages Class
#include "alffhelp.h"      // ALFFHelp Class (wrapparound HTMLHelp)

//ALFFSSLib includes
#include "alffx509.h"      	 // X509 Certificates Class
#include "alffx509util.h"      // X509 Utilities Method
#include "alffusesecurity.h"   // ALFF Security Control
#include "tecseclb.rh"    	 // ALFF SSL Library IDs

//OpenSSL Includes
#include <openssl/pkcs12.h>
#include <openssl/pkcs7.h>

/* X509Certificates Selection Dialog */
//{{ALFFX509Select}}
class _TECSECCLASS ALFFX509Select : public ALFFDialog
{
 public:
  ALFFX509Select(TWindow* Parent,
					  ALFFUseSecurity* pSec,
                 ALFFDate::DateFormat fmt,
                 STACK_OF(X509)* certs,
                 STACK_OF(X509)* caCerts,
                 char* title=NULL);
  virtual ~ALFFX509Select();
  char far* GetClassName() {return "ALFFX509Select";}
  int  ExecuteSel();
  int  RetrieveA3Certificate(char* certPath=NULL, char* certPwd=NULL);
  bool IsA3Certificate() {return isA3Certificate;}
  X509* GetA3Certificate() {return sk_X509_value(certsSK,0); }
  STACK_OF(X509)* GetA3CACerts() {return CACerts;}
  bool HasCACertificates() {return (certCount > 1);}
  EVP_PKEY*  GetA3CertPKey() {return pKey; }

 protected:
  void SetupWindow();
  void CmOk();
  void EvPaint();

  void EvLBNSelChange();
  void EvLBNSelCancel();
  void EvLBNDblClk();
  void EvRetrieveA3Certificate();
  void ShowCertificate();
  bool ShowCertList();

  ALFFDate::DateFormat dateFormat;
  ALFFUseSecurity* pSecurity;
  STACK_OF(X509)*  certsSK;
  STACK_OF(X509)*  CACerts;
  int              certCount;

  // Private Key Imported (or not)
  EVP_PKEY*        pKey;

  ALFFMsgs* 		pMsgs;
  TListBox* 		x509List;   //IDC_ALFFX509SELLIST
  TButton*        showCert;   //IDC_ALFFX509SELSHOW
  TButton*        getA3Cert;  //IDC_ALFFX509SELA3CERT

  UINT 				selIndex;
  bool      		x509Exist;
  bool            isA3Certificate;
  char*           userTitle;
 DECLARE_RESPONSE_TABLE(ALFFX509Select);
};

// Class For ALFFListWindow Columns Sorting (Comparing rows/items)
class ALFFCertsComparator : public TLwComparator
{
  public:
      ALFFCertsComparator(ALFFUseSecurity* pSec);
      virtual int Compare(uint32 item1, uint32 item2, uint32 lParam) const;
      char far* GetClassName() {return "ALFFCertsComparator";}

      void SetListWindow(ALFFListWindow* lW);
      void SetCertsStack(STACK_OF(X509)* x509Certs);
  protected:
      ALFFListWindow*  listWindow;
      ALFFUseSecurity* pSecurity;
      STACK_OF(X509)*  x509Stack;
};


/* Certificates Manager Dialog Box Definition */
//{{ALFFDialog = ALFFCertificateDlg}}
class _TECSECCLASS ALFFCertAdminDlg : public ALFFDialog
{
 public:
  ALFFCertAdminDlg(TWindow* parent,
                   ALFFUseSecurity* pSec,
                   ALFFDate::DateFormat fmt,
  						 const char* title = NULL,
                   TPoint dlgTopLeft = NULL,
                   TResId idDlg=IDD_ALFFCERTADMIN);
  ~ALFFCertAdminDlg();
  char far* GetClassName() {return "ALFFCertAdminDlg";}

 public:

 protected:
	 void 		SetupWindow();
	 void       CmOk();
	 void       CmHelp();
	 LRESULT    EvCommand(uint controlId, HWND , uint notifyCode);

    /* CRL Stack Handling Functions */
    ULONG		LoadCRLStack(STACK_OF(X509_CRL)** x509CRLs);
    ULONG		SaveCRLStack(STACK_OF(X509_CRL)** x509CRLs);

    bool       LoadCertListWind(ALFFListWindow* certsWind, STACK_OF(X509)* x509Certs);
    void       ReloadCertListWindows();
    bool       VerifyCertPurpose(ALFFX509Certificate* cert, int selPurpose);
    void       ShowCertificate(STACK_OF(X509)* x509Certs, int index);
    string     GetCertificatePurpose(ALFFX509Certificate* alffX509Cert);
    void       SetSelCertPurpose(STACK_OF(X509)* x509Certs, int selected);
    bool       ImportCertificate(/*int certType*/);
    bool       RemoveCertificate(int certType);
    bool       ExportCertificate(int certType);

    void       LoadAllCertificatesStacks();
    void       LoadCertListWindows();
    void			LoadCACertificatesStack();

    int        StoreCertificates(STACK_OF(X509)* x509Certs,
                                    int& trustedAddedCerts,
                                    int& intermedAddedCerts,
                                    int& otherAddedCerts,
                                    int  caIndex);


    /* Certificates Read from current security directory */
    STACK_OF(X509_INFO)*         skX509Info;

    /* Certificates Found On Security Subdirectory */
    STACK_OF(X509)*              skPersonalCerts;
    STACK_OF(X509)*              skOtherCerts;
    STACK_OF(X509)*              skIntermedCAsCerts;
    STACK_OF(X509)*              skTrustedCAsCerts;

    /* Trusted CA Certificates for verifying certificates  */
	 STACK_OF(X509)*              skCACertificates;

    /* Stack of CRLs for verifying certificates revocation */
	 STACK_OF(X509_CRL)*          skCRLs;

    /*  Current Certificate */
    X509* 								currentX509Cert;

    /* OpenSSL Controls  */
    bool                         errorStringsLoaded;

    /* Dialog Presentation Global Controls */
    ALFFDate::DateFormat   dateFormat;
	 TWindow*   				certAdminDlgParent;
    ALFFUseSecurity* 		pSecurity;
    ALFFX509Util*          pX509Util;
	 ALFFMsgs*  				pMsgs;
	 TNoteTab*  				certAdminTabCntrl;
    ALFFX509Certificate* 	selectedCert;
    ALFFUtil*            	pUtil;
    ALFFHelp*              helpFile;

    /* Dialog Presentation specific Controls */
    TComboBox*   				certPurpose;
    int				         selPurpose;
    TStatic*     				selCertPurposes;
    TButton*     				certShow;
    TButton*     				certExport;
    TButton*     				certRemove;

    // Dialog TAB Specific Controls
    ALFFListWindow*           personalCerts;
    ALFFListWindow*           otherCerts;
    ALFFListWindow*           intermedCAsCerts;
    ALFFListWindow*           trustedCAsCerts;
    ALFFImageList*				smImageList;

    int                    selPersonalCert;
    int                    selOtherCert;
    int                    selIntermedCAsCert;
    int                    selTrustedCAsCert;

    TFont*                 certColHdrFont;
    HFONT                  hFontExt;

    // Event handlers
    //
    void      TabSelChange(TNotify far&);

    void      EvPersonalItem(TLwNotify& nmHdr);
    void		  EvPersonalItemDBLCLK();
    void		  EvPersonalColumnClick(TLwNotify& nmHdr);

    void      EvOtherItem(TLwNotify& nmHdr);
    void		  EvOtherItemDBLCLK();
    void		  EvOtherColumnClick(TLwNotify& nmHdr);

    void      EvIntermedCaItem(TLwNotify& nmHdr);
    void		  EvIntermedCaItemDBLCLK();
    void		  EvIntermedCaColumnClick(TLwNotify& nmHdr);

    void      EvTrustedCaItem(TLwNotify& nmHdr);
    void		  EvTrustedCaItemDBLCLK();
    void		  EvTrustedCaColumnClick(TLwNotify& nmHdr);

  DECLARE_RESPONSE_TABLE(ALFFCertAdminDlg);
};

/* Certificates Manager Import Dialog Box Definition */
//{{ALFFDialog = ALFFImportCertificates}}
class ALFFImportCertificates : public ALFFDialog
{
 public:
    ALFFImportCertificates(TWindow* parent,
    								ALFFUseSecurity* 	pSec,
                           ALFFDate::DateFormat fmt,
                           int idDlg=IDD_ALFFCERTIMPORT,
                           const char* title = NULL,
                           TPoint dlgTopLeft = NULL);
    ~ALFFImportCertificates();
    char far* GetClassName() {return "ALFFImportCertificates";}

    bool       HasCertificatesImported() { return importDone; }
    bool       HasPrivateKey() { return hasPrivateKey; }
    bool       IsPersonalCertificate() { return isPersonalCertificate; }
    bool       IsCRL() { return isCRL; }
    STACK_OF(X509)*     GetImportedCertsStack() { return x509Certificates;}
    STACK_OF(X509_CRL)* GetImportedCrlsStack() { return x509CRL;}
    char*               GetCRLFileName() { return crlFileName; }
    EVP_PKEY*  GetPrivateKey()  { return privateKey; }
    ULONG      GetPrivateKeyCertHash() { return pKeyCertHash; }
    bool       IsSupportedExtension();
    //int        GetPassword(char* buffer, int len, int verify, void* userData);
    void       SetCertImportPath(const char* certPath);
    void       SetCertImportFileExt(const char* certPath);
    void       SetCertImportPwd(const char* certPwd);
    ULONG      DoImport();
 protected:
	 void 		SetupWindow();
    bool       IsPwdNeeded(const char* ext);
    void       SetImportDone(bool done) { importDone = done; }
    void       SetPersonalCertificate(bool personal) { isPersonalCertificate = personal; }

	 LRESULT    EvCommand(uint controlId, HWND , uint notifyCode);

    char*                  certImportFilePathText;
    char*                  certImportFileExtText;
    char*                  certImportFilePwdText;
    bool							importDone;
    bool                   hasPrivateKey;
    bool                   isPersonalCertificate;
    bool                   isCRL;

    ALFFDate::DateFormat   dateFormat;
	 TWindow*   				dlgParent;
    ALFFUseSecurity* 		pSecurity;
    ALFFX509Util*          pX509Util;
	 ALFFMsgs*  				pMsgs;
    int                    dlgId;

    // Stack Of Imported Certificates
    STACK_OF(X509)*        x509Certificates;

    // Private Key Imported (or not)
    EVP_PKEY*              privateKey;
    ULONG                  pKeyCertHash;

    // Stack of Imported  CRLs
    STACK_OF(X509_CRL)*    x509CRL;
    char*                  crlFileName;

    // Auxiliary   Structures
    PKCS12* 					pkcs12Cert;
    PKCS7*                 pkcs7Cert;

    // Dialog Controls
    TEdit*         certImportFilePath;     // IDC_ALFFCERTIMPORTPATH
    TButton*       certImportFileBrowse;   // IDC_ALFFCERTIMPORTBROWSE
    TEdit*         certImportFilePwd;      // IDC_ALFFCERTIMPORTFILEPWD

    // Buttons
    TButton*       certImport;       // IDC_ALFFCERTIMPORT

    // Event handlers
};

/* Certificates Manager Import Key Dialog Box Definition */
//{{ALFFDialog = ALFFCertImportKey}}
class ALFFCertImportKey : public ALFFDialog
{
 public:
    ALFFCertImportKey(TWindow* parent,
                      ALFFUseSecurity*  pSec,
                      const char* title = NULL,
                      TPoint dlgTopLeft = NULL,
                      TResId idDlg=IDD_ALFFCERTIMPORTKEY);
    ~ALFFCertImportKey();
    char far* GetClassName() {return "ALFFCertImportKey";}
    bool       IsPrivateKeyExportable() { return doExportKey; }
    char*      GetPrivateKeyPwd() {return certImportKeyPwdText; }

 protected:
	 void 		SetupWindow();
	 LRESULT    EvCommand(uint controlId, HWND , uint notifyCode);

    char*                  certImportKeyPwdText;
    char*                  certImportKeyPwdConfText;
    bool                   doExportKey;

	 TWindow*   				dlgParent;
    ALFFUseSecurity* 		pSecurity;
    //ALFFX509Util*          pX509Util;
	 ALFFMsgs*  				pMsgs;

    // Dialog Controls
    TEdit*         certImportKeyPwd;      // IDC_ALFFCERTIMPORTKEYPWD
    TEdit*         certImportKeyPwdConf;  // IDC_ALFFCERTIMPORTKEYPWDCONF
    TCheckBox*     certImportKeyDoExport; // IDC_ALFFCERTIMPORTKEYDOEXPORT

    // Buttons
    TButton*       certKeyImport;       // IDC_ALFFCERTIMPORT
};

/* Certificates Manager Export Dialog Box Definition */
//{{ALFFDialog = ALFFExportCertificates}}

class  ALFFExportCertificate : public ALFFDialog
{
 public:
    ALFFExportCertificate(TWindow* parent,
                           ALFFUseSecurity* pSec,
                           ALFFDate::DateFormat fmt,
                           bool     isPersonal,
                           X509*    expCert,
                           EVP_PKEY* pKey,
                           STACK_OF(X509)* caCerts,
                           const char* title = NULL,
                           TPoint dlgTopLeft = NULL,
                           TResId idDlg=IDD_ALFFCERTEXPORT);
    ~ALFFExportCertificate();
    char far* GetClassName() {return "ALFFExportCertificate";}

 protected:
	 void 		SetupWindow();
    ULONG      DoExport();
    void       SetPersonalCertificate(bool isPersonal) { isPersonalCertificate = isPersonal; }
    bool       IsPersonalCertificate() { return isPersonalCertificate; }
    void       SetExportDone(bool done) { exportDone = done; }
    bool       IsSupportedExtension(const char* ext);
    bool			IsPwdNeeded(const char* ext);

	 LRESULT    EvCommand(uint controlId, HWND , uint notifyCode);

    char*                  certExportFilePathText;
    char*                  certExportFileExtText;
    char*                  certExportFilePwdText;
    bool                   errorStringsLoaded;
    bool							exportDone;
    bool                   isPersonalCertificate;

    enum                   fileFormats {CER, P7B, PFX} formatX509;

    ALFFDate::DateFormat   dateFormat;
	 TWindow*   				dlgParent;
    ALFFUseSecurity* 		pSecurity;
    ALFFX509Util*          pX509Util;    
	 ALFFMsgs*  				pMsgs;

    // Stack Of Exported Certificates
    X509*        				exportedCert;
    STACK_OF(X509)*        caCertificates;
    
    // Private Key Exported (or not)
    string 						certPKeyDir;
    string 						certPKeyExportDir;
    bool                   hasExportablePKey;
    EVP_PKEY*              privateKey;

    // Auxiliary   Structures
    PKCS12* 					pkcs12Cert;
    PKCS7*                 pkcs7Cert;

    // Cert Subject Font
    TFont*                 certSubjectFont;
    HFONT                  hFontExt;

    // Dialog Controls
    TStatic*       certSubject;            // IDC_ALFFCERTEXPSUBJECT
    TRadioButton*  formatX509CER;          // IDC_ALFFCERTEXPBASE64
	 TRadioButton*  formatX509P7B;          // IDC_ALFFCERTEXPPKCS7
    TCheckBox*     exportCertAllP7B;       // IDC_ALFFCERTEXPPKCS7ALL
    bool				 exportCertAllP7B_Sw;
    TRadioButton*  formatX509PFX;          // IDC_ALFFCERTEXPPKCS12
    TCheckBox*     exportCertAllPFX;       // IDC_ALFFCERTEXPPKCS12ALL
    bool				 exportCertAllPFX_Sw;
    TCheckBox*     deletePKeyPFX;          // IDC_ALFFCERTEXPPKCS12DELKEY
    bool				 deletePKeyPFX_Sw;

    TCheckBox*     exportCertKeyPFX;       // IDC_ALFFCERTEXPPKCS12KEY
    bool           exportCertKeyPFX_Sw;
    TGroupBox*     formatGroup;            // IDC_ALFFCERTEXPORTFORMATGRP

    TEdit*         certExportFilePath;     // IDC_ALFFCERTIMPORTPATH
    TButton*       certExportFileBrowse;   // IDC_ALFFCERTIMPORTBROWSE
    TEdit*         certExportFilePwd;      // IDC_ALFFCERTIMPORTFILEPWD

    // Buttons
    TButton*       certExport;       // IDC_ALFFCERTIMPORT

    // Event handlers
};
#endif
