PuTTY.php 3.6 KB

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