Initial commit

This commit is contained in:
2020-10-07 10:37:15 +02:00
commit ce5f440392
28157 changed files with 4429172 additions and 0 deletions

View File

@@ -0,0 +1,314 @@
<?php
/**
* A Compatibility library with PHP 5.5's simplified password hashing API.
*
* @author Anthony Ferrara <ircmaxell@php.net>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2012 The Authors
*/
namespace {
if (!defined('PASSWORD_BCRYPT')) {
/**
* PHPUnit Process isolation caches constants, but not function declarations.
* So we need to check if the constants are defined separately from
* the functions to enable supporting process isolation in userland
* code.
*/
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
}
if (!function_exists('password_hash')) {
/**
* Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array()) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (is_null($password) || is_int($password)) {
$password = (string) $password;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
return null;
}
$resultLength = 0;
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = PASSWORD_BCRYPT_DEFAULT_COST;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
// The expected length of the final crypt() output
$resultLength = 60;
break;
default:
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
return null;
}
$salt_requires_encoding = false;
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt_requires_encoding = true;
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && @is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = PasswordCompat\binary\_strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = PasswordCompat\binary\_strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
$bl = PasswordCompat\binary\_strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = $buffer;
$salt_requires_encoding = true;
}
if ($salt_requires_encoding) {
// encode string with the Base64 variant used by crypt
$base64_digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$bcrypt64_digits =
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$base64_string = base64_encode($salt);
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
}
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
$hash = $hash_format . $salt;
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
return false;
}
return $ret;
}
/**
* Get information about the password hash. Returns an array of the information
* that was used to generate the password hash.
*
* array(
* 'algo' => 1,
* 'algoName' => 'bcrypt',
* 'options' => array(
* 'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
* ),
* )
*
* @param string $hash The password hash to extract info from
*
* @return array The array of information about the hash.
*/
function password_get_info($hash) {
$return = array(
'algo' => 0,
'algoName' => 'unknown',
'options' => array(),
);
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
$return['algo'] = PASSWORD_BCRYPT;
$return['algoName'] = 'bcrypt';
list($cost) = sscanf($hash, "$2y$%d$");
$return['options']['cost'] = $cost;
}
return $return;
}
/**
* Determine if the password hash needs to be rehashed according to the options provided
*
* If the answer is true, after validating the password using password_verify, rehash it.
*
* @param string $hash The hash to test
* @param int $algo The algorithm used for new password hashes
* @param array $options The options array passed to password_hash
*
* @return boolean True if the password needs to be rehashed.
*/
function password_needs_rehash($hash, $algo, array $options = array()) {
$info = password_get_info($hash);
if ($info['algo'] != $algo) {
return true;
}
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = isset($options['cost']) ? $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
if ($cost != $info['options']['cost']) {
return true;
}
break;
}
return false;
}
/**
* Verify a password against a hash using a timing attack resistant approach
*
* @param string $password The password to verify
* @param string $hash The hash to verify against
*
* @return boolean If the password matches the hash
*/
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
return false;
}
$status = 0;
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
}
}
namespace PasswordCompat\binary {
if (!function_exists('PasswordCompat\\binary\\_strlen')) {
/**
* Count the number of bytes in a string
*
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
* sequence of bytes might be regarded as a single multibyte character.
*
* @param string $binary_string The input string
*
* @internal
* @return int The number of bytes
*/
function _strlen($binary_string) {
if (function_exists('mb_strlen')) {
return mb_strlen($binary_string, '8bit');
}
return strlen($binary_string);
}
/**
* Get a substring based on byte limits
*
* @see _strlen()
*
* @param string $binary_string The input string
* @param int $start
* @param int $length
*
* @internal
* @return string The substring
*/
function _substr($binary_string, $start, $length) {
if (function_exists('mb_substr')) {
return mb_substr($binary_string, $start, $length, '8bit');
}
return substr($binary_string, $start, $length);
}
/**
* Check if current PHP version is compatible with the library
*
* @return boolean the check result
*/
function check() {
static $pass = NULL;
if (is_null($pass)) {
if (function_exists('crypt')) {
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
} else {
$pass = false;
}
}
return $pass;
}
}
}

View File

@@ -0,0 +1,6 @@
<?php
require "lib/password.php";
echo "Test for functionality of compat library: " . (PasswordCompat\binary\check() ? "Pass" : "Fail");
echo "\n";

58
vendor/ircmaxell/random-lib/.php_cs vendored Normal file
View File

@@ -0,0 +1,58 @@
<?php
$header = <<<'EOF'
The RandomLib library for securely generating random numbers and strings in PHP
@author Anthony Ferrara <ircmaxell@ircmaxell.com>
@copyright 2011 The Authors
@license http://www.opensource.org/licenses/mit-license.html MIT License
@version Build @@version@@
EOF;
Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader($header);
return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers([
'align_double_arrow',
'array_element_no_space_before_comma',
'array_element_white_space_after_comma',
'declare_equal_normalize',
'extra_empty_lines',
'header_comment',
'list_commas',
'multiline_array_trailing_comma',
'new_with_braces',
'no_blank_lines_before_namespace',
'no_empty_comment',
'no_empty_lines_after_phpdocs',
'no_empty_phpdoc',
'no_empty_statement',
'object_operator',
'ordered_use',
'php_unit_dedicate_assert',
'phpdoc_indent',
'phpdoc_order',
'phpdoc_params',
'phpdoc_scalar',
'phpdoc_separation',
'remove_leading_slash_use',
'remove_lines_between_uses',
'return',
'self_accessor',
'short_bool_cast',
'short_scalar_cast',
'single_blank_line_before_namespace',
'spaces_before_semicolon',
'ternary_spaces',
'trim_array_spaces',
'unneeded_control_parentheses',
'unused_use',
'whitespacey_lines',
])
->finder(
Symfony\CS\Finder\DefaultFinder::create()
->in(__DIR__ . "/lib")
->in(__DIR__ . "/test")
)
;

19
vendor/ircmaxell/random-lib/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2011 The Authors
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.

25
vendor/ircmaxell/random-lib/Makefile vendored Normal file
View File

@@ -0,0 +1,25 @@
.PHONY: all
all: build
.PHONY: build
build: lint cs test
lintfiles := $(shell find lib test -type f -iname '*.php')
.PHONY: ${lintfiles}
${lintfiles}:
php -l $@
.PHONY: lint
lint: $(lintfiles)
.PHONY: cs
cs:
vendor/bin/php-cs-fixer --quiet --no-interaction fix; true
.PHONY: test
test:
vendor/bin/phpunit

View File

