* @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib\Crypt\RSA\Keys; use phpseclib\Math\BigInteger; use phpseclib\Common\Functions\Strings; use phpseclib\Crypt\Common\Keys\PuTTY as Progenitor; /** * PuTTY Formatted RSA Key Handler * * @package RSA * @author Jim Wigginton * @access public */ abstract class PuTTY extends Progenitor { /** * Public Handler * * @var string * @access private */ const PUBLIC_HANDLER = 'phpseclib\Crypt\RSA\Keys\OpenSSH'; /** * Algorithm Identifier * * @var string * @access private */ const TYPE = 'ssh-rsa'; /** * Break a public or private key down into its constituent components * * @access public * @param string $key * @param string $password optional * @return array|bool */ public static function load($key, $password = '') { static $one; if (!isset($one)) { $one = new BigInteger(1); } $components = parent::load($key, $password); if ($components === false || !isset($components['private'])) { return $components; } extract($components); unset($components['public'], $components['private']); $isPublicKey = false; $result = Strings::unpackSSH2('ii', $public); if ($result === false) { return false; } list($publicExponent, $modulus) = $result; $result = Strings::unpackSSH2('iiii', $private); if ($result === false) { return false; } $primes = $coefficients = []; list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; $temp = $primes[1]->subtract($one); $exponents = [1 => $publicExponent->modInverse($temp)]; $temp = $primes[2]->subtract($one); $exponents[] = $publicExponent->modInverse($temp); return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); } /** * Convert a private key to the appropriate format. * * @access public * @param \phpseclib\Math\BigInteger $n * @param \phpseclib\Math\BigInteger $e * @param \phpseclib\Math\BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '') { if (count($primes) != 2) { throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); } $public = Strings::packSSH2('ii', $e, $n); $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); return self::wrapPrivateKey($public, $private, $password); } /** * Convert a public key to the appropriate format * * @access public * @param \phpseclib\Math\BigInteger $n * @param \phpseclib\Math\BigInteger $e * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e) { return self::wrapPublicKey(Strings::packSSH2($e, $n)); } }