From a43ad7bdf5026b5d75a8b006eddf9b20ef10f405 Mon Sep 17 00:00:00 2001 From: Gary Allan <github@gallan.co.uk> Date: Thu, 25 Jul 2019 12:35:31 +0100 Subject: [PATCH] Feature: Hook up PR #2667 --- api/index.php | 11 ++--- config.dist.php | 7 +++- functions/classes/class.Crypto.php | 67 +++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/api/index.php b/api/index.php index 23e54bbb..d9540508 100755 --- a/api/index.php +++ b/api/index.php @@ -66,16 +66,11 @@ try { // crypt check if($app->app_security=="crypt") { - $api_crypt_encryption_library = Config::get('api_crypt_encryption_library') === "mcrypt" ? 'mcrypt' : 'openssl'; - - // verify php extensions - if (!in_array($api_crypt_encryption_library, get_loaded_extensions())) { - $Response->throw_exception(500, 'php extension '.$api_crypt_encryption_library.' missing'); - } + $encryption_method = Config::get('api_crypt_encryption_library', 'openssl-128-cbc'); // decrypt request - form_encoded if(strpos($_SERVER['CONTENT_TYPE'], "application/x-www-form-urlencoded")!==false) { - $decoded = $User->Crypto->decrypt($_GET['enc_request'], $app->app_code, $api_crypt_encryption_library); + $decoded = $User->Crypto->decrypt($_GET['enc_request'], $app->app_code, $encryption_method); if ($decoded === false) $Response->throw_exception(503, 'Invalid enc_request'); $decoded = $decoded[0]=="?" ? substr($decoded, 1) : $decoded; parse_str($decoded, $encrypted_params); @@ -84,7 +79,7 @@ try { } // json_encoded else { - $encrypted_params = $User->Crypto->decrypt($_GET['enc_request'], $app->app_code, $api_crypt_encryption_library); + $encrypted_params = $User->Crypto->decrypt($_GET['enc_request'], $app->app_code, $encryption_method); if ($encrypted_params === false) $Response->throw_exception(503, 'Invalid enc_request'); $encrypted_params = json_decode($encrypted_params, true); $encrypted_params['app_id'] = $_GET['app_id']; diff --git a/config.dist.php b/config.dist.php index b77ed6ff..9073d1b7 100755 --- a/config.dist.php +++ b/config.dist.php @@ -75,9 +75,12 @@ $config['resolve_verbose'] = true; // verbose response - print $debugging = false; /* - * API Crypt security provider. "mcrypt" or "openssl" + * API Crypt security provider. "mcrypt" or "openssl*" + * Supported methods: + * openssl-128-cbc (alias openssl, openssl-128) *default + * openssl-256-cbc (alias openssl-256) * - * default as of 1.3.2 "openssl" + * default as of 1.3.2 "openssl-128-cbc" ******************************/ // $api_crypt_encryption_library = "mcrypt"; diff --git a/functions/classes/class.Crypto.php b/functions/classes/class.Crypto.php index df472524..9f429db8 100644 --- a/functions/classes/class.Crypto.php +++ b/functions/classes/class.Crypto.php @@ -71,28 +71,65 @@ class Crypto { * encrypt data and base64 encode results * @param string $rawdata * @param string $password - * @param string $encryption_library (default value: "openssl") + * @param string method (default value: "openssl-128-cbc") * @return string|false */ - public function encrypt($rawdata, $password, $encryption_library="openssl") { - if ($encryption_library === "mcrypt") + public function encrypt($rawdata, $password, $method="openssl-128-cbc") { + $method = $this->supported_methods($method); + + if ($method === 'mcrypt') return $this->encrypt_using_legacy_mcrypt($rawdata, $password); else - return $this->encrypt_using_openssl($rawdata, $password, $encryption_library); + return $this->encrypt_using_openssl($rawdata, $password, $method); } /** * decrypt base64 encoded data * @param string $base64data * @param string $password - * @param string $encryption_library (default value: "openssl") + * @param string $method (default value: "openssl-128-cbc") * @return string|false */ - public function decrypt($base64data, $password, $encryption_library="openssl") { - if ($encryption_library === "mcrypt") + public function decrypt($base64data, $password, $method="openssl-128-cbc") { + $method = $this->supported_methods($method); + + if ($method === "mcrypt") return $this->decrypt_using_legacy_mcrypt($base64data, $password); else - return $this->decrypt_using_openssl($base64data, $password, $encryption_library); + return $this->decrypt_using_openssl($base64data, $password, $method); + } + + /** + * Return a supported encryption method + * @param string $method + * @return string + */ + private function supported_methods($method) { + switch ($method) { + case 'mcrypt': + $retval = 'mcrypt'; + break; + + case 'openssl': + case 'openssl-128': + case 'openssl-128-cbc': + $retval = 'AES-128-CBC'; + break; + + case 'openssl-256': + case 'openssl-256-cbc': + $retval = 'AES-256-CBC'; + break; + + default: + $this->Result->show("danger", _("Error: "). _('Unsupported $api_crypt_encryption_library method: ').escape_input($method), true); + } + + $required_ext = ($retval === 'mcrypt') ? 'mcrypt' : 'openssl'; + if (!in_array($required_ext, get_loaded_extensions())) + $this->Result->show("danger", _("Error: "). _('php extension not installed: ').$required_ext, true); + + return $retval; } // OpenSSL @@ -101,12 +138,11 @@ class Crypto { * encrypt data and base64 encode results * @param string $rawdata * @param string $password + * @param string $method * @return string|false */ - private function encrypt_using_openssl($rawdata, $password, $key_size) { - $method = ($key_size == "openssl-256") ? 'AES-256-CBC' : 'AES-128-CBC'; - - // Binary key derived from password + private function encrypt_using_openssl($rawdata, $password, $method) { + // Binary key derived from password (32 bytes) $key = openssl_digest($password, 'sha256', true); // Encrypt using IV $ivlen = openssl_cipher_iv_length($method); @@ -124,12 +160,11 @@ class Crypto { * decrypt base64 encoded data * @param string $base64data * @param string $password + * @param string $method * @return string|false */ - private function decrypt_using_openssl($base64data, $password, $key_size) { - $method = ($key_size == "openssl-256") ? 'AES-256-CBC' : 'AES-128-CBC'; - - // Binary key derived from password + private function decrypt_using_openssl($base64data, $password, $method) { + // Binary key derived from password (32 bytes) $key = openssl_digest($password, 'sha256', true); $c = base64_decode($base64data); -- GitLab