@@ -0,0 +1,176 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mcrypt abstract mixer class
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The mcrypt abstract mixer class
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
abstract class AbstractMcryptMixer extends AbstractMixer
{
/**
* mcrypt module resource
*
* @var resource
*/
private $mcrypt;
/**
* Block size of cipher
*
* @var int
*/
private $blockSize;
/**
* Cipher initialization vector
*
* @var string
*/
private $initv;
/**
* {@inheritdoc}
*/
public static function test()
{
return extension_loaded('mcrypt');
}
/**
* Construct mcrypt mixer
*/
public function __construct()
{
$this->mcrypt = mcrypt_module_open($this->getCipher(), '', MCRYPT_MODE_ECB, '');
$this->blockSize = mcrypt_enc_get_block_size($this->mcrypt);
$this->initv = str_repeat(chr(0), mcrypt_enc_get_iv_size($this->mcrypt));
}
/**
* Performs cleanup
*/
public function __destruct()
{
if ($this->mcrypt) {
mcrypt_module_close($this->mcrypt);
}
}
/**
* Fetch the cipher for mcrypt.
*
* @return string
*/
abstract protected function getCipher();
/**
* {@inheritdoc}
*/
protected function getPartSize()
{
return $this->blockSize;
}
/**
* {@inheritdoc}
*/
protected function mixParts1($part1, $part2)
{
return $this->encryptBlock($part1, $part2);
}
/**
* {@inheritdoc}
*/
protected function mixParts2($part1, $part2)
{
return $this->decryptBlock($part2, $part1);
}
/**
* Encrypts a block using the suppied key
*
* @param string $input Plaintext to encrypt
* @param string $key Encryption key
*
* @return string Resulting ciphertext
*/
private function encryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mcrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Derypts a block using the suppied key
*
* @param string $input Ciphertext to decrypt
* @param string $key Encryption key
*
* @return string Resulting plaintext
*/
private function decryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mdecrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Sets up the mcrypt module
*
* @param string $key
*
* @return void
*/
private function prepareCipher($key)
{
if (0 !== mcrypt_generic_init($this->mcrypt, $key, $this->initv)) {
throw new \RuntimeException('Failed to prepare mcrypt module');
}
}
}

View File

@@ -0,0 +1,158 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* An abstract mixer to implement a common mixing strategy
*
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Util;
/**
* An abstract mixer to implement a common mixing strategy
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
abstract class AbstractMixer implements \RandomLib\Mixer
{
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
abstract protected function getPartSize();
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts1($part1, $part2);
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts2($part1, $part2);
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array $parts The parts to be mixed
*
* @return string The mixed result
*/
public function mix(array $parts)
{
if (empty($parts)) {
return '';
}
$len = Util::safeStrlen($parts[0]);
$parts = $this->normalizeParts($parts);
$stringSize = count($parts[0]);
$partsSize = count($parts);
$result = '';
$offset = 0;
for ($i = 0; $i < $stringSize; $i++) {
$stub = $parts[$offset][$i];
for ($j = 1; $j < $partsSize; $j++) {
$newKey = $parts[($j + $offset) % $partsSize][$i];
//Alternately mix the output for each source
if ($j % 2 == 1) {
$stub ^= $this->mixParts1($stub, $newKey);
} else {
$stub ^= $this->mixParts2($stub, $newKey);
}
}
$result .= $stub;
$offset = ($offset + 1) % $partsSize;
}
return Util::safeSubstr($result, 0, $len);
}
/**
* Normalize the part array and split it block part size.
*
* This will make all parts the same length and a multiple
* of the part size
*
* @param array $parts The parts to normalize
*
* @return array The normalized and split parts
*/
protected function normalizeParts(array $parts)
{
$blockSize = $this->getPartSize();
$callback = function ($value) {
return Util::safeStrlen($value);
};
$maxSize = max(array_map($callback, $parts));
if ($maxSize % $blockSize != 0) {
$maxSize += $blockSize - ($maxSize % $blockSize);
}
foreach ($parts as &$part) {
$part = $this->str_pad($part, $maxSize, chr(0));
$part = str_split($part, $blockSize);
}
return $parts;
}
private function str_pad($string, $size, $character)
{
$start = Util::safeStrlen($string);
$inc = Util::safeStrlen($character);
for ($i = $start; $i < $size; $i+= $inc) {
$string = $string . $character;
}
return Util::safeSubstr($string, 0, $size);
}
private function str_split($string, $size)
{
$blocks = array();
$length = Util::safeStrlen($string);
$parts = ceil($length / $size);
for ($i = 0; $i < $parts; $i++) {
$blocks[] = Util::safeSubstr($string, $i * $length, $length);
}
return $blocks;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* An abstract mixer to implement a common mixing strategy
*
* @category PHPSecurityLib
* @package Random
*/
abstract class AbstractSource implements \RandomLib\Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Returns a string of zeroes, useful when no entropy is available.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
protected static function emptyValue($size)
{
return str_repeat(chr(0), $size);
}
}

View File

