<?php
// +------------------------------------------------------------------------+
// | @author BΛSΞ
// | @author_email: support@buildwithbase.com
// | @company_name: BΛSΞ Framework
// +------------------------------------------------------------------------+
// | JWT-SSO -- JSON Web Token Based Single Sign On
// | Copyright (c) 2024 BΛSΞ. All rights reserved.
// +------------------------------------------------------------------------+

class Security
{
    public $salt;
        /**
     * Secure User Input
     * 
     * @param string $string User Typed String 
     */
    public static function input_secure($string, $br = true, $strip = 0)
    {
        $string = trim($string);
        $string = preg_replace("/&#?[a-z0-9]+;/i", "", $string);
        $string = htmlspecialchars($string, ENT_QUOTES);
        if ($br == true) {
            $string = str_replace('\r\n', " <br>", $string);
            $string = str_replace('\n\r', " <br>", $string);
            $string = str_replace('\r', " <br>", $string);
            $string = str_replace('\n', " <br>", $string);
        } else {
            $string = str_replace('\r\n', "", $string);
            $string = str_replace('\n\r', "", $string);
            $string = str_replace('\r', "", $string);
            $string = str_replace('\n', "", $string);
        }
        if ($strip == 1) {
            $string = stripslashes($string);
        }
        $string = str_replace('&amp;#', '&#', $string);
        return $string;
    }

    public static function int_only($string)
    {
        $string = preg_replace('/[^\d+$]/', "", $string);
        return $string;
    }

    /**
     * CSRF Protection 
     *  
     * @param string $token CSRF Protection Token
     */

    public static function create_csrftoken()
    {
        // create token
        $token = bin2hex(random_bytes(16));
        //Save in Session
        $_SESSION['csrf_token'] = $token;
        //create hidden field
        echo "<input type='hidden' name='csrf_token' value='$token'/>";
    }
    public static function validate_csrftoken($token)
    {
        //Validate Token
        return isset($_SESSION["csrf_token"]) && $_SESSION["csrf_token"] == $token;
    }
    /**
     * Get an AES key from a static password and a secret salt
     * 
     * @param string $password Your weak password here
     * @param int $keysize Number of bytes in encryption key
     */
    public function getKeyFromPassword($password, $keysize = 32)
    {
        $salt = base64_encode(openssl_random_pseudo_bytes(32));

        $key = hash_pbkdf2(
            'sha384',
            $password,
            $salt,
            120000, // Number of iterations
            $keysize,
            false
        );

        return array("key" => $key, "salt" => $salt);
    }

    /**
     * Generate Random Key for Encryption 
     * @param int $keysize Keysize in Bytes.
     */
    public function generateRandomKey($keysize)
    {
        return bin2hex(random_bytes($keysize));
    }

    /**
     * Regenerate AES key from a static password and a secret salt
     * 
     * @param string $password Your weak password here
     * @param string $salt Your Previous Generated Salt
     * @param int $keysize Number of bytes in encryption key
     */
    public function getKeyFromPasswordAndSalt($password, $salt, $keysize = 32)
    {
        return hash_pbkdf2(
            'sha384',
            $password,
            $salt,
            120000, // Number of iterations
            $keysize,
            false
        );
    }

    //  AES Encrypt Method
    /**
     * AES-CBC Encryption Text Function Default Set to AES-128-CBC
     * @param mixed $text String you want to encrypt
     * @param mixed $encryption_key Encryption Key 
     * @param int $options Options for openssl 
     * @return (string|false)[] 
     */
    public static function aescbc_encrypt($text, $encryption_key, $ciphering_method = "AES-256-CBC", $options = OPENSSL_RAW_DATA)
    {
        $iv_length = openssl_cipher_iv_length($ciphering_method);
        $iv = openssl_random_pseudo_bytes($iv_length);
        $encrypted = openssl_encrypt(
            $text,
            $ciphering_method,
            $encryption_key,
            $options,
            $iv
        );
        // return $encrypted;
        return base64_encode($iv . $encrypted);
    }
    
    /**
     * AES-CBC Decryption Text Function Default Set to AES-128-CBC
     * 
     * @param array|string $encrypted Array Of encrypted string and iv value
     * @param mixed $decryption_key Key used to Encrypt string
     * @param int $options Options for open ssl
     * @return false|string 
     */
    public static function aescbc_decrypt($encrypted, $decryption_key, $ciphering_method = "AES-256-CBC", $options = OPENSSL_RAW_DATA)
    {
        $data = base64_decode($encrypted);
        $iv_length = openssl_cipher_iv_length($ciphering_method);
        $iv = substr($data, 0, $iv_length);
        $text = substr($data, $iv_length);
        $decrypted = openssl_decrypt(
            $text,
            $ciphering_method,
            $decryption_key,
            $options,
            $iv
        );
        if ($decrypted == false) {
            return false;
        } else {
            return $decrypted;
        }
    }
}