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.  * PuTTY Formatted DSA Key Handler
  5.  *
  6.  * puttygen does not generate DSA keys with an N of anything other than 160, however,
  7.  * it can still load them and convert them. PuTTY will load them, too, but SSH servers
  8.  * won't accept them. Since PuTTY formatted keys are primarily used with SSH this makes
  9.  * keys with N > 160 kinda useless, hence this handlers not supporting such keys.
  10.  *
  11.  * PHP version 5
  12.  *
  13.  * @category  Crypt
  14.  * @package   DSA
  15.  * @author    Jim Wigginton <terrafrost@php.net>
  16.  * @copyright 2015 Jim Wigginton
  17.  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  18.  * @link      http://phpseclib.sourceforge.net
  19.  */
  20.  
  21. namespace phpseclib3\Crypt\DSA\Formats\Keys;
  22.  
  23. use phpseclib3\Common\Functions\Strings;
  24. use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
  25. use phpseclib3\Math\BigInteger;
  26.  
  27. /**
  28.  * PuTTY Formatted DSA Key Handler
  29.  *
  30.  * @package DSA
  31.  * @author  Jim Wigginton <terrafrost@php.net>
  32.  * @access  public
  33.  */
  34. abstract class PuTTY extends Progenitor
  35. {
  36.     /**
  37.      * Public Handler
  38.      *
  39.      * @var string
  40.      * @access private
  41.      */
  42.     const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH';
  43.  
  44.     /**
  45.      * Algorithm Identifier
  46.      *
  47.      * @var array
  48.      * @access private
  49.      */
  50.     protected static $types = ['ssh-dss'];
  51.  
  52.     /**
  53.      * Break a public or private key down into its constituent components
  54.      *
  55.      * @access public
  56.      * @param string $key
  57.      * @param string $password optional
  58.      * @return array
  59.      */
  60.     public static function load($key, $password = '')
  61.     {
  62.         $components = parent::load($key, $password);
  63.         if (!isset($components['private'])) {
  64.             return $components;
  65.         }
  66.         extract($components);
  67.         unset($components['public'], $components['private']);
  68.  
  69.         list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public);
  70.         list($x) = Strings::unpackSSH2('i', $private);
  71.  
  72.         return compact('p', 'q', 'g', 'y', 'x', 'comment');
  73.     }
  74.  
  75.     /**
  76.      * Convert a private key to the appropriate format.
  77.      *
  78.      * @access public
  79.      * @param \phpseclib3\Math\BigInteger $p
  80.      * @param \phpseclib3\Math\BigInteger $q
  81.      * @param \phpseclib3\Math\BigInteger $g
  82.      * @param \phpseclib3\Math\BigInteger $y
  83.      * @param \phpseclib3\Math\BigInteger $x
  84.      * @param string $password optional
  85.      * @param array $options optional
  86.      * @return string
  87.      */
  88.     public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = [])
  89.     {
  90.         if ($q->getLength() != 160) {
  91.             throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
  92.         }
  93.  
  94.         $public = Strings::packSSH2('iiii', $p, $q, $g, $y);
  95.         $private = Strings::packSSH2('i', $x);
  96.  
  97.         return self::wrapPrivateKey($public, $private, 'ssh-dsa', $password, $options);
  98.     }
  99.  
  100.     /**
  101.      * Convert a public key to the appropriate format
  102.      *
  103.      * @access public
  104.      * @param \phpseclib3\Math\BigInteger $p
  105.      * @param \phpseclib3\Math\BigInteger $q
  106.      * @param \phpseclib3\Math\BigInteger $g
  107.      * @param \phpseclib3\Math\BigInteger $y
  108.      * @return string
  109.      */
  110.     public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y)
  111.     {
  112.         if ($q->getLength() != 160) {
  113.             throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
  114.         }
  115.  
  116.         return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa');
  117.     }
  118. }
  119.