X-Git-Url: https://git.stricted.de/?p=GitHub%2FStricted%2Fspeedport-hybrid-php-api.git;a=blobdiff_plain;f=CryptLib%2FRandom%2FFactory.php;fp=CryptLib%2FRandom%2FFactory.php;h=468624ab1c8dcc49144bf686183672b86bd7c272;hp=0000000000000000000000000000000000000000;hb=14d4f286d33b631a93207e4d13086c0a3bc0df12;hpb=c9e082da5cc662b64a74d3770f13d1270068678f diff --git a/CryptLib/Random/Factory.php b/CryptLib/Random/Factory.php new file mode 100644 index 0000000..468624a --- /dev/null +++ b/CryptLib/Random/Factory.php @@ -0,0 +1,221 @@ + + * @copyright 2011 The Authors + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version Build @@version@@ + */ + +namespace CryptLib\Random; + +use CryptLib\Core\Strength; + +/** + * The Random Factory + * + * Use this factory to instantiate random number generators, sources and mixers. + * + * @category PHPCryptLib + * @package Random + * @author Anthony Ferrara + */ +class Factory extends \CryptLib\Core\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 + * + * @return Generator The instantiated generator + * @throws RuntimeException If an appropriate mixing strategy isn't found + */ + public function getGenerator(\CryptLib\Core\Strength $strength) { + $sources = $this->getSources(); + $newSources = array(); + foreach ($sources as $source) { + if ($strength->compare($source::getStrength()) <= 0) { + $newSources[] = new $source; + } + } + $mixer = $this->findMixer($strength); + return new Generator($newSources, $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 mixer based upon the requested strength + * + * @param Strength $strength The strength mixer to find + * + * @return Mixer The found mixer + * @throws RuntimeException if a valid mixer cannot be found + */ + protected function findMixer(\CryptLib\Core\Strength $strength) { + $newMixer = null; + $fallback = null; + foreach ($this->getMixers() as $mixer) { + 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') + ); + } + +} +