[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/ -> Identity.php (source)

   1  <?php
   2  
   3  /**
   4   * Pure-PHP ssh-agent client.
   5   *
   6   * {@internal See http://api.libssh.org/rfc/PROTOCOL.agent}
   7   *
   8   * PHP version 5
   9   *
  10   * @category  System
  11   * @package   SSH\Agent
  12   * @author    Jim Wigginton <[email protected]>
  13   * @copyright 2009 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\System\SSH\Agent;
  19  
  20  use phpseclib3\Common\Functions\Strings;
  21  use phpseclib3\Crypt\Common\PrivateKey;
  22  use phpseclib3\Crypt\Common\PublicKey;
  23  use phpseclib3\Crypt\DSA;
  24  use phpseclib3\Crypt\EC;
  25  use phpseclib3\Crypt\RSA;
  26  use phpseclib3\Exception\UnsupportedAlgorithmException;
  27  use phpseclib3\System\SSH\Agent;
  28  
  29  /**
  30   * Pure-PHP ssh-agent client identity object
  31   *
  32   * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class.
  33   * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA
  34   * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
  35   * The methods in this interface would be getPublicKey and sign since those are the
  36   * methods phpseclib looks for to perform public key authentication.
  37   *
  38   * @package SSH\Agent
  39   * @author  Jim Wigginton <[email protected]>
  40   * @access  internal
  41   */
  42  class Identity implements PrivateKey
  43  {
  44      use \phpseclib3\System\SSH\Common\Traits\ReadBytes;
  45  
  46      // Signature Flags
  47      // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
  48      const SSH_AGENT_RSA2_256 = 2;
  49      const SSH_AGENT_RSA2_512 = 4;
  50  
  51      /**
  52       * Key Object
  53       *
  54       * @var PublicKey
  55       * @access private
  56       * @see self::getPublicKey()
  57       */
  58      private $key;
  59  
  60      /**
  61       * Key Blob
  62       *
  63       * @var string
  64       * @access private
  65       * @see self::sign()
  66       */
  67      private $key_blob;
  68  
  69      /**
  70       * Socket Resource
  71       *
  72       * @var resource
  73       * @access private
  74       * @see self::sign()
  75       */
  76      private $fsock;
  77  
  78      /**
  79       * Signature flags
  80       *
  81       * @var int
  82       * @access private
  83       * @see self::sign()
  84       * @see self::setHash()
  85       */
  86      private $flags = 0;
  87  
  88      /**
  89       * Curve Aliases
  90       *
  91       * @var array
  92       * @access private
  93       */
  94      private static $curveAliases = [
  95          'secp256r1' => 'nistp256',
  96          'secp384r1' => 'nistp384',
  97          'secp521r1' => 'nistp521',
  98          'Ed25519' => 'Ed25519'
  99      ];
 100  
 101      /**
 102       * Default Constructor.
 103       *
 104       * @param resource $fsock
 105       * @access private
 106       */
 107      public function __construct($fsock)
 108      {
 109          $this->fsock = $fsock;
 110      }
 111  
 112      /**
 113       * Set Public Key
 114       *
 115       * Called by \phpseclib3\System\SSH\Agent::requestIdentities()
 116       *
 117       * @param \phpseclib3\Crypt\Common\PublicKey $key
 118       * @access private
 119       */
 120      public function withPublicKey($key)
 121      {
 122          if ($key instanceof EC) {
 123              if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) {
 124                  throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519');
 125              }
 126          }
 127  
 128          $new = clone $this;
 129          $new->key = $key;
 130          return $new;
 131      }
 132  
 133      /**
 134       * Set Public Key
 135       *
 136       * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
 137       * but this saves a small amount of computation.
 138       *
 139       * @param string $key_blob
 140       * @access private
 141       */
 142      public function withPublicKeyBlob($key_blob)
 143      {
 144          $new = clone $this;
 145          $new->key_blob = $key_blob;
 146          return $new;
 147      }
 148  
 149      /**
 150       * Get Public Key
 151       *
 152       * Wrapper for $this->key->getPublicKey()
 153       *
 154       * @param string $type optional
 155       * @return mixed
 156       * @access public
 157       */
 158      public function getPublicKey($type = 'PKCS8')
 159      {
 160          return $this->key;
 161      }
 162  
 163      /**
 164       * Sets the hash
 165       *
 166       * @param string $hash
 167       * @access public
 168       */
 169      public function withHash($hash)
 170      {
 171          $new = clone $this;
 172  
 173          $hash = strtolower($hash);
 174  
 175          if ($this->key instanceof RSA) {
 176              $new->flags = 0;
 177              switch ($hash) {
 178                  case 'sha1':
 179                      break;
 180                  case 'sha256':
 181                      $new->flags = self::SSH_AGENT_RSA2_256;
 182                      break;
 183                  case 'sha512':
 184                      $new->flags = self::SSH_AGENT_RSA2_512;
 185                      break;
 186                  default:
 187                      throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512');
 188              }
 189          }
 190          if ($this->key instanceof EC) {
 191              switch ($this->key->getCurve()) {
 192                  case 'secp256r1':
 193                      $expectedHash = 'sha256';
 194                      break;
 195                  case 'secp384r1':
 196                      $expectedHash = 'sha384';
 197                      break;
 198                  //case 'secp521r1':
 199                  //case 'Ed25519':
 200                  default:
 201                      $expectedHash = 'sha512';
 202              }
 203              if ($hash != $expectedHash) {
 204                  throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$this->key->getCurve()] . ' is ' . $expectedHash);
 205              }
 206          }
 207          if ($this->key instanceof DSA) {
 208              if ($hash != 'sha1') {
 209                  throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1');
 210              }
 211          }
 212          return $new;
 213      }
 214  
 215      /**
 216       * Sets the padding
 217       *
 218       * Only PKCS1 padding is supported
 219       *
 220       * @param string $padding
 221       * @access public
 222       */
 223      public function withPadding($padding)
 224      {
 225          if (!$this->key instanceof RSA) {
 226              throw new UnsupportedAlgorithmException('Only RSA keys support padding');
 227          }
 228          if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) {
 229              throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures');
 230          }
 231          return $this;
 232      }
 233  
 234      /**
 235       * Determines the signature padding mode
 236       *
 237       * Valid values are: ASN1, SSH2, Raw
 238       *
 239       * @access public
 240       * @param string $format
 241       */
 242      public function withSignatureFormat($format)
 243      {
 244          if ($this->key instanceof RSA) {
 245              throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting');
 246          }
 247          if ($format != 'SSH2') {
 248              throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported');
 249          }
 250  
 251          return $this;
 252      }
 253  
 254      /**
 255       * Returns the curve
 256       *
 257       * Returns a string if it's a named curve, an array if not
 258       *
 259       * @access public
 260       * @return string|array
 261       */
 262      public function getCurve()
 263      {
 264          if (!$this->key instanceof EC) {
 265              throw new UnsupportedAlgorithmException('Only EC keys have curves');
 266          }
 267  
 268          return $this->key->getCurve();
 269      }
 270  
 271      /**
 272       * Create a signature
 273       *
 274       * See "2.6.2 Protocol 2 private key signature request"
 275       *
 276       * @param string $message
 277       * @return string
 278       * @throws \RuntimeException on connection errors
 279       * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
 280       * @access public
 281       */
 282      public function sign($message)
 283      {
 284          // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
 285          $packet = Strings::packSSH2(
 286              'CssN',
 287              Agent::SSH_AGENTC_SIGN_REQUEST,
 288              $this->key_blob,
 289              $message,
 290              $this->flags
 291          );
 292          $packet = Strings::packSSH2('s', $packet);
 293          if (strlen($packet) != fputs($this->fsock, $packet)) {
 294              throw new \RuntimeException('Connection closed during signing');
 295          }
 296  
 297          $length = current(unpack('N', $this->readBytes(4)));
 298          $packet = $this->readBytes($length);
 299  
 300          list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet);
 301          if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
 302              throw new \RuntimeException('Unable to retrieve signature');
 303          }
 304  
 305          if (!$this->key instanceof RSA) {
 306              return $signature_blob;
 307          }
 308  
 309          list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob);
 310  
 311          return $signature_blob;
 312      }
 313  
 314      /**
 315       * Returns the private key
 316       *
 317       * @param string $type
 318       * @param array $options optional
 319       * @return string
 320       */
 321      public function toString($type, array $options = [])
 322      {
 323          throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key');
 324      }
 325  
 326      /**
 327       * Sets the password
 328       *
 329       * @access public
 330       * @param string|bool $password
 331       * @return never
 332       */
 333      public function withPassword($password = false)
 334      {
 335          throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key');
 336      }
 337  }


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