initial commit; version 22.5.12042
This commit is contained in:
19
libs/hash-compat/LICENSE
Normal file
19
libs/hash-compat/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015 Indigo Development Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
66
libs/hash-compat/hash_equals.php
Normal file
66
libs/hash-compat/hash_equals.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('hash_equals')) {
|
||||
defined('USE_MB_STRING') or define('USE_MB_STRING', function_exists('mb_strlen'));
|
||||
|
||||
/**
|
||||
* hash_equals — Timing attack safe string comparison
|
||||
*
|
||||
* Arguments are null by default, so an appropriate warning can be triggered
|
||||
*
|
||||
* @param string $known_string
|
||||
* @param string $user_string
|
||||
*
|
||||
* @link http://php.net/manual/en/function.hash-equals.php
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function hash_equals($known_string = null, $user_string = null)
|
||||
{
|
||||
$argc = func_num_args();
|
||||
|
||||
// Check the number of arguments
|
||||
if ($argc < 2) {
|
||||
trigger_error(sprintf('hash_equals() expects exactly 2 parameters, %d given', $argc), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $known_string type
|
||||
if (!is_string($known_string)) {
|
||||
trigger_error(sprintf('hash_equals(): Expected known_string to be a string, %s given', strtolower(gettype($known_string))), E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check $user_string type
|
||||
if (!is_string($user_string)) {
|
||||
trigger_error(sprintf('hash_equals(): Expected user_string to be a string, %s given', strtolower(gettype($user_string))), E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensures raw binary string length returned
|
||||
$strlen = function($string) {
|
||||
if (USE_MB_STRING) {
|
||||
return mb_strlen($string, '8bit');
|
||||
}
|
||||
|
||||
return strlen($string);
|
||||
};
|
||||
|
||||
// Compare string lengths
|
||||
if (($length = $strlen($known_string)) !== $strlen($user_string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$diff = 0;
|
||||
|
||||
// Calculate differences
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$diff |= ord($known_string[$i]) ^ ord($user_string[$i]);
|
||||
}
|
||||
|
||||
return $diff === 0;
|
||||
}
|
||||
}
|
167
libs/hash-compat/hash_pbkdf2.php
Normal file
167
libs/hash-compat/hash_pbkdf2.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('hash_pbkdf2')) {
|
||||
defined('USE_MB_STRING') or define('USE_MB_STRING', function_exists('mb_strlen'));
|
||||
|
||||
/**
|
||||
* hash_pbkdf2 — Generate a PBKDF2 key derivation of a supplied password
|
||||
*
|
||||
* Arguments are null by default, so an appropriate warning can be triggered
|
||||
*
|
||||
* @param string $algo
|
||||
* @param string $password
|
||||
* @param string $salt
|
||||
* @param integer $iterations
|
||||
* @param integer $length
|
||||
* @param boolean $raw_output
|
||||
*
|
||||
* @link http://php.net/manual/en/function.hash-pbkdf2.php
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function hash_pbkdf2($algo = null, $password = null, $salt = null, $iterations = null, $length = 0, $raw_output = false)
|
||||
{
|
||||
$argc = func_num_args();
|
||||
|
||||
// Check the number of arguments
|
||||
if ($argc < 4) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects at least 4 parameters, %d given', $argc), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if a variable is acceptable as a string
|
||||
$notStringCastable = function($var) {
|
||||
return !is_scalar($var) && !is_null($var) && !(is_object($var) && method_exists($var, '__toString'));
|
||||
};
|
||||
|
||||
// Check if a variable is acceptable as an integer
|
||||
$notIntegerCastable = function($var) {
|
||||
return !is_numeric($var) && !is_null($var) && !is_bool($var);
|
||||
};
|
||||
|
||||
|
||||
// Check $algo type
|
||||
// Any values that can be casted to string is valid
|
||||
if ($notStringCastable($algo)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 1 to be string, %s given', gettype($algo)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $password type
|
||||
// Any values that can be casted to string is valid
|
||||
if ($notStringCastable($password)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 2 to be string, %s given', gettype($password)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $salt type
|
||||
// Any values that can be casted to string is valid
|
||||
if ($notStringCastable($salt)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 3 to be string, %s given', gettype($salt)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $iterations type
|
||||
// Any values that can be casted to integer is valid (null is evaluated to 0)
|
||||
if ($notIntegerCastable($iterations)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 4 to be long, %s given', gettype($iterations)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $length type
|
||||
// Any values that can be casted to integer is valid (null is evaluated to 0)
|
||||
if ($notIntegerCastable($length)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 5 to be long, %s given', gettype($length)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check $raw_output type
|
||||
// Any values that can be casted to boolean is valid (null is evaluated to false)
|
||||
if (!is_scalar($raw_output) and !is_null($raw_output)) {
|
||||
trigger_error(sprintf('hash_pbkdf2() expects parameter 6 to be boolean, %s given', gettype($raw_output)), E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check the algorithm
|
||||
if (!in_array($algo, hash_algos(), true)) {
|
||||
trigger_error('hash_pbkdf2(): Unknown hashing algorithm: '.$algo, E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensures raw binary string length returned
|
||||
$strlen = function($string) {
|
||||
if (USE_MB_STRING) {
|
||||
return mb_strlen($string, '8bit');
|
||||
}
|
||||
|
||||
return strlen($string);
|
||||
};
|
||||
|
||||
// Check salt length
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($salt_len = $strlen($salt) > PHP_INT_MAX - 4) {
|
||||
trigger_error(sprintf('hash_pbkdf2(): Supplied salt is too long, max of PHP_INT_MAX - 4 bytes: %d supplied', $salt_len), E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// Check $iterations is a positive integer
|
||||
if ($iterations < 1) {
|
||||
trigger_error('hash_pbkdf2(): Iterations must be a positive integer: ' . (int) $iterations, E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check $length is greater than or equal to 0 and integer
|
||||
if ($length < 0) {
|
||||
trigger_error('hash_pbkdf2(): Length must be greater than or equal to 0: ' . (int) $length, E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Type casting
|
||||
$algo = (string) $algo;
|
||||
$password = (string) $password;
|
||||
$salt = (string) $salt;
|
||||
$iterations = (int) $iterations;
|
||||
$length = (int) $length;
|
||||
$raw_output = (bool) $raw_output;
|
||||
|
||||
$hash_length = $strlen(hash($algo, null, true));
|
||||
|
||||
if ($length == 0) {
|
||||
$length = $raw_output ? $hash_length : $hash_length * 2;
|
||||
}
|
||||
|
||||
$digest_length = $length;
|
||||
|
||||
if (!$raw_output) {
|
||||
$digest_length = ceil($digest_length / 2);
|
||||
}
|
||||
|
||||
$block_count = ceil($digest_length / $hash_length);
|
||||
$hash = '';
|
||||
|
||||
for ($i = 1; $i <= $block_count; $i++) {
|
||||
$key = $digest = hash_hmac($algo, $salt . pack('N', $i), $password, true);
|
||||
|
||||
for ($j = 1; $j < $iterations; $j++) {
|
||||
$digest ^= $key = hash_hmac($algo, $key, $password, true);
|
||||
}
|
||||
|
||||
$hash .= $digest;
|
||||
}
|
||||
|
||||
// Built-in function returns the length of string, not the length of bytes (not RFC compatible)
|
||||
return substr($raw_output ? $hash : bin2hex($hash), 0, $length);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user