/*(c) 2006 - 2008 AllenPort Co. All Rights Reserved.
All versions of this code, including the source and executable versions, 
constitute the intellectual property of AllenPort Co., which expressly reserves 
any and all U.S. and foreign rights and benefits to the code under copyright, 
trade secret and any other intellectual property law or international treaty 
whatsoever. Use of the code is subject to the terms and conditions of a separate 
written license agreement, and the code shall not be reproduced, modified, distributed 
or otherwise used in any form or manner whatsoever without obtaining the prior written 
permission of AllenPort Co. Any unauthorized reproduction or distribution of the code, 
or any portion of it, may result in civil and criminal penalties and be prosecuted 
to the fullest extent of the law.*/
function RSACipher()
{
    this.isDecrypted = false;
    this.isEncrypted = false;
    this.encrypted_message = "";
    this.decrypted_message = "";
}

function encrypt_with_rsa(rsa_key, message_to_encrypt)
{
	var encrypted_message = "";
	for(var i = 0; i < message_to_encrypt.length; i+=52)
	{
		var chunk = message_to_encrypt.substr(i, 52);
		var enc_chunk = rsa_key.encrypt(chunk);
		if(enc_chunk.length != 128)
		{
		    var pad_size = 128 - enc_chunk.length;
		    for(var j = 0; j < pad_size; j++) 
		        enc_chunk = '0' + enc_chunk;
		}
		  
		encrypted_message += enc_chunk;
	}		
	return encrypted_message;
}
		
//message_to_decrypt in hex
//return decrypted_message in hex
function decrypt_with_rsa(rsa_key, message_to_decrypt)
{
	var decrypted_message = "";
	for(var i = 0; i < message_to_decrypt.length; i+=128)
	{
		var chunk = message_to_decrypt.substr(i, 128);
		decrypted_message += rsa_key.decrypt(chunk);
	}		
	return decrypted_message;
}

function RSA_decrypt_with_rsa_Ex()
{
    if(!this.isDecrypted)
    {
        if(this.counter >= this.message.length)
        {
            this.isDecrypted = true;
            return;
        }
    	var chunk = this.message.substr(this.counter, 128);
    	this.decrypted_message += this.rsa_key.decrypt(chunk);
    	this.counter+=128;
    	var that = this;
        setTimeout(function () {that.decrypt_with_rsa_Ex_internal();} , 0);
    }
}

function decrypt_with_rsa_Ex(rsa_key, message)
{
    this.isDecrypted = false;
    this.decrypted_message = "";
    this.rsa_key = rsa_key;
    this.message = message;
    this.counter = 0;
    this.decrypt_with_rsa_Ex_internal();
}

function create_rsa()
{
    var rsa = new RSAKey();
    var e = "10001";
	//rsa.generate(parseInt(512),e);
	rsa.generateEx(parseInt(512),e);
	return rsa;
}

//rsa_public_pem_string [String] - public key in PEM format
//return                [RSAKey] - public part.
function get_public_rsa_key_from_pem(rsa_public_pem_string)
{
    var public_rsa_in_base64 = rsa_public_pem_string.split('\n').slice(1,-2).join('');
    var public_key_der = base64Decode(public_rsa_in_base64);
    return der_to_rsa_format(public_key_der, true);
}
//rsa_private_pem_string [String] - private key in PEM format 
//return                 [RSAKey] - private part.
function get_private_rsa_key_from_pem(rsa_private_pem_string)
{
    var private_rsa_in_base64 = rsa_private_pem_string.split('\n').slice(1,-2).join(''); 
    var private_key_der = base64Decode(private_rsa_in_base64);  
    return der_to_rsa_format(private_key_der, false);
}
//public_rsa_key [RSAKey] - public part 
//return         [String] - public key in PEM format.
function get_pem_from_public_rsa_key(public_rsa_key)
{
    var public_key_der = rsa_to_der_format(public_rsa_key, true);
	var public_key_pem = "-----BEGIN PUBLIC KEY-----\n" + base64ToOpenSSl(public_key_der) + "-----END PUBLIC KEY-----\n";
	return public_key_pem;
}
//private_rsa_key [RSAKey] - private part 
//return          [String] - private key in PEM format.
function get_pem_from_private_rsa_key(private_rsa_key)
{
    var private_key_der = rsa_to_der_format(private_rsa_key, false);
    var private_key_pem = "-----BEGIN RSA PRIVATE KEY-----\n" + base64ToOpenSSl(private_key_der) + "-----END RSA PRIVATE KEY-----\n";
    return private_key_pem;
}

RSACipher.prototype.decrypt_with_rsa_Ex_internal = RSA_decrypt_with_rsa_Ex;
RSACipher.prototype.decrypt_with_rsa = decrypt_with_rsa_Ex;