<?php

class CryptoEngine
{

  public $cipher = MCRYPT_BLOWFISH;

  public $mode = MCRYPT_MODE_ECB;

  public $source = MCRYPT_RAND;

  public $secret = null;

  public function encrypt($pure_string, $secret = null)
  {
    if ($secret == null)
      $secret = $this->secret;
    $iv_size = mcrypt_get_iv_size ( $this->cipher, $this->mode );
    $iv = mcrypt_create_iv ( $iv_size, $this->source );
    $pure_string = base64_encode ( $pure_string );
    $encrypted_string = mcrypt_encrypt ( $this->cipher, $secret, $pure_string, $this->mode, $iv );
    return $encrypted_string;
  }

  public function decrypt($encrypted_string, $secret = null)
  {
    if ($secret == null)
      $secret = $this->secret;
    $iv_size = mcrypt_get_iv_size ( $this->cipher, $this->mode );
    $iv = mcrypt_create_iv ( $iv_size, $this->source );
    $decrypted_string = mcrypt_decrypt ( $this->cipher, $secret, $encrypted_string, $this->mode, $iv );
    $decrypted_string = base64_decode ( $decrypted_string );
    return $decrypted_string;
  }
}

function rand_str($characters, $length)
{
  $randomString = '';
  for($i = 0; $i < $length; $i ++)
    $randomString .= $characters [rand ( 0, strlen ( $characters ) - 1 )];
  return $randomString;
}

/**
 *
 * @param boolean $forceNewPassword
 *          default=false
 * @return CryptoEngine
 */
function kria_get_ce($forceNewPassword = false)
{
  $masterSecretPath = dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'cert';
  if (! file_exists ( $masterSecretPath ))
    if (! mkdir ( $masterSecretPath ))
      return null;
  
  $secretRepositoryPath = $masterSecretPath . DIRECTORY_SEPARATOR . 'secrets';
  if (! file_exists ( $secretRepositoryPath ))
    if (! mkdir ( $secretRepositoryPath ))
      return null;
  
  $masterSecretFilename = $masterSecretPath . DIRECTORY_SEPARATOR . 'kria';
  if (! file_exists ( $masterSecretFilename ) || $forceNewPassword)
  {
    if (! file_put_contents ( $masterSecretFilename, rand_str ( '1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik9ol0p', 32 ) ))
      return null;
  }
  
  $ce = new CryptoEngine ();
  $ce->secret = file_get_contents ( $masterSecretFilename );
  return $ce;
}

function kria_get_secrets_folder()
{
  return dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'secrets';
}

function kria_get_secret_path($key)
{
  return kria_get_secrets_folder () . DIRECTORY_SEPARATOR . $key;
}

function kria_get_secrets()
{
  $dir = new DirectoryIterator ( kria_get_secrets_folder () );
  $secrets = array ();
  foreach ( $dir as $item )
  {
    if ($dir)
    {
      if ($dir->isFile ())
      {
        $secrets [] = $dir->getFilename ();
      }
    }
  }
  return $secrets;
}

function kria_reset_secret_environment()
{
  $secrets = array ();
  foreach ( kria_get_secrets () as $key )
    $secrets [$key] = kria_load_secret ( $key );
  kria_get_ce ( true );
  foreach ( $secrets as $key => $value )
    kria_save_secret ( $key, $value );
}

function kria_save_secret($key, $value)
{
  $ce = kria_get_ce ();
  $secretFilename = kria_get_secret_path ( $key );
  return file_put_contents ( $secretFilename, base64_encode ( $ce->encrypt ( $value ) ) ) !== false;
}

function kria_load_secret($key)
{
  $ce = kria_get_ce ();
  $secretFilename = kria_get_secret_path ( $key );
  return $ce->decrypt ( base64_decode ( file_get_contents ( $secretFilename ) ) );
}
