Commit | Line | Data |
---|---|---|
14d4f286 S |
1 | <?php |
2 | /** | |
3 | * The Cipher Factory | |
4 | * | |
5 | * Use this factory to instantiate ciphers and modes based upon their names. You | |
6 | * can register new ciphers and modes by simply calling the appropriate methods. | |
7 | * | |
8 | * PHP version 5.3 | |
9 | * | |
10 | * @category PHPCryptLib | |
11 | * @package Cipher | |
12 | * @author Anthony Ferrara <ircmaxell@ircmaxell.com> | |
13 | * @copyright 2011 The Authors | |
14 | * @license http://www.opensource.org/licenses/mit-license.html MIT License | |
15 | * @version Build @@version@@ | |
16 | */ | |
17 | ||
18 | namespace CryptLib\Cipher; | |
19 | ||
20 | /** | |
21 | * Some used classes, aliased appropriately | |
22 | */ | |
23 | use CryptLib\Cipher\Block\Cipher as Cipher; | |
24 | use CryptLib\Cipher\Block\Mode as Mode; | |
25 | use CryptLib\Cipher\Block\Cipher\MCrypt; | |
26 | ||
27 | ||
28 | /** | |
29 | * The Cipher Factory | |
30 | * | |
31 | * Use this factory to instantiate ciphers and modes based upon their names. You | |
32 | * can register new ciphers and modes by simply calling the appropriate methods. | |
33 | * | |
34 | * @category PHPCryptLib | |
35 | * @package Cipher | |
36 | * @author Anthony Ferrara <ircmaxell@ircmaxell.com> | |
37 | */ | |
38 | class Factory extends \CryptLib\Core\AbstractFactory { | |
39 | ||
40 | /** | |
41 | * @var array A list of available cipher implementations by name of cipher | |
42 | */ | |
43 | protected $ciphers = array(); | |
44 | ||
45 | /** | |
46 | * @var array A list of available mode implementations by name of mode | |
47 | */ | |
48 | protected $modes = array(); | |
49 | ||
50 | /** | |
51 | * Instantiate the factory | |
52 | * | |
53 | * This automatically loads and registers the default cipher and mode | |
54 | * implementations. | |
55 | * | |
56 | * @return void | |
57 | */ | |
58 | public function __construct() { | |
59 | $this->loadModes(); | |
60 | $this->loadCiphers(); | |
61 | } | |
62 | ||
63 | /** | |
64 | * Get an instance of a cipher by name | |
65 | * | |
66 | * Note that this will return the passed argument if it is an instance of | |
67 | * the Block cipher interface. | |
68 | * | |
69 | * @param string|Block $cipher The cipher name or instance to load | |
70 | * | |
71 | * @return Cipher The loaded block cipher | |
72 | * @throws RuntimeException if the cipher is not supported | |
73 | */ | |
74 | public function getBlockCipher($cipher) { | |
75 | if (is_object($cipher) && $cipher instanceof Cipher) { | |
76 | return $cipher; | |
77 | } | |
78 | $cipher = strtolower($cipher); | |
79 | if (in_array($cipher, MCrypt::getSupportedCiphers())) { | |
80 | //Use the built in MCrypt library if it's available | |
81 | return new MCrypt($cipher); | |
82 | } elseif (isset($this->ciphers[$cipher])) { | |
83 | $class = $this->ciphers[$cipher]; | |
84 | return new $class($cipher); | |
85 | } | |
86 | $message = sprintf('Unsupported Cipher %s', $cipher); | |
87 | throw new \RuntimeException($message); | |
88 | } | |
89 | ||
90 | /** | |
91 | * Get an instance of a mode by name | |
92 | * | |
93 | * Note that this will return the passed argument if it is an instance of | |
94 | * the Mode interface. | |
95 | * | |
96 | * @param string|Mode $mode The mode name or instance to load | |
97 | * | |
98 | * @return Mode The loaded mode instance | |
99 | * @throws RuntimeException if the mode is not supported | |
100 | */ | |
101 | public function getMode( | |
102 | $mode, | |
103 | \CryptLib\Cipher\Block\Cipher $cipher, | |
104 | $initv, | |
105 | array $options = array() | |
106 | ) { | |
107 | if (is_object($mode) && $mode instanceof Mode) { | |
108 | return $mode; | |
109 | } | |
110 | $mode = strtolower($mode); | |
111 | if (isset($this->modes[$mode])) { | |
112 | $class = $this->modes[$mode]; | |
113 | return new $class($cipher, $initv, $options); | |
114 | } | |
115 | $message = sprintf('Unsupported Mode %s', $mode); | |
116 | throw new \RuntimeException($message); | |
117 | } | |
118 | ||
119 | /** | |
120 | * Register a new cipher implementation class for this factory | |
121 | * | |
122 | * This will iterate over each supported cipher for the class and load the | |
123 | * cipher into the list of supported ciphers | |
124 | * | |
125 | * @param string $name The name of the cipher (ignored) | |
126 | * @param string $class The full class name of the cipher implementation | |
127 | * | |
128 | * @return Factory $this The current factory instance | |
129 | * @throws InvalidArgumentException If the class is not a block cipher | |
130 | */ | |
131 | public function registerCipher($name, $class) { | |
132 | $refl = new \ReflectionClass($class); | |
133 | $interface = '\\'. __NAMESPACE__ . '\\Block\\Cipher'; | |
134 | if (!$refl->implementsInterface($interface)) { | |
135 | $message = sprintf('Class must implement %s', $interface); | |
136 | throw new \InvalidArgumentException($message); | |
137 | } | |
138 | foreach ($class::getSupportedCiphers() as $cipher){ | |
139 | $this->ciphers[$cipher] = $class; | |
140 | } | |
141 | return $this; | |
142 | } | |
143 | ||
144 | /** | |
145 | * Register a new mode implementation class for this factory | |
146 | * | |
147 | * @param string $name The name of the mode (ignored) | |
148 | * @param string $class The full class name of the mode implementation | |
149 | * | |
150 | * @return Factory $this The current factory instance | |
151 | * @throws InvalidArgumentException If the class is not a valid mode | |
152 | */ | |
153 | public function registerMode($name, $class) { | |
154 | $refl = new \ReflectionClass($class); | |
155 | $interface = '\\'. __NAMESPACE__ . '\\Block\\Mode'; | |
156 | if (!$refl->implementsInterface($interface)) { | |
157 | throw new \InvalidArgumentException('Class must implement Mode'); | |
158 | } | |
159 | $this->modes[strtolower($name)] = $class; | |
160 | return $this; | |
161 | } | |
162 | ||
163 | /** | |
164 | * Load all core cipher implementations | |
165 | * | |
166 | * @return void | |
167 | */ | |
168 | protected function loadCiphers() { | |
169 | $this->loadFiles( | |
170 | __DIR__ . '/Block/Cipher', | |
171 | __NAMESPACE__ . '\\Block\\Cipher\\', | |
172 | array($this, 'registerCipher') | |
173 | ); | |
174 | } | |
175 | ||
176 | /** | |
177 | * Load all core mode implementations | |
178 | * | |
179 | * @return void | |
180 | */ | |
181 | protected function loadModes() { | |
182 | $this->loadFiles( | |
183 | __DIR__ . '/Block/Mode', | |
184 | __NAMESPACE__ . '\\Block\\Mode\\', | |
185 | array($this, 'registerMode') | |
186 | ); | |
187 | } | |
188 | ||
189 | } |