Subversion Repositories oidplus

Rev

Rev 846 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /**
  4.  * OpenSSH Formatted DSA Key Handler
  5.  *
  6.  * PHP version 5
  7.  *
  8.  * Place in $HOME/.ssh/authorized_keys
  9.  *
  10.  * @category  Crypt
  11.  * @package   DSA
  12.  * @author    Jim Wigginton <terrafrost@php.net>
  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\DSA\Formats\Keys;
  19.  
  20. use phpseclib3\Common\Functions\Strings;
  21. use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
  22. use phpseclib3\Math\BigInteger;
  23.  
  24. /**
  25.  * OpenSSH Formatted DSA Key Handler
  26.  *
  27.  * @package DSA
  28.  * @author  Jim Wigginton <terrafrost@php.net>
  29.  * @access  public
  30.  */
  31. abstract class OpenSSH extends Progenitor
  32. {
  33.     /**
  34.      * Supported Key Types
  35.      *
  36.      * @var array
  37.      */
  38.     protected static $types = ['ssh-dss'];
  39.  
  40.     /**
  41.      * Break a public or private key down into its constituent components
  42.      *
  43.      * @access public
  44.      * @param string $key
  45.      * @param string $password optional
  46.      * @return array
  47.      */
  48.     public static function load($key, $password = '')
  49.     {
  50.         $parsed = parent::load($key, $password);
  51.  
  52.         if (isset($parsed['paddedKey'])) {
  53.             list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']);
  54.             if ($type != $parsed['type']) {
  55.                 throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
  56.             }
  57.  
  58.             list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']);
  59.  
  60.             return compact('p', 'q', 'g', 'y', 'x', 'comment');
  61.         }
  62.  
  63.         list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']);
  64.  
  65.         $comment = $parsed['comment'];
  66.  
  67.         return compact('p', 'q', 'g', 'y', 'comment');
  68.     }
  69.  
  70.     /**
  71.      * Convert a public key to the appropriate format
  72.      *
  73.      * @access public
  74.      * @param \phpseclib3\Math\BigInteger $p
  75.      * @param \phpseclib3\Math\BigInteger $q
  76.      * @param \phpseclib3\Math\BigInteger $g
  77.      * @param \phpseclib3\Math\BigInteger $y
  78.      * @param array $options optional
  79.      * @return string
  80.      */
  81.     public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = [])
  82.     {
  83.         if ($q->getLength() != 160) {
  84.             throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
  85.         }
  86.  
  87.         // from <http://tools.ietf.org/html/rfc4253#page-15>:
  88.         // string    "ssh-dss"
  89.         // mpint     p
  90.         // mpint     q
  91.         // mpint     g
  92.         // mpint     y
  93.         $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y);
  94.  
  95.         if (isset($options['binary']) ? $options['binary'] : self::$binary) {
  96.             return $DSAPublicKey;
  97.         }
  98.  
  99.         $comment = isset($options['comment']) ? $options['comment'] : self::$comment;
  100.         $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment;
  101.  
  102.         return $DSAPublicKey;
  103.     }
  104.  
  105.     /**
  106.      * Convert a private key to the appropriate format.
  107.      *
  108.      * @access public
  109.      * @param \phpseclib3\Math\BigInteger $p
  110.      * @param \phpseclib3\Math\BigInteger $q
  111.      * @param \phpseclib3\Math\BigInteger $g
  112.      * @param \phpseclib3\Math\BigInteger $y
  113.      * @param \phpseclib3\Math\BigInteger $x
  114.      * @param string $password optional
  115.      * @param array $options optional
  116.      * @return string
  117.      */
  118.     public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = [])
  119.     {
  120.         $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]);
  121.         $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x);
  122.  
  123.         return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
  124.     }
  125. }
  126.