package eu.dnetlib.enabling.aas.utils;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * Utility class for creating asymmetric keys, encrypting and decrypting.
 * @author mhorst
 *
 */
public class SecurityUtils {

	public static int DEFAULT_KEYSIZE = 512;
	public static String DEFAULT_ENC_ALGORITHM = "RSA";
	public static String DEFAULT_TRANSFORMATION = "RSA/NONE/PKCS1PADDING";
	
	private int keysize = DEFAULT_KEYSIZE;
	private String encAlgorithm = DEFAULT_ENC_ALGORITHM;
	private String transformation = DEFAULT_TRANSFORMATION;
	
	static {
		Security.addProvider(new BouncyCastleProvider());
	}

	/**
	 * Generates random key pair.
	 * @return KeyPair
	 * @throws NoSuchAlgorithmException
	 */
	public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
		KeyPairGenerator generator = KeyPairGenerator.getInstance(encAlgorithm);
		SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
		generator.initialize(keysize,random);
		return generator.generateKeyPair();
	}

	
	/**
	 * Encrypts input data with public key given as parameter.
	 * @param inpBytes
	 * @param key
	 * @param xform
	 * @return
	 * @throws Exception
	 */
	public byte[] encrypt(byte[] inpBytes, PublicKey key)
			throws Exception {
		Cipher cipher = Cipher.getInstance(transformation);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(inpBytes);
	}

	/**
	 * Decrypts input data with private key given as parameter.
	 * @param inpBytes
	 * @param key
	 * @param xform
	 * @return
	 * @throws Exception
	 */
	public byte[] decrypt(byte[] inpBytes, PrivateKey key)
			throws Exception {
		Cipher cipher = Cipher.getInstance(transformation);
		cipher.init(Cipher.DECRYPT_MODE, key);
		return cipher.doFinal(inpBytes);
	}
	
	/**
	 * Sets keysize of generated keys.
	 * @param keysize
	 */
	public void setKeysize(int keysize) {
		this.keysize = keysize;
	}

	/**
	 * Sets encryption algorithm.
	 * @param encAlgorithm
	 */
	public void setEncAlgorithm(String encAlgorithm) {
		this.encAlgorithm = encAlgorithm;
	}

	/**
	 * Sets transformation method.
	 * @param transformation
	 */
	public void setTransformation(String transformation) {
		this.transformation = transformation;
	} 
}
