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 RSA Key Handler
  5.  *
  6.  * PHP version 5
  7.  *
  8.  * Place in $HOME/.ssh/authorized_keys
  9.  *
  10.  * @category  Crypt
  11.  * @package   RSA
  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\RSA\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 RSA Key Handler
  26.  *
  27.  * @package RSA
  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-rsa'];
  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.         static $one;
  51.         if (!isset($one)) {
  52.             $one = new BigInteger(1);
  53.         }
  54.  
  55.         $parsed = parent::load($key, $password);
  56.  
  57.         if (isset($parsed['paddedKey'])) {
  58.             list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']);
  59.             if ($type != $parsed['type']) {
  60.                 throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
  61.             }
  62.  
  63.             $primes = $coefficients = [];
  64.  
  65.             list(
  66.                 $modulus,
  67.                 $publicExponent,
  68.                 $privateExponent,
  69.                 $coefficients[2],
  70.                 $primes[1],
  71.                 $primes[2],
  72.                 $comment,
  73.             ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']);
  74.  
  75.             $temp = $primes[1]->subtract($one);
  76.             $exponents = [1 => $publicExponent->modInverse($temp)];
  77.             $temp = $primes[2]->subtract($one);
  78.             $exponents[] = $publicExponent->modInverse($temp);
  79.  
  80.             $isPublicKey = false;
  81.  
  82.             return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey');
  83.         }
  84.  
  85.         list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']);
  86.  
  87.         return [
  88.             'isPublicKey' => true,
  89.             'modulus' => $modulus,
  90.             'publicExponent' => $publicExponent,
  91.             'comment' => $parsed['comment']
  92.         ];
  93.     }
  94.  
  95.     /**
  96.      * Convert a public key to the appropriate format
  97.      *
  98.      * @access public
  99.      * @param \phpseclib3\Math\BigInteger $n
  100.      * @param \phpseclib3\Math\BigInteger $e
  101.      * @param array $options optional
  102.      * @return string
  103.      */
  104.     public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = [])
  105.     {
  106.         $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n);
  107.  
  108.         if (isset($options['binary']) ? $options['binary'] : self::$binary) {
  109.             return $RSAPublicKey;
  110.         }
  111.  
  112.         $comment = isset($options['comment']) ? $options['comment'] : self::$comment;
  113.         $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment;
  114.  
  115.         return $RSAPublicKey;
  116.     }
  117.  
  118.     /**
  119.      * Convert a private key to the appropriate format.
  120.      *
  121.      * @access public
  122.      * @param \phpseclib3\Math\BigInteger $n
  123.      * @param \phpseclib3\Math\BigInteger $e
  124.      * @param \phpseclib3\Math\BigInteger $d
  125.      * @param array $primes
  126.      * @param array $exponents
  127.      * @param array $coefficients
  128.      * @param string $password optional
  129.      * @param array $options optional
  130.      * @return string
  131.      */
  132.     public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = [])
  133.     {
  134.         $publicKey = self::savePublicKey($n, $e, ['binary' => true]);
  135.         $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]);
  136.  
  137.         return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
  138.     }
  139. }
  140.