[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

   1  <?php
   2  /**
   3   * Pure-PHP ssh-agent client.
   4   *
   5   * PHP version 5
   6   *
   7   * @category  System
   8   * @package   SSH\Agent
   9   * @author    Jim Wigginton <terrafrost@php.net>
  10   * @copyright 2009 Jim Wigginton
  11   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  12   * @link      http://phpseclib.sourceforge.net
  13   * @internal  See http://api.libssh.org/rfc/PROTOCOL.agent
  14   */
  15  
  16  namespace phpseclib\System\SSH\Agent;
  17  
  18  use phpseclib\System\SSH\Agent;
  19  
  20  /**
  21   * Pure-PHP ssh-agent client identity object
  22   *
  23   * Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
  24   * This could be thought of as implementing an interface that phpseclib\Crypt\RSA
  25   * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
  26   * The methods in this interface would be getPublicKey and sign since those are the
  27   * methods phpseclib looks for to perform public key authentication.
  28   *
  29   * @package SSH\Agent
  30   * @author  Jim Wigginton <terrafrost@php.net>
  31   * @access  internal
  32   */
  33  class Identity
  34  {
  35      /**@+
  36       * Signature Flags
  37       *
  38       * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
  39       *
  40       * @access private
  41       */
  42      const SSH_AGENT_RSA2_256 = 2;
  43      const SSH_AGENT_RSA2_512 = 4;
  44      /**#@-*/
  45  
  46      /**
  47       * Key Object
  48       *
  49       * @var \phpseclib\Crypt\RSA
  50       * @access private
  51       * @see self::getPublicKey()
  52       */
  53      var $key;
  54  
  55      /**
  56       * Key Blob
  57       *
  58       * @var string
  59       * @access private
  60       * @see self::sign()
  61       */
  62      var $key_blob;
  63  
  64      /**
  65       * Socket Resource
  66       *
  67       * @var resource
  68       * @access private
  69       * @see self::sign()
  70       */
  71      var $fsock;
  72  
  73      /**
  74       * Signature flags
  75       *
  76       * @var int
  77       * @access private
  78       * @see self::sign()
  79       * @see self::setHash()
  80       */
  81      var $flags = 0;
  82  
  83      /**
  84       * Default Constructor.
  85       *
  86       * @param resource $fsock
  87       * @return \phpseclib\System\SSH\Agent\Identity
  88       * @access private
  89       */
  90      function __construct($fsock)
  91      {
  92          $this->fsock = $fsock;
  93      }
  94  
  95      /**
  96       * Set Public Key
  97       *
  98       * Called by \phpseclib\System\SSH\Agent::requestIdentities()
  99       *
 100       * @param \phpseclib\Crypt\RSA $key
 101       * @access private
 102       */
 103      function setPublicKey($key)
 104      {
 105          $this->key = $key;
 106          $this->key->setPublicKey();
 107      }
 108  
 109      /**
 110       * Set Public Key
 111       *
 112       * Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
 113       * but this saves a small amount of computation.
 114       *
 115       * @param string $key_blob
 116       * @access private
 117       */
 118      function setPublicKeyBlob($key_blob)
 119      {
 120          $this->key_blob = $key_blob;
 121      }
 122  
 123      /**
 124       * Get Public Key
 125       *
 126       * Wrapper for $this->key->getPublicKey()
 127       *
 128       * @param int $format optional
 129       * @return mixed
 130       * @access public
 131       */
 132      function getPublicKey($format = null)
 133      {
 134          return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
 135      }
 136  
 137      /**
 138       * Set Signature Mode
 139       *
 140       * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
 141       * ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
 142       *
 143       * @param int $mode
 144       * @access public
 145       */
 146      function setSignatureMode($mode)
 147      {
 148      }
 149  
 150      /**
 151       * Set Hash
 152       *
 153       * ssh-agent doesn't support using hashes for RSA other than SHA1
 154       *
 155       * @param string $hash
 156       * @access public
 157       */
 158      function setHash($hash)
 159      {
 160          $this->flags = 0;
 161          switch ($hash) {
 162              case 'sha1':
 163                  break;
 164              case 'sha256':
 165                  $this->flags = self::SSH_AGENT_RSA2_256;
 166                  break;
 167              case 'sha512':
 168                  $this->flags = self::SSH_AGENT_RSA2_512;
 169                  break;
 170              default:
 171                  user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
 172          }
 173      }
 174  
 175      /**
 176       * Create a signature
 177       *
 178       * See "2.6.2 Protocol 2 private key signature request"
 179       *
 180       * @param string $message
 181       * @return string
 182       * @access public
 183       */
 184      function sign($message)
 185      {
 186          // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
 187          $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
 188          $packet = pack('Na*', strlen($packet), $packet);
 189          if (strlen($packet) != fputs($this->fsock, $packet)) {
 190              user_error('Connection closed during signing');
 191              return false;
 192          }
 193  
 194          $temp = fread($this->fsock, 4);
 195          if (strlen($temp) != 4) {
 196              user_error('Connection closed during signing');
 197              return false;
 198          }
 199          $length = current(unpack('N', $temp));
 200          $type = ord(fread($this->fsock, 1));
 201          if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
 202              user_error('Unable to retrieve signature');
 203              return false;
 204          }
 205  
 206          $signature_blob = fread($this->fsock, $length - 1);
 207          if (strlen($signature_blob) != $length - 1) {
 208              user_error('Connection closed during signing');
 209              return false;
 210          }
 211          $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
 212          if ($length != strlen($signature_blob)) {
 213              user_error('Malformed signature blob');
 214          }
 215          $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
 216          if ($length > strlen($signature_blob) + 4) {
 217              user_error('Malformed signature blob');
 218          }
 219          $type = $this->_string_shift($signature_blob, $length);
 220          $this->_string_shift($signature_blob, 4);
 221  
 222          return $signature_blob;
 223      }
 224  
 225      /**
 226       * String Shift
 227       *
 228       * Inspired by array_shift
 229       *
 230       * @param string $string
 231       * @param int $index
 232       * @return string
 233       * @access private
 234       */
 235      function _string_shift(&$string, $index = 1)
 236      {
 237          $substr = substr($string, 0, $index);
 238          $string = substr($string, $index);
 239          return $substr;
 240      }
 241  }