@@ -0,0 +1,273 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Factory extends \SecurityLib\AbstractFactory
{
/**
* @var array A list of available random number mixing strategies
*/
protected $mixers = array();
/**
* @var array A list of available random number sources
*/
protected $sources = array();
/**
* Build a new instance of the factory, loading core mixers and sources
*
* @return void
*/
public function __construct()
{
$this->loadMixers();
$this->loadSources();
}
/**
* Get a generator for the requested strength
*
* @param Strength $strength The requested strength of the random number
*
* @throws RuntimeException If an appropriate mixing strategy isn't found
*
* @return Generator The instantiated generator
*/
public function getGenerator(\SecurityLib\Strength $strength)
{
$sources = $this->findSources($strength);
$mixer = $this->findMixer($strength);
return new Generator($sources, $mixer);
}
/**
* Get a high strength random number generator
*
* High Strength keys should ONLY be used for generating extremely strong
* cryptographic keys. Generating them is very resource intensive and may
* take several minutes or more depending on the requested size.
*
* @return Generator The instantiated generator
*/
public function getHighStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::HIGH));
}
/**
* Get a low strength random number generator
*
* Low Strength should be used anywhere that random strings are needed in a
* non-cryptographical setting. They are not strong enough to be used as
* keys or salts. They are however useful for one-time use tokens.
*
* @return Generator The instantiated generator
*/
public function getLowStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::LOW));
}
/**
* Get a medium strength random number generator
*
* Medium Strength should be used for most needs of a cryptographic nature.
* They are strong enough to be used as keys and salts. However, they do
* take some time and resources to generate, so they should not be over-used
*
* @return Generator The instantiated generator
*/
public function getMediumStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::MEDIUM));
}
/**
* Get all loaded mixing strategies
*
* @return array An array of mixers
*/
public function getMixers()
{
return $this->mixers;
}
/**
* Get all loaded random number sources
*
* @return array An array of sources
*/
public function getSources()
{
return $this->sources;
}
/**
* Register a mixing strategy for this factory instance
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerMixer($name, $class)
{
$this->registerType(
'mixers',
__NAMESPACE__ . '\\Mixer',
$name,
$class
);
return $this;
}
/**
* Register a random number source for this factory instance
*
* Note that this class must implement the Source interface
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerSource($name, $class)
{
$this->registerType(
'sources',
__NAMESPACE__ . '\\Source',
$name,
$class
);
return $this;
}
/**
* Find a sources based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws RuntimeException if a valid source cannot be found
*
* @return Source The found source
*/
protected function findSources(\SecurityLib\Strength $strength)
{
$sources = array();
foreach ($this->getSources() as $source) {
if ($strength->compare($source::getStrength()) <= 0 && $source::isSupported()) {
$sources[] = new $source();
}
}
if (0 === count($sources)) {
throw new \RuntimeException('Could not find sources');
}
return $sources;
}
/**
* Find a mixer based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws RuntimeException if a valid mixer cannot be found
*
* @return Mixer The found mixer
*/
protected function findMixer(\SecurityLib\Strength $strength)
{
$newMixer = null;
$fallback = null;
foreach ($this->getMixers() as $mixer) {
if (!$mixer::test()) {
continue;
}
if ($strength->compare($mixer::getStrength()) == 0) {
$newMixer = new $mixer();
} elseif ($strength->compare($mixer::getStrength()) == 1) {
$fallback = new $mixer();
}
}
if (is_null($newMixer)) {
if (is_null($fallback)) {
throw new \RuntimeException('Could not find mixer');
}
return $fallback;
}
return $newMixer;
}
/**
* Load all core mixing strategies
*
* @return void
*/
protected function loadMixers()
{
$this->loadFiles(
__DIR__ . '/Mixer',
__NAMESPACE__ . '\\Mixer\\',
array($this, 'registerMixer')
);
}
/**
* Load all core random number sources
*
* @return void
*/
protected function loadSources()
{
$this->loadFiles(
__DIR__ . '/Source',
__NAMESPACE__ . '\\Source\\',
array($this, 'registerSource')
);
}
}

View File

