/* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; c-file-style:"stroustrup" -*-
*  
* Asyncronous key generation algorithm api
* 
* author: haavardm
*/
#ifndef ASYNCH_RSA_GEN_H_
#define ASYNCH_RSA_GEN_H_

#include "modules/libssl/sslenum.h"

typedef enum  
	{		
	RSA_KEYGEN_INITIALISING = 0,	
	RSA_KEYGEN_GENERATING_P,
	RSA_KEYGEN_DONE_GENERATING_P,
	RSA_KEYGEN_GENERATING_Q1,
	RSA_KEYGEN_GENERATING_Q2,	
	RSA_KEYGEN_DONE_GENERATING_Q,
	RSA_KEYGEN_DONE,
	} rsa_keygen_internal_state;

typedef struct keygen_state_handle 
	{
	rsa_keygen_internal_state state;	
	RSA *rsa; 
	int bits; 
	BIGNUM e_value; 
	BN_GENCB cb;

	BIGNUM *r0;
	BIGNUM *r1;
	BIGNUM *r2;
	BIGNUM *r3;
	BIGNUM *tmp;
	
	int bitsp;
	int bitsq;
	int ok;
	int n;
	BN_CTX *ctx;

	unsigned int degenerate;

	BOOL error;
	
	int progress;
	} RSA_KEYGEN_STATE_HANDLE;

#ifdef  __cplusplus
extern "C" {
#endif


/** Runs a slice of the keygeneration algorithm
 * 
 * 
 * @param state_handle (in) the state handle
 * 
 * @return ok-kode 1==ok, 0==error
 * 
 **/
int RSA_generate_key_ex_asynch_runslice(RSA_KEYGEN_STATE_HANDLE * state_handle);


/* Inits the keygeneration algorithm
 * 
 * @param keyPairBitSize (in) the bitsize of the keys
 * 
 * @return the a new state handler
 * 
 * when state_handle->state == RSA_KEYGEN_DONE,
 * stop loogin and call RSA_keygen_asynch_get_public_key
 * The state handle MUST be deleted by RSA_keygen_asynch_clean_up
 */
 
RSA_KEYGEN_STATE_HANDLE *RSA_generate_key_ex_asynch_init(int keyPairBitSize);

/* Call this when state_handle->state == RSA_KEYGEN_DONE after a call to RSA_generate_key_ex_asynch_runslice 
 * 
 * @param format (in) certificate format
 * @param challenge (in) unknown (ynge?)
 * @param publicKey (out) the public part of the key
 * @param public_key_length (out) length of public key
 * @param privateKeylength (out) length of the private key
 * @param state_handle the (in) keygeneration state handler
 * 
 * returns the the private key, NULL if error
 * 
 * check state_handle->state for state
 * and state_handle->error for error 
 */ 
unsigned char *
RSA_keygen_asynch_get_public_key(enum SSL_Certificate_Request_Format format,
						   	const char *challenge, unsigned char *public_key, 
						   	unsigned long *public_key_length,unsigned long *privateKeylength,
							RSA_KEYGEN_STATE_HANDLE * state_handle);
							
/** free's the RSA_KEYGEN_STATE_HANDLE generated by RSA_generate_key_ex_asynch_init
 *
 * @param state_handle (in) the state handle
 * 
 **/
void RSA_keygen_asynch_clean_up(RSA_KEYGEN_STATE_HANDLE * state_handle);

/**
 * Low level asynchronous keygeneration algorithm
 * Do --NOT-- use this function together with RSA_generate_key_ex_asynch_init or RSA_keygen_asynch_clean_up
 * 
 */
int RSA_generate_key_ex_asynch(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb, RSA_KEYGEN_STATE_HANDLE * state_handle);

#ifdef  __cplusplus
}
#endif
#endif /*ASYNCH_RSA_GEN_H_*/
