File indexing completed on 2024-12-22 05:36:34

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Crypt
0017  * @subpackage Rsa
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Crypt_Rsa_Key_Private
0025  */
0026 // require_once 'Zend/Crypt/Rsa/Key/Private.php';
0027 
0028 /**
0029  * @see Zend_Crypt_Rsa_Key_Public
0030  */
0031 // require_once 'Zend/Crypt/Rsa/Key/Public.php';
0032 
0033 /**
0034  * @category   Zend
0035  * @package    Zend_Crypt
0036  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0037  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0038  */
0039 class Zend_Crypt_Rsa
0040 {
0041 
0042     const BINARY = 'binary';
0043     const BASE64 = 'base64';
0044 
0045     protected $_privateKey;
0046 
0047     protected $_publicKey;
0048 
0049     /**
0050      * @var string
0051      */
0052     protected $_pemString;
0053 
0054     protected $_pemPath;
0055 
0056     protected $_certificateString;
0057 
0058     protected $_certificatePath;
0059 
0060     protected $_hashAlgorithm;
0061 
0062     protected $_passPhrase;
0063 
0064     /**
0065      * Class constructor
0066      *
0067      * @param array $options
0068      * @throws Zend_Crypt_Rsa_Exception
0069      */
0070     public function __construct(array $options = null)
0071     {
0072         if (!extension_loaded('openssl')) {
0073             // require_once 'Zend/Crypt/Rsa/Exception.php';
0074             throw new Zend_Crypt_Rsa_Exception('Zend_Crypt_Rsa requires openssl extension to be loaded.');
0075         }
0076 
0077         // Set _hashAlgorithm property when we are sure, that openssl extension is loaded
0078         // and OPENSSL_ALGO_SHA1 constant is available
0079         $this->_hashAlgorithm = OPENSSL_ALGO_SHA1;
0080 
0081         if (isset($options)) {
0082             $this->setOptions($options);
0083         }
0084     }
0085 
0086     public function setOptions(array $options)
0087     {
0088         if (isset($options['passPhrase'])) {
0089             $this->_passPhrase = $options['passPhrase'];
0090         }
0091         foreach ($options as $option=>$value) {
0092             switch ($option) {
0093                 case 'pemString':
0094                     $this->setPemString($value);
0095                     break;
0096                 case 'pemPath':
0097                     $this->setPemPath($value);
0098                     break;
0099                 case 'certificateString':
0100                     $this->setCertificateString($value);
0101                     break;
0102                 case 'certificatePath':
0103                     $this->setCertificatePath($value);
0104                     break;
0105                 case 'hashAlgorithm':
0106                     $this->setHashAlgorithm($value);
0107                     break;
0108             }
0109         }
0110     }
0111 
0112     public function getPrivateKey()
0113     {
0114         return $this->_privateKey;
0115     }
0116 
0117     public function getPublicKey()
0118     {
0119         return $this->_publicKey;
0120     }
0121 
0122     /**
0123      * @param string $data
0124      * @param Zend_Crypt_Rsa_Key_Private $privateKey
0125      * @param string $format
0126      * @return string
0127      */
0128     public function sign($data, Zend_Crypt_Rsa_Key_Private $privateKey = null, $format = null)
0129     {
0130         $signature = '';
0131         if (isset($privateKey)) {
0132             $opensslKeyResource = $privateKey->getOpensslKeyResource();
0133         } else {
0134             $opensslKeyResource = $this->_privateKey->getOpensslKeyResource();
0135         }
0136         $result = openssl_sign(
0137             $data, $signature,
0138             $opensslKeyResource,
0139             $this->getHashAlgorithm()
0140         );
0141         if ($format == self::BASE64) {
0142             return base64_encode($signature);
0143         }
0144         return $signature;
0145     }
0146 
0147     /**
0148      * @param string $data
0149      * @param string $signature
0150      * @param string $format
0151      * @return string
0152      */
0153     public function verifySignature($data, $signature, $format = null)
0154     {
0155         if ($format == self::BASE64) {
0156             $signature = base64_decode($signature);
0157         }
0158         $result = openssl_verify($data, $signature,
0159             $this->getPublicKey()->getOpensslKeyResource(),
0160             $this->getHashAlgorithm());
0161         return $result;
0162     }
0163 
0164     /**
0165      * @param string $data
0166      * @param Zend_Crypt_Rsa_Key $key
0167      * @param string $format
0168      * @return string
0169      */
0170     public function encrypt($data, Zend_Crypt_Rsa_Key $key, $format = null)
0171     {
0172         $encrypted = '';
0173         $function = 'openssl_public_encrypt';
0174         if ($key instanceof Zend_Crypt_Rsa_Key_Private) {
0175             $function = 'openssl_private_encrypt';
0176         }
0177         $function($data, $encrypted, $key->getOpensslKeyResource());
0178         if ($format == self::BASE64) {
0179             return base64_encode($encrypted);
0180         }
0181         return $encrypted;
0182     }
0183 
0184     /**
0185      * @param string $data
0186      * @param Zend_Crypt_Rsa_Key $key
0187      * @param string $format
0188      * @return string
0189      */
0190     public function decrypt($data, Zend_Crypt_Rsa_Key $key, $format = null)
0191     {
0192         $decrypted = '';
0193         if ($format == self::BASE64) {
0194             $data = base64_decode($data);
0195         }
0196         $function = 'openssl_private_decrypt';
0197         if ($key instanceof Zend_Crypt_Rsa_Key_Public) {
0198             $function = 'openssl_public_decrypt';
0199         }
0200         $function($data, $decrypted, $key->getOpensslKeyResource());
0201         return $decrypted;
0202     }
0203 
0204     /**
0205      * @param  array $configargs
0206      * 
0207      * @throws Zend_Crypt_Rsa_Exception
0208      * 
0209      * @return ArrayObject
0210      */
0211     public function generateKeys(array $configargs = null)
0212     {
0213         $config = null;
0214         $passPhrase = null;
0215         if ($configargs !== null) {
0216             if (isset($configargs['passPhrase'])) {
0217                 $passPhrase = $configargs['passPhrase'];
0218                 unset($configargs['passPhrase']);
0219             }
0220             $config = $this->_parseConfigArgs($configargs);
0221         }
0222         $privateKey = null;
0223         $publicKey = null;
0224         $resource = openssl_pkey_new($config);
0225         if (!$resource) {
0226             // require_once 'Zend/Crypt/Rsa/Exception.php';
0227             throw new Zend_Crypt_Rsa_Exception('Failed to generate a new private key');
0228         }
0229         // above fails on PHP 5.3
0230         openssl_pkey_export($resource, $private, $passPhrase);
0231         $privateKey = new Zend_Crypt_Rsa_Key_Private($private, $passPhrase);
0232         $details = openssl_pkey_get_details($resource);
0233         $publicKey = new Zend_Crypt_Rsa_Key_Public($details['key']);
0234         $return = new ArrayObject(array(
0235            'privateKey'=>$privateKey,
0236            'publicKey'=>$publicKey
0237         ), ArrayObject::ARRAY_AS_PROPS);
0238         return $return;
0239     }
0240 
0241     /**
0242      * @param string $value
0243      */
0244     public function setPemString($value)
0245     {
0246         $this->_pemString = $value;
0247         try {
0248             $this->_privateKey = new Zend_Crypt_Rsa_Key_Private($this->_pemString, $this->_passPhrase);
0249             $this->_publicKey = $this->_privateKey->getPublicKey();
0250         } catch (Zend_Crypt_Exception $e) {
0251             $this->_privateKey = null;
0252             $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_pemString);
0253         }
0254     }
0255 
0256     public function setPemPath($value)
0257     {
0258         $this->_pemPath = $value;
0259         $this->setPemString(file_get_contents($this->_pemPath));
0260     }
0261 
0262     public function setCertificateString($value)
0263     {
0264         $this->_certificateString = $value;
0265         $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_certificateString, $this->_passPhrase);
0266     }
0267 
0268     public function setCertificatePath($value)
0269     {
0270         $this->_certificatePath = $value;
0271         $this->setCertificateString(file_get_contents($this->_certificatePath));
0272     }
0273 
0274     public function setHashAlgorithm($name)
0275     {
0276         switch (strtolower($name)) {
0277             case 'md2':
0278                 $this->_hashAlgorithm = OPENSSL_ALGO_MD2;
0279                 break;
0280             case 'md4':
0281                 $this->_hashAlgorithm = OPENSSL_ALGO_MD4;
0282                 break;
0283             case 'md5':
0284                 $this->_hashAlgorithm = OPENSSL_ALGO_MD5;
0285                 break;
0286             case 'sha1':
0287                 $this->_hashAlgorithm = OPENSSL_ALGO_SHA1;
0288                 break;
0289             case 'dss1':
0290                 $this->_hashAlgorithm = OPENSSL_ALGO_DSS1;
0291                 break;
0292         }
0293     }
0294 
0295     /**
0296      * @return string
0297      */
0298     public function getPemString()
0299     {
0300         return $this->_pemString;
0301     }
0302 
0303     public function getPemPath()
0304     {
0305         return $this->_pemPath;
0306     }
0307 
0308     public function getCertificateString()
0309     {
0310         return $this->_certificateString;
0311     }
0312 
0313     public function getCertificatePath()
0314     {
0315         return $this->_certificatePath;
0316     }
0317 
0318     public function getHashAlgorithm()
0319     {
0320         return $this->_hashAlgorithm;
0321     }
0322 
0323     protected function _parseConfigArgs(array $config = null)
0324     {
0325         $configs = array();
0326         if (isset($config['private_key_bits'])) {
0327             $configs['private_key_bits'] = $config['private_key_bits'];
0328         }
0329         if (isset($config['privateKeyBits'])) {
0330             $configs['private_key_bits'] = $config['privateKeyBits'];
0331         }
0332         if (!empty($configs)) {
0333             return $configs;
0334         }
0335         return null;
0336     }
0337 
0338 }