[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/ -> OpenSSH.php (source)

   1  <?php
   2  
   3  /**
   4   * OpenSSH Formatted EC Key Handler
   5   *
   6   * PHP version 5
   7   *
   8   * Place in $HOME/.ssh/authorized_keys
   9   *
  10   * @category  Crypt
  11   * @package   EC
  12   * @author    Jim Wigginton <[email protected]>
  13   * @copyright 2015 Jim Wigginton
  14   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  15   * @link      http://phpseclib.sourceforge.net
  16   */
  17  
  18  namespace phpseclib3\Crypt\EC\Formats\Keys;
  19  
  20  use phpseclib3\Common\Functions\Strings;
  21  use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
  22  use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
  23  use phpseclib3\Crypt\EC\Curves\Ed25519;
  24  use phpseclib3\Exception\UnsupportedCurveException;
  25  use phpseclib3\Math\BigInteger;
  26  
  27  /**
  28   * OpenSSH Formatted EC Key Handler
  29   *
  30   * @package EC
  31   * @author  Jim Wigginton <[email protected]>
  32   * @access  public
  33   */
  34  abstract class OpenSSH extends Progenitor
  35  {
  36      use Common;
  37  
  38      /**
  39       * Supported Key Types
  40       *
  41       * @var array
  42       */
  43      protected static $types = [
  44          'ecdsa-sha2-nistp256',
  45          'ecdsa-sha2-nistp384',
  46          'ecdsa-sha2-nistp521',
  47          'ssh-ed25519'
  48      ];
  49  
  50      /**
  51       * Break a public or private key down into its constituent components
  52       *
  53       * @access public
  54       * @param string $key
  55       * @param string $password optional
  56       * @return array
  57       */
  58      public static function load($key, $password = '')
  59      {
  60          $parsed = parent::load($key, $password);
  61  
  62          if (isset($parsed['paddedKey'])) {
  63              $paddedKey = $parsed['paddedKey'];
  64              list($type) = Strings::unpackSSH2('s', $paddedKey);
  65              if ($type != $parsed['type']) {
  66                  throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
  67              }
  68              if ($type == 'ssh-ed25519') {
  69                  list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey);
  70                  $key = libsodium::load($key);
  71                  $key['comment'] = $comment;
  72                  return $key;
  73              }
  74              list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey);
  75              $curve = self::loadCurveByParam(['namedCurve' => $curveName]);
  76              $curve->rangeCheck($privateKey);
  77              return [
  78                  'curve' => $curve,
  79                  'dA' => $privateKey,
  80                  'QA' => self::extractPoint("\0$publicKey", $curve),
  81                  'comment' => $comment
  82              ];
  83          }
  84  
  85          if ($parsed['type'] == 'ssh-ed25519') {
  86              if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") {
  87                  throw new \RuntimeException('Length of ssh-ed25519 key should be 32');
  88              }
  89  
  90              $curve = new Ed25519();
  91              $qa = self::extractPoint($parsed['publicKey'], $curve);
  92          } else {
  93              list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']);
  94              $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName;
  95              $curve = new $curveName();
  96  
  97              $qa = self::extractPoint("\0" . $publicKey, $curve);
  98          }
  99  
 100          return [
 101              'curve' => $curve,
 102              'QA' => $qa,
 103              'comment' => $parsed['comment']
 104          ];
 105      }
 106  
 107      /**
 108       * Returns the alias that corresponds to a curve
 109       *
 110       * @return string
 111       */
 112      private static function getAlias(BaseCurve $curve)
 113      {
 114          self::initialize_static_variables();
 115  
 116          $reflect = new \ReflectionClass($curve);
 117          $name = $reflect->getShortName();
 118  
 119          $oid = self::$curveOIDs[$name];
 120          $aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) {
 121              return $v == $oid;
 122          });
 123          $aliases = array_keys($aliases);
 124  
 125          for ($i = 0; $i < count($aliases); $i++) {
 126              if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) {
 127                  $alias = $aliases[$i];
 128                  break;
 129              }
 130          }
 131  
 132          if (!isset($alias)) {
 133              throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports');
 134          }
 135  
 136          return $alias;
 137      }
 138  
 139      /**
 140       * Convert an EC public key to the appropriate format
 141       *
 142       * @access public
 143       * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve
 144       * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
 145       * @param array $options optional
 146       * @return string
 147       */
 148      public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = [])
 149      {
 150          $comment = isset($options['comment']) ? $options['comment'] : self::$comment;
 151  
 152          if ($curve instanceof Ed25519) {
 153              $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey));
 154  
 155              if (isset($options['binary']) ? $options['binary'] : self::$binary) {
 156                  return $key;
 157              }
 158  
 159              $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment;
 160              return $key;
 161          }
 162  
 163          $alias = self::getAlias($curve);
 164  
 165          $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes();
 166          $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points);
 167  
 168          if (isset($options['binary']) ? $options['binary'] : self::$binary) {
 169              return $key;
 170          }
 171  
 172          $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment;
 173  
 174          return $key;
 175      }
 176  
 177      /**
 178       * Convert a private key to the appropriate format.
 179       *
 180       * @access public
 181       * @param \phpseclib3\Math\BigInteger $privateKey
 182       * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
 183       * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
 184       * @param string $password optional
 185       * @param array $options optional
 186       * @return string
 187       */
 188      public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = [])
 189      {
 190          if ($curve instanceof Ed25519) {
 191              if (!isset($privateKey->secret)) {
 192                  throw new \RuntimeException('Private Key does not have a secret set');
 193              }
 194              if (strlen($privateKey->secret) != 32) {
 195                  throw new \RuntimeException('Private Key secret is not of the correct length');
 196              }
 197  
 198              $pubKey = $curve->encodePoint($publicKey);
 199  
 200              $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey);
 201              $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $privateKey->secret . $pubKey);
 202  
 203              return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
 204          }
 205  
 206          $alias = self::getAlias($curve);
 207  
 208          $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes();
 209          $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]);
 210  
 211          $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey);
 212  
 213          return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
 214      }
 215  }


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