PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Filter/Encrypt/Mcrypt.php

https://bitbucket.org/luizbrandaoj/mini-blog
PHP | 364 lines | 192 code | 42 blank | 130 comment | 31 complexity | 487ba7c91470134c80233b48e3f821dc MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Filter
  17. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Mcrypt.php 23775 2011-03-01 17:25:24Z ralph $
  20. */
  21. /**
  22. * @see Zend_Filter_Encrypt_Interface
  23. */
  24. require_once 'Zend/Filter/Encrypt/Interface.php';
  25. /**
  26. * Encryption adapter for mcrypt
  27. *
  28. * @category Zend
  29. * @package Zend_Filter
  30. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
  34. {
  35. /**
  36. * Definitions for encryption
  37. * array(
  38. * 'key' => encryption key string
  39. * 'algorithm' => algorithm to use
  40. * 'algorithm_directory' => directory where to find the algorithm
  41. * 'mode' => encryption mode to use
  42. * 'modedirectory' => directory where to find the mode
  43. * )
  44. */
  45. protected $_encryption = array(
  46. 'key' => 'ZendFramework',
  47. 'algorithm' => 'blowfish',
  48. 'algorithm_directory' => '',
  49. 'mode' => 'cbc',
  50. 'mode_directory' => '',
  51. 'vector' => null,
  52. 'salt' => false
  53. );
  54. /**
  55. * Internal compression
  56. *
  57. * @var array
  58. */
  59. protected $_compression;
  60. protected static $_srandCalled = false;
  61. /**
  62. * Class constructor
  63. *
  64. * @param string|array|Zend_Config $options Cryption Options
  65. */
  66. public function __construct($options)
  67. {
  68. if (!extension_loaded('mcrypt')) {
  69. require_once 'Zend/Filter/Exception.php';
  70. throw new Zend_Filter_Exception('This filter needs the mcrypt extension');
  71. }
  72. if ($options instanceof Zend_Config) {
  73. $options = $options->toArray();
  74. } elseif (is_string($options)) {
  75. $options = array('key' => $options);
  76. } elseif (!is_array($options)) {
  77. require_once 'Zend/Filter/Exception.php';
  78. throw new Zend_Filter_Exception('Invalid options argument provided to filter');
  79. }
  80. if (array_key_exists('compression', $options)) {
  81. $this->setCompression($options['compression']);
  82. unset($options['compress']);
  83. }
  84. $this->setEncryption($options);
  85. }
  86. /**
  87. * Returns the set encryption options
  88. *
  89. * @return array
  90. */
  91. public function getEncryption()
  92. {
  93. return $this->_encryption;
  94. }
  95. /**
  96. * Sets new encryption options
  97. *
  98. * @param string|array $options Encryption options
  99. * @return Zend_Filter_File_Encryption
  100. */
  101. public function setEncryption($options)
  102. {
  103. if (is_string($options)) {
  104. $options = array('key' => $options);
  105. }
  106. if (!is_array($options)) {
  107. require_once 'Zend/Filter/Exception.php';
  108. throw new Zend_Filter_Exception('Invalid options argument provided to filter');
  109. }
  110. $options = $options + $this->getEncryption();
  111. $algorithms = mcrypt_list_algorithms($options['algorithm_directory']);
  112. if (!in_array($options['algorithm'], $algorithms)) {
  113. require_once 'Zend/Filter/Exception.php';
  114. throw new Zend_Filter_Exception("The algorithm '{$options['algorithm']}' is not supported");
  115. }
  116. $modes = mcrypt_list_modes($options['mode_directory']);
  117. if (!in_array($options['mode'], $modes)) {
  118. require_once 'Zend/Filter/Exception.php';
  119. throw new Zend_Filter_Exception("The mode '{$options['mode']}' is not supported");
  120. }
  121. if (!mcrypt_module_self_test($options['algorithm'], $options['algorithm_directory'])) {
  122. require_once 'Zend/Filter/Exception.php';
  123. throw new Zend_Filter_Exception('The given algorithm can not be used due an internal mcrypt problem');
  124. }
  125. if (!isset($options['vector'])) {
  126. $options['vector'] = null;
  127. }
  128. $this->_encryption = $options;
  129. $this->setVector($options['vector']);
  130. return $this;
  131. }
  132. /**
  133. * Returns the set vector
  134. *
  135. * @return string
  136. */
  137. public function getVector()
  138. {
  139. return $this->_encryption['vector'];
  140. }
  141. /**
  142. * Sets the initialization vector
  143. *
  144. * @param string $vector (Optional) Vector to set
  145. * @return Zend_Filter_Encrypt_Mcrypt
  146. */
  147. public function setVector($vector = null)
  148. {
  149. $cipher = $this->_openCipher();
  150. $size = mcrypt_enc_get_iv_size($cipher);
  151. if (empty($vector)) {
  152. $this->_srand();
  153. if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<')) {
  154. $method = MCRYPT_RAND;
  155. } else {
  156. if (file_exists('/dev/urandom') || (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')) {
  157. $method = MCRYPT_DEV_URANDOM;
  158. } elseif (file_exists('/dev/random')) {
  159. $method = MCRYPT_DEV_RANDOM;
  160. } else {
  161. $method = MCRYPT_RAND;
  162. }
  163. }
  164. $vector = mcrypt_create_iv($size, $method);
  165. } else if (strlen($vector) != $size) {
  166. require_once 'Zend/Filter/Exception.php';
  167. throw new Zend_Filter_Exception('The given vector has a wrong size for the set algorithm');
  168. }
  169. $this->_encryption['vector'] = $vector;
  170. $this->_closeCipher($cipher);
  171. return $this;
  172. }
  173. /**
  174. * Returns the compression
  175. *
  176. * @return array
  177. */
  178. public function getCompression()
  179. {
  180. return $this->_compression;
  181. }
  182. /**
  183. * Sets a internal compression for values to encrypt
  184. *
  185. * @param string|array $compression
  186. * @return Zend_Filter_Encrypt_Mcrypt
  187. */
  188. public function setCompression($compression)
  189. {
  190. if (is_string($this->_compression)) {
  191. $compression = array('adapter' => $compression);
  192. }
  193. $this->_compression = $compression;
  194. return $this;
  195. }
  196. /**
  197. * Defined by Zend_Filter_Interface
  198. *
  199. * Encrypts $value with the defined settings
  200. *
  201. * @param string $value The content to encrypt
  202. * @return string The encrypted content
  203. */
  204. public function encrypt($value)
  205. {
  206. // compress prior to encryption
  207. if (!empty($this->_compression)) {
  208. require_once 'Zend/Filter/Compress.php';
  209. $compress = new Zend_Filter_Compress($this->_compression);
  210. $value = $compress->filter($value);
  211. }
  212. $cipher = $this->_openCipher();
  213. $this->_initCipher($cipher);
  214. $encrypted = mcrypt_generic($cipher, $value);
  215. mcrypt_generic_deinit($cipher);
  216. $this->_closeCipher($cipher);
  217. return $encrypted;
  218. }
  219. /**
  220. * Defined by Zend_Filter_Interface
  221. *
  222. * Decrypts $value with the defined settings
  223. *
  224. * @param string $value Content to decrypt
  225. * @return string The decrypted content
  226. */
  227. public function decrypt($value)
  228. {
  229. $cipher = $this->_openCipher();
  230. $this->_initCipher($cipher);
  231. $decrypted = mdecrypt_generic($cipher, $value);
  232. mcrypt_generic_deinit($cipher);
  233. $this->_closeCipher($cipher);
  234. // decompress after decryption
  235. if (!empty($this->_compression)) {
  236. require_once 'Zend/Filter/Decompress.php';
  237. $decompress = new Zend_Filter_Decompress($this->_compression);
  238. $decrypted = $decompress->filter($decrypted);
  239. }
  240. return $decrypted;
  241. }
  242. /**
  243. * Returns the adapter name
  244. *
  245. * @return string
  246. */
  247. public function toString()
  248. {
  249. return 'Mcrypt';
  250. }
  251. /**
  252. * Open a cipher
  253. *
  254. * @throws Zend_Filter_Exception When the cipher can not be opened
  255. * @return resource Returns the opened cipher
  256. */
  257. protected function _openCipher()
  258. {
  259. $cipher = mcrypt_module_open(
  260. $this->_encryption['algorithm'],
  261. $this->_encryption['algorithm_directory'],
  262. $this->_encryption['mode'],
  263. $this->_encryption['mode_directory']);
  264. if ($cipher === false) {
  265. require_once 'Zend/Filter/Exception.php';
  266. throw new Zend_Filter_Exception('Mcrypt can not be opened with your settings');
  267. }
  268. return $cipher;
  269. }
  270. /**
  271. * Close a cipher
  272. *
  273. * @param resource $cipher Cipher to close
  274. * @return Zend_Filter_Encrypt_Mcrypt
  275. */
  276. protected function _closeCipher($cipher)
  277. {
  278. mcrypt_module_close($cipher);
  279. return $this;
  280. }
  281. /**
  282. * Initialises the cipher with the set key
  283. *
  284. * @param resource $cipher
  285. * @throws
  286. * @return resource
  287. */
  288. protected function _initCipher($cipher)
  289. {
  290. $key = $this->_encryption['key'];
  291. $keysizes = mcrypt_enc_get_supported_key_sizes($cipher);
  292. if (empty($keysizes) || ($this->_encryption['salt'] == true)) {
  293. $this->_srand();
  294. $keysize = mcrypt_enc_get_key_size($cipher);
  295. $key = substr(md5($key), 0, $keysize);
  296. } else if (!in_array(strlen($key), $keysizes)) {
  297. require_once 'Zend/Filter/Exception.php';
  298. throw new Zend_Filter_Exception('The given key has a wrong size for the set algorithm');
  299. }
  300. $result = mcrypt_generic_init($cipher, $key, $this->_encryption['vector']);
  301. if ($result < 0) {
  302. require_once 'Zend/Filter/Exception.php';
  303. throw new Zend_Filter_Exception('Mcrypt could not be initialize with the given setting');
  304. }
  305. return $this;
  306. }
  307. /**
  308. * _srand() interception
  309. *
  310. * @see ZF-8742
  311. */
  312. protected function _srand()
  313. {
  314. if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
  315. return;
  316. }
  317. if (!self::$_srandCalled) {
  318. srand((double) microtime() * 1000000);
  319. self::$_srandCalled = true;
  320. }
  321. }
  322. }