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 RSA Key Handler
5
 *
6
 * PHP version 5
7
 *
874 daniel-mar 8
 * @category  Crypt
9
 * @package   RSA
827 daniel-mar 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
 *
874 daniel-mar 25
 * @package RSA
827 daniel-mar 26
 * @author  Jim Wigginton <terrafrost@php.net>
874 daniel-mar 27
 * @access  public
827 daniel-mar 28
 */
29
abstract class PuTTY extends Progenitor
30
{
31
    /**
32
     * Public Handler
33
     *
34
     * @var string
874 daniel-mar 35
     * @access private
827 daniel-mar 36
     */
37
    const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH';
38
 
39
    /**
40
     * Algorithm Identifier
41
     *
42
     * @var array
874 daniel-mar 43
     * @access private
827 daniel-mar 44
     */
45
    protected static $types = ['ssh-rsa'];
46
 
47
    /**
48
     * Break a public or private key down into its constituent components
49
     *
874 daniel-mar 50
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 95
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 121
     * @access public
827 daniel-mar 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
}