From 83a7bbc168eb3951b1c1c2cc0f2954bf97dbd8b6 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Wed, 20 Jul 2011 16:35:44 -0400 Subject: [PATCH] Restructure bootstrap system, add optional autoloader --- build/phar.stub.php | 27 ++----- build/phing/package.xml | 16 ++-- examples/Password/drupal.php | 6 +- examples/Random/numbers.php | 6 +- examples/Random/strings.php | 8 +- lib/CryptLib/Cipher/Block/Cipher/X_OR.php | 80 -------------------- lib/CryptLib/Core/AutoLoader.php | 92 +++++++++++++++++++++++ lib/CryptLib/CryptLib.php | 8 +- lib/CryptLib/Random/Generator.php | 7 +- lib/CryptLib/Random/Mixer/X_OR.php | 78 ------------------- lib/CryptLib/bootstrap.php | 24 +----- test/Unit/Cipher/Block/Cipher/XORTest.php | 76 ------------------- test/Unit/Random/Mixer/X_ORTest.php | 49 ------------ test/bootstrap.php | 6 +- 14 files changed, 130 insertions(+), 353 deletions(-) delete mode 100644 lib/CryptLib/Cipher/Block/Cipher/X_OR.php create mode 100644 lib/CryptLib/Core/AutoLoader.php delete mode 100644 lib/CryptLib/Random/Mixer/X_OR.php delete mode 100644 test/Unit/Cipher/Block/Cipher/XORTest.php delete mode 100644 test/Unit/Random/Mixer/X_ORTest.php diff --git a/build/phar.stub.php b/build/phar.stub.php index 2b4f115..aa2c91f 100644 --- a/build/phar.stub.php +++ b/build/phar.stub.php @@ -18,30 +18,13 @@ namespace CryptLib; -if (defined('\\CryptLib\\BOOTSTRAPPED')) { - return; -} - -define('BOOTSTRAPPED', true); - \Phar::mapPhar('CryptLib.phar'); \Phar::interceptFileFuncs(); -/** - * The simple autoloader for the CryptLib library. - * - * @param string $class The class name to load - * - * @return void - */ -spl_autoload_register(function ($class) { - if (substr($class, 0, strlen(__NAMESPACE__)) == __NAMESPACE__) { - $path = str_replace('\\', '/', $class); - $path = 'phar://CryptLib.phar/' . $path . '.php'; - if (file_exists($path)) { - require $path; - } - } -}); +require_once 'phar://CryptLib.phar/CryptLib/Core/AutoLoader.php'; + +$autoloader = new \CryptLib\Core\AutoLoader(__NAMESPACE__, 'phar://CryptLib.phar'); + +$autoloader->register(); __HALT_COMPILER(); diff --git a/build/phing/package.xml b/build/phing/package.xml index c3841e5..ab66b25 100644 --- a/build/phing/package.xml +++ b/build/phing/package.xml @@ -1,7 +1,7 @@ - + @@ -18,11 +18,11 @@ - + - + @@ -34,7 +34,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -87,11 +87,11 @@ - + @@ -101,7 +101,7 @@ - + diff --git a/examples/Password/drupal.php b/examples/Password/drupal.php index 431a86d..302c35d 100644 --- a/examples/Password/drupal.php +++ b/examples/Password/drupal.php @@ -32,7 +32,7 @@ //It's safe to print, so let's output it: printf( - "Password: %s, Hash: %s\n", + "Password: %s\nHash: %s\n\n", $password, $hash ); @@ -48,12 +48,12 @@ /** * Next, we verify the hash with the expected password. */ -$test = $hasher2->verify($hash, $password); +$test = $hasher2->verify($password, $hash); /** * $test should now contain a boolean value as to the validity of the hash */ printf( - "Verification was %s", + "Verification was %s\n\n", $test ? "Successful!" : "Failed!" ); \ No newline at end of file diff --git a/examples/Random/numbers.php b/examples/Random/numbers.php index cdb94be..1a8383f 100644 --- a/examples/Random/numbers.php +++ b/examples/Random/numbers.php @@ -16,7 +16,7 @@ /** - * Let's generate some random integers! For this, we'll use the + * Let's generate some random integers! For this, we'll use the * CryptLib\Random\Factory class to build a random number generator to suit * our needs here. */ @@ -28,11 +28,11 @@ $factory = new \CryptLib\Random\Factory; /** - * Now, since we want a low strength random number, let's get a low strength + * Now, since we want a low strength random number, let's get a low strength * generator from the factory. * * If we wanted stronger random numbers, we could change this to medium or high - * but both use significantly more resources to generate, so let's just stick + * but both use significantly more resources to generate, so let's just stick * with low for the purposes of this example: */ $generator = $factory->getLowStrengthGenerator(); diff --git a/examples/Random/strings.php b/examples/Random/strings.php index 8d637f9..0a524aa 100644 --- a/examples/Random/strings.php +++ b/examples/Random/strings.php @@ -15,7 +15,7 @@ namespace CryptLibExamples\Random; /** - * Let's generate some random strings! For this, we'll use the + * Let's generate some random strings! For this, we'll use the * CryptLib\Random\Factory class to build a random number generator to suit * our needs here. */ @@ -27,11 +27,11 @@ $factory = new \CryptLib\Random\Factory; /** - * Now, since we want a low strength random number, let's get a low strength + * Now, since we want a low strength random number, let's get a low strength * generator from the factory. * * If we wanted stronger random numbers, we could change this to medium or high - * but both use significantly more resources to generate, so let's just stick + * but both use significantly more resources to generate, so let's just stick * with low for the purposes of this example: */ $generator = $factory->getLowStrengthGenerator(); @@ -56,7 +56,7 @@ * But, we can also generate random strings against a list of characters. That * way we can use the random string in user-facing situations: (this can be for * one-time-use passwords, CRSF tokens, etc). - * + * * Now, let's define a string of allowable characters to use for token * generation. */ diff --git a/lib/CryptLib/Cipher/Block/Cipher/X_OR.php b/lib/CryptLib/Cipher/Block/Cipher/X_OR.php deleted file mode 100644 index 4aa34eb..0000000 --- a/lib/CryptLib/Cipher/Block/Cipher/X_OR.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright 2011 The Authors - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version Build @@version@@ - */ - -namespace CryptLib\Cipher\Block\Cipher; - - - -/** - * An implementation of the trivial XOR cipher - * - * This is more of an example implementation and should not be used for anything - * requiring any level of security - * - * @category PHPCryptLib - * @package Cipher - * @subpackage Block - * @author Anthony Ferrara - */ -class X_OR extends \CryptLib\Cipher\Block\AbstractCipher { - - /** - * Get a list of supported ciphers for this class implementation - * - * @return array A list of supported ciphers - */ - public static function getSupportedCiphers() { - return array('xor'); - } - - public function setKey($key) { - $this->key = $key; - $this->keySize = strlen($key); - $this->blockSize = $this->keySize; - $this->initialized = $this->initialize(); - } - - /** - * Decrypt a block of data using the supplied string key - * - * Note that the supplied data should be the same size as the block size of - * the cipher being used. - * - * @param string $data The data to decrypt - * - * @return string The result decrypted data - */ - protected function decryptBlockData($data) { - return $data ^ $this->key; - } - - /** - * Encrypt a block of data using the supplied string key - * - * Note that the supplied data should be the same size as the block size of - * the cipher being used. - * - * @param string $data The data to encrypt - * - * @return string The result encrypted data - */ - protected function encryptBlockData($data) { - return $data ^ $this->key; - } - -} diff --git a/lib/CryptLib/Core/AutoLoader.php b/lib/CryptLib/Core/AutoLoader.php new file mode 100644 index 0000000..ddd769e --- /dev/null +++ b/lib/CryptLib/Core/AutoLoader.php @@ -0,0 +1,92 @@ + + * @copyright 2011 The Authors + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version Build @@version@@ + */ + +namespace CryptLib\Core; + +/** + * An implementation of the PSR-0 Autoloader. This can be replaced at will with + * other implementations if necessary. + * + * @category PHPCryptLib + * @package Core + * @author Anthony Ferrara + */ +class AutoLoader { + + /** + * @var string The namespace prefix for this instance. + */ + protected $namespace = ''; + + /** + * @var string The filesystem prefix to use for this instance + */ + protected $path = ''; + + /** + * Build the instance of the autoloader + * + * @param string $namespace The prefixed namespace this instance will load + * @param string $path The filesystem path to the root of the namespace + * + * @return void + */ + public function __construct($namespace, $path) { + $this->namespace = ltrim($namespace, '\\'); + $this->path = rtrim($path, '/\\') . DIRECTORY_SEPARATOR; + } + + /** + * Try to load a class + * + * @param string $class The class name to load + * + * @return boolean If the loading was successful + */ + public function load($class) { + $class = ltrim($class, '\\'); + if (strpos($class, $this->namespace) === 0) { + $nsparts = explode('\\', $class); + $class = array_pop($nsparts); + $nsparts[] = ''; + $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); + $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; + if (file_exists($path)) { + require $path; + return true; + } + } + return false; + } + + /** + * Register the autoloader to PHP + * + * @return boolean The status of the registration + */ + public function register() { + return spl_autoload_register(array($this, 'load')); + } + + /** + * Unregister the autoloader to PHP + * + * @return boolean The status of the unregistration + */ + public function unregister() { + return spl_autoload_unregister(array($this, 'load')); + } + +} \ No newline at end of file diff --git a/lib/CryptLib/CryptLib.php b/lib/CryptLib/CryptLib.php index dc9f3f9..44caae6 100644 --- a/lib/CryptLib/CryptLib.php +++ b/lib/CryptLib/CryptLib.php @@ -16,9 +16,13 @@ namespace CryptLib; /** - * Ensure that we're bootstrapped + * The autoloader class will be autoloaded at this point even if another autoloader + * is in use. So if it does not exist at this point, we know we must bootstrap + * the libraries. */ -require_once __DIR__ . '/bootstrap.php'; +if (!class_exists('\\CryptLib\Core\AutoLoader', true)) { + require_once 'bootstrap.php'; +} use CryptLib\Password\Factory as PasswordFactory; use CryptLib\Random\Factory as RandomFactory; diff --git a/lib/CryptLib/Random/Generator.php b/lib/CryptLib/Random/Generator.php index cdd48c1..2dff2cd 100644 --- a/lib/CryptLib/Random/Generator.php +++ b/lib/CryptLib/Random/Generator.php @@ -18,11 +18,6 @@ use CryptLib\Core\BaseConverter; -/** - * The number of bits in each byte. - */ -define('BITS_PER_BYTE', 8); - /** * The Random Number Generator Class * @@ -151,7 +146,7 @@ public function generateString($length, $characters = '') { 'ABCDEFGHIJKLMNOPQRSTUVWXYZ./'; } //determine how many bytes to generate - $bytes = ceil($length * log(strlen($characters), 2) / BITS_PER_BYTE); + $bytes = ceil($length * log(strlen($characters), 2) / 8); $rand = $this->generate($bytes); $result = BaseConverter::convertFromBinary($rand, $characters); if (strlen($result) < $length) { diff --git a/lib/CryptLib/Random/Mixer/X_OR.php b/lib/CryptLib/Random/Mixer/X_OR.php deleted file mode 100644 index d8bcc8d..0000000 --- a/lib/CryptLib/Random/Mixer/X_OR.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright 2011 The Authors - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version Build @@version@@ - */ - -namespace CryptLib\Random\Mixer; - -use \CryptLib\Core\Strength; - -/** - * The XOR low strength mixer class - * - * This class implements a mixer based upon the recommendations in RFC 4086 - * section 5.2. It is a trivial mixer that's only advantage is that it runs - * very fast. It is only suitable for low strength keys - * - * @see http://tools.ietf.org/html/rfc4086#section-5.2 - * @category PHPCryptLib - * @package Random - * @subpackage Mixer - * @author Anthony Ferrara - */ -class X_OR implements \CryptLib\Random\Mixer { - - /** - * 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::VERYLOW); - } - - /** - * Test to see if the mixer is available - * - * @return boolean If the mixer is available on the system - */ - public static function test() { - return true; - } - - /** - * 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 ''; - } - $bits = array_pop($parts); - foreach ($parts as $part) { - $bits ^= $part; - } - return $bits; - } - -} diff --git a/lib/CryptLib/bootstrap.php b/lib/CryptLib/bootstrap.php index d1ce65e..a333926 100644 --- a/lib/CryptLib/bootstrap.php +++ b/lib/CryptLib/bootstrap.php @@ -18,26 +18,8 @@ namespace CryptLib; -if (defined('\\CryptLib\\BOOTSTRAPPED')) { - return; -} +require_once __DIR__ . '/Core/AutoLoader.php'; -define('BOOTSTRAPPED', true); +$autoloader = new Core\AutoLoader(__NAMESPACE__, dirname(__DIR__)); -/** - * The simple autoloader for the CryptLib library. - * - * @param string $class The class name to load - * - * @return void - */ -spl_autoload_register(function ($class) { - if (substr($class, 0, strlen(__NAMESPACE__)) == __NAMESPACE__) { - $class = substr($class, strlen(__NAMESPACE__) + 1); - $path = str_replace('\\', '/', $class); - $path = __DIR__ . '/' . $path . '.php'; - if (file_exists($path)) { - require $path; - } - } -}); +$autoloader->register(); \ No newline at end of file diff --git a/test/Unit/Cipher/Block/Cipher/XORTest.php b/test/Unit/Cipher/Block/Cipher/XORTest.php deleted file mode 100644 index 7b1add8..0000000 --- a/test/Unit/Cipher/Block/Cipher/XORTest.php +++ /dev/null @@ -1,76 +0,0 @@ -setKey(pack('H*', $key)); - $enc = $cipher->encryptBlock(pack('H*', $data)); - $this->assertEquals($expected, strtoupper(bin2hex($enc))); - } - - /** - * @dataProvider provideTestEncryptVectors - */ - public function testDecrypt($cipher, $key, $expected, $data) { - $cipher = new \CryptLib\Cipher\Block\Cipher\X_OR($cipher); - $cipher->setKey(pack('H*', $key)); - $enc = $cipher->decryptBlock(pack('H*', $data)); - $this->assertEquals($expected, strtoupper(bin2hex($enc))); - } - - /** - * @dataProvider provideTestEncryptVectors - */ - public function testEncryptThenDecrypt($cipher, $key, $data) { - $cipher = new \CryptLib\Cipher\Block\Cipher\X_OR($cipher); - $cipher->setKey(pack('H*', $key)); - $enc = $cipher->encryptBlock(pack('H*', $data)); - $dec = $cipher->decryptBlock($enc); - $this->assertEquals($data, strtoupper(bin2hex($dec))); - } - - public function testBlockSize() { - $cipher = new \CryptLib\Cipher\Block\Cipher\X_OR('xor'); - $cipher->setKey('foo'); - $this->assertEquals(3, $cipher->getBlockSize()); - } - - public function testGetCipher() { - $cipher = new \CryptLib\Cipher\Block\Cipher\X_OR('xor'); - $this->assertEquals('xor', $cipher->getCipher()); - } - - /** - * @expectedException InvalidArgumentException - */ - public function testConstructFailure() { - $cipher = new \CryptLib\Cipher\Block\Cipher\X_OR('rijndael-128'); - } - -} diff --git a/test/Unit/Random/Mixer/X_ORTest.php b/test/Unit/Random/Mixer/X_ORTest.php deleted file mode 100644 index 6ac383b..0000000 --- a/test/Unit/Random/Mixer/X_ORTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($actual, $strength); - } - - /** - * @covers CryptLib\Random\Mixer\X_OR - * @covers CryptLib\Random\AbstractMixer - */ - public function testTest() { - $actual = X_OR::test(); - $this->assertTrue($actual); - } - - /** - * @covers CryptLib\Random\Mixer\X_OR - * @covers CryptLib\Random\AbstractMixer - * @dataProvider provideMix - */ - public function testMix($parts, $result) { - $mixer = new X_OR; - $actual = $mixer->mix($parts); - $this->assertEquals($result, $actual); - } - -} diff --git a/test/bootstrap.php b/test/bootstrap.php index 8d3d96d..54e6caa 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -21,7 +21,10 @@ ini_set('memory_limit', '1G'); /** - * The simple autoloader for the CryptLib library. + * The simple autoloader for the CryptLibTest libraries. + * + * This does not use the PRS-0 standards due to the namespace prefix and directory + * structure * * @param string $class The class name to load * @@ -47,3 +50,4 @@ function getTestDataFile($file) { } require_once dirname(__DIR__) . '/lib/CryptLib/bootstrap.php'; +