[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/include/Zend/Crypt/ -> DiffieHellman.php (source)

   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 [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_Crypt
  17   * @subpackage DiffieHellman
  18   * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  20   * @version    $Id: DiffieHellman.php 24593 2012-01-05 20:35:02Z matthew $
  21   */
  22  
  23  /**
  24   * PHP implementation of the Diffie-Hellman public key encryption algorithm.
  25   * Allows two unassociated parties to establish a joint shared secret key
  26   * to be used in encrypting subsequent communications.
  27   *
  28   * @category   Zend
  29   * @package    Zend_Crypt
  30   * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  31   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  32   */
  33  class Zend_Crypt_DiffieHellman
  34  {
  35  
  36      /**
  37       * Static flag to select whether to use PHP5.3's openssl extension
  38       * if available.
  39       *
  40       * @var boolean
  41       */
  42      public static $useOpenssl = true;
  43  
  44      /**
  45       * Default large prime number; required by the algorithm.
  46       *
  47       * @var string
  48       */
  49      private $_prime = null;
  50  
  51      /**
  52       * The default generator number. This number must be greater than 0 but
  53       * less than the prime number set.
  54       *
  55       * @var string
  56       */
  57      private $_generator = null;
  58  
  59      /**
  60       * A private number set by the local user. It's optional and will
  61       * be generated if not set.
  62       *
  63       * @var string
  64       */
  65      private $_privateKey = null;
  66  
  67      /**
  68       * BigInteger support object courtesy of Zend_Crypt_Math
  69       *
  70       * @var Zend_Crypt_Math_BigInteger
  71       */
  72      private $_math = null;
  73  
  74      /**
  75       * The public key generated by this instance after calling generateKeys().
  76       *
  77       * @var string
  78       */
  79      private $_publicKey = null;
  80  
  81      /**
  82       * The shared secret key resulting from a completed Diffie Hellman
  83       * exchange
  84       *
  85       * @var string
  86       */
  87      private $_secretKey = null;
  88  
  89      /**
  90       * Constants
  91       */
  92      const BINARY = 'binary';
  93      const NUMBER = 'number';
  94      const BTWOC  = 'btwoc';
  95  
  96      /**
  97       * Constructor; if set construct the object using the parameter array to
  98       * set values for Prime, Generator and Private.
  99       * If a Private Key is not set, one will be generated at random.
 100       *
 101       * @param string $prime
 102       * @param string $generator
 103       * @param string $privateKey
 104       * @param string $privateKeyType
 105       * @return void
 106       */
 107      public function __construct($prime, $generator, $privateKey = null, $privateKeyType = self::NUMBER)
 108      {
 109          $this->setPrime($prime);
 110          $this->setGenerator($generator);
 111          if ($privateKey !== null) {
 112              $this->setPrivateKey($privateKey, $privateKeyType);
 113          }
 114          $this->setBigIntegerMath();
 115      }
 116  
 117      /**
 118       * Generate own public key. If a private number has not already been
 119       * set, one will be generated at this stage.
 120       *
 121       * @return Zend_Crypt_DiffieHellman
 122       */
 123      public function generateKeys()
 124      {
 125          if (function_exists('openssl_dh_compute_key') && self::$useOpenssl !== false) {
 126              $details = array();
 127              $details['p'] = $this->getPrime();
 128              $details['g'] = $this->getGenerator();
 129              if ($this->hasPrivateKey()) {
 130                  $details['priv_key'] = $this->getPrivateKey();
 131              }
 132              $opensslKeyResource = openssl_pkey_new( array('dh' => $details) );
 133              $data = openssl_pkey_get_details($opensslKeyResource);
 134              $this->setPrivateKey($data['dh']['priv_key'], self::BINARY);
 135              $this->setPublicKey($data['dh']['pub_key'], self::BINARY);
 136          } else {
 137              // Private key is lazy generated in the absence of PHP 5.3's ext/openssl
 138              $publicKey = $this->_math->powmod($this->getGenerator(), $this->getPrivateKey(), $this->getPrime());
 139              $this->setPublicKey($publicKey);
 140          }
 141          return $this;
 142      }
 143  
 144      /**
 145       * Setter for the value of the public number
 146       *
 147       * @param string $number
 148       * @param string $type
 149       * @return Zend_Crypt_DiffieHellman
 150       */
 151      public function setPublicKey($number, $type = self::NUMBER)
 152      {
 153          if ($type == self::BINARY) {
 154              $number = $this->_math->fromBinary($number);
 155          }
 156          if (!preg_match("/^\d+$/", $number)) {
 157              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 158              throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number');
 159          }
 160          $this->_publicKey = (string) $number;
 161          return $this;
 162      }
 163  
 164      /**
 165       * Returns own public key for communication to the second party to this
 166       * transaction.
 167       *
 168       * @param string $type
 169       * @return string
 170       */
 171      public function getPublicKey($type = self::NUMBER)
 172      {
 173          if ($this->_publicKey === null) {
 174              require_once  'Zend/Crypt/DiffieHellman/Exception.php';
 175              throw new Zend_Crypt_DiffieHellman_Exception('A public key has not yet been generated using a prior call to generateKeys()');
 176          }
 177          if ($type == self::BINARY) {
 178              return $this->_math->toBinary($this->_publicKey);
 179          } elseif ($type == self::BTWOC) {
 180              return $this->_math->btwoc($this->_math->toBinary($this->_publicKey));
 181          }
 182          return $this->_publicKey;
 183      }
 184  
 185      /**
 186       * Compute the shared secret key based on the public key received from the
 187       * the second party to this transaction. This should agree to the secret
 188       * key the second party computes on our own public key.
 189       * Once in agreement, the key is known to only to both parties.
 190       * By default, the function expects the public key to be in binary form
 191       * which is the typical format when being transmitted.
 192       *
 193       * If you need the binary form of the shared secret key, call
 194       * getSharedSecretKey() with the optional parameter for Binary output.
 195       *
 196       * @param string $publicKey
 197       * @param string $type
 198       * @return mixed
 199       */
 200      public function computeSecretKey($publicKey, $type = self::NUMBER, $output = self::NUMBER)
 201      {
 202          if ($type == self::BINARY) {
 203              $publicKey = $this->_math->fromBinary($publicKey);
 204          }
 205          if (!preg_match("/^\d+$/", $publicKey)) {
 206              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 207              throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number');
 208          }
 209          if (function_exists('openssl_dh_compute_key') && self::$useOpenssl !== false) {
 210              $this->_secretKey = openssl_dh_compute_key($publicKey, $this->getPublicKey());
 211          } else {
 212              $this->_secretKey = $this->_math->powmod($publicKey, $this->getPrivateKey(), $this->getPrime());
 213          }
 214          return $this->getSharedSecretKey($output);
 215      }
 216  
 217      /**
 218       * Return the computed shared secret key from the DiffieHellman transaction
 219       *
 220       * @param string $type
 221       * @return string
 222       */
 223      public function getSharedSecretKey($type = self::NUMBER)
 224      {
 225          if (!isset($this->_secretKey)) {
 226              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 227              throw new Zend_Crypt_DiffieHellman_Exception('A secret key has not yet been computed; call computeSecretKey()');
 228          }
 229          if ($type == self::BINARY) {
 230              return $this->_math->toBinary($this->_secretKey);
 231          } elseif ($type == self::BTWOC) {
 232              return $this->_math->btwoc($this->_math->toBinary($this->_secretKey));
 233          }
 234          return $this->_secretKey;
 235      }
 236  
 237      /**
 238       * Setter for the value of the prime number
 239       *
 240       * @param string $number
 241       * @return Zend_Crypt_DiffieHellman
 242       */
 243      public function setPrime($number)
 244      {
 245          if (!preg_match("/^\d+$/", $number) || $number < 11) {
 246              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 247              throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number or too small: should be a large natural number prime');
 248          }
 249          $this->_prime = (string) $number;
 250          return $this;
 251      }
 252  
 253      /**
 254       * Getter for the value of the prime number
 255       *
 256       * @return string
 257       */
 258      public function getPrime()
 259      {
 260          if (!isset($this->_prime)) {
 261              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 262              throw new Zend_Crypt_DiffieHellman_Exception('No prime number has been set');
 263          }
 264          return $this->_prime;
 265      }
 266  
 267  
 268      /**
 269       * Setter for the value of the generator number
 270       *
 271       * @param string $number
 272       * @return Zend_Crypt_DiffieHellman
 273       */
 274      public function setGenerator($number)
 275      {
 276          if (!preg_match("/^\d+$/", $number) || $number < 2) {
 277              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 278              throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number greater than 1');
 279          }
 280          $this->_generator = (string) $number;
 281          return $this;
 282      }
 283  
 284      /**
 285       * Getter for the value of the generator number
 286       *
 287       * @return string
 288       */
 289      public function getGenerator()
 290      {
 291          if (!isset($this->_generator)) {
 292              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 293              throw new Zend_Crypt_DiffieHellman_Exception('No generator number has been set');
 294          }
 295          return $this->_generator;
 296      }
 297  
 298      /**
 299       * Setter for the value of the private number
 300       *
 301       * @param string $number
 302       * @param string $type
 303       * @return Zend_Crypt_DiffieHellman
 304       */
 305      public function setPrivateKey($number, $type = self::NUMBER)
 306      {
 307          if ($type == self::BINARY) {
 308              $number = $this->_math->fromBinary($number);
 309          }
 310          if (!preg_match("/^\d+$/", $number)) {
 311              require_once ('Zend/Crypt/DiffieHellman/Exception.php');
 312              throw new Zend_Crypt_DiffieHellman_Exception('invalid parameter; not a positive natural number');
 313          }
 314          $this->_privateKey = (string) $number;
 315          return $this;
 316      }
 317  
 318      /**
 319       * Getter for the value of the private number
 320       *
 321       * @param string $type
 322       * @return string
 323       */
 324      public function getPrivateKey($type = self::NUMBER)
 325      {
 326          if (!$this->hasPrivateKey()) {
 327              $this->setPrivateKey($this->_generatePrivateKey(), self::BINARY);
 328          }
 329          if ($type == self::BINARY) {
 330              return $this->_math->toBinary($this->_privateKey);
 331          } elseif ($type == self::BTWOC) {
 332              return $this->_math->btwoc($this->_math->toBinary($this->_privateKey));
 333          }
 334          return $this->_privateKey;
 335      }
 336  
 337      /**
 338       * Check whether a private key currently exists.
 339       *
 340       * @return boolean
 341       */
 342      public function hasPrivateKey()
 343      {
 344          return isset($this->_privateKey);
 345      }
 346  
 347      /**
 348       * Setter to pass an extension parameter which is used to create
 349       * a specific BigInteger instance for a specific extension type.
 350       * Allows manual setting of the class in case of an extension
 351       * problem or bug.
 352       *
 353       * @param string $extension
 354       * @return void
 355       */
 356      public function setBigIntegerMath($extension = null)
 357      {
 358          /**
 359           * @see Zend_Crypt_Math
 360           */
 361          require_once  'Zend/Crypt/Math.php';
 362          $this->_math = new Zend_Crypt_Math($extension);
 363      }
 364  
 365      /**
 366       * In the event a private number/key has not been set by the user,
 367       * or generated by ext/openssl, a best attempt will be made to
 368       * generate a random key. Having a random number generator installed
 369       * on linux/bsd is highly recommended! The alternative is not recommended
 370       * for production unless without any other option.
 371       *
 372       * @return string
 373       */
 374      protected function _generatePrivateKey()
 375      {
 376          $rand = $this->_math->rand($this->getGenerator(), $this->getPrime());
 377          return $rand;
 378      }
 379  
 380  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1