This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
0 ignored issues
–
show
|
|||
2 | /** |
||
3 | * CodeIgniter |
||
4 | * |
||
5 | * An open source application development framework for PHP |
||
6 | * |
||
7 | * This content is released under the MIT License (MIT) |
||
8 | * |
||
9 | * Copyright (c) 2014 - 2015, British Columbia Institute of Technology |
||
10 | * |
||
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
||
12 | * of this software and associated documentation files (the "Software"), to deal |
||
13 | * in the Software without restriction, including without limitation the rights |
||
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||
15 | * copies of the Software, and to permit persons to whom the Software is |
||
16 | * furnished to do so, subject to the following conditions: |
||
17 | * |
||
18 | * The above copyright notice and this permission notice shall be included in |
||
19 | * all copies or substantial portions of the Software. |
||
20 | * |
||
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||
27 | * THE SOFTWARE. |
||
28 | * |
||
29 | * @package CodeIgniter |
||
30 | * @author EllisLab Dev Team |
||
31 | * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) |
||
32 | * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) |
||
33 | * @license http://opensource.org/licenses/MIT MIT License |
||
34 | * @link http://codeigniter.com |
||
35 | * @since Version 3.0.0 |
||
36 | * @filesource |
||
37 | */ |
||
38 | defined('BASEPATH') OR exit('No direct script access allowed'); |
||
39 | |||
40 | /** |
||
41 | * CodeIgniter Encryption Class |
||
42 | * |
||
43 | * Provides two-way keyed encryption via PHP's MCrypt and/or OpenSSL extensions. |
||
44 | * |
||
45 | * @package CodeIgniter |
||
46 | * @subpackage Libraries |
||
47 | * @category Libraries |
||
48 | * @author Andrey Andreev |
||
49 | * @link http://codeigniter.com/user_guide/libraries/encryption.html |
||
50 | */ |
||
51 | class CI_Encryption { |
||
52 | |||
53 | /** |
||
54 | * Encryption cipher |
||
55 | * |
||
56 | * @var string |
||
57 | */ |
||
58 | protected $_cipher = 'aes-128'; |
||
59 | |||
60 | /** |
||
61 | * Cipher mode |
||
62 | * |
||
63 | * @var string |
||
64 | */ |
||
65 | protected $_mode = 'cbc'; |
||
66 | |||
67 | /** |
||
68 | * Cipher handle |
||
69 | * |
||
70 | * @var mixed |
||
71 | */ |
||
72 | protected $_handle; |
||
73 | |||
74 | /** |
||
75 | * Encryption key |
||
76 | * |
||
77 | * @var string |
||
78 | */ |
||
79 | protected $_key; |
||
80 | |||
81 | /** |
||
82 | * PHP extension to be used |
||
83 | * |
||
84 | * @var string |
||
85 | */ |
||
86 | protected $_driver; |
||
87 | |||
88 | /** |
||
89 | * List of usable drivers (PHP extensions) |
||
90 | * |
||
91 | * @var array |
||
92 | */ |
||
93 | protected $_drivers = array(); |
||
94 | |||
95 | /** |
||
96 | * List of available modes |
||
97 | * |
||
98 | * @var array |
||
99 | */ |
||
100 | protected $_modes = array( |
||
101 | 'mcrypt' => array( |
||
102 | 'cbc' => 'cbc', |
||
103 | 'ecb' => 'ecb', |
||
104 | 'ofb' => 'nofb', |
||
105 | 'ofb8' => 'ofb', |
||
106 | 'cfb' => 'ncfb', |
||
107 | 'cfb8' => 'cfb', |
||
108 | 'ctr' => 'ctr', |
||
109 | 'stream' => 'stream' |
||
110 | ), |
||
111 | 'openssl' => array( |
||
112 | 'cbc' => 'cbc', |
||
113 | 'ecb' => 'ecb', |
||
114 | 'ofb' => 'ofb', |
||
115 | 'cfb' => 'cfb', |
||
116 | 'cfb8' => 'cfb8', |
||
117 | 'ctr' => 'ctr', |
||
118 | 'stream' => '', |
||
119 | 'xts' => 'xts' |
||
120 | ) |
||
121 | ); |
||
122 | |||
123 | /** |
||
124 | * List of supported HMAC algorithms |
||
125 | * |
||
126 | * name => digest size pairs |
||
127 | * |
||
128 | * @var array |
||
129 | */ |
||
130 | protected $_digests = array( |
||
131 | 'sha224' => 28, |
||
132 | 'sha256' => 32, |
||
133 | 'sha384' => 48, |
||
134 | 'sha512' => 64 |
||
135 | ); |
||
136 | |||
137 | /** |
||
138 | * mbstring.func_override flag |
||
139 | * |
||
140 | * @var bool |
||
141 | */ |
||
142 | protected static $func_override; |
||
143 | |||
144 | // -------------------------------------------------------------------- |
||
145 | |||
146 | /** |
||
147 | * Class constructor |
||
148 | * |
||
149 | * @param array $params Configuration parameters |
||
150 | * @return void |
||
151 | */ |
||
152 | public function __construct(array $params = array()) |
||
153 | { |
||
154 | $this->_drivers = array( |
||
155 | 'mcrypt' => defined('MCRYPT_DEV_URANDOM'), |
||
156 | // While OpenSSL is available for PHP 5.3.0, an IV parameter |
||
157 | // for the encrypt/decrypt functions is only available since 5.3.3 |
||
158 | 'openssl' => (is_php('5.3.3') && extension_loaded('openssl')) |
||
159 | ); |
||
160 | |||
161 | if ( ! $this->_drivers['mcrypt'] && ! $this->_drivers['openssl']) |
||
162 | { |
||
163 | show_error('Encryption: Unable to find an available encryption driver.'); |
||
164 | } |
||
165 | |||
166 | isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); |
||
167 | $this->initialize($params); |
||
168 | |||
169 | if ( ! isset($this->_key) && self::strlen($key = config_item('encryption_key')) > 0) |
||
170 | { |
||
171 | $this->_key = $key; |
||
172 | } |
||
173 | |||
174 | log_message('info', 'Encryption Class Initialized'); |
||
175 | } |
||
176 | |||
177 | // -------------------------------------------------------------------- |
||
178 | |||
179 | /** |
||
180 | * Initialize |
||
181 | * |
||
182 | * @param array $params Configuration parameters |
||
183 | * @return CI_Encryption |
||
184 | */ |
||
185 | public function initialize(array $params) |
||
186 | { |
||
187 | if ( ! empty($params['driver'])) |
||
188 | { |
||
189 | if (isset($this->_drivers[$params['driver']])) |
||
190 | { |
||
191 | if ($this->_drivers[$params['driver']]) |
||
192 | { |
||
193 | $this->_driver = $params['driver']; |
||
194 | } |
||
195 | else |
||
196 | { |
||
197 | log_message('error', "Encryption: Driver '".$params['driver']."' is not available."); |
||
198 | } |
||
199 | } |
||
200 | else |
||
201 | { |
||
202 | log_message('error', "Encryption: Unknown driver '".$params['driver']."' cannot be configured."); |
||
203 | } |
||
204 | } |
||
205 | |||
206 | if (empty($this->_driver)) |
||
207 | { |
||
208 | $this->_driver = ($this->_drivers['openssl'] === TRUE) |
||
209 | ? 'openssl' |
||
210 | : 'mcrypt'; |
||
211 | |||
212 | log_message('debug', "Encryption: Auto-configured driver '".$this->_driver."'."); |
||
213 | } |
||
214 | |||
215 | empty($params['cipher']) && $params['cipher'] = $this->_cipher; |
||
216 | empty($params['key']) OR $this->_key = $params['key']; |
||
217 | $this->{'_'.$this->_driver.'_initialize'}($params); |
||
218 | return $this; |
||
219 | } |
||
220 | |||
221 | // -------------------------------------------------------------------- |
||
222 | |||
223 | /** |
||
224 | * Initialize MCrypt |
||
225 | * |
||
226 | * @param array $params Configuration parameters |
||
227 | * @return void |
||
228 | */ |
||
229 | protected function _mcrypt_initialize($params) |
||
230 | { |
||
231 | if ( ! empty($params['cipher'])) |
||
232 | { |
||
233 | $params['cipher'] = strtolower($params['cipher']); |
||
234 | $this->_cipher_alias($params['cipher']); |
||
235 | |||
236 | if ( ! in_array($params['cipher'], mcrypt_list_algorithms(), TRUE)) |
||
237 | { |
||
238 | log_message('error', 'Encryption: MCrypt cipher '.strtoupper($params['cipher']).' is not available.'); |
||
239 | } |
||
240 | else |
||
241 | { |
||
242 | $this->_cipher = $params['cipher']; |
||
243 | } |
||
244 | } |
||
245 | |||
246 | View Code Duplication | if ( ! empty($params['mode'])) |
|
247 | { |
||
248 | $params['mode'] = strtolower($params['mode']); |
||
249 | if ( ! isset($this->_modes['mcrypt'][$params['mode']])) |
||
250 | { |
||
251 | log_message('error', 'Encryption: MCrypt mode '.strtoupper($params['mode']).' is not available.'); |
||
252 | } |
||
253 | else |
||
254 | { |
||
255 | $this->_mode = $this->_modes['mcrypt'][$params['mode']]; |
||
256 | } |
||
257 | } |
||
258 | |||
259 | if (isset($this->_cipher, $this->_mode)) |
||
260 | { |
||
261 | if (is_resource($this->_handle) |
||
262 | && (strtolower(mcrypt_enc_get_algorithms_name($this->_handle)) !== $this->_cipher |
||
263 | OR strtolower(mcrypt_enc_get_modes_name($this->_handle)) !== $this->_mode) |
||
264 | ) |
||
265 | { |
||
266 | mcrypt_module_close($this->_handle); |
||
267 | } |
||
268 | |||
269 | if ($this->_handle = mcrypt_module_open($this->_cipher, '', $this->_mode, '')) |
||
270 | { |
||
271 | log_message('info', 'Encryption: MCrypt cipher '.strtoupper($this->_cipher).' initialized in '.strtoupper($this->_mode).' mode.'); |
||
272 | } |
||
273 | else |
||
274 | { |
||
275 | log_message('error', 'Encryption: Unable to initialize MCrypt with cipher '.strtoupper($this->_cipher).' in '.strtoupper($this->_mode).' mode.'); |
||
276 | } |
||
277 | } |
||
278 | } |
||
279 | |||
280 | // -------------------------------------------------------------------- |
||
281 | |||
282 | /** |
||
283 | * Initialize OpenSSL |
||
284 | * |
||
285 | * @param array $params Configuration parameters |
||
286 | * @return void |
||
287 | */ |
||
288 | protected function _openssl_initialize($params) |
||
289 | { |
||
290 | if ( ! empty($params['cipher'])) |
||
291 | { |
||
292 | $params['cipher'] = strtolower($params['cipher']); |
||
293 | $this->_cipher_alias($params['cipher']); |
||
294 | $this->_cipher = $params['cipher']; |
||
295 | } |
||
296 | |||
297 | View Code Duplication | if ( ! empty($params['mode'])) |
|
298 | { |
||
299 | $params['mode'] = strtolower($params['mode']); |
||
300 | if ( ! isset($this->_modes['openssl'][$params['mode']])) |
||
301 | { |
||
302 | log_message('error', 'Encryption: OpenSSL mode '.strtoupper($params['mode']).' is not available.'); |
||
303 | } |
||
304 | else |
||
305 | { |
||
306 | $this->_mode = $this->_modes['openssl'][$params['mode']]; |
||
307 | } |
||
308 | } |
||
309 | |||
310 | if (isset($this->_cipher, $this->_mode)) |
||
311 | { |
||
312 | // This is mostly for the stream mode, which doesn't get suffixed in OpenSSL |
||
313 | $handle = empty($this->_mode) |
||
314 | ? $this->_cipher |
||
315 | : $this->_cipher.'-'.$this->_mode; |
||
316 | |||
317 | if ( ! in_array($handle, openssl_get_cipher_methods(), TRUE)) |
||
318 | { |
||
319 | $this->_handle = NULL; |
||
320 | log_message('error', 'Encryption: Unable to initialize OpenSSL with method '.strtoupper($handle).'.'); |
||
321 | } |
||
322 | else |
||
323 | { |
||
324 | $this->_handle = $handle; |
||
325 | log_message('info', 'Encryption: OpenSSL initialized with method '.strtoupper($handle).'.'); |
||
326 | } |
||
327 | } |
||
328 | } |
||
329 | |||
330 | // -------------------------------------------------------------------- |
||
331 | |||
332 | /** |
||
333 | * Create a random key |
||
334 | * |
||
335 | * @param int $length Output length |
||
336 | * @return string |
||
337 | */ |
||
338 | public function create_key($length) |
||
339 | { |
||
340 | if (function_exists('random_bytes')) |
||
341 | { |
||
342 | return random_bytes((int) $length); |
||
343 | } |
||
344 | |||
345 | return ($this->_driver === 'mcrypt') |
||
346 | ? mcrypt_create_iv($length, MCRYPT_DEV_URANDOM) |
||
347 | : openssl_random_pseudo_bytes($length); |
||
348 | } |
||
349 | |||
350 | // -------------------------------------------------------------------- |
||
351 | |||
352 | /** |
||
353 | * Encrypt |
||
354 | * |
||
355 | * @param string $data Input data |
||
356 | * @param array $params Input parameters |
||
357 | * @return string |
||
358 | */ |
||
359 | public function encrypt($data, array $params = NULL) |
||
360 | { |
||
361 | if (($params = $this->_get_params($params)) === FALSE) |
||
0 ignored issues
–
show
It seems like
$params defined by $this->_get_params($params) on line 361 can also be of type null ; however, CI_Encryption::_get_params() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
362 | { |
||
363 | return FALSE; |
||
364 | } |
||
365 | |||
366 | isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, self::strlen($this->_key), 'encryption'); |
||
367 | |||
368 | if (($data = $this->{'_'.$this->_driver.'_encrypt'}($data, $params)) === FALSE) |
||
369 | { |
||
370 | return FALSE; |
||
371 | } |
||
372 | |||
373 | $params['base64'] && $data = base64_encode($data); |
||
374 | |||
375 | if (isset($params['hmac_digest'])) |
||
376 | { |
||
377 | isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication'); |
||
378 | return hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']).$data; |
||
379 | } |
||
380 | |||
381 | return $data; |
||
382 | } |
||
383 | |||
384 | // -------------------------------------------------------------------- |
||
385 | |||
386 | /** |
||
387 | * Encrypt via MCrypt |
||
388 | * |
||
389 | * @param string $data Input data |
||
390 | * @param array $params Input parameters |
||
391 | * @return string |
||
392 | */ |
||
393 | protected function _mcrypt_encrypt($data, $params) |
||
394 | { |
||
395 | if ( ! is_resource($params['handle'])) |
||
396 | { |
||
397 | return FALSE; |
||
398 | } |
||
399 | |||
400 | // The greater-than-1 comparison is mostly a work-around for a bug, |
||
401 | // where 1 is returned for ARCFour instead of 0. |
||
402 | $iv = (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) |
||
403 | ? mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM) |
||
404 | : NULL; |
||
405 | |||
406 | View Code Duplication | if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) |
|
407 | { |
||
408 | if ($params['handle'] !== $this->_handle) |
||
409 | { |
||
410 | mcrypt_module_close($params['handle']); |
||
411 | } |
||
412 | |||
413 | return FALSE; |
||
414 | } |
||
415 | |||
416 | // Use PKCS#7 padding in order to ensure compatibility with OpenSSL |
||
417 | // and other implementations outside of PHP. |
||
418 | if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE)) |
||
419 | { |
||
420 | $block_size = mcrypt_enc_get_block_size($params['handle']); |
||
421 | $pad = $block_size - (self::strlen($data) % $block_size); |
||
422 | $data .= str_repeat(chr($pad), $pad); |
||
423 | } |
||
424 | |||
425 | // Work-around for yet another strange behavior in MCrypt. |
||
426 | // |
||
427 | // When encrypting in ECB mode, the IV is ignored. Yet |
||
428 | // mcrypt_enc_get_iv_size() returns a value larger than 0 |
||
429 | // even if ECB is used AND mcrypt_generic_init() complains |
||
430 | // if you don't pass an IV with length equal to the said |
||
431 | // return value. |
||
432 | // |
||
433 | // This probably would've been fine (even though still wasteful), |
||
434 | // but OpenSSL isn't that dumb and we need to make the process |
||
435 | // portable, so ... |
||
436 | $data = (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB') |
||
437 | ? $iv.mcrypt_generic($params['handle'], $data) |
||
438 | : mcrypt_generic($params['handle'], $data); |
||
439 | |||
440 | mcrypt_generic_deinit($params['handle']); |
||
441 | if ($params['handle'] !== $this->_handle) |
||
442 | { |
||
443 | mcrypt_module_close($params['handle']); |
||
444 | } |
||
445 | |||
446 | return $data; |
||
447 | } |
||
448 | |||
449 | // -------------------------------------------------------------------- |
||
450 | |||
451 | /** |
||
452 | * Encrypt via OpenSSL |
||
453 | * |
||
454 | * @param string $data Input data |
||
455 | * @param array $params Input parameters |
||
456 | * @return string |
||
457 | */ |
||
458 | protected function _openssl_encrypt($data, $params) |
||
459 | { |
||
460 | if (empty($params['handle'])) |
||
461 | { |
||
462 | return FALSE; |
||
463 | } |
||
464 | |||
465 | $iv = ($iv_size = openssl_cipher_iv_length($params['handle'])) |
||
466 | ? openssl_random_pseudo_bytes($iv_size) |
||
467 | : NULL; |
||
468 | |||
469 | $data = openssl_encrypt( |
||
470 | $data, |
||
471 | $params['handle'], |
||
472 | $params['key'], |
||
473 | 1, // DO NOT TOUCH! |
||
474 | $iv |
||
475 | ); |
||
476 | |||
477 | if ($data === FALSE) |
||
478 | { |
||
479 | return FALSE; |
||
480 | } |
||
481 | |||
482 | return $iv.$data; |
||
483 | } |
||
484 | |||
485 | // -------------------------------------------------------------------- |
||
486 | |||
487 | /** |
||
488 | * Decrypt |
||
489 | * |
||
490 | * @param string $data Encrypted data |
||
491 | * @param array $params Input parameters |
||
492 | * @return string |
||
493 | */ |
||
494 | public function decrypt($data, array $params = NULL) |
||
495 | { |
||
496 | if (($params = $this->_get_params($params)) === FALSE) |
||
0 ignored issues
–
show
It seems like
$params defined by $this->_get_params($params) on line 496 can also be of type null ; however, CI_Encryption::_get_params() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
497 | { |
||
498 | return FALSE; |
||
499 | } |
||
500 | |||
501 | if (isset($params['hmac_digest'])) |
||
502 | { |
||
503 | // This might look illogical, but it is done during encryption as well ... |
||
504 | // The 'base64' value is effectively an inverted "raw data" parameter |
||
505 | $digest_size = ($params['base64']) |
||
506 | ? $this->_digests[$params['hmac_digest']] * 2 |
||
507 | : $this->_digests[$params['hmac_digest']]; |
||
508 | |||
509 | if (self::strlen($data) <= $digest_size) |
||
510 | { |
||
511 | return FALSE; |
||
512 | } |
||
513 | |||
514 | $hmac_input = self::substr($data, 0, $digest_size); |
||
515 | $data = self::substr($data, $digest_size); |
||
516 | |||
517 | isset($params['hmac_key']) OR $params['hmac_key'] = $this->hkdf($this->_key, 'sha512', NULL, NULL, 'authentication'); |
||
518 | $hmac_check = hash_hmac($params['hmac_digest'], $data, $params['hmac_key'], ! $params['base64']); |
||
519 | |||
520 | // Time-attack-safe comparison |
||
521 | $diff = 0; |
||
522 | for ($i = 0; $i < $digest_size; $i++) |
||
523 | { |
||
524 | $diff |= ord($hmac_input[$i]) ^ ord($hmac_check[$i]); |
||
525 | } |
||
526 | |||
527 | if ($diff !== 0) |
||
528 | { |
||
529 | return FALSE; |
||
530 | } |
||
531 | } |
||
532 | |||
533 | if ($params['base64']) |
||
534 | { |
||
535 | $data = base64_decode($data); |
||
536 | } |
||
537 | |||
538 | isset($params['key']) OR $params['key'] = $this->hkdf($this->_key, 'sha512', NULL, self::strlen($this->_key), 'encryption'); |
||
539 | |||
540 | return $this->{'_'.$this->_driver.'_decrypt'}($data, $params); |
||
541 | } |
||
542 | |||
543 | // -------------------------------------------------------------------- |
||
544 | |||
545 | /** |
||
546 | * Decrypt via MCrypt |
||
547 | * |
||
548 | * @param string $data Encrypted data |
||
549 | * @param array $params Input parameters |
||
550 | * @return string |
||
551 | */ |
||
552 | protected function _mcrypt_decrypt($data, $params) |
||
553 | { |
||
554 | if ( ! is_resource($params['handle'])) |
||
555 | { |
||
556 | return FALSE; |
||
557 | } |
||
558 | |||
559 | // The greater-than-1 comparison is mostly a work-around for a bug, |
||
560 | // where 1 is returned for ARCFour instead of 0. |
||
561 | if (($iv_size = mcrypt_enc_get_iv_size($params['handle'])) > 1) |
||
562 | { |
||
563 | View Code Duplication | if (mcrypt_enc_get_modes_name($params['handle']) !== 'ECB') |
|
564 | { |
||
565 | $iv = self::substr($data, 0, $iv_size); |
||
566 | $data = self::substr($data, $iv_size); |
||
567 | } |
||
568 | else |
||
569 | { |
||
570 | // MCrypt is dumb and this is ignored, only size matters |
||
571 | $iv = str_repeat("\x0", $iv_size); |
||
572 | } |
||
573 | } |
||
574 | else |
||
575 | { |
||
576 | $iv = NULL; |
||
577 | } |
||
578 | |||
579 | View Code Duplication | if (mcrypt_generic_init($params['handle'], $params['key'], $iv) < 0) |
|
580 | { |
||
581 | if ($params['handle'] !== $this->_handle) |
||
582 | { |
||
583 | mcrypt_module_close($params['handle']); |
||
584 | } |
||
585 | |||
586 | return FALSE; |
||
587 | } |
||
588 | |||
589 | $data = mdecrypt_generic($params['handle'], $data); |
||
590 | // Remove PKCS#7 padding, if necessary |
||
591 | if (in_array(strtolower(mcrypt_enc_get_modes_name($params['handle'])), array('cbc', 'ecb'), TRUE)) |
||
592 | { |
||
593 | $data = self::substr($data, 0, -ord($data[self::strlen($data)-1])); |
||
594 | } |
||
595 | |||
596 | mcrypt_generic_deinit($params['handle']); |
||
597 | if ($params['handle'] !== $this->_handle) |
||
598 | { |
||
599 | mcrypt_module_close($params['handle']); |
||
600 | } |
||
601 | |||
602 | return $data; |
||
603 | } |
||
604 | |||
605 | // -------------------------------------------------------------------- |
||
606 | |||
607 | /** |
||
608 | * Decrypt via OpenSSL |
||
609 | * |
||
610 | * @param string $data Encrypted data |
||
611 | * @param array $params Input parameters |
||
612 | * @return string |
||
613 | */ |
||
614 | protected function _openssl_decrypt($data, $params) |
||
615 | { |
||
616 | View Code Duplication | if ($iv_size = openssl_cipher_iv_length($params['handle'])) |
|
617 | { |
||
618 | $iv = self::substr($data, 0, $iv_size); |
||
619 | $data = self::substr($data, $iv_size); |
||
620 | } |
||
621 | else |
||
622 | { |
||
623 | $iv = NULL; |
||
624 | } |
||
625 | |||
626 | return empty($params['handle']) |
||
627 | ? FALSE |
||
628 | : openssl_decrypt( |
||
629 | $data, |
||
630 | $params['handle'], |
||
631 | $params['key'], |
||
632 | 1, // DO NOT TOUCH! |
||
633 | $iv |
||
634 | ); |
||
635 | } |
||
636 | |||
637 | // -------------------------------------------------------------------- |
||
638 | |||
639 | /** |
||
640 | * Get params |
||
641 | * |
||
642 | * @param array $params Input parameters |
||
643 | * @return array |
||
644 | */ |
||
645 | protected function _get_params($params) |
||
646 | { |
||
647 | if (empty($params)) |
||
648 | { |
||
649 | return isset($this->_cipher, $this->_mode, $this->_key, $this->_handle) |
||
650 | ? array( |
||
651 | 'handle' => $this->_handle, |
||
652 | 'cipher' => $this->_cipher, |
||
653 | 'mode' => $this->_mode, |
||
654 | 'key' => NULL, |
||
655 | 'base64' => TRUE, |
||
656 | 'hmac_digest' => 'sha512', |
||
657 | 'hmac_key' => NULL |
||
658 | ) |
||
659 | : FALSE; |
||
660 | } |
||
661 | elseif ( ! isset($params['cipher'], $params['mode'], $params['key'])) |
||
662 | { |
||
663 | return FALSE; |
||
664 | } |
||
665 | |||
666 | if (isset($params['mode'])) |
||
667 | { |
||
668 | $params['mode'] = strtolower($params['mode']); |
||
669 | if ( ! isset($this->_modes[$this->_driver][$params['mode']])) |
||
670 | { |
||
671 | return FALSE; |
||
672 | } |
||
673 | else |
||
674 | { |
||
675 | $params['mode'] = $this->_modes[$this->_driver][$params['mode']]; |
||
676 | } |
||
677 | } |
||
678 | |||
679 | if (isset($params['hmac']) && $params['hmac'] === FALSE) |
||
680 | { |
||
681 | $params['hmac_digest'] = $params['hmac_key'] = NULL; |
||
682 | } |
||
683 | else |
||
684 | { |
||
685 | if ( ! isset($params['hmac_key'])) |
||
686 | { |
||
687 | return FALSE; |
||
688 | } |
||
689 | elseif (isset($params['hmac_digest'])) |
||
690 | { |
||
691 | $params['hmac_digest'] = strtolower($params['hmac_digest']); |
||
692 | if ( ! isset($this->_digests[$params['hmac_digest']])) |
||
693 | { |
||
694 | return FALSE; |
||
695 | } |
||
696 | } |
||
697 | else |
||
698 | { |
||
699 | $params['hmac_digest'] = 'sha512'; |
||
700 | } |
||
701 | } |
||
702 | |||
703 | $params = array( |
||
704 | 'handle' => NULL, |
||
705 | 'cipher' => $params['cipher'], |
||
706 | 'mode' => $params['mode'], |
||
707 | 'key' => $params['key'], |
||
708 | 'base64' => isset($params['raw_data']) ? ! $params['raw_data'] : FALSE, |
||
709 | 'hmac_digest' => $params['hmac_digest'], |
||
710 | 'hmac_key' => $params['hmac_key'] |
||
711 | ); |
||
712 | |||
713 | $this->_cipher_alias($params['cipher']); |
||
714 | $params['handle'] = ($params['cipher'] !== $this->_cipher OR $params['mode'] !== $this->_mode) |
||
715 | ? $this->{'_'.$this->_driver.'_get_handle'}($params['cipher'], $params['mode']) |
||
716 | : $this->_handle; |
||
717 | |||
718 | return $params; |
||
719 | } |
||
720 | |||
721 | // -------------------------------------------------------------------- |
||
722 | |||
723 | /** |
||
724 | * Get MCrypt handle |
||
725 | * |
||
726 | * @param string $cipher Cipher name |
||
727 | * @param string $mode Encryption mode |
||
728 | * @return resource |
||
729 | */ |
||
730 | protected function _mcrypt_get_handle($cipher, $mode) |
||
731 | { |
||
732 | return mcrypt_module_open($cipher, '', $mode, ''); |
||
733 | } |
||
734 | |||
735 | // -------------------------------------------------------------------- |
||
736 | |||
737 | /** |
||
738 | * Get OpenSSL handle |
||
739 | * |
||
740 | * @param string $cipher Cipher name |
||
741 | * @param string $mode Encryption mode |
||
742 | * @return string |
||
743 | */ |
||
744 | protected function _openssl_get_handle($cipher, $mode) |
||
745 | { |
||
746 | // OpenSSL methods aren't suffixed with '-stream' for this mode |
||
747 | return ($mode === 'stream') |
||
748 | ? $cipher |
||
749 | : $cipher.'-'.$mode; |
||
750 | } |
||
751 | |||
752 | // -------------------------------------------------------------------- |
||
753 | |||
754 | /** |
||
755 | * Cipher alias |
||
756 | * |
||
757 | * Tries to translate cipher names between MCrypt and OpenSSL's "dialects". |
||
758 | * |
||
759 | * @param string $cipher Cipher name |
||
760 | * @return void |
||
761 | */ |
||
762 | protected function _cipher_alias(&$cipher) |
||
763 | { |
||
764 | static $dictionary; |
||
765 | |||
766 | if (empty($dictionary)) |
||
767 | { |
||
768 | $dictionary = array( |
||
769 | 'mcrypt' => array( |
||
770 | 'aes-128' => 'rijndael-128', |
||
771 | 'aes-192' => 'rijndael-128', |
||
772 | 'aes-256' => 'rijndael-128', |
||
773 | 'des3-ede3' => 'tripledes', |
||
774 | 'bf' => 'blowfish', |
||
775 | 'cast5' => 'cast-128', |
||
776 | 'rc4' => 'arcfour', |
||
777 | 'rc4-40' => 'arcfour' |
||
778 | ), |
||
779 | 'openssl' => array( |
||
780 | 'rijndael-128' => 'aes-128', |
||
781 | 'tripledes' => 'des-ede3', |
||
782 | 'blowfish' => 'bf', |
||
783 | 'cast-128' => 'cast5', |
||
784 | 'arcfour' => 'rc4-40', |
||
785 | 'rc4' => 'rc4-40' |
||
786 | ) |
||
787 | ); |
||
788 | |||
789 | // Notes: |
||
790 | // |
||
791 | // - Rijndael-128 is, at the same time all three of AES-128, |
||
792 | // AES-192 and AES-256. The only difference between them is |
||
793 | // the key size. Rijndael-192, Rijndael-256 on the other hand |
||
794 | // also have different block sizes and are NOT AES-compatible. |
||
795 | // |
||
796 | // - Blowfish is said to be supporting key sizes between |
||
797 | // 4 and 56 bytes, but it appears that between MCrypt and |
||
798 | // OpenSSL, only those of 16 and more bytes are compatible. |
||
799 | // Also, don't know what MCrypt's 'blowfish-compat' is. |
||
800 | // |
||
801 | // - CAST-128/CAST5 produces a longer cipher when encrypted via |
||
802 | // OpenSSL, but (strangely enough) can be decrypted by either |
||
803 | // extension anyway. |
||
804 | // Also, it appears that OpenSSL uses 16 rounds regardless of |
||
805 | // the key size, while RFC2144 says that for key sizes lower |
||
806 | // than 11 bytes, only 12 rounds should be used. This makes |
||
807 | // it portable only with keys of between 11 and 16 bytes. |
||
808 | // |
||
809 | // - RC4 (ARCFour) has a strange implementation under OpenSSL. |
||
810 | // Its 'rc4-40' cipher method seems to work flawlessly, yet |
||
811 | // there's another one, 'rc4' that only works with a 16-byte key. |
||
812 | // |
||
813 | // - DES is compatible, but doesn't need an alias. |
||
814 | // |
||
815 | // Other seemingly matching ciphers between MCrypt, OpenSSL: |
||
816 | // |
||
817 | // - RC2 is NOT compatible and only an obscure forum post |
||
818 | // confirms that it is MCrypt's fault. |
||
819 | } |
||
820 | |||
821 | if (isset($dictionary[$this->_driver][$cipher])) |
||
822 | { |
||
823 | $cipher = $dictionary[$this->_driver][$cipher]; |
||
824 | } |
||
825 | } |
||
826 | |||
827 | // -------------------------------------------------------------------- |
||
828 | |||
829 | /** |
||
830 | * HKDF |
||
831 | * |
||
832 | * @link https://tools.ietf.org/rfc/rfc5869.txt |
||
833 | * @param $key Input key |
||
834 | * @param $digest A SHA-2 hashing algorithm |
||
835 | * @param $salt Optional salt |
||
836 | * @param $length Output length (defaults to the selected digest size) |
||
837 | * @param $info Optional context/application-specific info |
||
838 | * @return string A pseudo-random key |
||
839 | */ |
||
840 | public function hkdf($key, $digest = 'sha512', $salt = NULL, $length = NULL, $info = '') |
||
841 | { |
||
842 | if ( ! isset($this->_digests[$digest])) |
||
843 | { |
||
844 | return FALSE; |
||
845 | } |
||
846 | |||
847 | if (empty($length) OR ! is_int($length)) |
||
848 | { |
||
849 | $length = $this->_digests[$digest]; |
||
850 | } |
||
851 | elseif ($length > (255 * $this->_digests[$digest])) |
||
852 | { |
||
853 | return FALSE; |
||
854 | } |
||
855 | |||
856 | self::strlen($salt) OR $salt = str_repeat("\0", $this->_digests[$digest]); |
||
857 | |||
858 | $prk = hash_hmac($digest, $key, $salt, TRUE); |
||
859 | $key = ''; |
||
860 | for ($key_block = '', $block_index = 1; self::strlen($key) < $length; $block_index++) |
||
861 | { |
||
862 | $key_block = hash_hmac($digest, $key_block.$info.chr($block_index), $prk, TRUE); |
||
863 | $key .= $key_block; |
||
864 | } |
||
865 | |||
866 | return self::substr($key, 0, $length); |
||
867 | } |
||
868 | |||
869 | // -------------------------------------------------------------------- |
||
870 | |||
871 | /** |
||
872 | * __get() magic |
||
873 | * |
||
874 | * @param string $key Property name |
||
875 | * @return mixed |
||
876 | */ |
||
877 | public function __get($key) |
||
878 | { |
||
879 | // Because aliases |
||
880 | if ($key === 'mode') |
||
881 | { |
||
882 | return array_search($this->_mode, $this->_modes[$this->_driver], TRUE); |
||
883 | } |
||
884 | elseif (in_array($key, array('cipher', 'driver', 'drivers', 'digests'), TRUE)) |
||
885 | { |
||
886 | return $this->{'_'.$key}; |
||
887 | } |
||
888 | |||
889 | return NULL; |
||
890 | } |
||
891 | |||
892 | // -------------------------------------------------------------------- |
||
893 | |||
894 | /** |
||
895 | * Byte-safe strlen() |
||
896 | * |
||
897 | * @param string $str |
||
898 | * @return integer |
||
899 | */ |
||
900 | protected static function strlen($str) |
||
901 | { |
||
902 | return (self::$func_override) |
||
903 | ? mb_strlen($str, '8bit') |
||
904 | : strlen($str); |
||
905 | } |
||
906 | |||
907 | // -------------------------------------------------------------------- |
||
908 | |||
909 | /** |
||
910 | * Byte-safe substr() |
||
911 | * |
||
912 | * @param string $str |
||
913 | * @param int $start |
||
914 | * @param int $length |
||
915 | * @return string |
||
916 | */ |
||
917 | protected static function substr($str, $start, $length = NULL) |
||
918 | { |
||
919 | if (self::$func_override) |
||
920 | { |
||
921 | // mb_substr($str, $start, null, '8bit') returns an empty |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
922 | // string on PHP 5.3 |
||
923 | isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start); |
||
924 | return mb_substr($str, $start, $length, '8bit'); |
||
925 | } |
||
926 | |||
927 | return isset($length) |
||
928 | ? substr($str, $start, $length) |
||
929 | : substr($str, $start); |
||
930 | } |
||
931 | } |
||
932 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.