#ifndef __OEMPKILIB_H__
#define __OEMPKILIB_H__

#include "AEE.h"
#include "AEEShell.h"
#include "AEERSA.h"
#include "AEEAppGen.h"

#ifndef PKICONTROL

#include "wim.h"
#include "x509.h"
#endif

#include "OEMWIMPrompt.h"


#define CLIENTCERTS_MAX (4) // 扱えるクライアント証明書の最大数.

/* HandshakeDigitalSign()の結果として期待する長さ
   128である根拠は、トライアル版のソースコードで使用している値と、
   メモリ上の秘密鍵を使った場合のRSA_size()の戻り値がともに128であったこと */
#define WIM_RSA_SIZE (128)

/* WIMタスクからkickCaller()を呼び出すときに引数に指定する値 */
#define NON_UiTask (0)

enum BrewPKIKind {
	BREWCLIANTAUTH  = 1,
	BREWDIGITALSIGN = 2,
};

enum WimLibWrapperRc {
	WIMLIBWP_FAILED    =-1, // 失敗.
	WIMLIBWP_WAITFORCB = 0, // 結果待ち.
	WIMLIBWP_SUCCESS   = 1  // 成功.
};

#define l2n3(l,c)	((c[0]=(unsigned char)(((l)>>16)&0xff), \
			  c[1]=(unsigned char)(((l)>> 8)&0xff), \
			  c[2]=(unsigned char)(((l)    )&0xff)),c+=3)


#define INVALID_CERT_SELECTION -1

typedef struct _WIMParam{
	// UI起動パラメータ
	unsigned int UIParam;				// 2= 署名 1=クライアント認証

	// オープン中WIMチャンネル番号
	WIM_TChannelNumber channelNo;				//チャネル番号を格納する

	// クライアント認証選択UIで選択された番号が入る(キャンセルの場合-1)
	int selectedCert;

	WIM_TRootCertificate* rootCerts;
	//ルート証明書の枚数
	unsigned int numRootCerts;

	// ルート証明書からクライアント証明書を取得(WIM_SearchClientCertsByKeyIDWithRootCerts)
	WIM_TClientCertificateInfo clientCerts[CLIENTCERTS_MAX];

	// クライアント証明書数
	unsigned int numClientCerts;

	// 署名対象データ
	unsigned char *targetdata;
	// 署名対象データ長
	unsigned long targetlength;
} WIMParam;






typedef struct{
	struct {
		IWebOpts       *clientCert;			// prompt
		const IWebOpts *m_pIWebOpts;		// prompt
		const byte     *pDNList;			// prompt
		AEECallback    *pUserCb;			// prompt RSA
		int            *pnErr;				// prompt RSA

		int            ePadType;			// RSA
		const byte     *inBuf;				// RSA
		int            inLen;				// RSA
		byte           *outBuf;				// RSA
		int            *outLen;				// RSA
	} param;

	struct { // HandshakeDigitalSign()用構造体.
		WIM_TInputData            hash;
		// ssl3_send_client_verify()@s3_clnt.cの、dataと同じ大きさ
//		char                      inbuf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
		char                      inbuf[16+20];
		WIM_TOutputDataResult     out;
		char                      outbuf[WIM_RSA_SIZE];
	} sign;
	
	struct { 
		 WIM_TClientCertificateInfo list[CLIENTCERTS_MAX];
		 int                        num;
		 int                        selected;
	} client;

	

	AEECallback						execCb;
	WIM_TRequestID					*lastRequestID;
	WIM_TChannelNumberResult		ch;
	WIM_TResult						res;
	WIM_TSENumber					protocolVersion;
	boolean							promptEnd;

//////////////////////////////////////////////////////////////////////////////////
	int NativeFlag;								// Native連携中フラグ
	int CancelCallbackFlag;						// AEE_CALLBACKを行わない

	//キャッシュから取得した証明書を格納する
	WIM_TCertificate certificate;

	// UIで選択された証明書が設定される
	WIM_TClientCertificateInfo info;			//選択した証明書情報を格納する

	//ルート証明書の枚数
	unsigned int numRootCerts;

	/// IWeb のルート証明書をMALLOCして保存する
	WIM_TRootCertificate* Alloc_rootCerts;

	// WimDigitalSignライブラリ
	WIMParam WIMprm;
	
	unsigned char *certs; 
	
	int *pnErr;
	int currentDepth;
	
	WIM_TCertificateReference  issureRef[CLIENTCERTS_MAX+1];

	WIM_TCertificate cert;


} OEMPKILIB_PRM;



#define INVALID_CHNUM (0)

void OEMPKILIB_getInstance(void);
void OEMPKILIB_Releasee(void);

void OEMPKILIB_WIM_encrypt2(
		const byte			*inBuf,			// IN  暗号化するデータのバッファ.
		int					inLen,			// IN  入力バッファの長さ.
		byte				*outBuf,		// OUT 暗号化されたデータを格納するバッファ.
	               							//     コール側で割り当てる.
		int					*outLen,		// IO 入力時:出力バッファの長さ 出力時:データの長さ.
		int					ePadType,		// IN  使用するパディングのタイプ.
		uint32				*pdwResult,		// OUT 結果コード.
		AEECallback			*pUserCb);		// IO  完了コールバック.

void OEMPKILIB_WIM_Prompt(
		const SSLSecurityInfo *pSecInfo,	// IN  SSLv3/TLSv1の判別に使用.
		IWebOpts              *clientCert,	// OUT クライアント証明書格納.
		const IWebOpts        *rootCerts,	// IN  ルート証明書取り出し.
		const byte            *pDNList,		// IN  DNList取得.
		AEECallback           *pUserCb,		// IO  ユーザ選択終了CB.
		int                   *pnErr);		// OUT 結果.

WIM_TRootCertificate* OEMPKILIB_extractRootCerts(IWebOpts* opts, unsigned int* numRootCerts);
//extern boolean ApiPkiCmpCurrentTime( X509 *x509 );

WIM_TReturnCode OEMPKILIB_PinCache(WIM_TChannelNumber channelNo);
WIM_TReturnCode OEMPKILIB_CertificateInfoCache(WIM_TChannelNumber channelNo);
WIM_TReturnCode OEMPKILIB_CertificateCertificateCache(WIM_TChannelNumber channelNo, WIM_TCertificateReference certRef);

#endif //__OEMPKILIB_H__
