* @copyright 2011 The Authors * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version Build @@version@@ */ namespace CryptLib\Cipher; /** * Some used classes, aliased appropriately */ use CryptLib\Cipher\Block\Cipher as Cipher; use CryptLib\Cipher\Block\Mode as Mode; use CryptLib\Cipher\Block\Cipher\MCrypt; /** * The Cipher Factory * * Use this factory to instantiate ciphers and modes based upon their names. You * can register new ciphers and modes by simply calling the appropriate methods. * * @category PHPCryptLib * @package Cipher * @author Anthony Ferrara */ class Factory extends \CryptLib\Core\AbstractFactory { /** * @var array A list of available cipher implementations by name of cipher */ protected $ciphers = array(); /** * @var array A list of available mode implementations by name of mode */ protected $modes = array(); /** * Instantiate the factory * * This automatically loads and registers the default cipher and mode * implementations. * * @return void */ public function __construct() { $this->loadModes(); $this->loadCiphers(); } /** * Get an instance of a cipher by name * * Note that this will return the passed argument if it is an instance of * the Block cipher interface. * * @param string|Block $cipher The cipher name or instance to load * * @return Cipher The loaded block cipher * @throws RuntimeException if the cipher is not supported */ public function getBlockCipher($cipher) { if (is_object($cipher) && $cipher instanceof Cipher) { return $cipher; } $cipher = strtolower($cipher); if (in_array($cipher, MCrypt::getSupportedCiphers())) { //Use the built in MCrypt library if it's available return new MCrypt($cipher); } elseif (isset($this->ciphers[$cipher])) { $class = $this->ciphers[$cipher]; return new $class($cipher); } $message = sprintf('Unsupported Cipher %s', $cipher); throw new \RuntimeException($message); } /** * Get an instance of a mode by name * * Note that this will return the passed argument if it is an instance of * the Mode interface. * * @param string|Mode $mode The mode name or instance to load * * @return Mode The loaded mode instance * @throws RuntimeException if the mode is not supported */ public function getMode( $mode, \CryptLib\Cipher\Block\Cipher $cipher, $initv, array $options = array() ) { if (is_object($mode) && $mode instanceof Mode) { return $mode; } $mode = strtolower($mode); if (isset($this->modes[$mode])) { $class = $this->modes[$mode]; return new $class($cipher, $initv, $options); } $message = sprintf('Unsupported Mode %s', $mode); throw new \RuntimeException($message); } /** * Register a new cipher implementation class for this factory * * This will iterate over each supported cipher for the class and load the * cipher into the list of supported ciphers * * @param string $name The name of the cipher (ignored) * @param string $class The full class name of the cipher implementation * * @return Factory $this The current factory instance * @throws InvalidArgumentException If the class is not a block cipher */ public function registerCipher($name, $class) { $refl = new \ReflectionClass($class); $interface = '\\'. __NAMESPACE__ . '\\Block\\Cipher'; if (!$refl->implementsInterface($interface)) { $message = sprintf('Class must implement %s', $interface); throw new \InvalidArgumentException($message); } foreach ($class::getSupportedCiphers() as $cipher){ $this->ciphers[$cipher] = $class; } return $this; } /** * Register a new mode implementation class for this factory * * @param string $name The name of the mode (ignored) * @param string $class The full class name of the mode implementation * * @return Factory $this The current factory instance * @throws InvalidArgumentException If the class is not a valid mode */ public function registerMode($name, $class) { $refl = new \ReflectionClass($class); $interface = '\\'. __NAMESPACE__ . '\\Block\\Mode'; if (!$refl->implementsInterface($interface)) { throw new \InvalidArgumentException('Class must implement Mode'); } $this->modes[strtolower($name)] = $class; return $this; } /** * Load all core cipher implementations * * @return void */ protected function loadCiphers() { $this->loadFiles( __DIR__ . '/Block/Cipher', __NAMESPACE__ . '\\Block\\Cipher\\', array($this, 'registerCipher') ); } /** * Load all core mode implementations * * @return void */ protected function loadModes() { $this->loadFiles( __DIR__ . '/Block/Mode', __NAMESPACE__ . '\\Block\\Mode\\', array($this, 'registerMode') ); } }