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 RSA Key Handler
  5.  *
  6.  * PHP version 5
  7.  *
  8.  * @category  Crypt
  9.  * @package   RSA
  10.  * @author    Jim Wigginton <terrafrost@php.net>
  11.  * @copyright 2015 Jim Wigginton
  12.  * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  13.  * @link      http://phpseclib.sourceforge.net
  14.  */
  15.  
  16. namespace phpseclib3\Crypt\RSA\Formats\Keys;
  17.  
  18. use phpseclib3\Common\Functions\Strings;
  19. use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
  20. use phpseclib3\Math\BigInteger;
  21.  
  22. /**
  23.  * PuTTY Formatted RSA Key Handler
  24.  *
  25.  * @package RSA
  26.  * @author  Jim Wigginton <terrafrost@php.net>
  27.  * @access  public
  28.  */
  29. abstract class PuTTY extends Progenitor
  30. {
  31.     /**
  32.      * Public Handler
  33.      *
  34.      * @var string
  35.      * @access private
  36.      */
  37.     const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH';
  38.  
  39.     /**
  40.      * Algorithm Identifier
  41.      *
  42.      * @var array
  43.      * @access private
  44.      */
  45.     protected static $types = ['ssh-rsa'];
  46.  
  47.     /**
  48.      * Break a public or private key down into its constituent components
  49.      *
  50.      * @access public
  51.      * @param string $key
  52.      * @param string $password optional
  53.      * @return array
  54.      */
  55.     public static function load($key, $password = '')
  56.     {
  57.         static $one;
  58.         if (!isset($one)) {
  59.             $one = new BigInteger(1);
  60.         }
  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.         $isPublicKey = false;
  70.  
  71.         $result = Strings::unpackSSH2('ii', $public);
  72.         if ($result === false) {
  73.             throw new \UnexpectedValueException('Key appears to be malformed');
  74.         }
  75.         list($publicExponent, $modulus) = $result;
  76.  
  77.         $result = Strings::unpackSSH2('iiii', $private);
  78.         if ($result === false) {
  79.             throw new \UnexpectedValueException('Key appears to be malformed');
  80.         }
  81.         $primes = $coefficients = [];
  82.         list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result;
  83.  
  84.         $temp = $primes[1]->subtract($one);
  85.         $exponents = [1 => $publicExponent->modInverse($temp)];
  86.         $temp = $primes[2]->subtract($one);
  87.         $exponents[] = $publicExponent->modInverse($temp);
  88.  
  89.         return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey');
  90.     }
  91.  
  92.     /**
  93.      * Convert a private key to the appropriate format.
  94.      *
  95.      * @access public
  96.      * @param \phpseclib3\Math\BigInteger $n
  97.      * @param \phpseclib3\Math\BigInteger $e
  98.      * @param \phpseclib3\Math\BigInteger $d
  99.      * @param array $primes
  100.      * @param array $exponents
  101.      * @param array $coefficients
  102.      * @param string $password optional
  103.      * @param array $options optional
  104.      * @return string
  105.      */
  106.     public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = [])
  107.     {
  108.         if (count($primes) != 2) {
  109.             throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys');
  110.         }
  111.  
  112.         $public =  Strings::packSSH2('ii', $e, $n);
  113.         $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]);
  114.  
  115.         return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options);
  116.     }
  117.  
  118.     /**
  119.      * Convert a public key to the appropriate format
  120.      *
  121.      * @access public
  122.      * @param \phpseclib3\Math\BigInteger $n
  123.      * @param \phpseclib3\Math\BigInteger $e
  124.      * @return string
  125.      */
  126.     public static function savePublicKey(BigInteger $n, BigInteger $e)
  127.     {
  128.         return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa');
  129.     }
  130. }
  131.