<?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)));
}