@@ -0,0 +1,369 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Timo Hamina
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Timo Hamina
*/
class Generator
{
/**
* @const Flag for uppercase letters
*/
const CHAR_UPPER = 1;
/**
* @const Flag for lowercase letters
*/
const CHAR_LOWER = 2;
/**
* @const Flag for alpha characters (combines UPPER + LOWER)
*/
const CHAR_ALPHA = 3; // CHAR_UPPER | CHAR_LOWER
/**
* @const Flag for digits
*/
const CHAR_DIGITS = 4;
/**
* @const Flag for alpha numeric characters
*/
const CHAR_ALNUM = 7; // CHAR_ALPHA | CHAR_DIGITS
/**
* @const Flag for uppercase hexadecimal symbols
*/
const CHAR_UPPER_HEX = 12; // 8 | CHAR_DIGITS
/**
* @const Flag for lowercase hexidecimal symbols
*/
const CHAR_LOWER_HEX = 20; // 16 | CHAR_DIGITS
/**
* @const Flag for base64 symbols
*/
const CHAR_BASE64 = 39; // 32 | CHAR_ALNUM
/**
* @const Flag for additional symbols accessible via the keyboard
*/
const CHAR_SYMBOLS = 64;
/**
* @const Flag for brackets
*/
const CHAR_BRACKETS = 128;
/**
* @const Flag for punctuation marks
*/
const CHAR_PUNCT = 256;
/**
* @const Flag for upper/lower-case and digits but without "B8G6I1l|0OQDS5Z2"
*/
const EASY_TO_READ = 512;
/**
* @var Mixer The mixing strategy to use for this generator instance
*/
protected $mixer = null;
/**
* @var array An array of random number sources to use for this generator
*/
protected $sources = array();
/**
* @var array The different characters, by Flag
*/
protected $charArrays = array(
self::CHAR_UPPER => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
self::CHAR_LOWER => 'abcdefghijklmnopqrstuvwxyz',
self::CHAR_DIGITS => '0123456789',
self::CHAR_UPPER_HEX => 'ABCDEF',
self::CHAR_LOWER_HEX => 'abcdef',
self::CHAR_BASE64 => '+/',
self::CHAR_SYMBOLS => '!"#$%&\'()* +,-./:;<=>?@[\]^_`{|}~',
self::CHAR_BRACKETS => '()[]{}<>',
self::CHAR_PUNCT => ',.;:',
);
/**
* @internal
* @private
* @const string Ambiguous characters for "Easy To Read" sets
*/
const AMBIGUOUS_CHARS = 'B8G6I1l|0OQDS5Z2()[]{}:;,.';
/**
* Build a new instance of the generator
*
* @param array $sources An array of random data sources to use
* @param Mixer $mixer The mixing strategy to use for this generator
*/
public function __construct(array $sources, Mixer $mixer)
{
foreach ($sources as $source) {
$this->addSource($source);
}
$this->mixer = $mixer;
}
/**
* Add a random number source to the generator
*
* @param Source $source The random number source to add
*
* @return Generator $this The current generator instance
*/
public function addSource(Source $source)
{
$this->sources[] = $source;
return $this;
}
/**
* Generate a random number (string) of the requested size
*
* @param int $size The size of the requested random number
*
* @return string The generated random number (string)
*/
public function generate($size)
{
$seeds = array();
foreach ($this->sources as $source) {
$seeds[] = $source->generate($size);
}
return $this->mixer->mix($seeds);
}
/**
* Generate a random integer with the given range
*
* @param int $min The lower bound of the range to generate
* @param int $max The upper bound of the range to generate
*
* @return int The generated random number within the range
*/
public function generateInt($min = 0, $max = PHP_INT_MAX)
{
$tmp = (int) max($max, $min);
$min = (int) min($max, $min);
$max = $tmp;
$range = $max - $min;
if ($range == 0) {
return $max;
} elseif ($range > PHP_INT_MAX || is_float($range) || $range < 0) {
/**
* This works, because PHP will auto-convert it to a float at this point,
* But on 64 bit systems, the float won't have enough precision to
* actually store the difference, so we need to check if it's a float
* and hence auto-converted...
*/
throw new \RangeException(
'The supplied range is too great to generate'
);
}
$bits = $this->countBits($range) + 1;
$bytes = (int) max(ceil($bits / 8), 1);
if ($bits == 63) {
/**
* Fixes issue #22
*
* @see https://github.com/ircmaxell/RandomLib/issues/22
*/
$mask = 0x7fffffffffffffff;
} else {
$mask = (int) (pow(2, $bits) - 1);
}
/**
* The mask is a better way of dropping unused bits. Basically what it does
* is to set all the bits in the mask to 1 that we may need. Since the max
* range is PHP_INT_MAX, we will never need negative numbers (which would
* have the MSB set on the max int possible to generate). Therefore we
* can just mask that away. Since pow returns a float, we need to cast
* it back to an int so the mask will work.
*
* On a 64 bit platform, that means that PHP_INT_MAX is 2^63 - 1. Which
* is also the mask if 63 bits are needed (by the log(range, 2) call).
* So if the computed result is negative (meaning the 64th bit is set), the
* mask will correct that.
*
* This turns out to be slightly better than the shift as we don't need to
* worry about "fixing" negative values.
*/
do {
$test = $this->generate($bytes);
$result = hexdec(bin2hex($test)) & $mask;
} while ($result > $range);
return $result + $min;
}
/**
* Generate a random string of specified length.
*
* This uses the supplied character list for generating the new result
* string.
*
* @param int $length The length of the generated string
* @param mixed $characters String: An optional list of characters to use
* Integer: Character flags
*
* @return string The generated random string
*/
public function generateString($length, $characters = '')
{
if (is_int($characters)) {
// Combine character sets
$characters = $this->expandCharacterSets($characters);
}
if ($length == 0 || strlen($characters) == 1) {
return '';
} elseif (empty($characters)) {
// Default to base 64
$characters = $this->expandCharacterSets(self::CHAR_BASE64);
}
// determine how many bytes to generate
// This is basically doing floor(log(strlen($characters)))
// But it's fixed to work properly for all numbers
$len = strlen($characters);
// The max call here fixes an issue where we under-generate in cases
// where less than 8 bits are needed to represent $len
$bytes = $length * ceil(($this->countBits($len)) / 8);
// determine mask for valid characters
$mask = 256 - (256 % $len);
$result = '';
do {
$rand = $this->generate($bytes);
for ($i = 0; $i < $bytes; $i++) {
if (ord($rand[$i]) >= $mask) {
continue;
}
$result .= $characters[ord($rand[$i]) % $len];
}
} while (strlen($result) < $length);
// We may over-generate, since we always use the entire buffer
return substr($result, 0, $length);
}
/**
* Get the Mixer used for this instance
*
* @return Mixer the current mixer
*/
public function getMixer()
{
return $this->mixer;
}
/**
* Get the Sources used for this instance
*
* @return Source[] the current mixer
*/
public function getSources()
{
return $this->sources;
}
/**
* Count the minimum number of bits to represent the provided number
*
* This is basically floor(log($number, 2))
* But avoids float precision issues
*
* @param int $number The number to count
*
* @return int The number of bits
*/
protected function countBits($number)
{
$log2 = 0;
while ($number >>= 1) {
$log2++;
}
return $log2;
}
/**
* Expand a character set bitwise spec into a string character set
*
* This will also replace EASY_TO_READ characters if the flag is set
*
* @param int $spec The spec to expand (bitwise combination of flags)
*
* @return string The expanded string
*/
protected function expandCharacterSets($spec)
{
$combined = '';
if ($spec == self::EASY_TO_READ) {
$spec |= self::CHAR_ALNUM;
}
foreach ($this->charArrays as $flag => $chars) {
if ($flag == self::EASY_TO_READ) {
// handle this later
continue;
}
if (($spec & $flag) === $flag) {
$combined .= $chars;
}
}
if ($spec & self::EASY_TO_READ) {
// remove ambiguous characters
$combined = str_replace(str_split(self::AMBIGUOUS_CHARS), '', $combined);
}
return count_chars($combined, 3);
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
interface Mixer
{
/**
* Return an instance of Strength indicating the strength of the mixer
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test();
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array $parts The parts to be mixed
*
* @return string The mixed result
*/
public function mix(array $parts);
}

View File

@@ -0,0 +1,126 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Hash extends \RandomLib\AbstractMixer
{
/**
* @var string The hash instance to use
*/
protected $hash = null;
/**
* Build the hash mixer
*
* @param string $hash The hash instance to use (defaults to sha512)
*
* @return void
*/
public function __construct($hash = 'sha512')
{
$this->hash = $hash;
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return Util::safeStrlen(hash($this->hash, '', true));
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return hash_hmac($this->hash, $part1, $part2, true);
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
return hash_hmac($this->hash, $part2, $part1, true);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use RandomLib\AbstractMcryptMixer;
use SecurityLib\Strength;
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
class McryptRijndael128 extends AbstractMcryptMixer
{
/**
* {@inheritdoc}
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* {@inheritdoc}
*/
protected function getCipher()
{
return 'rijndael-128';
}
}

View File

@@ -0,0 +1,109 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class XorMixer extends \RandomLib\AbstractMixer
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return 64;
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return $part1 ^ $part2;
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
// Both mixers are identical, this is for speed, not security
return $part1 ^ $part2;
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
interface Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported();
/**
* Generate a random string of the specified size
*
* Note: If the source fails to generate enough data, the result must be
* padded to the requested length.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size);
}

View File

@@ -0,0 +1,89 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class CAPICOM extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\COM', false);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
try {
$util = new \COM('CAPICOM.Utilities.1');
$data = base64_decode($util->GetRandom($size, 0));
return str_pad($data, $size, chr(0));
} catch (\Exception $e) {
unset($e);
return static::emptyValue($size);
}
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class MTRand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::MEDIUM);
} else {
return new Strength(Strength::LOW);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((mt_rand() ^ mt_rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,136 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
final class MicroTime extends \RandomLib\AbstractSource
{
/**
* A static counter to ensure unique hashes and prevent state collisions
*
* @var int A counter
*/
private static $counter = null;
/**
* The current state of the random number generator.
*
* @var string The state of the PRNG
*/
private static $state = '';
public function __construct()
{
$state = self::$state;
if (function_exists('posix_times')) {
$state .= serialize(posix_times());
}
if (!defined('HHVM_VERSION') && function_exists('zend_thread_id')) {
$state .= zend_thread_id();
}
if (function_exists('hphp_get_thread_id')) {
$state .= hphp_get_thread_id();
}
$state .= getmypid() . memory_get_usage();
$state .= serialize($_ENV);
$state .= serialize($_SERVER);
$state .= count(debug_backtrace(false));
self::$state = hash('sha512', $state, true);
if (is_null(self::$counter)) {
list(, self::$counter) = unpack("i", Util::safeSubstr(self::$state, 0, 4));
$seed = $this->generate(Util::safeStrlen(dechex(PHP_INT_MAX)));
list(, self::$counter) = unpack("i", $seed);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
$seed = microtime() . memory_get_usage();
self::$state = hash('sha512', self::$state . $seed, true);
/**
* Make the generated randomness a bit better by forcing a GC run which
* should complete in a indeterminate amount of time, hence improving
* the strength of the randomness a bit. It's still not crypto-safe,
* but at least it's more difficult to predict.
*/
gc_collect_cycles();
for ($i = 0; $i < $size; $i += 8) {
$seed = self::$state .
microtime() .
pack('Ni', $i, self::counter());
self::$state = hash('sha512', $seed, true);
/**
* We only use the first 8 bytes here to prevent exposing the state
* in its entirety, which could potentially expose other random
* generations in the future (in the same process)...
*/
$result .= Util::safeSubstr(self::$state, 0, 8);
}
return Util::safeSubstr($result, 0, $size);
}
private static function counter()
{
if (self::$counter >= PHP_INT_MAX) {
self::$counter = -1 * PHP_INT_MAX - 1;
} else {
self::$counter++;
}
return self::$counter;
}
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class OpenSSL extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
/**
* Prior to PHP 5.6.12 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.6.12
*/
if (PHP_VERSION_ID >= 50612) {
return new Strength(Strength::HIGH);
}
/**
* Prior to PHP 5.5.28 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.5.28
*/
if (PHP_VERSION_ID >= 50528 && PHP_VERSION_ID < 50600) {
return new Strength(Strength::HIGH);
}
/**
* Prior to PHP 5.4.44 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.4.44
*/
if (PHP_VERSION_ID >= 50444 && PHP_VERSION_ID < 50500) {
return new Strength(Strength::HIGH);
}
return new Strength(Strength::MEDIUM);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return function_exists('openssl_random_pseudo_bytes');
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if ($size < 1) {
return str_repeat(chr(0), $size);
}
/**
* Note, normally we would check the return of of $crypto_strong to
* ensure that we generated a good random string. However, since we're
* using this as one part of many sources a low strength random number
* shouldn't be much of an issue.
*/
return openssl_random_pseudo_bytes($size);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class Rand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((rand() ^ rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Random Number Source
*
* This uses the *nix /dev/random device to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Random Random Number Source
*
* This uses the *nix /dev/random device to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class Random extends URandom
{
/**
* @var string The file to read from
*/
protected static $file = '/dev/random';
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The PHP7 Random Number Source
*
* This uses the inbuilt PHP7 Random Bytes function
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The PHP7 Random Number Source
*
* This uses the php7 secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class RandomBytes extends \RandomLib\AbstractSource
{
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return function_exists('random_bytes');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if (!self::isSupported()) {
return str_repeat(chr(0), $size);
}
return \random_bytes($size);
}
}

View File

@@ -0,0 +1,109 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*
* @link https://paragonie.com/book/pecl-libsodium
* @link http://pecl.php.net/package/libsodium
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
*/
class Sodium extends \RandomLib\AbstractSource
{
/**
* A property that may be forcibly set to `false` in the constructor, for
* the purpose of testing this source
*
* @var bool
*/
private $hasLibsodium = false;
/**
* Constructs a libsodium Random Number Source
*
* @param bool $useLibsodium May be set to `false` to disable libsodium for
* testing purposes
*/
public function __construct($useLibsodium = true)
{
if ($useLibsodium && extension_loaded('libsodium')) {
$this->hasLibsodium = true;
}
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return function_exists('Sodium\\randombytes_buf');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if (!$this->hasLibsodium || $size < 1) {
return str_repeat(chr(0), $size);
}
return \Sodium\randombytes_buf($size);
}
}

View File

@@ -0,0 +1,98 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class URandom extends \RandomLib\AbstractSource
{
/**
* @var string The file to read from
*/
protected static $file = '/dev/urandom';
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return @file_exists(static::$file);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if ($size == 0) {
return static::emptyValue($size);
}
$file = fopen(static::$file, 'rb');
if (!$file) {
return static::emptyValue($size);
}
if (function_exists('stream_set_read_buffer')) {
stream_set_read_buffer($file, 0);
}
$result = fread($file, $size);
fclose($file);
return $result;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class UniqID extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::LOW);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
while (Util::safeStrlen($result) < $size) {
$result = uniqid($result, true);
}
return Util::safeSubstr($result, 0, $size);
}
}

19
vendor/ircmaxell/security-lib/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2011 The Authors
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.

55
vendor/ircmaxell/security-lib/composer.lock generated vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "098e204bfe65a46e1866261c43a5ae88",
"packages": [
],
"packages-dev": [
{
"name": "mikey179/vfsStream",
"version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/mikey179/vfsStream",
"reference": "v1.1.0"
},
"dist": {
"type": "zip",
"url": "https://github.com/mikey179/vfsStream/zipball/v1.1.0",
"reference": "v1.1.0",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"org\\bovigo\\vfs": "src/main/php"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD"
],
"homepage": "http://vfs.bovigo.org/",
"time": "2012-08-25 05:49:29"
}
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": [
],
"platform": {
"php": ">=5.3.2"
},
"platform-dev": [
]
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* The base abstract factory used by all PasswordLib factories
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* The base abstract factory used by all PasswordLib factories
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
abstract class AbstractFactory {
/**
* Register a type with the factory by name
*
* This is an internal method to check if a provided class name implements
* an interface, and if it does to append that class to an internal array
* by name.
*
* @param string $type The name of the variable to store the class
* @param string $implements The interface to validate against
* @param string $name The name of this particular class
* @param string $class The fully qualified class name
* @param boolean $instantiate Should the class be stored instantiated
*
* @return void
* @throws InvalidArgumentException If class does not implement interface
*/
protected function registerType(
$type,
$implements,
$name,
$class,
$instantiate = false
) {
$name = strtolower($name);
$refl = new \ReflectionClass($class);
if (!$refl->implementsInterface($implements)) {
$message = sprintf('Class must implement %s', $implements);
throw new \InvalidArgumentException($message);
}
if ($instantiate) {
$class = new $class;
}
$this->{$type}[$name] = $class;
}
/**
* Load a set of classes from a directory into the factory
*
* @param string $directory The directory to search for classes in
* @param string $namespace The namespace prefix for any found classes
* @param string $callback The callback with which to register the class
*
* @return void
*/
protected function loadFiles($directory, $namespace, $callback) {
foreach (new \DirectoryIterator($directory) as $file) {
$filename = $file->getBasename();
if ($file->isFile() && substr($filename, -4) == '.php') {
$name = substr($filename, 0, -4);
$class = $namespace . $name;
call_user_func($callback, $name, $class);
}
}
}
}

View File

@@ -0,0 +1,114 @@
<?php
/**
* A Utility class for converting between raw binary strings and a given
* list of characters
*
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* A Utility class for converting between raw binary strings and a given
* list of characters
*
* @category PHPSecurityLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class BaseConverter {
/**
* Convert from a raw binary string to a string of characters
*
* @param string $string The string to convert from
* @param string $characters The list of characters to convert to
*
* @return string The converted string
*/
public static function convertFromBinary($string, $characters) {
if ($string === '' || empty($characters)) {
return '';
}
$string = str_split($string);
$callback = function($str) {
return ord($str);
};
$string = array_map($callback, $string);
$converted = static::baseConvert($string, 256, strlen($characters));
$callback = function ($num) use ($characters) {
return $characters[$num];
};
$ret = implode('', array_map($callback, $converted));
return $ret;
}
/**
* Convert to a raw binary string from a string of characters
*
* @param string $string The string to convert from
* @param string $characters The list of characters to convert to
*
* @return string The converted string
*/
public static function convertToBinary($string, $characters) {
if (empty($string) || empty($characters)) {
return '';
}
$string = str_split($string);
$callback = function($str) use ($characters) {
return strpos($characters, $str);
};
$string = array_map($callback, $string);
$converted = static::baseConvert($string, strlen($characters), 256);
$callback = function ($num) {
return chr($num);
};
return implode('', array_map($callback, $converted));
}
/**
* Convert an array of input blocks to another numeric base
*
* This function was modified from an implementation found on StackOverflow.
* Special Thanks to @KeithRandall for supplying the implementation.
*
* @param int[] $source The source number, as an array
* @param int $srcBase The source base as an integer
* @param int $dstBase The destination base as an integer
*
* @see http://codegolf.stackexchange.com/questions/1620/arb/1626#1626
* @return int[] An array of integers in the encoded base
*/
public static function baseConvert(array $source, $srcBase, $dstBase) {
if ($dstBase < 2) {
$message = sprintf('Invalid Destination Base: %d', $dstBase);
throw new \InvalidArgumentException($message);
}
$result = array();
$count = count($source);
while ($count) {
$itMax = $count;
$remainder = $count = $loop = 0;
while($loop < $itMax) {
$dividend = $source[$loop++] + $remainder * $srcBase;
$remainder = $dividend % $dstBase;
$res = ($dividend - $remainder) / $dstBase;
if ($count || $res) {
$source[$count++] = $res;
}
}
$result[] = $remainder;
}
return array_reverse($result);
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* A class for arbitrary precision math functions
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* A class for arbitrary precision math functions
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
abstract class BigMath {
/**
* Get an instance of the big math class
*
* This is NOT a singleton. It simply loads the proper strategy
* given the current server configuration
*
* @return \PasswordLib\Core\BigMath A big math instance
*/
public static function createFromServerConfiguration() {
//@codeCoverageIgnoreStart
if (extension_loaded('gmp')) {
return new \SecurityLib\BigMath\GMP();
} elseif (extension_loaded('bcmath')) {
return new \SecurityLib\BigMath\BCMath();
} else {
return new \SecurityLib\BigMath\PHPMath();
}
//@codeCoverageIgnoreEnd
}
/**
* Add two numbers together
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the sum of the two arguments
*/
abstract public function add($left, $right);
/**
* Subtract two numbers
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the difference of the two arguments
*/
abstract public function subtract($left, $right);
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* A class for arbitrary precision math functions implemented using bcmath
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib\BigMath;
/**
* A class for arbitrary precision math functions implemented using bcmath
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
*/
class BCMath extends \SecurityLib\BigMath {
/**
* Add two numbers together
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the sum of the two arguments
*/
public function add($left, $right) {
return bcadd($left, $right, 0);
}
/**
* Subtract two numbers
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the difference of the two arguments
*/
public function subtract($left, $right) {
return bcsub($left, $right);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* A class for arbitrary precision math functions implemented using GMP
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib\BigMath;
/**
* A class for arbitrary precision math functions implemented using GMP
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
*/
class GMP extends \SecurityLib\BigMath {
/**
* Add two numbers together
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the sum of the two arguments
*/
public function add($left, $right) {
return gmp_strval(gmp_add($left, $right));
}
/**
* Subtract two numbers
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the difference of the two arguments
*/
public function subtract($left, $right) {
return gmp_strval(gmp_sub($left, $right));
}
}

View File

@@ -0,0 +1,170 @@
<?php
/**
* A class for arbitrary precision math functions implemented in PHP
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib\BigMath;
use SecurityLib\BaseConverter;
/**
* A class for arbitrary precision math functions implemented in PHP
*
* @category PHPPasswordLib
* @package Core
* @subpackage BigMath
*/
class PHPMath extends \SecurityLib\BigMath {
/**
* Add two numbers together
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the sum of the two arguments
*/
public function add($left, $right) {
if (empty($left)) {
return $right;
} elseif (empty($right)) {
return $left;
}
$negative = '';
if ($left[0] == '-' && $right[0] == '-') {
$negative = '-';
$left = substr($left, 1);
$right = substr($right, 1);
} elseif ($left[0] == '-') {
return $this->subtract($right, substr($left, 1));
} elseif ($right[0] == '-') {
return $this->subtract($left, substr($right, 1));
}
$left = $this->normalize($left);
$right = $this->normalize($right);
$result = BaseConverter::convertFromBinary(
$this->addBinary($left, $right),
'0123456789'
);
return $negative . $result;
}
/**
* Subtract two numbers
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return A base-10 string of the difference of the two arguments
*/
public function subtract($left, $right) {
if (empty($left)) {
return $right;
} elseif (empty($right)) {
return $left;
} elseif ($right[0] == '-') {
return $this->add($left, substr($right, 1));
} elseif ($left[0] == '-') {
return '-' . $this->add(ltrim($left, '-'), $right);
}
$left = $this->normalize($left);
$right = $this->normalize($right);
$results = $this->subtractBinary($left, $right);
$result = BaseConverter::convertFromBinary($results[1], '0123456789');
return $results[0] . $result;
}
/**
* Add two binary strings together
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return string The binary result
*/
protected function addBinary($left, $right) {
$len = max(strlen($left), strlen($right));
$left = str_pad($left, $len, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $len, chr(0), STR_PAD_LEFT);
$result = '';
$carry = 0;
for ($i = 0; $i < $len; $i++) {
$sum = ord($left[$len - $i - 1])
+ ord($right[$len - $i - 1])
+ $carry;
$result .= chr($sum % 256);
$carry = $sum >> 8;
}
while ($carry) {
$result .= chr($carry % 256);
$carry >>= 8;
}
return strrev($result);
}
/**
* Subtract two binary strings using 256's compliment
*
* @param string $left The left argument
* @param string $right The right argument
*
* @return string The binary result
*/
protected function subtractBinary($left, $right) {
$len = max(strlen($left), strlen($right));
$left = str_pad($left, $len, chr(0), STR_PAD_LEFT);
$right = str_pad($right, $len, chr(0), STR_PAD_LEFT);
$right = $this->compliment($right);
$result = $this->addBinary($left, $right);
if (strlen($result) > $len) {
// Positive Result
$carry = substr($result, 0, -1 * $len);
$result = substr($result, strlen($carry));
return array(
'',
$this->addBinary($result, $carry)
);
}
return array('-', $this->compliment($result));
}
/**
* Take the 256 base compliment
*
* @param string $string The binary string to compliment
*
* @return string The complimented string
*/
protected function compliment($string) {
$result = '';
$len = strlen($string);
for ($i = 0; $i < $len; $i++) {
$result .= chr(255 - ord($string[$i]));
}
return $result;
}
/**
* Transform a string number into a binary string using base autodetection
*
* @param string $string The string to transform
*
* @return string The binary transformed number
*/
protected function normalize($string) {
return BaseConverter::convertToBinary(
$string,
'0123456789'
);
}
}

View File

@@ -0,0 +1,117 @@
<?php
/**
* The Enum base class for Enum functionality
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
use \ReflectionObject;
/**
* The Enum base class for Enum functionality
*
* This is based off of the SplEnum class implementation (which is only available
* as a PECL extension in 5.3)
*
* @see http://www.php.net/manual/en/class.splenum.php
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
abstract class Enum {
/**
* A default value of null is provided. Override this to set your own default
*/
const __DEFAULT = null;
/**
* @var string The name of the constant this instance is using
*/
protected $name = '';
/**
* @var scalar The value of the constant this instance is using.
*/
protected $value = '';
/**
* Creates a new value of the Enum type
*
* @param mixed $value The value this instance represents
* @param boolean $strict Not Implemented at this time
*
* @return void
* @throws UnexpectedValueException If the value is not a constant
*/
public function __construct($value = null, $strict = false) {
if (is_null($value)) {
$value = static::__DEFAULT;
}
$validValues = $this->getConstList();
$this->name = array_search($value, $validValues);
if (!$this->name) {
throw new \UnexpectedValueException(
'Value not a const in enum ' . get_class($this)
);
}
$this->value = $value;
}
/**
* Cast the current object to a string and return its value
*
* @return mixed the current value of the instance
*/
public function __toString() {
return (string) $this->value;
}
/**
* Compare two enums using numeric comparison
*
* @param Enum $arg The enum to compare this instance to
*
* @return int 0 if same, 1 if the argument is greater, -1 else
*/
public function compare(Enum $arg) {
if ($this->value == $arg->value) {
return 0;
} elseif ($this->value > $arg->value) {
return -1;
} else {
return 1;
}
}
/**
* Returns all constants (including values) as an associative array
*
* @param boolean $include_default Include the __default magic value?
*
* @return array All of the constants found against this instance
*/
public function getConstList($include_default = false) {
static $constCache = array();
$class = get_class($this);
if (!isset($constCache[$class])) {
$reflector = new ReflectionObject($this);
$constCache[$class] = $reflector->getConstants();
}
if (!$include_default) {
$constants = $constCache[$class];
unset($constants['__DEFAULT']);
return $constants;
}
return $constCache[$class];
}
}

View File

@@ -0,0 +1,360 @@
<?php
/**
* A hash utility data mapper class
*
* This class's purpose is to store information about hash algorithms that is
* otherwise unavailable during runtime. Some information is available (such
* as the output size), but is included anyway for performance and completeness
* reasons.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Hash
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* A hash utility data mapper class
*
* This class's purpose is to store information about hash algorithms that is
* otherwise unavailable during runtime. Some information is available (such
* as the output size), but is included anyway for performance and completeness
* reasons.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Hash
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Hash {
/**
* This array contains information about each hash function available to PHP
* at the present time. Block sizes are not available from functions, so they
* must be hard coded.
*
* The "secure" indicates the strength of the hash and whether or not any known
* cryptographic attacks exist for the hash function. This will only apply when
* using the hash functions for situations that require cryptographic strength
* such as message signing. For other uses the insecure ones can have valid
* uses.
*
* @var array An array of information about each supported hash function
*/
protected static $hashInfo = array(
'md2' => array(
'HashSize' => 128,
'BlockSize' => 128,
'secure' => false,
),
'md4' => array(
'HashSize' => 128,
'BlockSize' => 512,
'secure' => false,
),
'md5' => array(
'HashSize' => 128,
'BlockSize' => 512,
'secure' => false,
),
'sha1' => array(
'HashSize' => 160,
'BlockSize' => 512,
'secure' => false,
),
'sha224' => array(
'HashSize' => 224,
'BlockSize' => 512,
'secure' => true,
),
'sha256' => array(
'HashSize' => 256,
'BlockSize' => 512,
'secure' => true,
),
'sha384' => array(
'HashSize' => 384,
'BlockSize' => 1024,
'secure' => true,
),
'sha512' => array(
'HashSize' => 512,
'BlockSize' => 1024,
'secure' => true,
),
'ripemd128' => array(
'HashSize' => 128,
'BlockSize' => 512,
'secure' => true,
),
'ripemd160' => array(
'HashSize' => 160,
'BlockSize' => 512,
'secure' => true,
),
'ripemd256' => array(
'HashSize' => 256,
'BlockSize' => 512,
'secure' => true,
),
'ripemd320' => array(
'HashSize' => 320,
'BlockSize' => 512,
'secure' => true,
),
'whirlpool' => array(
'HashSize' => 512,
'BlockSize' => 512,
'secure' => true,
),
'tiger128,3' => array(
'HashSize' => 128,
'BlockSize' => 512,
'secure' => true,
),
'tiger160,3' => array(
'HashSize' => 160,
'BlockSize' => 512,
'secure' => true,
),
'tiger192,3' => array(
'HashSize' => 192,
'BlockSize' => 512,
'secure' => true,
),
'tiger128,4' => array(
'HashSize' => 128,
'BlockSize' => 512,
'secure' => true,
),
'tiger160,4' => array(
'HashSize' => 160,
'BlockSize' => 512,
'secure' => true,
),
'tiger192,4' => array(
'HashSize' => 192,
'BlockSize' => 512,
'secure' => true,
),
'snefru' => array(
'HashSize' => 256,
'BlockSize' => 512,
'secure' => false,
),
'snefru256' => array(
'HashSize' => 256,
'BlockSize' => 512,
'secure' => false,
),
'gost' => array(
'HashSize' => 256,
'BlockSize' => 256,
'secure' => false,
),
'adler32' => array(
'HashSize' => 32,
'BlockSize' => 16,
'secure' => false,
),
'crc32' => array(
'HashSize' => 32,
'BlockSize' => 32,
'secure' => false,
),
'crc32b' => array(
'HashSize' => 32,
'BlockSize' => 32,
'secure' => false,
),
'salsa10' => array(
'HashSize' => 512,
'BlockSize' => 512,
'secure' => true,
),
'salsa20' => array(
'HashSize' => 512,
'BlockSize' => 512,
'secure' => true,
),
'haval128,3' => array(
'HashSize' => 128,
'BlockSize' => 1024,
'secure' => false,
),
'haval160,3' => array(
'HashSize' => 160,
'BlockSize' => 1024,
'secure' => false,
),
'haval192,3' => array(
'HashSize' => 192,
'BlockSize' => 1024,
'secure' => false,
),
'haval224,3' => array(
'HashSize' => 224,
'BlockSize' => 1024,
'secure' => false,
),
'haval256,3' => array(
'HashSize' => 256,
'BlockSize' => 1024,
'secure' => false,
),
'haval128,4' => array(
'HashSize' => 128,
'BlockSize' => 1024,
'secure' => false,
),
'haval160,4' => array(
'HashSize' => 160,
'BlockSize' => 1024,
'secure' => false,
),
'haval192,4' => array(
'HashSize' => 192,
'BlockSize' => 1024,
'secure' => false,
),
'haval224,4' => array(
'HashSize' => 224,
'BlockSize' => 1024,
'secure' => false,
),
'haval256,4' => array(
'HashSize' => 256,
'BlockSize' => 1024,
'secure' => false,
),
'haval128,5' => array(
'HashSize' => 128,
'BlockSize' => 1024,
'secure' => false,
),
'haval160,5' => array(
'HashSize' => 160,
'BlockSize' => 1024,
'secure' => false,
),
'haval192,5' => array(
'HashSize' => 192,
'BlockSize' => 1024,
'secure' => false,
),
'haval224,5' => array(
'HashSize' => 224,
'BlockSize' => 1024,
'secure' => false,
),
'haval256,5' => array(
'HashSize' => 256,
'BlockSize' => 1024,
'secure' => false,
),
'joaat' => array(
'HashSize' => 32,
'BlockSize' => 64,
'secure' => false,
),
'fnv132' => array(
'HashSize' => 32,
'BlockSize' => 32,
'secure' => false,
),
'fnv164' => array(
'HashSize' => 64,
'BlockSize' => 64,
'secure' => false,
),
);
/**
* Get the block size of the specified function in bytes
*
* @param string $hash The hash function to look up
*
* @return int The number of bytes in the block function
*/
public static function getBlockSize($hash) {
return static::getBlockSizeInBits($hash) / 8;
}
/**
* Get the block size of the specified function in bits
*
* @param string $hash The hash function to look up
*
* @return int The number of bits in the block function
*/
public static function getBlockSizeInBits($hash) {
if (isset(static::$hashInfo[$hash]['BlockSize'])) {
return static::$hashInfo[$hash]['BlockSize'];
}
return 0;
}
/**
* Get the output size of the specified function in bytes
*
* @param string $hash The hash function to look up
*
* @return int The number of bytes outputted by the hash function
*/
public static function getHashSize($hash) {
return static::getHashSizeInBits($hash) / 8;
}
/**
* Get the output size of the specified function in bits
*
* @param string $hash The hash function to look up
*
* @return int The number of bits outputted by the hash function
*/
public static function getHashSizeInBits($hash) {
if (isset(static::$hashInfo[$hash]['HashSize'])) {
return static::$hashInfo[$hash]['HashSize'];
}
return 0;
}
/**
* Check to see if the hash function specified is available
*
* @param string $hash The hash function to look up
*
* @return boolean If the hash function is available in this version of PHP
*/
public static function isAvailable($hash) {
return in_array($hash, hash_algos());
}
/**
* Check to see if the specified hash function is secure enough for
* cryptographic uses
*
* The "secure" indicates the strength of the hash and whether or not any known
* cryptographic attacks exist for the hash function. This will only apply when
* using the hash functions for situations that require cryptographic strength
* such as message signing. For other uses the insecure ones can have valid
* uses.
*
* @param string $hash The hash function to look up
*
* @return bolean If the function is secure
*/
public static function isSecure($hash) {
if (isset(static::$hashInfo[$hash])) {
return static::$hashInfo[$hash]['secure'];
}
return false;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* The strength FlyweightEnum class
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* The strength FlyweightEnum class
*
* All mixing strategies must extend this class
*
* @category PHPPasswordLib
* @package Core
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Strength extends Enum {
/**
* We provide a default value of VeryLow so that we don't accidentally over
* state the strength if we forget to pass in a value...
*/
const __DEFAULT = self::VERYLOW;
/**
* This represents Non-Cryptographic strengths. It should not be used any time
* that security or confidentiality is at stake
*/
const VERYLOW = 1;
/**
* This represents the bottom line of Cryptographic strengths. It may be used
* for low security uses where some strength is required.
*/
const LOW = 3;
/**
* This is the general purpose Cryptographical strength. It should be suitable
* for all uses except the most sensitive.
*/
const MEDIUM = 5;
/**
* This is the highest strength available. It should not be used unless the
* high strength is needed, due to hardware constraints (and entropy
* limitations).
*/
const HIGH = 7;
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Hash
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace SecurityLib;
/**
* The Utility trait.
*
* Contains methods used internally to this library.
*
* @category PHPPasswordLib
* @package Random
* @author Scott Arciszewski <scott@arciszewski.me>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @codeCoverageIgnore
*/
abstract class Util {
/**
* Return the length of a string, even in the presence of
* mbstring.func_overload
*
* @param string $string the string we're measuring
* @return int
*/
public static function safeStrlen($string)
{
if (\function_exists('mb_strlen')) {
return \mb_strlen($string, '8bit');
}
return \strlen($string);
}
/**
* Return a string contained within a string, even in the presence of
* mbstring.func_overload
*
* @param string $string The string we're searching
* @param int $start What offset should we begin
* @param int|null $length How long should the substring be?
* (default: the remainder)
* @return string
*/
public static function safeSubstr($string, $start = 0, $length = null)
{
if (\function_exists('mb_substr')) {
return \mb_substr($string, $start, $length, '8bit');
} elseif ($length !== null) {
return \substr($string, $start, $length);
}
return \substr($string, $start);
}
}