/*! \file piauth.h
 * \ingroup Crypt
 * \~\brief
 * \~english Authentication API
 * \~russian API аутентификации
 */
/*
	PIP - Platform Independent Primitives
	PIP Authentication API
	Andrey Bychkov work.a.b@yandex.ru

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

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PIAUTH_H
#define PIAUTH_H

#include "pip_crypt_export.h"
#include "piobject.h"
#include "picrypt.h"


class PIP_CRYPT_EXPORT PIAuth : public PIObject
{
	PIOBJECT(PIAuth)
public:
	enum State {NotConnected, AuthProbe, PassRequest, AuthReply, KeyExchange, Connected};

	//! Create PIAuth with your digital sign
	PIAuth(const PIByteArray & sign);

	//! Set server info data for client authorize event
	void setInfoData(const PIByteArray & info) {custom_info = info;}

	//! Set server password for check
	void setServerPassword(const PIString & ps);

	//! Set list of trusted clients/servers public digital sign keys
	void setAuthorizedPublicKeys(const PIVector<PIByteArray> & pkeys) {auth_pkeys = pkeys;}

	//! Get list of trusted clients/servers public digital sign keys
	PIVector<PIByteArray> getAuthorizedPublicKeys() {return auth_pkeys;}

	//! Get your digital sign public key
	PIByteArray getSignPublicKey() {return sign_pk;}


	//! Stop authorization
	void stop();

	//! Start authorization as client
	void startClient();

	//! Start authorization as server, return first server message for client
	PIByteArray startServer();

	//! Process reseived message both for client and server, return current state and new message writed in "ba"
	State receive(PIByteArray & ba);

	//! Get session secret key, return key only when Connected state
	PIByteArray getSecretKey();

	//! Generate digital sign from seed
	static PIByteArray generateSign(const PIByteArray & seed);


	//! Disconneted event
	EVENT1(disconnected, PIString, reason);

	//! Conneted event
	EVENT1(connected, PIString, info);

	//! Client event for authorize new server
	EVENT2(authorize, PIByteArray, info, bool *, ok);

	//! Client event for input server password
	EVENT1(passwordRequest, PIString *, pass);

	//! Server event on check client password
	EVENT1(passwordCheck, bool, result);

private:
	enum Role {Client, Server};

	State disconnect(PIByteArray & ba, const PIString & error = PIString());
	bool isAuthorizedKey(const PIByteArray & pkey);

	PIByteArray createSKMessage();

	Role role;
	State state;
	PIByteArray custom_info;
	PICrypt crypt;
	PIByteArray sign_sk, sign_pk;
	PIByteArray auth_sign;
	PIByteArray box_sk, box_pk;
	PIByteArray my_pk;
	PIByteArray secret_key;
	PIByteArray pass_hash;
	PIVector<PIByteArray> auth_pkeys;
};

#endif // PIAUTH_H
