Subversion Repositories oidplus

Rev

Rev 846 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
827 daniel-mar 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
 *
874 daniel-mar 13
 * @category  Crypt
14
 * @package   DSA
827 daniel-mar 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
 *
874 daniel-mar 30
 * @package DSA
827 daniel-mar 31
 * @author  Jim Wigginton <terrafrost@php.net>
874 daniel-mar 32
 * @access  public
827 daniel-mar 33
 */
34
abstract class PuTTY extends Progenitor
35
{
36
    /**
37
     * Public Handler
38
     *
39
     * @var string
874 daniel-mar 40
     * @access private
827 daniel-mar 41
     */
42
    const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH';
43
 
44
    /**
45
     * Algorithm Identifier
46
     *
47
     * @var array
874 daniel-mar 48
     * @access private
827 daniel-mar 49
     */
50
    protected static $types = ['ssh-dss'];
51
 
52
    /**
53
     * Break a public or private key down into its constituent components
54
     *
874 daniel-mar 55
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 78
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 103
     * @access public
827 daniel-mar 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
}