diff options
Diffstat (limited to 'library/vendor/Zend/Filter/Encrypt/Openssl.php')
-rw-r--r-- | library/vendor/Zend/Filter/Encrypt/Openssl.php | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/library/vendor/Zend/Filter/Encrypt/Openssl.php b/library/vendor/Zend/Filter/Encrypt/Openssl.php new file mode 100644 index 0000000..7a46b8e --- /dev/null +++ b/library/vendor/Zend/Filter/Encrypt/Openssl.php @@ -0,0 +1,480 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Filter + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * @see Zend_Filter_Encrypt_Interface + */ + +/** + * Encryption adapter for openssl + * + * @category Zend + * @package Zend_Filter + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface +{ + /** + * Definitions for encryption + * array( + * 'public' => public keys + * 'private' => private keys + * 'envelope' => resulting envelope keys + * ) + */ + protected $_keys = array( + 'public' => array(), + 'private' => array(), + 'envelope' => array() + ); + + /** + * Internal passphrase + * + * @var string + */ + protected $_passphrase; + + /** + * Internal compression + * + * @var array + */ + protected $_compression; + + /** + * Internal create package + * + * @var boolean + */ + protected $_package = false; + + /** + * Class constructor + * Available options + * 'public' => public key + * 'private' => private key + * 'envelope' => envelope key + * 'passphrase' => passphrase + * 'compression' => compress value with this compression adapter + * 'package' => pack envelope keys into encrypted string, simplifies decryption + * + * @param string|array $options Options for this adapter + */ + public function __construct($options = array()) + { + if (!extension_loaded('openssl')) { + throw new Zend_Filter_Exception('This filter needs the openssl extension'); + } + + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } + + if (!is_array($options)) { + $options = array('public' => $options); + } + + if (array_key_exists('passphrase', $options)) { + $this->setPassphrase($options['passphrase']); + unset($options['passphrase']); + } + + if (array_key_exists('compression', $options)) { + $this->setCompression($options['compression']); + unset($options['compress']); + } + + if (array_key_exists('package', $options)) { + $this->setPackage($options['package']); + unset($options['package']); + } + + $this->_setKeys($options); + } + + /** + * Sets the encryption keys + * + * @param string|array $keys Key with type association + * @return Zend_Filter_Encrypt_Openssl + */ + protected function _setKeys($keys) + { + if (!is_array($keys)) { + throw new Zend_Filter_Exception('Invalid options argument provided to filter'); + } + + foreach ($keys as $type => $key) { + if (ctype_print($key) && is_file(realpath($key)) && is_readable($key)) { + $file = fopen($key, 'r'); + $cert = fread($file, 8192); + fclose($file); + } else { + $cert = $key; + $key = count($this->_keys[$type]); + } + + switch ($type) { + case 'public': + $test = openssl_pkey_get_public($cert); + if ($test === false) { + throw new Zend_Filter_Exception("Public key '{$cert}' not valid"); + } + + openssl_free_key($test); + $this->_keys['public'][$key] = $cert; + break; + case 'private': + $test = openssl_pkey_get_private($cert, $this->_passphrase); + if ($test === false) { + throw new Zend_Filter_Exception("Private key '{$cert}' not valid"); + } + + openssl_free_key($test); + $this->_keys['private'][$key] = $cert; + break; + case 'envelope': + $this->_keys['envelope'][$key] = $cert; + break; + default: + break; + } + } + + return $this; + } + + /** + * Returns all public keys + * + * @return array + */ + public function getPublicKey() + { + $key = $this->_keys['public']; + return $key; + } + + /** + * Sets public keys + * + * @param string|array $key Public keys + * @return Zend_Filter_Encrypt_Openssl + */ + public function setPublicKey($key) + { + if (is_array($key)) { + foreach($key as $type => $option) { + if ($type !== 'public') { + $key['public'] = $option; + unset($key[$type]); + } + } + } else { + $key = array('public' => $key); + } + + return $this->_setKeys($key); + } + + /** + * Returns all private keys + * + * @return array + */ + public function getPrivateKey() + { + $key = $this->_keys['private']; + return $key; + } + + /** + * Sets private keys + * + * @param string $key Private key + * @param string $passphrase + * @return Zend_Filter_Encrypt_Openssl + */ + public function setPrivateKey($key, $passphrase = null) + { + if (is_array($key)) { + foreach($key as $type => $option) { + if ($type !== 'private') { + $key['private'] = $option; + unset($key[$type]); + } + } + } else { + $key = array('private' => $key); + } + + if ($passphrase !== null) { + $this->setPassphrase($passphrase); + } + + return $this->_setKeys($key); + } + + /** + * Returns all envelope keys + * + * @return array + */ + public function getEnvelopeKey() + { + $key = $this->_keys['envelope']; + return $key; + } + + /** + * Sets envelope keys + * + * @param string|array $options Envelope keys + * @return Zend_Filter_Encrypt_Openssl + */ + public function setEnvelopeKey($key) + { + if (is_array($key)) { + foreach($key as $type => $option) { + if ($type !== 'envelope') { + $key['envelope'] = $option; + unset($key[$type]); + } + } + } else { + $key = array('envelope' => $key); + } + + return $this->_setKeys($key); + } + + /** + * Returns the passphrase + * + * @return string + */ + public function getPassphrase() + { + return $this->_passphrase; + } + + /** + * Sets a new passphrase + * + * @param string $passphrase + * @return Zend_Filter_Encrypt_Openssl + */ + public function setPassphrase($passphrase) + { + $this->_passphrase = $passphrase; + return $this; + } + + /** + * Returns the compression + * + * @return array + */ + public function getCompression() + { + return $this->_compression; + } + + /** + * Sets a internal compression for values to encrypt + * + * @param string|array $compression + * @return Zend_Filter_Encrypt_Openssl + */ + public function setCompression($compression) + { + if (is_string($this->_compression)) { + $compression = array('adapter' => $compression); + } + + $this->_compression = $compression; + return $this; + } + + /** + * Returns if header should be packaged + * + * @return boolean + */ + public function getPackage() + { + return $this->_package; + } + + /** + * Sets if the envelope keys should be included in the encrypted value + * + * @param boolean $package + * @return Zend_Filter_Encrypt_Openssl + */ + public function setPackage($package) + { + $this->_package = (boolean) $package; + return $this; + } + + /** + * Encrypts $value with the defined settings + * Note that you also need the "encrypted" keys to be able to decrypt + * + * @param string $value Content to encrypt + * @return string The encrypted content + * @throws Zend_Filter_Exception + */ + public function encrypt($value) + { + $encrypted = array(); + $encryptedkeys = array(); + + if (count($this->_keys['public']) == 0) { + throw new Zend_Filter_Exception('Openssl can not encrypt without public keys'); + } + + $keys = array(); + $fingerprints = array(); + $count = -1; + foreach($this->_keys['public'] as $key => $cert) { + $keys[$key] = openssl_pkey_get_public($cert); + if ($this->_package) { + $details = openssl_pkey_get_details($keys[$key]); + if ($details === false) { + $details = array('key' => 'ZendFramework'); + } + + ++$count; + $fingerprints[$count] = md5($details['key']); + } + } + + // compress prior to encryption + if (!empty($this->_compression)) { + $compress = new Zend_Filter_Compress($this->_compression); + $value = $compress->filter($value); + } + + $crypt = openssl_seal($value, $encrypted, $encryptedkeys, $keys); + foreach ($keys as $key) { + openssl_free_key($key); + } + + if ($crypt === false) { + throw new Zend_Filter_Exception('Openssl was not able to encrypt your content with the given options'); + } + + $this->_keys['envelope'] = $encryptedkeys; + + // Pack data and envelope keys into single string + if ($this->_package) { + $header = pack('n', count($this->_keys['envelope'])); + foreach($this->_keys['envelope'] as $key => $envKey) { + $header .= pack('H32n', $fingerprints[$key], strlen($envKey)) . $envKey; + } + + $encrypted = $header . $encrypted; + } + + return $encrypted; + } + + /** + * Defined by Zend_Filter_Interface + * + * Decrypts $value with the defined settings + * + * @param string $value Content to decrypt + * @return string The decrypted content + * @throws Zend_Filter_Exception + */ + public function decrypt($value) + { + $decrypted = ""; + $envelope = current($this->getEnvelopeKey()); + + if (count($this->_keys['private']) !== 1) { + throw new Zend_Filter_Exception('Please give a private key for decryption with Openssl'); + } + + if (!$this->_package && empty($envelope)) { + throw new Zend_Filter_Exception('Please give a envelope key for decryption with Openssl'); + } + + foreach($this->_keys['private'] as $key => $cert) { + $keys = openssl_pkey_get_private($cert, $this->getPassphrase()); + } + + if ($this->_package) { + $details = openssl_pkey_get_details($keys); + if ($details !== false) { + $fingerprint = md5($details['key']); + } else { + $fingerprint = md5("ZendFramework"); + } + + $count = unpack('ncount', $value); + $count = $count['count']; + $length = 2; + for($i = $count; $i > 0; --$i) { + $header = unpack('H32print/nsize', substr($value, $length, 18)); + $length += 18; + if ($header['print'] == $fingerprint) { + $envelope = substr($value, $length, $header['size']); + } + + $length += $header['size']; + } + + // remainder of string is the value to decrypt + $value = substr($value, $length); + } + + $crypt = openssl_open($value, $decrypted, $envelope, $keys); + openssl_free_key($keys); + + if ($crypt === false) { + throw new Zend_Filter_Exception('Openssl was not able to decrypt you content with the given options'); + } + + // decompress after decryption + if (!empty($this->_compression)) { + $decompress = new Zend_Filter_Decompress($this->_compression); + $decrypted = $decompress->filter($decrypted); + } + + return $decrypted; + } + + /** + * Returns the adapter name + * + * @return string + */ + public function toString() + { + return 'Openssl'; + } +} |