/***************************************************************************
                          cssl.h  -  description
                             -------------------
    begin                : Sat Dec 7 2002
    copyright            : (C) 2002-2003 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef CSSL_H
#define CSSL_H

/**
  *@author Mathias Küster
  *
  * This has some SSL utility functions and does some
  * cryptography for the "secure" private chat.
  */

#include <dclib/dcos.h>
#include <dclib/core/cstring.h>

#include <dclib/dclib-ssl-use.h>

#if DCLIB_USES_OPENSSL == 1

#include <openssl/opensslv.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#else

/* this may also work for SSL builds */
typedef struct rsa_st RSA;
typedef struct ssl_ctx_st SSL_CTX;

#endif

class CMutex;

class CSSLObject {
public:
	/** */
	CSSLObject() {
		m_bHandshakeState = 0;
		m_pRSA            = 0;
	};
	/** */
	~CSSLObject();

	/** */
	int m_bHandshakeState;
	/* */
	RSA * m_pRSA;
	/** */
	unsigned char m_localkey[16];
	/** */
	unsigned char m_localiv[8];
	/** */
	unsigned char m_remotekey[16];
	/** */
	unsigned char m_remoteiv[8];
};

class CSSL {
public:
	/** */
	CSSL();
	/** */
	virtual ~CSSL();

	/** */
	static SSL_CTX * InitClientCTX();
	/** */
	static SSL_CTX * InitServerCTX();
	/**
	 * As the name suggests it creates a new client SSL_CTX
	 * that only supports >= TLSv1, required for
	 * *DC++ compatibility.
	 */
	static SSL_CTX * NewTLSv1ClientCTX();
	/**
	 * As the name suggests it creates a new server SSL_CTX
	 * that only supports >= TLSv1, required for
	 * *DC++ compatibility.
	 */
	static SSL_CTX * NewTLSv1ServerCTX();
	/** */
	static bool LoadCertificates( SSL_CTX * ctx, char * CertFile, char * KeyFile );
	/** Get SSL library version string */
	static CString GetSSLVersionString();
	/** Perform library initialisation functions */
	static void InitSSLLibrary();
	/** Perform library deinitialisation functions */
	static void DeInitSSLLibrary();

protected:
	/** */
	void InitRand();
	/** */
	void InitRandArray( unsigned char * a, int len );
	/** */
	bool GenerateRsaKey();
	/** */
	CString GetPublicRsaKey();
	/** */
	bool SetPublicKey( CSSLObject * SSLObject, CString s );
	/** */
	void InitSessionKey( CSSLObject * SSLObject );
	/** */
	CString GetSessionKey( CSSLObject * SSLObject );
	/** */
	bool SetSessionKey( CSSLObject * SSLObject, CString s );
	/** */
	CString EncryptData( CSSLObject * SSLObject, CString s );
	/** */
	CString DecryptData( CSSLObject * SSLObject, CString s );

	/* */
	RSA * m_pRSA;
	/** */
	int * m_pRandBuffer;

private:
	/** some mutexes for OpenSSL to use */
	static CMutex * mutexes;
	/**
	 * a function to give to OpenSSL for it to use the mutexes
	 * FIXME that const will have been added in some version...
	 * breaking things with older versions
	 */
	static void locking_callback( int mode, int type, const char * file, int line );
#ifndef WIN32
	/** a thread id function, not required on Windows */
	static unsigned long thread_id();
#endif /* WIN32 */
};

#endif
