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
 * OpenSSH Formatted RSA Key Handler
5
 *
6
 * PHP version 5
7
 *
8
 * Place in $HOME/.ssh/authorized_keys
9
 *
874 daniel-mar 10
 * @category  Crypt
11
 * @package   RSA
827 daniel-mar 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
 *
874 daniel-mar 27
 * @package RSA
827 daniel-mar 28
 * @author  Jim Wigginton <terrafrost@php.net>
874 daniel-mar 29
 * @access  public
827 daniel-mar 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
     *
874 daniel-mar 43
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 98
     * @access public
827 daniel-mar 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
     *
874 daniel-mar 121
     * @access public
827 daniel-mar 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
}