[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/ -> AsymmetricKey.php (source)

   1  <?php
   2  
   3  /**
   4   * Base Class for all asymmetric key ciphers
   5   *
   6   * PHP version 5
   7   *
   8   * @category  Crypt
   9   * @package   AsymmetricKey
  10   * @author    Jim Wigginton <[email protected]>
  11   * @copyright 2016 Jim Wigginton
  12   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  13   * @link      http://phpseclib.sourceforge.net
  14   */
  15  
  16  namespace phpseclib3\Crypt\Common;
  17  
  18  use phpseclib3\Crypt\DSA;
  19  use phpseclib3\Crypt\Hash;
  20  use phpseclib3\Crypt\RSA;
  21  use phpseclib3\Exception\NoKeyLoadedException;
  22  use phpseclib3\Exception\UnsupportedFormatException;
  23  use phpseclib3\Math\BigInteger;
  24  
  25  /**
  26   * Base Class for all asymmetric cipher classes
  27   *
  28   * @package AsymmetricKey
  29   * @author  Jim Wigginton <[email protected]>
  30   */
  31  abstract class AsymmetricKey
  32  {
  33      /**
  34       * Precomputed Zero
  35       *
  36       * @var \phpseclib3\Math\BigInteger
  37       * @access private
  38       */
  39      protected static $zero;
  40  
  41      /**
  42       * Precomputed One
  43       *
  44       * @var \phpseclib3\Math\BigInteger
  45       * @access private
  46       */
  47      protected static $one;
  48  
  49      /**
  50       * Format of the loaded key
  51       *
  52       * @var string
  53       * @access private
  54       */
  55      protected $format;
  56  
  57      /**
  58       * Hash function
  59       *
  60       * @var \phpseclib3\Crypt\Hash
  61       * @access private
  62       */
  63      protected $hash;
  64  
  65      /**
  66       * HMAC function
  67       *
  68       * @var \phpseclib3\Crypt\Hash
  69       * @access private
  70       */
  71      private $hmac;
  72  
  73      /**
  74       * Supported plugins (lower case)
  75       *
  76       * @see self::initialize_static_variables()
  77       * @var array
  78       * @access private
  79       */
  80      private static $plugins = [];
  81  
  82      /**
  83       * Invisible plugins
  84       *
  85       * @see self::initialize_static_variables()
  86       * @var array
  87       * @access private
  88       */
  89      private static $invisiblePlugins = [];
  90  
  91      /**
  92       * Supported signature formats (lower case)
  93       *
  94       * @see self::initialize_static_variables()
  95       * @var array
  96       * @access private
  97       */
  98      private static $signatureFormats = [];
  99  
 100      /**
 101       * Supported signature formats (original case)
 102       *
 103       * @see self::initialize_static_variables()
 104       * @var array
 105       * @access private
 106       */
 107      private static $signatureFileFormats = [];
 108  
 109      /**
 110       * Available Engines
 111       *
 112       * @var boolean[]
 113       * @access private
 114       */
 115      protected static $engines = [];
 116  
 117      /**
 118       * Key Comment
 119       *
 120       * @var null|string
 121       * @access private
 122       */
 123      private $comment;
 124  
 125      /**
 126       * @param string $type
 127       * @return string
 128       */
 129      abstract public function toString($type, array $options = []);
 130  
 131      /**
 132       * The constructor
 133       */
 134      protected function __construct()
 135      {
 136          self::initialize_static_variables();
 137  
 138          $this->hash = new Hash('sha256');
 139          $this->hmac = new Hash('sha256');
 140      }
 141  
 142      /**
 143       * Initialize static variables
 144       */
 145      protected static function initialize_static_variables()
 146      {
 147          if (!isset(self::$zero)) {
 148              self::$zero = new BigInteger(0);
 149              self::$one = new BigInteger(1);
 150          }
 151  
 152          self::loadPlugins('Keys');
 153          if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') {
 154              self::loadPlugins('Signature');
 155          }
 156      }
 157  
 158      /**
 159       * Load the key
 160       *
 161       * @param string $key
 162       * @param string $password optional
 163       * @return AsymmetricKey
 164       */
 165      public static function load($key, $password = false)
 166      {
 167          self::initialize_static_variables();
 168  
 169          $components = false;
 170          foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) {
 171              if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) {
 172                  continue;
 173              }
 174              try {
 175                  $components = $format::load($key, $password);
 176              } catch (\Exception $e) {
 177                  $components = false;
 178              }
 179              if ($components !== false) {
 180                  break;
 181              }
 182          }
 183  
 184          if ($components === false) {
 185              throw new NoKeyLoadedException('Unable to read key');
 186          }
 187  
 188          $components['format'] = $format;
 189          $comment = isset($components['comment']) ? $components['comment'] : null;
 190          $new = static::onLoad($components);
 191          $new->format = $format;
 192          $new->comment = $comment;
 193          return $new instanceof PrivateKey ?
 194              $new->withPassword($password) :
 195              $new;
 196      }
 197  
 198      /**
 199       * Loads a private key
 200       *
 201       * @return PrivateKey
 202       * @access public
 203       * @param string|array $key
 204       * @param string $password optional
 205       */
 206      public static function loadPrivateKey($key, $password = '')
 207      {
 208          $key = self::load($key, $password);
 209          if (!$key instanceof PrivateKey) {
 210              throw new NoKeyLoadedException('The key that was loaded was not a private key');
 211          }
 212          return $key;
 213      }
 214  
 215      /**
 216       * Loads a public key
 217       *
 218       * @return PublicKey
 219       * @access public
 220       * @param string|array $key
 221       */
 222      public static function loadPublicKey($key)
 223      {
 224          $key = self::load($key);
 225          if (!$key instanceof PublicKey) {
 226              throw new NoKeyLoadedException('The key that was loaded was not a public key');
 227          }
 228          return $key;
 229      }
 230  
 231      /**
 232       * Loads parameters
 233       *
 234       * @return AsymmetricKey
 235       * @access public
 236       * @param string|array $key
 237       */
 238      public static function loadParameters($key)
 239      {
 240          $key = self::load($key);
 241          if (!$key instanceof PrivateKey && !$key instanceof PublicKey) {
 242              throw new NoKeyLoadedException('The key that was loaded was not a parameter');
 243          }
 244          return $key;
 245      }
 246  
 247      /**
 248       * Load the key, assuming a specific format
 249       *
 250       * @param string $type
 251       * @param string $key
 252       * @param string $password optional
 253       * @return static
 254       */
 255      public static function loadFormat($type, $key, $password = false)
 256      {
 257          self::initialize_static_variables();
 258  
 259          $components = false;
 260          $format = strtolower($type);
 261          if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) {
 262              $format = self::$plugins[static::ALGORITHM]['Keys'][$format];
 263              $components = $format::load($key, $password);
 264          }
 265  
 266          if ($components === false) {
 267              throw new NoKeyLoadedException('Unable to read key');
 268          }
 269  
 270          $components['format'] = $format;
 271  
 272          $new = static::onLoad($components);
 273          $new->format = $format;
 274          return $new instanceof PrivateKey ?
 275              $new->withPassword($password) :
 276              $new;
 277      }
 278  
 279      /**
 280       * Loads a private key
 281       *
 282       * @return PrivateKey
 283       * @access public
 284       * @param string $type
 285       * @param string $key
 286       * @param string $password optional
 287       */
 288      public static function loadPrivateKeyFormat($type, $key, $password = false)
 289      {
 290          $key = self::loadFormat($type, $key, $password);
 291          if (!$key instanceof PrivateKey) {
 292              throw new NoKeyLoadedException('The key that was loaded was not a private key');
 293          }
 294          return $key;
 295      }
 296  
 297      /**
 298       * Loads a public key
 299       *
 300       * @return PublicKey
 301       * @access public
 302       * @param string $type
 303       * @param string $key
 304       */
 305      public static function loadPublicKeyFormat($type, $key)
 306      {
 307          $key = self::loadFormat($type, $key);
 308          if (!$key instanceof PublicKey) {
 309              throw new NoKeyLoadedException('The key that was loaded was not a public key');
 310          }
 311          return $key;
 312      }
 313  
 314      /**
 315       * Loads parameters
 316       *
 317       * @return AsymmetricKey
 318       * @access public
 319       * @param string $type
 320       * @param string|array $key
 321       */
 322      public static function loadParametersFormat($type, $key)
 323      {
 324          $key = self::loadFormat($type, $key);
 325          if (!$key instanceof PrivateKey && !$key instanceof PublicKey) {
 326              throw new NoKeyLoadedException('The key that was loaded was not a parameter');
 327          }
 328          return $key;
 329      }
 330  
 331      /**
 332       * Validate Plugin
 333       *
 334       * @access private
 335       * @param string $format
 336       * @param string $type
 337       * @param string $method optional
 338       * @return mixed
 339       */
 340      protected static function validatePlugin($format, $type, $method = null)
 341      {
 342          $type = strtolower($type);
 343          if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) {
 344              throw new UnsupportedFormatException("$type is not a supported format");
 345          }
 346          $type = self::$plugins[static::ALGORITHM][$format][$type];
 347          if (isset($method) && !method_exists($type, $method)) {
 348              throw new UnsupportedFormatException("$type does not implement $method");
 349          }
 350  
 351          return $type;
 352      }
 353  
 354      /**
 355       * Load Plugins
 356       *
 357       * @access private
 358       * @param string $format
 359       */
 360      private static function loadPlugins($format)
 361      {
 362          if (!isset(self::$plugins[static::ALGORITHM][$format])) {
 363              self::$plugins[static::ALGORITHM][$format] = [];
 364              foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) {
 365                  if ($file->getExtension() != 'php') {
 366                      continue;
 367                  }
 368                  $name = $file->getBasename('.php');
 369                  if ($name[0] == '.') {
 370                      continue;
 371                  }
 372                  $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name;
 373                  $reflect = new \ReflectionClass($type);
 374                  if ($reflect->isTrait()) {
 375                      continue;
 376                  }
 377                  self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type;
 378                  if ($reflect->hasConstant('IS_INVISIBLE')) {
 379                      self::$invisiblePlugins[static::ALGORITHM][] = $type;
 380                  }
 381              }
 382          }
 383      }
 384  
 385      /**
 386       * Returns a list of supported formats.
 387       *
 388       * @access public
 389       * @return array
 390       */
 391      public static function getSupportedKeyFormats()
 392      {
 393          self::initialize_static_variables();
 394  
 395          return self::$plugins[static::ALGORITHM]['Keys'];
 396      }
 397  
 398      /**
 399       * Add a fileformat plugin
 400       *
 401       * The plugin needs to either already be loaded or be auto-loadable.
 402       * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin.
 403       *
 404       * @see self::load()
 405       * @param string $fullname
 406       * @access public
 407       * @return bool
 408       */
 409      public static function addFileFormat($fullname)
 410      {
 411          self::initialize_static_variables();
 412  
 413          if (class_exists($fullname)) {
 414              $meta = new \ReflectionClass($fullname);
 415              $shortname = $meta->getShortName();
 416              self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname;
 417              if ($meta->hasConstant('IS_INVISIBLE')) {
 418                  self::$invisiblePlugins[static::ALGORITHM] = strtolower($name);
 419              }
 420          }
 421      }
 422  
 423      /**
 424       * Returns the format of the loaded key.
 425       *
 426       * If the key that was loaded wasn't in a valid or if the key was auto-generated
 427       * with RSA::createKey() then this will throw an exception.
 428       *
 429       * @see self::load()
 430       * @access public
 431       * @return mixed
 432       */
 433      public function getLoadedFormat()
 434      {
 435          if (empty($this->format)) {
 436              throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"');
 437          }
 438  
 439          $meta = new \ReflectionClass($this->format);
 440          return $meta->getShortName();
 441      }
 442  
 443      /**
 444       * Returns the key's comment
 445       *
 446       * Not all key formats support comments. If you want to set a comment use toString()
 447       *
 448       * @access public
 449       * @return null|string
 450       */
 451      public function getComment()
 452      {
 453          return $this->comment;
 454      }
 455  
 456      /**
 457       * Tests engine validity
 458       *
 459       * @access public
 460       */
 461      public static function useBestEngine()
 462      {
 463          static::$engines = [
 464              'PHP' => true,
 465              'OpenSSL' => extension_loaded('openssl'),
 466              // this test can be satisfied by either of the following:
 467              // http://php.net/manual/en/book.sodium.php
 468              // https://github.com/paragonie/sodium_compat
 469              'libsodium' => function_exists('sodium_crypto_sign_keypair')
 470          ];
 471  
 472          return static::$engines;
 473      }
 474  
 475      /**
 476       * Flag to use internal engine only (useful for unit testing)
 477       *
 478       * @access public
 479       */
 480      public static function useInternalEngine()
 481      {
 482          static::$engines = [
 483              'PHP' => true,
 484              'OpenSSL' => false,
 485              'libsodium' => false
 486          ];
 487      }
 488  
 489      /**
 490       * __toString() magic method
 491       *
 492       * @return string
 493       */
 494      public function __toString()
 495      {
 496          return $this->toString('PKCS8');
 497      }
 498  
 499      /**
 500       * Determines which hashing function should be used
 501       *
 502       * @access public
 503       * @param string $hash
 504       */
 505      public function withHash($hash)
 506      {
 507          $new = clone $this;
 508  
 509          $new->hash = new Hash($hash);
 510          $new->hmac = new Hash($hash);
 511  
 512          return $new;
 513      }
 514  
 515      /**
 516       * Returns the hash algorithm currently being used
 517       *
 518       * @access public
 519       */
 520      public function getHash()
 521      {
 522          return clone $this->hash;
 523      }
 524  
 525      /**
 526       * Compute the pseudorandom k for signature generation,
 527       * using the process specified for deterministic DSA.
 528       *
 529       * @access public
 530       * @param string $h1
 531       * @return string
 532       */
 533      protected function computek($h1)
 534      {
 535          $v = str_repeat("\1", strlen($h1));
 536  
 537          $k = str_repeat("\0", strlen($h1));
 538  
 539          $x = $this->int2octets($this->x);
 540          $h1 = $this->bits2octets($h1);
 541  
 542          $this->hmac->setKey($k);
 543          $k = $this->hmac->hash($v . "\0" . $x . $h1);
 544          $this->hmac->setKey($k);
 545          $v = $this->hmac->hash($v);
 546          $k = $this->hmac->hash($v . "\1" . $x . $h1);
 547          $this->hmac->setKey($k);
 548          $v = $this->hmac->hash($v);
 549  
 550          $qlen = $this->q->getLengthInBytes();
 551  
 552          while (true) {
 553              $t = '';
 554              while (strlen($t) < $qlen) {
 555                  $v = $this->hmac->hash($v);
 556                  $t = $t . $v;
 557              }
 558              $k = $this->bits2int($t);
 559  
 560              if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) {
 561                  break;
 562              }
 563              $k = $this->hmac->hash($v . "\0");
 564              $this->hmac->setKey($k);
 565              $v = $this->hmac->hash($v);
 566          }
 567  
 568          return $k;
 569      }
 570  
 571      /**
 572       * Integer to Octet String
 573       *
 574       * @access private
 575       * @param \phpseclib3\Math\BigInteger $v
 576       * @return string
 577       */
 578      private function int2octets($v)
 579      {
 580          $out = $v->toBytes();
 581          $rolen = $this->q->getLengthInBytes();
 582          if (strlen($out) < $rolen) {
 583              return str_pad($out, $rolen, "\0", STR_PAD_LEFT);
 584          } elseif (strlen($out) > $rolen) {
 585              return substr($out, -$rolen);
 586          } else {
 587              return $out;
 588          }
 589      }
 590  
 591      /**
 592       * Bit String to Integer
 593       *
 594       * @access private
 595       * @param string $in
 596       * @return \phpseclib3\Math\BigInteger
 597       */
 598      protected function bits2int($in)
 599      {
 600          $v = new BigInteger($in, 256);
 601          $vlen = strlen($in) << 3;
 602          $qlen = $this->q->getLength();
 603          if ($vlen > $qlen) {
 604              return $v->bitwise_rightShift($vlen - $qlen);
 605          }
 606          return $v;
 607      }
 608  
 609      /**
 610       * Bit String to Octet String
 611       *
 612       * @access private
 613       * @param string $in
 614       * @return string
 615       */
 616      private function bits2octets($in)
 617      {
 618          $z1 = $this->bits2int($in);
 619          $z2 = $z1->subtract($this->q);
 620          return $z2->compare(self::$zero) < 0 ?
 621              $this->int2octets($z1) :
 622              $this->int2octets($z2);
 623      }
 624  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer