package tr.gov.titck.recete.encryptor;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.openssl.PEMParser;
import tr.gov.titck.recete.encryptor.Utils.RenkliKey;
import tr.gov.titck.recete.encryptor.Utils.RenkliRsaPublicKey;

class RenkliRsa
{
  private final KEYSIZE keysize;
  private static final int PADDING_PKCS1 = 11;
  
  public static enum KEYSIZE
  {
    RSA_2K(2048);
    
    int value;
    
    private KEYSIZE(int value)
    {
      this.value = value;
    }
    
    public int getEncLength()
    {
      return value / 8;
    }
  }
  



  RenkliRsa(KEYSIZE keysize)
  {
    this.keysize = keysize;
  }
  
  private AsymmetricBlockCipher getCipher(RenkliKey key)
  {
    AsymmetricBlockCipher cipher = new org.bouncycastle.crypto.engines.RSAEngine();
    cipher = new org.bouncycastle.crypto.encodings.PKCS1Encoding(cipher);
    cipher.init(true, key.getKey());
    return cipher;
  }
  








  RenkliRsaPublicKey readPublicKey(String filename)
    throws java.io.IOException
  {
    FileInputStream in = new FileInputStream(filename);Throwable localThrowable3 = null;
    try {
      key = readPublicKey(in);
    }
    catch (Throwable localThrowable1)
    {
      RenkliRsaPublicKey key;
      localThrowable3 = localThrowable1;throw localThrowable1;
    }
    finally {
      if (in != null) if (localThrowable3 != null) try { in.close(); } catch (Throwable localThrowable2) { localThrowable3.addSuppressed(localThrowable2); } else in.close(); }
    RenkliRsaPublicKey key; return key;
  }
  








  private RenkliRsaPublicKey readPublicKey(InputStream instream)
    throws java.io.IOException
  {
    InputStreamReader reader = new InputStreamReader(instream);Throwable localThrowable6 = null;
    try {
      PEMParser pem = new PEMParser(reader);Throwable localThrowable7 = null;
      try {
        pki = (SubjectPublicKeyInfo)pem.readObject();
      }
      catch (Throwable localThrowable1)
      {
        SubjectPublicKeyInfo pki;
        localThrowable7 = localThrowable1;throw localThrowable1;
      }
      finally {}
    }
    catch (Throwable localThrowable4)
    {
      SubjectPublicKeyInfo pki;
      localThrowable6 = localThrowable4;throw localThrowable4;

    }
    finally
    {

      if (reader != null) if (localThrowable6 != null) try { reader.close(); } catch (Throwable localThrowable5) { localThrowable6.addSuppressed(localThrowable5); } else reader.close(); }
    SubjectPublicKeyInfo pki;
    byte[] data = pki.getEncoded();
    RenkliRsaPublicKey key = new RenkliRsaPublicKey();
    key.setKey(org.bouncycastle.crypto.util.PublicKeyFactory.createKey(data));
    
    return key;
  }
  
  private byte[] doCipher(byte[] data, RenkliKey key) throws InvalidCipherTextException
  {
    AsymmetricBlockCipher cipher = getCipher(key);
    
    int max_length = keysize.getEncLength() - 11;
    int blocksize = max_length;
    int offset = 0;
    byte[] bytes = new byte[0];
    
    while (blocksize == max_length)
    {
      int remainder = data.length - offset;
      blocksize = remainder > max_length ? max_length : remainder;
      if (blocksize != 0)
      {
        byte[] enc = cipher.processBlock(data, offset, blocksize);
        bytes = tr.gov.titck.recete.encryptor.Utils.ByteUtils.concatenate(bytes, enc);
      }
      offset += max_length;
    }
    if (bytes.length == 0)
    {
      bytes = null;
    }
    
    return bytes;
  }
  
  byte[] encode(byte[] data, RenkliKey key) throws InvalidCipherTextException
  {
    return doCipher(data, key);
  }
}
